Javascript Three.js:使用一种颜色将网格着色器材质填充到特定位置
我在理解3.js着色器时遇到一些问题。我正在尝试使用颜色为网格着色,但仅限于特定位置。到目前为止,这是我最接近实现这一目标的一次Javascript Three.js:使用一种颜色将网格着色器材质填充到特定位置,javascript,three.js,glsl,fragment-shader,vertex-shader,Javascript,Three.js,Glsl,Fragment Shader,Vertex Shader,我在理解3.js着色器时遇到一些问题。我正在尝试使用颜色为网格着色,但仅限于特定位置。到目前为止,这是我最接近实现这一目标的一次 我需要使绿色“停止”在网格高度的50% 对于网格的其余部分(50%以上),要么用另一种颜色填充,要么根本不填充(这两种情况在这里都适用) 着色器代码: const _VS = ` uniform vec3 bboxMin; uniform vec3 bboxMax; varying vec2 vUv;
- 我需要使绿色“停止”在网格高度的50%
- 对于网格的其余部分(50%以上),要么用另一种颜色填充,要么根本不填充(这两种情况在这里都适用)
const _VS = `
uniform vec3 bboxMin;
uniform vec3 bboxMax;
varying vec2 vUv;
void main() {
vUv.x = (position.x - bboxMin.x) / (bboxMax.x - bboxMin.x);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
const _FS = `
uniform vec3 incompleteColor;
uniform vec3 completenessColor;
varying vec2 vUv;
void main() {
gl_FragColor = vec4(mix(incompleteColor, completenessColor, vUv.x), 1.0);
}
`;
let geometries = element.geometry.clone(); // Inherits geometries from parent element
let wall = new THREE.Mesh(
geometries,
new THREE.ShaderMaterial({
uniforms: {
incompleteColor: {
value: new THREE.Color('red')
},
completenessColor: {
value: new THREE.Color('green')
},
bboxMin: {
value: element.geometry.boundingBox.min
},
bboxMax: {
value: element.geometry.boundingBox.max
}
},
vertexShader: _VS,
fragmentShader: _FS,
})
);
wall.castShadow = true;
wall.position.setFromMatrixPosition(element.matrixWorld);
wall.rotation.setFromRotationMatrix(element.matrixWorld, 'XYZ');
scene.add(wall);
Javascript代码:
const _VS = `
uniform vec3 bboxMin;
uniform vec3 bboxMax;
varying vec2 vUv;
void main() {
vUv.x = (position.x - bboxMin.x) / (bboxMax.x - bboxMin.x);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
const _FS = `
uniform vec3 incompleteColor;
uniform vec3 completenessColor;
varying vec2 vUv;
void main() {
gl_FragColor = vec4(mix(incompleteColor, completenessColor, vUv.x), 1.0);
}
`;
let geometries = element.geometry.clone(); // Inherits geometries from parent element
let wall = new THREE.Mesh(
geometries,
new THREE.ShaderMaterial({
uniforms: {
incompleteColor: {
value: new THREE.Color('red')
},
completenessColor: {
value: new THREE.Color('green')
},
bboxMin: {
value: element.geometry.boundingBox.min
},
bboxMax: {
value: element.geometry.boundingBox.max
}
},
vertexShader: _VS,
fragmentShader: _FS,
})
);
wall.castShadow = true;
wall.position.setFromMatrixPosition(element.matrixWorld);
wall.rotation.setFromRotationMatrix(element.matrixWorld, 'XYZ');
scene.add(wall);
此图有助于说明我想要实现的目标:
const _VS = `
uniform vec3 bboxMin;
uniform vec3 bboxMax;
varying vec2 vUv;
void main() {
vUv.x = (position.x - bboxMin.x) / (bboxMax.x - bboxMin.x);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
const _FS = `
uniform vec3 incompleteColor;
uniform vec3 completenessColor;
varying vec2 vUv;
void main() {
gl_FragColor = vec4(mix(incompleteColor, completenessColor, vUv.x), 1.0);
}
`;
let geometries = element.geometry.clone(); // Inherits geometries from parent element
let wall = new THREE.Mesh(
geometries,
new THREE.ShaderMaterial({
uniforms: {
incompleteColor: {
value: new THREE.Color('red')
},
completenessColor: {
value: new THREE.Color('green')
},
bboxMin: {
value: element.geometry.boundingBox.min
},
bboxMax: {
value: element.geometry.boundingBox.max
}
},
vertexShader: _VS,
fragmentShader: _FS,
})
);
wall.castShadow = true;
wall.position.setFromMatrixPosition(element.matrixWorld);
wall.rotation.setFromRotationMatrix(element.matrixWorld, 'XYZ');
scene.add(wall);
左:我发布的代码的外观(Three.js场景)
对:我想要实现的目标
我花了几个小时研究这个问题,但似乎找不到一个能为我指明方向的例子。您需要使用GLSL
step()
函数。你可以
void main(){
//首先,在UV超过0.5阈值时创建一个硬步骤
浮动开关=阶跃(0.5,vUv.x);
//然后在混合函数中使用这一艰难步骤
gl_FragColor=vec4(混合(不完全颜色、完全颜色、开关),1.0);
}
看看这个论坛主题:Thx,这正是我需要的!