2014-08-29 60 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;