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

View File

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