Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop z-fighting by pushing world/view/projection multiplications onto the GPU #807

Merged
merged 1 commit into from
Mar 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 6 additions & 5 deletions Source/RunActivity/Content/SceneryShader.fx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
//////////////////// G L O B A L V A L U E S ///////////////////////////

float4x4 World; // model -> world
float4x4 WorldViewProjection; // model -> world -> view -> projection
float4x4 View; // world -> view
float4x4 Projection; // view -> projection
float4x4 LightViewProjectionShadowProjection0; // world -> light view -> light projection -> shadow map projection
float4x4 LightViewProjectionShadowProjection1;
float4x4 LightViewProjectionShadowProjection2;
Expand Down Expand Up @@ -156,7 +157,7 @@ struct VERTEX_OUTPUT
void _VSNormalProjection(in VERTEX_INPUT In, inout VERTEX_OUTPUT Out)
{
// Project position, normal and copy texture coords
Out.Position = mul(In.Position, WorldViewProjection);
Out.Position = mul(mul(mul(In.Position, World), View), Projection);
Out.RelPosition.xyz = mul(In.Position, World).xyz - ViewerPos;
Out.RelPosition.w = Out.Position.z;
Out.TexCoords.xy = In.TexCoords;
Expand Down Expand Up @@ -184,7 +185,7 @@ void _VSSignalProjection(uniform bool Glow, in VERTEX_INPUT_SIGNAL In, inout VER
const float GlowScalingFactor = 40;
In.Position.xyz *= log(1 + max(0, length(relPos) - GlowCutOffM) / GlowScalingFactor) * ZBias_Lighting.x;
}
Out.Position = mul(In.Position, WorldViewProjection);
Out.Position = mul(mul(mul(In.Position, World), View), Projection);
Out.RelPosition.xyz = relPos;
Out.RelPosition.w = Out.Position.z;
Out.TexCoords.xy = In.TexCoords;
Expand All @@ -194,7 +195,7 @@ void _VSSignalProjection(uniform bool Glow, in VERTEX_INPUT_SIGNAL In, inout VER
void _VSTransferProjection(in VERTEX_INPUT_TRANSFER In, inout VERTEX_OUTPUT Out)
{
// Project position, normal and copy texture coords
Out.Position = mul(In.Position, WorldViewProjection);
Out.Position = mul(mul(mul(In.Position, World), View), Projection);
Out.RelPosition.xyz = mul(In.Position, World).xyz - ViewerPos;
Out.RelPosition.w = Out.Position.z;
Out.TexCoords.xy = In.TexCoords;
Expand Down Expand Up @@ -301,7 +302,7 @@ VERTEX_OUTPUT VSForest(in VERTEX_INPUT_FOREST In)
In.Position = float4(newPosition, 1);

// Project vertex with fixed w=1 and normal=eye.
Out.Position = mul(In.Position, WorldViewProjection);
Out.Position = mul(mul(mul(In.Position, World), View), Projection);
Out.RelPosition.xyz = mul(In.Position, World).xyz - ViewerPos;
Out.RelPosition.w = Out.Position.z;
Out.TexCoords.xy = In.TexCoords;
Expand Down
3 changes: 1 addition & 2 deletions Source/RunActivity/Viewer3D/Forest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -431,15 +431,14 @@ public override void SetState(GraphicsDevice graphicsDevice, Material previousMa
public override void Render(GraphicsDevice graphicsDevice, IEnumerable<RenderItem> renderItems, ref Matrix XNAViewMatrix, ref Matrix XNAProjectionMatrix)
{
var shader = Viewer.MaterialManager.SceneryShader;
var viewproj = XNAViewMatrix * XNAProjectionMatrix;

shader.SetViewMatrix(ref XNAViewMatrix);
ShaderPasses.Reset();
while (ShaderPasses.MoveNext())
{
foreach (var item in renderItems)
{
shader.SetMatrix(item.XNAMatrix, ref viewproj);
shader.SetMatrix(item.XNAMatrix, ref XNAViewMatrix, ref XNAProjectionMatrix);
shader.ZBias = item.RenderPrimitive.ZBias;
ShaderPasses.Current.Apply();

Expand Down
3 changes: 1 addition & 2 deletions Source/RunActivity/Viewer3D/Materials.cs
Original file line number Diff line number Diff line change
Expand Up @@ -904,14 +904,13 @@ public override void SetState(GraphicsDevice graphicsDevice, Material previousMa
public override void Render(GraphicsDevice graphicsDevice, IEnumerable<RenderItem> renderItems, ref Matrix XNAViewMatrix, ref Matrix XNAProjectionMatrix)
{
var shader = Viewer.MaterialManager.SceneryShader;
var viewProj = XNAViewMatrix * XNAProjectionMatrix;

ShaderPasses.Reset();
while (ShaderPasses.MoveNext())
{
foreach (var item in renderItems)
{
shader.SetMatrix(item.XNAMatrix, ref viewProj);
shader.SetMatrix(item.XNAMatrix, ref XNAViewMatrix, ref XNAProjectionMatrix);
shader.ZBias = item.RenderPrimitive.ZBias;
ShaderPasses.Current.Apply();

Expand Down
11 changes: 7 additions & 4 deletions Source/RunActivity/Viewer3D/Shaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ class Logger : ContentBuildLogger
public class SceneryShader : Shader
{
readonly EffectParameter world;
readonly EffectParameter worldViewProjection;
readonly EffectParameter view;
readonly EffectParameter projection;
readonly EffectParameter[] lightViewProjectionShadowProjection;
readonly EffectParameter[] shadowMapTextures;
readonly EffectParameter shadowMapLimit;
Expand Down Expand Up @@ -116,10 +117,11 @@ public void SetViewMatrix(ref Matrix v)
sideVector.SetValue(Vector3.Normalize(Vector3.Cross(_eyeVector, Vector3.Down)));
}

public void SetMatrix(Matrix w, ref Matrix vp)
public void SetMatrix(Matrix w, ref Matrix v, ref Matrix p)
{
world.SetValue(w);
worldViewProjection.SetValue(w * vp);
view.SetValue(v);
projection.SetValue(p);

int vIn = Program.Simulator.Settings.DayAmbientLight;

Expand Down Expand Up @@ -225,7 +227,8 @@ public SceneryShader(GraphicsDevice graphicsDevice)
: base(graphicsDevice, "SceneryShader")
{
world = Parameters["World"];
worldViewProjection = Parameters["WorldViewProjection"];
view = Parameters["View"];
projection = Parameters["Projection"];
lightViewProjectionShadowProjection = new EffectParameter[RenderProcess.ShadowMapCountMaximum];
shadowMapTextures = new EffectParameter[RenderProcess.ShadowMapCountMaximum];
for (var i = 0; i < RenderProcess.ShadowMapCountMaximum; i++)
Expand Down
8 changes: 2 additions & 6 deletions Source/RunActivity/Viewer3D/Signals.cs
Original file line number Diff line number Diff line change
Expand Up @@ -694,14 +694,12 @@ public override void SetState(GraphicsDevice graphicsDevice, Material previousMa

public override void Render(GraphicsDevice graphicsDevice, IEnumerable<RenderItem> renderItems, ref Matrix XNAViewMatrix, ref Matrix XNAProjectionMatrix)
{
var viewProj = XNAViewMatrix * XNAProjectionMatrix;

foreach (var pass in SceneryShader.CurrentTechnique.Passes)
{
foreach (var item in renderItems)
{
SceneryShader.SignalLightIntensity = (item.ItemData as SignalLightState).GetIntensity();
SceneryShader.SetMatrix(item.XNAMatrix, ref viewProj);
SceneryShader.SetMatrix(item.XNAMatrix, ref XNAViewMatrix, ref XNAProjectionMatrix);
pass.Apply();
item.RenderPrimitive.Draw(graphicsDevice);
}
Expand Down Expand Up @@ -752,16 +750,14 @@ public override void SetState(GraphicsDevice graphicsDevice, Material previousMa

public override void Render(GraphicsDevice graphicsDevice, IEnumerable<RenderItem> renderItems, ref Matrix XNAViewMatrix, ref Matrix XNAProjectionMatrix)
{
var viewProj = XNAViewMatrix * XNAProjectionMatrix;

foreach (var pass in SceneryShader.CurrentTechnique.Passes)
{
foreach (var item in renderItems)
{
var slp = item.RenderPrimitive as SignalLightPrimitive;
SceneryShader.ZBias = MathHelper.Lerp(slp.GlowIntensityDay, slp.GlowIntensityNight, NightEffect);
SceneryShader.SignalLightIntensity = (item.ItemData as SignalLightState).GetIntensity();
SceneryShader.SetMatrix(item.XNAMatrix, ref viewProj);
SceneryShader.SetMatrix(item.XNAMatrix, ref XNAViewMatrix, ref XNAProjectionMatrix);
pass.Apply();
item.RenderPrimitive.Draw(graphicsDevice);
}
Expand Down
3 changes: 1 addition & 2 deletions Source/RunActivity/Viewer3D/Terrain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -530,14 +530,13 @@ public override void SetState(GraphicsDevice graphicsDevice, Material previousMa
public override void Render(GraphicsDevice graphicsDevice, IEnumerable<RenderItem> renderItems, ref Matrix XNAViewMatrix, ref Matrix XNAProjectionMatrix)
{
var shader = Viewer.MaterialManager.SceneryShader;
var viewproj = XNAViewMatrix * XNAProjectionMatrix;

ShaderPasses.Reset();
while (ShaderPasses.MoveNext())
{
foreach (var item in renderItems)
{
shader.SetMatrix(item.XNAMatrix, ref viewproj);
shader.SetMatrix(item.XNAMatrix, ref XNAViewMatrix, ref XNAProjectionMatrix);
shader.ZBias = item.RenderPrimitive.ZBias;
ShaderPasses.Current.Apply();
// SamplerStates can only be set after the ShaderPasses.Current.Apply().
Expand Down
3 changes: 1 addition & 2 deletions Source/RunActivity/Viewer3D/Transfers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,14 @@ public override void SetState(GraphicsDevice graphicsDevice, Material previousMa
public override void Render(GraphicsDevice graphicsDevice, IEnumerable<RenderItem> renderItems, ref Matrix XNAViewMatrix, ref Matrix XNAProjectionMatrix)
{
var shader = Viewer.MaterialManager.SceneryShader;
var viewproj = XNAViewMatrix * XNAProjectionMatrix;

shader.SetViewMatrix(ref XNAViewMatrix);
ShaderPasses.Reset();
while (ShaderPasses.MoveNext())
{
foreach (var item in renderItems)
{
shader.SetMatrix(item.XNAMatrix, ref viewproj);
shader.SetMatrix(item.XNAMatrix, ref XNAViewMatrix, ref XNAProjectionMatrix);
shader.ZBias = item.RenderPrimitive.ZBias;
ShaderPasses.Current.Apply();
// SamplerStates can only be set after the ShaderPasses.Current.Apply().
Expand Down
3 changes: 1 addition & 2 deletions Source/RunActivity/Viewer3D/Water.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,13 @@ public override void SetState(GraphicsDevice graphicsDevice, Material previousMa
public override void Render(GraphicsDevice graphicsDevice, IEnumerable<RenderItem> renderItems, ref Matrix XNAViewMatrix, ref Matrix XNAProjectionMatrix)
{
var shader = Viewer.MaterialManager.SceneryShader;
var viewproj = XNAViewMatrix * XNAProjectionMatrix;

ShaderPasses.Reset();
while (ShaderPasses.MoveNext())
{
foreach (var item in renderItems)
{
shader.SetMatrix(item.XNAMatrix, ref viewproj);
shader.SetMatrix(item.XNAMatrix, ref XNAViewMatrix, ref XNAProjectionMatrix);
shader.ZBias = item.RenderPrimitive.ZBias;
ShaderPasses.Current.Apply();
// SamplerStates can only be set after the ShaderPasses.Current.Apply().
Expand Down