Three.js ThreeJS:如何使自定义着色器由场景照亮';什么灯?

Three.js ThreeJS:如何使自定义着色器由场景照亮';什么灯?,three.js,Three.js,我使用THREE.ShaderMaterial制作了一个简单的自定义着色器,该着色器仅使用高度贴图更改平面的形状 有人知道使用场景的平行光源和非常简单的自定义着色器的正确方法吗 编辑 顶点着色器 uniform sampler2D heightTexture; varying float displacement; varying vec2 vUv; varying vec3 vPosition; varying vec3 vNormal; void main() { vUv = uv

我使用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;
}
均匀二维纹理;
均匀vec3点光源颜色[最大点光源];
均匀vec3点光源位置[最大点光源];
均匀浮动点光距离[最大点光];
可变vec2 vUv;
可变vec3位置;
可变vec3 vNormal;
void main(){
vec4纹理=纹理2D(纹理,vUv);
vec4灯光=vec4(0.0,0.0,0.0,1.0);
对于(int i=0;i
我尝试使用点光源,因为我根本不能使用方向灯,即使我需要使用方向灯。在片段着色器中,如果我写入
gl\u FragColor=lights灯光是可见的,但如果我尝试类似于
gl\u FragColor=纹理*灯光的东西飞机变黑。如果我使用颜色而不是纹理,它也可以工作,但我需要使用纹理


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

通过将'THREE.UniformsLib['lights']与制服合并来包含所需的灯光制服。例如

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 ];
我用了聚光灯。
我一直在three.js中使用着色器

更新

我有一个顶点置换演示。通过单击dat.gui中的“source”,可以轻松查看着色器代码。它使用噪波进行置换,您可以忽略它,只使用纹理值

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

更新

合并浅色制服和使用纹理似乎有问题,我按照你的建议做了,飞机变黑了。此外,不再应用高度贴图。你有什么建议吗?我用gl_FragColor输出什么并不重要。如果我设置lights=true(甚至lights=false)并合并制服,则平面将变黑,并且没有高度贴图。如果不放置任何着色器代码,则很难为您提供帮助。在我发布的页面上有很多例子,包括置换贴图。当我合并灯光并尝试使用纹理时,我似乎也遇到了同样的问题。仍在调查:)这似乎是一个错误/问题