Reputation: 127
I've written a custom shader intended to be added to an existing Three.js shader. Currently I've defined a Shader Material with relatively simple vertex and fragment shaders. The shader itself changes specific colors on an object.
As it's written right now, however, these colors don't interact with light. To fix this, I was hoping to inject my code into the code for existing Three.js Materials (namely, Phong and/or Lambert). I've tried a few different approaches all with no success. The most promising approach seems to be something similar to this post:
Replicating MeshLambertMaterial Using ShaderMaterial ignores textures
When I tried to implement this approach, my shaders wouldn't compile. I'd post a code sample, but it's really a garbled mess (~90% copy/pasted from firefox's GLSL live-editor, so I don't think it would be very informative). My primary questions are these:
1) Is the approach employed by the OP of the above the best choice?
2) Where is the best place to find three.js' Lambert/Phong Shader code. I realize that a huge portion is automatically generated, but surely copy/pasting from firefox isn't the best choice...
Hopefully someone can help.
Upvotes: 1
Views: 1641
Reputation: 252
I used the example you found and added texture blending to it.
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;
Upvotes: 1