如何使自定义着色器在three.js中接收阴影

时间:2018-05-28 01:48:38

标签: three.js

原帖在这里https://discourse.threejs.org/t/please-help-me-find-the-error-in-my-shader/2924/7
似乎这是一项非常重要的工作,因为在three.js网站上缺少关于这个主题的文档和示例。

到目前为止,我可以使它呈现正确的图片,并且在@ Mugen87的亲切帮助下,它也可以投射阴影,但它仍然无法接收阴影。

这是上面链接中的最新代码,我在这里写,以便人们可以直接看到它,

var mat = new THREE.ShaderMaterial({
            uniforms: THREE.UniformsUtils.merge([
                THREE.UniformsLib.fog,
                THREE.UniformsLib.lights,
                THREE.UniformsLib.shadowmap,
                {
                    mapMain: {value: null},
                    mapGlow: {value: null}
                }
            ]),
            vertexShader: [
                "uniform vec4 offsetRepeat;",

                "varying vec3 vNormal;",
                "varying vec2 vUv;",

                "varying vec3 vViewPosition;",


                "varying vec3 fPosition;",
                "varying vec2 vUvM;",


                THREE.ShaderChunk.common,
                THREE.ShaderChunk.lights_pars_begin,
                THREE.ShaderChunk.shadowmap_pars_vertex,
                THREE.ShaderChunk.fog_pars_vertex,

                    // "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);",
                "void main(){",
                        // THREE.ShaderChunk.beginnormal_vertex,
                        // THREE.ShaderChunk.defaultnormal_vertex,
                        "vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);",
                        "vec4 worldPosition = modelMatrix * vec4(position, 1.0);",

                        "vViewPosition = - mvPosition.xyz;",

                        "vNormal = normalize( normalMatrix *normal );",

                        // "vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
                        // "vUvM = uv * offsetRepeat.zw + offsetRepeat.xy;",

                        "vUv = uv ;",
                        "vUvM = uv;",

                        "gl_Position = projectionMatrix * mvPosition;",

                        // THREE.ShaderChunk.begin_vertex,
                        // THREE.ShaderChunk.project_vertex,
                        // THREE.ShaderChunk.worldpos_vertex,
                        // //THREE.ShaderChunk.logdepthbuf_vertex,
                        // "fPosition = position;",
                        THREE.ShaderChunk.shadowmap_vertex,
                        THREE.ShaderChunk.fog_vertex,
                    "}"
            ].join("\n"),
            fragmentShader: [

                "uniform sampler2D mapMain;",
                "uniform sampler2D mapGlow;",

                THREE.ShaderChunk.common,
                THREE.ShaderChunk.bsdfs,
                THREE.ShaderChunk.packing,
                THREE.ShaderChunk.shadowmap_pars_fragment,
                THREE.ShaderChunk.fog_pars_fragment,

                // THREE.ShaderChunk.dithering_pars_fragment,
                // THREE.ShaderChunk.emissivemap_pars_fragment,
                // // THREE.ShaderChunk.lights_pars,
                THREE.ShaderChunk.lights_pars_begin,
                THREE.ShaderChunk.lights_pars_maps,
                // THREE.ShaderChunk.lights_phong_pars_fragment,
                // THREE.ShaderChunk.specularmap_pars_fragment,

                "varying vec3 vNormal;",
                "varying vec2 vUv;",
                "varying vec2 vUvM;",

                "varying vec3 vViewPosition;",


                "void main(){",

                    // "vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does
                    // "vec4 diffuseColor = vec4( diffuse, opacity );",

                    "vec4 mainColor = texture2D(mapMain, vUv);",
                    "vec3 glowColor = texture2D(mapGlow, vUvM).rgb;",
                    "vec3 glow = (1.0 - mainColor.a) * glowColor;",

                    // THREE.ShaderChunk.specularmap_fragment,
                    "vec3 normal = normalize( vNormal );",

                    // "vec3 viewerDirection = normalize( vViewPosition );",
                    "vec3 viewPosition = normalize( vViewPosition );",

                    "vec3 totalDiffuseLight = vec3( 0.0 );",
                    "vec3 totalSpecularLight = vec3( 0.0 );",

                    // directional lights

                    "#if NUM_DIR_LIGHTS > 0",

                        "vec3 dirDiffuse = vec3( 0.0 );",
                        "vec3 dirSpecular = vec3( 0.0 );",

                        "for( int i = 0; i < NUM_DIR_LIGHTS; i++ ) {",

                            "vec3 dirVector = directionalLights[ i ].direction;",
                            "vec3 dirHalfVector = normalize( dirVector + viewPosition );",

                            "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
                            "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",

                            // "float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, shininess ), 0.0 );",

                            "totalDiffuseLight += directionalLights[ i ].color * dirDiffuseWeight;",
                            // "totalSpecularLight += directionalLights[ i ].color * specular * dirSpecularWeight * dirDiffuseWeight;",

                        "}",

                    "#endif",

                    // THREE.ShaderChunk.lights_phong_fragment,
                    //THREE.ShaderChunk.lights_template,
                    THREE.ShaderChunk.lights_fragment_begin,
                    THREE.ShaderChunk.lights_fragment_maps,
                    THREE.ShaderChunk.lights_fragment_end, 
                    "gl_FragColor = vec4((mainColor.rgb + glow) * totalDiffuseLight, 1.0);",
                    // THREE.ShaderChunk.shadowmap_fragment,

                    // THREE.ShaderChunk.tonemapping_fragment,
                    // THREE.ShaderChunk.encodings_fragment,
                    // THREE.ShaderChunk.premultiplied_alpha_fragment,
                    // THREE.ShaderChunk.dithering_fragment,
                    THREE.ShaderChunk.fog_fragment,
                "}"
            ].join("\n")
        });

错误:

three.js:15911 Uncaught TypeError: Cannot read property 'direction' of 
undefined
at StructuredUniform.setValue (three.js:15911)
at StructuredUniform.setValue (three.js:15911)
at Function.WebGLUniforms.upload (three.js:16039)
at setProgram (three.js:23023)
at WebGLRenderer.renderBufferDirect (three.js:21797)
at renderObject (three.js:22556)
at renderObjects (three.js:22526)
at WebGLRenderer.render (three.js:22288)
at GameModel.update (main.js:1632)
at render (main.js:2555)

1 个答案:

答案 0 :(得分:0)

需要添加照明标志

var mat = new THREE.ShaderMaterial({             制服:...,             vertexShader:...,             fragmentShader:...,

        lights: true // add this,
        fog: true,
        transparent: true

});