使用 GLSL 在 THREE.ShaderMaterial 中照明

Lighting in THREE.ShaderMaterial using GLSL

我正在尝试使用带有 Three.js 的 ShaderMaterial 来模拟 PhongMaterial。

我正在为场景添加灯光:

            var lightColor = new THREE.Color(0xffffff);
            var aLight = new THREE.AmbientLight(lightColor);
            scene.add(aLight);
            var dLight = new THREE.DirectionalLight(lightColor,1.0);
            dLight.name = "dLight";
            dLight.position.set(-1.0, 0.0, -0.3).normalize();
            scene.add(dLight);

当我将 MeshPhongMaterial 添加到场景时,一切都很酷。现在我正在使用 ShaderMaterial:

        var shaderMaterial = new THREE.ShaderMaterial({

            uniforms:THREE.UniformsUtils.merge( [

                THREE.UniformsLib["lights"],

                {
                    diffuseMaterial: {type: "c", value: new THREE.Color(1,0,0)},
                    specularMaterial: {type: "c", value: new THREE.Color(0.7,0.7,0.7)},
                    ambientMaterial:{type:"c", value: new THREE.Color(0.8,0.2,0.2)},
                    shininessMaterial: {type:"f", value: 16.0}
                }
            ]),

            vertexShader: vs,
            fragmentShader: fs,
            lights:true
        });

这是我的顶点着色器:

uniform vec3 diffuseMaterial;
uniform vec3 specularMaterial;
uniform vec3 ambientMaterial;
uniform float shininessMaterial;
uniform vec3 ambientLight;
uniform vec3 directionalLightColor[NUM_DIR_LIGHTS];
uniform vec3 directionalLightDirection[NUM_DIR_LIGHTS];
uniform vec3 ambientLightColor[1];

varying vec3 fragColor;

vec3 phong(vec3 p, vec3 n, vec3 v){

    vec3 fromLight = normalize(directionalLightDirection[0]);
    vec3 toLight = -fromLight;

    vec3 reflectLight = reflect(toLight,n);

    float ndots = dot(n, toLight);
    float vdotr = abs(dot(v,reflectLight));

    vec3 ambi = ambientMaterial * ambientLightColor[0];
    vec3 diff = diffuseMaterial * directionalLightColor[0] * ndots;
    vec3 spec = specularMaterial * directionalLightColor[0] * pow(vdotr,shininessMaterial);

    return ambi + diff + spec ;
    //return ambi + diff;
}



void main() {

     gl_PointSize = 3.0;

     vec4 ecPosition=modelViewMatrix*vec4(position,1.0);
     vec3 ecNormal= normalize(normalMatrix*normal);

     bool useOrtho = projectionMatrix[2][3] == 0.0;


     vec3 viewDir=useOrtho ? vec3(0,0,1) : normalize(-ecPosition.xyz);

     fragColor=phong(ecPosition.xyz, ecNormal, viewDir);


     gl_Position = projectionMatrix *
                   modelViewMatrix *
                   vec4(position,1.0);
}

但我得到的只是 this. When I only want the diffuse or specular part I get this black one。我做错了什么?

线

float vdotr = abs(dot(v,reflectLight));

必须

float vdotr = max(0,dot(v,reflectLight));