Double paraboloid shadow display

I am using OpenGL 4.0, GLSL 4.0, not GLEW or the like, not GLU or the like, not GLUT or the like. OpenCL or CUDA are also used, but they are not involved in this case.

I tried to solve my problem for several weeks without success, and now I hope that someone who has experience with double paraboloid shadow imaging can give me advice. Go straight to the problem and check out some snapshots (Figure 1):

Picture_1

1 , . , . : , , , , / . , ( , ). , ( 1):

"swap.z=-sign(swap.z)*swap.z;\n" //mostly right results in the main project, but wrong way

GLSL- , , , . , , 4 . 1 DPSM, , . , , ( 2 2):

Picture_2

"swap.z=sign(swap.z)*swap.z;\n" //almost dark picture, wrong way

, , ( 3 3):

Picture_3

"swap.z=-(teDistance-n)/(f-n);\n" //lightning is mainly working but no shadows, should be the right way

, , , () , ( 4 4):

Picture_4

"swap.z=(teDistance-n)/(f-n);\n" //almost dark picture, doesn't work in the main project, but works in the test program, right way

- , , , , " ", , , . , , , SHADOW_EPSILON = 0.000005f ( 5):

Picture_5

, Windows 7.1, nVIDIA GeForce GT 525M AMD Radeon R6. . - Visual Studio 2010. , , OpenGL.

, , , . , , , 1-5, , . . :

    static const char *vertex1=
"#version 400 core\n"

"layout (location=1) in vec3 vertexLocation;\n"

"out vec3 vPosition;\n"

"void main() {\n"
    "vPosition=vertexLocation;\n"
"}\0";




static const char *tessIn1=
"#version 400 core\n"

"layout (vertices=3) out;\n"

"in vec3 vPosition[];\n"
"out vec3 tcPosition[];\n"

"void main() {\n"
    "tcPosition[gl_InvocationID]=vPosition[gl_InvocationID];\n"
    "if (gl_InvocationID==0) {\n"

        "gl_TessLevelOuter[0]=max(distance(vPosition[1], vPosition[2]), 1.0);\n"
        "gl_TessLevelOuter[1]=max(distance(vPosition[2], vPosition[0]), 1.0);\n"
        "gl_TessLevelOuter[2]=max(distance(vPosition[0], vPosition[1]), 1.0);\n"
        "gl_TessLevelInner[0]=max(0.33*(gl_TessLevelOuter[0]+gl_TessLevelOuter[1]+gl_TessLevelOuter[2]), 1.0);\n"

    "}\n"
"}\0";


static const char* tessOut1=
"#version 400 core\n"

"layout(triangles, equal_spacing, ccw) in;\n"

"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 lightOrientation;\n"

"in vec3 tcPosition[];\n"
"out float teDistance;\n"
"out float teClip;\n"

"const float n=0.5;\n"
"const float f=20000.0;\n"

"void main() {\n"

    "vec3 accum=vec3(0.0);\n"
    "accum=accum+gl_TessCoord.x*tcPosition[0];\n"
    "accum=accum+gl_TessCoord.y*tcPosition[1];\n"
    "accum=accum+gl_TessCoord.z*tcPosition[2];\n"

// Transform position to the paraboloid view space
    "vec4 swap=lightOrientation*model*vec4(accum, 1.0);\n"

//store the distance and other variables
    "teDistance=abs(swap.z);\n"
    "teClip=swap.z;\n"

//calculate and set X and Y coordinates
    "swap.xyz=normalize(swap.xyz);\n"
    "if (swap.z<=0.0) {\n"
        "swap.xy=swap.xy/(1.0-swap.z);\n"
    "} else {\n"
        "swap.xy=swap.xy/(1.0+swap.z);\n"
    "}\n"

//calculate and set Z and W coordinates
//  "swap.z=-sign(swap.z)*swap.z;\n"  //Wrong way
//  "swap.z=sign(swap.z)*swap.z;\n"  //Wrong way
//  "swap.z=-(teDistance-n)/(f-n);\n"      //Wrong way
    "swap.z=(teDistance-n)/(f-n);\n"      //Right way
    "swap.w=1.0;\n"

    "gl_Position=swap;\n"
"}\0";


static const char* geometry1=
"#version 400 core\n"

"layout(triangles) in;\n"
"layout(triangle_strip, max_vertices=3) out;\n"

"in float teDistance[];\n"
"in float teClip[];\n"
"out float gDistance;\n"

"void main() {\n"
    "for (int i=0; i<3; i++) {\n"
        "gDistance=teDistance[i];\n"
        "if (teClip[i]<=0.0) {\n"
            "gl_Layer=0;\n"
        "} else {\n"
            "gl_Layer=1;\n"
        "}\n"
        "gl_Position=gl_in[i].gl_Position;\n"
        "EmitVertex();\n"
    "}\n"
    "EndPrimitive();\n"
"}\0";


static const char* fragment1=
"#version 400 core\n"

"in float gDistance;\n"

"out vec2 fragmentVari;\n"

"void main() {\n"

    "fragmentVari=vec2(gDistance, gDistance*gDistance);\n"

"}\0";


const char *vertex2=
"#version 400 core\n"

"layout (location=1) in vec3 vertexPosition;\n"
"layout (location=2) in vec2 vertexTexCoord;\n"
"layout (location=3) in vec3 vertexNormal;\n"

"const float n=0.5;\n"
"const float f=20000.0;\n"

"uniform vec4 colour;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 normal;\n"
"uniform mat4 projection;\n"
"uniform mat4 lightOrientation;\n"

"out vec2 texKoord;\n"
"out vec3 pointNormal;\n"
"out vec3 point;\n"
"out vec4 color;\n"
"out vec4 vOriginPoint;\n"

"void main() {\n"
    "texKoord=vertexTexCoord;\n"
    "pointNormal=normalize(vec3(normal*vec4(vertexNormal, 1.0)));\n"
    "point=vec3(model*vec4(vertexPosition, 1.0));\n"
    "color=colour;\n"
    "vOriginPoint=vec4(vertexPosition, 1.0);\n"
    "gl_Position=projection*view*model*vec4(vertexPosition, 1.0);\n"
"}\0";


const char *fragment2=
"#version 400 core\n"

"uniform sampler2DArray tex1;\n"

"uniform vec4 colour;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 normal;\n"
"uniform mat4 projection;\n"
"uniform mat4 lightOrientation;\n"

"in vec2 texKoord;\n"
"in vec3 pointNormal;\n"
"in vec3 point;\n"
"in vec4 color;\n"
"in vec4 vOriginPoint;\n"
"out vec4 fragmentColor;\n"

"const float SHADOW_EPSILON = 0.05f;\n"
"const vec3 Ka=vec3(0.05, 0.05, 0.05);\n"  //Ambient reflectivity
"const vec3 Kd=vec3(1.0, 1.0, 1.0);\n"  //Diffuse reflectivity
"const float At=0.4;\n"                 //Light attenuation

"vec3 ads(in vec3 position, in vec3 normal) {\n"
    "vec3 l=vec3(lightOrientation*model*vOriginPoint);\n"
    "vec3 s=normalize(l - position);\n"
    "vec3 intensity=vec3(0.5, 0.5, 0.5)*10.0;\n"
    "float attenuation=1.0/(1.0+At*max(length(l), 1.0));\n"
    "intensity=intensity*attenuation*Kd*abs(dot(s, normal));\n"
    "return intensity;\n"
"}\n"

"float drawShadow() {\n"
    "vec3 texKoord;\n"
    "vec4 textureDepth;\n"

    "vec4 originPoint=vec4(lightOrientation*model*vOriginPoint);\n"
    "float distance=abs(originPoint.z);\n"
    "vec3 normalized=normalize(originPoint.xyz);\n"

    "if (normalized.z<=0.0) {\n"
        "texKoord.xy=normalized.xy/(1.0-normalized.z);\n"
        "texKoord.xy=0.5*texKoord.xy+0.5;\n"
        "texKoord.z=0.0;\n"
        "textureDepth=texture(tex1, texKoord);\n"
    "} else {\n"
        "texKoord.xy=normalized.xy/(1.0+normalized.z);\n"
        "texKoord.xy=0.5*texKoord.xy+0.5;\n"
        "texKoord.z=1.0;\n"
        "textureDepth=texture(tex1, texKoord);\n"
    "}\n"

    "if (textureDepth.x+SHADOW_EPSILON>=distance) {\n"
        "return 1.0;\n"
    "} else {\n"
        "return 0.0;\n"
    "}\n"
"}\n"

"void main() {\n"
    "vec4 lightning=vec4(Ka, 1.0);\n"
    "swap2=swap2*drawShadow();\n"
    "lightning=lightning+swap2;\n"
    "fragmentColor=color*lightning;\n"
"}\0";


const char *vertexLight=
"#version 400 core\n"

"layout (location=1) in vec3 vertexPosition;\n"

"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"uniform mat4 lightOrientation;\n"

"void main() {\n"
    "gl_Position=projection*view*lightOrientation*vec4(vertexPosition, 1.0);\n"
"}\0";


const char *fragmentLight=
"#version 400 core\n"

"out vec4 fragmentColor;\n"

"void main() {\n"
    "fragmentColor=vec4(1.0, 1.0, 1.0, 1.0);\n"
"}\0";

:

void TForm1::display()
{
    GLuint loc1, loc2, loc3, loc4, loc5, loc6;
    float swap[16];
    float normal[16]={0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0};

//first we render a shadow map
    {
        glUseProgram(shaderT1);
        glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer[0]);
        glClearColor(20000.0f, 0.0f, 0.0f, 0.0f);
        glDepthMask(GL_TRUE);
        glDepthRange(0, 1);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glViewport(0, 0, textureDim.x, textureDim.y);
        glPatchParameteri(GL_PATCH_VERTICES, 3);
        loc1=glGetUniformLocation(shaderT1, "model\0");
        loc2=glGetUniformLocation(shaderT1, "lightOrientation\0");
        loc3=glGetUniformLocation(shaderT1, "view\0");
        swap[0]=1.0; swap[1]=0.0; swap[2]=0.0; swap[3]=0.0;
        swap[4]=0.0; swap[5]=1.0; swap[6]=0.0; swap[7]=0.0;
        swap[8]=0.0; swap[9]=0.0; swap[10]=1.0; swap[11]=0.0;
        swap[12]=-lightMatrix[12]; swap[13]=-lightMatrix[13]; swap[14]=-lightMatrix[14]; swap[15]=1.0;
        glUniformMatrix4fv(loc1, 1, GL_FALSE, triangleMatrix);
        glUniformMatrix4fv(loc2, 1, GL_FALSE, swap);
        glUniformMatrix4fv(loc3, 1, GL_FALSE, view);
        glBindVertexArray(VAO[1]);
        glDrawArrays(GL_PATCHES, 0, 3);
        glUniformMatrix4fv(loc1, 1, GL_FALSE, identity);
        glUniformMatrix4fv(loc2, 1, GL_FALSE, swap);
        glUniformMatrix4fv(loc3, 1, GL_FALSE, view);
        glBindVertexArray(VAO[0]);
        glDrawArrays(GL_PATCHES, 0, 6);
    }

//then we render the world and make use of that rendered shadow map
    {
        glUseProgram(shaderT2);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glDepthMask(GL_TRUE);
        glDepthRange(0, 1);
        glClearColor(0.0f, 1.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glUniform1i(glGetUniformLocation(shaderT2, "tex1"), 1);
        glActiveTexture(GL_TEXTURE0+1);
        glBindTexture(GL_TEXTURE_2D_ARRAY, texID[0]);
        glViewport(0, 0, 512, 512);
        loc1=glGetUniformLocation(shaderT2, "model\0");
        loc2=glGetUniformLocation(shaderT2, "view\0");
        loc3=glGetUniformLocation(shaderT2, "normal\0");
        loc4=glGetUniformLocation(shaderT2, "colour\0");
        loc5=glGetUniformLocation(shaderT2, "projection\0");
        loc6=glGetUniformLocation(shaderT2, "lightOrientation\0");

//render a rectangle where the shadow is drawn onto
        glUniformMatrix4fv(loc1, 1, GL_FALSE, identity);
        glUniformMatrix4fv(loc2, 1, GL_FALSE, view);
        matrixMultiply4D(swap, view, identity);
        inverseMatrix4D(swap, swap);
        transpose4D(normal, swap);
        glUniformMatrix4fv(loc3, 1, GL_FALSE, normal);
        glUniform4fv(loc4, 1, red);
        glUniformMatrix4fv(loc5, 1, GL_FALSE, projection);
        swap[0]=1.0; swap[1]=0.0; swap[2]=0.0; swap[3]=0.0;
        swap[4]=0.0; swap[5]=1.0; swap[6]=0.0; swap[7]=0.0;
        swap[8]=0.0; swap[9]=0.0; swap[10]=1.0; swap[11]=0.0;
        swap[12]=-lightMatrix[12]; swap[13]=-lightMatrix[13]; swap[14]=-lightMatrix[14]; swap[15]=1.0;
        glUniformMatrix4fv(loc6, 1, GL_FALSE, swap);
        glBindVertexArray(VAO[0]);
        glDrawArrays(GL_TRIANGLES, 0, 6);

//render the triangle which makes a shadow
        glUniformMatrix4fv(loc1, 1, GL_FALSE, triangleMatrix);
        glUniformMatrix4fv(loc2, 1, GL_FALSE, view);
        matrixMultiply4D(swap, view, triangleMatrix);
        inverseMatrix4D(swap, swap);
         transpose4D(normal, swap);
        glUniformMatrix4fv(loc3, 1, GL_FALSE, normal);
        glUniform4fv(loc4, 1, yellow);
        glUniformMatrix4fv(loc5, 1, GL_FALSE, projection);
        swap[0]=1.0; swap[1]=0.0; swap[2]=0.0; swap[3]=0.0;
        swap[4]=0.0; swap[5]=1.0; swap[6]=0.0; swap[7]=0.0;
        swap[8]=0.0; swap[9]=0.0; swap[10]=1.0; swap[11]=0.0;
        swap[12]=-lightMatrix[12]; swap[13]=-lightMatrix[13]; swap[14]=-lightMatrix[14]; swap[15]=1.0;
        glUniformMatrix4fv(loc6, 1, GL_FALSE, swap);
        glBindVertexArray(VAO[1]);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }

//finally render a white triangle which represents a location of the light
    {
        glUseProgram(shaderT3);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glDepthMask(GL_TRUE);
        glDepthRange(0, 1);
        glViewport(0, 0, 512, 512);
        loc1=glGetUniformLocation(shaderT3, "view\0");
        loc2=glGetUniformLocation(shaderT3, "projection\0");
        loc3=glGetUniformLocation(shaderT3, "lightOrientation\0");
        glUniformMatrix4fv(loc1, 1, GL_FALSE, view);
        glUniformMatrix4fv(loc2, 1, GL_FALSE, projection);
        glUniformMatrix4fv(loc3, 1, GL_FALSE, lightMatrix);
        glBindVertexArray(VAO[2]);
         glDrawArrays(GL_TRIANGLES, 0, 3);
    }

    glFinish();

//rotate a light on it orbit
    matrixMultiply4D(lightMatrix, rotationMatrix, lightMatrix);

}

, 1-4 . 1 1:

Movie_1

2 2:

Movie_2

3 3:

Movie_3

4 4:

Movie_4

, Movie 4 , ( , . , - , , , ). ! , , , ...

+4
1

, ...

: , . ...

, . - , ?

0

Source: https://habr.com/ru/post/1664329/


All Articles