我将一个 STL 文件加载到我的场景中,并将单一颜色应用于 phong 材质
我想要一种将两种颜色应用于此网格材质的方法,并在 Z 轴上应用渐变效果,如下例所示。 渐变花瓶] 1
我有一种感觉,我可能必须引入着色器,但我对 three.js 还没有做到这一点。
原文由 Huskie69 发布,翻译遵循 CC BY-SA 4.0 许可协议
我将一个 STL 文件加载到我的场景中,并将单一颜色应用于 phong 材质
我想要一种将两种颜色应用于此网格材质的方法,并在 Z 轴上应用渐变效果,如下例所示。 渐变花瓶] 1
我有一种感觉,我可能必须引入着色器,但我对 three.js 还没有做到这一点。
原文由 Huskie69 发布,翻译遵循 CC BY-SA 4.0 许可协议
如果您想保留 MeshPhongMaterial
的功能,您可以尝试扩展材料。
这是一个包含多种方法的宽泛主题,您可以 在此处 深入了解它。
phong 材质着色器中有一行看起来像这样
vec4 diffuseColor = vec4( diffuse, opacity );
因此,在学习了着色器之书或其他一些教程之后,您将了解到可以使用归一化因子(介于 0,1 之间的数字)来混合两种颜色。
这意味着您可以将此行更改为类似这样的内容
vec4 diffuseColor = vec4( mix(diffuse, myColor, vec3(myFactor)), opacity);
您可以这样扩展着色器
const myFactor = { value: 0 }
const myColor = {value: new THREE.Color}
myMaterial.onBeforeCompile = shader=>{
shader.uniforms.myFactor = myFactor
shader.uniforms.myColor = myColor
shader.fragmentShader = `
uniform vec3 myColor;
uniform float myFactor;
${shader.fragmentShader.replace(
vec4 diffuseColor = vec4( diffuse, opacity );
vec4 diffuseColor = vec4( mix(diffuse, myColor, vec3(myFactor)), opacity);
)}
`
现在,当您更改 myFactor.value
时,对象的颜色应该从 myMaterial.color
更改为 myColor.value
。
现在要真正将其变成渐变,您可以将 myFactor
替换为动态的东西。我喜欢使用紫外线的囚犯解决方案。它完全是用 javascript 完成的,并且很容易连接到这个着色器中。其他方法可能需要更多的着色器工作。
vec4 diffuseColor = vec4( mix(diffuse, myColor, vec3(vUv.y)), opacity);
现在您可能遇到的问题 - 如果您调用 new PhongMaterial({color})
即。如果没有提供任何纹理,着色器将在没有 vUv
的情况下编译。有很多条件会导致它编译并对你有用,但我不确定它们是否会破坏其他东西:
#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )
所以,添加类似
myMaterial.defines = {USE_MAP:''}
可能会使 vUv
变量可用于您的着色器。通过这种方式,您可以让 phong 材质的所有灯光影响材质,您只需更改基色。
原文由 pailhead 发布,翻译遵循 CC BY-SA 4.0 许可协议
8 回答4.5k 阅读✓ 已解决
6 回答3.1k 阅读✓ 已解决
5 回答2.7k 阅读✓ 已解决
5 回答6.2k 阅读✓ 已解决
4 回答2.2k 阅读✓ 已解决
3 回答2.4k 阅读
4 回答2.7k 阅读✓ 已解决
简单的渐变着色器,基于 uvs:
简单的渐变着色器,基于坐标:
具有顶点颜色的渐变:
实际上,使用哪种方法取决于您:着色器、顶点颜色、纹理等。