Compare commits
No commits in common. "main" and "instancing" have entirely different histories.
main
...
instancing
|
@ -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,12 +16,6 @@ namespace Kav
|
|||
EffectParameter metallicParam;
|
||||
EffectParameter roughnessParam;
|
||||
|
||||
EffectParameter uvOffsetAndDimensionsParam;
|
||||
EffectParameter isSpriteParam;
|
||||
|
||||
EffectParameter numTextureRowsParam;
|
||||
EffectParameter numTextureColumnsParam;
|
||||
|
||||
EffectParameter vertexShaderIndexParam;
|
||||
EffectParameter shaderIndexParam;
|
||||
|
||||
|
@ -33,14 +27,6 @@ namespace Kav
|
|||
float metallic;
|
||||
float roughness;
|
||||
|
||||
Vector2 uvOffset;
|
||||
Vector2 subTextureDimensions;
|
||||
|
||||
bool isSprite = false;
|
||||
|
||||
int numTextureRows = 1;
|
||||
int numTextureColumns = 1;
|
||||
|
||||
bool albedoTextureEnabled = false;
|
||||
bool metallicRoughnessMapEnabled = false;
|
||||
bool normalMapEnabled = false;
|
||||
|
@ -141,56 +127,6 @@ namespace Kav
|
|||
}
|
||||
}
|
||||
|
||||
public int NumTextureRows
|
||||
{
|
||||
get { return numTextureRows; }
|
||||
set
|
||||
{
|
||||
numTextureRows = value;
|
||||
numTextureRowsParam.SetValue(numTextureRows);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
get { return hardwareInstancingEnabled; }
|
||||
|
@ -248,16 +184,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;
|
||||
|
@ -322,12 +248,6 @@ namespace Kav
|
|||
metallicParam = Parameters["MetallicValue"];
|
||||
roughnessParam = Parameters["RoughnessValue"];
|
||||
|
||||
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();
|
||||
|
@ -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/LinearDepthEffectInstanced.fxb (Stored with Git LFS)
BIN
Effects/FXB/LinearDepthEffectInstanced.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.
BIN
Effects/FXB/SimpleDepthEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/SimpleDepthEffect.fxb (Stored with Git LFS)
Binary file not shown.
|
@ -4,18 +4,12 @@ DECLARE_TEXTURE(AlbedoTexture, 0);
|
|||
DECLARE_TEXTURE(NormalTexture, 1);
|
||||
DECLARE_TEXTURE(MetallicRoughnessTexture, 2);
|
||||
|
||||
float4 UVOffsetAndDimensions;
|
||||
float IsSprite;
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
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);
|
||||
|
@ -54,11 +48,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);
|
||||
|
@ -66,11 +56,8 @@ PixelInput main_vs(VertexInput input)
|
|||
return output;
|
||||
}
|
||||
|
||||
PixelInput instanced_vs(
|
||||
VertexInput input,
|
||||
float3 Translation : TEXCOORD2,
|
||||
float2 UVOffset : TEXCOORD5
|
||||
) {
|
||||
PixelInput instanced_vs(VertexInput input, float3 Translation : TEXCOORD2)
|
||||
{
|
||||
PixelInput output;
|
||||
|
||||
float4x4 world = float4x4(
|
||||
|
@ -78,17 +65,13 @@ PixelInput instanced_vs(
|
|||
float4(0, 1, 0, 0),
|
||||
float4(0, 0, 1, 0),
|
||||
float4(Translation.x, Translation.y, Translation.z, 1)
|
||||
);
|
||||
);
|
||||
|
||||
float4x4 worldViewProjection = mul(world, ViewProjection);
|
||||
|
||||
output.PositionWorld = mul(input.Position, world);
|
||||
output.NormalWorld = mul(input.Normal, world);
|
||||
|
||||
float2 texCoord;
|
||||
texCoord.x = (input.TexCoord.x / NumTextureColumns + UVOffset.x);
|
||||
texCoord.y = (input.TexCoord.y / NumTextureRows + UVOffset.y);
|
||||
output.TexCoord = texCoord;
|
||||
output.TexCoord = input.TexCoord;
|
||||
|
||||
output.Position = mul(input.Position, worldViewProjection);
|
||||
|
||||
|
@ -120,7 +103,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 +115,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 +127,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 +139,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 +151,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 +163,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 +175,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 +187,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,5 +1,3 @@
|
|||
// Assumes you are drawing a sphere!!
|
||||
|
||||
#include "Macros.fxh" //from FNA
|
||||
#include "Lighting.fxh"
|
||||
#include "Shadow.fxh"
|
||||
|
@ -21,27 +19,26 @@ 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,55 +0,0 @@
|
|||
#include "Macros.fxh"
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
float4x4 ViewProjection _vs(c4) _cb(c4);
|
||||
|
||||
float3 LightPosition _ps(c0) _cb(c8);
|
||||
float FarPlane _ps(c1) _cb(c9);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
};
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float3 PositionWorld : TEXCOORD0;
|
||||
};
|
||||
|
||||
VertexShaderOutput instanced_vs(VertexShaderInput input, float3 Translation : TEXCOORD2)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
|
||||
float4x4 world = float4x4(
|
||||
float4(1, 0, 0, 0),
|
||||
float4(0, 1, 0, 0),
|
||||
float4(0, 0, 1, 0),
|
||||
float4(Translation.x, Translation.y, Translation.z, 1)
|
||||
);
|
||||
|
||||
float4x4 worldViewProjection = mul(world, ViewProjection);
|
||||
output.Position = mul(input.Position, worldViewProjection);
|
||||
output.Position.x *= -1; // otherwise cube map render will be horizontally flipped
|
||||
output.PositionWorld = mul(input.Position, world);
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 main_ps(VertexShaderOutput input) : SV_TARGET0
|
||||
{
|
||||
float lightDistance = length(input.PositionWorld - LightPosition);
|
||||
lightDistance /= FarPlane;
|
||||
return float4(lightDistance, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
Technique SimpleDepth
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 instanced_vs();
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
#include "Macros.fxh"
|
||||
|
||||
DECLARE_TEXTURE(Texture, 0);
|
||||
DECLARE_TEXTURE(Palette, 1);
|
||||
|
||||
BEGIN_CONSTANTS
|
||||
|
||||
int PaletteWidth _ps(c0) _cb(c0);
|
||||
|
||||
END_CONSTANTS
|
||||
|
||||
struct VertexInput
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
float2 TexCoord : TEXCOORD;
|
||||
};
|
||||
|
||||
struct PixelInput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
PixelInput main_vs(VertexInput input)
|
||||
{
|
||||
PixelInput output;
|
||||
|
||||
output.Position = input.Position;
|
||||
output.TexCoord = input.TexCoord;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 main_ps(PixelInput input) : SV_TARGET0
|
||||
{
|
||||
float4 sampled = SAMPLE_TEXTURE(Texture, input.TexCoord);
|
||||
|
||||
float3 sampled_color = sampled.rgb;
|
||||
|
||||
float3 closest_color = float3(0, 0, 0);
|
||||
float closest_dist = 100000;
|
||||
|
||||
for (int i = 0; i < PaletteWidth; i++)
|
||||
{
|
||||
float texX = (i / (float)PaletteWidth);
|
||||
float3 palette_color = SAMPLE_TEXTURE(Palette, float2(texX, 0));
|
||||
float dist = distance(palette_color, sampled_color);
|
||||
if (dist < closest_dist)
|
||||
{
|
||||
closest_dist = dist;
|
||||
closest_color = palette_color;
|
||||
}
|
||||
}
|
||||
|
||||
return float4(closest_color, sampled.a);
|
||||
}
|
||||
|
||||
Technique PaletteCrush
|
||||
{
|
||||
Pass
|
||||
{
|
||||
VertexShader = compile vs_3_0 main_vs();
|
||||
PixelShader = compile ps_3_0 main_ps();
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ struct VertexShaderInput
|
|||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float Depth : TEXCOORD0;
|
||||
float Depth : DEPTH;
|
||||
};
|
||||
|
||||
VertexShaderOutput main_vs(VertexShaderInput input)
|
||||
|
|
|
@ -20,7 +20,7 @@ VertexShaderOutput instanced_vs(VertexShaderInput input, float3 Translation : TE
|
|||
float4(0, 1, 0, 0),
|
||||
float4(0, 0, 1, 0),
|
||||
float4(Translation.x, Translation.y, Translation.z, 1)
|
||||
);
|
||||
);
|
||||
|
||||
float4x4 worldViewProjection = mul(world, ViewProjection);
|
||||
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class LinearDepthEffectInstanced : Effect
|
||||
{
|
||||
EffectParameter viewProjectionParam;
|
||||
EffectParameter lightPositionParam;
|
||||
EffectParameter farPlaneParam;
|
||||
|
||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||
|
||||
Matrix view;
|
||||
Matrix projection;
|
||||
|
||||
public Vector3 LightPosition { get; set; }
|
||||
public float FarPlane { get; set; }
|
||||
|
||||
public Matrix View
|
||||
{
|
||||
get { return view; }
|
||||
set
|
||||
{
|
||||
view = value;
|
||||
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix Projection
|
||||
{
|
||||
get { return projection; }
|
||||
set
|
||||
{
|
||||
projection = value;
|
||||
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||
}
|
||||
}
|
||||
|
||||
public LinearDepthEffectInstanced(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.LinearDepthEffectInstanced)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
if ((dirtyFlags & EffectDirtyFlags.ViewProj) != 0)
|
||||
{
|
||||
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
||||
viewProjectionParam.SetValue(viewProjection);
|
||||
|
||||
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
||||
}
|
||||
|
||||
lightPositionParam.SetValue(LightPosition);
|
||||
farPlaneParam.SetValue(FarPlane);
|
||||
}
|
||||
|
||||
private void CacheEffectParameters()
|
||||
{
|
||||
viewProjectionParam = Parameters["ViewProjection"];
|
||||
|
||||
lightPositionParam = Parameters["LightPosition"];
|
||||
farPlaneParam = Parameters["FarPlane"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class PaletteCrushEffect : Effect
|
||||
{
|
||||
EffectParameter textureParam;
|
||||
EffectParameter paletteParam;
|
||||
EffectParameter paletteWidthParam;
|
||||
|
||||
Texture2D texture;
|
||||
Texture2D palette;
|
||||
|
||||
int paletteWidth;
|
||||
|
||||
public Texture2D Texture
|
||||
{
|
||||
get { return texture; }
|
||||
set
|
||||
{
|
||||
texture = value;
|
||||
textureParam.SetValue(texture);
|
||||
}
|
||||
}
|
||||
|
||||
public Texture2D Palette
|
||||
{
|
||||
get { return palette; }
|
||||
set
|
||||
{
|
||||
palette = value;
|
||||
paletteWidth = palette.Width;
|
||||
paletteParam.SetValue(palette);
|
||||
paletteWidthParam.SetValue(paletteWidth);
|
||||
}
|
||||
}
|
||||
|
||||
public PaletteCrushEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.PaletteCrushEffect)
|
||||
{
|
||||
CacheEffectParameters();
|
||||
}
|
||||
|
||||
void CacheEffectParameters()
|
||||
{
|
||||
textureParam = Parameters["Texture"];
|
||||
paletteParam = Parameters["Palette"];
|
||||
|
||||
paletteWidthParam = Parameters["PaletteWidth"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -12,8 +12,5 @@ namespace Kav
|
|||
Texture2D AlbedoTexture { get; }
|
||||
Texture2D NormalTexture { 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; }
|
||||
}
|
||||
}
|
|
@ -38,9 +38,6 @@ namespace Kav
|
|||
public float Metallic { 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 DisableNormalMap { get; set; } = false;
|
||||
public bool DisableMetallicRoughnessMap { get; set; } = false;
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
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 SpriteBillboardConstraint BillboardConstraint { get; }
|
||||
|
||||
public IndexBuffer IndexBuffer { get; }
|
||||
public VertexBuffer VertexBuffer { get; }
|
||||
public BoundingBox BoundingBox { get; }
|
||||
|
||||
public MeshSprite(
|
||||
GraphicsDevice graphicsDevice,
|
||||
Texture2D texture,
|
||||
SpriteBillboardConstraint billboardConstraint
|
||||
) {
|
||||
Texture = texture;
|
||||
Normal = null;
|
||||
BillboardConstraint = billboardConstraint;
|
||||
|
||||
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,
|
||||
SpriteBillboardConstraint billboardConstraint
|
||||
) {
|
||||
Texture = texture;
|
||||
Normal = normal;
|
||||
BillboardConstraint = billboardConstraint;
|
||||
|
||||
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>
|
||||
|
@ -50,24 +49,15 @@
|
|||
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
||||
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\LinearDepthEffectInstanced.fxb">
|
||||
<LogicalName>Kav.Resources.LinearDepthEffectInstanced.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
||||
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DiffuseLitSpriteEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DiffuseLitSpriteEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\PaletteCrushEffect.fxb">
|
||||
<LogicalName>Kav.Resources.PaletteCrushEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<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,14 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<RootNamespace>Kav</RootNamespace>
|
||||
<Authors>Evan Hemsley</Authors>
|
||||
<Copyright>Evan Hemsley 2020</Copyright>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<AssemblyName>Kav</AssemblyName>
|
||||
<Platforms>x64;x86</Platforms>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -50,24 +49,15 @@
|
|||
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
||||
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\LinearDepthEffectInstanced.fxb">
|
||||
<LogicalName>Kav.Resources.LinearDepthEffectInstanced.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
||||
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\DiffuseLitSpriteEffect.fxb">
|
||||
<LogicalName>Kav.Resources.DiffuseLitSpriteEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Effects\FXB\PaletteCrushEffect.fxb">
|
||||
<LogicalName>Kav.Resources.PaletteCrushEffect.fxb</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<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.
343
Renderer.cs
343
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;
|
||||
|
||||
|
@ -9,6 +8,8 @@ namespace Kav
|
|||
{
|
||||
public class Renderer
|
||||
{
|
||||
private const int MAX_INSTANCE_VERTEX_COUNT = 1000000;
|
||||
|
||||
private GraphicsDevice GraphicsDevice { get; }
|
||||
|
||||
private VertexBuffer FullscreenTriangle { get; }
|
||||
|
@ -23,13 +24,14 @@ namespace Kav
|
|||
private SimpleDepthEffect SimpleDepthEffect { get; }
|
||||
private SimpleDepthEffectInstanced SimpleDepthEffectInstanced { get; }
|
||||
private LinearDepthEffect LinearDepthEffect { get; }
|
||||
private LinearDepthEffectInstanced LinearDepthEffectInstanced { get; }
|
||||
private Effect ToneMapEffect { get; }
|
||||
private SkyboxEffect SkyboxEffect { get; }
|
||||
private DiffuseLitSpriteEffect DiffuseLitSpriteEffect { get; }
|
||||
|
||||
private Kav.Model UnitCube { get; }
|
||||
private Kav.Model UnitSphere { get; }
|
||||
|
||||
private DynamicVertexBuffer PositionInstanceVertexBuffer { get; }
|
||||
private readonly PositionInstanceVertex[] PositionInstanceVertices = new PositionInstanceVertex[MAX_INSTANCE_VERTEX_COUNT];
|
||||
|
||||
public Renderer(
|
||||
GraphicsDevice graphicsDevice
|
||||
|
@ -39,8 +41,6 @@ namespace Kav
|
|||
SimpleDepthEffect = new SimpleDepthEffect(GraphicsDevice);
|
||||
SimpleDepthEffectInstanced = new SimpleDepthEffectInstanced(GraphicsDevice);
|
||||
LinearDepthEffect = new LinearDepthEffect(GraphicsDevice);
|
||||
LinearDepthEffectInstanced = new LinearDepthEffectInstanced(GraphicsDevice);
|
||||
|
||||
DeferredPBREffect = new DeferredPBREffect(GraphicsDevice);
|
||||
|
||||
Deferred_GBufferEffect = new DeferredPBR_GBufferEffect(GraphicsDevice);
|
||||
|
@ -64,26 +64,12 @@ namespace Kav
|
|||
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>(
|
||||
GraphicsDevice graphicsDevice,
|
||||
int instanceVertexCount
|
||||
) where T : IVertexType {
|
||||
var positionData = new T[instanceVertexCount];
|
||||
|
||||
var vertexBuffer = new DynamicVertexBuffer(
|
||||
graphicsDevice,
|
||||
typeof(T),
|
||||
instanceVertexCount,
|
||||
PositionInstanceVertexBuffer = new DynamicVertexBuffer(
|
||||
GraphicsDevice,
|
||||
VertexDeclarations.PositionInstanceDeclaration,
|
||||
MAX_INSTANCE_VERTEX_COUNT,
|
||||
BufferUsage.WriteOnly
|
||||
);
|
||||
|
||||
return (positionData, vertexBuffer);
|
||||
}
|
||||
|
||||
public static RenderTargetCube CreateShadowCubeMap(
|
||||
|
@ -118,14 +104,14 @@ namespace Kav
|
|||
public void MeshSpriteRender(
|
||||
RenderTarget2D renderTarget,
|
||||
PerspectiveCamera camera,
|
||||
IEnumerable<MeshSpriteDrawData> meshSpriteDrawDatas,
|
||||
IEnumerable<(MeshSprite, Matrix)> meshSpriteTransforms,
|
||||
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 +145,40 @@ namespace Kav
|
|||
|
||||
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
|
||||
|
||||
foreach (var data in meshSpriteDrawDatas)
|
||||
foreach (var (sprite, transform) in FrustumCull(boundingFrustum, meshSpriteTransforms))
|
||||
{
|
||||
var matrix = BillboardTransforms(camera, data.TransformMatrix, data.BillboardConstraint);
|
||||
DiffuseLitSpriteEffect.NormalMapEnabled = sprite.Normal != null;
|
||||
|
||||
if (FrustumCull(boundingFrustum, data.MeshSprite, matrix))
|
||||
if (sprite.BillboardConstraint == SpriteBillboardConstraint.None)
|
||||
{
|
||||
continue;
|
||||
DiffuseLitSpriteEffect.World = transform;
|
||||
}
|
||||
else if (sprite.BillboardConstraint == SpriteBillboardConstraint.Horizontal)
|
||||
{
|
||||
DiffuseLitSpriteEffect.World = Matrix.CreateConstrainedBillboard(
|
||||
transform.Translation,
|
||||
camera.Position,
|
||||
Vector3.Up,
|
||||
camera.Forward,
|
||||
camera.Position - transform.Translation
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
DiffuseLitSpriteEffect.World = Matrix.CreateConstrainedBillboard(
|
||||
transform.Translation,
|
||||
camera.Position,
|
||||
Vector3.Up,
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
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 +188,7 @@ namespace Kav
|
|||
PrimitiveType.TriangleList,
|
||||
0,
|
||||
0,
|
||||
data.MeshSprite.VertexBuffer.VertexCount,
|
||||
sprite.VertexBuffer.VertexCount,
|
||||
0,
|
||||
2
|
||||
);
|
||||
|
@ -196,82 +196,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(
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Renders a series of drawable-transform pairs using an effect that has a World matrix.
|
||||
// Effect must be pre-configured!!
|
||||
public static void CullAndRenderIndexed<T, U>(
|
||||
|
@ -317,19 +241,47 @@ namespace Kav
|
|||
}
|
||||
}
|
||||
|
||||
public static void RenderInstanced<T>(
|
||||
public static int FillAndSetBuffersForInstancing<T, V>(
|
||||
GraphicsDevice graphicsDevice,
|
||||
BoundingFrustum boundingFrustum,
|
||||
T drawable,
|
||||
VertexBuffer instanceVertexBuffer,
|
||||
int numInstances,
|
||||
Effect effect
|
||||
) where T : IIndexDrawable {
|
||||
IEnumerable<Matrix> transforms,
|
||||
V[] vertexData,
|
||||
DynamicVertexBuffer dynamicVertexBuffer
|
||||
) where T : ICullable, IIndexDrawable where V : struct, IVertexType, IHasTranslation
|
||||
{
|
||||
int numInstances = 0;
|
||||
foreach (var transform in FrustumCull(boundingFrustum, drawable, transforms))
|
||||
{
|
||||
vertexData[numInstances].Translation = transform.Translation;
|
||||
numInstances += 1;
|
||||
}
|
||||
|
||||
if (numInstances == 0) { return 0; }
|
||||
|
||||
dynamicVertexBuffer.SetData(
|
||||
vertexData,
|
||||
0,
|
||||
numInstances,
|
||||
SetDataOptions.Discard
|
||||
);
|
||||
|
||||
graphicsDevice.SetVertexBuffers(
|
||||
drawable.VertexBuffer,
|
||||
new VertexBufferBinding(instanceVertexBuffer, 0, 1)
|
||||
new VertexBufferBinding(dynamicVertexBuffer, 0, 1)
|
||||
);
|
||||
graphicsDevice.Indices = drawable.IndexBuffer;
|
||||
|
||||
return numInstances;
|
||||
}
|
||||
|
||||
public static void RenderInstanced<T, U>(
|
||||
GraphicsDevice graphicsDevice,
|
||||
T drawable,
|
||||
U effect,
|
||||
int numInstances
|
||||
) where T : ICullable, IIndexDrawable where U : Effect
|
||||
{
|
||||
foreach (var pass in effect.CurrentTechnique.Passes)
|
||||
{
|
||||
pass.Apply();
|
||||
|
@ -378,21 +330,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,
|
||||
|
@ -421,30 +358,24 @@ namespace Kav
|
|||
|
||||
/// <summary>
|
||||
/// GBuffer binding must have 4 render targets.
|
||||
/// Assumes that vertex buffer has been filled.
|
||||
/// </summary>
|
||||
public void RenderGBufferInstanced<T>(
|
||||
RenderTargetBinding[] gBuffer,
|
||||
RenderTarget2D depthBuffer,
|
||||
PerspectiveCamera camera,
|
||||
T drawable,
|
||||
VertexBuffer instanceVertexBuffer,
|
||||
int numInstances
|
||||
) where T : IGBufferDrawable, IIndexDrawable {
|
||||
IEnumerable<Matrix> transforms
|
||||
) where T : ICullable, IIndexDrawable, IGBufferDrawable {
|
||||
GraphicsDevice.SetRenderTargets(gBuffer);
|
||||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||
GraphicsDevice.BlendState = BlendState.Opaque;
|
||||
|
||||
Deferred_GBufferEffect.HardwareInstancingEnabled = true;
|
||||
Deferred_GBufferEffect.IsSprite = false;
|
||||
|
||||
Deferred_GBufferEffect.Albedo = drawable.Albedo;
|
||||
Deferred_GBufferEffect.Metallic = drawable.Metallic;
|
||||
Deferred_GBufferEffect.Roughness = drawable.Roughness;
|
||||
|
||||
Deferred_GBufferEffect.NumTextureRows = drawable.NumTextureRows;
|
||||
Deferred_GBufferEffect.NumTextureColumns = drawable.NumTextureColumns;
|
||||
|
||||
Deferred_GBufferEffect.AlbedoTexture = drawable.AlbedoTexture;
|
||||
Deferred_GBufferEffect.NormalTexture = drawable.NormalTexture;
|
||||
Deferred_GBufferEffect.MetallicRoughnessTexture = drawable.MetallicRoughnessTexture;
|
||||
|
@ -452,12 +383,20 @@ namespace Kav
|
|||
Deferred_GBufferEffect.View = camera.View;
|
||||
Deferred_GBufferEffect.Projection = camera.Projection;
|
||||
|
||||
var numInstances = FillAndSetBuffersForInstancing(
|
||||
GraphicsDevice,
|
||||
new BoundingFrustum(camera.View * camera.Projection),
|
||||
drawable,
|
||||
transforms,
|
||||
PositionInstanceVertices,
|
||||
PositionInstanceVertexBuffer
|
||||
);
|
||||
|
||||
RenderInstanced(
|
||||
GraphicsDevice,
|
||||
drawable,
|
||||
instanceVertexBuffer,
|
||||
numInstances,
|
||||
Deferred_GBufferEffect
|
||||
Deferred_GBufferEffect,
|
||||
numInstances
|
||||
);
|
||||
|
||||
// re-render to get depth
|
||||
|
@ -469,9 +408,8 @@ namespace Kav
|
|||
RenderInstanced(
|
||||
GraphicsDevice,
|
||||
drawable,
|
||||
instanceVertexBuffer,
|
||||
numInstances,
|
||||
SimpleDepthEffectInstanced
|
||||
SimpleDepthEffectInstanced,
|
||||
numInstances
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -484,7 +422,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 +474,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 +487,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 +505,6 @@ namespace Kav
|
|||
DirectionalLight directionalLight
|
||||
) {
|
||||
GraphicsDevice.SetRenderTarget(renderTarget);
|
||||
GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
|
||||
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||
GraphicsDevice.BlendState = BlendState.Additive;
|
||||
|
||||
|
@ -782,9 +707,8 @@ namespace Kav
|
|||
public void RenderDirectionalShadowsInstanced<T>(
|
||||
DirectionalShadowMapData shadowMapData,
|
||||
T drawable,
|
||||
VertexBuffer instanceVertexBuffer,
|
||||
int numInstances
|
||||
) where T : IIndexDrawable
|
||||
IEnumerable<Matrix> transforms
|
||||
) where T : ICullable, IIndexDrawable
|
||||
{
|
||||
// render the individual shadow cascades
|
||||
for (var i = 0; i < shadowMapData.NumShadowCascades; i++)
|
||||
|
@ -793,8 +717,7 @@ namespace Kav
|
|||
shadowMapData,
|
||||
i,
|
||||
drawable,
|
||||
instanceVertexBuffer,
|
||||
numInstances
|
||||
transforms
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -803,9 +726,8 @@ namespace Kav
|
|||
DirectionalShadowMapData shadowMapData,
|
||||
int shadowCascadeIndex,
|
||||
T drawable,
|
||||
VertexBuffer instanceVertexBuffer,
|
||||
int numInstances
|
||||
) where T : IIndexDrawable
|
||||
IEnumerable<Matrix> transforms
|
||||
) where T : ICullable, IIndexDrawable
|
||||
{
|
||||
GraphicsDevice.SetRenderTarget(shadowMapData.ShadowMaps[shadowCascadeIndex]);
|
||||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||
|
@ -814,17 +736,26 @@ namespace Kav
|
|||
SimpleDepthEffectInstanced.View = shadowMapData.LightSpaceViews[shadowCascadeIndex];
|
||||
SimpleDepthEffectInstanced.Projection = shadowMapData.LightSpaceProjections[shadowCascadeIndex];
|
||||
|
||||
var numInstances = FillAndSetBuffersForInstancing(
|
||||
GraphicsDevice,
|
||||
new BoundingFrustum(SimpleDepthEffectInstanced.View * SimpleDepthEffectInstanced.Projection),
|
||||
drawable,
|
||||
transforms,
|
||||
PositionInstanceVertices,
|
||||
PositionInstanceVertexBuffer
|
||||
);
|
||||
|
||||
RenderInstanced(
|
||||
GraphicsDevice,
|
||||
drawable,
|
||||
instanceVertexBuffer,
|
||||
numInstances,
|
||||
SimpleDepthEffectInstanced
|
||||
SimpleDepthEffectInstanced,
|
||||
numInstances
|
||||
);
|
||||
}
|
||||
|
||||
public void RenderPointShadowMapIndexed<T>(
|
||||
RenderTargetCube pointShadowCubeMap,
|
||||
PerspectiveCamera camera,
|
||||
IEnumerable<(T, Matrix)> modelTransforms,
|
||||
PointLight pointLight
|
||||
) where T : ICullable, IIndexDrawable {
|
||||
|
@ -901,9 +832,9 @@ namespace Kav
|
|||
|
||||
public void RenderPointShadowMapInstanced<T>(
|
||||
RenderTargetCube pointShadowCubeMap,
|
||||
PerspectiveCamera camera,
|
||||
T drawable,
|
||||
VertexBuffer instanceVertexBuffer,
|
||||
int numInstances,
|
||||
IEnumerable<Matrix> modelTransforms,
|
||||
PointLight pointLight
|
||||
) where T : ICullable, IIndexDrawable
|
||||
{
|
||||
|
@ -954,28 +885,36 @@ namespace Kav
|
|||
break;
|
||||
}
|
||||
|
||||
LinearDepthEffectInstanced.View = Matrix.CreateLookAt(
|
||||
LinearDepthEffect.View = Matrix.CreateLookAt(
|
||||
pointLight.Position,
|
||||
pointLight.Position + targetDirection,
|
||||
targetUpDirection
|
||||
);
|
||||
LinearDepthEffectInstanced.Projection = Matrix.CreatePerspectiveFieldOfView(
|
||||
LinearDepthEffect.Projection = Matrix.CreatePerspectiveFieldOfView(
|
||||
MathHelper.PiOver2,
|
||||
1,
|
||||
0.1f,
|
||||
25f // FIXME: magic value
|
||||
);
|
||||
LinearDepthEffect.FarPlane = 25f;
|
||||
|
||||
LinearDepthEffectInstanced.FarPlane = 25f;
|
||||
LinearDepthEffectInstanced.LightPosition = pointLight.Position;
|
||||
LinearDepthEffect.LightPosition = pointLight.Position;
|
||||
|
||||
RenderInstanced(
|
||||
GraphicsDevice,
|
||||
drawable,
|
||||
instanceVertexBuffer,
|
||||
numInstances,
|
||||
LinearDepthEffectInstanced
|
||||
);
|
||||
// TODO: set up instancing
|
||||
// var numInstances = FillAndSetBuffersForInstancing(
|
||||
// GraphicsDevice,
|
||||
// camera,
|
||||
// drawable,
|
||||
// transforms,
|
||||
// VertexPos
|
||||
// );
|
||||
|
||||
// RenderInstanced(
|
||||
// GraphicsDevice,
|
||||
// camera,
|
||||
// modelTransforms,
|
||||
// LinearDepthEffect
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -994,27 +933,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
39
Resources.cs
39
Resources.cs
|
@ -135,18 +135,6 @@ namespace Kav
|
|||
}
|
||||
}
|
||||
|
||||
public static byte[] LinearDepthEffectInstanced
|
||||
{
|
||||
get
|
||||
{
|
||||
if (linearDepthEffectInstanced == null)
|
||||
{
|
||||
linearDepthEffectInstanced = GetResource("LinearDepthEffectInstanced.fxb");
|
||||
}
|
||||
return linearDepthEffectInstanced;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] SkyboxEffect
|
||||
{
|
||||
get
|
||||
|
@ -171,18 +159,6 @@ namespace Kav
|
|||
}
|
||||
}
|
||||
|
||||
public static byte[] PaletteCrushEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
if (paletteCrushEffect == null)
|
||||
{
|
||||
paletteCrushEffect = GetResource("PaletteCrushEffect.fxb");
|
||||
}
|
||||
return paletteCrushEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] UnitCubeModel
|
||||
{
|
||||
get
|
||||
|
@ -195,18 +171,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;
|
||||
|
@ -218,13 +182,10 @@ namespace Kav
|
|||
private static byte[] simpleDepthEffect;
|
||||
private static byte[] simpleDepthEffectInstanced;
|
||||
private static byte[] linearDepthEffect;
|
||||
private static byte[] linearDepthEffectInstanced;
|
||||
private static byte[] skyboxEffect;
|
||||
private static byte[] diffuseLitSpriteEffect;
|
||||
private static byte[] paletteCrushEffect;
|
||||
|
||||
private static byte[] unitCubeModel;
|
||||
private static byte[] unitSphereModel;
|
||||
|
||||
private static byte[] GetResource(string name)
|
||||
{
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Kav.Utils
|
||||
{
|
||||
public static class QuaternionUtils
|
||||
{
|
||||
// assumes that the input vectors are normalized and orthogonal
|
||||
public static Quaternion LookAt(in Vector3 forward, in Vector3 up)
|
||||
{
|
||||
Matrix orientation = Matrix.Identity;
|
||||
orientation.Forward = forward;
|
||||
orientation.Right = Vector3.Normalize(Vector3.Cross(forward, up));
|
||||
orientation.Up = Vector3.Cross(orientation.Right, forward);
|
||||
|
||||
return Quaternion.CreateFromRotationMatrix(orientation);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,11 +8,5 @@ namespace Kav
|
|||
(
|
||||
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 2)
|
||||
);
|
||||
|
||||
public static VertexDeclaration PositionTextureOffsetInstanceDeclaration = new VertexDeclaration
|
||||
(
|
||||
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 2),
|
||||
new VertexElement(12, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 5)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,27 +5,24 @@ using Microsoft.Xna.Framework.Graphics;
|
|||
namespace Kav
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct PositionTextureOffsetInstanceVertex : IVertexType
|
||||
public struct PositionInstanceVertex : IVertexType, IHasTranslation
|
||||
{
|
||||
VertexDeclaration IVertexType.VertexDeclaration
|
||||
{
|
||||
get
|
||||
{
|
||||
return VertexDeclarations.PositionTextureOffsetInstanceDeclaration;
|
||||
return VertexDeclarations.PositionInstanceDeclaration;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 Translation { get; set; }
|
||||
public Vector2 UVOffset { get; set; }
|
||||
|
||||
public static readonly VertexDeclaration VertexDeclaration;
|
||||
|
||||
public PositionTextureOffsetInstanceVertex(
|
||||
Vector3 translation,
|
||||
Vector2 uvOffset
|
||||
public PositionInstanceVertex(
|
||||
Vector3 translation
|
||||
) {
|
||||
Translation = translation;
|
||||
UVOffset = uvOffset;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue