3

我目前正在学习 C++ 和 OpenGL,想知道是否有人可以引导我了解以下代码到底发生了什么。它目前计算 3D 环境中阴影贴图的定位和分辨率。

该代码目前有效,只是想掌握一些东西。

//Vertex Shader Essentials.
Position = ProjectionMatrix * ViewMatrix * WorldMatrix * vec4 (VertexPosition, 1);
Normal = (ViewMatrix * WorldMatrix * vec4 (VertexNormal, 0)).xyz;
EyeSpaceLightPosition = ViewMatrix * LightPosition;
EyeSpacePosition = ViewMatrix * WorldMatrix * vec4 (VertexPosition, 1);
STCoords = VertexST;

//What is this block of code currently doing?
ShadowCoord = ProjectionMatrix * ShadowMatrix * WorldMatrix * vec4 (VertexPosition, 1);
ShadowCoord = ShadowCoord / ShadowCoord.w;  
ShadowCoord = (ShadowCoord + vec4 (1.0, 1.0, 1.0, 1.0)) * vec4 (1.0/2.0, 1.0/2.0, 1.0/2.0, 1.0);

//Alters the Shadow Map Resolution. 
//    Please Note - c is a slider that I control in the program execution.
float rounding = (c + 2.1) * 100.0;
ShadowCoord.x = (floor (ShadowCoord.x * rounding)) / rounding;
ShadowCoord.y = (floor (ShadowCoord.y * rounding)) / rounding;
ShadowCoord.z = (floor (ShadowCoord.z * rounding)) / rounding;


gl_Position = Position;
4

1 回答 1

1
ShadowCoord = ProjectionMatrix * ShadowMatrix * WorldMatrix * vec4 (VertexPosition, 1);

这将计算该顶点在光的眼睛空间内的位置。您正在重新计算的是Position = ProjectionMatrix * ViewMatrix * WorldMatrix * vec4 (VertexPosition, 1);当您渲染到阴影缓冲区时该行必须产生的内容。

ShadowCoord = ShadowCoord / ShadowCoord.w;  

这将应用透视投影,确定阴影坐标应落在灯光视图平面上的位置。

可以这样想:从灯光的角度来看,(1, 1, 1) 处的坐标应该与 (2, 2, 2) 处的坐标出现在同一个点上。对于这两个,您应该在深度缓冲区上采样相同的 2d 位置。除以w实现这一点。

ShadowCoord = (ShadowCoord + vec4 (1.0, 1.0, 1.0, 1.0)) * vec4 (1.0/2.0, 1.0/2.0, 1.0/2.0, 1.0);

这也是关于在正确的位置取样。上面的投影使物体位于光源视图的中心——例如 (0, 0, 1) 处的物体——最终位于 (0, 0)。但是 (0, 0) 是光照贴图的左下角,而不是中心。这条线确保光照贴图覆盖灯光投影空间中从 (-1, -1) 到 (1, 1) 的区域。

...所以,总的来说,代码是关于从描述从光到光空间中的点的向量的 3d 向量,到描述点落在光的视图平面上的位置的 2d 向量的映射——那个平面是渲染以生成深度图。

于 2015-04-28T16:50:28.667 回答