在THREE.JS中合并着色器

5
我正在编写一个着色器来从高度图渲染地形,一切都进行得很顺利,但是在我有了我的着色器之后,我失去了光照和阴影。这就是问题开始的地方。事实证明我应该使用THREE.ShaderChunk来添加默认着色器块,但不仅仅是添加——还要修改我的着色器。
因此,经过长时间的谷歌搜索,我找到了这个建议

你只需要在适当的位置将几个片段添加到自定义ShaderMaterial中:

// uniforms

THREE.UniformsLib[ "shadowmap" ],

// fragment shader

THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "shadowmap_fragment" ],

// vertex shader

THREE.ShaderChunk[ "shadowmap_pars_vertex" ], THREE.ShaderChunk[ "shadowmap_vertex" ],

但对我来说,这并没有添加光照和阴影。然后我能想到的最好的办法是查看ShaderLib.js并尝试使用其中一个默认着色器的设置。所以我使用了lambert的设置,最终得到了这段代码:
        @tileMaterial = new THREE.ShaderMaterial
        uniforms:  THREE.UniformsUtils.merge [
            THREE.UniformsLib[ "common" ],
            THREE.UniformsLib[ "fog" ],
            THREE.UniformsLib[ "lights" ],
            THREE.UniformsLib[ "shadowmap" ],

            {
                "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
                "wrapRGB"  : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
            }

        ]
        vertexShader: [
            "#define LAMBERT",

            "varying vec3 vLightFront;",

            "#ifdef DOUBLE_SIDED",

            "   varying vec3 vLightBack;",

            "#endif",

            THREE.ShaderChunk[ "common" ],
            THREE.ShaderChunk[ "map_pars_vertex" ],
            THREE.ShaderChunk[ "lightmap_pars_vertex" ],
            THREE.ShaderChunk[ "envmap_pars_vertex" ],
            THREE.ShaderChunk[ "lights_lambert_pars_vertex" ],
            THREE.ShaderChunk[ "color_pars_vertex" ],
            THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
            THREE.ShaderChunk[ "skinning_pars_vertex" ],
            THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
            THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],

            "void main() {",

                THREE.ShaderChunk[ "map_vertex" ],
                THREE.ShaderChunk[ "lightmap_vertex" ],
                THREE.ShaderChunk[ "color_vertex" ],

                THREE.ShaderChunk[ "morphnormal_vertex" ],
                THREE.ShaderChunk[ "skinbase_vertex" ],
                THREE.ShaderChunk[ "skinnormal_vertex" ],
                THREE.ShaderChunk[ "defaultnormal_vertex" ],

                THREE.ShaderChunk[ "morphtarget_vertex" ],
                THREE.ShaderChunk[ "skinning_vertex" ],
                THREE.ShaderChunk[ "default_vertex" ],
                THREE.ShaderChunk[ "logdepthbuf_vertex" ],

                THREE.ShaderChunk[ "worldpos_vertex" ],
                THREE.ShaderChunk[ "envmap_vertex" ],
                THREE.ShaderChunk[ "lights_lambert_vertex" ],
                THREE.ShaderChunk[ "shadowmap_vertex" ],

            "}"

        ].join "\n"
        fragmentShader: [
            "uniform vec3 diffuse;",
        "uniform vec3 emissive;",
        "uniform float opacity;",

        "varying vec3 vLightFront;",

        "#ifdef DOUBLE_SIDED",

        "   varying vec3 vLightBack;",

        "#endif",

        THREE.ShaderChunk[ "common" ],
        THREE.ShaderChunk[ "color_pars_fragment" ],
        THREE.ShaderChunk[ "map_pars_fragment" ],
        THREE.ShaderChunk[ "alphamap_pars_fragment" ],
        THREE.ShaderChunk[ "lightmap_pars_fragment" ],
        THREE.ShaderChunk[ "envmap_pars_fragment" ],
        THREE.ShaderChunk[ "fog_pars_fragment" ],
        THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
        THREE.ShaderChunk[ "specularmap_pars_fragment" ],
        THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],

        "void main() {",

        "   vec3 outgoingLight = vec3( 0.0 );",
        "   vec4 diffuseColor = vec4( diffuse, opacity );",

            THREE.ShaderChunk[ "logdepthbuf_fragment" ],
            THREE.ShaderChunk[ "map_fragment" ],
            THREE.ShaderChunk[ "color_fragment" ],
            THREE.ShaderChunk[ "alphamap_fragment" ],
            THREE.ShaderChunk[ "alphatest_fragment" ],
            THREE.ShaderChunk[ "specularmap_fragment" ],

        "   #ifdef DOUBLE_SIDED",


        "       if ( gl_FrontFacing )",
        "           outgoingLight += diffuseColor.rgb * vLightFront + emissive;",
        "       else",
        "           outgoingLight += diffuseColor.rgb * vLightBack + emissive;",

        "   #else",

        "       outgoingLight += diffuseColor.rgb * vLightFront + emissive;",

        "   #endif",

            THREE.ShaderChunk[ "lightmap_fragment" ],
            THREE.ShaderChunk[ "envmap_fragment" ],
            THREE.ShaderChunk[ "shadowmap_fragment" ],

            THREE.ShaderChunk[ "linear_to_gamma_fragment" ],

            THREE.ShaderChunk[ "fog_fragment" ],

        "   gl_FragColor = vec4( outgoingLight, diffuseColor.a );",

        "}"
        ].join "\n"
        attributes:
            height:
                type: "f"
                value: heightData
        wireframe: no

目前还未添加光影效果,同时也存在错误:

three.js:22804 WebGL: INVALID_VALUE: uniform3fv: no array
three.js:22804 WebGL: INVALID_VALUE: uniform3fv: no array

所以问题是 - 如何为自定义着色器(如r71)添加光照和阴影?
jsfiddle - http://jsfiddle.net/SET001/0wzqemks/2/

看看这里的链接,也许它们会有所帮助。 - 2pha
@2pha,这里只有各种着色器示例,但没有使用“THREE.ShaderChunk”将现有的threejs着色器添加到自定义着色器的内容。 - SET001
1个回答

1
在我的情况下,解决方案是将lights: yes添加到ShaderMaterial中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接