diff --git a/Effects/DeferredPBR_PointLightEffect.cs b/Effects/DeferredPBR_PointLightEffect.cs index 6f959ea..82a73ea 100644 --- a/Effects/DeferredPBR_PointLightEffect.cs +++ b/Effects/DeferredPBR_PointLightEffect.cs @@ -9,22 +9,28 @@ namespace Kav EffectParameter gAlbedoParam; EffectParameter gNormalParam; EffectParameter gMetallicRoughnessParam; + EffectParameter shadowMapParam; EffectParameter eyePositionParam; EffectParameter pointLightColorParam; EffectParameter pointLightPositionParam; + 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 PointLightPosition { get; set; } public Vector3 PointLightColor { get; set; } + public float FarPlane { get; set; } + public DeferredPBR_PointLightEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_PointLightEffect) { CacheEffectParameters(); @@ -32,15 +38,20 @@ namespace Kav public DeferredPBR_PointLightEffect(DeferredPBR_PointLightEffect cloneSource) : base(cloneSource) { + CacheEffectParameters(); + GPosition = cloneSource.GPosition; GAlbedo = cloneSource.GAlbedo; GNormal = cloneSource.GNormal; GMetallicRoughness = cloneSource.GMetallicRoughness; + ShadowMap = cloneSource.ShadowMap; EyePosition = cloneSource.EyePosition; PointLightPosition = cloneSource.PointLightPosition; PointLightColor = cloneSource.PointLightColor; + + FarPlane = cloneSource.FarPlane; } public override Effect Clone() @@ -54,11 +65,14 @@ namespace Kav gAlbedoParam.SetValue(GAlbedo); gNormalParam.SetValue(GNormal); gMetallicRoughnessParam.SetValue(GMetallicRoughness); + shadowMapParam.SetValue(ShadowMap); eyePositionParam.SetValue(EyePosition); pointLightPositionParam.SetValue(PointLightPosition); pointLightColorParam.SetValue(PointLightColor); + + farPlaneParam.SetValue(FarPlane); } void CacheEffectParameters() @@ -67,11 +81,14 @@ namespace Kav gAlbedoParam = Parameters["gAlbedo"]; gNormalParam = Parameters["gNormal"]; gMetallicRoughnessParam = Parameters["gMetallicRoughness"]; + shadowMapParam = Parameters["shadowMap"]; eyePositionParam = Parameters["EyePosition"]; pointLightPositionParam = Parameters["PointLightPosition"]; pointLightColorParam = Parameters["PointLightColor"]; + + farPlaneParam = Parameters["FarPlane"]; } } } diff --git a/Effects/FXB/DeferredPBR_PointLightEffect.fxb b/Effects/FXB/DeferredPBR_PointLightEffect.fxb index 398f66b..330086e 100644 --- a/Effects/FXB/DeferredPBR_PointLightEffect.fxb +++ b/Effects/FXB/DeferredPBR_PointLightEffect.fxb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e51395e0f0dd1e1b86272dde1e4fb5aea1fdf9b86399416015ad33cfb7260691 -size 3108 +oid sha256:0331c52bcbc31d3639743c487ff1b48e6e90c5c4f9134f6b2154736a9dd8d6d0 +size 3740 diff --git a/Effects/FXB/LinearDepthEffect.fxb b/Effects/FXB/LinearDepthEffect.fxb new file mode 100644 index 0000000..f805053 --- /dev/null +++ b/Effects/FXB/LinearDepthEffect.fxb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9509896b7532c6ecf77aef4e575a7bceb8a106f4ad0c1a9c11a1608c9807cc10 +size 1332 diff --git a/Effects/FXB/SimpleDepthEffect.fxb b/Effects/FXB/SimpleDepthEffect.fxb index c60bf15..8281157 100644 --- a/Effects/FXB/SimpleDepthEffect.fxb +++ b/Effects/FXB/SimpleDepthEffect.fxb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b7e52830f9c3e89d230f12b98bc42cbc3af7a488c584c9ff48cd571115d57d85 -size 832 +oid sha256:e0984ae92245afe3e2bda5fab0135293b5121c3ee7b5f146e7d4ddd1684ee74b +size 848 diff --git a/Effects/HLSL/DeferredPBR_PointLightEffect.fx b/Effects/HLSL/DeferredPBR_PointLightEffect.fx index fba3c6e..d6e1933 100644 --- a/Effects/HLSL/DeferredPBR_PointLightEffect.fx +++ b/Effects/HLSL/DeferredPBR_PointLightEffect.fx @@ -1,10 +1,12 @@ #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 @@ -13,6 +15,8 @@ BEGIN_CONSTANTS float3 PointLightPosition _ps(c1) _cb(c1); float3 PointLightColor _ps(c2) _cb(c2); + float FarPlane _ps(c3) _cb(c3); + MATRIX_CONSTANTS END_CONSTANTS @@ -60,9 +64,11 @@ float4 ComputeColor( float attenuation = 1.0 / (distance * distance); 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(shadow, shadow, shadow, 1.0); } float4 main_ps(PixelInput input) : SV_TARGET0 diff --git a/Effects/HLSL/LinearDepthEffect.fx b/Effects/HLSL/LinearDepthEffect.fx new file mode 100644 index 0000000..164da5b --- /dev/null +++ b/Effects/HLSL/LinearDepthEffect.fx @@ -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(); + } +} diff --git a/Effects/HLSL/Shadow.fxh b/Effects/HLSL/Shadow.fxh index 47af839..c1bb9ba 100644 --- a/Effects/HLSL/Shadow.fxh +++ b/Effects/HLSL/Shadow.fxh @@ -120,3 +120,23 @@ float HardShadow( 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; +} diff --git a/Effects/HLSL/SimpleDepthEffect.fx b/Effects/HLSL/SimpleDepthEffect.fx index 3598eb5..f813bd7 100644 --- a/Effects/HLSL/SimpleDepthEffect.fx +++ b/Effects/HLSL/SimpleDepthEffect.fx @@ -24,7 +24,7 @@ VertexShaderOutput main_vs(VertexShaderInput input) VertexShaderOutput output; output.Position = mul(input.Position, ModelViewProjection); - output.Depth = output.Position.z; + output.Depth = output.Position.z / output.Position.w; return output; } diff --git a/Effects/LinearDepthEffect.cs b/Effects/LinearDepthEffect.cs new file mode 100644 index 0000000..2a6a76a --- /dev/null +++ b/Effects/LinearDepthEffect.cs @@ -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"]; + } + } +} diff --git a/Kav.Core.csproj b/Kav.Core.csproj index fc78de4..1a7954e 100644 --- a/Kav.Core.csproj +++ b/Kav.Core.csproj @@ -42,6 +42,9 @@ Kav.Resources.SimpleDepthEffect.fxb + + Kav.Resources.LinearDepthEffect.fxb + Kav.Resources.SkyboxEffect.fxb diff --git a/Kav.Framework.csproj b/Kav.Framework.csproj index 4b72a58..c60f949 100644 --- a/Kav.Framework.csproj +++ b/Kav.Framework.csproj @@ -42,12 +42,15 @@ Kav.Resources.SimpleDepthEffect.fxb - - Kav.Resources.SkyboxEffect.fxb - - - Kav.Resources.UnitCube.glb - + + Kav.Resources.LinearDepthEffect.fxb + + + Kav.Resources.SkyboxEffect.fxb + + + Kav.Resources.UnitCube.glb + diff --git a/README.md b/README.md index 8f3190b..9cfb2c3 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Essential - [ ] Frustum culling - [ ] Shadow-casting point lights - [ ] Parabolic lights -- [ ] Skyboxes +- [x] Skyboxes - [ ] Screen-space reflection Nice-To-Haves diff --git a/Renderer.cs b/Renderer.cs index 2e11a73..27b4b1b 100644 --- a/Renderer.cs +++ b/Renderer.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; @@ -29,6 +30,7 @@ namespace Kav private DeferredPBR_DirectionalLightEffect DeferredDirectionalLightEffect { get; } private Deferred_ToonEffect Deferred_ToonEffect { get; } private SimpleDepthEffect SimpleDepthEffect { get; } + private LinearDepthEffect LinearDepthEffect { get; } private Effect ToneMapEffect { get; } private SkyboxEffect SkyboxEffect { get; } @@ -36,6 +38,7 @@ namespace Kav private RenderTarget2D gNormal { get; } private RenderTarget2D gAlbedo { get; } private RenderTarget2D gMetallicRoughness { get; } + private RenderTargetCube PointShadowCubeMap { get; } private RenderTargetBinding[] GBuffer { get; } @@ -136,7 +139,16 @@ namespace Kav new RenderTargetBinding(gMetallicRoughness) }; + PointShadowCubeMap = new RenderTargetCube( + GraphicsDevice, + shadowMapSize, + false, + SurfaceFormat.Single, + DepthFormat.Depth24 + ); + SimpleDepthEffect = new SimpleDepthEffect(GraphicsDevice); + LinearDepthEffect = new LinearDepthEffect(GraphicsDevice); DeferredPBREffect = new DeferredPBREffect(GraphicsDevice); Deferred_GBufferEffect = new DeferredPBR_GBufferEffect(GraphicsDevice); @@ -181,7 +193,7 @@ namespace Kav foreach (var pointLight in pointLights) { - PointLightRender(pointLight); + PointLightRender(camera, modelTransforms, pointLight); } DirectionalLightRender(camera, modelTransforms, directionalLight); @@ -197,6 +209,7 @@ namespace Kav PerspectiveCamera camera, IEnumerable<(Model, Matrix)> modelTransforms, AmbientLight ambientLight, + IEnumerable pointLights, DirectionalLight directionalLight, TextureCube skybox ) { @@ -210,7 +223,11 @@ namespace Kav GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead; AmbientLightRender(ambientLight); - DirectionalLightToonRender(camera, modelTransforms, directionalLight); + foreach (var pointLight in pointLights) + { + PointLightRender(camera, modelTransforms, pointLight); + } + //DirectionalLightToonRender(camera, modelTransforms, directionalLight); SkyboxRender(camera, skybox); 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.GAlbedo = gAlbedo; DeferredPointLightEffect.GNormal = gNormal; DeferredPointLightEffect.GMetallicRoughness = gMetallicRoughness; + DeferredPointLightEffect.ShadowMap = PointShadowCubeMap; DeferredPointLightEffect.PointLightPosition = pointLight.Position; DeferredPointLightEffect.PointLightColor = pointLight.Color.ToVector3() * pointLight.Intensity; + DeferredPointLightEffect.FarPlane = 25f; // FIXME: magic value + foreach (var pass in DeferredPointLightEffect.CurrentTechnique.Passes) { pass.Apply(); @@ -375,7 +404,7 @@ namespace Kav IEnumerable<(Model, Matrix)> modelTransforms, DirectionalLight directionalLight ) { - RenderShadows(camera, modelTransforms, directionalLight, DeferredDirectionalLightEffect); + RenderDirectionalShadows(camera, modelTransforms, directionalLight, DeferredDirectionalLightEffect); DeferredDirectionalLightEffect.GPosition = gPosition; DeferredDirectionalLightEffect.GAlbedo = gAlbedo; @@ -419,7 +448,7 @@ namespace Kav IEnumerable<(Model, Matrix)> modelTransforms, DirectionalLight directionalLight ) { - RenderShadows(camera, modelTransforms, directionalLight, Deferred_ToonEffect); + RenderDirectionalShadows(camera, modelTransforms, directionalLight, Deferred_ToonEffect); GraphicsDevice.SetRenderTarget(ColorRenderTarget); GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead; @@ -461,7 +490,7 @@ namespace Kav } } - private void RenderShadows( + private void RenderDirectionalShadows( PerspectiveCamera camera, IEnumerable<(Model, Matrix)> modelTransforms, DirectionalLight directionalLight, @@ -485,14 +514,14 @@ namespace Kav ); // 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; previousFarPlane = farPlane; } } - private void RenderShadowMap( + private void RenderDirectionalShadowMap( PerspectiveCamera camera, IEnumerable<(Model, Matrix)> modelTransforms, 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 + ); + } + } + } + } + } + } } } diff --git a/Resources.cs b/Resources.cs index 251b820..fd5daa5 100644 --- a/Resources.cs +++ b/Resources.cs @@ -10,7 +10,7 @@ namespace Kav { if (ambientLightEffect == null) { - ambientLightEffect = GetResource("DeferredPBR_AmbientLightEffect.fxb"); + ambientLightEffect = GetResource("DeferredPBR_AmbientLightEffect.fxb"); } return ambientLightEffect; } @@ -21,7 +21,7 @@ namespace Kav { if (pointLightEffect == null) { - pointLightEffect = GetResource("DeferredPBR_PointLightEffect.fxb"); + pointLightEffect = GetResource("DeferredPBR_PointLightEffect.fxb"); } return pointLightEffect; } @@ -33,7 +33,7 @@ namespace Kav { if (directionalLightEffect == null) { - directionalLightEffect = GetResource("DeferredPBR_DirectionalLightEffect.fxb"); + directionalLightEffect = GetResource("DeferredPBR_DirectionalLightEffect.fxb"); } return directionalLightEffect; } @@ -45,7 +45,7 @@ namespace Kav { if (gBufferEffect == null) { - gBufferEffect = GetResource("DeferredPBR_GBufferEffect.fxb"); + gBufferEffect = GetResource("DeferredPBR_GBufferEffect.fxb"); } return gBufferEffect; } @@ -57,7 +57,7 @@ namespace Kav { if (toneMapEffect == null) { - toneMapEffect = GetResource("ToneMapEffect.fxb"); + toneMapEffect = GetResource("ToneMapEffect.fxb"); } return toneMapEffect; } @@ -69,7 +69,7 @@ namespace Kav { if (deferredToonEffect == null) { - deferredToonEffect = GetResource("Deferred_ToonEffect.fxb"); + deferredToonEffect = GetResource("Deferred_ToonEffect.fxb"); } return deferredToonEffect; } @@ -81,7 +81,7 @@ namespace Kav { if (deferredPBREffect == null) { - deferredPBREffect = GetResource("DeferredPBREffect.fxb"); + deferredPBREffect = GetResource("DeferredPBREffect.fxb"); } return deferredPBREffect; } @@ -93,7 +93,7 @@ namespace Kav { if (pbrEffect == null) { - pbrEffect = GetResource("PBREffect.fxb"); + pbrEffect = GetResource("PBREffect.fxb"); } return pbrEffect; } @@ -105,36 +105,48 @@ namespace Kav { if (simpleDepthEffect == null) { - simpleDepthEffect = GetResource("SimpleDepthEffect.fxb"); + 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; - } - } - + public static byte[] LinearDepthEffect + { + get + { + if (linearDepthEffect == null) + { + linearDepthEffect = GetResource("LinearDepthEffect.fxb"); + } + return linearDepthEffect; + } + } + + 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; @@ -144,14 +156,15 @@ 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[] linearDepthEffect; + private static byte[] skyboxEffect; + + private static byte[] unitCubeModel; private static byte[] GetResource(string name) { Stream stream = typeof(Resources).Assembly.GetManifestResourceStream( - "Kav.Resources." + name + "Kav.Resources." + name ); using (MemoryStream ms = new MemoryStream()) {