2016-12-20 3 views
4

OpenGL 4.0, GLSL 4.0, GLEW 또는 유사하지 않음, GLU 또는 유사하지 않음, GLUT 또는 유사하지 않음)을 사용 중입니다. OpenCL 또는 CUDA도 사용되지만이 경우에는 관련되지 않습니다.이중 포물면 그림자 매핑

필자는 지난 몇 주 동안 성공하지 못한 채 문제를 풀려고 노력해 왔으며, 이제는 이중 포물면 쉐도우 매핑 경험이있는 사람이 조언을 해줄 수 있기를 바랍니다. 의 바로 문제에 가서 일부 사진 (사진 1)을 검사 보자

Picture_1

사진 1 내가 설명 할 필요가 몇 가지 색의 화살표가 포함되어 있습니다. 빨간색 화살표는 우리가 볼 수있는 유일한 정확한 그림자를 보여줍니다. 다른 화살표는 쉐도 잉 오류를 나타냅니다. 노란색 화살표는 테셀레이션으로 인한 스폿을 나타내며, 파란색 화살표도 표시되지만 위치는 앞/뒤 반구의 경계에 있습니다. 그리고 녹색 화살표는 존재하지 않아야하는 톱니 모양을 가리 킵니다 (최근에 우리가 보는 예에서는 빠졌습니다). 이제 사진이 위의 다음 코드 줄을 계산 한 것을 통지 (코드 1) 중요 :

이 코드 라인은 GLSL 셰이더 프로그램에있는 그리고 내가했던 네 후보 중 하나입니다
"swap.z=-sign(swap.z)*swap.z;\n" //mostly right results in the main project, but wrong way 

사진이 찍히는 곳에서 주요 프로젝트에서 성공하지 않으려 고 노력했습니다. 그러나 코드 4는 별도의 테스트 프로그램에서 작동합니다. 코드 1은 실제로 DPSM을 수행하는 완전히 잘못된 방법이지만 내 프로젝트가 섀도 잉되는 유일한 방법입니다.

Picture_2

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

는 다시 우리가 같은 장면을보고, 그러나 지금 우리는 완전히 다른 사용 : 다음 우리는 같은 장면 (그림 2와 코드 2) 조금 다른,하지만 여전히 잘못된 코드 라인을 계산보고 , 정통 코드 라인 (그림 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 

사람이 사진에서 본 유물은 위의 "그림자 여드름이라는 현상 때문이라고 의심하는 경우 "아니, 나는 그렇지 않다고 생각한다. 내가 말할 필요가이 시점에서

Picture_5

내가 두에 프로그램을 실행 한 것을 : 다음은 내가 의도적으로 흐리게 SHADOW_EPSILON = 0.000005f을 설정 및 해제로 전환하여 만든 그림자 여드름 패턴 (그림 5)를 가지고 사진입니다 별도의 Windows 7.1 노트북, nVIDIA GeForce GT 525M 및 다른 AMD Radeon R6 탑재. 결과는 동일했다. 컴파일러는 Visual Studio 2010입니다. 이것은 순수 OpenGL 관련 문제인 것처럼 보입니다.

문제를 해결하기 위해 별도의 작은 테스트 프로그램을 작성하고 마침내 섀도우 매핑을 작동 시켰습니다. 내가 볼 수있는 한 테스트 프로그램은 그림 1-5를 만든 프로그램과 거의 똑같이 작동하지만 최적화가없고 매트릭스 승수가 호스트에서 셰이더로 이동되었습니다. 테스트 프로그램 소스의 관련 부분은 다음과 같습니다.첫째 쉐이더 : 나는 테스트 프로그램 및 코드 선 위의 1-4를 나타내는 네 개의 영화를 촬영 한

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's orbit 
    matrixMultiply4D(lightMatrix, rotationMatrix, lightMatrix); 

} 

: 여기

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's 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"; 

그리고는 화면 표시 기능입니다. 코드 3

Movie_2

영화 3 : 코드 2

Movie_1

영화 2 : 다음 영화 1은 코드 1로 이루어집니다

Movie_3

영화 4 코드 4 포함 :

Movie_4

그림자 매핑이 작동하는 곳은 영화 4뿐입니다 (두 반구 사이의 경계 영역에는 그림자가 없지만 그걸로 살 수 있습니다). 그러나, 누군가 그것을 고치는 방법을 안다면, 당신이 나에게 말하면 행복 할 것입니다.) 그러나 그것은 주 프로젝트에서 작동하지 않습니다! 내가 ... 내가 확인하거나 저에게 당신의 작업 듀얼 포물면 그림자 매핑 코드 샘플을 제공해야하는지, 당신이 나에게 잘못 될 수 있는지에 대한 조언을 줄 수있는 희망

답변

0

음 ... 자신에게 응답

나는 발견 내 버그 : 그림자 맵을 렌더링하는 동안 나는 또한 빛을 나타내는 흰 공을 렌더링했습니다. 그것은 모든 것을 막아서 그 이유는 어둠이었습니다. ...

이제 내 주요 프로젝트가 내 프로젝트로 작동하지만, 여전히 반구 사이에 성가신 얇은 어두운 선이 있습니다. 아무도 내가 그걸 위해 무엇을 할 수 있는지 아니?

+0

동일한 문제가 발생했습니다. 두 개의 포물면 사이의 경계에 "솔기"선이 생겼습니다. 참조 : https://stackoverflow.com/questions/44118994/dual-paraboloid-shadow-texture-edge-seams 그게 당신이 얻고있는가요? –