js创建材质

为了使用场景中的光照信息,需要设置lights:true

const material=new THREE.RawShaderMaterial(
            {
               // 设置uniforms变量,因为需要引用光照uniforms,所以需要使用merge合并
                uniforms: THREE.UniformsUtils.merge([
                   
                    // 引用光照uniforms
                    THREE.UniformsLib.lights,
                    {
                        // 自定义uniforms
                        // 基础颜色
                        color: { value: new THREE.Color(0xff0000) },
                        
                        diffuse: { value: 0.5 },
                        specular: { value: 0.5 },
                        glossiness: { value: 100 },
                    }
                ]),
                vertexShader: vertexShader,
                fragmentShader: fragmentShader,
                lights: true,
            }

顶点着色器

const fragmentShader = /*glsl*/`


    precision mediump float;
    uniform vec3 color;

    uniform float diffuse;
    uniform float specular;
    uniform float glossiness;

    uniform vec3 cameraPosition;
    
    uniform vec3 ambientLightColor;

   
    struct DirectionalLight {
        vec3 direction;
        vec3 color;
     };
    
    uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];
    

    varying vec3 vWorldPosition;
    varying vec3 vWorldNormal;
    varying vec3 vNormal;

    void main() {
        vec3 normal = normalize(vWorldNormal);
        vec3 lightDirection = normalize(directionalLights[0].direction);

        float lambert = max(dot(normal, lightDirection), 0.0);

        float specularStrength = 0.5;
        vec3 viewDirection = normalize(cameraPosition - vWorldPosition);

        vec3 halfDirection = normalize(lightDirection + viewDirection);
        float specularFactor = pow(max(dot(normal, halfDirection), 0.0), glossiness);

        vec3 specularColor = specularStrength * specularFactor * directionalLights[0].color;

        vec3 diffuseColor = color * lambert;
        vec3 ambientColor = ambientLightColor * 0.1;
        vec3 finalColor = (diffuseColor + ambientColor + specularColor) ;

        gl_FragColor = vec4(finalColor, 1.0);
        
    }
`;
export default fragmentShader;

片元着色器

const fragmentShader = /*glsl*/`

    // 需要设置精度,否则会报错
    precision mediump float;

    // 由threejs自动传入
    uniform vec3 color;

    uniform float diffuse;
    uniform float specular;
    uniform float glossiness;

    uniform vec3 cameraPosition;
    
    uniform vec3 ambientLightColor;

   
    struct DirectionalLight {
        vec3 direction;
        vec3 color;
     };
    
    uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];
    
     // 顶点着色器传入的变量
    varying vec3 vWorldPosition;
    varying vec3 vWorldNormal;
    varying vec3 vNormal;

    void main() {
        vec3 normal = normalize(vWorldNormal);
        vec3 lightDirection = normalize(directionalLights[0].direction);

        float lambert = max(dot(normal, lightDirection), 0.0);

        float specularStrength = 0.5;
        vec3 viewDirection = normalize(cameraPosition - vWorldPosition);

        vec3 halfDirection = normalize(lightDirection + viewDirection);
        float specularFactor = pow(max(dot(normal, halfDirection), 0.0), glossiness);

        vec3 specularColor = specularStrength * specularFactor * directionalLights[0].color;

        vec3 diffuseColor = color * lambert;
        vec3 ambientColor = ambientLightColor * 0.1;
        vec3 finalColor = (diffuseColor + ambientColor + specularColor) ;

        gl_FragColor = vec4(finalColor, 1.0);
        
    }
`;
export default fragmentShader;

源码

https://github.com/buggzd/threejsLearning

Q.E.D.


寄蜉蝣于天地,渺沧海之一粟