6. 模型扫光效果(顶点位置插值)
# 模型扫光效果(顶点位置插值)
接着2.4节顶点位置插值计算的讲解,设置一个扫光动画效果,你可以打开2.6、2.7小节源码查看效果。
# 扫光思路
回顾前两节内容,模型上的光带效果是通过片元对应y坐标控制的。
if(vPosition.y > 20.0 && vPosition.y < 21.0 ){
gl_FragColor = vec4(1.0,1.0,0.0,1.0);
}
那么如果想让光带动起来,生成一个扫光效果,那么你就可以让vPosition.y判断条件片元高度是随着时间改变的即可。
uniform float y; //变化的y控制光带高度
viod main(){
// 如果让y随着时间的变化,就可以实现一个动态的扫光效果。
if(vPosition.y > y && vPosition.y < y + 1.0 ){
gl_FragColor = vec4(1.0,1.0,0.0,1.0);
}
}
# 测试shader.uniforms
给着色器变量y
传值
执行shader.uniforms.y = { value: 30 };
给片元着色器uniform变量y传递一个值30,查看视觉效果。
material.onBeforeCompile = function (shader) {
...
shader.fragmentShader = shader.fragmentShader.replace(
'void main() {',
`
uniform float y; //变化的y控制光带高度
varying vec3 vPosition;
void main() {
`
);
...
shader.uniforms.y = { value: 30 };
};
# 在onBeforeCompile函数外访问shader.uniforms
属性
material.onBeforeCompile = function (shader) {
...
mesh.shader = shader;
};
在渲染循环中访问shader,你会发现首次打印值是未定义undefined
,这说明renderer.render(scene, camera)
执行一次后,才能获取到material.onBeforeCompile
函数的参数shader,完成赋值mesh.shader = shader;
function render() {
console.log('mesh.shader', mesh.shader);
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
function render() {
renderer.render(scene, camera);
// enderer.render执行一次,才能获取到mesh.shader
console.log('mesh.shader', mesh.shader);
requestAnimationFrame(render);
}
render();
# 时间改变来控制模型光带的位置
可以通过时间,改变mesh.shader.uniforms.y
的值,这样模型光带就会随着时间改变。
// 渲染循环
const clock = new THREE.Clock();
function render() {
// console.log('mesh.shader', mesh.shader);
const deltaTime = clock.getDelta();
renderer.render(scene, camera);
// enderer.render执行一次,才能获取到mesh.shader
mesh.shader.uniforms.y.value += 30 * deltaTime;
// 一旦y接近模型mesh顶部,重新设置为0,这样扫光反复循环
if (mesh.shader.uniforms.y.value > 99) mesh.shader.uniforms.y.value = 0;
requestAnimationFrame(render);
}
render();