decouple billboard constraints from meshsprite

palette_crush
cosmonaut 2020-12-08 15:29:28 -08:00
parent 1723f1dff8
commit 367e2795ae
2 changed files with 41 additions and 37 deletions

View File

@ -19,7 +19,6 @@ namespace Kav
public Texture2D Texture { get; } public Texture2D Texture { get; }
public Texture2D Normal { get; } public Texture2D Normal { get; }
public SpriteBillboardConstraint BillboardConstraint { get; }
public IndexBuffer IndexBuffer { get; } public IndexBuffer IndexBuffer { get; }
public VertexBuffer VertexBuffer { get; } public VertexBuffer VertexBuffer { get; }
@ -27,12 +26,10 @@ namespace Kav
public MeshSprite( public MeshSprite(
GraphicsDevice graphicsDevice, GraphicsDevice graphicsDevice,
Texture2D texture, Texture2D texture
SpriteBillboardConstraint billboardConstraint
) { ) {
Texture = texture; Texture = texture;
Normal = null; Normal = null;
BillboardConstraint = billboardConstraint;
IndexBuffer = new IndexBuffer( IndexBuffer = new IndexBuffer(
graphicsDevice, graphicsDevice,
@ -58,12 +55,10 @@ namespace Kav
public MeshSprite( public MeshSprite(
GraphicsDevice graphicsDevice, GraphicsDevice graphicsDevice,
Texture2D texture, Texture2D texture,
Texture2D normal, Texture2D normal
SpriteBillboardConstraint billboardConstraint
) { ) {
Texture = texture; Texture = texture;
Normal = normal; Normal = normal;
BillboardConstraint = billboardConstraint;
IndexBuffer = new IndexBuffer( IndexBuffer = new IndexBuffer(
graphicsDevice, graphicsDevice,

View File

@ -104,7 +104,7 @@ namespace Kav
public void MeshSpriteRender( public void MeshSpriteRender(
RenderTarget2D renderTarget, RenderTarget2D renderTarget,
PerspectiveCamera camera, PerspectiveCamera camera,
IEnumerable<(MeshSprite, Matrix)> meshSpriteTransforms, IEnumerable<(MeshSprite, SpriteBillboardConstraint, Matrix)> meshSpriteBillboardTransforms,
AmbientLight ambientLight, AmbientLight ambientLight,
IEnumerable<PointLight> pointLights, IEnumerable<PointLight> pointLights,
DirectionalLight? directionalLight DirectionalLight? directionalLight
@ -145,34 +145,11 @@ namespace Kav
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection); var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
foreach (var (sprite, transform) in FrustumCull(boundingFrustum, meshSpriteTransforms)) foreach (var (sprite, transform) in FrustumCull(boundingFrustum, BillboardTransforms(camera, meshSpriteBillboardTransforms)))
{ {
DiffuseLitSpriteEffect.NormalMapEnabled = sprite.Normal != null; DiffuseLitSpriteEffect.NormalMapEnabled = sprite.Normal != null;
if (sprite.BillboardConstraint == SpriteBillboardConstraint.None) DiffuseLitSpriteEffect.World = transform;
{
DiffuseLitSpriteEffect.World = transform;
}
else if (sprite.BillboardConstraint == SpriteBillboardConstraint.Horizontal)
{
DiffuseLitSpriteEffect.World = Matrix.CreateConstrainedBillboard(
transform.Translation,
camera.Position,
Vector3.Up,
camera.Forward,
camera.Position - transform.Translation
);
}
else
{
DiffuseLitSpriteEffect.World = Matrix.CreateConstrainedBillboard(
transform.Translation,
camera.Position,
Vector3.Up,
null,
null
);
}
GraphicsDevice.Textures[0] = sprite.Texture; GraphicsDevice.Textures[0] = sprite.Texture;
GraphicsDevice.Textures[1] = sprite.Normal; GraphicsDevice.Textures[1] = sprite.Normal;
@ -196,6 +173,39 @@ namespace Kav
} }
} }
private IEnumerable<(MeshSprite, Matrix)> BillboardTransforms(
PerspectiveCamera camera,
IEnumerable<(MeshSprite, SpriteBillboardConstraint, Matrix)> meshSpriteBillboardTransforms
) {
foreach (var (sprite, billboardConstraint, transform) in meshSpriteBillboardTransforms)
{
if (billboardConstraint == SpriteBillboardConstraint.None)
{
yield return (sprite, transform);
}
else if (billboardConstraint == SpriteBillboardConstraint.Horizontal)
{
yield return (sprite, Matrix.CreateConstrainedBillboard(
transform.Translation,
camera.Position,
Vector3.Up,
camera.Forward,
camera.Position - transform.Translation
));
}
else
{
yield return (sprite, Matrix.CreateConstrainedBillboard(
transform.Translation,
camera.Position,
Vector3.Up,
null,
null
));
}
}
}
// Renders a series of drawable-transform pairs using an effect that has a World matrix. // Renders a series of drawable-transform pairs using an effect that has a World matrix.
// Effect must be pre-configured!! // Effect must be pre-configured!!
public static void CullAndRenderIndexed<T, U>( public static void CullAndRenderIndexed<T, U>(
@ -243,7 +253,6 @@ namespace Kav
public static int FillAndSetBuffersForInstancing<T, V>( public static int FillAndSetBuffersForInstancing<T, V>(
GraphicsDevice graphicsDevice, GraphicsDevice graphicsDevice,
BoundingFrustum boundingFrustum,
T drawable, T drawable,
IEnumerable<Matrix> transforms, IEnumerable<Matrix> transforms,
V[] vertexData, V[] vertexData,
@ -251,7 +260,7 @@ namespace Kav
) where T : ICullable, IIndexDrawable where V : struct, IVertexType, IHasTranslation ) where T : ICullable, IIndexDrawable where V : struct, IVertexType, IHasTranslation
{ {
int numInstances = 0; int numInstances = 0;
foreach (var transform in FrustumCull(boundingFrustum, drawable, transforms)) foreach (var transform in transforms)
{ {
vertexData[numInstances].Translation = transform.Translation; vertexData[numInstances].Translation = transform.Translation;
numInstances += 1; numInstances += 1;
@ -385,13 +394,14 @@ namespace Kav
var numInstances = FillAndSetBuffersForInstancing( var numInstances = FillAndSetBuffersForInstancing(
GraphicsDevice, GraphicsDevice,
new BoundingFrustum(camera.View * camera.Projection),
drawable, drawable,
transforms, transforms,
PositionInstanceVertices, PositionInstanceVertices,
PositionInstanceVertexBuffer PositionInstanceVertexBuffer
); );
if (numInstances == 0) { return; }
RenderInstanced( RenderInstanced(
GraphicsDevice, GraphicsDevice,
drawable, drawable,
@ -738,7 +748,6 @@ namespace Kav
var numInstances = FillAndSetBuffersForInstancing( var numInstances = FillAndSetBuffersForInstancing(
GraphicsDevice, GraphicsDevice,
new BoundingFrustum(SimpleDepthEffectInstanced.View * SimpleDepthEffectInstanced.Projection),
drawable, drawable,
transforms, transforms,
PositionInstanceVertices, PositionInstanceVertices,