GL_TEXTURE_2D替代GL_TEXTURE_RECTANGLE实现深度剥离出现锯齿问题求助
深度剥离算法切换GL_TEXTURE_2D后出现锯齿问题排查
问题背景
实现透明物体渲染的深度剥离算法时,原本采用GL_TEXTURE_RECTANGLE存储透明路径的深度值,采样无锯齿问题;但因目标平台不支持该格式,改用GL_TEXTURE_2D后出现大量锯齿。推测问题出在采样过滤异常或纹理坐标计算错误,导致深度比较逻辑出错。
代码对比
GL_TEXTURE_2D采样代码(出现锯齿)
ivec2 dbSize = textureSize(uOpaqueDepthMap, 0); float opaquePathDepth1 = texelFetch(uOpaqueDepthMap, ivec2(ceil(gl_FragCoord.xy)), 0).z; if(opaquePathDepth1 < gl_FragCoord.z) discard; else { ivec2 dpSize = textureSize(uDepthPeelMap, 0); float transparentPathDepth = texture(uDepthPeelMap, (gl_FragCoord.xy - vec2(0.5, 0.5)) / vec2(dpSize)).z; if(transparentPathDepth >= gl_FragCoord.z) discard; }
GL_TEXTURE_RECTANGLE采样代码(无锯齿)
float opaquePathDepth1 = texture(uOpaqueDepthMap, gl_FragCoord.xy).z; if(opaquePathDepth1 < gl_FragCoord.z) discard; else { float transparentPathDepth = texture(uDepthPeelMap, gl_FragCoord.xy).z; if(transparentPathDepth >= gl_FragCoord.z) discard; }
纹理配置
GL_TEXTURE_2D配置由NVIDIA NSIGHT捕获(原图片略)
问题分析与修复方案
1. 纹理坐标计算错误
- 不透明深度纹理采样错误:使用
ceil(gl_FragCoord.xy)获取像素索引是错误的。gl_FragCoord.xy表示片元中心坐标(例如第一个片元中心为(0.5, 0.5)),ceil后会得到(1,1),取到了下一个像素的深度值,导致深度比较逻辑混乱。应改为直接用ivec2(gl_FragCoord.xy)(或floor(gl_FragCoord.xy))获取正确的像素索引。 - 透明深度纹理采样错误:使用
texture()函数结合归一化坐标时,(gl_FragCoord.xy - vec2(0.5, 0.5)) / vec2(dpSize)的计算会指向像素左上角,而非片元对应的像素中心,容易触发纹理过滤的插值计算,导致深度值不准确。更可靠的方式是用texelFetch()直接按像素索引采样,和GL_TEXTURE_RECTANGLE的逻辑保持一致。
修正后的GL_TEXTURE_2D采样代码:
float opaquePathDepth1 = texelFetch(uOpaqueDepthMap, ivec2(gl_FragCoord.xy), 0).z; if(opaquePathDepth1 < gl_FragCoord.z) discard; else { float transparentPathDepth = texelFetch(uDepthPeelMap, ivec2(gl_FragCoord.xy), 0).z; if(transparentPathDepth >= gl_FragCoord.z) discard; }
2. 纹理过滤设置问题
深度剥离算法需要精确的单个像素深度值,若GL_TEXTURE_2D的GL_TEXTURE_MIN_FILTER或GL_TEXTURE_MAG_FILTER设置为GL_LINEAR,会对相邻像素深度进行线性插值,导致深度比较结果出错,产生锯齿。需确保两个过滤参数都设置为GL_NEAREST,禁用插值过滤。
内容的提问来源于stack exchange,提问作者Ivan Folbort
相关产品推荐
相关产品推荐

