Please help me find the error in my shader

I should have sleep now, but the code is not work, unfortunately.

This is my shader code, modifieied from https://github.com/mrdoob/three.js/issues/12355

        // after this.meshObj was loaded
        var outer = this.meshObj.getObjectByName("l_box005_01")
        outer.visible = false;
        this.flashObj = this.meshObj.getObjectByName("l_box005");

        var newMat = function() {
            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: [
                    "varying vec3 vNormal;",
                    "varying vec3 vViewPosition;",
                    "varying vec3 fPosition;",

                    "varying vec2 vUv;",
                    "varying vec2 vUvM;",
                    "uniform vec4 offsetRepeat;",

                    // THREE.ShaderChunk.common,
                    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,
                            "vUvM = uv * offsetRepeat.zw + offsetRepeat.xy;",
                            "vUv = uv;",
                            "vNormal = normalize( transformedNormal );",
                            THREE.ShaderChunk.begin_vertex,
                            THREE.ShaderChunk.project_vertex,
                            //THREE.ShaderChunk.logdepthbuf_vertex,
                            "fPosition = position;",
                            "vViewPosition = - mvPosition.xyz;",
                            THREE.ShaderChunk.worldpos_vertex,
                            THREE.ShaderChunk.shadowmap_vertex,
                            THREE.ShaderChunk.fog_vertex,
                        "}"
                ].join("\n"),
                fragmentShader: [
                    "uniform sampler2D mapMain;",
                    "uniform sampler2D mapGlow;",

                    THREE.ShaderChunk.common,
                    THREE.ShaderChunk.packing,
                    THREE.ShaderChunk.dithering_pars_fragment,
                    THREE.ShaderChunk.emissivemap_pars_fragment,
                    THREE.ShaderChunk.fog_pars_fragment,
                    THREE.ShaderChunk.bsdfs,
                    THREE.ShaderChunk.lights_pars,
                    THREE.ShaderChunk.lights_phong_pars_fragment,
                    THREE.ShaderChunk.shadowmap_pars_fragment,
                    THREE.ShaderChunk.specularmap_pars_fragment,

                    "uniform vec3 topColor;",
                    "uniform vec3 bottomColor;",
                    "varying vec2 vUv;",
                    "varying vec2 vUvM;",

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

                        THREE.ShaderChunk.lights_template,
                        "gl_FragColor = vec4(mainColor.rgb + glow, 1.0);",
                        // THREE.ShaderChunk.shadowmap_fragment,

                        THREE.ShaderChunk.tonemapping_fragment,
                        THREE.ShaderChunk.encodings_fragment,
                        THREE.ShaderChunk.fog_fragment,
                        THREE.ShaderChunk.premultiplied_alpha_fragment,
                        THREE.ShaderChunk.dithering_fragment,
                    "}"
                ].join("\n")
            });
            return mat;
        }
        this.flashObj.material = newMat(); 
        this.flashObj.material.needsUpdate = true;

        var loader = new THREE.TextureLoader();
        loader.load("resource/model/test/l_box005/l_box005_colour_1.tga", function(texture) {
            // set main texture, which has alpha channel
            this.flashObj.material.uniforms.mapMain.value = texture
            this.flashObj.material.needsUpdate = true;
            var self = this;
            var loader = new THREE.TextureLoader();
            loader.load("resource/model/test/l_box005/glow.png", function(texture) {
                this.flashObj.material.uniforms.mapGlow.value = texture
                this.flashObj.material.needsUpdate = true;
            }.bind(self))
        }.bind(this))

The result scene is black, no error show in console, please help me.
the shader logic is fine, ie, the logic of calculation final color , I haved tested in unity, so the wrong thing is related with three.js specific.

Some shader chunks you are using are not existing anymore. (see Migration Guide · mrdoob/three.js Wiki · GitHub)

It’s now:

THREE.ShaderChunk.lights_pars_begin
THREE.ShaderChunk.lights_pars_maps

It’s now:

THREE.ShaderChunk.lights_fragment_begin
THREE.ShaderChunk.lights_fragment_maps
THREE.ShaderChunk.lights_fragment_end

Maybe it’s better to work with the latest version of the phong shader implementation:

https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderLib/meshphong_vert.glsl
https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderLib/meshphong_frag.glsl

var outer = this.meshObj.getObjectByName("l_box005_01")
        outer.visible = false;
        this.flashObj = this.meshObj.getObjectByName("l_box005");
        // this.flashObj = outer;
        // this.flashObj.visible = false;
        // this.flashObj = outer;

        var youku = function() {
            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 totalDiffuseLight = vec3( 0.0 );",
                        "vec3 totalSpecularLight = vec3( 0.0 );",

                        // directional lights

                        // "#if NUM_DIR_LIGHTS > 0",

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

                        //         "vec3 dirVector = directionalLights[ i ].direction;",

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


                        //         "totalDiffuseLight += directionalLights[ i ].color * 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, 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")
            });
            return mat;
        }
        // return;
        this.flashObj.material = youku(); 
        this.flashObj.material.needsUpdate = true;

        console.log("Start load texture l_box005")
        // var loader = new THREE.TextureLoader();
        var loader = new THREE.TGALoader();
        loader.load("resource/model/test/l_box005/l_box005_colour_1.tga", function(texture) {
            console.log("tga loaded:", texture)
            console.log("tga loaded:", this.flashObj)
            this.flashObj.material.uniforms.mapMain.value = texture
            this.flashObj.material.needsUpdate = true;
            var self = this;
            var loader = new THREE.TextureLoader();
            loader.load("resource/model/test/l_box005/88会员_渐变.png", function(texture) {
                console.log("png loaded:", texture)
                console.log("tga loaded:", this.flashObj)
                this.flashObj.material.uniforms.mapGlow.value = texture
                this.flashObj.material.needsUpdate = true;
            }.bind(self), undefined, function(e) {
                console.log(e);
            })
        }.bind(this), undefined, function(e) {
            console.log(e)
        })
    }

Mugen, I updated my shader code, then scene render ok, but my flashObj is not cast any shadow

1 Like

Does it work if you set this.flashObj.castShadow to true?

Oh yeah, It works, thanks so much!

One more thing left, I want it receive shadaow too, so I set this.flashObj.receiveShadow = true, but three.js throw me some error:

three.js:15553 Uncaught TypeError: Cannot read property 'toArray' of undefined
at flatten (three.js:15553)
at PureArrayUniform.setValueM4a [as setValue] (three.js:15807)
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:1616)
at render (main.js:2539)

Is there some thing more I need to do to make it receive shadow ?

The following fragment does not exist anymore THREE.ShaderChunk.shadowmap_fragment. Does it work if you remove it from your code?

No, It doesn’t work

I can find an example in three.js https://github.com/mrdoob/three.js/blob/dev/examples/js/ShaderTerrain.js
it seems I need calculate the light proportion, so it can receive shadow.
I modified my shader code to this, and get some error:

                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")
            });

The error is this:

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)

I can see some shadow received by my flashObj, but the error makes the object not render correctly.