Pass depth scale factors to vertex shaders.

This commit is contained in:
Paul Chote
2015-10-01 18:55:54 +01:00
parent c00ef40151
commit dabea59b7d
7 changed files with 61 additions and 19 deletions

View File

@@ -359,6 +359,9 @@ namespace OpenRA
ModData.InitializeLoaders(ModData.DefaultFileSystem); ModData.InitializeLoaders(ModData.DefaultFileSystem);
Renderer.InitializeFonts(ModData); Renderer.InitializeFonts(ModData);
var grid = ModData.Manifest.Contains<MapGrid>() ? ModData.Manifest.Get<MapGrid>() : null;
Renderer.InitializeDepthBuffer(grid);
if (Cursor != null) if (Cursor != null)
Cursor.Dispose(); Cursor.Dispose();

View File

@@ -114,11 +114,17 @@ namespace OpenRA.Graphics
shader.SetTexture("Palette", palette); shader.SetTexture("Palette", palette);
} }
public void SetViewportParams(Size screen, float zoom, int2 scroll) public void SetViewportParams(Size screen, float depthScale, float depthOffset, float zoom, int2 scroll)
{ {
shader.SetVec("Scroll", scroll.X, scroll.Y); shader.SetVec("Scroll", scroll.X, scroll.Y, scroll.Y);
shader.SetVec("r1", zoom * 2f / screen.Width, -zoom * 2f / screen.Height); shader.SetVec("r1",
shader.SetVec("r2", -1, 1); zoom * 2f / screen.Width,
-zoom * 2f / screen.Height,
-depthScale * zoom / screen.Height);
shader.SetVec("r2", -1, 1, 1 - depthOffset);
// Texture index is sampled as a float, so convert to pixels then scale
shader.SetVec("DepthTextureScale", 128 * depthScale * zoom / screen.Height);
} }
public void SetDepthPreviewEnabled(bool enabled) public void SetDepthPreviewEnabled(bool enabled)

View File

@@ -28,6 +28,8 @@ namespace OpenRA
public readonly int MaximumTileSearchRange = 50; public readonly int MaximumTileSearchRange = 50;
public readonly bool EnableDepthBuffer = false;
public readonly WVec[] SubCellOffsets = public readonly WVec[] SubCellOffsets =
{ {
new WVec(0, 0, 0), // full cell - index 0 new WVec(0, 0, 0), // full cell - index 0

View File

@@ -40,6 +40,9 @@ namespace OpenRA
SheetBuilder fontSheetBuilder; SheetBuilder fontSheetBuilder;
float depthScale;
float depthOffset;
Size? lastResolution; Size? lastResolution;
int2? lastScroll; int2? lastScroll;
float? lastZoom; float? lastZoom;
@@ -102,6 +105,20 @@ namespace OpenRA
} }
} }
public void InitializeDepthBuffer(MapGrid mapGrid)
{
// The depth buffer needs to be initialized with enough range to cover:
// - the height of the screen
// - the z-offset of tiles from MaxTerrainHeight below the bottom of the screen (pushed into view)
// - additional z-offset from actors on top of MaxTerrainHeight terrain
// - a small margin so that tiles rendered partially above the top edge of the screen aren't pushed behind the clip plane
// We need an offset of mapGrid.MaximumTerrainHeight * mapGrid.TileSize.Height / 2 to cover the terrain height
// and choose to use mapGrid.MaximumTerrainHeight * mapGrid.TileSize.Height / 4 for each of the actor and top-edge cases
this.depthScale = mapGrid == null || !mapGrid.EnableDepthBuffer ? 0 :
(float)Resolution.Height / (Resolution.Height + mapGrid.TileSize.Height * mapGrid.MaximumTerrainHeight);
this.depthOffset = this.depthScale / 2;
}
public void BeginFrame(int2 scroll, float zoom) public void BeginFrame(int2 scroll, float zoom)
{ {
Device.Clear(); Device.Clear();
@@ -115,8 +132,8 @@ namespace OpenRA
if (resolutionChanged) if (resolutionChanged)
{ {
lastResolution = Resolution; lastResolution = Resolution;
RgbaSpriteRenderer.SetViewportParams(Resolution, 1f, int2.Zero); RgbaSpriteRenderer.SetViewportParams(Resolution, 0f, 0f, 1f, int2.Zero);
SpriteRenderer.SetViewportParams(Resolution, 1f, int2.Zero); SpriteRenderer.SetViewportParams(Resolution, 0f, 0f, 1f, int2.Zero);
RgbaColorRenderer.SetViewportParams(Resolution, 1f, int2.Zero); RgbaColorRenderer.SetViewportParams(Resolution, 1f, int2.Zero);
} }
@@ -125,8 +142,8 @@ namespace OpenRA
{ {
lastScroll = scroll; lastScroll = scroll;
lastZoom = zoom; lastZoom = zoom;
WorldRgbaSpriteRenderer.SetViewportParams(Resolution, zoom, scroll); WorldRgbaSpriteRenderer.SetViewportParams(Resolution, depthScale, depthOffset, zoom, scroll);
WorldSpriteRenderer.SetViewportParams(Resolution, zoom, scroll); WorldSpriteRenderer.SetViewportParams(Resolution, depthScale, depthOffset, zoom, scroll);
WorldVoxelRenderer.SetViewportParams(Resolution, zoom, scroll); WorldVoxelRenderer.SetViewportParams(Resolution, zoom, scroll);
WorldRgbaColorRenderer.SetViewportParams(Resolution, zoom, scroll); WorldRgbaColorRenderer.SetViewportParams(Resolution, zoom, scroll);
} }

View File

@@ -1,5 +1,5 @@
uniform vec2 Scroll; uniform vec3 Scroll;
uniform vec2 r1, r2; uniform vec3 r1, r2;
attribute vec4 aVertexPosition; attribute vec4 aVertexPosition;
attribute vec4 aVertexTexCoord; attribute vec4 aVertexTexCoord;
@@ -7,7 +7,6 @@ varying vec4 vTexCoord;
void main() void main()
{ {
vec2 p = (aVertexPosition.xy - Scroll.xy)*r1 + r2; gl_Position = vec4((aVertexPosition.xyz - Scroll.xyz) * r1 + r2, 1);
gl_Position = vec4(p.x,p.y,0,1);
vTexCoord = aVertexTexCoord; vTexCoord = aVertexTexCoord;
} }

View File

@@ -1,6 +1,7 @@
uniform sampler2D DiffuseTexture, Palette; uniform sampler2D DiffuseTexture, Palette;
uniform bool EnableDepthPreview; uniform bool EnableDepthPreview;
uniform float DepthTextureScale;
varying vec4 vTexCoord; varying vec4 vTexCoord;
varying vec4 vChannelMask; varying vec4 vChannelMask;
@@ -18,8 +19,23 @@ void main()
if (EnableDepthPreview && length(vDepthMask) > 0.0) if (EnableDepthPreview && length(vDepthMask) > 0.0)
{ {
float depth = dot(x, vDepthMask); if (abs(DepthTextureScale) > 0.0)
gl_FragColor = vec4(depth, depth, depth, 1); {
// Preview vertex aware depth
float depth = gl_FragCoord.z + DepthTextureScale * dot(x, vDepthMask);
// Convert to window coords
depth = 0.5 * depth + 0.5;
// Front of the depth buffer is at 0, but we want to render it as bright
gl_FragColor = vec4(vec3(1.0 - depth), 1.0);
}
else
{
// Preview boring sprite-only depth
float depth = dot(x, vDepthMask);
gl_FragColor = vec4(depth, depth, depth, 1.0);
}
} }
else else
gl_FragColor = c; gl_FragColor = c;

View File

@@ -1,5 +1,5 @@
uniform vec2 Scroll; uniform vec3 Scroll;
uniform vec2 r1,r2; // matrix elements uniform vec3 r1, r2;
attribute vec4 aVertexPosition; attribute vec4 aVertexPosition;
attribute vec4 aVertexTexCoord; attribute vec4 aVertexTexCoord;
@@ -36,8 +36,7 @@ vec4 DecodeDepthChannelMask(float x)
void main() void main()
{ {
vec2 p = (aVertexPosition.xy - Scroll.xy) * r1 + r2; gl_Position = vec4((aVertexPosition.xyz - Scroll.xyz) * r1 + r2, 1);
gl_Position = vec4(p.x,p.y,0,1);
vTexCoord = aVertexTexCoord; vTexCoord = aVertexTexCoord;
vChannelMask = DecodeChannelMask(aVertexTexCoord.w); vChannelMask = DecodeChannelMask(aVertexTexCoord.w);
vDepthMask = DecodeDepthChannelMask(aVertexTexCoord.w); vDepthMask = DecodeDepthChannelMask(aVertexTexCoord.w);