我正在尝试使用OpenGL实现一个延迟屏幕空间贴花系统,这篇文章名为“使用延迟屏幕空间贴花在其他东西上绘制东西”,链接:http://martindevans.me/game-development/2015/02/27/Drawing-Stuff-On-Other-Stuff-With-Deferred-Screenspace-Decals/。你知道吗
将在场景顶部绘制一个红色着色的立方体,该立方体与depthmask设置为false的墙一致。 图像链接(无边界立方体):https://gyazo.com/8487947bd4afb08d8d0431551057ad6f
来自墙的depthbuffer和一些vertexshader输出用于计算墙在墙的尺寸内的objectspace位置立方体。立方体绑定检查确保在墙的objectspace位置之外的立方体的每个pixle都被丢弃。你知道吗
问题是边界没有正常工作,立方体完全消失了。你知道吗
我已经通过在lighitingpass中可视化depthbuffer来检查它是否工作正常,它似乎工作正常。depthbuffer存储在gbuffer中的颜色附件中,floatsize为GL\u RGB32F。 图像链接(liggingpass depthbuffer faraway wall可视化):https://gyazo.com/69920a532ca27aa9f57478cb57e0c84c
顶点着色器
// 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的深度纹理。你知道吗
与立方体一致的墙部分应为红色阴影,如下图所示。你知道吗
图像链接(有边界的立方体):https://gyazo.com/ab6d0db2483a969db932d2480a5acd08
我猜问题是如何将viewspace位置转换为objectspace位置,但我想不出来!你知道吗
你把粉笔和奶酪搞混了。
PositionCS
是剪辑空间位置,可以通过Perspective divide转换为规范化的设备空间位置:sampledDepth
是一个深度值(默认范围为[0,1]),可以通过从深度缓冲区纹理读取“红色”颜色通道(.r
,.x
)获得。深度可以通过depth*2.0-1.0
转换为标准化设备空间Z坐标:在透视投影和标准化设备空间中,具有相同x和y坐标的所有点都位于从视图位置开始的相同光线上。你知道吗
这意味着,如果深度缓冲区
gDepth
是使用与ndcPos
(PositionCS
)相同的视图矩阵和投影矩阵生成的,则可以用深度缓冲区(sampleNdcZ
)中相应的NDC z坐标替换ndcPos.z
,并且该点仍然位于同一视图光线上。ndcPos.z
和sampleNdcZ
是同一参考系中的可比较值。你知道吗该坐标可以通过逆投影矩阵和透视分割转换为视图空间坐标。
如果将同一视图光线上的NDC点转换为视图空间,则XY坐标将不同。注意,转换不是线性的,因为(
* 1/.w
)。另见OpenGL - Mouse coordinates to Space coordinates。你知道吗这可以通过逆视图矩阵到世界空间和逆模型矩阵到对象空间进一步转换:
相关问题 更多 >
编程相关推荐