Search code examples
three.jsfragment-shadervertex-shadershadermaterial

Three.js - How to Rotate Shader Material?


My problem is trying to get the sky to rotate on its z-axis. For example if I rotate the sky by 180 degrees the shadow from the sun light should display in the opposite direction.

The code sandbox: https://codesandbox.io/s/friendly-cloud-c00zr?file=/src/main.js:

This is where I create the sky in the main.js file:

const createSky = () => {

  const sky = new Sky();
  sky.scale.setScalar(1000);
  sky.castShadow = true;
  return sky;
};

I’ve tried rotateZ and sky.rotation to no avail.

The code in the sky.js file:

https://codesandbox.io/s/little-microservice-7nh53?file=/src/sky.js

is a modified iteration of the original three.js sky-sun-shader:

https://threejs.org/examples/webgl_shaders_sky.html

All that I have changed is the up position of the sky and its geometry from boxBuffer to sphereBuffer.

I would post the code here but it but it's over 200 lines of code.

I am wondering if there is a special way to rotate this ShaderMaterial in sky.js?


Solution

  • sky.material.uniforms.sunPosition.value.copy( light.position ); It looks like you can use this line to have the sun move from east to west.

    Here the east-west is on the x axis and north-south is on z;

    let sunPivot = new THREE.Object3D();
    
    //add the light to the pivot at an offset off 100 units( can be changed );
    light.positions.set( -100, 0, 0); 
    sunPivot.add( light );
    

    in the render loop:

    sunPivot.rotateZ( 0.005 ); //arbitrary rotation speed
    light.getWorldPosition( sky.material.uniforms.sunPosition.value ); //the uniform value as target (puts the world position of the light into the sunPosition.value