Compare commits
	
		
			No commits in common. "main" and "palette_crush" have entirely different histories. 
		
	
	
		
			main
			...
			palette_cr
		
	
		|  | @ -10,7 +10,6 @@ namespace Kav | |||
|         public Vector3 Position { get; } | ||||
|         public Vector3 Forward { get; } | ||||
|         public Vector3 Up { get; } | ||||
|         public Vector3 Right { get; } | ||||
| 
 | ||||
|         public float FieldOfView { get; } | ||||
|         public float AspectRatio { get; } | ||||
|  | @ -29,7 +28,6 @@ namespace Kav | |||
|             Position = position; | ||||
|             Forward = forward; | ||||
|             Up = up; | ||||
|             Right = Vector3.Cross(forward, up); | ||||
|             View = Matrix.CreateLookAt(Position, Position + Forward, Up); | ||||
| 
 | ||||
|             FieldOfView = fieldOfView; | ||||
|  |  | |||
|  | @ -1,14 +0,0 @@ | |||
| namespace Kav | ||||
| { | ||||
|     public struct AtlasAnimation | ||||
|     { | ||||
|         public UVData[] Frames { get; } | ||||
|         public int Framerate { get; } | ||||
| 
 | ||||
|         public AtlasAnimation(UVData[] frames, int framerate) | ||||
|         { | ||||
|             Frames = frames; | ||||
|             Framerate = framerate; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,63 +0,0 @@ | |||
| using System.Collections.Generic; | ||||
| using Microsoft.Xna.Framework.Graphics; | ||||
| 
 | ||||
| namespace Kav | ||||
| { | ||||
|     public class InstanceData<T> where T : struct, IVertexType | ||||
|     { | ||||
|         public T[] InstanceDataArray { get; } | ||||
|         public DynamicVertexBuffer VertexBuffer { get; } | ||||
|         public int InstanceCount { get; private set; } | ||||
| 
 | ||||
|         public InstanceData(GraphicsDevice graphicsDevice, int size) | ||||
|         { | ||||
|             InstanceDataArray = new T[size]; | ||||
| 
 | ||||
|             VertexBuffer = new DynamicVertexBuffer( | ||||
|                 graphicsDevice, | ||||
|                 typeof(T), | ||||
|                 size, | ||||
|                 BufferUsage.WriteOnly | ||||
|             ); | ||||
| 
 | ||||
|             InstanceCount = 0; | ||||
|         } | ||||
| 
 | ||||
|         public void AddAndSetData(IEnumerable<T> data) | ||||
|         { | ||||
|             InstanceCount = 0; | ||||
|             foreach (var datum in data) | ||||
|             { | ||||
|                 AddData(datum); | ||||
|             } | ||||
| 
 | ||||
|             if (InstanceCount == 0) { throw new System.Exception(); } | ||||
| 
 | ||||
|             SetData(); | ||||
|         } | ||||
| 
 | ||||
|         public void AddData(T datum) | ||||
|         { | ||||
|             InstanceDataArray[InstanceCount] = datum; | ||||
|             InstanceCount += 1; | ||||
|         } | ||||
| 
 | ||||
|         public void SetData() | ||||
|         { | ||||
|             if (InstanceCount > 0) | ||||
|             { | ||||
|                 VertexBuffer.SetData( | ||||
|                     InstanceDataArray, | ||||
|                     0, | ||||
|                     InstanceCount, | ||||
|                     SetDataOptions.NoOverwrite | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Clear() | ||||
|         { | ||||
|             InstanceCount = 0; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,35 +0,0 @@ | |||
| using Microsoft.Xna.Framework; | ||||
| using Microsoft.Xna.Framework.Graphics; | ||||
| 
 | ||||
| namespace Kav.Data | ||||
| { | ||||
|     public struct MeshSpriteDrawData : IIndexDrawable, ICullable, ITransformable | ||||
|     { | ||||
|         public SpriteMesh MeshSprite { get; } | ||||
|         public Texture2D Texture { get; } | ||||
|         public Texture2D Normal { get; } | ||||
|         public SpriteBillboardConstraint BillboardConstraint { get; } | ||||
|         public Matrix TransformMatrix { get; } | ||||
|         public UVData UVOffset { get; } | ||||
| 
 | ||||
|         public IndexBuffer IndexBuffer => MeshSprite.IndexBuffer; | ||||
|         public VertexBuffer VertexBuffer => MeshSprite.VertexBuffer; | ||||
|         public BoundingBox BoundingBox => MeshSprite.BoundingBox; | ||||
| 
 | ||||
|         public MeshSpriteDrawData( | ||||
|             SpriteMesh meshSprite, | ||||
|             Texture2D texture, | ||||
|             Texture2D normal, | ||||
|             SpriteBillboardConstraint billboardConstraint, | ||||
|             Matrix transformMatrix, | ||||
|             UVData offset | ||||
|         ) { | ||||
|             MeshSprite = meshSprite; | ||||
|             Texture = texture; | ||||
|             Normal = normal; | ||||
|             BillboardConstraint = billboardConstraint; | ||||
|             TransformMatrix = transformMatrix; | ||||
|             UVOffset = offset; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,96 +0,0 @@ | |||
| using Kav.Data; | ||||
| using Microsoft.Xna.Framework; | ||||
| using Microsoft.Xna.Framework.Graphics; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| 
 | ||||
| namespace Kav | ||||
| { | ||||
|     public struct TextureAtlasSlice | ||||
|     { | ||||
|         public int X { get; } | ||||
|         public int Y { get; } | ||||
|         public int W { get; } | ||||
|         public int H { get; } | ||||
| 
 | ||||
|         public UVData UVData { get; } | ||||
| 
 | ||||
|         // for use with tiling | ||||
|         public Vector2 TiledUVOffset { get; } | ||||
| 
 | ||||
|         public TextureAtlasSlice(int x, int y, int w, int h, int totalW, int totalH) | ||||
|         { | ||||
|             X = x; | ||||
|             Y = y; | ||||
|             W = w; | ||||
|             H = h; | ||||
| 
 | ||||
|             UVData = new UVData(new Vector2(x, y), new Vector2(w, h), new Vector2(totalW, totalH)); | ||||
| 
 | ||||
|             TiledUVOffset = new Vector2(x / (float)totalW, y / (float)totalH); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public class TextureAtlas | ||||
|     { | ||||
|         public Texture2D Texture { get; } | ||||
|         protected List<string> Names { get; } = new List<string>(); | ||||
|         protected Dictionary<string, TextureAtlasSlice> Slices { get; } = new Dictionary<string, TextureAtlasSlice>(); | ||||
| 
 | ||||
|         public TextureAtlas(GraphicsDevice graphicsDevice, FileInfo atlasMetadataFile) | ||||
|         { | ||||
|             var atlasData = CrunchAtlasReader.ReadTextureAtlas(atlasMetadataFile); | ||||
| 
 | ||||
|             var textureData = atlasData.Textures[0]; | ||||
| 
 | ||||
|             using var stream = File.OpenRead(Path.Combine(atlasMetadataFile.DirectoryName, textureData.Name + ".png")); | ||||
|             Texture = Texture2D.FromStream(graphicsDevice, stream); | ||||
| 
 | ||||
|             foreach (var slice in textureData.Images) | ||||
|             { | ||||
|                 Names.Add(slice.N); | ||||
| 
 | ||||
|                 Slices.Add( | ||||
|                     slice.N, | ||||
|                     new TextureAtlasSlice( | ||||
|                         slice.X, | ||||
|                         slice.Y, | ||||
|                         slice.W, | ||||
|                         slice.H, | ||||
|                         Texture.Width, | ||||
|                         Texture.Height | ||||
|                     ) | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public TextureAtlasSlice Lookup(string name) | ||||
|         { | ||||
|             return Slices[name]; | ||||
|         } | ||||
| 
 | ||||
|         public string Name(int index) | ||||
|         { | ||||
|             return Names[index]; | ||||
|         } | ||||
| 
 | ||||
|         public int Count() | ||||
|         { | ||||
|             return Names.Count; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Assumes all subimages are the same size | ||||
|     public class TiledTextureAtlas : TextureAtlas | ||||
|     { | ||||
|         public int NumRows { get; } | ||||
|         public int NumColumns { get; } | ||||
| 
 | ||||
|         public TiledTextureAtlas(GraphicsDevice graphicsDevice, FileInfo atlasMetadataFile) : base(graphicsDevice, atlasMetadataFile) | ||||
|         { | ||||
|             var subImageSlice = Slices[Names[0]]; | ||||
|             NumRows = Texture.Height / subImageSlice.H; | ||||
|             NumColumns = Texture.Width / subImageSlice.W; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,19 +0,0 @@ | |||
| using Microsoft.Xna.Framework; | ||||
| 
 | ||||
| namespace Kav | ||||
| { | ||||
|     public struct UVData | ||||
|     { | ||||
|         public Vector2 Offset { get; } | ||||
|         public Vector2 Percentage { get; } | ||||
| 
 | ||||
|         public UVData( | ||||
|             Vector2 positionInAtlas, | ||||
|             Vector2 subTextureDimensions, | ||||
|             Vector2 atlasDimensions | ||||
|         ) { | ||||
|             Percentage = subTextureDimensions / atlasDimensions; | ||||
|             Offset = positionInAtlas / atlasDimensions; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -74,6 +74,32 @@ namespace Kav | |||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         protected DeferredPBREffect(DeferredPBREffect cloneSource) : base(cloneSource) | ||||
|         { | ||||
|             GPosition = cloneSource.GPosition; | ||||
|             GAlbedo = cloneSource.GAlbedo; | ||||
|             GNormal = cloneSource.GNormal; | ||||
|             GMetallicRoughness = cloneSource.GMetallicRoughness; | ||||
| 
 | ||||
|             EyePosition = cloneSource.EyePosition; | ||||
| 
 | ||||
|             PointLights = new PointLightCollection( | ||||
|                 Parameters["LightPositions"], | ||||
|                 Parameters["PositionLightColors"], | ||||
|                 MaxPointLights | ||||
|             ); | ||||
| 
 | ||||
|             for (int i = 0; i < MaxPointLights; i++) | ||||
|             { | ||||
|                 PointLights[i] = cloneSource.PointLights[i]; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public override Effect Clone() | ||||
|         { | ||||
|             return new DeferredPBREffect(this); | ||||
|         } | ||||
| 
 | ||||
|         protected override void OnApply() | ||||
|         { | ||||
|             gPositionParam.SetValue(GPosition); | ||||
|  |  | |||
|  | @ -16,9 +16,6 @@ namespace Kav | |||
|         EffectParameter metallicParam; | ||||
|         EffectParameter roughnessParam; | ||||
| 
 | ||||
|         EffectParameter uvOffsetAndDimensionsParam; | ||||
|         EffectParameter isSpriteParam; | ||||
| 
 | ||||
|         EffectParameter numTextureRowsParam; | ||||
|         EffectParameter numTextureColumnsParam; | ||||
| 
 | ||||
|  | @ -33,11 +30,6 @@ namespace Kav | |||
|         float metallic; | ||||
|         float roughness; | ||||
| 
 | ||||
|         Vector2 uvOffset; | ||||
|         Vector2 subTextureDimensions; | ||||
| 
 | ||||
|         bool isSprite = false; | ||||
| 
 | ||||
|         int numTextureRows = 1; | ||||
|         int numTextureColumns = 1; | ||||
| 
 | ||||
|  | @ -161,36 +153,6 @@ namespace Kav | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public Vector2 UVOffset | ||||
|         { | ||||
|             get { return uvOffset; } | ||||
|             set | ||||
|             { | ||||
|                 uvOffset = value; | ||||
|                 dirtyFlags |= EffectDirtyFlags.UVOrDimensions; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public Vector2 SubTextureDimensions | ||||
|         { | ||||
|             get { return subTextureDimensions; } | ||||
|             set | ||||
|             { | ||||
|                 subTextureDimensions = value; | ||||
|                 dirtyFlags |= EffectDirtyFlags.UVOrDimensions; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public bool IsSprite | ||||
|         { | ||||
|             get { return isSprite; } | ||||
|             set | ||||
|             { | ||||
|                 isSprite = value; | ||||
|                 isSpriteParam.SetValue(isSprite ? 1f : 0f); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public bool HardwareInstancingEnabled | ||||
|         { | ||||
|             get { return hardwareInstancingEnabled; } | ||||
|  | @ -248,16 +210,6 @@ namespace Kav | |||
|                 dirtyFlags &= ~EffectDirtyFlags.ViewProj; | ||||
|             } | ||||
| 
 | ||||
|             if ((dirtyFlags & EffectDirtyFlags.UVOrDimensions) != 0) | ||||
|             { | ||||
|                 uvOffsetAndDimensionsParam.SetValue(new Vector4( | ||||
|                     UVOffset.X, UVOffset.Y, | ||||
|                     SubTextureDimensions.X, SubTextureDimensions.Y | ||||
|                 )); | ||||
| 
 | ||||
|                 dirtyFlags &= ~EffectDirtyFlags.UVOrDimensions; | ||||
|             } | ||||
| 
 | ||||
|             if ((dirtyFlags & EffectDirtyFlags.VertexShaderIndex) != 0) | ||||
|             { | ||||
|                 int vertexShaderIndex = 0; | ||||
|  | @ -325,9 +277,6 @@ namespace Kav | |||
|             numTextureRowsParam = Parameters["NumTextureRows"]; | ||||
|             numTextureColumnsParam = Parameters["NumTextureColumns"]; | ||||
| 
 | ||||
|             uvOffsetAndDimensionsParam = Parameters["UVOffsetAndDimensions"]; | ||||
|             isSpriteParam = Parameters["IsSprite"]; | ||||
| 
 | ||||
|             shaderIndexParam = Parameters["PixelShaderIndex"]; | ||||
|             vertexShaderIndexParam = Parameters["VertexShaderIndex"]; | ||||
|         } | ||||
|  |  | |||
|  | @ -18,8 +18,6 @@ namespace Kav | |||
| 
 | ||||
|         EffectParameter farPlaneParam; | ||||
| 
 | ||||
|         EffectParameter worldViewProjectionParam; | ||||
| 
 | ||||
|         public Texture2D GPosition { get; set; } | ||||
|         public Texture2D GAlbedo { get; set; } | ||||
|         public Texture2D GNormal { get; set; } | ||||
|  | @ -33,42 +31,6 @@ namespace Kav | |||
| 
 | ||||
|         public float FarPlane { get; set; } | ||||
| 
 | ||||
|         Matrix world = Matrix.Identity; | ||||
|         Matrix view = Matrix.Identity; | ||||
|         Matrix projection = Matrix.Identity; | ||||
| 
 | ||||
|         EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All; | ||||
| 
 | ||||
|         public Matrix World | ||||
|         { | ||||
|             get { return world; } | ||||
|             set | ||||
|             { | ||||
|                 world = value; | ||||
|                 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 DeferredPBR_PointLightEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_PointLightEffect) | ||||
|         { | ||||
|             CacheEffectParameters(); | ||||
|  | @ -77,7 +39,7 @@ namespace Kav | |||
|         public DeferredPBR_PointLightEffect(DeferredPBR_PointLightEffect cloneSource) : base(cloneSource) | ||||
|         { | ||||
|             CacheEffectParameters(); | ||||
| 
 | ||||
|              | ||||
|             GPosition = cloneSource.GPosition; | ||||
|             GAlbedo = cloneSource.GAlbedo; | ||||
|             GNormal = cloneSource.GNormal; | ||||
|  | @ -111,13 +73,6 @@ namespace Kav | |||
|             pointLightColorParam.SetValue(PointLightColor); | ||||
| 
 | ||||
|             farPlaneParam.SetValue(FarPlane); | ||||
| 
 | ||||
|             if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0) | ||||
|             { | ||||
|                 worldViewProjectionParam.SetValue(world * view * projection); | ||||
| 
 | ||||
|                 dirtyFlags &= ~EffectDirtyFlags.WorldViewProj; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         void CacheEffectParameters() | ||||
|  | @ -134,8 +89,6 @@ namespace Kav | |||
|             pointLightColorParam           = Parameters["PointLightColor"]; | ||||
| 
 | ||||
|             farPlaneParam                  = Parameters["FarPlane"]; | ||||
| 
 | ||||
|             worldViewProjectionParam       = Parameters["WorldViewProjection"]; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| using Kav.Data; | ||||
| using Microsoft.Xna.Framework; | ||||
| using Microsoft.Xna.Framework.Graphics; | ||||
| 
 | ||||
|  | @ -11,8 +10,6 @@ namespace Kav | |||
|         EffectParameter directionalLightDirectionParam; | ||||
|         EffectParameter directionalLightColorParam; | ||||
| 
 | ||||
|         EffectParameter uvOffsetAndDimensionsParam; | ||||
| 
 | ||||
|         EffectParameter worldParam; | ||||
|         EffectParameter worldViewProjectionParam; | ||||
|         EffectParameter worldInverseTransposeParam; | ||||
|  | @ -33,9 +30,6 @@ namespace Kav | |||
|         Matrix view = Matrix.Identity; | ||||
|         Matrix projection = Matrix.Identity; | ||||
| 
 | ||||
|         Vector2 uvOffset; | ||||
|         Vector2 subTextureDimensions; | ||||
| 
 | ||||
|         EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All; | ||||
| 
 | ||||
|         public bool NormalMapEnabled | ||||
|  | @ -115,26 +109,6 @@ namespace Kav | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public Vector2 UVOffset | ||||
|         { | ||||
|             get { return uvOffset; } | ||||
|             set | ||||
|             { | ||||
|                 uvOffset = value; | ||||
|                 dirtyFlags |= EffectDirtyFlags.UVOrDimensions; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public Vector2 SubTextureDimensions | ||||
|         { | ||||
|             get { return subTextureDimensions; } | ||||
|             set | ||||
|             { | ||||
|                 subTextureDimensions = value; | ||||
|                 dirtyFlags |= EffectDirtyFlags.UVOrDimensions; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public DiffuseLitSpriteEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DiffuseLitSpriteEffect) | ||||
|         { | ||||
|             CacheEffectParameters(); | ||||
|  | @ -168,16 +142,6 @@ namespace Kav | |||
|                 dirtyFlags &= ~EffectDirtyFlags.WorldViewProj; | ||||
|             } | ||||
| 
 | ||||
|             if ((dirtyFlags & EffectDirtyFlags.UVOrDimensions) != 0) | ||||
|             { | ||||
|                 uvOffsetAndDimensionsParam.SetValue(new Vector4( | ||||
|                     UVOffset.X, UVOffset.Y, | ||||
|                     SubTextureDimensions.X, SubTextureDimensions.Y | ||||
|                 )); | ||||
| 
 | ||||
|                 dirtyFlags &= ~EffectDirtyFlags.UVOrDimensions; | ||||
|             } | ||||
| 
 | ||||
|             if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0) | ||||
|             { | ||||
|                 int shaderIndex = 0; | ||||
|  | @ -202,8 +166,6 @@ namespace Kav | |||
|             directionalLightDirectionParam = Parameters["DirectionalLightDirection"]; | ||||
|             directionalLightColorParam = Parameters["DirectionalLightColor"]; | ||||
| 
 | ||||
|             uvOffsetAndDimensionsParam = Parameters["UVOffsetAndDimensions"]; | ||||
| 
 | ||||
|             shaderIndexParam = Parameters["ShaderIndex"]; | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -11,7 +11,6 @@ namespace Kav | |||
|         VertexShaderIndex = 8, | ||||
|         PixelShaderIndex = 16, | ||||
|         ViewProj = 32, | ||||
|         UVOrDimensions = 64, | ||||
|         All = -1 | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										
											BIN
										
									
								
								Effects/FXB/DeferredPBR_GBufferEffect.fxb (Stored with Git LFS)
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								Effects/FXB/DeferredPBR_GBufferEffect.fxb (Stored with Git LFS)
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Effects/FXB/DeferredPBR_PointLightEffect.fxb (Stored with Git LFS)
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								Effects/FXB/DeferredPBR_PointLightEffect.fxb (Stored with Git LFS)
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Effects/FXB/DiffuseLitSpriteEffect.fxb (Stored with Git LFS)
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								Effects/FXB/DiffuseLitSpriteEffect.fxb (Stored with Git LFS)
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Effects/FXB/PaletteCrushEffect.fxb (Stored with Git LFS)
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								Effects/FXB/PaletteCrushEffect.fxb (Stored with Git LFS)
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -4,9 +4,6 @@ DECLARE_TEXTURE(AlbedoTexture, 0); | |||
| DECLARE_TEXTURE(NormalTexture, 1); | ||||
| DECLARE_TEXTURE(MetallicRoughnessTexture, 2); | ||||
| 
 | ||||
| float4 UVOffsetAndDimensions; | ||||
| float IsSprite; | ||||
| 
 | ||||
| BEGIN_CONSTANTS | ||||
| 
 | ||||
|     float3 AlbedoValue                         _ps(c0)    _cb(c0); | ||||
|  | @ -54,11 +51,7 @@ PixelInput main_vs(VertexInput input) | |||
| 
 | ||||
|     output.PositionWorld = mul(input.Position, World).xyz; | ||||
|     output.NormalWorld = normalize(mul(input.Normal, World)); | ||||
| 
 | ||||
|     float2 texCoord; | ||||
|     texCoord.x = (input.TexCoord.x * UVOffsetAndDimensions.z) + UVOffsetAndDimensions.x; | ||||
|     texCoord.y = (input.TexCoord.y * UVOffsetAndDimensions.w) + UVOffsetAndDimensions.y; | ||||
|     output.TexCoord = texCoord; | ||||
|     output.TexCoord = input.TexCoord; | ||||
| 
 | ||||
|     float4x4 worldViewProjection = mul(World, ViewProjection); | ||||
|     output.Position = mul(input.Position, worldViewProjection); | ||||
|  | @ -67,7 +60,7 @@ PixelInput main_vs(VertexInput input) | |||
| } | ||||
| 
 | ||||
| PixelInput instanced_vs( | ||||
|     VertexInput input, | ||||
|     VertexInput input,  | ||||
|     float3 Translation : TEXCOORD2, | ||||
|     float2 UVOffset    : TEXCOORD5 | ||||
| ) { | ||||
|  | @ -120,7 +113,7 @@ PixelOutput NonePS(PixelInput input) | |||
|     PixelOutput output; | ||||
| 
 | ||||
|     output.gPosition = float4(input.PositionWorld, 1.0); | ||||
|     output.gNormal = float4(normalize(input.NormalWorld), IsSprite); | ||||
|     output.gNormal = float4(normalize(input.NormalWorld), 1.0); | ||||
|     output.gAlbedo = float4(AlbedoValue, 1.0); | ||||
|     output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0); | ||||
| 
 | ||||
|  | @ -132,12 +125,10 @@ PixelOutput AlbedoPS(PixelInput input) | |||
|     PixelOutput output; | ||||
| 
 | ||||
|     output.gPosition = float4(input.PositionWorld, 1.0); | ||||
|     output.gNormal = float4(normalize(input.NormalWorld), IsSprite); | ||||
|     output.gNormal = float4(normalize(input.NormalWorld), 1.0); | ||||
|     output.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord); | ||||
|     output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0); | ||||
| 
 | ||||
|     if (output.gAlbedo.a == 0.0) { discard; } | ||||
| 
 | ||||
|     return output; | ||||
| } | ||||
| 
 | ||||
|  | @ -146,7 +137,7 @@ PixelOutput MetallicRoughnessPS(PixelInput input) | |||
|     PixelOutput output; | ||||
| 
 | ||||
|     output.gPosition = float4(input.PositionWorld, 1.0); | ||||
|     output.gNormal = float4(normalize(input.NormalWorld), IsSprite); | ||||
|     output.gNormal = float4(normalize(input.NormalWorld), 1.0); | ||||
|     output.gAlbedo = float4(AlbedoValue, 1.0); | ||||
|     output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord); | ||||
| 
 | ||||
|  | @ -158,7 +149,7 @@ PixelOutput NormalPS(PixelInput input) | |||
|     PixelOutput output; | ||||
| 
 | ||||
|     output.gPosition = float4(input.PositionWorld, 1.0); | ||||
|     output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), IsSprite); | ||||
|     output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), 1.0); | ||||
|     output.gAlbedo = float4(AlbedoValue, 1.0); | ||||
|     output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0); | ||||
| 
 | ||||
|  | @ -170,12 +161,10 @@ PixelOutput AlbedoMetallicRoughnessPS(PixelInput input) | |||
|     PixelOutput output; | ||||
| 
 | ||||
|     output.gPosition = float4(input.PositionWorld, 1.0); | ||||
|     output.gNormal = float4(normalize(input.NormalWorld), IsSprite); | ||||
|     output.gNormal = float4(normalize(input.NormalWorld), 1.0); | ||||
|     output.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord); | ||||
|     output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord); | ||||
| 
 | ||||
|     if (output.gAlbedo.a == 0.0) { discard; } | ||||
| 
 | ||||
|     return output; | ||||
| } | ||||
| 
 | ||||
|  | @ -184,12 +173,10 @@ PixelOutput AlbedoNormalPS(PixelInput input) | |||
|     PixelOutput output; | ||||
| 
 | ||||
|     output.gPosition = float4(input.PositionWorld, 1.0); | ||||
|     output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), IsSprite); | ||||
|     output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), 1.0); | ||||
|     output.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord); | ||||
|     output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0); | ||||
| 
 | ||||
|     if (output.gAlbedo.a == 0.0) { discard; } | ||||
| 
 | ||||
|     return output; | ||||
| } | ||||
| 
 | ||||
|  | @ -198,7 +185,7 @@ PixelOutput MetallicRoughnessNormalPS(PixelInput input) | |||
|     PixelOutput output; | ||||
| 
 | ||||
|     output.gPosition = float4(input.PositionWorld, 1.0); | ||||
|     output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), IsSprite); | ||||
|     output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), 1.0); | ||||
|     output.gAlbedo = float4(AlbedoValue, 1.0); | ||||
|     output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord); | ||||
| 
 | ||||
|  | @ -210,12 +197,10 @@ PixelOutput AlbedoMetallicRoughnessNormalMapPS(PixelInput input) | |||
|     PixelOutput output; | ||||
| 
 | ||||
|     output.gPosition = float4(input.PositionWorld, 1.0); | ||||
|     output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), IsSprite); | ||||
|     output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), 1.0); | ||||
|     output.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord); | ||||
|     output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord); | ||||
| 
 | ||||
|     if (output.gAlbedo.a == 0.0) { discard; } | ||||
| 
 | ||||
|     return output; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,5 @@ | |||
| // Assumes you are drawing a sphere!! | ||||
| 
 | ||||
| #include "Macros.fxh" //from FNA | ||||
| #include "Lighting.fxh" | ||||
| #include "Lighting.fxh"  | ||||
| #include "Shadow.fxh" | ||||
| 
 | ||||
| DECLARE_TEXTURE(gPosition, 0); | ||||
|  | @ -13,7 +11,7 @@ DECLARE_CUBEMAP(shadowMap, 4); | |||
| BEGIN_CONSTANTS | ||||
| 
 | ||||
|     float3 EyePosition                      _ps(c0)     _cb(c0); | ||||
| 
 | ||||
|      | ||||
|     float3 PointLightPosition               _ps(c1)     _cb(c1); | ||||
|     float3 PointLightColor                  _ps(c2)     _cb(c2); | ||||
| 
 | ||||
|  | @ -21,28 +19,27 @@ BEGIN_CONSTANTS | |||
| 
 | ||||
| MATRIX_CONSTANTS | ||||
| 
 | ||||
|     float4x4 WorldViewProjection _vs(c0)                _cb(c4); | ||||
| 
 | ||||
| END_CONSTANTS | ||||
| 
 | ||||
| struct VertexInput | ||||
| { | ||||
|     float4 Position : POSITION; | ||||
|     float2 TexCoord : TEXCOORD; | ||||
| }; | ||||
| 
 | ||||
| struct PixelInput | ||||
| { | ||||
|     float4 Position : SV_POSITION; | ||||
|     float4 ScreenPosition : TEXCOORD0; | ||||
|     float2 TexCoord : TEXCOORD0; | ||||
| }; | ||||
| 
 | ||||
| PixelInput main_vs(VertexInput input) | ||||
| { | ||||
|     PixelInput output; | ||||
| 
 | ||||
|     output.Position = mul(input.Position, WorldViewProjection); | ||||
|     output.ScreenPosition = output.Position; | ||||
| 
 | ||||
|     output.Position = input.Position; | ||||
|     output.TexCoord = input.TexCoord; | ||||
|      | ||||
|     return output; | ||||
| } | ||||
| 
 | ||||
|  | @ -76,36 +73,18 @@ float4 ComputeColor( | |||
| 
 | ||||
| float4 main_ps(PixelInput input) : SV_TARGET0 | ||||
| { | ||||
|     input.ScreenPosition.xy /= input.ScreenPosition.w; | ||||
|     float2 texCoord = 0.5f * float2(input.ScreenPosition.x,-input.ScreenPosition.y) + 0.5f; | ||||
|     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 worldPosition = SAMPLE_TEXTURE(gPosition, texCoord).rgb; | ||||
|     float4 normalSample = SAMPLE_TEXTURE(gNormal, texCoord); | ||||
|     float3 normal = normalSample.xyz; | ||||
|     float isSprite = normalSample.a; | ||||
|     float3 albedo = SAMPLE_TEXTURE(gAlbedo, texCoord).rgb; | ||||
|     float2 metallicRoughness = SAMPLE_TEXTURE(gMetallicRoughness, texCoord).rg; | ||||
| 
 | ||||
|     if (isSprite == 1.0) | ||||
|     { | ||||
|         float3 lightDir = PointLightPosition - worldPosition; | ||||
|         float3 L = normalize(lightDir); | ||||
|         float distance = length(lightDir); | ||||
|         float attenuation = 1.0 / (distance * distance); | ||||
|         float3 radiance = PointLightColor * attenuation; | ||||
| 
 | ||||
|         return float4(albedo * radiance * 0.1, 1.0); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return ComputeColor( | ||||
|             worldPosition, | ||||
|             normal, | ||||
|             albedo, | ||||
|             metallicRoughness.r, | ||||
|             metallicRoughness.g | ||||
|         ); | ||||
|     } | ||||
|     return ComputeColor( | ||||
|         worldPosition, | ||||
|         normal, | ||||
|         albedo, | ||||
|         metallicRoughness.r, | ||||
|         metallicRoughness.g | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| Technique DeferredPBR_Point | ||||
|  |  | |||
|  | @ -5,19 +5,23 @@ | |||
| DECLARE_TEXTURE(Texture, 0); | ||||
| DECLARE_TEXTURE(Normal, 1); | ||||
| 
 | ||||
| float3 AmbientColor; | ||||
| BEGIN_CONSTANTS | ||||
| 
 | ||||
| float3 PointLightPositions[8]; | ||||
| float3 PointLightColors[8]; | ||||
|     float3 AmbientColor                       _ps(c0)    _cb(c0); | ||||
| 
 | ||||
| float3 DirectionalLightDirection; | ||||
| float3 DirectionalLightColor; | ||||
|     float3 PointLightPositions[8]            _ps(c1)    _cb(c1); | ||||
|     float3 PointLightColors[8]               _ps(c9)    _cb(c9); | ||||
| 
 | ||||
| float4 UVOffsetAndDimensions; | ||||
|     float3 DirectionalLightDirection          _ps(c17)   _cb(c17); | ||||
|     float3 DirectionalLightColor              _ps(c18)   _cb(c18); | ||||
| 
 | ||||
| float4x4 WorldInverseTranspose; | ||||
| float4x4 World; | ||||
| float4x4 WorldViewProjection; | ||||
| MATRIX_CONSTANTS | ||||
| 
 | ||||
|     float4x4 WorldInverseTranspose           _ps(c19)   _cb(c19); | ||||
|     float4x4 World                  _vs(c0)             _cb(c23); | ||||
|     float4x4 WorldViewProjection    _vs(c4)             _cb(c27); | ||||
| 
 | ||||
| END_CONSTANTS | ||||
| 
 | ||||
| struct VertexShaderInput | ||||
| { | ||||
|  | @ -39,14 +43,10 @@ PixelShaderInput main_vs(VertexShaderInput input) | |||
|     PixelShaderInput output; | ||||
| 
 | ||||
|     output.Position = mul(input.Position, WorldViewProjection); | ||||
|     output.NormalWS = normalize(mul(input.Normal, (float3x3)WorldInverseTranspose)); | ||||
|     output.TexCoord = input.TexCoord; | ||||
|     output.NormalWS = mul(input.Normal, (float3x3)WorldInverseTranspose).xyz; | ||||
|     output.PositionWS = mul(input.Position, World).xyz; | ||||
| 
 | ||||
|     float2 texCoord; | ||||
|     texCoord.x = (input.TexCoord.x * UVOffsetAndDimensions.z) + UVOffsetAndDimensions.x; | ||||
|     texCoord.y = (input.TexCoord.y * UVOffsetAndDimensions.w) + UVOffsetAndDimensions.y; | ||||
|     output.TexCoord = texCoord; | ||||
| 
 | ||||
|     return output; | ||||
| } | ||||
| 
 | ||||
|  | @ -98,9 +98,6 @@ float4 LightColor(float3 worldPosition, float3 worldNormal) | |||
| float4 WithoutNormalMap(PixelShaderInput input) : COLOR0 | ||||
| { | ||||
|     float4 tex = SAMPLE_TEXTURE(Texture, input.TexCoord); | ||||
| 
 | ||||
|     if (tex.a == 0.0) { discard; } | ||||
| 
 | ||||
|     float3 normalWS = normalize(input.NormalWS); | ||||
| 
 | ||||
|     return tex * LightColor(input.PositionWS, normalWS); | ||||
|  | @ -109,9 +106,6 @@ float4 WithoutNormalMap(PixelShaderInput input) : COLOR0 | |||
| float4 WithNormalMap(PixelShaderInput input) : COLOR0 | ||||
| { | ||||
|     float4 tex = SAMPLE_TEXTURE(Texture, input.TexCoord); | ||||
| 
 | ||||
|     if (tex.a == 0.0) { discard; } | ||||
| 
 | ||||
|     float3 normalWS = GetNormalFromMap(input.PositionWS, input.TexCoord, input.NormalWS); | ||||
| 
 | ||||
|     return tex * LightColor(input.PositionWS, normalWS); | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| #include "Macros.fxh" | ||||
| 
 | ||||
| #define FLT_MAX 3.402823466e+38 | ||||
| 
 | ||||
| DECLARE_TEXTURE(Texture, 0); | ||||
| DECLARE_TEXTURE(Palette, 1); | ||||
| 
 | ||||
|  | @ -38,12 +40,11 @@ float4 main_ps(PixelInput input) : SV_TARGET0 | |||
| 	float3 sampled_color = sampled.rgb; | ||||
| 	 | ||||
| 	float3 closest_color = float3(0, 0, 0); | ||||
| 	float closest_dist = 100000; | ||||
| 	float closest_dist = FLT_MAX; | ||||
| 
 | ||||
| 	for (int i = 0; i < PaletteWidth; i++) | ||||
| 	{ | ||||
| 		float texX = (i / (float)PaletteWidth); | ||||
| 		float3 palette_color = SAMPLE_TEXTURE(Palette, float2(texX, 0)); | ||||
| 		float3 palette_color = SAMPLE_TEXTURE(Palette, float2(i / (float)PaletteWidth, 0)); | ||||
| 		float dist = distance(palette_color, sampled_color); | ||||
| 		if (dist < closest_dist) | ||||
| 		{ | ||||
|  |  | |||
|  | @ -197,6 +197,45 @@ namespace Kav | |||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         protected PBREffect(PBREffect cloneSource) : base(cloneSource) | ||||
|         { | ||||
|             CacheEffectParameters(); | ||||
| 
 | ||||
|             World = cloneSource.World; | ||||
|             View = cloneSource.View; | ||||
|             Projection = cloneSource.Projection; | ||||
| 
 | ||||
|             PointLights = new PointLightCollection( | ||||
|                 Parameters["LightPositions"], | ||||
|                 Parameters["PositionLightColors"], | ||||
|                 MaxPointLights | ||||
|             ); | ||||
| 
 | ||||
|             for (int i = 0; i < MaxPointLights; i++) | ||||
|             { | ||||
|                 PointLights[i] = cloneSource.PointLights[i]; | ||||
|             } | ||||
| 
 | ||||
|             AlbedoTexture = cloneSource.AlbedoTexture; | ||||
|             NormalTexture = cloneSource.NormalTexture; | ||||
|             EmissionTexture = cloneSource.EmissionTexture; | ||||
|             OcclusionTexture = cloneSource.OcclusionTexture; | ||||
|             MetallicRoughnessTexture = cloneSource.MetallicRoughnessTexture; | ||||
|             EnvDiffuseTexture = cloneSource.EnvDiffuseTexture; | ||||
|             BRDFLutTexture = cloneSource.BRDFLutTexture; | ||||
|             EnvSpecularTexture = cloneSource.EnvSpecularTexture; | ||||
| 
 | ||||
|             Albedo = cloneSource.Albedo; | ||||
|             Metallic = cloneSource.Metallic; | ||||
|             Roughness = cloneSource.Roughness; | ||||
|             AO = cloneSource.AO; | ||||
|         } | ||||
| 
 | ||||
|         public override Effect Clone() | ||||
|         { | ||||
|             return new PBREffect(this); | ||||
|         } | ||||
| 
 | ||||
|         protected override void OnApply() | ||||
|         { | ||||
|             if ((dirtyFlags & EffectDirtyFlags.World) != 0) | ||||
|  |  | |||
|  | @ -7,24 +7,41 @@ namespace Kav | |||
|     { | ||||
|         private readonly Vector3[] positions; | ||||
|         private readonly Vector3[] colors; | ||||
|         private readonly float[] intensities; | ||||
| 
 | ||||
|         readonly EffectParameter lightPositionsParam; | ||||
|         readonly EffectParameter lightColorsParam; | ||||
| 
 | ||||
|         public PointLightCollection(EffectParameter lightPositionsParam, EffectParameter lightColorsParam, int maxLights) | ||||
|         { | ||||
|             positions = new Vector3[maxLights]; | ||||
|             colors = new Vector3[maxLights]; | ||||
|             this.positions = new Vector3[maxLights]; | ||||
|             this.colors = new Vector3[maxLights]; | ||||
|             this.intensities = new float[maxLights]; | ||||
|             this.lightPositionsParam = lightPositionsParam; | ||||
|             this.lightColorsParam = lightColorsParam; | ||||
|         } | ||||
| 
 | ||||
|         public PointLight this[int i] | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 var color = colors[i] / intensities[i]; | ||||
|                 return new PointLight( | ||||
|                     positions[i], | ||||
|                     new Color( | ||||
|                         color.X, | ||||
|                         color.Y, | ||||
|                         color.Z, | ||||
|                         1f | ||||
|                     ), | ||||
|                     intensities[i] | ||||
|                 ); | ||||
|             } | ||||
|             set | ||||
|             { | ||||
|                 positions[i] = value.Position; | ||||
|                 colors[i] = value.Color.ToVector3() * value.Radius; | ||||
|                 colors[i] = value.Color.ToVector3() * value.Intensity; | ||||
|                 intensities[i] = value.Intensity; | ||||
|                 lightPositionsParam.SetValue(positions); | ||||
|                 lightColorsParam.SetValue(colors); | ||||
|             } | ||||
|  |  | |||
|  | @ -1,9 +0,0 @@ | |||
| using Microsoft.Xna.Framework; | ||||
| 
 | ||||
| namespace Kav | ||||
| { | ||||
|     public interface ITransformable | ||||
|     { | ||||
|         Matrix TransformMatrix { get; } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,115 @@ | |||
| using System.Collections.Generic; | ||||
| using Microsoft.Xna.Framework; | ||||
| using Microsoft.Xna.Framework.Graphics; | ||||
| 
 | ||||
| namespace Kav | ||||
| { | ||||
|     public class MeshSprite : ICullable, IIndexDrawable | ||||
|     { | ||||
|         private static readonly int PixelScale = 40; | ||||
|         private static readonly short[] Indices = new short[] | ||||
|         { | ||||
|             0, | ||||
|             1, | ||||
|             2, | ||||
|             1, | ||||
|             3, | ||||
|             2 | ||||
|         }; | ||||
| 
 | ||||
|         public Texture2D Texture { get; } | ||||
|         public Texture2D Normal { get; } | ||||
| 
 | ||||
|         public IndexBuffer IndexBuffer { get; } | ||||
|         public VertexBuffer VertexBuffer { get; } | ||||
|         public BoundingBox BoundingBox { get; } | ||||
| 
 | ||||
|         public MeshSprite( | ||||
|             GraphicsDevice graphicsDevice, | ||||
|             Texture2D texture | ||||
|         ) { | ||||
|             Texture = texture; | ||||
|             Normal = null; | ||||
| 
 | ||||
| 			IndexBuffer = new IndexBuffer( | ||||
| 				graphicsDevice, | ||||
| 				IndexElementSize.SixteenBits, | ||||
| 				6, | ||||
| 				BufferUsage.WriteOnly | ||||
| 			); | ||||
|             IndexBuffer.SetData(Indices); | ||||
| 
 | ||||
|             var vertexArray = GenerateVertexArray(Texture); | ||||
| 
 | ||||
|             VertexBuffer = new VertexBuffer( | ||||
|                 graphicsDevice, | ||||
|                 typeof(VertexPositionNormalTexture), | ||||
|                 4, | ||||
|                 BufferUsage.WriteOnly | ||||
|             ); | ||||
|             VertexBuffer.SetData(vertexArray); | ||||
| 
 | ||||
|             BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray)); | ||||
|         } | ||||
| 
 | ||||
|         public MeshSprite( | ||||
|             GraphicsDevice graphicsDevice, | ||||
|             Texture2D texture, | ||||
|             Texture2D normal | ||||
|         ) { | ||||
|             Texture = texture; | ||||
|             Normal = normal; | ||||
| 
 | ||||
| 			IndexBuffer = new IndexBuffer( | ||||
| 				graphicsDevice, | ||||
| 				IndexElementSize.SixteenBits, | ||||
| 				6, | ||||
| 				BufferUsage.WriteOnly | ||||
| 			); | ||||
|             IndexBuffer.SetData(Indices); | ||||
| 
 | ||||
|             var vertexArray = GenerateVertexArray(Texture); | ||||
| 
 | ||||
|             VertexBuffer = new VertexBuffer( | ||||
|                 graphicsDevice, | ||||
|                 typeof(VertexPositionNormalTexture), | ||||
|                 4, | ||||
|                 BufferUsage.WriteOnly | ||||
|             ); | ||||
|             VertexBuffer.SetData(vertexArray); | ||||
| 
 | ||||
|             BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray)); | ||||
|         } | ||||
| 
 | ||||
|         private static VertexPositionNormalTexture[] GenerateVertexArray(Texture2D texture) | ||||
|         { | ||||
|             VertexPositionNormalTexture[] result = new VertexPositionNormalTexture[4]; | ||||
| 
 | ||||
|             result[0].Position = new Vector3(-texture.Width / 2, texture.Height / 2, 0) / PixelScale; | ||||
|             result[0].Normal = new Vector3(0, 0, 1); | ||||
|             result[0].TextureCoordinate = new Vector2(0, 0); | ||||
| 
 | ||||
|             result[1].Position = new Vector3(texture.Width / 2, texture.Height / 2, 0) / PixelScale; | ||||
|             result[1].Normal = new Vector3(0, 0, 1); | ||||
|             result[1].TextureCoordinate = new Vector2(1, 0); | ||||
| 
 | ||||
|             result[2].Position = new Vector3(-texture.Width / 2, -texture.Height / 2, 0) / PixelScale; | ||||
|             result[2].Normal = new Vector3(0, 0, 1); | ||||
|             result[2].TextureCoordinate = new Vector2(0, 1); | ||||
| 
 | ||||
|             result[3].Position = new Vector3(texture.Width / 2, -texture.Height / 2, 0) / PixelScale; | ||||
|             result[3].Normal = new Vector3(0, 0, 1); | ||||
|             result[3].TextureCoordinate = new Vector2(1, 1); | ||||
| 
 | ||||
|             return result; | ||||
|         } | ||||
| 
 | ||||
|         private static IEnumerable<Vector3> Positions(IEnumerable<VertexPositionNormalTexture> vertices) | ||||
|         { | ||||
|             foreach (var vertex in vertices) | ||||
|             { | ||||
|                 yield return vertex.Position; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,109 +0,0 @@ | |||
| using System.Collections.Generic; | ||||
| using Microsoft.Xna.Framework; | ||||
| using Microsoft.Xna.Framework.Graphics; | ||||
| 
 | ||||
| namespace Kav | ||||
| { | ||||
|     public class SpriteMesh : ICullable, IIndexDrawable | ||||
|     { | ||||
|         public enum FlipOptions | ||||
|         { | ||||
|             None, | ||||
|             Horizontal, | ||||
|             Vertical, | ||||
|             Both | ||||
|         } | ||||
| 
 | ||||
|         private static readonly short[] Indices = new short[] | ||||
|         { | ||||
|             0, | ||||
|             1, | ||||
|             2, | ||||
|             1, | ||||
|             3, | ||||
|             2 | ||||
|         }; | ||||
| 
 | ||||
|         public IndexBuffer IndexBuffer { get; } | ||||
|         public VertexBuffer VertexBuffer { get; } | ||||
|         public BoundingBox BoundingBox { get; } | ||||
| 
 | ||||
|         public SpriteMesh( | ||||
|             GraphicsDevice graphicsDevice, | ||||
|             int width, | ||||
|             int height, | ||||
|             FlipOptions flipOptions | ||||
|         ) { | ||||
| 			IndexBuffer = new IndexBuffer( | ||||
| 				graphicsDevice, | ||||
| 				IndexElementSize.SixteenBits, | ||||
| 				6, | ||||
| 				BufferUsage.WriteOnly | ||||
| 			); | ||||
|             IndexBuffer.SetData(Indices); | ||||
| 
 | ||||
|             var vertexArray = GenerateVertexArray(width, height, flipOptions); | ||||
| 
 | ||||
|             VertexBuffer = new VertexBuffer( | ||||
|                 graphicsDevice, | ||||
|                 typeof(VertexPositionNormalTexture), | ||||
|                 4, | ||||
|                 BufferUsage.WriteOnly | ||||
|             ); | ||||
|             VertexBuffer.SetData(vertexArray); | ||||
| 
 | ||||
|             BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray)); | ||||
|         } | ||||
| 
 | ||||
|         private static VertexPositionNormalTexture[] GenerateVertexArray(int pixelWidth, int pixelHeight, FlipOptions flipOptions) | ||||
|         { | ||||
|             var width = pixelWidth / (float)40; | ||||
|             var height = pixelHeight / (float)40; | ||||
| 
 | ||||
|             VertexPositionNormalTexture[] result = new VertexPositionNormalTexture[4]; | ||||
| 
 | ||||
|             var xLeft = 0; | ||||
|             var xRight = 1; | ||||
| 
 | ||||
|             var yTop = 0; | ||||
|             var yBottom = 1; | ||||
| 
 | ||||
|             if (flipOptions == FlipOptions.Horizontal || flipOptions == FlipOptions.Both) | ||||
|             { | ||||
|                 xLeft = 1; | ||||
|                 xRight = 0; | ||||
|             } | ||||
|             if (flipOptions == FlipOptions.Vertical || flipOptions == FlipOptions.Both) | ||||
|             { | ||||
|                 yTop = 1; | ||||
|                 yBottom = 0; | ||||
|             } | ||||
| 
 | ||||
|             result[0].Position = new Vector3(-width / 2, height / 2, 0); | ||||
|             result[0].Normal = new Vector3(0, 0, -1); | ||||
|             result[0].TextureCoordinate = new Vector2(xLeft, yTop); | ||||
| 
 | ||||
|             result[1].Position = new Vector3(width / 2, height / 2, 0); | ||||
|             result[1].Normal = new Vector3(0, 0, -1); | ||||
|             result[1].TextureCoordinate = new Vector2(xRight, yTop); | ||||
| 
 | ||||
|             result[2].Position = new Vector3(-width / 2, -height / 2, 0); | ||||
|             result[2].Normal = new Vector3(0, 0, -1); | ||||
|             result[2].TextureCoordinate = new Vector2(xLeft, yBottom); | ||||
| 
 | ||||
|             result[3].Position = new Vector3(width / 2, -height / 2, 0); | ||||
|             result[3].Normal = new Vector3(0, 0, -1); | ||||
|             result[3].TextureCoordinate = new Vector2(xRight, yBottom); | ||||
| 
 | ||||
|             return result; | ||||
|         } | ||||
| 
 | ||||
|         private static IEnumerable<Vector3> Positions(IEnumerable<VertexPositionNormalTexture> vertices) | ||||
|         { | ||||
|             foreach (var vertex in vertices) | ||||
|             { | ||||
|                 yield return vertex.Position; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -2,7 +2,6 @@ | |||
| 
 | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>netstandard2.0</TargetFramework> | ||||
|     <LangVersion>8.0</LangVersion> | ||||
|     <RootNamespace>Kav</RootNamespace> | ||||
|     <Authors>Evan Hemsley</Authors> | ||||
|     <Copyright>Evan Hemsley 2020</Copyright> | ||||
|  | @ -65,9 +64,6 @@ | |||
|     <EmbeddedResource Include="Models\UnitCube.glb"> | ||||
|       <LogicalName>Kav.Resources.UnitCube.glb</LogicalName> | ||||
| 		</EmbeddedResource> | ||||
|     <EmbeddedResource Include="Models\UnitSphere.glb"> | ||||
|       <LogicalName>Kav.Resources.UnitSphere.glb</LogicalName> | ||||
| 		</EmbeddedResource> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
| </Project> | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ | |||
| 
 | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>netstandard2.0</TargetFramework> | ||||
|     <LangVersion>8.0</LangVersion> | ||||
|     <RootNamespace>Kav</RootNamespace> | ||||
|     <Authors>Evan Hemsley</Authors> | ||||
|     <Copyright>Evan Hemsley 2020</Copyright> | ||||
|  | @ -65,9 +64,6 @@ | |||
|     <EmbeddedResource Include="Models\UnitCube.glb"> | ||||
|       <LogicalName>Kav.Resources.UnitCube.glb</LogicalName> | ||||
| 		</EmbeddedResource> | ||||
|     <EmbeddedResource Include="Models\UnitSphere.glb"> | ||||
|       <LogicalName>Kav.Resources.UnitSphere.glb</LogicalName> | ||||
| 		</EmbeddedResource> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
| </Project> | ||||
|  |  | |||
|  | @ -1,55 +1,18 @@ | |||
| using Microsoft.Xna.Framework; | ||||
| using Microsoft.Xna.Framework.Graphics; | ||||
| using System; | ||||
| 
 | ||||
| namespace Kav | ||||
| { | ||||
|     public sealed class PointLight : IDisposable | ||||
|     public struct PointLight | ||||
|     { | ||||
|         public Vector3 Position { get; } | ||||
|         public Color Color { get; } | ||||
|         public float Radius { get; } | ||||
|         public float Intensity { get; } | ||||
| 
 | ||||
|         public BoundingSphere BoundingSphere { get; } | ||||
| 
 | ||||
|         public RenderTargetCube ShadowMap { get; } | ||||
| 
 | ||||
|         public PointLight( | ||||
|             GraphicsDevice graphicsDevice, | ||||
|             Vector3 position,  | ||||
|             Color color,  | ||||
|             float radius, | ||||
|             int shadowMapSize | ||||
|         ) { | ||||
|         public PointLight(Vector3 position, Color color, float intensity = 1f) | ||||
|         { | ||||
|             Position = position; | ||||
|             Color = color; | ||||
|             Radius = radius; | ||||
| 
 | ||||
|             BoundingSphere = new BoundingSphere(position, Radius); | ||||
| 
 | ||||
|             ShadowMap = new RenderTargetCube( | ||||
|                 graphicsDevice, | ||||
|                 shadowMapSize, | ||||
|                 false, | ||||
|                 SurfaceFormat.Single, | ||||
|                 DepthFormat.Depth24, | ||||
|                 0, | ||||
|                 RenderTargetUsage.PreserveContents | ||||
|             ); | ||||
| 
 | ||||
|             var currentRTs = graphicsDevice.GetRenderTargets(); | ||||
|             foreach (CubeMapFace face in Enum.GetValues(typeof(CubeMapFace))) | ||||
|             { | ||||
|                 graphicsDevice.SetRenderTarget(ShadowMap, face); | ||||
|                 graphicsDevice.Clear(Color.White); | ||||
|             } | ||||
| 
 | ||||
|             graphicsDevice.SetRenderTargets(currentRTs); | ||||
|         } | ||||
| 
 | ||||
|         public void Dispose() | ||||
|         { | ||||
|             ShadowMap.Dispose(); | ||||
|             Intensity = intensity; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,18 +0,0 @@ | |||
| using System.IO; | ||||
| using System.Text.Json; | ||||
| 
 | ||||
| namespace Kav | ||||
| { | ||||
|     public static class CrunchAtlasReader | ||||
|     { | ||||
|         static JsonSerializerOptions options = new JsonSerializerOptions | ||||
|         { | ||||
|             PropertyNameCaseInsensitive = true | ||||
|         }; | ||||
| 
 | ||||
|         public static CrunchTextureAtlasData ReadTextureAtlas(FileInfo file) | ||||
|         { | ||||
|             return JsonSerializer.Deserialize<CrunchTextureAtlasData>(File.ReadAllText(file.FullName), options); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,22 +0,0 @@ | |||
| namespace Kav | ||||
| { | ||||
|     public struct CrunchTextureAtlasData | ||||
|     { | ||||
|         public CrunchTextureAtlasTextureData[] Textures { get; set; } | ||||
|     } | ||||
| 
 | ||||
|     public struct CrunchTextureAtlasTextureData | ||||
|     { | ||||
|         public string Name { get; set; } | ||||
|         public CrunchTextureAtlasImageData[] Images { get; set; } | ||||
|     } | ||||
| 
 | ||||
|     public struct CrunchTextureAtlasImageData | ||||
|     { | ||||
|         public string N { get; set; } | ||||
|         public int X { get; set; } | ||||
|         public int Y { get; set; } | ||||
|         public int W { get; set; } | ||||
|         public int H { get; set; } | ||||
|     } | ||||
| } | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										213
									
								
								Renderer.cs
								
								
								
								
							
							
						
						
									
										213
									
								
								Renderer.cs
								
								
								
								
							|  | @ -1,7 +1,6 @@ | |||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using Kav.Data; | ||||
| using Microsoft.Xna.Framework; | ||||
| using Microsoft.Xna.Framework.Graphics; | ||||
| 
 | ||||
|  | @ -27,9 +26,8 @@ namespace Kav | |||
|         private Effect ToneMapEffect { get; } | ||||
|         private SkyboxEffect SkyboxEffect { get; } | ||||
|         private DiffuseLitSpriteEffect DiffuseLitSpriteEffect { get; } | ||||
| 
 | ||||
|          | ||||
|         private Kav.Model UnitCube { get; } | ||||
|         private Kav.Model UnitSphere { get; } | ||||
| 
 | ||||
|         public Renderer( | ||||
|             GraphicsDevice graphicsDevice | ||||
|  | @ -63,11 +61,6 @@ namespace Kav | |||
|                 GraphicsDevice, | ||||
|                 Smuggler.Importer.ImportGLB(GraphicsDevice, new MemoryStream(Resources.UnitCubeModel)) | ||||
|             ); | ||||
| 
 | ||||
|             UnitSphere = Kav.ModelLoader.Load( | ||||
|                 graphicsDevice, | ||||
|                 Smuggler.Importer.ImportGLB(graphicsDevice, new MemoryStream(Resources.UnitSphereModel)) | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public static (T[], DynamicVertexBuffer) CreateInstanceVertexBuffer<T>( | ||||
|  | @ -118,14 +111,14 @@ namespace Kav | |||
|         public void MeshSpriteRender( | ||||
|             RenderTarget2D renderTarget, | ||||
|             PerspectiveCamera camera, | ||||
|             IEnumerable<MeshSpriteDrawData> meshSpriteDrawDatas, | ||||
|             IEnumerable<(MeshSprite, SpriteBillboardConstraint, Matrix)> meshSpriteBillboardTransforms, | ||||
|             AmbientLight ambientLight, | ||||
|             IEnumerable<PointLight> pointLights, | ||||
|             DirectionalLight? directionalLight | ||||
|         ) { | ||||
|             GraphicsDevice.SetRenderTarget(renderTarget); | ||||
| 
 | ||||
|             GraphicsDevice.DepthStencilState = DepthStencilState.Default; | ||||
|             GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead; | ||||
|             GraphicsDevice.RasterizerState = RasterizerState.CullNone; | ||||
|             GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp; | ||||
|             GraphicsDevice.SamplerStates[1] = SamplerState.PointClamp; | ||||
|  | @ -159,26 +152,17 @@ namespace Kav | |||
| 
 | ||||
|             var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection); | ||||
| 
 | ||||
|             foreach (var data in meshSpriteDrawDatas) | ||||
|             foreach (var (sprite, transform) in FrustumCull(boundingFrustum, BillboardTransforms(camera, meshSpriteBillboardTransforms))) | ||||
|             { | ||||
|                 var matrix = BillboardTransforms(camera, data.TransformMatrix, data.BillboardConstraint); | ||||
|                 DiffuseLitSpriteEffect.NormalMapEnabled = sprite.Normal != null; | ||||
| 
 | ||||
|                 if (FrustumCull(boundingFrustum, data.MeshSprite, matrix)) | ||||
|                 { | ||||
|                     continue; | ||||
|                 } | ||||
|                 DiffuseLitSpriteEffect.World = transform; | ||||
| 
 | ||||
|                 DiffuseLitSpriteEffect.NormalMapEnabled = data.Normal != null; | ||||
|                 GraphicsDevice.Textures[0] = sprite.Texture; | ||||
|                 GraphicsDevice.Textures[1] = sprite.Normal; | ||||
| 
 | ||||
|                 DiffuseLitSpriteEffect.World = matrix; | ||||
|                 DiffuseLitSpriteEffect.UVOffset = data.UVOffset.Offset; | ||||
|                 DiffuseLitSpriteEffect.SubTextureDimensions = data.UVOffset.Percentage; | ||||
| 
 | ||||
|                 GraphicsDevice.Textures[0] = data.Texture; | ||||
|                 GraphicsDevice.Textures[1] = data.Normal; | ||||
| 
 | ||||
|                 GraphicsDevice.SetVertexBuffer(data.MeshSprite.VertexBuffer); | ||||
|                 GraphicsDevice.Indices = data.MeshSprite.IndexBuffer; | ||||
|                 GraphicsDevice.SetVertexBuffer(sprite.VertexBuffer); | ||||
|                 GraphicsDevice.Indices = sprite.IndexBuffer; | ||||
| 
 | ||||
|                 foreach (var pass in DiffuseLitSpriteEffect.CurrentTechnique.Passes) | ||||
|                 { | ||||
|  | @ -188,7 +172,7 @@ namespace Kav | |||
|                         PrimitiveType.TriangleList, | ||||
|                         0, | ||||
|                         0, | ||||
|                         data.MeshSprite.VertexBuffer.VertexCount, | ||||
|                         sprite.VertexBuffer.VertexCount, | ||||
|                         0, | ||||
|                         2 | ||||
|                     ); | ||||
|  | @ -196,79 +180,36 @@ namespace Kav | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void RenderMeshSpriteGBuffer( | ||||
|             RenderTargetBinding[] gBuffer, | ||||
|         private static IEnumerable<(MeshSprite, Matrix)> BillboardTransforms( | ||||
|             PerspectiveCamera camera, | ||||
|             IEnumerable<MeshSpriteDrawData> meshSpriteDrawDatas, | ||||
|             DepthStencilState depthStencilState | ||||
|             IEnumerable<(MeshSprite, SpriteBillboardConstraint, Matrix)> meshSpriteBillboardTransforms | ||||
|         ) { | ||||
|             GraphicsDevice.SetRenderTargets(gBuffer); | ||||
|             GraphicsDevice.RasterizerState = RasterizerState.CullNone; | ||||
|             GraphicsDevice.DepthStencilState = depthStencilState; | ||||
|             GraphicsDevice.BlendState = BlendState.AlphaBlend; | ||||
| 
 | ||||
|             Deferred_GBufferEffect.HardwareInstancingEnabled = false; | ||||
|             Deferred_GBufferEffect.IsSprite = true; | ||||
| 
 | ||||
|             Deferred_GBufferEffect.View = camera.View; | ||||
|             Deferred_GBufferEffect.Projection = camera.Projection; | ||||
| 
 | ||||
|             var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection); | ||||
| 
 | ||||
|             foreach (var data in meshSpriteDrawDatas) | ||||
|             foreach (var (sprite, billboardConstraint, transform) in meshSpriteBillboardTransforms) | ||||
|             { | ||||
|                 var matrix = BillboardTransforms(camera, data.TransformMatrix, data.BillboardConstraint); | ||||
| 
 | ||||
|                 if (FrustumCull(boundingFrustum, data.MeshSprite, matrix)) | ||||
|                 if (billboardConstraint == SpriteBillboardConstraint.None) | ||||
|                 { | ||||
|                     continue; | ||||
|                     yield return (sprite, transform); | ||||
|                 } | ||||
|                 else if (billboardConstraint == SpriteBillboardConstraint.Horizontal) | ||||
|                 { | ||||
|                     yield return (sprite, Matrix.CreateConstrainedBillboard( | ||||
|                         transform.Translation, | ||||
|                         camera.Position, | ||||
|                         Vector3.Up, | ||||
|                         camera.Forward, | ||||
|                         camera.Position - transform.Translation | ||||
|                     )); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     yield return (sprite, Matrix.CreateConstrainedBillboard( | ||||
|                         transform.Translation, | ||||
|                         camera.Position, | ||||
|                         Vector3.Up, | ||||
|                         null, | ||||
|                         null | ||||
|                     )); | ||||
|                 } | ||||
| 
 | ||||
|                 Deferred_GBufferEffect.World = matrix; | ||||
| 
 | ||||
|                 Deferred_GBufferEffect.UVOffset = data.UVOffset.Offset; | ||||
|                 Deferred_GBufferEffect.SubTextureDimensions = data.UVOffset.Percentage; | ||||
| 
 | ||||
|                 Deferred_GBufferEffect.Albedo = Color.White.ToVector3(); | ||||
|                 Deferred_GBufferEffect.Metallic = 0f; | ||||
|                 Deferred_GBufferEffect.Roughness = 1f; | ||||
| 
 | ||||
|                 Deferred_GBufferEffect.AlbedoTexture = data.Texture; | ||||
|                 Deferred_GBufferEffect.NormalTexture = data.Normal; | ||||
|                 Deferred_GBufferEffect.MetallicRoughnessTexture = null; | ||||
| 
 | ||||
|                 RenderIndexed(GraphicsDevice, data, Deferred_GBufferEffect); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private static Matrix BillboardTransforms( | ||||
|             PerspectiveCamera camera, | ||||
|             Matrix transform, | ||||
|             SpriteBillboardConstraint billboardConstraint | ||||
|         ) { | ||||
|             if (billboardConstraint == SpriteBillboardConstraint.None) | ||||
|             { | ||||
|                 return transform; | ||||
|             } | ||||
|             else if (billboardConstraint == SpriteBillboardConstraint.Horizontal) | ||||
|             { | ||||
|                 return Matrix.CreateConstrainedBillboard( | ||||
|                     transform.Translation, | ||||
|                     camera.Position, | ||||
|                     Vector3.Up, | ||||
|                     camera.Forward, | ||||
|                     camera.Position - transform.Translation | ||||
|                 ); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return Matrix.CreateConstrainedBillboard( | ||||
|                     transform.Translation, | ||||
|                     camera.Position, | ||||
|                     Vector3.Up, | ||||
|                     null, | ||||
|                     null | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -279,7 +220,7 @@ namespace Kav | |||
|             BoundingFrustum boundingFrustum, | ||||
|             IEnumerable<(T, Matrix)> drawableTransformPairs, | ||||
|             U effect | ||||
|         ) where T : IIndexDrawable, ICullable where U : Effect, IHasWorldMatrix | ||||
|         ) where T : IIndexDrawable, ICullable where U : Effect, IHasWorldMatrix  | ||||
|         { | ||||
|             foreach (var (drawable, transform) in FrustumCull(boundingFrustum, drawableTransformPairs)) | ||||
|             { | ||||
|  | @ -362,7 +303,7 @@ namespace Kav | |||
|             RenderTarget2D renderTarget, | ||||
|             PerspectiveCamera camera, | ||||
|             IEnumerable<(T, Matrix)> drawableTransforms | ||||
|         ) where T : ICullable, IIndexDrawable | ||||
|         ) where T : ICullable, IIndexDrawable  | ||||
|         { | ||||
|             GraphicsDevice.SetRenderTarget(renderTarget); | ||||
|             GraphicsDevice.DepthStencilState = DepthStencilState.Default; | ||||
|  | @ -378,21 +319,6 @@ namespace Kav | |||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void RenderDepthIndexed<T>( | ||||
|             RenderTarget2D renderTarget, | ||||
|             PerspectiveCamera camera, | ||||
|             T drawable, | ||||
|             DepthStencilState depthStencilState | ||||
|         ) where T : IIndexDrawable { | ||||
|             GraphicsDevice.SetRenderTarget(renderTarget); | ||||
|             GraphicsDevice.DepthStencilState = depthStencilState; | ||||
| 
 | ||||
|             SimpleDepthEffect.View = camera.View; | ||||
|             SimpleDepthEffect.Projection = camera.Projection; | ||||
| 
 | ||||
|             RenderIndexed(GraphicsDevice, drawable, SimpleDepthEffect); | ||||
|         } | ||||
| 
 | ||||
|         public void RenderSkybox( | ||||
|             RenderTarget2D renderTarget, | ||||
|             PerspectiveCamera camera, | ||||
|  | @ -412,7 +338,7 @@ namespace Kav | |||
| 
 | ||||
|             RenderIndexed( | ||||
|                 GraphicsDevice, | ||||
|                 UnitCube.Meshes[0].MeshParts[0], | ||||
|                 UnitCube.Meshes[0].MeshParts[0],  | ||||
|                 SkyboxEffect | ||||
|             ); | ||||
| 
 | ||||
|  | @ -436,7 +362,6 @@ namespace Kav | |||
|             GraphicsDevice.BlendState = BlendState.Opaque; | ||||
| 
 | ||||
|             Deferred_GBufferEffect.HardwareInstancingEnabled = true; | ||||
|             Deferred_GBufferEffect.IsSprite = false; | ||||
| 
 | ||||
|             Deferred_GBufferEffect.Albedo = drawable.Albedo; | ||||
|             Deferred_GBufferEffect.Metallic = drawable.Metallic; | ||||
|  | @ -484,7 +409,6 @@ namespace Kav | |||
|             GraphicsDevice.DepthStencilState = DepthStencilState.Default; | ||||
|             GraphicsDevice.BlendState = BlendState.Opaque; | ||||
| 
 | ||||
|             Deferred_GBufferEffect.IsSprite = false; | ||||
|             Deferred_GBufferEffect.HardwareInstancingEnabled = false; | ||||
|             Deferred_GBufferEffect.View = camera.View; | ||||
|             Deferred_GBufferEffect.Projection = camera.Projection; | ||||
|  | @ -537,8 +461,7 @@ namespace Kav | |||
|             PointLight pointLight | ||||
|         ) { | ||||
|             GraphicsDevice.SetRenderTarget(renderTarget); | ||||
|             GraphicsDevice.RasterizerState = RasterizerState.CullClockwise; | ||||
|             GraphicsDevice.DepthStencilState = DepthStencilState.None; | ||||
|             GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead; | ||||
|             GraphicsDevice.BlendState = BlendState.Additive; | ||||
| 
 | ||||
|             DeferredPointLightEffect.GPosition = gPosition; | ||||
|  | @ -551,21 +474,11 @@ namespace Kav | |||
| 
 | ||||
|             DeferredPointLightEffect.PointLightPosition = pointLight.Position; | ||||
|             DeferredPointLightEffect.PointLightColor = | ||||
|                 pointLight.Color.ToVector3() * pointLight.Radius; | ||||
|                 pointLight.Color.ToVector3() * pointLight.Intensity; | ||||
| 
 | ||||
|             DeferredPointLightEffect.FarPlane = 25f; // FIXME: magic value | ||||
| 
 | ||||
|             DeferredPointLightEffect.World = | ||||
|                 Matrix.CreateScale(pointLight.Radius) * | ||||
|                 Matrix.CreateTranslation(pointLight.Position); | ||||
|             DeferredPointLightEffect.View = camera.View; | ||||
|             DeferredPointLightEffect.Projection = camera.Projection; | ||||
| 
 | ||||
|             RenderIndexed( | ||||
|                 GraphicsDevice, | ||||
|                 UnitSphere.Meshes[0].MeshParts[0], | ||||
|                 DeferredPointLightEffect | ||||
|             ); | ||||
|             RenderFullscreenEffect(DeferredPointLightEffect); | ||||
|         } | ||||
| 
 | ||||
|         public void RenderDirectionalLight( | ||||
|  | @ -579,7 +492,6 @@ namespace Kav | |||
|             DirectionalLight directionalLight | ||||
|         ) { | ||||
|             GraphicsDevice.SetRenderTarget(renderTarget); | ||||
|             GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; | ||||
|             GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead; | ||||
|             GraphicsDevice.BlendState = BlendState.Additive; | ||||
| 
 | ||||
|  | @ -752,8 +664,8 @@ namespace Kav | |||
|             for (var i = 0; i < shadowMapData.NumShadowCascades; i++) | ||||
|             { | ||||
|                 RenderDirectionalShadowMapIndexed( | ||||
|                     shadowMapData, | ||||
|                     i, | ||||
|                     shadowMapData,  | ||||
|                     i,  | ||||
|                     drawableTransforms | ||||
|                 ); | ||||
|             } | ||||
|  | @ -772,9 +684,9 @@ namespace Kav | |||
|             SimpleDepthEffect.Projection = shadowMapData.LightSpaceProjections[shadowCascadeIndex]; | ||||
| 
 | ||||
|             CullAndRenderIndexed( | ||||
|                 GraphicsDevice, | ||||
|                 new BoundingFrustum(SimpleDepthEffect.View * SimpleDepthEffect.Projection), | ||||
|                 drawableTransforms, | ||||
|                 GraphicsDevice,  | ||||
|                 new BoundingFrustum(SimpleDepthEffect.View * SimpleDepthEffect.Projection),  | ||||
|                 drawableTransforms,  | ||||
|                 SimpleDepthEffect | ||||
|             ); | ||||
|         } | ||||
|  | @ -815,7 +727,7 @@ namespace Kav | |||
|             SimpleDepthEffectInstanced.Projection = shadowMapData.LightSpaceProjections[shadowCascadeIndex]; | ||||
| 
 | ||||
|             RenderInstanced( | ||||
|                 GraphicsDevice, | ||||
|                 GraphicsDevice,  | ||||
|                 drawable, | ||||
|                 instanceVertexBuffer, | ||||
|                 numInstances, | ||||
|  | @ -825,6 +737,7 @@ namespace Kav | |||
| 
 | ||||
|         public void RenderPointShadowMapIndexed<T>( | ||||
|             RenderTargetCube pointShadowCubeMap, | ||||
|             PerspectiveCamera camera, | ||||
|             IEnumerable<(T, Matrix)> modelTransforms, | ||||
|             PointLight pointLight | ||||
|         ) where T : ICullable, IIndexDrawable { | ||||
|  | @ -892,8 +805,8 @@ namespace Kav | |||
| 
 | ||||
|                 CullAndRenderIndexed( | ||||
|                     GraphicsDevice, | ||||
|                     new BoundingFrustum(LinearDepthEffect.View * LinearDepthEffect.Projection), | ||||
|                     modelTransforms, | ||||
|                     new BoundingFrustum(LinearDepthEffect.View * LinearDepthEffect.Projection),  | ||||
|                     modelTransforms,  | ||||
|                     LinearDepthEffect | ||||
|                 ); | ||||
|             } | ||||
|  | @ -905,7 +818,7 @@ namespace Kav | |||
|             VertexBuffer instanceVertexBuffer, | ||||
|             int numInstances, | ||||
|             PointLight pointLight | ||||
|         ) where T : ICullable, IIndexDrawable | ||||
|         ) where T : ICullable, IIndexDrawable  | ||||
|         { | ||||
|             GraphicsDevice.DepthStencilState = DepthStencilState.Default; | ||||
|             GraphicsDevice.BlendState = BlendState.Opaque; | ||||
|  | @ -994,27 +907,19 @@ namespace Kav | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private static bool FrustumCull<T>( | ||||
|         private static IEnumerable<Matrix> FrustumCull<T>( | ||||
|             BoundingFrustum boundingFrustum, | ||||
|             T cullable, | ||||
|             Matrix transform | ||||
|         ) where T : ICullable { | ||||
|             var boundingBox = TransformedBoundingBox(cullable.BoundingBox, transform); | ||||
|             var containment = boundingFrustum.Contains(boundingBox); | ||||
|             return (containment == ContainmentType.Disjoint); | ||||
|         } | ||||
| 
 | ||||
|         private static IEnumerable<T> FrustumCull<T>( | ||||
|             BoundingFrustum boundingFrustum, | ||||
|             IEnumerable<T> cullableTransformables | ||||
|         ) where T : ICullable, ITransformable { | ||||
|             foreach (var cullableTransformable in cullableTransformables) | ||||
|             IEnumerable<Matrix> transforms | ||||
|         ) where T : ICullable | ||||
|         { | ||||
|             foreach (var transform in transforms) | ||||
|             { | ||||
|                 var boundingBox = TransformedBoundingBox(cullableTransformable.BoundingBox, cullableTransformable.TransformMatrix); | ||||
|                 var boundingBox = TransformedBoundingBox(cullable.BoundingBox, transform); | ||||
|                 var containment = boundingFrustum.Contains(boundingBox); | ||||
|                 if (containment != ContainmentType.Disjoint) | ||||
|                 { | ||||
|                     yield return cullableTransformable; | ||||
|                     yield return transform; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  |  | |||
							
								
								
									
										13
									
								
								Resources.cs
								
								
								
								
							
							
						
						
									
										13
									
								
								Resources.cs
								
								
								
								
							|  | @ -195,18 +195,6 @@ namespace Kav | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static byte[] UnitSphereModel | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if (unitSphereModel == null) | ||||
|                 { | ||||
|                     unitSphereModel = GetResource("UnitSphere.glb"); | ||||
|                 } | ||||
|                 return unitSphereModel; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private static byte[] ambientLightEffect; | ||||
|         private static byte[] pointLightEffect; | ||||
|         private static byte[] directionalLightEffect; | ||||
|  | @ -224,7 +212,6 @@ namespace Kav | |||
|         private static byte[] paletteCrushEffect; | ||||
| 
 | ||||
|         private static byte[] unitCubeModel; | ||||
|         private static byte[] unitSphereModel; | ||||
| 
 | ||||
|         private static byte[] GetResource(string name) | ||||
|         { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue