我试图将一个基本的香椿阴影ShaderMaterial
与三个'内置在影子系统中(某些代码是从here获取和修改的)。从我在网上找到的内容中,我发现我在宣布制服,顶点和片段部分时应该使用ShaderChunks
。我这样做了,每当我将Mesh的recieveShadow
属性设置为true时,我都会收到错误。以下是我遇到的错误:
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'
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'
我正在使用超级大国游戏引擎,它使用的是打字稿。它的threejs插件目前在r73上。这是我的代码(仍然有点凌乱,我只是想在抛光之前完成所有工作):
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 );
//was: "float diffuse = max( dot( normal, lVector ), 0.0);",
// solution
float diffuse = dot( normal, lVector );
if ( diffuse > 0.5 ) { diffuse = 1.0; }
//else { diffuse = 0.5; };
else if ( diffuse > -0.2 ) { diffuse = 0.7; }
else { diffuse = 0.6; }
//gl_FragColor = vec4( uMaterialColor.rgb, 1.0 );
gl_FragColor = vec4( uKd * uMaterialColor * uDirLightColor * diffuse, 1.0 );
${ THREE.ShaderChunk[ "shadowmap_fragment" ] }
}
`
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; // Probably not needed
shader.needsUpdate = true; // Probably not needed either
var mesh = new THREE.Mesh( sphere, shader );
mesh.castShadow = true;
mesh.receiveShadow = true; // The culprit
( <any>this.actor ).__inner.threeObject.add( mesh ); // Ignore this
答案 0 :(得分:1)
好的,我经过一番挖掘后得到了它。如果您使用的是更新版本,那么很多内容都无关紧要,但这里是现在更正的代码:
const IslandVertexShader = `
varying vec3 vNormal;
varying vec3 vViewPosition;
varying vec2 vUv;
${ THREE.ShaderChunk[ "shadowmap_pars_vertex" ] }
void main() {
${ THREE.ShaderChunk[ "begin_vertex" ] }
vNormal = normalize( normalMatrix * normal );
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
vViewPosition = -mvPosition.xyz;
vUv = uv;
${ THREE.ShaderChunk[ "worldpos_vertex" ] }
${ 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;
vec3 shadowMask = vec3( 1.0 );
${ 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 );
//was: "float diffuse = max( dot( normal, lVector ), 0.0);",
// solution
float diffuse = dot( normal, lVector );
if ( diffuse > 0.5 ) { diffuse = 1.0; }
//else { diffuse = 0.5; };
else if ( diffuse > -0.2 ) { diffuse = 0.7; }
else { diffuse = 0.6; }
${ THREE.ShaderChunk[ "shadowmap_fragment" ] }
//gl_FragColor = vec4( shadowMask, 1.0 );
gl_FragColor = vec4( shadowMask * uKd * uMaterialColor * uDirLightColor * diffuse, 1.0 );
}
`
我需要添加begin_vertex
和worldpos_vertex
块并在片段着色器中定义vec3 shadowMask,并在计算最终gl_FragColor
时使用它。我通过检查BasicMaterial
着色器在threejs r73提交(link here)中的工作原理来获取此信息。