小编mob*_*bob的帖子

阴影贴图 - 与光正交的薄壁上的伪影

我遇到了背面(光线)和阴影贴图的问题,我似乎无法通过.我仍处于优化引擎的相对早期阶段,但是我似乎无法实现这一点,即使手动调整这一块几何形状,它仍然看起来像垃圾.

它是一个瘦墙,通过约5个不同的墙块"弯曲".当我创建我的深度图时,我正在剔除前脸(对光线).这肯定有帮助,但是墙的另一侧的正面似乎是导致z战斗/投射阴影.

弯曲的墙上的文物

截图上的一些注释:

  • 当绘制深度纹理(来自光)时,正面被剔除
  • 我有近距离和远距离飞机调整只是为了这个几何形状(分别设置为20和25)
  • 一个方向光源,朝向场景右侧稍微倾斜,足以表明墙应该被遮挡,但大多是直下
  • 使用一个荒谬的大4096x4096阴影贴图纹理
  • 所有照明都被禁用,但我知道即使在这面墙上,我也在做柔和的光照(因此也就是顶点的顶点法线)

正如这里提到的那样,你得出的结论是,你不应该遮住光线背面的多边形.我正在努力解决这个问题,因为我不想将面法线一直传递到片段着色器以排除那里真正的背面 - 但是如果有人觉得这是最好的/唯一的解决方案这种几何形状就是我必须要做的.考虑到管道如何不容易/明显地通过面法线通过它让我觉得这不是阻力最小的路径.请注意,我传递的法线是顶点法线,以允许边缘周围更柔和的光照效果(可能包括非阴影和阴影表面).

请注意,我有一些讨厌的透视别名,但我希望我接下来的步骤是在级联阴影贴图上工作,但是如果不解决这个问题,我觉得我只是推迟了不可避免的事情,因为我已经把视图作为手工收紧了我能做到最好(或者我认为).

无论如何我觉得我错过了什么,所以如果你有任何想法或帮助,将非常感激!

编辑

需要明确的是,根据光线的来源,墙壁在技术上不应该是阴影.

顶视图

下面是阴影关闭的图像.这只是使用顶点法线来计算漫反射光照 - 它不漂亮(太多几何体是可见的),但它确实显示某些边缘有些可见.

没有阴影打开

所以是的,墙应该在阴影中,但我希望我可以让平滑效果更好,所以边缘可以有一些漫射光.如果我需要将它完全放在阴影中,那么如果它的阴影贴图将它置于阴影中,或者我的代码专门将它置于阴影中,因为面部法线不在,我对此很好 - 但将面部正常通过到我的顶点/片段着色器似乎不是阻力最小的路径.

也许这些将有助于更好地说明我的问题,或者可能揭示我缺少的一些基本理解.

编辑#2

我在下面加入了深度纹理.你可以在左下方看到有问题的墙,从截图中你可以看到我如何将深度值修剪为~0.4-> 1.这意味着该墙的深度值从0.4范围开始.所以它没有完美地剪裁它,但它的接近.这看起来合情合理吗?我很确定它是一个完整的24或32位深度缓冲区,是iOS上的DEPTH_COMPONENT扩展.对于@starmole,这有助于确定我的投影中是否存在缩放误差?你认为我的地图覆盖的尺寸/面积是否太大,因此如果它靠近它可能有帮助吗?

在此输入图像描述

3d opengl-es opengl-es-2.0 shadow-mapping

17
推荐指数
1
解决办法
1089
查看次数

如何在透明纹理上停止OpenGL背景渗色

我有一个iOS OpenGL ES 2.0 3D游戏,我正在努力让透明纹理很好地工作,在这个特殊的栅栏示例中.

我将从最终结果开始.绿色背景/清晰的颜色在围栏的边缘穿过 - 注意它不是所有的边缘,有些是好的:

背景流血证据

右上角没有出血的原因是操作顺序.从下面的镜头中可以看出,绘制顺序包括一些在围栏之前绘制的建筑物.但大部分都是在围栏之后:

随深度绘制进展

因此,一种解决方案是始终最后绘制透明纹理对象.我想探索其他解决方案,因为我的管道可能并不总是允许这样做.我正在寻找其他建议来解决这个问题,而无需对我的抽奖进行排序.

这可能是一个深度或混合功能,但我已经尝试了大量的东西,似乎没有任何工作(不同的混合功能,不同的丢弃alpha级别,不同的背景颜色,不同的纹理设置).

以下是我实施的一些细节.

在我的frag shader中,我丢弃了具有透明度的碎片 - 这样它们就不会渲染到深度:

lowp vec4 texVal = texture2D(sTexture, texCoord);
if(texVal.w < 0.5)
    discard;
Run Code Online (Sandbox Code Playgroud)

我正在使用一个巨大的PVR纹理图集和mipmapping - 纹理本身应该只有0或1的alpha,但混合的东西可能导致这个:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
Run Code Online (Sandbox Code Playgroud)

我在渲染时使用以下混合:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Run Code Online (Sandbox Code Playgroud)

任何修复这种出血的建议都会很棒!

编辑 - 根据注释LINEAR/NEAREST中的建议尝试了不同的纹理过滤器,但结果相同.注意我也尝试过NEAREST/NEAREST并且没有运气:

在此输入图像描述

transparency opengl-es-2.0

5
推荐指数
0
解决办法
1922
查看次数

如何在OpenGL ES上有效地将深度缓冲区复制到纹理

我试图通过从标准GL 移植一些代码,在iOS上的OpenGL ES 2.0中使用一些阴影效果.部分示例涉及将深度缓冲区复制到纹理:

glBindTexture(GL_TEXTURE_2D, g_uiDepthBuffer);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 800, 600, 0);
Run Code Online (Sandbox Code Playgroud)

但是,似乎ES上不支持glCopyTexImage2D.读取相关的线程,似乎我可以使用帧缓冲区和片段着色器来提取深度数据.所以我试图将深度组件写入颜色缓冲区,然后复制它:

// clear everything
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 

// turn on depth rendering
glUseProgram(m_BaseShader.uiId);

// this is a switch to cause the fragment shader to just dump out the depth component
glUniform1i(uiBaseShaderRenderDepth, true);

// and for this, the color buffer needs to be on
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);

// and clear it to 1.0, like how the depth buffer starts
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); …
Run Code Online (Sandbox Code Playgroud)

opengl-es depth-buffer opengl-es-2.0

4
推荐指数
1
解决办法
5106
查看次数