starting on point shadows
parent
06e5523996
commit
0a7698c315
|
@ -9,22 +9,28 @@ namespace Kav
|
||||||
EffectParameter gAlbedoParam;
|
EffectParameter gAlbedoParam;
|
||||||
EffectParameter gNormalParam;
|
EffectParameter gNormalParam;
|
||||||
EffectParameter gMetallicRoughnessParam;
|
EffectParameter gMetallicRoughnessParam;
|
||||||
|
EffectParameter shadowMapParam;
|
||||||
|
|
||||||
EffectParameter eyePositionParam;
|
EffectParameter eyePositionParam;
|
||||||
|
|
||||||
EffectParameter pointLightColorParam;
|
EffectParameter pointLightColorParam;
|
||||||
EffectParameter pointLightPositionParam;
|
EffectParameter pointLightPositionParam;
|
||||||
|
|
||||||
|
EffectParameter farPlaneParam;
|
||||||
|
|
||||||
public Texture2D GPosition { get; set; }
|
public Texture2D GPosition { get; set; }
|
||||||
public Texture2D GAlbedo { get; set; }
|
public Texture2D GAlbedo { get; set; }
|
||||||
public Texture2D GNormal { get; set; }
|
public Texture2D GNormal { get; set; }
|
||||||
public Texture2D GMetallicRoughness { get; set; }
|
public Texture2D GMetallicRoughness { get; set; }
|
||||||
|
public TextureCube ShadowMap { get; set; }
|
||||||
|
|
||||||
public Vector3 EyePosition { get; set; }
|
public Vector3 EyePosition { get; set; }
|
||||||
|
|
||||||
public Vector3 PointLightPosition { get; set; }
|
public Vector3 PointLightPosition { get; set; }
|
||||||
public Vector3 PointLightColor { get; set; }
|
public Vector3 PointLightColor { get; set; }
|
||||||
|
|
||||||
|
public float FarPlane { get; set; }
|
||||||
|
|
||||||
public DeferredPBR_PointLightEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_PointLightEffect)
|
public DeferredPBR_PointLightEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_PointLightEffect)
|
||||||
{
|
{
|
||||||
CacheEffectParameters();
|
CacheEffectParameters();
|
||||||
|
@ -32,15 +38,20 @@ namespace Kav
|
||||||
|
|
||||||
public DeferredPBR_PointLightEffect(DeferredPBR_PointLightEffect cloneSource) : base(cloneSource)
|
public DeferredPBR_PointLightEffect(DeferredPBR_PointLightEffect cloneSource) : base(cloneSource)
|
||||||
{
|
{
|
||||||
|
CacheEffectParameters();
|
||||||
|
|
||||||
GPosition = cloneSource.GPosition;
|
GPosition = cloneSource.GPosition;
|
||||||
GAlbedo = cloneSource.GAlbedo;
|
GAlbedo = cloneSource.GAlbedo;
|
||||||
GNormal = cloneSource.GNormal;
|
GNormal = cloneSource.GNormal;
|
||||||
GMetallicRoughness = cloneSource.GMetallicRoughness;
|
GMetallicRoughness = cloneSource.GMetallicRoughness;
|
||||||
|
ShadowMap = cloneSource.ShadowMap;
|
||||||
|
|
||||||
EyePosition = cloneSource.EyePosition;
|
EyePosition = cloneSource.EyePosition;
|
||||||
|
|
||||||
PointLightPosition = cloneSource.PointLightPosition;
|
PointLightPosition = cloneSource.PointLightPosition;
|
||||||
PointLightColor = cloneSource.PointLightColor;
|
PointLightColor = cloneSource.PointLightColor;
|
||||||
|
|
||||||
|
FarPlane = cloneSource.FarPlane;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Effect Clone()
|
public override Effect Clone()
|
||||||
|
@ -54,11 +65,14 @@ namespace Kav
|
||||||
gAlbedoParam.SetValue(GAlbedo);
|
gAlbedoParam.SetValue(GAlbedo);
|
||||||
gNormalParam.SetValue(GNormal);
|
gNormalParam.SetValue(GNormal);
|
||||||
gMetallicRoughnessParam.SetValue(GMetallicRoughness);
|
gMetallicRoughnessParam.SetValue(GMetallicRoughness);
|
||||||
|
shadowMapParam.SetValue(ShadowMap);
|
||||||
|
|
||||||
eyePositionParam.SetValue(EyePosition);
|
eyePositionParam.SetValue(EyePosition);
|
||||||
|
|
||||||
pointLightPositionParam.SetValue(PointLightPosition);
|
pointLightPositionParam.SetValue(PointLightPosition);
|
||||||
pointLightColorParam.SetValue(PointLightColor);
|
pointLightColorParam.SetValue(PointLightColor);
|
||||||
|
|
||||||
|
farPlaneParam.SetValue(FarPlane);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CacheEffectParameters()
|
void CacheEffectParameters()
|
||||||
|
@ -67,11 +81,14 @@ namespace Kav
|
||||||
gAlbedoParam = Parameters["gAlbedo"];
|
gAlbedoParam = Parameters["gAlbedo"];
|
||||||
gNormalParam = Parameters["gNormal"];
|
gNormalParam = Parameters["gNormal"];
|
||||||
gMetallicRoughnessParam = Parameters["gMetallicRoughness"];
|
gMetallicRoughnessParam = Parameters["gMetallicRoughness"];
|
||||||
|
shadowMapParam = Parameters["shadowMap"];
|
||||||
|
|
||||||
eyePositionParam = Parameters["EyePosition"];
|
eyePositionParam = Parameters["EyePosition"];
|
||||||
|
|
||||||
pointLightPositionParam = Parameters["PointLightPosition"];
|
pointLightPositionParam = Parameters["PointLightPosition"];
|
||||||
pointLightColorParam = Parameters["PointLightColor"];
|
pointLightColorParam = Parameters["PointLightColor"];
|
||||||
|
|
||||||
|
farPlaneParam = Parameters["FarPlane"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
Effects/FXB/DeferredPBR_PointLightEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/DeferredPBR_PointLightEffect.fxb (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
Effects/FXB/SimpleDepthEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/SimpleDepthEffect.fxb (Stored with Git LFS)
Binary file not shown.
|
@ -1,10 +1,12 @@
|
||||||
#include "Macros.fxh" //from FNA
|
#include "Macros.fxh" //from FNA
|
||||||
#include "Lighting.fxh"
|
#include "Lighting.fxh"
|
||||||
|
#include "Shadow.fxh"
|
||||||
|
|
||||||
DECLARE_TEXTURE(gPosition, 0);
|
DECLARE_TEXTURE(gPosition, 0);
|
||||||
DECLARE_TEXTURE(gAlbedo, 1);
|
DECLARE_TEXTURE(gAlbedo, 1);
|
||||||
DECLARE_TEXTURE(gNormal, 2);
|
DECLARE_TEXTURE(gNormal, 2);
|
||||||
DECLARE_TEXTURE(gMetallicRoughness, 3);
|
DECLARE_TEXTURE(gMetallicRoughness, 3);
|
||||||
|
DECLARE_CUBEMAP(shadowMap, 4);
|
||||||
|
|
||||||
BEGIN_CONSTANTS
|
BEGIN_CONSTANTS
|
||||||
|
|
||||||
|
@ -13,6 +15,8 @@ BEGIN_CONSTANTS
|
||||||
float3 PointLightPosition _ps(c1) _cb(c1);
|
float3 PointLightPosition _ps(c1) _cb(c1);
|
||||||
float3 PointLightColor _ps(c2) _cb(c2);
|
float3 PointLightColor _ps(c2) _cb(c2);
|
||||||
|
|
||||||
|
float FarPlane _ps(c3) _cb(c3);
|
||||||
|
|
||||||
MATRIX_CONSTANTS
|
MATRIX_CONSTANTS
|
||||||
|
|
||||||
END_CONSTANTS
|
END_CONSTANTS
|
||||||
|
@ -60,9 +64,11 @@ float4 ComputeColor(
|
||||||
float attenuation = 1.0 / (distance * distance);
|
float attenuation = 1.0 / (distance * distance);
|
||||||
float3 radiance = PointLightColor * attenuation;
|
float3 radiance = PointLightColor * attenuation;
|
||||||
|
|
||||||
float3 color = ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, 1.0);
|
float shadow = HardPointShadow(worldPosition, N, L, PointLightPosition, SAMPLER(shadowMap), FarPlane);
|
||||||
|
float3 color = ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, shadow);
|
||||||
|
|
||||||
return float4(color, 1.0);
|
return float4(color, 1.0);
|
||||||
|
//return float4(shadow, shadow, shadow, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 main_ps(PixelInput input) : SV_TARGET0
|
float4 main_ps(PixelInput input) : SV_TARGET0
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include "Macros.fxh"
|
||||||
|
|
||||||
|
BEGIN_CONSTANTS
|
||||||
|
|
||||||
|
float4x4 Model _vs(c0) _cb(c0);
|
||||||
|
float4x4 ModelViewProjection _vs(c4) _cb(c4);
|
||||||
|
|
||||||
|
float3 LightPosition _ps(c0) _cb(c8);
|
||||||
|
float FarPlane _ps(c1) _cb(c9);
|
||||||
|
|
||||||
|
END_CONSTANTS
|
||||||
|
|
||||||
|
struct VertexShaderInput
|
||||||
|
{
|
||||||
|
float4 Position : POSITION;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexShaderOutput
|
||||||
|
{
|
||||||
|
float4 Position : SV_Position;
|
||||||
|
float3 PositionWorld : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
VertexShaderOutput main_vs(VertexShaderInput input)
|
||||||
|
{
|
||||||
|
VertexShaderOutput output;
|
||||||
|
output.Position = mul(input.Position, ModelViewProjection);
|
||||||
|
output.PositionWorld = mul(input.Position, Model);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 main_ps(VertexShaderOutput input) : SV_TARGET0
|
||||||
|
{
|
||||||
|
float lightDistance = length(input.PositionWorld - LightPosition);
|
||||||
|
lightDistance /= FarPlane;
|
||||||
|
return float4(lightDistance, 0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique SimpleDepth
|
||||||
|
{
|
||||||
|
Pass
|
||||||
|
{
|
||||||
|
VertexShader = compile vs_3_0 main_vs();
|
||||||
|
PixelShader = compile ps_3_0 main_ps();
|
||||||
|
}
|
||||||
|
}
|
|
@ -120,3 +120,23 @@ float HardShadow(
|
||||||
|
|
||||||
return (currentDepth - bias > closestDepth ? 0.25 : 1.0);
|
return (currentDepth - bias > closestDepth ? 0.25 : 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float HardPointShadow(
|
||||||
|
float3 positionWorldSpace,
|
||||||
|
float3 N,
|
||||||
|
float3 L,
|
||||||
|
float3 lightPosition,
|
||||||
|
sampler shadowMap,
|
||||||
|
float farPlane
|
||||||
|
) {
|
||||||
|
float3 lightToFrag = positionWorldSpace - lightPosition;
|
||||||
|
float closestDepth = texCUBE(shadowMap, lightToFrag).r;
|
||||||
|
closestDepth *= farPlane;
|
||||||
|
|
||||||
|
float currentDepth = length(lightToFrag);
|
||||||
|
|
||||||
|
float bias = max(0.05 * (1.0 - dot(N, L)), 0.005);
|
||||||
|
|
||||||
|
return (currentDepth - bias > closestDepth ? 0.25 : 1.0);
|
||||||
|
//return closestDepth / farPlane;
|
||||||
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ VertexShaderOutput main_vs(VertexShaderInput input)
|
||||||
VertexShaderOutput output;
|
VertexShaderOutput output;
|
||||||
|
|
||||||
output.Position = mul(input.Position, ModelViewProjection);
|
output.Position = mul(input.Position, ModelViewProjection);
|
||||||
output.Depth = output.Position.z;
|
output.Depth = output.Position.z / output.Position.w;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public class LinearDepthEffect : Effect
|
||||||
|
{
|
||||||
|
EffectParameter modelParam;
|
||||||
|
EffectParameter modelViewProjectionParam;
|
||||||
|
EffectParameter lightPositionParam;
|
||||||
|
EffectParameter farPlaneParam;
|
||||||
|
|
||||||
|
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||||
|
|
||||||
|
Matrix model;
|
||||||
|
Matrix view;
|
||||||
|
Matrix projection;
|
||||||
|
|
||||||
|
public Vector3 LightPosition { get; set; }
|
||||||
|
public float FarPlane { get; set; }
|
||||||
|
|
||||||
|
public Matrix Model
|
||||||
|
{
|
||||||
|
get { return model; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
model = value;
|
||||||
|
dirtyFlags |= EffectDirtyFlags.World;
|
||||||
|
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matrix View
|
||||||
|
{
|
||||||
|
get { return view; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
view = value;
|
||||||
|
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matrix Projection
|
||||||
|
{
|
||||||
|
get { return projection; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
projection = value;
|
||||||
|
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinearDepthEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.LinearDepthEffect)
|
||||||
|
{
|
||||||
|
CacheEffectParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApply()
|
||||||
|
{
|
||||||
|
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
||||||
|
{
|
||||||
|
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
||||||
|
Matrix.Multiply(ref model, ref viewProjection, out Matrix worldViewProj);
|
||||||
|
|
||||||
|
modelViewProjectionParam.SetValue(worldViewProj);
|
||||||
|
|
||||||
|
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
||||||
|
{
|
||||||
|
modelParam.SetValue(model);
|
||||||
|
|
||||||
|
dirtyFlags &= ~EffectDirtyFlags.World;
|
||||||
|
}
|
||||||
|
|
||||||
|
lightPositionParam.SetValue(LightPosition);
|
||||||
|
farPlaneParam.SetValue(FarPlane);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CacheEffectParameters()
|
||||||
|
{
|
||||||
|
modelParam = Parameters["Model"];
|
||||||
|
modelViewProjectionParam = Parameters["ModelViewProjection"];
|
||||||
|
|
||||||
|
lightPositionParam = Parameters["LightPosition"];
|
||||||
|
farPlaneParam = Parameters["FarPlane"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,6 +42,9 @@
|
||||||
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
||||||
|
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
|
|
@ -42,12 +42,15 @@
|
||||||
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Models\UnitCube.glb">
|
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.UnitCube.glb</LogicalName>
|
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Models\UnitCube.glb">
|
||||||
|
<LogicalName>Kav.Resources.UnitCube.glb</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -17,7 +17,7 @@ Essential
|
||||||
- [ ] Frustum culling
|
- [ ] Frustum culling
|
||||||
- [ ] Shadow-casting point lights
|
- [ ] Shadow-casting point lights
|
||||||
- [ ] Parabolic lights
|
- [ ] Parabolic lights
|
||||||
- [ ] Skyboxes
|
- [x] Skyboxes
|
||||||
- [ ] Screen-space reflection
|
- [ ] Screen-space reflection
|
||||||
|
|
||||||
Nice-To-Haves
|
Nice-To-Haves
|
||||||
|
|
146
Renderer.cs
146
Renderer.cs
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
@ -29,6 +30,7 @@ namespace Kav
|
||||||
private DeferredPBR_DirectionalLightEffect DeferredDirectionalLightEffect { get; }
|
private DeferredPBR_DirectionalLightEffect DeferredDirectionalLightEffect { get; }
|
||||||
private Deferred_ToonEffect Deferred_ToonEffect { get; }
|
private Deferred_ToonEffect Deferred_ToonEffect { get; }
|
||||||
private SimpleDepthEffect SimpleDepthEffect { get; }
|
private SimpleDepthEffect SimpleDepthEffect { get; }
|
||||||
|
private LinearDepthEffect LinearDepthEffect { get; }
|
||||||
private Effect ToneMapEffect { get; }
|
private Effect ToneMapEffect { get; }
|
||||||
private SkyboxEffect SkyboxEffect { get; }
|
private SkyboxEffect SkyboxEffect { get; }
|
||||||
|
|
||||||
|
@ -36,6 +38,7 @@ namespace Kav
|
||||||
private RenderTarget2D gNormal { get; }
|
private RenderTarget2D gNormal { get; }
|
||||||
private RenderTarget2D gAlbedo { get; }
|
private RenderTarget2D gAlbedo { get; }
|
||||||
private RenderTarget2D gMetallicRoughness { get; }
|
private RenderTarget2D gMetallicRoughness { get; }
|
||||||
|
private RenderTargetCube PointShadowCubeMap { get; }
|
||||||
|
|
||||||
private RenderTargetBinding[] GBuffer { get; }
|
private RenderTargetBinding[] GBuffer { get; }
|
||||||
|
|
||||||
|
@ -136,7 +139,16 @@ namespace Kav
|
||||||
new RenderTargetBinding(gMetallicRoughness)
|
new RenderTargetBinding(gMetallicRoughness)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PointShadowCubeMap = new RenderTargetCube(
|
||||||
|
GraphicsDevice,
|
||||||
|
shadowMapSize,
|
||||||
|
false,
|
||||||
|
SurfaceFormat.Single,
|
||||||
|
DepthFormat.Depth24
|
||||||
|
);
|
||||||
|
|
||||||
SimpleDepthEffect = new SimpleDepthEffect(GraphicsDevice);
|
SimpleDepthEffect = new SimpleDepthEffect(GraphicsDevice);
|
||||||
|
LinearDepthEffect = new LinearDepthEffect(GraphicsDevice);
|
||||||
DeferredPBREffect = new DeferredPBREffect(GraphicsDevice);
|
DeferredPBREffect = new DeferredPBREffect(GraphicsDevice);
|
||||||
|
|
||||||
Deferred_GBufferEffect = new DeferredPBR_GBufferEffect(GraphicsDevice);
|
Deferred_GBufferEffect = new DeferredPBR_GBufferEffect(GraphicsDevice);
|
||||||
|
@ -181,7 +193,7 @@ namespace Kav
|
||||||
|
|
||||||
foreach (var pointLight in pointLights)
|
foreach (var pointLight in pointLights)
|
||||||
{
|
{
|
||||||
PointLightRender(pointLight);
|
PointLightRender(camera, modelTransforms, pointLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectionalLightRender(camera, modelTransforms, directionalLight);
|
DirectionalLightRender(camera, modelTransforms, directionalLight);
|
||||||
|
@ -197,6 +209,7 @@ namespace Kav
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||||
AmbientLight ambientLight,
|
AmbientLight ambientLight,
|
||||||
|
IEnumerable<PointLight> pointLights,
|
||||||
DirectionalLight directionalLight,
|
DirectionalLight directionalLight,
|
||||||
TextureCube skybox
|
TextureCube skybox
|
||||||
) {
|
) {
|
||||||
|
@ -210,7 +223,11 @@ namespace Kav
|
||||||
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||||
|
|
||||||
AmbientLightRender(ambientLight);
|
AmbientLightRender(ambientLight);
|
||||||
DirectionalLightToonRender(camera, modelTransforms, directionalLight);
|
foreach (var pointLight in pointLights)
|
||||||
|
{
|
||||||
|
PointLightRender(camera, modelTransforms, pointLight);
|
||||||
|
}
|
||||||
|
//DirectionalLightToonRender(camera, modelTransforms, directionalLight);
|
||||||
SkyboxRender(camera, skybox);
|
SkyboxRender(camera, skybox);
|
||||||
|
|
||||||
GraphicsDevice.SetRenderTarget(null);
|
GraphicsDevice.SetRenderTarget(null);
|
||||||
|
@ -351,17 +368,29 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PointLightRender(PointLight pointLight)
|
private void PointLightRender(
|
||||||
{
|
PerspectiveCamera camera,
|
||||||
|
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||||
|
PointLight pointLight
|
||||||
|
) {
|
||||||
|
RenderPointShadows(camera, modelTransforms, pointLight);
|
||||||
|
|
||||||
|
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
||||||
|
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||||
|
GraphicsDevice.BlendState = BlendState.Additive;
|
||||||
|
|
||||||
DeferredPointLightEffect.GPosition = gPosition;
|
DeferredPointLightEffect.GPosition = gPosition;
|
||||||
DeferredPointLightEffect.GAlbedo = gAlbedo;
|
DeferredPointLightEffect.GAlbedo = gAlbedo;
|
||||||
DeferredPointLightEffect.GNormal = gNormal;
|
DeferredPointLightEffect.GNormal = gNormal;
|
||||||
DeferredPointLightEffect.GMetallicRoughness = gMetallicRoughness;
|
DeferredPointLightEffect.GMetallicRoughness = gMetallicRoughness;
|
||||||
|
DeferredPointLightEffect.ShadowMap = PointShadowCubeMap;
|
||||||
|
|
||||||
DeferredPointLightEffect.PointLightPosition = pointLight.Position;
|
DeferredPointLightEffect.PointLightPosition = pointLight.Position;
|
||||||
DeferredPointLightEffect.PointLightColor =
|
DeferredPointLightEffect.PointLightColor =
|
||||||
pointLight.Color.ToVector3() * pointLight.Intensity;
|
pointLight.Color.ToVector3() * pointLight.Intensity;
|
||||||
|
|
||||||
|
DeferredPointLightEffect.FarPlane = 25f; // FIXME: magic value
|
||||||
|
|
||||||
foreach (var pass in DeferredPointLightEffect.CurrentTechnique.Passes)
|
foreach (var pass in DeferredPointLightEffect.CurrentTechnique.Passes)
|
||||||
{
|
{
|
||||||
pass.Apply();
|
pass.Apply();
|
||||||
|
@ -375,7 +404,7 @@ namespace Kav
|
||||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||||
DirectionalLight directionalLight
|
DirectionalLight directionalLight
|
||||||
) {
|
) {
|
||||||
RenderShadows(camera, modelTransforms, directionalLight, DeferredDirectionalLightEffect);
|
RenderDirectionalShadows(camera, modelTransforms, directionalLight, DeferredDirectionalLightEffect);
|
||||||
|
|
||||||
DeferredDirectionalLightEffect.GPosition = gPosition;
|
DeferredDirectionalLightEffect.GPosition = gPosition;
|
||||||
DeferredDirectionalLightEffect.GAlbedo = gAlbedo;
|
DeferredDirectionalLightEffect.GAlbedo = gAlbedo;
|
||||||
|
@ -419,7 +448,7 @@ namespace Kav
|
||||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||||
DirectionalLight directionalLight
|
DirectionalLight directionalLight
|
||||||
) {
|
) {
|
||||||
RenderShadows(camera, modelTransforms, directionalLight, Deferred_ToonEffect);
|
RenderDirectionalShadows(camera, modelTransforms, directionalLight, Deferred_ToonEffect);
|
||||||
|
|
||||||
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
||||||
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||||
|
@ -461,7 +490,7 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RenderShadows(
|
private void RenderDirectionalShadows(
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||||
DirectionalLight directionalLight,
|
DirectionalLight directionalLight,
|
||||||
|
@ -485,14 +514,14 @@ namespace Kav
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: This is tightly coupled to the effect and it sucks
|
// TODO: This is tightly coupled to the effect and it sucks
|
||||||
RenderShadowMap(shadowCamera, modelTransforms, directionalLight, effect, i);
|
RenderDirectionalShadowMap(shadowCamera, modelTransforms, directionalLight, effect, i);
|
||||||
|
|
||||||
effect.CascadeFarPlanes[i] = farPlane;
|
effect.CascadeFarPlanes[i] = farPlane;
|
||||||
previousFarPlane = farPlane;
|
previousFarPlane = farPlane;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RenderShadowMap(
|
private void RenderDirectionalShadowMap(
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||||
DirectionalLight directionalLight,
|
DirectionalLight directionalLight,
|
||||||
|
@ -580,5 +609,102 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RenderPointShadows(
|
||||||
|
PerspectiveCamera camera,
|
||||||
|
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||||
|
PointLight pointLight
|
||||||
|
) {
|
||||||
|
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||||
|
GraphicsDevice.BlendState = BlendState.Opaque;
|
||||||
|
|
||||||
|
LinearDepthEffect.Projection = Matrix.CreatePerspectiveFieldOfView(
|
||||||
|
MathHelper.PiOver2,
|
||||||
|
1,
|
||||||
|
0.1f,
|
||||||
|
25f // FIXME: magic value
|
||||||
|
);
|
||||||
|
LinearDepthEffect.FarPlane = 25f;
|
||||||
|
LinearDepthEffect.LightPosition = pointLight.Position;
|
||||||
|
|
||||||
|
foreach (CubeMapFace face in Enum.GetValues(typeof(CubeMapFace)))
|
||||||
|
{
|
||||||
|
GraphicsDevice.SetRenderTarget(PointShadowCubeMap, face);
|
||||||
|
|
||||||
|
Vector3 targetDirection;
|
||||||
|
Vector3 targetUpDirection;
|
||||||
|
switch(face)
|
||||||
|
{
|
||||||
|
case CubeMapFace.PositiveX:
|
||||||
|
targetDirection = Vector3.Right;
|
||||||
|
targetUpDirection = Vector3.Up;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CubeMapFace.NegativeX:
|
||||||
|
targetDirection = Vector3.Left;
|
||||||
|
targetUpDirection = Vector3.Up;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CubeMapFace.PositiveY:
|
||||||
|
targetDirection = Vector3.Up;
|
||||||
|
targetUpDirection = Vector3.Forward;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CubeMapFace.NegativeY:
|
||||||
|
targetDirection = Vector3.Down;
|
||||||
|
targetUpDirection = Vector3.Backward;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CubeMapFace.PositiveZ:
|
||||||
|
targetDirection = Vector3.Backward;
|
||||||
|
targetUpDirection = Vector3.Up;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CubeMapFace.NegativeZ:
|
||||||
|
targetDirection = Vector3.Forward;
|
||||||
|
targetUpDirection = Vector3.Up;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
targetDirection = Vector3.Right;
|
||||||
|
targetUpDirection = Vector3.Up;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinearDepthEffect.View = Matrix.CreateLookAt(
|
||||||
|
pointLight.Position,
|
||||||
|
pointLight.Position + targetDirection,
|
||||||
|
targetUpDirection
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach (var (model, transform) in modelTransforms)
|
||||||
|
{
|
||||||
|
foreach (var modelMesh in model.Meshes)
|
||||||
|
{
|
||||||
|
foreach (var meshPart in modelMesh.MeshParts)
|
||||||
|
{
|
||||||
|
GraphicsDevice.SetVertexBuffer(meshPart.VertexBuffer);
|
||||||
|
GraphicsDevice.Indices = meshPart.IndexBuffer;
|
||||||
|
|
||||||
|
LinearDepthEffect.Model = transform;
|
||||||
|
|
||||||
|
foreach (var pass in LinearDepthEffect.CurrentTechnique.Passes)
|
||||||
|
{
|
||||||
|
pass.Apply();
|
||||||
|
|
||||||
|
GraphicsDevice.DrawIndexedPrimitives(
|
||||||
|
PrimitiveType.TriangleList,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
meshPart.VertexBuffer.VertexCount,
|
||||||
|
0,
|
||||||
|
meshPart.Triangles.Length
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
87
Resources.cs
87
Resources.cs
|
@ -10,7 +10,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
if (ambientLightEffect == null)
|
if (ambientLightEffect == null)
|
||||||
{
|
{
|
||||||
ambientLightEffect = GetResource("DeferredPBR_AmbientLightEffect.fxb");
|
ambientLightEffect = GetResource("DeferredPBR_AmbientLightEffect.fxb");
|
||||||
}
|
}
|
||||||
return ambientLightEffect;
|
return ambientLightEffect;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
if (pointLightEffect == null)
|
if (pointLightEffect == null)
|
||||||
{
|
{
|
||||||
pointLightEffect = GetResource("DeferredPBR_PointLightEffect.fxb");
|
pointLightEffect = GetResource("DeferredPBR_PointLightEffect.fxb");
|
||||||
}
|
}
|
||||||
return pointLightEffect;
|
return pointLightEffect;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
if (directionalLightEffect == null)
|
if (directionalLightEffect == null)
|
||||||
{
|
{
|
||||||
directionalLightEffect = GetResource("DeferredPBR_DirectionalLightEffect.fxb");
|
directionalLightEffect = GetResource("DeferredPBR_DirectionalLightEffect.fxb");
|
||||||
}
|
}
|
||||||
return directionalLightEffect;
|
return directionalLightEffect;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
if (gBufferEffect == null)
|
if (gBufferEffect == null)
|
||||||
{
|
{
|
||||||
gBufferEffect = GetResource("DeferredPBR_GBufferEffect.fxb");
|
gBufferEffect = GetResource("DeferredPBR_GBufferEffect.fxb");
|
||||||
}
|
}
|
||||||
return gBufferEffect;
|
return gBufferEffect;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
if (toneMapEffect == null)
|
if (toneMapEffect == null)
|
||||||
{
|
{
|
||||||
toneMapEffect = GetResource("ToneMapEffect.fxb");
|
toneMapEffect = GetResource("ToneMapEffect.fxb");
|
||||||
}
|
}
|
||||||
return toneMapEffect;
|
return toneMapEffect;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
if (deferredToonEffect == null)
|
if (deferredToonEffect == null)
|
||||||
{
|
{
|
||||||
deferredToonEffect = GetResource("Deferred_ToonEffect.fxb");
|
deferredToonEffect = GetResource("Deferred_ToonEffect.fxb");
|
||||||
}
|
}
|
||||||
return deferredToonEffect;
|
return deferredToonEffect;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
if (deferredPBREffect == null)
|
if (deferredPBREffect == null)
|
||||||
{
|
{
|
||||||
deferredPBREffect = GetResource("DeferredPBREffect.fxb");
|
deferredPBREffect = GetResource("DeferredPBREffect.fxb");
|
||||||
}
|
}
|
||||||
return deferredPBREffect;
|
return deferredPBREffect;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
if (pbrEffect == null)
|
if (pbrEffect == null)
|
||||||
{
|
{
|
||||||
pbrEffect = GetResource("PBREffect.fxb");
|
pbrEffect = GetResource("PBREffect.fxb");
|
||||||
}
|
}
|
||||||
return pbrEffect;
|
return pbrEffect;
|
||||||
}
|
}
|
||||||
|
@ -105,36 +105,48 @@ namespace Kav
|
||||||
{
|
{
|
||||||
if (simpleDepthEffect == null)
|
if (simpleDepthEffect == null)
|
||||||
{
|
{
|
||||||
simpleDepthEffect = GetResource("SimpleDepthEffect.fxb");
|
simpleDepthEffect = GetResource("SimpleDepthEffect.fxb");
|
||||||
}
|
}
|
||||||
return simpleDepthEffect;
|
return simpleDepthEffect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] SkyboxEffect
|
public static byte[] LinearDepthEffect
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (skyboxEffect == null)
|
if (linearDepthEffect == null)
|
||||||
{
|
{
|
||||||
skyboxEffect = GetResource("SkyboxEffect.fxb");
|
linearDepthEffect = GetResource("LinearDepthEffect.fxb");
|
||||||
}
|
}
|
||||||
return skyboxEffect;
|
return linearDepthEffect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] UnitCubeModel
|
public static byte[] SkyboxEffect
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (unitCubeModel == null)
|
if (skyboxEffect == null)
|
||||||
{
|
{
|
||||||
unitCubeModel = GetResource("UnitCube.glb");
|
skyboxEffect = GetResource("SkyboxEffect.fxb");
|
||||||
}
|
}
|
||||||
return unitCubeModel;
|
return skyboxEffect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] UnitCubeModel
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (unitCubeModel == null)
|
||||||
|
{
|
||||||
|
unitCubeModel = GetResource("UnitCube.glb");
|
||||||
|
}
|
||||||
|
return unitCubeModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static byte[] ambientLightEffect;
|
private static byte[] ambientLightEffect;
|
||||||
private static byte[] pointLightEffect;
|
private static byte[] pointLightEffect;
|
||||||
private static byte[] directionalLightEffect;
|
private static byte[] directionalLightEffect;
|
||||||
|
@ -144,14 +156,15 @@ namespace Kav
|
||||||
private static byte[] deferredPBREffect;
|
private static byte[] deferredPBREffect;
|
||||||
private static byte[] pbrEffect;
|
private static byte[] pbrEffect;
|
||||||
private static byte[] simpleDepthEffect;
|
private static byte[] simpleDepthEffect;
|
||||||
private static byte[] skyboxEffect;
|
private static byte[] linearDepthEffect;
|
||||||
|
private static byte[] skyboxEffect;
|
||||||
private static byte[] unitCubeModel;
|
|
||||||
|
private static byte[] unitCubeModel;
|
||||||
|
|
||||||
private static byte[] GetResource(string name)
|
private static byte[] GetResource(string name)
|
||||||
{
|
{
|
||||||
Stream stream = typeof(Resources).Assembly.GetManifestResourceStream(
|
Stream stream = typeof(Resources).Assembly.GetManifestResourceStream(
|
||||||
"Kav.Resources." + name
|
"Kav.Resources." + name
|
||||||
);
|
);
|
||||||
using (MemoryStream ms = new MemoryStream())
|
using (MemoryStream ms = new MemoryStream())
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue