如何将半球灯应用到ShaderMaterial?



我想添加半球光来照亮一个用ShaderMaterial构建的对象。但当我简单地将光线加到屏幕上时,物体似乎没有受到影响。事实上,我已经尝试了所有其他的光,没有一个光影响到物体。我需要设置什么来使物体受到灯光的影响?

<script src="https://threejs.org/build/three.js"></script>
<script type="module">
var clock = new THREE.Clock()
function main() {
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 200, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var vShader = `
precision mediump float;
uniform float uTime;
void main() {
float z = 0.1*cos(uTime)   * cos(position.y*40. - uTime) * position.y*sin(log(position.y))*0.5 + 0.5;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position.x, position.y, z, 1.0);
}
`
var fShader = `
precision mediump float;
uniform vec2 uRes;
void main() {
vec2 uv = 1.5*gl_FragCoord.xy/uRes;
gl_FragColor = vec4(uv.x, uv.y, 0.0, 1.0);
}
//   `
var planeG = new THREE.PlaneGeometry(25, 60, 20, 20);
var planeM = new THREE.ShaderMaterial({
uniforms: {
//ambientLightColor: 0xffffff,
uTime: {
type:"f",
value:0.0,
},
uRes: {
type:"f",
value:new THREE.Vector2(window.innerWidth, window.innerHeight),
}
},
// wireframe:true,
//lights:true,
vertexShader:vShader,
fragmentShader:fShader,
side:THREE.DoubleSide,
});

var plane = new THREE.Mesh( planeG, planeM );
var light = new THREE.HemisphereLight(0xffffff, 0x000000, 2);
//var light = new THREE.AmbientLight(0xFFFFFF, 1.0)


scene.add(light);
scene.add(plane);

plane.rotateZ(Math.PI/2)
camera.position.z = 4;

scene.background = new THREE.Color(0xfffffff);
var render = function (time) {
requestAnimationFrame( render );   
plane.material.uniforms.uTime.value = time/100;
renderer.render(scene, camera);
};
render();
};
main()
</script>

ShaderMaterial不响应光,因为你手动告诉着色器输出什么颜色,当你在片段着色器中分配值给gl_FragColor。你重写了材质的默认行为,所以所有的东西,比如position, rotation, color,都是由你来控制的。

如果你想要一个半球光影响你的着色器,那么你必须在GLSL中手动编写这些计算,这是一个相当复杂的过程。你必须把光的颜色作为统一的颜色输入,然后你必须找出哪些三角形是朝上和朝下的,这样它们才能"反射"。

Three.js将所有材质着色器分解为&;ShaderChunks"中的几个文件,因此很难准确地跟踪每个步骤发生的位置。

最新更新