started spotlight effect
parent
ed5a7df614
commit
b66f3a750a
|
@ -0,0 +1,79 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public class DeferredPBR_SpotLightEffect : Effect
|
||||||
|
{
|
||||||
|
EffectParameter gPositionParam;
|
||||||
|
EffectParameter gAlbedoParam;
|
||||||
|
EffectParameter gNormalParam;
|
||||||
|
EffectParameter gMetallicRoughnessParam;
|
||||||
|
EffectParameter shadowMapParam;
|
||||||
|
|
||||||
|
EffectParameter eyePositionParam;
|
||||||
|
|
||||||
|
EffectParameter lightPositionParam;
|
||||||
|
EffectParameter lightDirectionParam;
|
||||||
|
EffectParameter lightColorParam;
|
||||||
|
EffectParameter lightCutoffParam;
|
||||||
|
|
||||||
|
EffectParameter farPlaneParam;
|
||||||
|
|
||||||
|
public Texture2D GPosition { get; set; }
|
||||||
|
public Texture2D GAlbedo { get; set; }
|
||||||
|
public Texture2D GNormal { get; set; }
|
||||||
|
public Texture2D GMetallicRoughness { get; set; }
|
||||||
|
public TextureCube ShadowMap { get; set; }
|
||||||
|
|
||||||
|
public Vector3 EyePosition { get; set; }
|
||||||
|
|
||||||
|
public Vector3 LightPosition { get; set; }
|
||||||
|
public Vector3 LightDirection { get; set; }
|
||||||
|
public Vector3 LightColor { get; set; }
|
||||||
|
public float LightCutoff { get; set; } //could be named lightangle?
|
||||||
|
|
||||||
|
public float FarPlane { get; set; }
|
||||||
|
|
||||||
|
public DeferredPBR_SpotLightEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_SpotLightEffect)
|
||||||
|
{
|
||||||
|
CacheEffectParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApply()
|
||||||
|
{
|
||||||
|
gPositionParam.SetValue(GPosition);
|
||||||
|
gAlbedoParam.SetValue(GAlbedo);
|
||||||
|
gNormalParam.SetValue(GNormal);
|
||||||
|
gMetallicRoughnessParam.SetValue(GMetallicRoughness);
|
||||||
|
shadowMapParam.SetValue(ShadowMap);
|
||||||
|
|
||||||
|
eyePositionParam.SetValue(EyePosition);
|
||||||
|
|
||||||
|
lightPositionParam.SetValue(LightPosition);
|
||||||
|
lightDirectionParam.SetValue(LightDirection);
|
||||||
|
lightColorParam.SetValue(LightColor);
|
||||||
|
lightCutoffParam.SetValue(LightCutoff);
|
||||||
|
|
||||||
|
farPlaneParam.SetValue(FarPlane);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CacheEffectParameters()
|
||||||
|
{
|
||||||
|
gPositionParam = Parameters["gPosition"];
|
||||||
|
gAlbedoParam = Parameters["gAlbedo"];
|
||||||
|
gNormalParam = Parameters["gNormal"];
|
||||||
|
gMetallicRoughnessParam = Parameters["gMetallicRoughness"];
|
||||||
|
shadowMapParam = Parameters["shadowMap"];
|
||||||
|
|
||||||
|
eyePositionParam = Parameters["EyePosition"];
|
||||||
|
|
||||||
|
lightPositionParam = Parameters["LightPosition"];
|
||||||
|
lightDirectionParam = Parameters["LightDirection"];
|
||||||
|
lightColorParam = Parameters["LightColor"];
|
||||||
|
lightCutoffParam = Parameters["LightCutoff"];
|
||||||
|
|
||||||
|
farPlaneParam = Parameters["FarPlane"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
|
@ -68,7 +68,6 @@ float4 ComputeColor(
|
||||||
float3 color = ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, shadow);
|
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,109 @@
|
||||||
|
#include "Macros.fxh" //from FNA
|
||||||
|
#include "Lighting.fxh"
|
||||||
|
#include "Shadow.fxh"
|
||||||
|
|
||||||
|
DECLARE_TEXTURE(gPosition, 0);
|
||||||
|
DECLARE_TEXTURE(gAlbedo, 1);
|
||||||
|
DECLARE_TEXTURE(gNormal, 2);
|
||||||
|
DECLARE_TEXTURE(gMetallicRoughness, 3);
|
||||||
|
DECLARE_CUBEMAP(shadowMap, 4);
|
||||||
|
|
||||||
|
BEGIN_CONSTANTS
|
||||||
|
|
||||||
|
float3 EyePosition _ps(c0) _cb(c0);
|
||||||
|
|
||||||
|
float3 LightPosition _ps(c1) _cb(c1);
|
||||||
|
float3 LightDirection _ps(c2) _cb(c2);
|
||||||
|
float3 LightColor _ps(c3) _cb(c3);
|
||||||
|
float LightCutoff _ps(c4) _cb(c4);
|
||||||
|
|
||||||
|
float FarPlane _ps(c5) _cb(c5);
|
||||||
|
|
||||||
|
MATRIX_CONSTANTS
|
||||||
|
|
||||||
|
END_CONSTANTS
|
||||||
|
|
||||||
|
struct VertexInput
|
||||||
|
{
|
||||||
|
float4 Position : POSITION;
|
||||||
|
float2 TexCoord : TEXCOORD;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PixelInput
|
||||||
|
{
|
||||||
|
float4 Position : SV_POSITION;
|
||||||
|
float2 TexCoord : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
PixelInput main_vs(VertexInput input)
|
||||||
|
{
|
||||||
|
PixelInput output;
|
||||||
|
|
||||||
|
output.Position = input.Position;
|
||||||
|
output.TexCoord = input.TexCoord;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pixel Shader
|
||||||
|
|
||||||
|
float4 ComputeColor(
|
||||||
|
float3 worldPosition,
|
||||||
|
float3 worldNormal,
|
||||||
|
float3 albedo,
|
||||||
|
float metallic,
|
||||||
|
float roughness
|
||||||
|
) {
|
||||||
|
float3 V = normalize(EyePosition - worldPosition);
|
||||||
|
float3 N = normalize(worldNormal);
|
||||||
|
|
||||||
|
float3 F0 = float3(0.04, 0.04, 0.04);
|
||||||
|
F0 = lerp(F0, albedo, metallic);
|
||||||
|
|
||||||
|
float3 lightDir = LightPosition - worldPosition;
|
||||||
|
float3 L = normalize(lightDir);
|
||||||
|
float distance = length(lightDir);
|
||||||
|
float attenuation = 1.0 / (distance * distance);
|
||||||
|
float3 radiance = LightColor * attenuation;
|
||||||
|
|
||||||
|
//float shadow = HardPointShadow(worldPosition, N, L, PointLightPosition, SAMPLER(shadowMap), FarPlane);
|
||||||
|
float3 color = ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, 1.0);
|
||||||
|
|
||||||
|
return float4(color, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 main_ps(PixelInput input) : SV_TARGET0
|
||||||
|
{
|
||||||
|
float3 worldPosition = SAMPLE_TEXTURE(gPosition, input.TexCoord).rgb;
|
||||||
|
float3 normal = SAMPLE_TEXTURE(gNormal, input.TexCoord).xyz;
|
||||||
|
float3 albedo = SAMPLE_TEXTURE(gAlbedo, input.TexCoord).rgb;
|
||||||
|
float2 metallicRoughness = SAMPLE_TEXTURE(gMetallicRoughness, input.TexCoord).rg;
|
||||||
|
|
||||||
|
float3 lightDir = normalize(LightPosition - worldPosition);
|
||||||
|
|
||||||
|
float theta = dot(lightDir, normalize(-LightDirection));
|
||||||
|
|
||||||
|
if (theta > LightCutoff)
|
||||||
|
{
|
||||||
|
return ComputeColor(
|
||||||
|
worldPosition,
|
||||||
|
normal,
|
||||||
|
albedo,
|
||||||
|
metallicRoughness.r,
|
||||||
|
metallicRoughness.g
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return float4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique DeferredPBR_Point
|
||||||
|
{
|
||||||
|
Pass
|
||||||
|
{
|
||||||
|
VertexShader = compile vs_3_0 main_vs();
|
||||||
|
PixelShader = compile ps_3_0 main_ps();
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,9 @@
|
||||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_DirectionalLightEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\DeferredPBR_DirectionalLightEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.DeferredPBR_DirectionalLightEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.DeferredPBR_DirectionalLightEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Effects\FXB\DeferredPBR_SpotLightEffect.fxb">
|
||||||
|
<LogicalName>Kav.Resources.DeferredPBR_SpotLightEffect.fxb</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_GBufferEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\DeferredPBR_GBufferEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.DeferredPBR_GBufferEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.DeferredPBR_GBufferEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_GBufferEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\DeferredPBR_GBufferEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.DeferredPBR_GBufferEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.DeferredPBR_GBufferEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Effects\FXB\DeferredPBR_SpotLightEffect.fxb">
|
||||||
|
<LogicalName>Kav.Resources.DeferredPBR_SpotLightEffect.fxb</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Effects\FXB\ToneMapEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\ToneMapEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.ToneMapEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.ToneMapEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public struct SpotLight
|
||||||
|
{
|
||||||
|
public Vector3 Position { get; }
|
||||||
|
public Vector3 Direction { get; }
|
||||||
|
public Color Color { get; }
|
||||||
|
public float Intensity { get; }
|
||||||
|
public float Cutoff { get; }
|
||||||
|
|
||||||
|
public SpotLight(Vector3 position, Vector3 direction, Color color, float intensity, float cutoff)
|
||||||
|
{
|
||||||
|
Position = position;
|
||||||
|
Direction = direction;
|
||||||
|
Color = color;
|
||||||
|
Intensity = intensity;
|
||||||
|
Cutoff = cutoff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
58
Renderer.cs
58
Renderer.cs
|
@ -28,6 +28,7 @@ namespace Kav
|
||||||
private DeferredPBR_AmbientLightEffect DeferredAmbientLightEffect { get; }
|
private DeferredPBR_AmbientLightEffect DeferredAmbientLightEffect { get; }
|
||||||
private DeferredPBR_PointLightEffect DeferredPointLightEffect { get; }
|
private DeferredPBR_PointLightEffect DeferredPointLightEffect { get; }
|
||||||
private DeferredPBR_DirectionalLightEffect DeferredDirectionalLightEffect { get; }
|
private DeferredPBR_DirectionalLightEffect DeferredDirectionalLightEffect { get; }
|
||||||
|
private DeferredPBR_SpotLightEffect DeferredSpotLightEffect { 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 LinearDepthEffect LinearDepthEffect { get; }
|
||||||
|
@ -156,6 +157,7 @@ namespace Kav
|
||||||
DeferredPointLightEffect = new DeferredPBR_PointLightEffect(GraphicsDevice);
|
DeferredPointLightEffect = new DeferredPBR_PointLightEffect(GraphicsDevice);
|
||||||
DeferredDirectionalLightEffect = new DeferredPBR_DirectionalLightEffect(GraphicsDevice);
|
DeferredDirectionalLightEffect = new DeferredPBR_DirectionalLightEffect(GraphicsDevice);
|
||||||
DeferredDirectionalLightEffect.ShadowMapSize = ShadowMapSize;
|
DeferredDirectionalLightEffect.ShadowMapSize = ShadowMapSize;
|
||||||
|
DeferredSpotLightEffect = new DeferredPBR_SpotLightEffect(GraphicsDevice);
|
||||||
ToneMapEffect = new Effect(graphicsDevice, Resources.ToneMapEffect);
|
ToneMapEffect = new Effect(graphicsDevice, Resources.ToneMapEffect);
|
||||||
Deferred_ToonEffect = new Deferred_ToonEffect(GraphicsDevice);
|
Deferred_ToonEffect = new Deferred_ToonEffect(GraphicsDevice);
|
||||||
SkyboxEffect = new SkyboxEffect(GraphicsDevice);
|
SkyboxEffect = new SkyboxEffect(GraphicsDevice);
|
||||||
|
@ -193,7 +195,7 @@ namespace Kav
|
||||||
|
|
||||||
foreach (var pointLight in pointLights)
|
foreach (var pointLight in pointLights)
|
||||||
{
|
{
|
||||||
PointLightRender(camera, modelTransforms, pointLight);
|
PointLightRender(modelTransforms, pointLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectionalLightRender(camera, modelTransforms, directionalLight);
|
DirectionalLightRender(camera, modelTransforms, directionalLight);
|
||||||
|
@ -208,9 +210,10 @@ namespace Kav
|
||||||
public void DeferredToonRender(
|
public void DeferredToonRender(
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||||
AmbientLight ambientLight,
|
AmbientLight? ambientLight,
|
||||||
IEnumerable<PointLight> pointLights,
|
IEnumerable<PointLight> pointLights,
|
||||||
DirectionalLight directionalLight,
|
IEnumerable<SpotLight> spotLights,
|
||||||
|
DirectionalLight? directionalLight,
|
||||||
TextureCube skybox
|
TextureCube skybox
|
||||||
) {
|
) {
|
||||||
GBufferRender(camera, modelTransforms);
|
GBufferRender(camera, modelTransforms);
|
||||||
|
@ -222,12 +225,22 @@ namespace Kav
|
||||||
DepthRender(camera, modelTransforms);
|
DepthRender(camera, modelTransforms);
|
||||||
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||||
|
|
||||||
AmbientLightRender(ambientLight);
|
if (ambientLight.HasValue)
|
||||||
|
{
|
||||||
|
AmbientLightRender(ambientLight.Value);
|
||||||
|
}
|
||||||
foreach (var pointLight in pointLights)
|
foreach (var pointLight in pointLights)
|
||||||
{
|
{
|
||||||
PointLightRender(camera, modelTransforms, pointLight);
|
PointLightRender(modelTransforms, pointLight);
|
||||||
|
}
|
||||||
|
foreach (var spotLight in spotLights)
|
||||||
|
{
|
||||||
|
SpotLightRender(modelTransforms, spotLight);
|
||||||
|
}
|
||||||
|
if (directionalLight.HasValue)
|
||||||
|
{
|
||||||
|
DirectionalLightToonRender(camera, modelTransforms, directionalLight.Value);
|
||||||
}
|
}
|
||||||
DirectionalLightToonRender(camera, modelTransforms, directionalLight);
|
|
||||||
SkyboxRender(camera, skybox);
|
SkyboxRender(camera, skybox);
|
||||||
|
|
||||||
GraphicsDevice.SetRenderTarget(null);
|
GraphicsDevice.SetRenderTarget(null);
|
||||||
|
@ -373,11 +386,10 @@ namespace Kav
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PointLightRender(
|
private void PointLightRender(
|
||||||
PerspectiveCamera camera,
|
|
||||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||||
PointLight pointLight
|
PointLight pointLight
|
||||||
) {
|
) {
|
||||||
RenderPointShadows(camera, modelTransforms, pointLight);
|
RenderPointShadows(modelTransforms, pointLight);
|
||||||
|
|
||||||
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
||||||
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||||
|
@ -403,6 +415,35 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SpotLightRender(
|
||||||
|
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||||
|
SpotLight spotLight
|
||||||
|
) {
|
||||||
|
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
||||||
|
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||||
|
GraphicsDevice.BlendState = BlendState.Additive;
|
||||||
|
|
||||||
|
DeferredSpotLightEffect.GPosition = gPosition;
|
||||||
|
DeferredSpotLightEffect.GAlbedo = gAlbedo;
|
||||||
|
DeferredSpotLightEffect.GNormal = gNormal;
|
||||||
|
DeferredSpotLightEffect.GMetallicRoughness = gMetallicRoughness;
|
||||||
|
|
||||||
|
DeferredSpotLightEffect.LightPosition = spotLight.Position;
|
||||||
|
DeferredSpotLightEffect.LightDirection = spotLight.Direction;
|
||||||
|
DeferredSpotLightEffect.LightColor =
|
||||||
|
spotLight.Color.ToVector3() * spotLight.Intensity;
|
||||||
|
DeferredSpotLightEffect.LightCutoff = spotLight.Cutoff;
|
||||||
|
|
||||||
|
DeferredSpotLightEffect.FarPlane = 25f; // FIXME: magic value
|
||||||
|
|
||||||
|
foreach (var pass in DeferredSpotLightEffect.CurrentTechnique.Passes)
|
||||||
|
{
|
||||||
|
pass.Apply();
|
||||||
|
GraphicsDevice.SetVertexBuffer(FullscreenTriangle);
|
||||||
|
GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void DirectionalLightRender(
|
private void DirectionalLightRender(
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||||
|
@ -617,7 +658,6 @@ namespace Kav
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RenderPointShadows(
|
private void RenderPointShadows(
|
||||||
PerspectiveCamera camera,
|
|
||||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||||
PointLight pointLight
|
PointLight pointLight
|
||||||
) {
|
) {
|
||||||
|
|
13
Resources.cs
13
Resources.cs
|
@ -39,6 +39,18 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] DeferredPBR_SpotLightEffect
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (spotLightEffect == null)
|
||||||
|
{
|
||||||
|
spotLightEffect = GetResource("DeferredPBR_SpotLightEffect.fxb");
|
||||||
|
}
|
||||||
|
return spotLightEffect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] DeferredPBR_GBufferEffect
|
public static byte[] DeferredPBR_GBufferEffect
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -150,6 +162,7 @@ namespace Kav
|
||||||
private static byte[] ambientLightEffect;
|
private static byte[] ambientLightEffect;
|
||||||
private static byte[] pointLightEffect;
|
private static byte[] pointLightEffect;
|
||||||
private static byte[] directionalLightEffect;
|
private static byte[] directionalLightEffect;
|
||||||
|
private static byte[] spotLightEffect;
|
||||||
private static byte[] gBufferEffect;
|
private static byte[] gBufferEffect;
|
||||||
private static byte[] toneMapEffect;
|
private static byte[] toneMapEffect;
|
||||||
private static byte[] deferredToonEffect;
|
private static byte[] deferredToonEffect;
|
||||||
|
|
Loading…
Reference in New Issue