我試圖用three.js製作汽車模型的材質,其中汽車的基礎顏色可以動態改變。這很容易通過更改我正在使用的MeshPhongMaterial的顏色屬性。 然後,我需要在頂部應用紋理,並認爲通過向材質的貼圖屬性添加圖像足夠簡單。 雖然結果並不是我期望的結果,但是地圖/紋理圖像也用顏色屬性設置的顏色着色。我希望它基本上覆蓋基本顏色。Three.js material texture and color
任何人都可以指向正確的方向嗎?
我試圖用three.js製作汽車模型的材質,其中汽車的基礎顏色可以動態改變。這很容易通過更改我正在使用的MeshPhongMaterial的顏色屬性。 然後,我需要在頂部應用紋理,並認爲通過向材質的貼圖屬性添加圖像足夠簡單。 雖然結果並不是我期望的結果,但是地圖/紋理圖像也用顏色屬性設置的顏色着色。我希望它基本上覆蓋基本顏色。Three.js material texture and color
任何人都可以指向正確的方向嗎?
這是一個完整的腳本塊。插入閱讀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。
您將需要一個自定義着色器 - 以及具有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」,除了這裏引用的區別。
嗨,我試着用上面的版本替換'map_fragment',但我仍然得到相同的結果(這是與透明度.png紋理)。我也嘗試過使用alpha通道的.tif和.dds,但是獲得了黑色素材。 – user1871801
我也試過gl_FragColor = texelColor來測試它,期待這個只顯示紋理並忽略顏色,但是這樣會產生一個錯誤。 – user1871801
任何一個工作示例的機會? :) – user1871801
你的冠軍,這工作完美。 – user1871801