You can defined and use your custom shader by using three-shader-material
element.
<three-shader-material id="custom-shader-1">
<three-vertex-shader>
uniform bool edge;
varying vec3 vNormal;
void main(void) {
vec3 pos = position;
if (edge) {
pos += normal * 0.04;
}
vNormal = normal;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
</three-vertex-shader>
<three-fragment-shader>
precision mediump float;
uniform vec3 lightDirection;
uniform sampler2D texture;
uniform vec4 edgeColor;
varying vec3 vNormal;
void main(void) {
if (edgeColor.a > 0.0) {
gl_FragColor = edgeColor;
}
else {
float diffuse = clamp(dot(vNormal, lightDirection), 0.0, 1.0);
vec4 smpColor = texture2D(texture, vec2(diffuse, 0.0));
gl_FragColor = smpColor;
}
}
</three-fragment-shader>
<three-shader-uniforms>
<three-shader-variable name="uDirLightPos" type="v3" value="new THREE.Vector3()"></three-shader-variable>
<three-shader-variable name="edgeColor" type="v4" value="new THREE.Vector4(0, 0, 0, 0)"></three-shader-variable>
<three-shader-variable name="edge" type="i" value="true"></three-shader-variable>
<three-shader-variable name="lightDirection" type="v3" value="new THREE.Vector3(0.577,0.577,0.577)"></three-shader-variable>
<three-shader-variable name="texture" type="t" value="THREE.ImageUtils.loadTexture('../images/toon.png')"></three-shader-variable>
</three-shader-uniforms>
</three-shader-material>
Although this material can be used in a three-mesh
element as usual, I recomend you to use a ref
attribute in a three-material
element in order for readability. The ref
attribute refers other three-material
element and its material by ID.
<three-canvas width="200" height="200" antialias="true" clear-color="#000000" default-light="true">
<three-camera position="0,0,8" look-at="0,0,0" controls="orbit"></three-camera>
<three-mesh>
<three-material ref="custom-shader-1"></three-material>
<three-torus-geometry radius="0.5" tube="0.3"></three-torus-geometry>
</three-mesh>
</three-canvas>