使用GLSL在THREE.ShaderMaterial中进行照明

时间:2016-07-05 18:38:05

标签: three.js glsl webgl shader

我尝试使用带有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。当我只想要漫反射或镜面反射部分时,我得到this black one。我做错了什么?

1 个答案:

答案 0 :(得分:0)

The Line

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

必须是

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