Python 使用延迟屏幕空间贴花系统的边界检查问题
我正在尝试使用OpenGL实现一个延迟屏幕空间贴花系统,这篇文章名为“使用延迟屏幕空间贴花在其他东西上绘制东西”,链接: 将在场景的顶部绘制一个红色着色立方体,该立方体与深度任务设置为false的墙一致。 图像链接(无边界立方体): 墙的depthbuffer和一些vertexshader输出用于计算立方体尺寸内墙的objectspace位置。绑定检查确保丢弃墙objectspace位置之外的立方体的每个像素轴 问题是边界没有正常工作,立方体完全消失 潜在故障 我已经通过在lighitingpass中可视化depthbuffer来检查它是否正常工作,它似乎工作得很好。depthbuffer存储在gbuffer中的颜色附件中,floatsize为GL_RGB32F。 图像链接(照明通道深度缓冲区显示远处墙壁): 贴花着色器代码 顶点着色器Python 使用延迟屏幕空间贴花系统的边界检查问题,python,glsl,coordinate-transformation,Python,Glsl,Coordinate Transformation,我正在尝试使用OpenGL实现一个延迟屏幕空间贴花系统,这篇文章名为“使用延迟屏幕空间贴花在其他东西上绘制东西”,链接: 将在场景的顶部绘制一个红色着色立方体,该立方体与深度任务设置为false的墙一致。 图像链接(无边界立方体): 墙的depthbuffer和一些vertexshader输出用于计算立方体尺寸内墙的objectspace位置。绑定检查确保丢弃墙objectspace位置之外的立方体的每个像素轴 问题是边界没有正常工作,立方体完全消失 潜在故障 我已经通过在lighitingpa
// Vertex positions
vec4 InputPosition = vec4(aPos, 1);
// Viewspace Position
PositionVS = view* model* InputPosition;
// Clipspace Position
PositionCS = projection*PositionVS;
gl_Position = PositionCS;
碎片着色器
// Position on the screen
vec2 screenPos = PositionCS.xy / PositionCS.w;
// Convert into a texture coordinate
vec2 texCoord = vec2((1 + screenPos.x) / 2 + (0.5 / resolution.x), (1 -
screenPos.y) / 2 + (0.5 / resolution.y));
// Sampled value from depth buffer
vec4 sampledDepth = texture(gDepth, texCoord);
// View-direction
vec3 viewRay = PositionVS.xyz * (farClip / -PositionVS.z);
// Wallposition in view-space
vec3 viewPosition = viewRay*sampledDepth.z;
// Transformation from view-space to world-space
vec3 WorldPos = (invView*vec4(viewPosition, 1)).xyz;
// Transformation from world-space to object-space
vec3 objectPosition = (invModel*vec4(WorldPos, 1)).xyz;
// Bounds check, discard pixels outside the wall in object-space
if (abs(objectPosition.x) > 0.5) discard;
else if (abs(objectPosition.y) > 0.5) discard;
else if (abs(objectPosition.z) > 0.5) discard;
// Color to Gbuffer
gAlbedoSpec = vec4(1, 0, 0, 1);
代码描述
invView和invModel分别是view和model marices的逆对象。矩阵求逆计算在CPU中完成,并作为一致性发送到fragmentshader。farClip是到摄影机远平面的距离(此处设置为3000)。gDepth是Gbuffer的深度纹理
问题
与立方体一致的墙部分应为红色阴影,如下图所示
图像链接(带边界的立方体):
我猜问题在于如何将viewspace位置转换为objectspace位置,但我无法理解 你把粉笔和奶酪搞混了<代码>位置cs是剪辑空间位置,可通过以下方式转换为标准化设备空间位置:
vec2 ndcPos=PositionCS.xyz/PositionCS.w;
sampledDepth
是深度值(默认范围为[0,1]),可通过从深度缓冲区纹理读取“红色”颜色通道(.r
,.x
)获得。深度可以通过深度*2.0-1.0
转换为标准化设备空间Z坐标:
vec2 texCoord=ndcPos.xy*0.5+0.5;
//如果纹理过滤器是GL_最近的,则不需要(+0.5/分辨率.xy;)
float sampledDepth=纹理(gDepth,texCoord).x;
float-sampleNdcZ=sampledDepth*2.0-1.0;
在透视投影和规格化设备空间中,具有相同x和y坐标的所有点位于相同的光线上,该光线从视图位置开始
这意味着如果深度缓冲区gDepth
是使用与ndcPos
(PositionCS
)相同的视图矩阵和投影矩阵生成的,则可以用深度缓冲区(sampleNdcZ
)中相应的NDC z坐标替换ndcPos.z
),并且该点仍然位于同一视图光线上。ndcPos.z
和sampleNdcZ
是同一参考系中的可比较值
vec3 ndcSample=vec3(ndcPos.xy,sampleNdcZ);
该坐标可以通过逆投影矩阵和透视分割转换为视图空间坐标。如果将同一视图光线上的NDC点转换为视图空间,则XY坐标将不同。注意,转换不是线性的,因为(
*1/.w
)。另见
uniform mat4 invProj;//=逆(投影)
vec4 hViewPos=invProj*vec4(ndcSample,1.0);
vec3 viewPosition=hViewPos.xyz/hViewPos.w;
这可以通过将逆视图矩阵转换为世界空间和将逆模型矩阵转换为对象空间来进一步转换:
vec3worldpos=(invView*vec4(viewPosition,1.0)).xyz;
vec3 objectPosition=(invModel*vec4(WorldPos,1.0)).xyz;
什么是
gDepth
?是深度缓冲区吗?深度缓冲区只有“红色”通道.x
或.r
:浮动采样深度=纹理(gDepth,texCoord).x代码>谢谢!你是对的,它应该是“.r”而不是“.z”。这没有帮助:P,但我想我比你矮了一个错误!非常感谢你,我谦恭地向你的博学鞠躬!链接到正确的红色着色墙:。