Compare commits
1 Commits
main
...
tiled_draw
Author | SHA1 | Date |
---|---|---|
cosmonaut | 40b5d71bfe |
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav.Data
|
||||||
|
{
|
||||||
|
public struct MeshPartDrawData : IGBufferDrawable, IUVDrawable, ICullable, IIndexDrawable
|
||||||
|
{
|
||||||
|
public MeshPart MeshPart { get; }
|
||||||
|
public Matrix TransformMatrix { get; }
|
||||||
|
public UVData UVData { get; }
|
||||||
|
|
||||||
|
public BoundingBox BoundingBox => MeshPart.BoundingBox;
|
||||||
|
|
||||||
|
public IndexBuffer IndexBuffer => MeshPart.IndexBuffer;
|
||||||
|
public VertexBuffer VertexBuffer => MeshPart.VertexBuffer;
|
||||||
|
|
||||||
|
public Vector3 Albedo => MeshPart.Albedo;
|
||||||
|
public float Metallic => MeshPart.Metallic;
|
||||||
|
public float Roughness => MeshPart.Roughness;
|
||||||
|
|
||||||
|
public Texture2D AlbedoTexture => MeshPart.AlbedoTexture;
|
||||||
|
public Texture2D NormalTexture => MeshPart.NormalTexture;
|
||||||
|
public Texture2D MetallicRoughnessTexture => MeshPart.MetallicRoughnessTexture;
|
||||||
|
|
||||||
|
public MeshPartDrawData(
|
||||||
|
MeshPart meshPart,
|
||||||
|
Matrix transformMatrix,
|
||||||
|
UVData uvData
|
||||||
|
) {
|
||||||
|
MeshPart = meshPart;
|
||||||
|
TransformMatrix = transformMatrix;
|
||||||
|
UVData = uvData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,35 +1,26 @@
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
|
|
||||||
namespace Kav.Data
|
namespace Kav.Data
|
||||||
{
|
{
|
||||||
public struct MeshSpriteDrawData : IIndexDrawable, ICullable, ITransformable
|
public struct MeshSpriteDrawData : ICullable
|
||||||
{
|
{
|
||||||
public SpriteMesh MeshSprite { get; }
|
public MeshSprite MeshSprite { get; }
|
||||||
public Texture2D Texture { get; }
|
|
||||||
public Texture2D Normal { get; }
|
|
||||||
public SpriteBillboardConstraint BillboardConstraint { get; }
|
public SpriteBillboardConstraint BillboardConstraint { get; }
|
||||||
public Matrix TransformMatrix { get; }
|
public Matrix TransformMatrix { get; }
|
||||||
public UVData UVOffset { get; }
|
public UVData UVData { get; }
|
||||||
|
|
||||||
public IndexBuffer IndexBuffer => MeshSprite.IndexBuffer;
|
|
||||||
public VertexBuffer VertexBuffer => MeshSprite.VertexBuffer;
|
|
||||||
public BoundingBox BoundingBox => MeshSprite.BoundingBox;
|
public BoundingBox BoundingBox => MeshSprite.BoundingBox;
|
||||||
|
|
||||||
public MeshSpriteDrawData(
|
public MeshSpriteDrawData(
|
||||||
SpriteMesh meshSprite,
|
MeshSprite meshSprite,
|
||||||
Texture2D texture,
|
|
||||||
Texture2D normal,
|
|
||||||
SpriteBillboardConstraint billboardConstraint,
|
SpriteBillboardConstraint billboardConstraint,
|
||||||
Matrix transformMatrix,
|
Matrix transformMatrix,
|
||||||
UVData offset
|
UVData uvData
|
||||||
) {
|
) {
|
||||||
MeshSprite = meshSprite;
|
MeshSprite = meshSprite;
|
||||||
Texture = texture;
|
|
||||||
Normal = normal;
|
|
||||||
BillboardConstraint = billboardConstraint;
|
BillboardConstraint = billboardConstraint;
|
||||||
TransformMatrix = transformMatrix;
|
TransformMatrix = transformMatrix;
|
||||||
UVOffset = offset;
|
UVData = uvData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,6 +1,6 @@
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
namespace Kav
|
namespace Kav.Data
|
||||||
{
|
{
|
||||||
public struct UVData
|
public struct UVData
|
||||||
{
|
{
|
||||||
|
@ -15,5 +15,10 @@ namespace Kav
|
||||||
Percentage = subTextureDimensions / atlasDimensions;
|
Percentage = subTextureDimensions / atlasDimensions;
|
||||||
Offset = positionInAtlas / atlasDimensions;
|
Offset = positionInAtlas / atlasDimensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector4 ToVector4()
|
||||||
|
{
|
||||||
|
return new Vector4(Offset.X, Offset.Y, Percentage.X, Percentage.Y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,17 +12,12 @@ namespace Kav
|
||||||
EffectParameter normalTextureParam;
|
EffectParameter normalTextureParam;
|
||||||
EffectParameter metallicRoughnessTextureParam;
|
EffectParameter metallicRoughnessTextureParam;
|
||||||
|
|
||||||
|
EffectParameter uvOffsetAndDimensionsParam;
|
||||||
|
|
||||||
EffectParameter albedoParam;
|
EffectParameter albedoParam;
|
||||||
EffectParameter metallicParam;
|
EffectParameter metallicParam;
|
||||||
EffectParameter roughnessParam;
|
EffectParameter roughnessParam;
|
||||||
|
|
||||||
EffectParameter uvOffsetAndDimensionsParam;
|
|
||||||
EffectParameter isSpriteParam;
|
|
||||||
|
|
||||||
EffectParameter numTextureRowsParam;
|
|
||||||
EffectParameter numTextureColumnsParam;
|
|
||||||
|
|
||||||
EffectParameter vertexShaderIndexParam;
|
|
||||||
EffectParameter shaderIndexParam;
|
EffectParameter shaderIndexParam;
|
||||||
|
|
||||||
Matrix world = Matrix.Identity;
|
Matrix world = Matrix.Identity;
|
||||||
|
@ -33,13 +28,7 @@ namespace Kav
|
||||||
float metallic;
|
float metallic;
|
||||||
float roughness;
|
float roughness;
|
||||||
|
|
||||||
Vector2 uvOffset;
|
Vector4 uvData;
|
||||||
Vector2 subTextureDimensions;
|
|
||||||
|
|
||||||
bool isSprite = false;
|
|
||||||
|
|
||||||
int numTextureRows = 1;
|
|
||||||
int numTextureColumns = 1;
|
|
||||||
|
|
||||||
bool albedoTextureEnabled = false;
|
bool albedoTextureEnabled = false;
|
||||||
bool metallicRoughnessMapEnabled = false;
|
bool metallicRoughnessMapEnabled = false;
|
||||||
|
@ -141,54 +130,15 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int NumTextureRows
|
public Vector4 UVData
|
||||||
{
|
{
|
||||||
get { return numTextureRows; }
|
get { return uvData; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
numTextureRows = value;
|
uvData = value;
|
||||||
numTextureRowsParam.SetValue(numTextureRows);
|
uvOffsetAndDimensionsParam.SetValue(uvData);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public int NumTextureColumns
|
|
||||||
{
|
|
||||||
get { return numTextureColumns; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
numTextureColumns = value;
|
|
||||||
numTextureColumnsParam.SetValue(numTextureColumns);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
public bool HardwareInstancingEnabled
|
||||||
|
@ -248,28 +198,6 @@ namespace Kav
|
||||||
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
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;
|
|
||||||
|
|
||||||
if (hardwareInstancingEnabled)
|
|
||||||
{
|
|
||||||
vertexShaderIndex = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
vertexShaderIndexParam.SetValue(vertexShaderIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
|
if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
|
||||||
{
|
{
|
||||||
int shaderIndex = 0;
|
int shaderIndex = 0;
|
||||||
|
@ -322,14 +250,9 @@ namespace Kav
|
||||||
metallicParam = Parameters["MetallicValue"];
|
metallicParam = Parameters["MetallicValue"];
|
||||||
roughnessParam = Parameters["RoughnessValue"];
|
roughnessParam = Parameters["RoughnessValue"];
|
||||||
|
|
||||||
numTextureRowsParam = Parameters["NumTextureRows"];
|
|
||||||
numTextureColumnsParam = Parameters["NumTextureColumns"];
|
|
||||||
|
|
||||||
uvOffsetAndDimensionsParam = Parameters["UVOffsetAndDimensions"];
|
uvOffsetAndDimensionsParam = Parameters["UVOffsetAndDimensions"];
|
||||||
isSpriteParam = Parameters["IsSprite"];
|
|
||||||
|
|
||||||
shaderIndexParam = Parameters["PixelShaderIndex"];
|
shaderIndexParam = Parameters["PixelShaderIndex"];
|
||||||
vertexShaderIndexParam = Parameters["VertexShaderIndex"];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,7 @@ namespace Kav
|
||||||
Matrix view = Matrix.Identity;
|
Matrix view = Matrix.Identity;
|
||||||
Matrix projection = Matrix.Identity;
|
Matrix projection = Matrix.Identity;
|
||||||
|
|
||||||
Vector2 uvOffset;
|
Vector4 uvData;
|
||||||
Vector2 subTextureDimensions;
|
|
||||||
|
|
||||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||||
|
|
||||||
|
@ -115,23 +114,13 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 UVOffset
|
public Vector4 UVData
|
||||||
{
|
{
|
||||||
get { return uvOffset; }
|
get { return uvData; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uvOffset = value;
|
uvData = value;
|
||||||
dirtyFlags |= EffectDirtyFlags.UVOrDimensions;
|
dirtyFlags |= EffectDirtyFlags.UVData;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2 SubTextureDimensions
|
|
||||||
{
|
|
||||||
get { return subTextureDimensions; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
subTextureDimensions = value;
|
|
||||||
dirtyFlags |= EffectDirtyFlags.UVOrDimensions;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,14 +157,11 @@ namespace Kav
|
||||||
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dirtyFlags & EffectDirtyFlags.UVOrDimensions) != 0)
|
if ((dirtyFlags & EffectDirtyFlags.UVData) != 0)
|
||||||
{
|
{
|
||||||
uvOffsetAndDimensionsParam.SetValue(new Vector4(
|
uvOffsetAndDimensionsParam.SetValue(uvData);
|
||||||
UVOffset.X, UVOffset.Y,
|
|
||||||
SubTextureDimensions.X, SubTextureDimensions.Y
|
|
||||||
));
|
|
||||||
|
|
||||||
dirtyFlags &= ~EffectDirtyFlags.UVOrDimensions;
|
dirtyFlags &= ~EffectDirtyFlags.UVData;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
|
if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Kav
|
||||||
VertexShaderIndex = 8,
|
VertexShaderIndex = 8,
|
||||||
PixelShaderIndex = 16,
|
PixelShaderIndex = 16,
|
||||||
ViewProj = 32,
|
ViewProj = 32,
|
||||||
UVOrDimensions = 64,
|
UVData = 64,
|
||||||
All = -1
|
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,32 +4,31 @@ DECLARE_TEXTURE(AlbedoTexture, 0);
|
||||||
DECLARE_TEXTURE(NormalTexture, 1);
|
DECLARE_TEXTURE(NormalTexture, 1);
|
||||||
DECLARE_TEXTURE(MetallicRoughnessTexture, 2);
|
DECLARE_TEXTURE(MetallicRoughnessTexture, 2);
|
||||||
|
|
||||||
|
float3 AlbedoValue;
|
||||||
|
float MetallicValue;
|
||||||
|
float RoughnessValue;
|
||||||
|
|
||||||
float4 UVOffsetAndDimensions;
|
float4 UVOffsetAndDimensions;
|
||||||
float IsSprite;
|
|
||||||
|
|
||||||
BEGIN_CONSTANTS
|
float4x4 World;
|
||||||
|
float4x4 ViewProjection;
|
||||||
float3 AlbedoValue _ps(c0) _cb(c0);
|
|
||||||
float MetallicValue _ps(c1) _cb(c1);
|
|
||||||
float RoughnessValue _ps(c2) _cb(c2);
|
|
||||||
|
|
||||||
int NumTextureRows _vs(c9) _cb(c3);
|
|
||||||
int NumTextureColumns _vs(c10) _cb(c4);
|
|
||||||
|
|
||||||
MATRIX_CONSTANTS
|
|
||||||
|
|
||||||
float4x4 World _vs(c0) _cb(c7);
|
|
||||||
float4x4 ViewProjection _vs(c4) _cb(c11);
|
|
||||||
|
|
||||||
END_CONSTANTS
|
|
||||||
|
|
||||||
struct VertexInput
|
struct VertexInput
|
||||||
{
|
{
|
||||||
float4 Position : POSITION;
|
float3 Position : POSITION;
|
||||||
float3 Normal : NORMAL;
|
float3 Normal : NORMAL;
|
||||||
float2 TexCoord : TEXCOORD;
|
float2 TexCoord : TEXCOORD;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VertexInstancedInput
|
||||||
|
{
|
||||||
|
float3 Position : POSITION;
|
||||||
|
float3 Normal : NORMAL;
|
||||||
|
float2 TexCoord : TEXCOORD0;
|
||||||
|
float3 Translation : TEXCOORD2;
|
||||||
|
float2 UVData : TANGENT;
|
||||||
|
};
|
||||||
|
|
||||||
struct PixelInput
|
struct PixelInput
|
||||||
{
|
{
|
||||||
float4 Position : SV_POSITION;
|
float4 Position : SV_POSITION;
|
||||||
|
@ -56,8 +55,8 @@ PixelInput main_vs(VertexInput input)
|
||||||
output.NormalWorld = normalize(mul(input.Normal, World));
|
output.NormalWorld = normalize(mul(input.Normal, World));
|
||||||
|
|
||||||
float2 texCoord;
|
float2 texCoord;
|
||||||
texCoord.x = (input.TexCoord.x * UVOffsetAndDimensions.z) + UVOffsetAndDimensions.x;
|
texCoord.x = (input.TexCoord.x / UVOffsetAndDimensions.z) + UVOffsetAndDimensions.x;
|
||||||
texCoord.y = (input.TexCoord.y * UVOffsetAndDimensions.w) + UVOffsetAndDimensions.y;
|
texCoord.y = (input.TexCoord.y / UVOffsetAndDimensions.w) + UVOffsetAndDimensions.y;
|
||||||
output.TexCoord = texCoord;
|
output.TexCoord = texCoord;
|
||||||
|
|
||||||
float4x4 worldViewProjection = mul(World, ViewProjection);
|
float4x4 worldViewProjection = mul(World, ViewProjection);
|
||||||
|
@ -67,9 +66,7 @@ PixelInput main_vs(VertexInput input)
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelInput instanced_vs(
|
PixelInput instanced_vs(
|
||||||
VertexInput input,
|
VertexInstancedInput input
|
||||||
float3 Translation : TEXCOORD2,
|
|
||||||
float2 UVOffset : TEXCOORD5
|
|
||||||
) {
|
) {
|
||||||
PixelInput output;
|
PixelInput output;
|
||||||
|
|
||||||
|
@ -77,7 +74,7 @@ PixelInput instanced_vs(
|
||||||
float4(1, 0, 0, 0),
|
float4(1, 0, 0, 0),
|
||||||
float4(0, 1, 0, 0),
|
float4(0, 1, 0, 0),
|
||||||
float4(0, 0, 1, 0),
|
float4(0, 0, 1, 0),
|
||||||
float4(Translation.x, Translation.y, Translation.z, 1)
|
float4(input.Translation.x, input.Translation.y, input.Translation.z, 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
float4x4 worldViewProjection = mul(world, ViewProjection);
|
float4x4 worldViewProjection = mul(world, ViewProjection);
|
||||||
|
@ -86,9 +83,9 @@ PixelInput instanced_vs(
|
||||||
output.NormalWorld = mul(input.Normal, world);
|
output.NormalWorld = mul(input.Normal, world);
|
||||||
|
|
||||||
float2 texCoord;
|
float2 texCoord;
|
||||||
texCoord.x = (input.TexCoord.x / NumTextureColumns + UVOffset.x);
|
texCoord.x = (input.TexCoord.x / 8) + input.UVData.x;
|
||||||
texCoord.y = (input.TexCoord.y / NumTextureRows + UVOffset.y);
|
texCoord.y = (input.TexCoord.y / 1) + input.UVData.y;
|
||||||
output.TexCoord = texCoord;
|
output.TexCoord = input.TexCoord;
|
||||||
|
|
||||||
output.Position = mul(input.Position, worldViewProjection);
|
output.Position = mul(input.Position, worldViewProjection);
|
||||||
|
|
||||||
|
@ -120,7 +117,7 @@ PixelOutput NonePS(PixelInput input)
|
||||||
PixelOutput output;
|
PixelOutput output;
|
||||||
|
|
||||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
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.gAlbedo = float4(AlbedoValue, 1.0);
|
||||||
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
||||||
|
|
||||||
|
@ -132,12 +129,10 @@ PixelOutput AlbedoPS(PixelInput input)
|
||||||
PixelOutput output;
|
PixelOutput output;
|
||||||
|
|
||||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
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.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord);
|
||||||
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
||||||
|
|
||||||
if (output.gAlbedo.a == 0.0) { discard; }
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +141,7 @@ PixelOutput MetallicRoughnessPS(PixelInput input)
|
||||||
PixelOutput output;
|
PixelOutput output;
|
||||||
|
|
||||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
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.gAlbedo = float4(AlbedoValue, 1.0);
|
||||||
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
||||||
|
|
||||||
|
@ -158,7 +153,7 @@ PixelOutput NormalPS(PixelInput input)
|
||||||
PixelOutput output;
|
PixelOutput output;
|
||||||
|
|
||||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
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.gAlbedo = float4(AlbedoValue, 1.0);
|
||||||
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
||||||
|
|
||||||
|
@ -170,12 +165,10 @@ PixelOutput AlbedoMetallicRoughnessPS(PixelInput input)
|
||||||
PixelOutput output;
|
PixelOutput output;
|
||||||
|
|
||||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
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.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord);
|
||||||
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
||||||
|
|
||||||
if (output.gAlbedo.a == 0.0) { discard; }
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,12 +177,10 @@ PixelOutput AlbedoNormalPS(PixelInput input)
|
||||||
PixelOutput output;
|
PixelOutput output;
|
||||||
|
|
||||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
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.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord);
|
||||||
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
||||||
|
|
||||||
if (output.gAlbedo.a == 0.0) { discard; }
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +189,7 @@ PixelOutput MetallicRoughnessNormalPS(PixelInput input)
|
||||||
PixelOutput output;
|
PixelOutput output;
|
||||||
|
|
||||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
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.gAlbedo = float4(AlbedoValue, 1.0);
|
||||||
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
||||||
|
|
||||||
|
@ -210,28 +201,13 @@ PixelOutput AlbedoMetallicRoughnessNormalMapPS(PixelInput input)
|
||||||
PixelOutput output;
|
PixelOutput output;
|
||||||
|
|
||||||
output.gPosition = float4(input.PositionWorld, 1.0);
|
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.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord);
|
||||||
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
||||||
|
|
||||||
if (output.gAlbedo.a == 0.0) { discard; }
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexShader VSArray[2] =
|
|
||||||
{
|
|
||||||
compile vs_3_0 main_vs(),
|
|
||||||
compile vs_3_0 instanced_vs()
|
|
||||||
};
|
|
||||||
|
|
||||||
int VSIndices[2] =
|
|
||||||
{
|
|
||||||
0, 1
|
|
||||||
};
|
|
||||||
|
|
||||||
int VertexShaderIndex = 0;
|
|
||||||
|
|
||||||
PixelShader PSArray[8] =
|
PixelShader PSArray[8] =
|
||||||
{
|
{
|
||||||
compile ps_3_0 NonePS(),
|
compile ps_3_0 NonePS(),
|
||||||
|
@ -258,7 +234,7 @@ Technique GBuffer
|
||||||
{
|
{
|
||||||
Pass
|
Pass
|
||||||
{
|
{
|
||||||
VertexShader = (VSArray[VSIndices[VertexShaderIndex]]);
|
VertexShader = compile vs_3_0 instanced_vs();
|
||||||
PixelShader = (PSArray[PSIndices[PixelShaderIndex]]);
|
PixelShader = (PSArray[PSIndices[PixelShaderIndex]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,32 +80,17 @@ float4 main_ps(PixelInput input) : SV_TARGET0
|
||||||
float2 texCoord = 0.5f * float2(input.ScreenPosition.x,-input.ScreenPosition.y) + 0.5f;
|
float2 texCoord = 0.5f * float2(input.ScreenPosition.x,-input.ScreenPosition.y) + 0.5f;
|
||||||
|
|
||||||
float3 worldPosition = SAMPLE_TEXTURE(gPosition, texCoord).rgb;
|
float3 worldPosition = SAMPLE_TEXTURE(gPosition, texCoord).rgb;
|
||||||
float4 normalSample = SAMPLE_TEXTURE(gNormal, texCoord);
|
float3 normal = SAMPLE_TEXTURE(gNormal, texCoord).xyz;
|
||||||
float3 normal = normalSample.xyz;
|
|
||||||
float isSprite = normalSample.a;
|
|
||||||
float3 albedo = SAMPLE_TEXTURE(gAlbedo, texCoord).rgb;
|
float3 albedo = SAMPLE_TEXTURE(gAlbedo, texCoord).rgb;
|
||||||
float2 metallicRoughness = SAMPLE_TEXTURE(gMetallicRoughness, texCoord).rg;
|
float2 metallicRoughness = SAMPLE_TEXTURE(gMetallicRoughness, texCoord).rg;
|
||||||
|
|
||||||
if (isSprite == 1.0)
|
return ComputeColor(
|
||||||
{
|
worldPosition,
|
||||||
float3 lightDir = PointLightPosition - worldPosition;
|
normal,
|
||||||
float3 L = normalize(lightDir);
|
albedo,
|
||||||
float distance = length(lightDir);
|
metallicRoughness.r,
|
||||||
float attenuation = 1.0 / (distance * distance);
|
metallicRoughness.g
|
||||||
float3 radiance = PointLightColor * attenuation;
|
);
|
||||||
|
|
||||||
return float4(albedo * radiance * 0.1, 1.0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ComputeColor(
|
|
||||||
worldPosition,
|
|
||||||
normal,
|
|
||||||
albedo,
|
|
||||||
metallicRoughness.r,
|
|
||||||
metallicRoughness.g
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Technique DeferredPBR_Point
|
Technique DeferredPBR_Point
|
||||||
|
|
|
@ -43,8 +43,8 @@ PixelShaderInput main_vs(VertexShaderInput input)
|
||||||
output.PositionWS = mul(input.Position, World).xyz;
|
output.PositionWS = mul(input.Position, World).xyz;
|
||||||
|
|
||||||
float2 texCoord;
|
float2 texCoord;
|
||||||
texCoord.x = (input.TexCoord.x * UVOffsetAndDimensions.z) + UVOffsetAndDimensions.x;
|
texCoord.x = (input.TexCoord.x / UVOffsetAndDimensions.z) + UVOffsetAndDimensions.x;
|
||||||
texCoord.y = (input.TexCoord.y * UVOffsetAndDimensions.w) + UVOffsetAndDimensions.y;
|
texCoord.y = (input.TexCoord.y / UVOffsetAndDimensions.w) + UVOffsetAndDimensions.y;
|
||||||
output.TexCoord = texCoord;
|
output.TexCoord = texCoord;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
@ -98,9 +98,6 @@ float4 LightColor(float3 worldPosition, float3 worldNormal)
|
||||||
float4 WithoutNormalMap(PixelShaderInput input) : COLOR0
|
float4 WithoutNormalMap(PixelShaderInput input) : COLOR0
|
||||||
{
|
{
|
||||||
float4 tex = SAMPLE_TEXTURE(Texture, input.TexCoord);
|
float4 tex = SAMPLE_TEXTURE(Texture, input.TexCoord);
|
||||||
|
|
||||||
if (tex.a == 0.0) { discard; }
|
|
||||||
|
|
||||||
float3 normalWS = normalize(input.NormalWS);
|
float3 normalWS = normalize(input.NormalWS);
|
||||||
|
|
||||||
return tex * LightColor(input.PositionWS, normalWS);
|
return tex * LightColor(input.PositionWS, normalWS);
|
||||||
|
@ -109,9 +106,6 @@ float4 WithoutNormalMap(PixelShaderInput input) : COLOR0
|
||||||
float4 WithNormalMap(PixelShaderInput input) : COLOR0
|
float4 WithNormalMap(PixelShaderInput input) : COLOR0
|
||||||
{
|
{
|
||||||
float4 tex = SAMPLE_TEXTURE(Texture, input.TexCoord);
|
float4 tex = SAMPLE_TEXTURE(Texture, input.TexCoord);
|
||||||
|
|
||||||
if (tex.a == 0.0) { discard; }
|
|
||||||
|
|
||||||
float3 normalWS = GetNormalFromMap(input.PositionWS, input.TexCoord, input.NormalWS);
|
float3 normalWS = GetNormalFromMap(input.PositionWS, input.TexCoord, input.NormalWS);
|
||||||
|
|
||||||
return tex * LightColor(input.PositionWS, normalWS);
|
return tex * LightColor(input.PositionWS, normalWS);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "Macros.fxh"
|
#include "Macros.fxh"
|
||||||
|
|
||||||
|
#define FLT_MAX 3.402823466e+38
|
||||||
|
|
||||||
DECLARE_TEXTURE(Texture, 0);
|
DECLARE_TEXTURE(Texture, 0);
|
||||||
DECLARE_TEXTURE(Palette, 1);
|
DECLARE_TEXTURE(Palette, 1);
|
||||||
|
|
||||||
|
@ -38,12 +40,11 @@ float4 main_ps(PixelInput input) : SV_TARGET0
|
||||||
float3 sampled_color = sampled.rgb;
|
float3 sampled_color = sampled.rgb;
|
||||||
|
|
||||||
float3 closest_color = float3(0, 0, 0);
|
float3 closest_color = float3(0, 0, 0);
|
||||||
float closest_dist = 100000;
|
float closest_dist = FLT_MAX;
|
||||||
|
|
||||||
for (int i = 0; i < PaletteWidth; i++)
|
for (int i = 0; i < PaletteWidth; i++)
|
||||||
{
|
{
|
||||||
float texX = (i / (float)PaletteWidth);
|
float3 palette_color = SAMPLE_TEXTURE(Palette, float2(i / (float)PaletteWidth, 0));
|
||||||
float3 palette_color = SAMPLE_TEXTURE(Palette, float2(texX, 0));
|
|
||||||
float dist = distance(palette_color, sampled_color);
|
float dist = distance(palette_color, sampled_color);
|
||||||
if (dist < closest_dist)
|
if (dist < closest_dist)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,5 +5,6 @@ namespace Kav
|
||||||
public interface ICullable
|
public interface ICullable
|
||||||
{
|
{
|
||||||
BoundingBox BoundingBox { get; }
|
BoundingBox BoundingBox { get; }
|
||||||
|
Matrix TransformMatrix { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Kav.Data;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
@ -12,8 +13,5 @@ namespace Kav
|
||||||
Texture2D AlbedoTexture { get; }
|
Texture2D AlbedoTexture { get; }
|
||||||
Texture2D NormalTexture { get; }
|
Texture2D NormalTexture { get; }
|
||||||
Texture2D MetallicRoughnessTexture { get; }
|
Texture2D MetallicRoughnessTexture { get; }
|
||||||
|
|
||||||
int NumTextureRows { get; }
|
|
||||||
int NumTextureColumns { get; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
|
|
||||||
namespace Kav
|
|
||||||
{
|
|
||||||
public interface ITransformable
|
|
||||||
{
|
|
||||||
Matrix TransformMatrix { get; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
using Kav.Data;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface IUVDrawable
|
||||||
|
{
|
||||||
|
UVData UVData { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
namespace Kav
|
namespace Kav
|
||||||
{
|
{
|
||||||
public class MeshPart : IIndexDrawable, IGBufferDrawable, ICullable, IHasVertexPositions
|
public class MeshPart : IIndexDrawable, IGBufferDrawable, IHasVertexPositions
|
||||||
{
|
{
|
||||||
public IndexBuffer IndexBuffer { get; }
|
public IndexBuffer IndexBuffer { get; }
|
||||||
public VertexBuffer VertexBuffer { get; }
|
public VertexBuffer VertexBuffer { get; }
|
||||||
|
@ -38,9 +38,6 @@ namespace Kav
|
||||||
public float Metallic { get; set; } = 0.5f;
|
public float Metallic { get; set; } = 0.5f;
|
||||||
public float Roughness { get; set; } = 0.5f;
|
public float Roughness { get; set; } = 0.5f;
|
||||||
|
|
||||||
public int NumTextureRows { get; set; } = 1;
|
|
||||||
public int NumTextureColumns { get; set; } = 1;
|
|
||||||
|
|
||||||
public bool DisableAlbedoMap { get; set; } = false;
|
public bool DisableAlbedoMap { get; set; } = false;
|
||||||
public bool DisableNormalMap { get; set; } = false;
|
public bool DisableNormalMap { get; set; } = false;
|
||||||
public bool DisableMetallicRoughnessMap { get; set; } = false;
|
public bool DisableMetallicRoughnessMap { get; set; } = false;
|
||||||
|
|
|
@ -4,7 +4,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
namespace Kav
|
namespace Kav
|
||||||
{
|
{
|
||||||
public class SpriteMesh : ICullable, IIndexDrawable
|
public class MeshSprite : IIndexDrawable
|
||||||
{
|
{
|
||||||
public enum FlipOptions
|
public enum FlipOptions
|
||||||
{
|
{
|
||||||
|
@ -14,6 +14,7 @@ namespace Kav
|
||||||
Both
|
Both
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly int PixelScale = 40;
|
||||||
private static readonly short[] Indices = new short[]
|
private static readonly short[] Indices = new short[]
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
|
@ -24,16 +25,21 @@ namespace Kav
|
||||||
2
|
2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public Texture2D Texture { get; }
|
||||||
|
public Texture2D Normal { get; }
|
||||||
|
|
||||||
public IndexBuffer IndexBuffer { get; }
|
public IndexBuffer IndexBuffer { get; }
|
||||||
public VertexBuffer VertexBuffer { get; }
|
public VertexBuffer VertexBuffer { get; }
|
||||||
public BoundingBox BoundingBox { get; }
|
public BoundingBox BoundingBox { get; }
|
||||||
|
|
||||||
public SpriteMesh(
|
public MeshSprite(
|
||||||
GraphicsDevice graphicsDevice,
|
GraphicsDevice graphicsDevice,
|
||||||
int width,
|
Texture2D texture,
|
||||||
int height,
|
|
||||||
FlipOptions flipOptions
|
FlipOptions flipOptions
|
||||||
) {
|
) {
|
||||||
|
Texture = texture;
|
||||||
|
Normal = null;
|
||||||
|
|
||||||
IndexBuffer = new IndexBuffer(
|
IndexBuffer = new IndexBuffer(
|
||||||
graphicsDevice,
|
graphicsDevice,
|
||||||
IndexElementSize.SixteenBits,
|
IndexElementSize.SixteenBits,
|
||||||
|
@ -42,7 +48,7 @@ namespace Kav
|
||||||
);
|
);
|
||||||
IndexBuffer.SetData(Indices);
|
IndexBuffer.SetData(Indices);
|
||||||
|
|
||||||
var vertexArray = GenerateVertexArray(width, height, flipOptions);
|
var vertexArray = GenerateVertexArray(Texture, flipOptions);
|
||||||
|
|
||||||
VertexBuffer = new VertexBuffer(
|
VertexBuffer = new VertexBuffer(
|
||||||
graphicsDevice,
|
graphicsDevice,
|
||||||
|
@ -55,11 +61,38 @@ namespace Kav
|
||||||
BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray));
|
BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static VertexPositionNormalTexture[] GenerateVertexArray(int pixelWidth, int pixelHeight, FlipOptions flipOptions)
|
public MeshSprite(
|
||||||
{
|
GraphicsDevice graphicsDevice,
|
||||||
var width = pixelWidth / (float)40;
|
Texture2D texture,
|
||||||
var height = pixelHeight / (float)40;
|
Texture2D normal,
|
||||||
|
FlipOptions flipOptions
|
||||||
|
) {
|
||||||
|
Texture = texture;
|
||||||
|
Normal = normal;
|
||||||
|
|
||||||
|
IndexBuffer = new IndexBuffer(
|
||||||
|
graphicsDevice,
|
||||||
|
IndexElementSize.SixteenBits,
|
||||||
|
6,
|
||||||
|
BufferUsage.WriteOnly
|
||||||
|
);
|
||||||
|
IndexBuffer.SetData(Indices);
|
||||||
|
|
||||||
|
var vertexArray = GenerateVertexArray(Texture, flipOptions);
|
||||||
|
|
||||||
|
VertexBuffer = new VertexBuffer(
|
||||||
|
graphicsDevice,
|
||||||
|
typeof(VertexPositionNormalTexture),
|
||||||
|
4,
|
||||||
|
BufferUsage.WriteOnly
|
||||||
|
);
|
||||||
|
VertexBuffer.SetData(vertexArray);
|
||||||
|
|
||||||
|
BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static VertexPositionNormalTexture[] GenerateVertexArray(Texture2D texture, FlipOptions flipOptions)
|
||||||
|
{
|
||||||
VertexPositionNormalTexture[] result = new VertexPositionNormalTexture[4];
|
VertexPositionNormalTexture[] result = new VertexPositionNormalTexture[4];
|
||||||
|
|
||||||
var xLeft = 0;
|
var xLeft = 0;
|
||||||
|
@ -79,20 +112,20 @@ namespace Kav
|
||||||
yBottom = 0;
|
yBottom = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
result[0].Position = new Vector3(-width / 2, height / 2, 0);
|
result[0].Position = new Vector3(-texture.Width / 2, texture.Height / 2, 0) / PixelScale;
|
||||||
result[0].Normal = new Vector3(0, 0, -1);
|
result[0].Normal = new Vector3(0, 0, 1);
|
||||||
result[0].TextureCoordinate = new Vector2(xLeft, yTop);
|
result[0].TextureCoordinate = new Vector2(xLeft, yTop);
|
||||||
|
|
||||||
result[1].Position = new Vector3(width / 2, height / 2, 0);
|
result[1].Position = new Vector3(texture.Width / 2, texture.Height / 2, 0) / PixelScale;
|
||||||
result[1].Normal = new Vector3(0, 0, -1);
|
result[1].Normal = new Vector3(0, 0, 1);
|
||||||
result[1].TextureCoordinate = new Vector2(xRight, yTop);
|
result[1].TextureCoordinate = new Vector2(xRight, yTop);
|
||||||
|
|
||||||
result[2].Position = new Vector3(-width / 2, -height / 2, 0);
|
result[2].Position = new Vector3(-texture.Width / 2, -texture.Height / 2, 0) / PixelScale;
|
||||||
result[2].Normal = new Vector3(0, 0, -1);
|
result[2].Normal = new Vector3(0, 0, 1);
|
||||||
result[2].TextureCoordinate = new Vector2(xLeft, yBottom);
|
result[2].TextureCoordinate = new Vector2(xLeft, yBottom);
|
||||||
|
|
||||||
result[3].Position = new Vector3(width / 2, -height / 2, 0);
|
result[3].Position = new Vector3(texture.Width / 2, -texture.Height / 2, 0) / PixelScale;
|
||||||
result[3].Normal = new Vector3(0, 0, -1);
|
result[3].Normal = new Vector3(0, 0, 1);
|
||||||
result[3].TextureCoordinate = new Vector2(xRight, yBottom);
|
result[3].TextureCoordinate = new Vector2(xRight, yBottom);
|
||||||
|
|
||||||
return result;
|
return result;
|
|
@ -2,7 +2,7 @@ using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
namespace Kav
|
namespace Kav
|
||||||
{
|
{
|
||||||
public class Model : ICullable
|
public class Model
|
||||||
{
|
{
|
||||||
public Mesh[] Meshes { get; }
|
public Mesh[] Meshes { get; }
|
||||||
public BoundingBox BoundingBox { get; }
|
public BoundingBox BoundingBox { get; }
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
<RootNamespace>Kav</RootNamespace>
|
<RootNamespace>Kav</RootNamespace>
|
||||||
<Authors>Evan Hemsley</Authors>
|
<Authors>Evan Hemsley</Authors>
|
||||||
<Copyright>Evan Hemsley 2020</Copyright>
|
<Copyright>Evan Hemsley 2020</Copyright>
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
<RootNamespace>Kav</RootNamespace>
|
<RootNamespace>Kav</RootNamespace>
|
||||||
<Authors>Evan Hemsley</Authors>
|
<Authors>Evan Hemsley</Authors>
|
||||||
<Copyright>Evan Hemsley 2020</Copyright>
|
<Copyright>Evan Hemsley 2020</Copyright>
|
||||||
|
|
|
@ -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; }
|
|
||||||
}
|
|
||||||
}
|
|
150
Renderer.cs
150
Renderer.cs
|
@ -125,7 +125,7 @@ namespace Kav
|
||||||
) {
|
) {
|
||||||
GraphicsDevice.SetRenderTarget(renderTarget);
|
GraphicsDevice.SetRenderTarget(renderTarget);
|
||||||
|
|
||||||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||||
GraphicsDevice.RasterizerState = RasterizerState.CullNone;
|
GraphicsDevice.RasterizerState = RasterizerState.CullNone;
|
||||||
GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
|
GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
|
||||||
GraphicsDevice.SamplerStates[1] = SamplerState.PointClamp;
|
GraphicsDevice.SamplerStates[1] = SamplerState.PointClamp;
|
||||||
|
@ -159,23 +159,17 @@ namespace Kav
|
||||||
|
|
||||||
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
|
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
|
||||||
|
|
||||||
foreach (var data in meshSpriteDrawDatas)
|
foreach (var data in FrustumCull(boundingFrustum, meshSpriteDrawDatas))
|
||||||
{
|
{
|
||||||
var matrix = BillboardTransforms(camera, data.TransformMatrix, data.BillboardConstraint);
|
var matrix = BillboardTransforms(camera, data.TransformMatrix, data.BillboardConstraint);
|
||||||
|
|
||||||
if (FrustumCull(boundingFrustum, data.MeshSprite, matrix))
|
DiffuseLitSpriteEffect.NormalMapEnabled = data.MeshSprite.Normal != null;
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
DiffuseLitSpriteEffect.NormalMapEnabled = data.Normal != null;
|
|
||||||
|
|
||||||
DiffuseLitSpriteEffect.World = matrix;
|
DiffuseLitSpriteEffect.World = matrix;
|
||||||
DiffuseLitSpriteEffect.UVOffset = data.UVOffset.Offset;
|
DiffuseLitSpriteEffect.UVData = data.UVData.ToVector4();
|
||||||
DiffuseLitSpriteEffect.SubTextureDimensions = data.UVOffset.Percentage;
|
|
||||||
|
|
||||||
GraphicsDevice.Textures[0] = data.Texture;
|
GraphicsDevice.Textures[0] = data.MeshSprite.Texture;
|
||||||
GraphicsDevice.Textures[1] = data.Normal;
|
GraphicsDevice.Textures[1] = data.MeshSprite.Normal;
|
||||||
|
|
||||||
GraphicsDevice.SetVertexBuffer(data.MeshSprite.VertexBuffer);
|
GraphicsDevice.SetVertexBuffer(data.MeshSprite.VertexBuffer);
|
||||||
GraphicsDevice.Indices = data.MeshSprite.IndexBuffer;
|
GraphicsDevice.Indices = data.MeshSprite.IndexBuffer;
|
||||||
|
@ -196,51 +190,6 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RenderMeshSpriteGBuffer(
|
|
||||||
RenderTargetBinding[] gBuffer,
|
|
||||||
PerspectiveCamera camera,
|
|
||||||
IEnumerable<MeshSpriteDrawData> meshSpriteDrawDatas,
|
|
||||||
DepthStencilState depthStencilState
|
|
||||||
) {
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
var matrix = BillboardTransforms(camera, data.TransformMatrix, data.BillboardConstraint);
|
|
||||||
|
|
||||||
if (FrustumCull(boundingFrustum, data.MeshSprite, matrix))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
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(
|
private static Matrix BillboardTransforms(
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
Matrix transform,
|
Matrix transform,
|
||||||
|
@ -277,13 +226,13 @@ namespace Kav
|
||||||
public static void CullAndRenderIndexed<T, U>(
|
public static void CullAndRenderIndexed<T, U>(
|
||||||
GraphicsDevice graphicsDevice,
|
GraphicsDevice graphicsDevice,
|
||||||
BoundingFrustum boundingFrustum,
|
BoundingFrustum boundingFrustum,
|
||||||
IEnumerable<(T, Matrix)> drawableTransformPairs,
|
IEnumerable<T> drawables,
|
||||||
U effect
|
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))
|
foreach (var drawable in FrustumCull(boundingFrustum, drawables))
|
||||||
{
|
{
|
||||||
effect.World = transform;
|
effect.World = drawable.TransformMatrix;
|
||||||
|
|
||||||
RenderIndexed(
|
RenderIndexed(
|
||||||
graphicsDevice,
|
graphicsDevice,
|
||||||
|
@ -361,7 +310,7 @@ namespace Kav
|
||||||
public void RenderDepthIndexed<T>(
|
public void RenderDepthIndexed<T>(
|
||||||
RenderTarget2D renderTarget,
|
RenderTarget2D renderTarget,
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
IEnumerable<(T, Matrix)> drawableTransforms
|
IEnumerable<T> drawables
|
||||||
) where T : ICullable, IIndexDrawable
|
) where T : ICullable, IIndexDrawable
|
||||||
{
|
{
|
||||||
GraphicsDevice.SetRenderTarget(renderTarget);
|
GraphicsDevice.SetRenderTarget(renderTarget);
|
||||||
|
@ -373,26 +322,11 @@ namespace Kav
|
||||||
CullAndRenderIndexed(
|
CullAndRenderIndexed(
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
new BoundingFrustum(camera.View * camera.Projection),
|
new BoundingFrustum(camera.View * camera.Projection),
|
||||||
drawableTransforms,
|
drawables,
|
||||||
SimpleDepthEffect
|
SimpleDepthEffect
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
public void RenderSkybox(
|
||||||
RenderTarget2D renderTarget,
|
RenderTarget2D renderTarget,
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
|
@ -436,15 +370,11 @@ namespace Kav
|
||||||
GraphicsDevice.BlendState = BlendState.Opaque;
|
GraphicsDevice.BlendState = BlendState.Opaque;
|
||||||
|
|
||||||
Deferred_GBufferEffect.HardwareInstancingEnabled = true;
|
Deferred_GBufferEffect.HardwareInstancingEnabled = true;
|
||||||
Deferred_GBufferEffect.IsSprite = false;
|
|
||||||
|
|
||||||
Deferred_GBufferEffect.Albedo = drawable.Albedo;
|
Deferred_GBufferEffect.Albedo = drawable.Albedo;
|
||||||
Deferred_GBufferEffect.Metallic = drawable.Metallic;
|
Deferred_GBufferEffect.Metallic = drawable.Metallic;
|
||||||
Deferred_GBufferEffect.Roughness = drawable.Roughness;
|
Deferred_GBufferEffect.Roughness = drawable.Roughness;
|
||||||
|
|
||||||
Deferred_GBufferEffect.NumTextureRows = drawable.NumTextureRows;
|
|
||||||
Deferred_GBufferEffect.NumTextureColumns = drawable.NumTextureColumns;
|
|
||||||
|
|
||||||
Deferred_GBufferEffect.AlbedoTexture = drawable.AlbedoTexture;
|
Deferred_GBufferEffect.AlbedoTexture = drawable.AlbedoTexture;
|
||||||
Deferred_GBufferEffect.NormalTexture = drawable.NormalTexture;
|
Deferred_GBufferEffect.NormalTexture = drawable.NormalTexture;
|
||||||
Deferred_GBufferEffect.MetallicRoughnessTexture = drawable.MetallicRoughnessTexture;
|
Deferred_GBufferEffect.MetallicRoughnessTexture = drawable.MetallicRoughnessTexture;
|
||||||
|
@ -478,22 +408,21 @@ namespace Kav
|
||||||
public void RenderGBufferIndexed<T>(
|
public void RenderGBufferIndexed<T>(
|
||||||
RenderTargetBinding[] gBuffer,
|
RenderTargetBinding[] gBuffer,
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
IEnumerable<(T, Matrix)> drawableTransforms
|
IEnumerable<T> drawables
|
||||||
) where T : ICullable, IIndexDrawable, IGBufferDrawable {
|
) where T : ICullable, IIndexDrawable, IUVDrawable, IGBufferDrawable {
|
||||||
GraphicsDevice.SetRenderTargets(gBuffer);
|
GraphicsDevice.SetRenderTargets(gBuffer);
|
||||||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||||
GraphicsDevice.BlendState = BlendState.Opaque;
|
GraphicsDevice.BlendState = BlendState.Opaque;
|
||||||
|
|
||||||
Deferred_GBufferEffect.IsSprite = false;
|
|
||||||
Deferred_GBufferEffect.HardwareInstancingEnabled = false;
|
Deferred_GBufferEffect.HardwareInstancingEnabled = false;
|
||||||
Deferred_GBufferEffect.View = camera.View;
|
Deferred_GBufferEffect.View = camera.View;
|
||||||
Deferred_GBufferEffect.Projection = camera.Projection;
|
Deferred_GBufferEffect.Projection = camera.Projection;
|
||||||
|
|
||||||
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
|
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
|
||||||
|
|
||||||
foreach (var (drawable, transform) in FrustumCull(boundingFrustum, drawableTransforms))
|
foreach (var drawable in FrustumCull(boundingFrustum, drawables))
|
||||||
{
|
{
|
||||||
Deferred_GBufferEffect.World = transform;
|
Deferred_GBufferEffect.World = drawable.TransformMatrix;
|
||||||
|
|
||||||
Deferred_GBufferEffect.HardwareInstancingEnabled = false;
|
Deferred_GBufferEffect.HardwareInstancingEnabled = false;
|
||||||
|
|
||||||
|
@ -501,6 +430,8 @@ namespace Kav
|
||||||
Deferred_GBufferEffect.Metallic = drawable.Metallic;
|
Deferred_GBufferEffect.Metallic = drawable.Metallic;
|
||||||
Deferred_GBufferEffect.Roughness = drawable.Roughness;
|
Deferred_GBufferEffect.Roughness = drawable.Roughness;
|
||||||
|
|
||||||
|
Deferred_GBufferEffect.UVData = drawable.UVData.ToVector4();
|
||||||
|
|
||||||
Deferred_GBufferEffect.AlbedoTexture = drawable.AlbedoTexture;
|
Deferred_GBufferEffect.AlbedoTexture = drawable.AlbedoTexture;
|
||||||
Deferred_GBufferEffect.NormalTexture = drawable.NormalTexture;
|
Deferred_GBufferEffect.NormalTexture = drawable.NormalTexture;
|
||||||
Deferred_GBufferEffect.MetallicRoughnessTexture = drawable.MetallicRoughnessTexture;
|
Deferred_GBufferEffect.MetallicRoughnessTexture = drawable.MetallicRoughnessTexture;
|
||||||
|
@ -746,7 +677,7 @@ namespace Kav
|
||||||
|
|
||||||
public void RenderDirectionalShadowsIndexed<T>(
|
public void RenderDirectionalShadowsIndexed<T>(
|
||||||
DirectionalShadowMapData shadowMapData,
|
DirectionalShadowMapData shadowMapData,
|
||||||
IEnumerable<(T, Matrix)> drawableTransforms
|
IEnumerable<T> drawableTransforms
|
||||||
) where T : ICullable, IIndexDrawable {
|
) where T : ICullable, IIndexDrawable {
|
||||||
// render the individual shadow cascades
|
// render the individual shadow cascades
|
||||||
for (var i = 0; i < shadowMapData.NumShadowCascades; i++)
|
for (var i = 0; i < shadowMapData.NumShadowCascades; i++)
|
||||||
|
@ -762,7 +693,7 @@ namespace Kav
|
||||||
private void RenderDirectionalShadowMapIndexed<T>(
|
private void RenderDirectionalShadowMapIndexed<T>(
|
||||||
DirectionalShadowMapData shadowMapData,
|
DirectionalShadowMapData shadowMapData,
|
||||||
int shadowCascadeIndex,
|
int shadowCascadeIndex,
|
||||||
IEnumerable<(T, Matrix)> drawableTransforms
|
IEnumerable<T> drawables
|
||||||
) where T : ICullable, IIndexDrawable {
|
) where T : ICullable, IIndexDrawable {
|
||||||
GraphicsDevice.SetRenderTarget(shadowMapData.ShadowMaps[shadowCascadeIndex]);
|
GraphicsDevice.SetRenderTarget(shadowMapData.ShadowMaps[shadowCascadeIndex]);
|
||||||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||||
|
@ -774,7 +705,7 @@ namespace Kav
|
||||||
CullAndRenderIndexed(
|
CullAndRenderIndexed(
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
new BoundingFrustum(SimpleDepthEffect.View * SimpleDepthEffect.Projection),
|
new BoundingFrustum(SimpleDepthEffect.View * SimpleDepthEffect.Projection),
|
||||||
drawableTransforms,
|
drawables,
|
||||||
SimpleDepthEffect
|
SimpleDepthEffect
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -825,7 +756,7 @@ namespace Kav
|
||||||
|
|
||||||
public void RenderPointShadowMapIndexed<T>(
|
public void RenderPointShadowMapIndexed<T>(
|
||||||
RenderTargetCube pointShadowCubeMap,
|
RenderTargetCube pointShadowCubeMap,
|
||||||
IEnumerable<(T, Matrix)> modelTransforms,
|
IEnumerable<T> drawables,
|
||||||
PointLight pointLight
|
PointLight pointLight
|
||||||
) where T : ICullable, IIndexDrawable {
|
) where T : ICullable, IIndexDrawable {
|
||||||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||||
|
@ -893,7 +824,7 @@ namespace Kav
|
||||||
CullAndRenderIndexed(
|
CullAndRenderIndexed(
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
new BoundingFrustum(LinearDepthEffect.View * LinearDepthEffect.Projection),
|
new BoundingFrustum(LinearDepthEffect.View * LinearDepthEffect.Projection),
|
||||||
modelTransforms,
|
drawables,
|
||||||
LinearDepthEffect
|
LinearDepthEffect
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -905,7 +836,7 @@ namespace Kav
|
||||||
VertexBuffer instanceVertexBuffer,
|
VertexBuffer instanceVertexBuffer,
|
||||||
int numInstances,
|
int numInstances,
|
||||||
PointLight pointLight
|
PointLight pointLight
|
||||||
) where T : ICullable, IIndexDrawable
|
) where T : IIndexDrawable
|
||||||
{
|
{
|
||||||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||||
GraphicsDevice.BlendState = BlendState.Opaque;
|
GraphicsDevice.BlendState = BlendState.Opaque;
|
||||||
|
@ -979,42 +910,17 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<(T, Matrix)> FrustumCull<T>(
|
|
||||||
BoundingFrustum boundingFrustum,
|
|
||||||
IEnumerable<(T, Matrix)> cullableTransforms
|
|
||||||
) where T : ICullable {
|
|
||||||
foreach (var (cullable, transform) in cullableTransforms)
|
|
||||||
{
|
|
||||||
var boundingBox = TransformedBoundingBox(cullable.BoundingBox, transform);
|
|
||||||
var containment = boundingFrustum.Contains(boundingBox);
|
|
||||||
if (containment != ContainmentType.Disjoint)
|
|
||||||
{
|
|
||||||
yield return (cullable, transform);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool 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>(
|
private static IEnumerable<T> FrustumCull<T>(
|
||||||
BoundingFrustum boundingFrustum,
|
BoundingFrustum boundingFrustum,
|
||||||
IEnumerable<T> cullableTransformables
|
IEnumerable<T> cullables
|
||||||
) where T : ICullable, ITransformable {
|
) where T : ICullable {
|
||||||
foreach (var cullableTransformable in cullableTransformables)
|
foreach (var cullable in cullables)
|
||||||
{
|
{
|
||||||
var boundingBox = TransformedBoundingBox(cullableTransformable.BoundingBox, cullableTransformable.TransformMatrix);
|
var boundingBox = TransformedBoundingBox(cullable.BoundingBox, cullable.TransformMatrix);
|
||||||
var containment = boundingFrustum.Contains(boundingBox);
|
var containment = boundingFrustum.Contains(boundingBox);
|
||||||
if (containment != ContainmentType.Disjoint)
|
if (containment != ContainmentType.Disjoint)
|
||||||
{
|
{
|
||||||
yield return cullableTransformable;
|
yield return cullable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Kav
|
||||||
public static VertexDeclaration PositionTextureOffsetInstanceDeclaration = new VertexDeclaration
|
public static VertexDeclaration PositionTextureOffsetInstanceDeclaration = new VertexDeclaration
|
||||||
(
|
(
|
||||||
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 2),
|
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 2),
|
||||||
new VertexElement(12, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 5)
|
new VertexElement(12, VertexElementFormat.Vector4, VertexElementUsage.Tangent, 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,16 +16,16 @@ namespace Kav
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 Translation { get; set; }
|
public Vector3 Translation { get; set; }
|
||||||
public Vector2 UVOffset { get; set; }
|
public Vector4 UVData { get; set; }
|
||||||
|
|
||||||
public static readonly VertexDeclaration VertexDeclaration;
|
public static readonly VertexDeclaration VertexDeclaration;
|
||||||
|
|
||||||
public PositionTextureOffsetInstanceVertex(
|
public PositionTextureOffsetInstanceVertex(
|
||||||
Vector3 translation,
|
Vector3 translation,
|
||||||
Vector2 uvOffset
|
Vector4 uvData
|
||||||
) {
|
) {
|
||||||
Translation = translation;
|
Translation = translation;
|
||||||
UVOffset = uvOffset;
|
UVData = uvData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue