2014-08-29 63 views
1

我写了一个自定义着色器,用于添加到现有的Three.js着色器中。目前我已经用相对简单的顶点和片段着色器定义了着色器材质。着色器本身会更改对象上的特定颜色。修改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

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

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;