我一直试图解决我的问题几周没有成功,现在我希望有双抛物面阴影映射经验的人可以给我建议.让我们直接解决问题并检查一些图片(图片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):
"swap.z=sign(swap.z)*swap.z;\n" //almost dark picture,wrong way
我们再次看同一个场景,但现在我们使用完全不同的正统代码行(图3和代码3):
"swap.z=-(tedistance-n)/(f-n);\n" //lightning is mainly working but no shadows,should be the right way
最后,我们看一下代码行计算的场景,它在我们最近看到的例子中(几乎)完美地工作(图4和代码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)故意制作阴影痤疮图案的图片:
在这一点上,我需要说,我在两台独立的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""}voID TForm1::display(){ gluint loc1,loc2,loc3,loc4,loc5,loc6; float swap[16]; float normal[16]={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); glDepthMask(GL_TRUE); glDepthRange(0,1); glClear(GL_color_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glVIEwport(0,textureDim.x,textureDim.y); glPatchParameteri(GL_PATCH_VERTICES,3); loc1=glGetUniformlocation(shaderT1,"model"); loc2=glGetUniformlocation(shaderT1,"lightOrIEntation"); loc3=glGetUniformlocation(shaderT1,"vIEw"); 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,swap); gluniformMatrix4fv(loc3,vIEw); glBindVertexArray(VAO[1]); glDrawArrays(GL_PATCHES,3); gluniformMatrix4fv(loc1,IDentity); gluniformMatrix4fv(loc2,vIEw); glBindVertexArray(VAO[0]); glDrawArrays(GL_PATCHES,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); 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,512,512); loc1=glGetUniformlocation(shaderT2,"model"); loc2=glGetUniformlocation(shaderT2,"vIEw"); loc3=glGetUniformlocation(shaderT2,"normal"); loc4=glGetUniformlocation(shaderT2,"colour"); loc5=glGetUniformlocation(shaderT2,"projection"); loc6=glGetUniformlocation(shaderT2,"lightOrIEntation");//render a rectangle where the shadow is drawn onto gluniformMatrix4fv(loc1,vIEw); matrixMultiply4D(swap,vIEw,IDentity); inverseMatrix4D(swap,swap); transpose4D(normal,normal); gluniform4fv(loc4,red); gluniformMatrix4fv(loc5,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,swap); glBindVertexArray(VAO[0]); glDrawArrays(GL_TRIANGLES,6);//render the triangle which makes a shadow gluniformMatrix4fv(loc1,triangleMatrix); inverseMatrix4D(swap,swap); transpose4D(normal,yellow); gluniformMatrix4fv(loc5,swap); glBindVertexArray(VAO[1]); glDrawArrays(GL_TRIANGLES,3); }//finally render a white triangle which represents a location of the light { gluseProgram(shaderT3); glBindFramebuffer(GL_FRAMEBUFFER,1); glVIEwport(0,512); loc1=glGetUniformlocation(shaderT3,"vIEw"); loc2=glGetUniformlocation(shaderT3,"projection"); loc3=glGetUniformlocation(shaderT3,"lightOrIEntation"); gluniformMatrix4fv(loc1,vIEw); gluniformMatrix4fv(loc2,projection); gluniformMatrix4fv(loc3,lightmatrix); glBindVertexArray(VAO[2]); glDrawArrays(GL_TRIANGLES,3); } glFinish();//rotate a light on it's orbit matrixMultiply4D(lightmatrix,rotationMatrix,lightmatrix);}";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""}";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""}";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""}";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""}";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""}";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""}";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""}";const char *fragmentlight="#version 400 core\n""out vec4 fragmentcolor;\n""voID main() {\n" "fragmentcolor=vec4(1.0,1.0);\n""}";
这是显示功能:
我拍了四部电影代表上面的测试程序和代码行1-4.下面是用代码1完成的电影1:
Movie_1
电影2代码2:
Movie_2
电影3代码3:
Movie_3
电影4代码4:
Movie_4
你可以看到MovIE 4是唯一一个阴影贴图工作的地方(两个半球之间的边界区域没有阴影,但我可以忍受.但是,如果有人知道如何修复它,我会很高兴如果你告诉我).但它不适用于主项目!我希望你能给我一些关于可能出错的建议,我应该检查或给你你的双抛物面阴影映射代码样本……
@H_419_4@解决方法 好吧,回答自己……我发现了我的错误:在渲染阴影贴图时,我还渲染了代表光线的白球.它掩盖了一切,这就是一个词是黑暗的原因……
现在我的主要项目是我的测试项目,但是半球之间仍然存在令人讨厌的细线.有谁知道我能为此做些什么?
@H_419_4@ @H_419_4@ @H_419_4@ @H_419_4@ 总结以上是内存溢出为你收集整理的c – 双抛物面阴影映射全部内容,希望文章能够帮你解决c – 双抛物面阴影映射所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)