WebGL自定义阴影贴图着色器代码无法正常工作

时间:2015-04-11 21:12:56

标签: webgl shader shadow

我已经在互联网上看到了不同的阴影贴图方法,但我只看到一种方法来映射由点光源投射的阴影,即立方体映射。即使我听说过它,我也从未见过它的实际解释。

在我听说过立方体映射之前,我开始编写这段代码。我使用此代码的目的是将阴影深度从球面坐标映射到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>

0 个答案:

没有答案