Fix and document the depth buffer calculations.
This commit is contained in:
@@ -210,20 +210,28 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
public void SetViewportParams(Size sheetSize, int downscale, float depthMargin, int2 scroll)
|
public void SetViewportParams(Size sheetSize, int downscale, float depthMargin, int2 scroll)
|
||||||
{
|
{
|
||||||
// Calculate the effective size of the render surface in viewport pixels
|
// Calculate the scale (r1) and offset (r2) that convert from OpenRA viewport pixels
|
||||||
var width = downscale * sheetSize.Width;
|
// to OpenGL normalized device coordinates (NDC). OpenGL expects coordinates to vary from [-1, 1],
|
||||||
var height = downscale * sheetSize.Height;
|
// so we rescale viewport pixels to the range [0, 2] using r1 then subtract 1 using r2.
|
||||||
var depthScale = height / (height + depthMargin);
|
var width = 2f / (downscale * sheetSize.Width);
|
||||||
var depthOffset = depthScale / 2;
|
var height = 2f / (downscale * sheetSize.Height);
|
||||||
shader.SetVec("Scroll", scroll.X, scroll.Y, scroll.Y);
|
|
||||||
shader.SetVec("r1",
|
|
||||||
2f / width,
|
|
||||||
2f / height,
|
|
||||||
-depthScale / height);
|
|
||||||
shader.SetVec("r2", -1, -1, 1 - depthOffset);
|
|
||||||
|
|
||||||
// Texture index is sampled as a float, so convert to pixels then scale
|
// Depth is more complicated:
|
||||||
shader.SetVec("DepthTextureScale", 128 * depthScale / height);
|
// * The OpenGL z axis is inverted (negative is closer) relative to OpenRA (positive is closer).
|
||||||
|
// * We want to avoid clipping pixels that are behind the nominal z == y plane at the
|
||||||
|
// top of the map, or above the nominal z == y plane at the bottom of the map.
|
||||||
|
// We therefore expand the depth range by an extra margin that is calculated based on
|
||||||
|
// the maximum expected world height (see Renderer.InitializeDepthBuffer).
|
||||||
|
// * Sprites can specify an additional per-pixel depth offset map, which is applied in the
|
||||||
|
// fragment shader. The fragment shader operates in OpenGL window coordinates, not NDC,
|
||||||
|
// with a depth range [0, 1] corresponding to the NDC [-1, 1]. We must therefore multiply the
|
||||||
|
// sprite channel value [0, 1] by 255 to find the pixel depth offset, then by our depth scale
|
||||||
|
// to find the equivalent NDC offset, then divide by 2 to find the window coordinate offset.
|
||||||
|
var depth = 2f / (downscale * (sheetSize.Height + depthMargin));
|
||||||
|
shader.SetVec("DepthTextureScale", 128 * depth);
|
||||||
|
shader.SetVec("Scroll", scroll.X, scroll.Y, scroll.Y);
|
||||||
|
shader.SetVec("r1", width, height, -depth);
|
||||||
|
shader.SetVec("r2", -1, -1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDepthPreview(bool enabled, float contrast, float offset)
|
public void SetDepthPreview(bool enabled, float contrast, float offset)
|
||||||
|
|||||||
@@ -270,8 +270,7 @@ void main()
|
|||||||
depth = depth + DepthTextureScale * dot(y, vDepthMask);
|
depth = depth + DepthTextureScale * dot(y, vDepthMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to window coords
|
gl_FragDepth = depth;
|
||||||
gl_FragDepth = 0.5 * depth + 0.5;
|
|
||||||
|
|
||||||
if (EnableDepthPreview)
|
if (EnableDepthPreview)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user