deferred skybox
parent
19a61985ca
commit
06e5523996
Binary file not shown.
|
@ -0,0 +1,45 @@
|
|||
#include "Macros.fxh"
|
||||
|
||||
DECLARE_CUBEMAP(skybox, 0);
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
float4x4 ViewProjection _vs(c0) _cb(c0);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float3 Position : POSITION;
|
||||
};
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float3 TexCoord : TEXCOORD;
|
||||
};
|
||||
|
||||
VertexShaderOutput main_vs(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
|
||||
output.Position = mul(float4(input.Position, 1.0), ViewProjection);
|
||||
output.Position = output.Position.xyww;
|
||||
output.TexCoord = input.Position;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 main_ps(VertexShaderOutput input) : SV_TARGET0
|
||||
{
|
||||
return SAMPLE_CUBEMAP(skybox, input.TexCoord);
|
||||
}
|
||||
|
||||
Technique Skybox
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 main_vs();
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class SkyboxEffect : Effect
|
||||
{
|
||||
EffectParameter viewProjectionParam;
|
||||
EffectParameter skyboxParam;
|
||||
|
||||
Matrix view;
|
||||
Matrix projection;
|
||||
TextureCube skybox;
|
||||
|
||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||
|
||||
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 TextureCube Skybox
|
||||
{
|
||||
get { return skybox; }
|
||||
set
|
||||
{
|
||||
skybox = value;
|
||||
dirtyFlags |= EffectDirtyFlags.World; // hack flag but whatever
|
||||
}
|
||||
}
|
||||
|
||||
public SkyboxEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.SkyboxEffect)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
||||
{
|
||||
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
||||
|
||||
viewProjectionParam.SetValue(viewProjection);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
||||
}
|
||||
|
||||
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
||||
{
|
||||
skyboxParam.SetValue(skybox);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.World;
|
||||
}
|
||||
}
|
||||
|
||||
private void CacheEffectParameters()
|
||||
{
|
||||
viewProjectionParam = Parameters["ViewProjection"];
|
||||
skyboxParam = Parameters["skybox"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,6 +42,12 @@
|
|||
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
||||
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
||||
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Models\UnitCube.glb">
|
||||
<LogicalName>Kav.Resources.UnitCube.glb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -42,6 +42,12 @@
|
|||
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
||||
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
||||
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Models\UnitCube.glb">
|
||||
<LogicalName>Kav.Resources.UnitCube.glb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
Binary file not shown.
94
Renderer.cs
94
Renderer.cs
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
|
@ -29,6 +30,7 @@ namespace Kav
|
|||
private Deferred_ToonEffect Deferred_ToonEffect { get; }
|
||||
private SimpleDepthEffect SimpleDepthEffect { get; }
|
||||
private Effect ToneMapEffect { get; }
|
||||
private SkyboxEffect SkyboxEffect { get; }
|
||||
|
||||
private RenderTarget2D gPosition { get; }
|
||||
private RenderTarget2D gNormal { get; }
|
||||
|
@ -37,6 +39,8 @@ namespace Kav
|
|||
|
||||
private RenderTargetBinding[] GBuffer { get; }
|
||||
|
||||
private Kav.Model UnitCube { get; }
|
||||
|
||||
private SpriteBatch SpriteBatch { get; }
|
||||
|
||||
public Renderer(
|
||||
|
@ -73,7 +77,7 @@ namespace Kav
|
|||
renderDimensionsY,
|
||||
false,
|
||||
SurfaceFormat.Color,
|
||||
DepthFormat.None,
|
||||
DepthFormat.Depth24,
|
||||
0,
|
||||
RenderTargetUsage.PreserveContents
|
||||
);
|
||||
|
@ -142,6 +146,7 @@ namespace Kav
|
|||
DeferredDirectionalLightEffect.ShadowMapSize = ShadowMapSize;
|
||||
ToneMapEffect = new Effect(graphicsDevice, Resources.ToneMapEffect);
|
||||
Deferred_ToonEffect = new Deferred_ToonEffect(GraphicsDevice);
|
||||
SkyboxEffect = new SkyboxEffect(GraphicsDevice);
|
||||
|
||||
FullscreenTriangle = new VertexBuffer(GraphicsDevice, typeof(VertexPositionTexture), 3, BufferUsage.WriteOnly);
|
||||
FullscreenTriangle.SetData(new VertexPositionTexture[3] {
|
||||
|
@ -150,6 +155,11 @@ namespace Kav
|
|||
new VertexPositionTexture(new Vector3(3, 1, 0), new Vector2(2, 0))
|
||||
});
|
||||
|
||||
UnitCube = Kav.ModelLoader.Load(
|
||||
GraphicsDevice,
|
||||
Smuggler.Importer.ImportGLB(GraphicsDevice, new MemoryStream(Resources.UnitCubeModel))
|
||||
);
|
||||
|
||||
SpriteBatch = new SpriteBatch(graphicsDevice);
|
||||
}
|
||||
|
||||
|
@ -187,23 +197,95 @@ namespace Kav
|
|||
PerspectiveCamera camera,
|
||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||
AmbientLight ambientLight,
|
||||
DirectionalLight directionalLight
|
||||
DirectionalLight directionalLight,
|
||||
TextureCube skybox
|
||||
) {
|
||||
GBufferRender(camera, modelTransforms);
|
||||
|
||||
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
||||
GraphicsDevice.Clear(Color.Black);
|
||||
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1f, 0);
|
||||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||
|
||||
DepthRender(camera, modelTransforms);
|
||||
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||
|
||||
AmbientLightRender(ambientLight);
|
||||
DirectionalLightToonRender(camera, modelTransforms, directionalLight);
|
||||
SkyboxRender(camera, skybox);
|
||||
|
||||
GraphicsDevice.SetRenderTarget(null);
|
||||
GraphicsDevice.Clear(Color.Black);
|
||||
SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, null);
|
||||
SpriteBatch.Draw(ColorRenderTarget, Vector2.Zero, Color.White);
|
||||
SpriteBatch.End();
|
||||
}
|
||||
|
||||
private void DepthRender(
|
||||
PerspectiveCamera camera,
|
||||
IEnumerable<(Model, Matrix)> modelTransforms
|
||||
) {
|
||||
foreach (var (model, transform) in modelTransforms)
|
||||
{
|
||||
foreach (var modelMesh in model.Meshes)
|
||||
{
|
||||
foreach (var meshPart in modelMesh.MeshParts)
|
||||
{
|
||||
SimpleDepthEffect.Model = transform;
|
||||
SimpleDepthEffect.View = camera.View;
|
||||
SimpleDepthEffect.Projection = camera.Projection;
|
||||
|
||||
GraphicsDevice.SetVertexBuffer(meshPart.VertexBuffer);
|
||||
GraphicsDevice.Indices = meshPart.IndexBuffer;
|
||||
|
||||
foreach (var pass in SimpleDepthEffect.CurrentTechnique.Passes)
|
||||
{
|
||||
pass.Apply();
|
||||
|
||||
GraphicsDevice.DrawIndexedPrimitives(
|
||||
PrimitiveType.TriangleList,
|
||||
0,
|
||||
0,
|
||||
meshPart.VertexBuffer.VertexCount,
|
||||
0,
|
||||
meshPart.Triangles.Length
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SkyboxRender(
|
||||
PerspectiveCamera camera,
|
||||
TextureCube skybox
|
||||
) {
|
||||
GraphicsDevice.RasterizerState.CullMode = CullMode.CullClockwiseFace;
|
||||
SkyboxEffect.Skybox = skybox;
|
||||
|
||||
var view = camera.View;
|
||||
view.Translation = Vector3.Zero;
|
||||
SkyboxEffect.View = view;
|
||||
|
||||
SkyboxEffect.Projection = camera.Projection;
|
||||
|
||||
GraphicsDevice.SetVertexBuffer(UnitCube.Meshes[0].MeshParts[0].VertexBuffer);
|
||||
GraphicsDevice.Indices = UnitCube.Meshes[0].MeshParts[0].IndexBuffer;
|
||||
|
||||
foreach (var pass in SkyboxEffect.CurrentTechnique.Passes)
|
||||
{
|
||||
pass.Apply();
|
||||
|
||||
GraphicsDevice.DrawIndexedPrimitives(
|
||||
PrimitiveType.TriangleList,
|
||||
0,
|
||||
0,
|
||||
UnitCube.Meshes[0].MeshParts[0].VertexBuffer.VertexCount,
|
||||
0,
|
||||
UnitCube.Meshes[0].MeshParts[0].Triangles.Length
|
||||
);
|
||||
}
|
||||
GraphicsDevice.RasterizerState.CullMode = CullMode.CullCounterClockwiseFace;
|
||||
}
|
||||
|
||||
private void GBufferRender(
|
||||
PerspectiveCamera camera,
|
||||
IEnumerable<(Model, Matrix)> modelTransforms
|
||||
|
@ -255,8 +337,7 @@ namespace Kav
|
|||
private void AmbientLightRender(AmbientLight ambientLight)
|
||||
{
|
||||
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
||||
GraphicsDevice.BlendState = BlendState.Additive;
|
||||
GraphicsDevice.DepthStencilState = DepthStencilState.None;
|
||||
GraphicsDevice.BlendState = BlendState.Opaque;
|
||||
|
||||
DeferredAmbientLightEffect.GPosition = gPosition;
|
||||
DeferredAmbientLightEffect.GAlbedo = gAlbedo;
|
||||
|
@ -341,6 +422,7 @@ namespace Kav
|
|||
RenderShadows(camera, modelTransforms, directionalLight, Deferred_ToonEffect);
|
||||
|
||||
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
||||
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||
GraphicsDevice.BlendState = BlendState.Additive;
|
||||
|
||||
Deferred_ToonEffect.GPosition = gPosition;
|
||||
|
|
47
Resources.cs
47
Resources.cs
|
@ -10,7 +10,7 @@ namespace Kav
|
|||
{
|
||||
if (ambientLightEffect == null)
|
||||
{
|
||||
ambientLightEffect = GetResource("DeferredPBR_AmbientLightEffect");
|
||||
ambientLightEffect = GetResource("DeferredPBR_AmbientLightEffect.fxb");
|
||||
}
|
||||
return ambientLightEffect;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace Kav
|
|||
{
|
||||
if (pointLightEffect == null)
|
||||
{
|
||||
pointLightEffect = GetResource("DeferredPBR_PointLightEffect");
|
||||
pointLightEffect = GetResource("DeferredPBR_PointLightEffect.fxb");
|
||||
}
|
||||
return pointLightEffect;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ namespace Kav
|
|||
{
|
||||
if (directionalLightEffect == null)
|
||||
{
|
||||
directionalLightEffect = GetResource("DeferredPBR_DirectionalLightEffect");
|
||||
directionalLightEffect = GetResource("DeferredPBR_DirectionalLightEffect.fxb");
|
||||
}
|
||||
return directionalLightEffect;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ namespace Kav
|
|||
{
|
||||
if (gBufferEffect == null)
|
||||
{
|
||||
gBufferEffect = GetResource("DeferredPBR_GBufferEffect");
|
||||
gBufferEffect = GetResource("DeferredPBR_GBufferEffect.fxb");
|
||||
}
|
||||
return gBufferEffect;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ namespace Kav
|
|||
{
|
||||
if (toneMapEffect == null)
|
||||
{
|
||||
toneMapEffect = GetResource("ToneMapEffect");
|
||||
toneMapEffect = GetResource("ToneMapEffect.fxb");
|
||||
}
|
||||
return toneMapEffect;
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ namespace Kav
|
|||
{
|
||||
if (deferredToonEffect == null)
|
||||
{
|
||||
deferredToonEffect = GetResource("Deferred_ToonEffect");
|
||||
deferredToonEffect = GetResource("Deferred_ToonEffect.fxb");
|
||||
}
|
||||
return deferredToonEffect;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ namespace Kav
|
|||
{
|
||||
if (deferredPBREffect == null)
|
||||
{
|
||||
deferredPBREffect = GetResource("DeferredPBREffect");
|
||||
deferredPBREffect = GetResource("DeferredPBREffect.fxb");
|
||||
}
|
||||
return deferredPBREffect;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ namespace Kav
|
|||
{
|
||||
if (pbrEffect == null)
|
||||
{
|
||||
pbrEffect = GetResource("PBREffect");
|
||||
pbrEffect = GetResource("PBREffect.fxb");
|
||||
}
|
||||
return pbrEffect;
|
||||
}
|
||||
|
@ -105,12 +105,36 @@ namespace Kav
|
|||
{
|
||||
if (simpleDepthEffect == null)
|
||||
{
|
||||
simpleDepthEffect = GetResource("SimpleDepthEffect");
|
||||
simpleDepthEffect = GetResource("SimpleDepthEffect.fxb");
|
||||
}
|
||||
return simpleDepthEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] SkyboxEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (skyboxEffect == null)
|
||||
{
|
||||
skyboxEffect = GetResource("SkyboxEffect.fxb");
|
||||
}
|
||||
return skyboxEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] UnitCubeModel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (unitCubeModel == null)
|
||||
{
|
||||
unitCubeModel = GetResource("UnitCube.glb");
|
||||
}
|
||||
return unitCubeModel;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] ambientLightEffect;
|
||||
private static byte[] pointLightEffect;
|
||||
private static byte[] directionalLightEffect;
|
||||
|
@ -120,11 +144,14 @@ namespace Kav
|
|||
private static byte[] deferredPBREffect;
|
||||
private static byte[] pbrEffect;
|
||||
private static byte[] simpleDepthEffect;
|
||||
private static byte[] skyboxEffect;
|
||||
|
||||
private static byte[] unitCubeModel;
|
||||
|
||||
private static byte[] GetResource(string name)
|
||||
{
|
||||
Stream stream = typeof(Resources).Assembly.GetManifestResourceStream(
|
||||
"Kav.Resources." + name + ".fxb"
|
||||
"Kav.Resources." + name
|
||||
);
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue