我已经在互联网上看到了不同的阴影贴图方法,但我只看到一种方法来映射由点光源投射的阴影,即立方体映射。即使我听说过它,我也从未见过它的实际解释。
在我听说过立方体映射之前,我开始编写这段代码。我使用此代码的目的是将阴影深度从球面坐标映射到2D纹理。
我现在已经简化了片段的着色,以便更好地可视化正在发生的事情。
但是,基本上模型是在坐标(0.0,0.0,-5.0)处的半径为2.0的球体和在(0.0,0.0,-2.0)处的高度为1.0的双曲面,光源位于(0.0,0.0,8.0) )。
如果我通过小于9.6的反比因子缩放(在代码中写入)深度值,它们都显示为环境颜色的完全着色。大于9.6,它们慢慢变得正常纹理。我试图在jsfiddle中做一个例子,但我无法使纹理起作用。
这种方法不能一起工作,我迷路了。
<script id="shadow-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
varying float vDepth;
uniform vec3 uLightLocation;
uniform mat4 uMMatrix;
void main(void){
const float I_PI = 0.318309886183790671537767; //Inverse pi
vec4 aPos = uMMatrix * vec4(aVertexPosition, 1.0); //The actual position of the vertex
vec3 position = aPos.xyz - uLightLocation; //The position of the vertex relative to the light source i.e. "the vector"
float len = length(position);
float theta = 2.0 * acos(position.y/len) * I_PI - 1.0; //The angle of the vector from the xz plane bound between -1 and 1
float phi = atan(position.z, position.x) * I_PI; //The angle of the vector on the xz plane bound between -1 and 1
vDepth = len; //Divided by some scale. The depth of the vertex from the light source
gl_Position = vec4(phi, theta, len, 1.0);
}
</script>
<script id="shadow-fs" type="x-shader/x-fragment">
precision mediump float;
varying float vDepth;
void main(void){
gl_FragColor = vec4(vDepth, 0.0, 0.0, 1.0); //Records the depth in the red channel of the fragment color
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat4 uMMatrix;
uniform mat3 uNMatrix;
varying vec2 vTextureCoord;
varying vec3 vTransformedNormal;
varying vec4 vPosition;
varying vec4 aPos;
void main(void) {
aPos = uMMatrix * vec4(aVertexPosition, 1.0); //The actual position of the vertex
vPosition = uMVMatrix * uMMatrix * vec4(aVertexPosition, 1.0);
gl_Position = uPMatrix * vPosition;
vTextureCoord = aTextureCoord;
vTransformedNormal = normalize(uNMatrix * mat3(uMMatrix) * aVertexNormal);
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTextureCoord;
varying vec3 vTransformedNormal;
varying vec4 vPosition;
varying vec4 aPos;
uniform sampler2D uSampler;
uniform sampler2D uShSampler;
uniform vec3 uLightLocation;
uniform vec3 uAmbientColor;
uniform vec4 uLightColor;
void main(void) {
const float I_PI = 0.318309886183790671537767;
vec3 position = aPos.xyz - uLightLocation; //The position of the vertex relative to the light source i.e. "the vector"
float len = length(position);
float theta = acos(position.y/len) * I_PI; //The angle of the vector from the xz axis bound between 0 and 1
float phi = 0.5 + 0.5 * atan(position.z, position.x) * I_PI; //The angle of the vector on the xz axis bound between 0 and 1
float posDepth = len; //Divided by some scale. The depth of the vertex from the light source
vec4 shadowMap = texture2D(uShSampler, vec2(phi, theta)); //The color at the texture coordinates of the current vertex
float shadowDepth = shadowMap.r; //The depth of the vertex closest to the light source
if (posDepth > shadowDepth){ //Check if this vertex is further away from the light source than the closest vertex
gl_FragColor = vec4(uAmbientColor, 1.0);
}
else{
gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
}
}
</script>