Compare commits
50 Commits
Author | SHA1 | Date |
---|---|---|
cosmonaut | f5cdd0b566 | |
cosmonaut | 808d50ccc2 | |
cosmonaut | d537993530 | |
cosmonaut | 3338bf3b06 | |
cosmonaut | 16ecb5afa6 | |
cosmonaut | 51d7f3e772 | |
cosmonaut | 3a0aa8894d | |
cosmonaut | c468d6276d | |
cosmonaut | d476f254e4 | |
cosmonaut | 2ff5cb1ca5 | |
cosmonaut | 40ca0402d6 | |
cosmonaut | 0ebad486c5 | |
cosmonaut | 8ff6e26887 | |
cosmonaut | 7f0bf47f07 | |
cosmonaut | 2f589e584d | |
cosmonaut | 7964d8a171 | |
cosmonaut | d5d0a38ff1 | |
cosmonaut | ee909ba94e | |
cosmonaut | 0060c22d72 | |
cosmonaut | 2c113ed642 | |
cosmonaut | b1395babfe | |
cosmonaut | ef948cf7fb | |
cosmonaut | 9a7fb75ec5 | |
cosmonaut | 0c576668cb | |
cosmonaut | 367e2795ae | |
cosmonaut | 1723f1dff8 | |
cosmonaut | 14e07c7476 | |
cosmonaut | 4b7d31f2b2 | |
cosmonaut | 4d3c5fc316 | |
cosmonaut | 96f6d22896 | |
cosmonaut | 84601379b5 | |
cosmonaut | fe222e266f | |
cosmonaut | bb694d3dbe | |
cosmonaut | e2fdbff7d1 | |
cosmonaut | 283b078641 | |
cosmonaut | b784f9df4b | |
cosmonaut | 8b43e8f45e | |
cosmonaut | ee8b0c5ee8 | |
cosmonaut | c9a4e35816 | |
cosmonaut | 7f986c546a | |
cosmonaut | fc09082f1b | |
cosmonaut | 46f2cad81a | |
cosmonaut | ca6c91446e | |
cosmonaut | 60ebb19e24 | |
cosmonaut | 47242e4f52 | |
cosmonaut | ae445d94d3 | |
cosmonaut | 665ff6dd44 | |
cosmonaut | 56cdffdff6 | |
cosmonaut | acaafdcdcd | |
cosmonaut | d83aacd57f |
|
@ -10,17 +10,26 @@ namespace Kav
|
||||||
public Vector3 Position { get; }
|
public Vector3 Position { get; }
|
||||||
public Vector3 Forward { get; }
|
public Vector3 Forward { get; }
|
||||||
public Vector3 Up { get; }
|
public Vector3 Up { get; }
|
||||||
|
public Vector3 Right { get; }
|
||||||
|
|
||||||
public float FieldOfView { get; }
|
public float FieldOfView { get; }
|
||||||
public float AspectRatio { get; }
|
public float AspectRatio { get; }
|
||||||
public float NearPlane { get; }
|
public float NearPlane { get; }
|
||||||
public float FarPlane { get; }
|
public float FarPlane { get; }
|
||||||
|
|
||||||
public PerspectiveCamera(Vector3 position, Vector3 forward, Vector3 up, float fieldOfView, float aspectRatio, float nearPlane, float farPlane)
|
public PerspectiveCamera(
|
||||||
{
|
Vector3 position,
|
||||||
|
Vector3 forward,
|
||||||
|
Vector3 up,
|
||||||
|
float fieldOfView,
|
||||||
|
float aspectRatio,
|
||||||
|
float nearPlane,
|
||||||
|
float farPlane
|
||||||
|
) {
|
||||||
Position = position;
|
Position = position;
|
||||||
Forward = forward;
|
Forward = forward;
|
||||||
Up = up;
|
Up = up;
|
||||||
|
Right = Vector3.Cross(forward, up);
|
||||||
View = Matrix.CreateLookAt(Position, Position + Forward, Up);
|
View = Matrix.CreateLookAt(Position, Position + Forward, Up);
|
||||||
|
|
||||||
FieldOfView = fieldOfView;
|
FieldOfView = fieldOfView;
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public struct AtlasAnimation
|
||||||
|
{
|
||||||
|
public UVData[] Frames { get; }
|
||||||
|
public int Framerate { get; }
|
||||||
|
|
||||||
|
public AtlasAnimation(UVData[] frames, int framerate)
|
||||||
|
{
|
||||||
|
Frames = frames;
|
||||||
|
Framerate = framerate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public class DirectionalShadowMapData
|
||||||
|
{
|
||||||
|
public static readonly int MAX_SHADOW_CASCADES = 4;
|
||||||
|
|
||||||
|
public RenderTarget2D[] ShadowMaps { get; }
|
||||||
|
|
||||||
|
public Matrix[] LightSpaceViews { get; }
|
||||||
|
public Matrix[] LightSpaceProjections { get; }
|
||||||
|
|
||||||
|
public float[] CascadeFarPlanes { get; }
|
||||||
|
|
||||||
|
public int ShadowMapSize { get; }
|
||||||
|
public int NumShadowCascades { get; }
|
||||||
|
|
||||||
|
internal DirectionalShadowMapData(
|
||||||
|
GraphicsDevice graphicsDevice,
|
||||||
|
int shadowMapSize,
|
||||||
|
int numCascades
|
||||||
|
) {
|
||||||
|
ShadowMapSize = shadowMapSize;
|
||||||
|
NumShadowCascades = (int)MathHelper.Clamp(numCascades, 1, MAX_SHADOW_CASCADES);
|
||||||
|
|
||||||
|
LightSpaceViews = new Matrix[4];
|
||||||
|
LightSpaceProjections = new Matrix[4];
|
||||||
|
|
||||||
|
ShadowMaps = new RenderTarget2D[NumShadowCascades];
|
||||||
|
|
||||||
|
for (var i = 0; i < NumShadowCascades; i++)
|
||||||
|
{
|
||||||
|
ShadowMaps[i] = new RenderTarget2D(
|
||||||
|
graphicsDevice,
|
||||||
|
shadowMapSize,
|
||||||
|
shadowMapSize,
|
||||||
|
false,
|
||||||
|
SurfaceFormat.Single,
|
||||||
|
DepthFormat.Depth24,
|
||||||
|
0,
|
||||||
|
RenderTargetUsage.PreserveContents
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
CascadeFarPlanes = new float[MAX_SHADOW_CASCADES];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear(GraphicsDevice graphicsDevice)
|
||||||
|
{
|
||||||
|
foreach (var shadowMap in ShadowMaps)
|
||||||
|
{
|
||||||
|
graphicsDevice.SetRenderTarget(shadowMap);
|
||||||
|
graphicsDevice.Clear(Color.White);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface IHasTranslation
|
||||||
|
{
|
||||||
|
Vector3 Translation { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface IHasWorldMatrix
|
||||||
|
{
|
||||||
|
Matrix World { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -74,32 +74,6 @@ 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()
|
protected override void OnApply()
|
||||||
{
|
{
|
||||||
gPositionParam.SetValue(GPosition);
|
gPositionParam.SetValue(GPosition);
|
||||||
|
|
|
@ -6,8 +6,7 @@ namespace Kav
|
||||||
public class DeferredPBR_GBufferEffect : Effect, TransformEffect
|
public class DeferredPBR_GBufferEffect : Effect, TransformEffect
|
||||||
{
|
{
|
||||||
EffectParameter worldParam;
|
EffectParameter worldParam;
|
||||||
EffectParameter worldViewProjectionParam;
|
EffectParameter viewProjectionParam;
|
||||||
EffectParameter worldInverseTransposeParam;
|
|
||||||
|
|
||||||
EffectParameter albedoTextureParam;
|
EffectParameter albedoTextureParam;
|
||||||
EffectParameter normalTextureParam;
|
EffectParameter normalTextureParam;
|
||||||
|
@ -17,6 +16,13 @@ namespace Kav
|
||||||
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;
|
||||||
|
@ -27,9 +33,18 @@ namespace Kav
|
||||||
float metallic;
|
float metallic;
|
||||||
float roughness;
|
float roughness;
|
||||||
|
|
||||||
|
Vector2 uvOffset;
|
||||||
|
Vector2 subTextureDimensions;
|
||||||
|
|
||||||
|
bool isSprite = false;
|
||||||
|
|
||||||
|
int numTextureRows = 1;
|
||||||
|
int numTextureColumns = 1;
|
||||||
|
|
||||||
bool albedoTextureEnabled = false;
|
bool albedoTextureEnabled = false;
|
||||||
bool metallicRoughnessMapEnabled = false;
|
bool metallicRoughnessMapEnabled = false;
|
||||||
bool normalMapEnabled = false;
|
bool normalMapEnabled = false;
|
||||||
|
bool hardwareInstancingEnabled = false;
|
||||||
|
|
||||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||||
|
|
||||||
|
@ -39,7 +54,7 @@ namespace Kav
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
world = value;
|
world = value;
|
||||||
dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj;
|
dirtyFlags |= EffectDirtyFlags.World;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +64,7 @@ namespace Kav
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
view = value;
|
view = value;
|
||||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition;
|
dirtyFlags |= EffectDirtyFlags.ViewProj | EffectDirtyFlags.EyePosition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +74,7 @@ namespace Kav
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
projection = value;
|
projection = value;
|
||||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +115,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
albedoTextureParam.SetValue(value);
|
albedoTextureParam.SetValue(value);
|
||||||
albedoTextureEnabled = value != null;
|
albedoTextureEnabled = value != null;
|
||||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
|
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +126,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
normalTextureParam.SetValue(value);
|
normalTextureParam.SetValue(value);
|
||||||
normalMapEnabled = value != null;
|
normalMapEnabled = value != null;
|
||||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
|
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +137,70 @@ namespace Kav
|
||||||
{
|
{
|
||||||
metallicRoughnessTextureParam.SetValue(value);
|
metallicRoughnessTextureParam.SetValue(value);
|
||||||
metallicRoughnessMapEnabled = value != null;
|
metallicRoughnessMapEnabled = value != null;
|
||||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
|
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != hardwareInstancingEnabled)
|
||||||
|
{
|
||||||
|
hardwareInstancingEnabled = value;
|
||||||
|
dirtyFlags |= EffectDirtyFlags.VertexShaderIndex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,30 +237,40 @@ namespace Kav
|
||||||
{
|
{
|
||||||
worldParam.SetValue(world);
|
worldParam.SetValue(world);
|
||||||
|
|
||||||
Matrix.Invert(ref world, out Matrix worldInverse);
|
|
||||||
Matrix.Transpose(ref worldInverse, out Matrix worldInverseTranspose);
|
|
||||||
worldInverseTransposeParam.SetValue(worldInverseTranspose);
|
|
||||||
|
|
||||||
dirtyFlags &= ~EffectDirtyFlags.World;
|
dirtyFlags &= ~EffectDirtyFlags.World;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
if ((dirtyFlags & EffectDirtyFlags.ViewProj) != 0)
|
||||||
{
|
{
|
||||||
Matrix.Multiply(ref world, ref view, out Matrix worldView);
|
Matrix.Multiply(ref view, ref projection, out Matrix viewProj);
|
||||||
Matrix.Multiply(ref worldView, ref projection, out Matrix worldViewProj);
|
viewProjectionParam.SetValue(viewProj);
|
||||||
worldViewProjectionParam.SetValue(worldViewProj);
|
|
||||||
|
|
||||||
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dirtyFlags & EffectDirtyFlags.EyePosition) != 0)
|
if ((dirtyFlags & EffectDirtyFlags.UVOrDimensions) != 0)
|
||||||
{
|
{
|
||||||
Matrix.Invert(ref view, out Matrix inverseView);
|
uvOffsetAndDimensionsParam.SetValue(new Vector4(
|
||||||
|
UVOffset.X, UVOffset.Y,
|
||||||
|
SubTextureDimensions.X, SubTextureDimensions.Y
|
||||||
|
));
|
||||||
|
|
||||||
dirtyFlags &= ~EffectDirtyFlags.EyePosition;
|
dirtyFlags &= ~EffectDirtyFlags.UVOrDimensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0)
|
if ((dirtyFlags & EffectDirtyFlags.VertexShaderIndex) != 0)
|
||||||
|
{
|
||||||
|
int vertexShaderIndex = 0;
|
||||||
|
|
||||||
|
if (hardwareInstancingEnabled)
|
||||||
|
{
|
||||||
|
vertexShaderIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vertexShaderIndexParam.SetValue(vertexShaderIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
|
||||||
{
|
{
|
||||||
int shaderIndex = 0;
|
int shaderIndex = 0;
|
||||||
|
|
||||||
|
@ -217,15 +305,14 @@ namespace Kav
|
||||||
|
|
||||||
shaderIndexParam.SetValue(shaderIndex);
|
shaderIndexParam.SetValue(shaderIndex);
|
||||||
|
|
||||||
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex;
|
dirtyFlags &= ~EffectDirtyFlags.PixelShaderIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CacheEffectParameters()
|
void CacheEffectParameters()
|
||||||
{
|
{
|
||||||
worldParam = Parameters["World"];
|
worldParam = Parameters["World"];
|
||||||
worldViewProjectionParam = Parameters["WorldViewProjection"];
|
viewProjectionParam = Parameters["ViewProjection"];
|
||||||
worldInverseTransposeParam = Parameters["WorldInverseTranspose"];
|
|
||||||
|
|
||||||
albedoTextureParam = Parameters["AlbedoTexture"];
|
albedoTextureParam = Parameters["AlbedoTexture"];
|
||||||
normalTextureParam = Parameters["NormalTexture"];
|
normalTextureParam = Parameters["NormalTexture"];
|
||||||
|
@ -235,7 +322,14 @@ namespace Kav
|
||||||
metallicParam = Parameters["MetallicValue"];
|
metallicParam = Parameters["MetallicValue"];
|
||||||
roughnessParam = Parameters["RoughnessValue"];
|
roughnessParam = Parameters["RoughnessValue"];
|
||||||
|
|
||||||
shaderIndexParam = Parameters["ShaderIndex"];
|
numTextureRowsParam = Parameters["NumTextureRows"];
|
||||||
|
numTextureColumnsParam = Parameters["NumTextureColumns"];
|
||||||
|
|
||||||
|
uvOffsetAndDimensionsParam = Parameters["UVOffsetAndDimensions"];
|
||||||
|
isSpriteParam = Parameters["IsSprite"];
|
||||||
|
|
||||||
|
shaderIndexParam = Parameters["PixelShaderIndex"];
|
||||||
|
vertexShaderIndexParam = Parameters["VertexShaderIndex"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ namespace Kav
|
||||||
|
|
||||||
EffectParameter farPlaneParam;
|
EffectParameter farPlaneParam;
|
||||||
|
|
||||||
|
EffectParameter worldViewProjectionParam;
|
||||||
|
|
||||||
public Texture2D GPosition { get; set; }
|
public Texture2D GPosition { get; set; }
|
||||||
public Texture2D GAlbedo { get; set; }
|
public Texture2D GAlbedo { get; set; }
|
||||||
public Texture2D GNormal { get; set; }
|
public Texture2D GNormal { get; set; }
|
||||||
|
@ -31,6 +33,42 @@ namespace Kav
|
||||||
|
|
||||||
public float FarPlane { get; set; }
|
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)
|
public DeferredPBR_PointLightEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_PointLightEffect)
|
||||||
{
|
{
|
||||||
CacheEffectParameters();
|
CacheEffectParameters();
|
||||||
|
@ -73,6 +111,13 @@ namespace Kav
|
||||||
pointLightColorParam.SetValue(PointLightColor);
|
pointLightColorParam.SetValue(PointLightColor);
|
||||||
|
|
||||||
farPlaneParam.SetValue(FarPlane);
|
farPlaneParam.SetValue(FarPlane);
|
||||||
|
|
||||||
|
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
||||||
|
{
|
||||||
|
worldViewProjectionParam.SetValue(world * view * projection);
|
||||||
|
|
||||||
|
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CacheEffectParameters()
|
void CacheEffectParameters()
|
||||||
|
@ -89,6 +134,8 @@ namespace Kav
|
||||||
pointLightColorParam = Parameters["PointLightColor"];
|
pointLightColorParam = Parameters["PointLightColor"];
|
||||||
|
|
||||||
farPlaneParam = Parameters["FarPlane"];
|
farPlaneParam = Parameters["FarPlane"];
|
||||||
|
|
||||||
|
worldViewProjectionParam = Parameters["WorldViewProjection"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
|
|
||||||
namespace Kav
|
|
||||||
{
|
|
||||||
public class DeferredPBR_SpotLightEffect : Effect
|
|
||||||
{
|
|
||||||
EffectParameter gPositionParam;
|
|
||||||
EffectParameter gAlbedoParam;
|
|
||||||
EffectParameter gNormalParam;
|
|
||||||
EffectParameter gMetallicRoughnessParam;
|
|
||||||
EffectParameter shadowMapParam;
|
|
||||||
|
|
||||||
EffectParameter eyePositionParam;
|
|
||||||
|
|
||||||
EffectParameter lightPositionParam;
|
|
||||||
EffectParameter lightDirectionParam;
|
|
||||||
EffectParameter lightColorParam;
|
|
||||||
EffectParameter lightCutoffParam;
|
|
||||||
|
|
||||||
EffectParameter farPlaneParam;
|
|
||||||
|
|
||||||
public Texture2D GPosition { get; set; }
|
|
||||||
public Texture2D GAlbedo { get; set; }
|
|
||||||
public Texture2D GNormal { get; set; }
|
|
||||||
public Texture2D GMetallicRoughness { get; set; }
|
|
||||||
public TextureCube ShadowMap { get; set; }
|
|
||||||
|
|
||||||
public Vector3 EyePosition { get; set; }
|
|
||||||
|
|
||||||
public Vector3 LightPosition { get; set; }
|
|
||||||
public Vector3 LightDirection { get; set; }
|
|
||||||
public Vector3 LightColor { get; set; }
|
|
||||||
public float LightCutoff { get; set; } //could be named lightangle?
|
|
||||||
|
|
||||||
public float FarPlane { get; set; }
|
|
||||||
|
|
||||||
public DeferredPBR_SpotLightEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_SpotLightEffect)
|
|
||||||
{
|
|
||||||
CacheEffectParameters();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnApply()
|
|
||||||
{
|
|
||||||
gPositionParam.SetValue(GPosition);
|
|
||||||
gAlbedoParam.SetValue(GAlbedo);
|
|
||||||
gNormalParam.SetValue(GNormal);
|
|
||||||
gMetallicRoughnessParam.SetValue(GMetallicRoughness);
|
|
||||||
shadowMapParam.SetValue(ShadowMap);
|
|
||||||
|
|
||||||
eyePositionParam.SetValue(EyePosition);
|
|
||||||
|
|
||||||
lightPositionParam.SetValue(LightPosition);
|
|
||||||
lightDirectionParam.SetValue(LightDirection);
|
|
||||||
lightColorParam.SetValue(LightColor);
|
|
||||||
lightCutoffParam.SetValue(LightCutoff);
|
|
||||||
|
|
||||||
farPlaneParam.SetValue(FarPlane);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CacheEffectParameters()
|
|
||||||
{
|
|
||||||
gPositionParam = Parameters["gPosition"];
|
|
||||||
gAlbedoParam = Parameters["gAlbedo"];
|
|
||||||
gNormalParam = Parameters["gNormal"];
|
|
||||||
gMetallicRoughnessParam = Parameters["gMetallicRoughness"];
|
|
||||||
shadowMapParam = Parameters["shadowMap"];
|
|
||||||
|
|
||||||
eyePositionParam = Parameters["EyePosition"];
|
|
||||||
|
|
||||||
lightPositionParam = Parameters["LightPosition"];
|
|
||||||
lightDirectionParam = Parameters["LightDirection"];
|
|
||||||
lightColorParam = Parameters["LightColor"];
|
|
||||||
lightCutoffParam = Parameters["LightCutoff"];
|
|
||||||
|
|
||||||
farPlaneParam = Parameters["FarPlane"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,210 @@
|
||||||
|
using Kav.Data;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public class DiffuseLitSpriteEffect : Effect
|
||||||
|
{
|
||||||
|
EffectParameter ambientColorParam;
|
||||||
|
|
||||||
|
EffectParameter directionalLightDirectionParam;
|
||||||
|
EffectParameter directionalLightColorParam;
|
||||||
|
|
||||||
|
EffectParameter uvOffsetAndDimensionsParam;
|
||||||
|
|
||||||
|
EffectParameter worldParam;
|
||||||
|
EffectParameter worldViewProjectionParam;
|
||||||
|
EffectParameter worldInverseTransposeParam;
|
||||||
|
|
||||||
|
EffectParameter shaderIndexParam;
|
||||||
|
|
||||||
|
Texture2D texture;
|
||||||
|
Texture2D normal;
|
||||||
|
|
||||||
|
bool normalMapEnabled = false;
|
||||||
|
|
||||||
|
Vector3 ambientColor;
|
||||||
|
|
||||||
|
Vector3 directionalLightDirection;
|
||||||
|
Vector3 directionalLightColor;
|
||||||
|
|
||||||
|
Matrix world = Matrix.Identity;
|
||||||
|
Matrix view = Matrix.Identity;
|
||||||
|
Matrix projection = Matrix.Identity;
|
||||||
|
|
||||||
|
Vector2 uvOffset;
|
||||||
|
Vector2 subTextureDimensions;
|
||||||
|
|
||||||
|
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||||
|
|
||||||
|
public bool NormalMapEnabled
|
||||||
|
{
|
||||||
|
get { return normalMapEnabled; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (normalMapEnabled != value)
|
||||||
|
{
|
||||||
|
normalMapEnabled = value;
|
||||||
|
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matrix World
|
||||||
|
{
|
||||||
|
get { return world; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
world = value;
|
||||||
|
dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matrix View
|
||||||
|
{
|
||||||
|
get { return view; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
view = value;
|
||||||
|
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matrix Projection
|
||||||
|
{
|
||||||
|
get { return projection; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
projection = value;
|
||||||
|
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int MaxPointLights { get; } = 8;
|
||||||
|
|
||||||
|
public Vector3 AmbientColor
|
||||||
|
{
|
||||||
|
get { return ambientColor; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ambientColor = value;
|
||||||
|
ambientColorParam.SetValue(ambientColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PointLightCollection PointLights { get; private set; }
|
||||||
|
|
||||||
|
public Vector3 DirectionalLightDirection
|
||||||
|
{
|
||||||
|
get { return directionalLightDirection; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
directionalLightDirection = value;
|
||||||
|
directionalLightDirectionParam.SetValue(directionalLightDirection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 DirectionalLightColor
|
||||||
|
{
|
||||||
|
get { return directionalLightColor; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
directionalLightColor = value;
|
||||||
|
directionalLightColorParam.SetValue(directionalLightColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
PointLights = new PointLightCollection(
|
||||||
|
Parameters["PointLightPositions"],
|
||||||
|
Parameters["PointLightColors"],
|
||||||
|
MaxPointLights
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApply()
|
||||||
|
{
|
||||||
|
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
||||||
|
{
|
||||||
|
worldParam.SetValue(world);
|
||||||
|
|
||||||
|
Matrix.Invert(ref world, out Matrix worldInverse);
|
||||||
|
Matrix.Transpose(ref worldInverse, out Matrix worldInverseTranspose);
|
||||||
|
worldInverseTransposeParam.SetValue(worldInverseTranspose);
|
||||||
|
|
||||||
|
dirtyFlags &= ~EffectDirtyFlags.World;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
||||||
|
{
|
||||||
|
Matrix.Multiply(ref world, ref view, out Matrix worldView);
|
||||||
|
Matrix.Multiply(ref worldView, ref projection, out Matrix worldViewProj);
|
||||||
|
worldViewProjectionParam.SetValue(worldViewProj);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (normalMapEnabled)
|
||||||
|
{
|
||||||
|
shaderIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
shaderIndexParam.SetValue(shaderIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CacheEffectParameters()
|
||||||
|
{
|
||||||
|
worldParam = Parameters["World"];
|
||||||
|
worldViewProjectionParam = Parameters["WorldViewProjection"];
|
||||||
|
worldInverseTransposeParam = Parameters["WorldInverseTranspose"];
|
||||||
|
|
||||||
|
ambientColorParam = Parameters["AmbientColor"];
|
||||||
|
|
||||||
|
directionalLightDirectionParam = Parameters["DirectionalLightDirection"];
|
||||||
|
directionalLightColorParam = Parameters["DirectionalLightColor"];
|
||||||
|
|
||||||
|
uvOffsetAndDimensionsParam = Parameters["UVOffsetAndDimensions"];
|
||||||
|
|
||||||
|
shaderIndexParam = Parameters["ShaderIndex"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,10 @@ namespace Kav
|
||||||
WorldViewProj = 1,
|
WorldViewProj = 1,
|
||||||
World = 2,
|
World = 2,
|
||||||
EyePosition = 4,
|
EyePosition = 4,
|
||||||
ShaderIndex = 8,
|
VertexShaderIndex = 8,
|
||||||
|
PixelShaderIndex = 16,
|
||||||
|
ViewProj = 32,
|
||||||
|
UVOrDimensions = 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/DeferredPBR_SpotLightEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/DeferredPBR_SpotLightEffect.fxb (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Binary file not shown.
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.
Binary file not shown.
|
@ -4,17 +4,22 @@ DECLARE_TEXTURE(AlbedoTexture, 0);
|
||||||
DECLARE_TEXTURE(NormalTexture, 1);
|
DECLARE_TEXTURE(NormalTexture, 1);
|
||||||
DECLARE_TEXTURE(MetallicRoughnessTexture, 2);
|
DECLARE_TEXTURE(MetallicRoughnessTexture, 2);
|
||||||
|
|
||||||
|
float4 UVOffsetAndDimensions;
|
||||||
|
float IsSprite;
|
||||||
|
|
||||||
BEGIN_CONSTANTS
|
BEGIN_CONSTANTS
|
||||||
|
|
||||||
float3 AlbedoValue _ps(c0) _cb(c0);
|
float3 AlbedoValue _ps(c0) _cb(c0);
|
||||||
float MetallicValue _ps(c1) _cb(c1);
|
float MetallicValue _ps(c1) _cb(c1);
|
||||||
float RoughnessValue _ps(c2) _cb(c2);
|
float RoughnessValue _ps(c2) _cb(c2);
|
||||||
|
|
||||||
|
int NumTextureRows _vs(c9) _cb(c3);
|
||||||
|
int NumTextureColumns _vs(c10) _cb(c4);
|
||||||
|
|
||||||
MATRIX_CONSTANTS
|
MATRIX_CONSTANTS
|
||||||
|
|
||||||
float4x4 World _vs(c0) _cb(c7);
|
float4x4 World _vs(c0) _cb(c7);
|
||||||
float4x4 WorldInverseTranspose _vs(c4) _cb(c11);
|
float4x4 ViewProjection _vs(c4) _cb(c11);
|
||||||
float4x4 WorldViewProjection _vs(c8) _cb(c15);
|
|
||||||
|
|
||||||
END_CONSTANTS
|
END_CONSTANTS
|
||||||
|
|
||||||
|
@ -22,7 +27,7 @@ struct VertexInput
|
||||||
{
|
{
|
||||||
float4 Position : POSITION;
|
float4 Position : POSITION;
|
||||||
float3 Normal : NORMAL;
|
float3 Normal : NORMAL;
|
||||||
float2 TexCoord : TEXCOORD0;
|
float2 TexCoord : TEXCOORD;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PixelInput
|
struct PixelInput
|
||||||
|
@ -48,9 +53,44 @@ PixelInput main_vs(VertexInput input)
|
||||||
PixelInput output;
|
PixelInput output;
|
||||||
|
|
||||||
output.PositionWorld = mul(input.Position, World).xyz;
|
output.PositionWorld = mul(input.Position, World).xyz;
|
||||||
output.NormalWorld = mul(input.Normal, (float3x3)WorldInverseTranspose).xyz;
|
output.NormalWorld = normalize(mul(input.Normal, World));
|
||||||
output.TexCoord = input.TexCoord;
|
|
||||||
output.Position = mul(input.Position, WorldViewProjection);
|
float2 texCoord;
|
||||||
|
texCoord.x = (input.TexCoord.x * UVOffsetAndDimensions.z) + UVOffsetAndDimensions.x;
|
||||||
|
texCoord.y = (input.TexCoord.y * UVOffsetAndDimensions.w) + UVOffsetAndDimensions.y;
|
||||||
|
output.TexCoord = texCoord;
|
||||||
|
|
||||||
|
float4x4 worldViewProjection = mul(World, ViewProjection);
|
||||||
|
output.Position = mul(input.Position, worldViewProjection);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
PixelInput instanced_vs(
|
||||||
|
VertexInput input,
|
||||||
|
float3 Translation : TEXCOORD2,
|
||||||
|
float2 UVOffset : TEXCOORD5
|
||||||
|
) {
|
||||||
|
PixelInput 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.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.Position = mul(input.Position, worldViewProjection);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +120,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), 1.0);
|
output.gNormal = float4(normalize(input.NormalWorld), IsSprite);
|
||||||
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);
|
||||||
|
|
||||||
|
@ -92,10 +132,12 @@ 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), 1.0);
|
output.gNormal = float4(normalize(input.NormalWorld), IsSprite);
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +146,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), 1.0);
|
output.gNormal = float4(normalize(input.NormalWorld), IsSprite);
|
||||||
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);
|
||||||
|
|
||||||
|
@ -116,7 +158,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), 1.0);
|
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), IsSprite);
|
||||||
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);
|
||||||
|
|
||||||
|
@ -128,10 +170,12 @@ 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), 1.0);
|
output.gNormal = float4(normalize(input.NormalWorld), IsSprite);
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,10 +184,12 @@ 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), 1.0);
|
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), IsSprite);
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +198,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), 1.0);
|
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), IsSprite);
|
||||||
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);
|
||||||
|
|
||||||
|
@ -164,13 +210,28 @@ 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), 1.0);
|
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), IsSprite);
|
||||||
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(),
|
||||||
|
@ -191,13 +252,13 @@ int PSIndices[8] =
|
||||||
0, 1, 2, 3, 4, 5, 6, 7
|
0, 1, 2, 3, 4, 5, 6, 7
|
||||||
};
|
};
|
||||||
|
|
||||||
int ShaderIndex = 0;
|
int PixelShaderIndex = 0;
|
||||||
|
|
||||||
Technique GBuffer
|
Technique GBuffer
|
||||||
{
|
{
|
||||||
Pass
|
Pass
|
||||||
{
|
{
|
||||||
VertexShader = compile vs_3_0 main_vs();
|
VertexShader = (VSArray[VSIndices[VertexShaderIndex]]);
|
||||||
PixelShader = (PSArray[PSIndices[ShaderIndex]]);
|
PixelShader = (PSArray[PSIndices[PixelShaderIndex]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// Assumes you are drawing a sphere!!
|
||||||
|
|
||||||
#include "Macros.fxh" //from FNA
|
#include "Macros.fxh" //from FNA
|
||||||
#include "Lighting.fxh"
|
#include "Lighting.fxh"
|
||||||
#include "Shadow.fxh"
|
#include "Shadow.fxh"
|
||||||
|
@ -19,26 +21,27 @@ BEGIN_CONSTANTS
|
||||||
|
|
||||||
MATRIX_CONSTANTS
|
MATRIX_CONSTANTS
|
||||||
|
|
||||||
|
float4x4 WorldViewProjection _vs(c0) _cb(c4);
|
||||||
|
|
||||||
END_CONSTANTS
|
END_CONSTANTS
|
||||||
|
|
||||||
struct VertexInput
|
struct VertexInput
|
||||||
{
|
{
|
||||||
float4 Position : POSITION;
|
float4 Position : POSITION;
|
||||||
float2 TexCoord : TEXCOORD;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PixelInput
|
struct PixelInput
|
||||||
{
|
{
|
||||||
float4 Position : SV_POSITION;
|
float4 Position : SV_POSITION;
|
||||||
float2 TexCoord : TEXCOORD0;
|
float4 ScreenPosition : TEXCOORD0;
|
||||||
};
|
};
|
||||||
|
|
||||||
PixelInput main_vs(VertexInput input)
|
PixelInput main_vs(VertexInput input)
|
||||||
{
|
{
|
||||||
PixelInput output;
|
PixelInput output;
|
||||||
|
|
||||||
output.Position = input.Position;
|
output.Position = mul(input.Position, WorldViewProjection);
|
||||||
output.TexCoord = input.TexCoord;
|
output.ScreenPosition = output.Position;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -68,15 +71,33 @@ float4 ComputeColor(
|
||||||
float3 color = ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, shadow);
|
float3 color = ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, shadow);
|
||||||
|
|
||||||
return float4(color, 1.0);
|
return float4(color, 1.0);
|
||||||
|
//return float4(shadow, shadow, shadow, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 main_ps(PixelInput input) : SV_TARGET0
|
float4 main_ps(PixelInput input) : SV_TARGET0
|
||||||
{
|
{
|
||||||
float3 worldPosition = SAMPLE_TEXTURE(gPosition, input.TexCoord).rgb;
|
input.ScreenPosition.xy /= input.ScreenPosition.w;
|
||||||
float3 normal = SAMPLE_TEXTURE(gNormal, input.TexCoord).xyz;
|
float2 texCoord = 0.5f * float2(input.ScreenPosition.x,-input.ScreenPosition.y) + 0.5f;
|
||||||
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(
|
return ComputeColor(
|
||||||
worldPosition,
|
worldPosition,
|
||||||
normal,
|
normal,
|
||||||
|
@ -85,6 +106,7 @@ float4 main_ps(PixelInput input) : SV_TARGET0
|
||||||
metallicRoughness.g
|
metallicRoughness.g
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Technique DeferredPBR_Point
|
Technique DeferredPBR_Point
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
#include "Macros.fxh" //from FNA
|
|
||||||
#include "Lighting.fxh"
|
|
||||||
#include "Shadow.fxh"
|
|
||||||
|
|
||||||
DECLARE_TEXTURE(gPosition, 0);
|
|
||||||
DECLARE_TEXTURE(gAlbedo, 1);
|
|
||||||
DECLARE_TEXTURE(gNormal, 2);
|
|
||||||
DECLARE_TEXTURE(gMetallicRoughness, 3);
|
|
||||||
DECLARE_CUBEMAP(shadowMap, 4);
|
|
||||||
|
|
||||||
BEGIN_CONSTANTS
|
|
||||||
|
|
||||||
float3 EyePosition _ps(c0) _cb(c0);
|
|
||||||
|
|
||||||
float3 LightPosition _ps(c1) _cb(c1);
|
|
||||||
float3 LightDirection _ps(c2) _cb(c2);
|
|
||||||
float3 LightColor _ps(c3) _cb(c3);
|
|
||||||
float LightCutoff _ps(c4) _cb(c4);
|
|
||||||
|
|
||||||
float FarPlane _ps(c5) _cb(c5);
|
|
||||||
|
|
||||||
MATRIX_CONSTANTS
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pixel Shader
|
|
||||||
|
|
||||||
float4 ComputeColor(
|
|
||||||
float3 worldPosition,
|
|
||||||
float3 worldNormal,
|
|
||||||
float3 albedo,
|
|
||||||
float metallic,
|
|
||||||
float roughness
|
|
||||||
) {
|
|
||||||
float3 V = normalize(EyePosition - worldPosition);
|
|
||||||
float3 N = normalize(worldNormal);
|
|
||||||
|
|
||||||
float3 F0 = float3(0.04, 0.04, 0.04);
|
|
||||||
F0 = lerp(F0, albedo, metallic);
|
|
||||||
|
|
||||||
float3 lightDir = LightPosition - worldPosition;
|
|
||||||
float3 L = normalize(lightDir);
|
|
||||||
float distance = length(lightDir);
|
|
||||||
float attenuation = 1.0 / (distance * distance);
|
|
||||||
float3 radiance = LightColor * attenuation;
|
|
||||||
|
|
||||||
//float shadow = HardPointShadow(worldPosition, N, L, PointLightPosition, SAMPLER(shadowMap), FarPlane);
|
|
||||||
float3 color = ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, 1.0);
|
|
||||||
|
|
||||||
return float4(color, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 main_ps(PixelInput input) : SV_TARGET0
|
|
||||||
{
|
|
||||||
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 lightDir = normalize(LightPosition - worldPosition);
|
|
||||||
|
|
||||||
float theta = dot(lightDir, normalize(-LightDirection));
|
|
||||||
|
|
||||||
if (theta > LightCutoff)
|
|
||||||
{
|
|
||||||
return ComputeColor(
|
|
||||||
worldPosition,
|
|
||||||
normal,
|
|
||||||
albedo,
|
|
||||||
metallicRoughness.r,
|
|
||||||
metallicRoughness.g
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return float4(0.0, 0.0, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Technique DeferredPBR_Point
|
|
||||||
{
|
|
||||||
Pass
|
|
||||||
{
|
|
||||||
VertexShader = compile vs_3_0 main_vs();
|
|
||||||
PixelShader = compile ps_3_0 main_ps();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
#include "Macros.fxh" //from FNA
|
||||||
|
|
||||||
|
// Effect applies normalmapped lighting to a 2D sprite.
|
||||||
|
|
||||||
|
DECLARE_TEXTURE(Texture, 0);
|
||||||
|
DECLARE_TEXTURE(Normal, 1);
|
||||||
|
|
||||||
|
float3 AmbientColor;
|
||||||
|
|
||||||
|
float3 PointLightPositions[8];
|
||||||
|
float3 PointLightColors[8];
|
||||||
|
|
||||||
|
float3 DirectionalLightDirection;
|
||||||
|
float3 DirectionalLightColor;
|
||||||
|
|
||||||
|
float4 UVOffsetAndDimensions;
|
||||||
|
|
||||||
|
float4x4 WorldInverseTranspose;
|
||||||
|
float4x4 World;
|
||||||
|
float4x4 WorldViewProjection;
|
||||||
|
|
||||||
|
struct VertexShaderInput
|
||||||
|
{
|
||||||
|
float4 Position : POSITION;
|
||||||
|
float3 Normal : NORMAL;
|
||||||
|
float2 TexCoord : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PixelShaderInput
|
||||||
|
{
|
||||||
|
float4 Position : SV_Position;
|
||||||
|
float2 TexCoord : TEXCOORD0;
|
||||||
|
float3 NormalWS : TEXCOORD1;
|
||||||
|
float3 PositionWS : TEXCOORD2;
|
||||||
|
};
|
||||||
|
|
||||||
|
PixelShaderInput main_vs(VertexShaderInput input)
|
||||||
|
{
|
||||||
|
PixelShaderInput output;
|
||||||
|
|
||||||
|
output.Position = mul(input.Position, WorldViewProjection);
|
||||||
|
output.NormalWS = normalize(mul(input.Normal, (float3x3)WorldInverseTranspose));
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Easy trick to get tangent-normals to world-space to keep PBR code simplified.
|
||||||
|
float3 GetNormalFromMap(float3 worldPos, float2 texCoords, float3 normal)
|
||||||
|
{
|
||||||
|
float3 tangentNormal = SAMPLE_TEXTURE(Normal, texCoords).xyz * 2.0 - 1.0;
|
||||||
|
|
||||||
|
float3 Q1 = ddx(worldPos);
|
||||||
|
float3 Q2 = ddy(worldPos);
|
||||||
|
float2 st1 = ddx(texCoords);
|
||||||
|
float2 st2 = ddy(texCoords);
|
||||||
|
|
||||||
|
float3 N = normalize(normal);
|
||||||
|
float3 T = normalize(Q1*st2.y - Q2*st1.y);
|
||||||
|
float3 B = -normalize(cross(N, T));
|
||||||
|
float3x3 TBN = float3x3(T, B, N);
|
||||||
|
|
||||||
|
return normalize(mul(tangentNormal, TBN));
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 LightColor(float3 worldPosition, float3 worldNormal)
|
||||||
|
{
|
||||||
|
float3 lightColor = float3(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
// point lights
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
float3 lightVec = PointLightPositions[i] - worldPosition;
|
||||||
|
float distance = length(lightVec);
|
||||||
|
|
||||||
|
float3 lightDir = normalize(lightVec);
|
||||||
|
float diffuse = max(dot(worldNormal, lightDir), 0.0);
|
||||||
|
float3 attenuation = 1.0 / (distance * distance);
|
||||||
|
|
||||||
|
lightColor += diffuse * attenuation * PointLightColors[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// directional light
|
||||||
|
float directionalDiffuse = max(dot(worldNormal, DirectionalLightDirection), 0.0);
|
||||||
|
lightColor += directionalDiffuse * DirectionalLightColor;
|
||||||
|
|
||||||
|
// ambient light
|
||||||
|
lightColor += AmbientColor;
|
||||||
|
|
||||||
|
return float4(lightColor, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
PixelShader PSArray[2] =
|
||||||
|
{
|
||||||
|
compile ps_3_0 WithoutNormalMap(),
|
||||||
|
compile ps_3_0 WithNormalMap()
|
||||||
|
};
|
||||||
|
|
||||||
|
int PSIndices[2] =
|
||||||
|
{
|
||||||
|
0, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
int ShaderIndex = 0;
|
||||||
|
|
||||||
|
Technique DiffuseLitSprite
|
||||||
|
{
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
VertexShader = compile vs_3_0 main_vs();
|
||||||
|
PixelShader = (PSArray[PSIndices[ShaderIndex]]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
#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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
#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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
BEGIN_CONSTANTS
|
BEGIN_CONSTANTS
|
||||||
|
|
||||||
float4x4 ModelViewProjection _vs(c0) _cb(c0);
|
|
||||||
|
|
||||||
MATRIX_CONSTANTS
|
MATRIX_CONSTANTS
|
||||||
|
|
||||||
|
float4x4 World _vs(c0) _cb(c0);
|
||||||
|
float4x4 ViewProjection _vs(c4) _cb(c4);
|
||||||
|
|
||||||
END_CONSTANTS
|
END_CONSTANTS
|
||||||
|
|
||||||
struct VertexShaderInput
|
struct VertexShaderInput
|
||||||
|
@ -15,7 +16,7 @@ struct VertexShaderInput
|
||||||
|
|
||||||
struct VertexShaderOutput
|
struct VertexShaderOutput
|
||||||
{
|
{
|
||||||
float4 Position : SV_Position;
|
float4 Position : SV_POSITION;
|
||||||
float Depth : TEXCOORD0;
|
float Depth : TEXCOORD0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,7 +24,8 @@ VertexShaderOutput main_vs(VertexShaderInput input)
|
||||||
{
|
{
|
||||||
VertexShaderOutput output;
|
VertexShaderOutput output;
|
||||||
|
|
||||||
output.Position = mul(input.Position, ModelViewProjection);
|
float4x4 worldViewProjection = mul(World, ViewProjection);
|
||||||
|
output.Position = mul(input.Position, worldViewProjection);
|
||||||
output.Depth = output.Position.z / output.Position.w;
|
output.Depth = output.Position.z / output.Position.w;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
float4x4 ViewProjection;
|
||||||
|
|
||||||
|
struct VertexShaderInput
|
||||||
|
{
|
||||||
|
float4 Position : POSITION;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexShaderOutput
|
||||||
|
{
|
||||||
|
float4 Position : POSITION0;
|
||||||
|
float4 ProjectedPosition : 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.ProjectedPosition = output.Position;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 main_ps(VertexShaderOutput input) : COLOR0
|
||||||
|
{
|
||||||
|
return float4(input.ProjectedPosition.z / input.ProjectedPosition.w, 0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique SimpleDepth
|
||||||
|
{
|
||||||
|
Pass
|
||||||
|
{
|
||||||
|
VertexShader = compile vs_3_0 instanced_vs();
|
||||||
|
PixelShader = compile ps_3_0 main_ps();
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,28 +3,28 @@ using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
namespace Kav
|
namespace Kav
|
||||||
{
|
{
|
||||||
public class LinearDepthEffect : Effect
|
public class LinearDepthEffect : Effect, IHasWorldMatrix
|
||||||
{
|
{
|
||||||
EffectParameter modelParam;
|
EffectParameter worldParam;
|
||||||
EffectParameter modelViewProjectionParam;
|
EffectParameter worldViewProjectionParam;
|
||||||
EffectParameter lightPositionParam;
|
EffectParameter lightPositionParam;
|
||||||
EffectParameter farPlaneParam;
|
EffectParameter farPlaneParam;
|
||||||
|
|
||||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||||
|
|
||||||
Matrix model;
|
Matrix world;
|
||||||
Matrix view;
|
Matrix view;
|
||||||
Matrix projection;
|
Matrix projection;
|
||||||
|
|
||||||
public Vector3 LightPosition { get; set; }
|
public Vector3 LightPosition { get; set; }
|
||||||
public float FarPlane { get; set; }
|
public float FarPlane { get; set; }
|
||||||
|
|
||||||
public Matrix Model
|
public Matrix World
|
||||||
{
|
{
|
||||||
get { return model; }
|
get { return world; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
model = value;
|
world = value;
|
||||||
dirtyFlags |= EffectDirtyFlags.World;
|
dirtyFlags |= EffectDirtyFlags.World;
|
||||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
||||||
}
|
}
|
||||||
|
@ -60,16 +60,16 @@ namespace Kav
|
||||||
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
||||||
{
|
{
|
||||||
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
||||||
Matrix.Multiply(ref model, ref viewProjection, out Matrix worldViewProj);
|
Matrix.Multiply(ref world, ref viewProjection, out Matrix worldViewProj);
|
||||||
|
|
||||||
modelViewProjectionParam.SetValue(worldViewProj);
|
worldViewProjectionParam.SetValue(worldViewProj);
|
||||||
|
|
||||||
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
||||||
{
|
{
|
||||||
modelParam.SetValue(model);
|
worldParam.SetValue(world);
|
||||||
|
|
||||||
dirtyFlags &= ~EffectDirtyFlags.World;
|
dirtyFlags &= ~EffectDirtyFlags.World;
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,8 @@ namespace Kav
|
||||||
|
|
||||||
private void CacheEffectParameters()
|
private void CacheEffectParameters()
|
||||||
{
|
{
|
||||||
modelParam = Parameters["Model"];
|
worldParam = Parameters["Model"];
|
||||||
modelViewProjectionParam = Parameters["ModelViewProjection"];
|
worldViewProjectionParam = Parameters["ModelViewProjection"];
|
||||||
|
|
||||||
lightPositionParam = Parameters["LightPosition"];
|
lightPositionParam = Parameters["LightPosition"];
|
||||||
farPlaneParam = Parameters["FarPlane"];
|
farPlaneParam = Parameters["FarPlane"];
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
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"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -130,7 +130,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
albedoTextureParam.SetValue(value);
|
albedoTextureParam.SetValue(value);
|
||||||
albedoTextureEnabled = value != null;
|
albedoTextureEnabled = value != null;
|
||||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
|
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
normalTextureParam.SetValue(value);
|
normalTextureParam.SetValue(value);
|
||||||
normalMapEnabled = value != null;
|
normalMapEnabled = value != null;
|
||||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
|
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ namespace Kav
|
||||||
{
|
{
|
||||||
metallicRoughnessTextureParam.SetValue(value);
|
metallicRoughnessTextureParam.SetValue(value);
|
||||||
metallicRoughnessMapEnabled = value != null;
|
metallicRoughnessMapEnabled = value != null;
|
||||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
|
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,45 +197,6 @@ 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()
|
protected override void OnApply()
|
||||||
{
|
{
|
||||||
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
||||||
|
@ -266,7 +227,7 @@ namespace Kav
|
||||||
dirtyFlags &= ~EffectDirtyFlags.EyePosition;
|
dirtyFlags &= ~EffectDirtyFlags.EyePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0)
|
if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
|
||||||
{
|
{
|
||||||
int shaderIndex = 0;
|
int shaderIndex = 0;
|
||||||
|
|
||||||
|
@ -301,7 +262,7 @@ namespace Kav
|
||||||
|
|
||||||
shaderIndexParam.SetValue(shaderIndex);
|
shaderIndexParam.SetValue(shaderIndex);
|
||||||
|
|
||||||
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex;
|
dirtyFlags &= ~EffectDirtyFlags.PixelShaderIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
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,41 +7,24 @@ namespace Kav
|
||||||
{
|
{
|
||||||
private readonly Vector3[] positions;
|
private readonly Vector3[] positions;
|
||||||
private readonly Vector3[] colors;
|
private readonly Vector3[] colors;
|
||||||
private readonly float[] intensities;
|
|
||||||
|
|
||||||
readonly EffectParameter lightPositionsParam;
|
readonly EffectParameter lightPositionsParam;
|
||||||
readonly EffectParameter lightColorsParam;
|
readonly EffectParameter lightColorsParam;
|
||||||
|
|
||||||
public PointLightCollection(EffectParameter lightPositionsParam, EffectParameter lightColorsParam, int maxLights)
|
public PointLightCollection(EffectParameter lightPositionsParam, EffectParameter lightColorsParam, int maxLights)
|
||||||
{
|
{
|
||||||
this.positions = new Vector3[maxLights];
|
positions = new Vector3[maxLights];
|
||||||
this.colors = new Vector3[maxLights];
|
colors = new Vector3[maxLights];
|
||||||
this.intensities = new float[maxLights];
|
|
||||||
this.lightPositionsParam = lightPositionsParam;
|
this.lightPositionsParam = lightPositionsParam;
|
||||||
this.lightColorsParam = lightColorsParam;
|
this.lightColorsParam = lightColorsParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PointLight this[int i]
|
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
|
set
|
||||||
{
|
{
|
||||||
positions[i] = value.Position;
|
positions[i] = value.Position;
|
||||||
colors[i] = value.Color.ToVector3() * value.Intensity;
|
colors[i] = value.Color.ToVector3() * value.Radius;
|
||||||
intensities[i] = value.Intensity;
|
|
||||||
lightPositionsParam.SetValue(positions);
|
lightPositionsParam.SetValue(positions);
|
||||||
lightColorsParam.SetValue(colors);
|
lightColorsParam.SetValue(colors);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,23 +3,24 @@ using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
namespace Kav
|
namespace Kav
|
||||||
{
|
{
|
||||||
public class SimpleDepthEffect : Effect
|
public class SimpleDepthEffect : Effect, IHasWorldMatrix
|
||||||
{
|
{
|
||||||
EffectParameter modelViewProjectionParam;
|
EffectParameter worldParam;
|
||||||
|
EffectParameter viewProjectionParam;
|
||||||
|
|
||||||
Matrix model;
|
Matrix world;
|
||||||
Matrix view;
|
Matrix view;
|
||||||
Matrix projection;
|
Matrix projection;
|
||||||
|
|
||||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||||
|
|
||||||
public Matrix Model
|
public Matrix World
|
||||||
{
|
{
|
||||||
get { return model; }
|
get { return world; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
model = value;
|
world = value;
|
||||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
dirtyFlags |= EffectDirtyFlags.World;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ namespace Kav
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
view = value;
|
view = value;
|
||||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ namespace Kav
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
projection = value;
|
projection = value;
|
||||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,20 +51,26 @@ namespace Kav
|
||||||
|
|
||||||
protected override void OnApply()
|
protected override void OnApply()
|
||||||
{
|
{
|
||||||
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
||||||
|
{
|
||||||
|
worldParam.SetValue(world);
|
||||||
|
|
||||||
|
dirtyFlags &= ~EffectDirtyFlags.World;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dirtyFlags & EffectDirtyFlags.ViewProj) != 0)
|
||||||
{
|
{
|
||||||
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
||||||
Matrix.Multiply(ref model, ref viewProjection, out Matrix worldViewProj);
|
viewProjectionParam.SetValue(viewProjection);
|
||||||
|
|
||||||
modelViewProjectionParam.SetValue(worldViewProj);
|
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
||||||
|
|
||||||
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CacheEffectParameters()
|
private void CacheEffectParameters()
|
||||||
{
|
{
|
||||||
modelViewProjectionParam = Parameters["ModelViewProjection"];
|
worldParam = Parameters["World"];
|
||||||
|
viewProjectionParam = Parameters["ViewProjection"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public class SimpleDepthEffectInstanced : Effect
|
||||||
|
{
|
||||||
|
EffectParameter viewProjectionParam;
|
||||||
|
|
||||||
|
Matrix view;
|
||||||
|
Matrix projection;
|
||||||
|
|
||||||
|
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||||
|
|
||||||
|
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 SimpleDepthEffectInstanced(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.SimpleDepthEffectInstanced)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CacheEffectParameters()
|
||||||
|
{
|
||||||
|
viewProjectionParam = Parameters["ViewProjection"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public enum SpriteBillboardConstraint
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Horizontal,
|
||||||
|
Full
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface ICullable
|
||||||
|
{
|
||||||
|
BoundingBox BoundingBox { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface IGBufferDrawable
|
||||||
|
{
|
||||||
|
Vector3 Albedo { get; }
|
||||||
|
float Metallic { get; }
|
||||||
|
float Roughness { get; }
|
||||||
|
|
||||||
|
Texture2D AlbedoTexture { get; }
|
||||||
|
Texture2D NormalTexture { get; }
|
||||||
|
Texture2D MetallicRoughnessTexture { get; }
|
||||||
|
|
||||||
|
int NumTextureRows { get; }
|
||||||
|
int NumTextureColumns { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface IHasVertexPositions
|
||||||
|
{
|
||||||
|
Vector3[] Positions { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface IIndexDrawable
|
||||||
|
{
|
||||||
|
VertexBuffer VertexBuffer { get; }
|
||||||
|
IndexBuffer IndexBuffer { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface ITransformable
|
||||||
|
{
|
||||||
|
Matrix TransformMatrix { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
namespace Kav
|
namespace Kav
|
||||||
{
|
{
|
||||||
public class MeshPart
|
public class MeshPart : IIndexDrawable, IGBufferDrawable, ICullable, IHasVertexPositions
|
||||||
{
|
{
|
||||||
public IndexBuffer IndexBuffer { get; }
|
public IndexBuffer IndexBuffer { get; }
|
||||||
public VertexBuffer VertexBuffer { get; }
|
public VertexBuffer VertexBuffer { get; }
|
||||||
|
@ -38,6 +38,9 @@ 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;
|
||||||
|
|
|
@ -2,7 +2,7 @@ using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
namespace Kav
|
namespace Kav
|
||||||
{
|
{
|
||||||
public class Model
|
public class Model : ICullable
|
||||||
{
|
{
|
||||||
public Mesh[] Meshes { get; }
|
public Mesh[] Meshes { get; }
|
||||||
public BoundingBox BoundingBox { get; }
|
public BoundingBox BoundingBox { get; }
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public struct Sprite
|
||||||
|
{
|
||||||
|
public Texture2D Texture { get; }
|
||||||
|
public Vector3 Position { get; }
|
||||||
|
public Vector2 Origin { get; }
|
||||||
|
public float Rotation { get; }
|
||||||
|
public Vector2 Scale { get; }
|
||||||
|
public SpriteBillboardConstraint BillboardConstraint { get; }
|
||||||
|
|
||||||
|
public Matrix TransformMatrix { get; }
|
||||||
|
|
||||||
|
public Sprite(
|
||||||
|
Texture2D texture,
|
||||||
|
Vector3 position,
|
||||||
|
Vector2 origin,
|
||||||
|
float rotation,
|
||||||
|
Vector2 scale,
|
||||||
|
SpriteBillboardConstraint billboardConstraint = SpriteBillboardConstraint.None
|
||||||
|
) {
|
||||||
|
Texture = texture;
|
||||||
|
Position = position;
|
||||||
|
Origin = origin;
|
||||||
|
Rotation = rotation;
|
||||||
|
Scale = scale;
|
||||||
|
BillboardConstraint = billboardConstraint;
|
||||||
|
TransformMatrix = ConstructTransformMatrix(Position, Scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Sprite(
|
||||||
|
Texture2D texture,
|
||||||
|
Vector3 position,
|
||||||
|
SpriteBillboardConstraint billboardConstraint = SpriteBillboardConstraint.None
|
||||||
|
) {
|
||||||
|
Texture = texture;
|
||||||
|
Position = position;
|
||||||
|
Origin = Vector2.Zero;
|
||||||
|
Rotation = 0;
|
||||||
|
Scale = Vector2.One;
|
||||||
|
BillboardConstraint = billboardConstraint;
|
||||||
|
TransformMatrix = ConstructTransformMatrix(Position, Scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Matrix ConstructTransformMatrix(
|
||||||
|
Vector3 position,
|
||||||
|
Vector2 scale
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
Matrix.CreateTranslation(position) *
|
||||||
|
Matrix.CreateScale(scale.X, scale.Y, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
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,11 +2,13 @@
|
||||||
|
|
||||||
<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>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<AssemblyName>Kav</AssemblyName>
|
<AssemblyName>Kav</AssemblyName>
|
||||||
|
<Platforms>x64</Platforms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -24,9 +26,6 @@
|
||||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_DirectionalLightEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\DeferredPBR_DirectionalLightEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.DeferredPBR_DirectionalLightEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.DeferredPBR_DirectionalLightEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_SpotLightEffect.fxb">
|
|
||||||
<LogicalName>Kav.Resources.DeferredPBR_SpotLightEffect.fxb</LogicalName>
|
|
||||||
</EmbeddedResource>
|
|
||||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_GBufferEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\DeferredPBR_GBufferEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.DeferredPBR_GBufferEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.DeferredPBR_GBufferEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
@ -45,15 +44,30 @@
|
||||||
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffectInstanced.fxb">
|
||||||
|
<LogicalName>Kav.Resources.SimpleDepthEffectInstanced.fxb</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Effects\FXB\LinearDepthEffectInstanced.fxb">
|
||||||
|
<LogicalName>Kav.Resources.LinearDepthEffectInstanced.fxb</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</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">
|
<EmbeddedResource Include="Models\UnitCube.glb">
|
||||||
<LogicalName>Kav.Resources.UnitCube.glb</LogicalName>
|
<LogicalName>Kav.Resources.UnitCube.glb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Models\UnitSphere.glb">
|
||||||
|
<LogicalName>Kav.Resources.UnitSphere.glb</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.26124.0
|
||||||
|
MinimumVisualStudioVersion = 15.0.26124.0
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kav", "Kav.Core.csproj", "{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|x64.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -1,12 +1,14 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<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>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<AssemblyName>Kav</AssemblyName>
|
<AssemblyName>Kav</AssemblyName>
|
||||||
|
<Platforms>x64;x86</Platforms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -27,9 +29,6 @@
|
||||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_GBufferEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\DeferredPBR_GBufferEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.DeferredPBR_GBufferEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.DeferredPBR_GBufferEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Effects\FXB\DeferredPBR_SpotLightEffect.fxb">
|
|
||||||
<LogicalName>Kav.Resources.DeferredPBR_SpotLightEffect.fxb</LogicalName>
|
|
||||||
</EmbeddedResource>
|
|
||||||
<EmbeddedResource Include="Effects\FXB\ToneMapEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\ToneMapEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.ToneMapEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.ToneMapEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
@ -45,15 +44,30 @@
|
||||||
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffectInstanced.fxb">
|
||||||
|
<LogicalName>Kav.Resources.SimpleDepthEffectInstanced.fxb</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Effects\FXB\LinearDepthEffectInstanced.fxb">
|
||||||
|
<LogicalName>Kav.Resources.LinearDepthEffectInstanced.fxb</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\SkyboxEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.SkyboxEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</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">
|
<EmbeddedResource Include="Models\UnitCube.glb">
|
||||||
<LogicalName>Kav.Resources.UnitCube.glb</LogicalName>
|
<LogicalName>Kav.Resources.UnitCube.glb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Models\UnitSphere.glb">
|
||||||
|
<LogicalName>Kav.Resources.UnitSphere.glb</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.26124.0
|
||||||
|
MinimumVisualStudioVersion = 15.0.26124.0
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kav.Framework", "Kav.Framework.csproj", "{B46F5438-2EE3-4EB1-9ECD-251D3B3CBD9A}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{B46F5438-2EE3-4EB1-9ECD-251D3B3CBD9A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{B46F5438-2EE3-4EB1-9ECD-251D3B3CBD9A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{B46F5438-2EE3-4EB1-9ECD-251D3B3CBD9A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{B46F5438-2EE3-4EB1-9ECD-251D3B3CBD9A}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
34
Kav.sln
34
Kav.sln
|
@ -1,34 +0,0 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio 15
|
|
||||||
VisualStudioVersion = 15.0.26124.0
|
|
||||||
MinimumVisualStudioVersion = 15.0.26124.0
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kav", "Kav.csproj", "{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Debug|x64 = Debug|x64
|
|
||||||
Debug|x86 = Debug|x86
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
Release|x64 = Release|x64
|
|
||||||
Release|x86 = Release|x86
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{34C1B784-AE9C-4EBC-A03A-AC401CB1219A}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
|
@ -1,18 +1,55 @@
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Kav
|
namespace Kav
|
||||||
{
|
{
|
||||||
public struct PointLight
|
public sealed class PointLight : IDisposable
|
||||||
{
|
{
|
||||||
public Vector3 Position { get; }
|
public Vector3 Position { get; }
|
||||||
public Color Color { get; }
|
public Color Color { get; }
|
||||||
public float Intensity { get; }
|
public float Radius { get; }
|
||||||
|
|
||||||
public PointLight(Vector3 position, Color color, float intensity = 1f)
|
public BoundingSphere BoundingSphere { get; }
|
||||||
{
|
|
||||||
|
public RenderTargetCube ShadowMap { get; }
|
||||||
|
|
||||||
|
public PointLight(
|
||||||
|
GraphicsDevice graphicsDevice,
|
||||||
|
Vector3 position,
|
||||||
|
Color color,
|
||||||
|
float radius,
|
||||||
|
int shadowMapSize
|
||||||
|
) {
|
||||||
Position = position;
|
Position = position;
|
||||||
Color = color;
|
Color = color;
|
||||||
Intensity = intensity;
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
|
|
||||||
namespace Kav
|
|
||||||
{
|
|
||||||
public struct SpotLight
|
|
||||||
{
|
|
||||||
public Vector3 Position { get; }
|
|
||||||
public Vector3 Direction { get; }
|
|
||||||
public Color Color { get; }
|
|
||||||
public float Intensity { get; }
|
|
||||||
public float Cutoff { get; }
|
|
||||||
|
|
||||||
public SpotLight(Vector3 position, Vector3 direction, Color color, float intensity, float cutoff)
|
|
||||||
{
|
|
||||||
Position = position;
|
|
||||||
Direction = direction;
|
|
||||||
Color = color;
|
|
||||||
Intensity = intensity;
|
|
||||||
Cutoff = cutoff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
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.
1179
Renderer.cs
1179
Renderer.cs
File diff suppressed because it is too large
Load Diff
78
Resources.cs
78
Resources.cs
|
@ -39,18 +39,6 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] DeferredPBR_SpotLightEffect
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (spotLightEffect == null)
|
|
||||||
{
|
|
||||||
spotLightEffect = GetResource("DeferredPBR_SpotLightEffect.fxb");
|
|
||||||
}
|
|
||||||
return spotLightEffect;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] DeferredPBR_GBufferEffect
|
public static byte[] DeferredPBR_GBufferEffect
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -123,6 +111,18 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] SimpleDepthEffectInstanced
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (simpleDepthEffectInstanced == null)
|
||||||
|
{
|
||||||
|
simpleDepthEffectInstanced = GetResource("SimpleDepthEffectInstanced.fxb");
|
||||||
|
}
|
||||||
|
return simpleDepthEffectInstanced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] LinearDepthEffect
|
public static byte[] LinearDepthEffect
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -135,6 +135,18 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] LinearDepthEffectInstanced
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (linearDepthEffectInstanced == null)
|
||||||
|
{
|
||||||
|
linearDepthEffectInstanced = GetResource("LinearDepthEffectInstanced.fxb");
|
||||||
|
}
|
||||||
|
return linearDepthEffectInstanced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] SkyboxEffect
|
public static byte[] SkyboxEffect
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -147,6 +159,30 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] DiffuseLitSpriteEffect
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (diffuseLitSpriteEffect == null)
|
||||||
|
{
|
||||||
|
diffuseLitSpriteEffect = GetResource("DiffuseLitSpriteEffect.fxb");
|
||||||
|
}
|
||||||
|
return diffuseLitSpriteEffect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] PaletteCrushEffect
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (paletteCrushEffect == null)
|
||||||
|
{
|
||||||
|
paletteCrushEffect = GetResource("PaletteCrushEffect.fxb");
|
||||||
|
}
|
||||||
|
return paletteCrushEffect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] UnitCubeModel
|
public static byte[] UnitCubeModel
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -159,20 +195,36 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] UnitSphereModel
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (unitSphereModel == null)
|
||||||
|
{
|
||||||
|
unitSphereModel = GetResource("UnitSphere.glb");
|
||||||
|
}
|
||||||
|
return unitSphereModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static byte[] ambientLightEffect;
|
private static byte[] ambientLightEffect;
|
||||||
private static byte[] pointLightEffect;
|
private static byte[] pointLightEffect;
|
||||||
private static byte[] directionalLightEffect;
|
private static byte[] directionalLightEffect;
|
||||||
private static byte[] spotLightEffect;
|
|
||||||
private static byte[] gBufferEffect;
|
private static byte[] gBufferEffect;
|
||||||
private static byte[] toneMapEffect;
|
private static byte[] toneMapEffect;
|
||||||
private static byte[] deferredToonEffect;
|
private static byte[] deferredToonEffect;
|
||||||
private static byte[] deferredPBREffect;
|
private static byte[] deferredPBREffect;
|
||||||
private static byte[] pbrEffect;
|
private static byte[] pbrEffect;
|
||||||
private static byte[] simpleDepthEffect;
|
private static byte[] simpleDepthEffect;
|
||||||
|
private static byte[] simpleDepthEffectInstanced;
|
||||||
private static byte[] linearDepthEffect;
|
private static byte[] linearDepthEffect;
|
||||||
|
private static byte[] linearDepthEffectInstanced;
|
||||||
private static byte[] skyboxEffect;
|
private static byte[] skyboxEffect;
|
||||||
|
private static byte[] diffuseLitSpriteEffect;
|
||||||
|
private static byte[] paletteCrushEffect;
|
||||||
|
|
||||||
private static byte[] unitCubeModel;
|
private static byte[] unitCubeModel;
|
||||||
|
private static byte[] unitSphereModel;
|
||||||
|
|
||||||
private static byte[] GetResource(string name)
|
private static byte[] GetResource(string name)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public static class VertexDeclarations
|
||||||
|
{
|
||||||
|
public static VertexDeclaration PositionInstanceDeclaration = new VertexDeclaration
|
||||||
|
(
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
public struct PositionTextureOffsetInstanceVertex : IVertexType
|
||||||
|
{
|
||||||
|
VertexDeclaration IVertexType.VertexDeclaration
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return VertexDeclarations.PositionTextureOffsetInstanceDeclaration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 Translation { get; set; }
|
||||||
|
public Vector2 UVOffset { get; set; }
|
||||||
|
|
||||||
|
public static readonly VertexDeclaration VertexDeclaration;
|
||||||
|
|
||||||
|
public PositionTextureOffsetInstanceVertex(
|
||||||
|
Vector3 translation,
|
||||||
|
Vector2 uvOffset
|
||||||
|
) {
|
||||||
|
Translation = translation;
|
||||||
|
UVOffset = uvOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue