Skip to content

Commit

Permalink
fix: Stop z-fighting by pushing world/view/projection multiplications…
Browse files Browse the repository at this point in the history
… onto the GPU
  • Loading branch information
twpol committed Mar 2, 2023
1 parent 9079364 commit 791c0a3
Show file tree
Hide file tree
Showing 8 changed files with 20 additions and 25 deletions.
11 changes: 6 additions & 5 deletions Source/RunActivity/Content/SceneryShader.fx
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
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
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
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
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
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
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
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

0 comments on commit 791c0a3

Please sign in to comment.