ThreeJS:如何使场景灯点亮自定义着色器?

时间:2015-05-10 11:54:30

标签: three.js

我使用THREE.ShaderMaterial创建了一个简单的自定义着色器,它只使用高度图更改了平面的形状。

有没有人知道使用非常简单的自定义着色器使用场景定向光源的正确方法?

修改

顶点着色器

uniform sampler2D heightTexture;
varying float displacement;
varying vec2 vUv;
varying vec3 vPosition;
varying vec3 vNormal;

void main() {
    vUv = uv;
    vec4 data = texture2D(heightTexture, uv);
    displacement = data.b;
    vec3 height = position + normal * displacement;
    vPosition = (modelMatrix * vec4(position, 1.0)).xyz;
    vNormal = (modelMatrix * vec4(normal, 0.0)).xyz;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(height, 1.0);
}

片段着色器

uniform sampler2D texture;
uniform vec3 pointLightColor[MAX_POINT_LIGHTS];
uniform vec3 pointLightPosition[MAX_POINT_LIGHTS];
uniform float pointLightDistance[MAX_POINT_LIGHTS];
varying vec2 vUv;
varying vec3 vPosition;
varying vec3 vNormal;

void main() {                  

    vec4 texture = texture2D(texture, vUv);
    vec4 lights = vec4(0.0, 0.0, 0.0, 1.0);
    for(int i = 0; i < MAX_POINT_LIGHTS; i++) {
        vec3 lightVector = normalize(vPosition - pointLightPosition[i]);
        lights.rgb += clamp(dot(-lightVector, vNormal), 0.0, 1.0) * pointLightColor[i];
    }
    gl_FragColor = texture * lights;
}

我尝试使用点光源,因为我根本不能使用方向,即使我需要使用方向。在片段着色器中,如果我写gl_FragColor = lights;灯光是可见的,但如果我尝试gl_FragColor = texture * lights;之类的东西,则该平面变为黑色。如果我使用颜色而不是纹理,它也可以使用,但我需要使用纹理。

第二个问题是,当灯光设置为true且制服与THREE.UniformsLib['lights']合并时,高度图根本不会影响飞机。

1 个答案:

答案 0 :(得分:2)

通过将`THREE.UniformsLib [&#39; lights&#39;]与你的制服合并,包括所需的轻型制服。例如。

var uniforms = THREE.UniformsUtils.merge(
        [THREE.UniformsLib['lights'],
        {
          diffuse: {type: 'c', value: new THREE.Color(0x0000ff)}
        }
        ]
    )

将ShaderMaterial灯光参数设置为true。例如。

material = new THREE.ShaderMaterial(
        {
          uniforms : uniforms,
          vertexShader : vertexShader,
          fragmentShader : fragmentShader,
          lights: true
        });

现在,在您的着色器中,您将可以使用轻型制服:

uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];
uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];

HERE is an example我用点灯做了 Here are some other experiments我一直在使用three.js中的着色器。

<强>更新

我有一个顶点位移演示HERE。您可以通过单击&#34; source&#34;轻松查看着色器代码。在dat.gui中。它使用噪声作为位移,你可以忽略它,只使用你的纹理值。

如果您在Chrome浏览器中进行测试,它实际上会在控制台中提供相当不错的错误消息。

<强>更新
合并轻型制服和使用纹理似乎存在问题,概述为HERE

相关问题