As I work on combining a basic toon shaded ShaderMaterial
with threejs' built-in shadow system, I encountered some errors. It seems that when I set the Mesh's recieveShadow
property to true, I run into issues. The errors I am facing are:
Vertex Errors
THREE.WebGLShader: gl.getShaderInfoLog() vertex ERROR: 0:72: 'worldPosition' : undeclared identifier
ERROR: 0:72: 'assign' : cannot convert from 'mediump 4X4 matrix of float' to 'mediump 4-component vector of float'
Fragment Errors
THREE.WebGLShader: gl.getShaderInfoLog() fragment ERROR: 0:356: 'shadowMask' : undeclared identifier
ERROR: 0:356: 'assign' : cannot convert from 'mediump 3-component vector float' to 'float'
I am using the superpowers-game engine, which utilizes typescript and the threejs plugin version r73. Below is my code (still in progress):
Shaders
const IslandVertexShader = `
varying vec3 vNormal;
varying vec3 vViewPosition;
varying vec2 vUv;
${ THREE.ShaderChunk[ "shadowmap_pars_vertex" ] }
void main() {
vNormal = normalize( normalMatrix * normal );
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
vViewPosition = -mvPosition.xyz;
vUv = uv;
${ THREE.ShaderChunk[ "shadowmap_vertex" ] }
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
`
const IslandFragmentShader = `
uniform vec3 uMaterialColor;
uniform vec3 uDirLightPos;
uniform vec3 uDirLightColor;
uniform float uKd;
uniform float uBorder;
varying vec3 vNormal;
varying vec3 vViewPosition;
varying vec2 vUv;
${ THREE.ShaderChunk[ "shadowmap_pars_fragment" ] }
void main() {
// compute direction to light
vec4 lDirection = viewMatrix * vec4( uDirLightPos, 0.0 );
vec3 lVector = normalize( lDirection.xyz );
// diffuse: N * L. Normal must be normalized, since it's interpolated.
vec3 normal = normalize( vNormal );
float diffuse = dot( normal, lVector );
if ( diffuse > 0.5 ) { diffuse = 1.0; }
else if ( diffuse > -0.2 ) { diffuse = 0.7; }
else { diffuse = 0.6; }
gl_FragColor = vec4( uKd * uMaterialColor * uDirLightColor * diffuse, 1.0 );
${ THREE.ShaderChunk[ "shadowmap_fragment" ] }
}
`
Declaration
var sphere = new THREE.TorusKnotGeometry( 5, 1, 100, 16 );
var shader = new THREE.ShaderMaterial();
shader.uniforms = THREE.UniformsUtils.merge([THREE.UniformsLib["shadowmap"], {
uDirLightPos: { type: "v3", value: new THREE.Vector3(0, 10, 0) },
uDirLightColor: { type: "v3", value: new THREE.Vector3(1, 1, 1) },
uMaterialColor: { type: "v3", value: new THREE.Vector3(0.5, 1, 1) },
uKd: { type: "f", value: 1 }
}]);
shader.vertexShader = IslandVertexShader;
shader.fragmentShader = IslandFragmentShader;
shader.lights = true;
shader.needsUpdate = true;
var mesh = new THREE.Mesh(sphere, shader);
mesh.castShadow = true;
mesh.receiveShadow = true;
(<any>this.actor).__inner.threeObject.add(mesh); // Ignore this