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);
|
||||
|
||||
return float4(color, 1.0);
|
||||
//return float4(shadow, shadow, shadow, 1.0);
|
||||
}
|
||||
|
||||
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">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_DirectionalLightEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_SpotLightEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_SpotLightEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_GBufferEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_GBufferEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_GBufferEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_GBufferEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_SpotLightEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DeferredPBR_SpotLightEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\ToneMapEffect.fxb">
|
||||
<LogicalName>Kav.Resources.ToneMapEffect.fxb</LogicalName>
|
||||
</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_PointLightEffect DeferredPointLightEffect { get; }
|
||||
private DeferredPBR_DirectionalLightEffect DeferredDirectionalLightEffect { get; }
|
||||
private DeferredPBR_SpotLightEffect DeferredSpotLightEffect { get; }
|
||||
private Deferred_ToonEffect Deferred_ToonEffect { get; }
|
||||
private SimpleDepthEffect SimpleDepthEffect { get; }
|
||||
private LinearDepthEffect LinearDepthEffect { get; }
|
||||
|
@ -156,6 +157,7 @@ namespace Kav
|
|||
DeferredPointLightEffect = new DeferredPBR_PointLightEffect(GraphicsDevice);
|
||||
DeferredDirectionalLightEffect = new DeferredPBR_DirectionalLightEffect(GraphicsDevice);
|
||||
DeferredDirectionalLightEffect.ShadowMapSize = ShadowMapSize;
|
||||
DeferredSpotLightEffect = new DeferredPBR_SpotLightEffect(GraphicsDevice);
|
||||
ToneMapEffect = new Effect(graphicsDevice, Resources.ToneMapEffect);
|
||||
Deferred_ToonEffect = new Deferred_ToonEffect(GraphicsDevice);
|
||||
SkyboxEffect = new SkyboxEffect(GraphicsDevice);
|
||||
|
@ -193,7 +195,7 @@ namespace Kav
|
|||
|
||||
foreach (var pointLight in pointLights)
|
||||
{
|
||||
PointLightRender(camera, modelTransforms, pointLight);
|
||||
PointLightRender(modelTransforms, pointLight);
|
||||
}
|
||||
|
||||
DirectionalLightRender(camera, modelTransforms, directionalLight);
|
||||
|
@ -208,9 +210,10 @@ namespace Kav
|
|||
public void DeferredToonRender(
|
||||
PerspectiveCamera camera,
|
||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||
AmbientLight ambientLight,
|
||||
AmbientLight? ambientLight,
|
||||
IEnumerable<PointLight> pointLights,
|
||||
DirectionalLight directionalLight,
|
||||
IEnumerable<SpotLight> spotLights,
|
||||
DirectionalLight? directionalLight,
|
||||
TextureCube skybox
|
||||
) {
|
||||
GBufferRender(camera, modelTransforms);
|
||||
|
@ -222,12 +225,22 @@ namespace Kav
|
|||
DepthRender(camera, modelTransforms);
|
||||
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||
|
||||
AmbientLightRender(ambientLight);
|
||||
if (ambientLight.HasValue)
|
||||
{
|
||||
AmbientLightRender(ambientLight.Value);
|
||||
}
|
||||
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);
|
||||
|
||||
GraphicsDevice.SetRenderTarget(null);
|
||||
|
@ -373,11 +386,10 @@ namespace Kav
|
|||
}
|
||||
|
||||
private void PointLightRender(
|
||||
PerspectiveCamera camera,
|
||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||
PointLight pointLight
|
||||
) {
|
||||
RenderPointShadows(camera, modelTransforms, pointLight);
|
||||
RenderPointShadows(modelTransforms, pointLight);
|
||||
|
||||
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
||||
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(
|
||||
PerspectiveCamera camera,
|
||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||
|
@ -617,7 +658,6 @@ namespace Kav
|
|||
}
|
||||
|
||||
private void RenderPointShadows(
|
||||
PerspectiveCamera camera,
|
||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||
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
|
||||
{
|
||||
get
|
||||
|
@ -150,6 +162,7 @@ namespace Kav
|
|||
private static byte[] ambientLightEffect;
|
||||
private static byte[] pointLightEffect;
|
||||
private static byte[] directionalLightEffect;
|
||||
private static byte[] spotLightEffect;
|
||||
private static byte[] gBufferEffect;
|
||||
private static byte[] toneMapEffect;
|
||||
private static byte[] deferredToonEffect;
|
||||
|
|
Loading…
Reference in New Issue