阴影贴图定位和分辨率
Shadow Map Positioning and Resolution
我目前正在学习 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;
ShadowCoord = ProjectionMatrix * ShadowMatrix * WorldMatrix * vec4 (VertexPosition, 1);
这将计算该顶点在光眼 space 内的位置。您正在重新计算的是 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) 的区域 space.
...所以,总的来说,代码是关于从描述从光到光的点的向量的 3d 向量映射 space,到描述点落在何处的 2d 向量灯光的视平面 — 为生成深度图而渲染的平面。
我目前正在学习 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;
ShadowCoord = ProjectionMatrix * ShadowMatrix * WorldMatrix * vec4 (VertexPosition, 1);
这将计算该顶点在光眼 space 内的位置。您正在重新计算的是 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) 的区域 space.
...所以,总的来说,代码是关于从描述从光到光的点的向量的 3d 向量映射 space,到描述点落在何处的 2d 向量灯光的视平面 — 为生成深度图而渲染的平面。