2012-12-03 59 views
4

我試圖用three.js製作汽車模型的材質,其中汽車的基礎顏色可以動態改變。這很容易通過更改我正在使用的MeshPhongMaterial的顏色屬性。 然後,我需要在頂部應用紋理,並認爲通過向材質的貼圖屬性添加圖像足夠簡單。 雖然結果並不是我期望的結果,但是地圖/紋理圖像也用顏色屬性設置的顏色着色。我希望它基本上覆蓋基本顏色。Three.js material texture and color

任何人都可以指向正確的方向嗎?

回答

3

這是一個完整的腳本塊。插入閱讀three.js所

<script> 
THREE.ShaderChunk.map_fragment = [ 
    "#ifdef USE_MAP", 
     "vec4 texelColor = texture2D(map, vUv); /* NEWWW */", 
     "#ifdef GAMMA_INPUT", 
     "texelColor.xyz *= texelColor.xyz;", 
     "#endif", 
     "gl_FragColor.rgb = mix(gl_FragColor.rgb,texelColor.rgb,texelColor.a);", 
     "vec3 surfDiffuse = mix(diffuse,vec3(1,1,1),texelColor.a);", 
    "#else", 
     "vec3 surfDiffuse = diffuse;", 
    "#endif"].join('\n'); 
// now replace references to 'diffuse' with 'surfDiffuse' 
THREE.ShaderChunk.lights_phong_fragment = 
    THREE.ShaderChunk.lights_phong_fragment.replace(/\bdiffuse\b/gm,'surfDiffuse') 
THREE.ShaderLib.phong.fragmentShader = [ 
    "uniform vec3 diffuse;", 
    "uniform float opacity;", 
    "uniform vec3 ambient;", 
    "uniform vec3 emissive;", 
    "uniform vec3 specular;", 
    "uniform float shininess;", 
    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[ "lights_phong_pars_fragment" ], 
    THREE.ShaderChunk[ "shadowmap_pars_fragment" ], 
    THREE.ShaderChunk[ "bumpmap_pars_fragment" ], 
    THREE.ShaderChunk[ "normalmap_pars_fragment" ], 
    THREE.ShaderChunk[ "specularmap_pars_fragment" ], 
    "void main() {", 
     "gl_FragColor = vec4(vec3 (1.0), opacity);", 
     THREE.ShaderChunk[ "map_fragment" ], 
     THREE.ShaderChunk[ "alphatest_fragment" ], 
     THREE.ShaderChunk[ "specularmap_fragment" ], 
     THREE.ShaderChunk[ "lights_phong_fragment" ], 
     THREE.ShaderChunk[ "lightmap_fragment" ], 
     THREE.ShaderChunk[ "color_fragment" ], 
     THREE.ShaderChunk[ "envmap_fragment" ], 
     THREE.ShaderChunk[ "shadowmap_fragment" ], 
     THREE.ShaderChunk[ "linear_to_gamma_fragment" ], 
     THREE.ShaderChunk[ "fog_fragment" ], 
    "}" 
].join('\n'); 
</script> 

後立即瞭解了three.js所海防材料一點點 - 它不處理的亮點,我想的方式,但...無論什麼。如果你需要更復雜的話,我建議使用ShaderMaterial。

+1

你的冠軍,這工作完美。 – user1871801

0

您將需要一個自定義着色器 - 以及具有alpha通道(實質上是DDS格式)的紋理。如果您在three.js所源看,你會看到一個位的片段着色器代碼名爲「map_fragment」,看起來像這樣:

"#ifdef USE_MAP", 

     "#ifdef GAMMA_INPUT", 

      "vec4 texelColor = texture2D(map, vUv);", 
      "texelColor.xyz *= texelColor.xyz;", 

      "gl_FragColor = gl_FragColor * texelColor;", 

     "#else", 

      "gl_FragColor = gl_FragColor * texture2D(map, vUv);", 

     "#endif", 

    "#endif" 

正如你可以看到它的顏色乘以你的紋理貼圖(在那個點上是「gl_FragColor」)。相反,它聽起來像你希望你的地圖覆蓋在基本顏色的頂部,只是你畫了它(比如,鍍鉻保險槓和大燈)。

一個簡單的方法可能是通過改變「map_fragment」字符串的值來改變'phong'在實例化任何phong資料之前的工作方式。

而不是「gl_FragColor *(東西)」 - 試試這個作爲THREE.ShaderChunk.map_fragment的重新分配:

[ 

    "#ifdef USE_MAP", 

     "vec4 texelColor = texture2D(map, vUv);", 

     "#ifdef GAMMA_INPUT", 

      "texelColor.xyz *= texelColor.xyz;", 

     "#endif", 

     "gl_FragColor = vec4(mix(gl_FragColor.rgb,texelColor.rgb,texelColor.a),(gl_FragColor.a*texelColor.a));", 

    "#endif" 

].join('\n'); 

與重寫股法這種方法是,它適用危害到場景中的所有模型 - 繪製的紋理將覆蓋材質的顏色。如果沒關係,你就完成了。否則,你應該創建一個新的THREE.ShaderMaterial,就像「phong」,除了這裏引用的區別。

+0

嗨,我試着用上面的版本替換'map_fragment',但我仍然得到相同的結果(這是與透明度.png紋理)。我也嘗試過使用alpha通道的.tif和.dds,但是獲得了黑色素材。 – user1871801

+0

我也試過gl_FragColor = texelColor來測試它,期待這個只顯示紋理並忽略顏色,但是這樣會產生一個錯誤。 – user1871801

+0

任何一個工作示例的機會? :) – user1871801