我编写了一个自定义着色器,旨在添加到现有的Three.js着色器中。目前我已经使用相对简单的顶点和片段着色器定义了着色器材质。着色器本身会更改对象上的特定颜色。
然而,正如现在所写,这些颜色不会与光相互作用。为了解决这个问题,我希望将我的代码注入到现有Three.js材料(即Phong和/或Lambert)的代码中。我尝试过几种不同的方法都没有成功。最有希望的方法似乎与这篇文章类似:
Replicating MeshLambertMaterial Using ShaderMaterial ignores textures
当我尝试实现此方法时,我的着色器无法编译。我发布了一个代码示例,但它实际上是一个乱码(从firefox的GLSL实时编辑器复制/粘贴约90%,所以我不认为它会提供非常丰富的信息)。我的主要问题是:
1)上述OP采用的方法是最佳选择吗?
2)找到three.js'Lambert / Phong Shader代码的最佳位置在哪里。我意识到自动生成了很大一部分,但是从firefox中复制/粘贴肯定不是最好的选择......
希望有人可以提供帮助。
答案 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;