在Three.js中调整现有着色器

时间:2014-08-29 02:47:18

标签: javascript three.js glsl shader

我编写了一个自定义着色器,旨在添加到现有的Three.js着色器中。目前我已经使用相对简单的顶点和片段着色器定义了着色器材质。着色器本身会更改对象上的特定颜色。

然而,正如现在所写,这些颜色不会与光相互作用。为了解决这个问题,我希望将我的代码注入到现有Three.js材料(即Phong和/或Lambert)的代码中。我尝试过几种不同的方法都没有成功。最有希望的方法似乎与这篇文章类似:

Replicating MeshLambertMaterial Using ShaderMaterial ignores textures

当我尝试实现此方法时,我的着色器无法编译。我发布了一个代码示例,但它实际上是一个乱码(从firefox的GLSL实时编辑器复制/粘贴约90%,所以我不认为它会提供非常丰富的信息)。我的主要问题是:

1)上述OP采用的方法是最佳选择吗?

2)找到three.js'Lambert / Phong Shader代码的最佳位置在哪里。我意识到自动生成了很大一部分,但是从firefox中复制/粘贴肯定不是最好的选择......

希望有人可以提供帮助。

1 个答案:

答案 0 :(得分:1)

我使用了你找到的例子并添加了纹理混合。

material = new THREE.ShaderMaterial(
    {
        uniforms: THREE.UniformsUtils.merge(
        [
            THREE.UniformsLib['lights'],
            THREE.UniformsLib[ "common" ],
            THREE.UniformsLib[ "fog" ],
            THREE.UniformsLib[ "lights" ],
            THREE.UniformsLib[ "shadowmap" ],
        {
            t0: { type: "t", value: null},
            t1: { type: "t", value: null},
            blendMap: { type: "t", value: null},
            repeat: { type:'f', value: 35 },
            topColor:    { type: "c", value: new THREE.Color( 0x0077ff ) },
            bottomColor: { type: "c", value: new THREE.Color( 0xffffff ) },
            offset:      { type: "f", value: 33 },
            exponent:    { type: "f", value: 0.6 },
            fogColor:    { type: "c", value: scene.fog.color },
            fogNear:     { type: "f", value: scene.fog.near },
            fogFar:      { type: "f", value: scene.fog.far }
        }
        ]), 
        lights: true,
        fog: true,
        vertexShader: 
        [

            "#define LAMBERT",

            "varying vec3 vLightFront;",

            "varying vec2 vUv;",

            "#ifdef DOUBLE_SIDED",

            "varying vec3 vLightBack;",

            "#endif",

            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" ],

            "void main() {",
                "vUv = uv;",

                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[ "worldpos_vertex" ],
                THREE.ShaderChunk[ "envmap_vertex" ],
                THREE.ShaderChunk[ "lights_lambert_vertex" ],
                THREE.ShaderChunk[ "shadowmap_vertex" ],
            "}"

        ].join("\n"),
        fragmentShader: 
        [

            "uniform float opacity;",

            "varying vec3 vLightFront;",

            "#ifdef DOUBLE_SIDED",

                "varying vec3 vLightBack;",

            "#endif",

            "uniform sampler2D t0;",
            "uniform sampler2D t1;",
            "uniform sampler2D blendMap;",
            "uniform float repeat;",
            "varying vec2 vUv;",

            THREE.ShaderChunk[ "color_pars_fragment" ],
            THREE.ShaderChunk[ "map_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" ],



            "void main() {",
                "gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",

                "vec3 c;",
                "vec4 Ca = texture2D(t0, vUv * repeat);",
                "vec4 Cb = texture2D(t1, vUv * repeat);",
                "vec4 b = texture2D(blendMap, vUv);",
                THREE.ShaderChunk[ "map_fragment" ],
                THREE.ShaderChunk[ "alphatest_fragment" ],
                THREE.ShaderChunk[ "specularmap_fragment" ],

                "#ifdef DOUBLE_SIDED",

                    "float isFront = float( gl_FrontFacing );",
                    "gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;",

                    "if ( gl_FrontFacing )",
                        "gl_FragColor.xyz *= vLightFront;",
                    "else",
                        "gl_FragColor.xyz *= vLightBack;",

                "#else",

                    "gl_FragColor.xyz *= vLightFront;",

                "#endif",


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

                "gl_FragColor *= vec4(mix(Ca.rgb, Cb.rgb, b.r),0);",
                THREE.ShaderChunk[ "linear_to_gamma_fragment" ],

                THREE.ShaderChunk[ "fog_fragment" ],

            "}"

        ].join("\n")


    });

    material.uniforms.t0.value = texture1;
    material.uniforms.t1.value = texture2;
    material.uniforms.blendMap.value = 
    ImageLoad("land/land"+landx+"_blendmap.png" );

    material.uniforms.t0.value.wrapS = material.uniforms.t0.value.wrapT = THREE.RepeatWrapping;
    material.uniforms.t1.value.wrapS = material.uniforms.t1.value.wrapT = THREE.RepeatWrapping;