【发布时间】:2016-12-13 04:36:22
【问题描述】:
我正在尝试将带有 ShaderMaterial 的基本卡通阴影与 threejs 的内置阴影系统相结合(一些代码取自 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'
我正在使用使用 typescript 的 superpowers-game 引擎。它的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
【问题讨论】:
-
您确定像您正在做的那样将 ShaderChunks 直接添加到着色器字符串中会起作用吗?创建一个小提琴,以便更容易为您提供帮助
-
是的,着色器似乎已检出。它只会失败,我将收到Shadow 设置为true。我不确定模板字符串是否只是打字稿,但 ${} 只是连接一个变量。
-
再深入一点,这似乎是threejs版本的问题。我实际上在r68上。从那时起,关于
shaderChunk阴影的事情发生了变化。但是,问题是我需要添加一些其他块才能使其正常工作。 -
哦,如果您使用的是旧版本,那么示例 HERE 可能会有所帮助
-
对不起,我的错。我在寻找错误的文件。我在 r73,我发现出了什么问题。现在写一个答案。
标签: typescript three.js glsl