javascript - THREE.js vertexShader 基于高度的颜色混合
问题描述
仅当高度为零时如何将颜色设置为网格?
至于现在,我只是混合颜色:
问题是这种混合不精确。我只在高度为零时才想要蓝色(所以只在我用油漆制作的红色路径内)。
我为网格创建了一个自定义材质,如下所示:
material = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.merge([
THREE.UniformsLib['lights'],
{
lightIntensity: {type: 'f', value: 1.0},
diffuse: {type: 'c', value: new THREE.Color(0x0000ff)},
color0: {
value: new THREE.Color("blue")
},
color1: {
value: new THREE.Color("green")
},
color2: {
value: new THREE.Color("brown")
},
color3: {
value: new THREE.Color("black")
},
bboxMin: {
value: geom.boundingBox.min
},
bboxMax: {
value: geom.boundingBox.max
}
}
]),
vertexShader: `
uniform vec3 bboxMin;
uniform vec3 bboxMax;
varying vec2 vUv;
varying vec3 vPos;
varying vec3 vNormal;
void main() {
vPos = (modelMatrix * vec4(position, 1.0 )).xyz;
vNormal = normalMatrix * normal;
vUv.y = (position.y - bboxMin.y) / (bboxMax.y - bboxMin.y);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
`,
fragmentShader: `
uniform vec3 color1;
uniform vec3 color2;
uniform vec3 color3;
uniform vec3 color0;
varying vec2 vUv;
uniform vec3 diffuse;
varying vec3 vPos;
varying vec3 vNormal;
struct PointLight {
vec3 position;
vec3 color;
};
uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
void main() {
vec4 addedLights = vec4(0.1, 0.1, 0.1, 1.0);
for(int l = 0; l < NUM_POINT_LIGHTS; l++) {
vec3 adjustedLight = pointLights[l].position + cameraPosition;
vec3 lightDirection = normalize(vPos - adjustedLight);
addedLights.rgb += clamp(dot(-lightDirection, vNormal), 0.0, 1.0) * pointLights[l].color;
}
gl_FragColor = mix(vec4(mix(mix(mix(color0, color1, vUv.y), color1, vUv.y), mix(color1, color2, vUv.y), vUv.y), 1.0),addedLights, addedLights);
}
`,
lights: true
});
解决方案
尝试使用该step()
功能。这里有一个定义来帮助你理解它。以下是它的工作原理:
float step(float edge, float x)
- 它接受一个常量来声明
edge
, 和x
,这是你的变量。 - 如果 x 低于边缘,则得到
0
,如果 x 高于边缘,则得到1
。
这是它的简化用法。当高度低于 0.2 时,你会得到蓝色,当高度高于 0.2 时,你会得到绿色。
vec3 green = vec3(0.0, 1.0, 0.0);
vec3 blue = vec3(0.0, 0.0, 1.0);
float edge = 0.2;
float colorMix = step(edge, height);
vec3 finalColor = mix(blue, green, colorMix);
我选择了 0.2 给蓝色带一些厚度,否则它不会可见。
推荐阅读
- json - 从共享点列表中获取 URL 和标题并使标题可点击
- react-native - Sendbird 连接失败:连接超时
- python - 如何在 Seaborn 中使用 FacetGrid 分别绘制变量
- matrix - 在执行这个fortran 95代码时,它给了我一个错误PARAB - 在第221行的文件hammer.f95 [+0203] main - 在第171行的文件hammer.f95 [+2e49]
- c# - 如何获取对应的变量名到其对应的值C#
- angular - 无法访问.catch(函数(错误)Ionic 3中的变量
- ms-access - MS Access 报告无数据输出
- python - 如何在 Python 中使 Sqlite3 的列名区分大小写?
- asp.net-mvc - 如何使用 MVC 将 PaginatedList 与 ViewModel 一起使用
- java - Apache Camel Rest 503 错误