implement different kinds of billboarding
parent
665ff6dd44
commit
ae445d94d3
|
@ -16,8 +16,15 @@ namespace Kav
|
||||||
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;
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public enum SpriteBillboardConstraint
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Horizontal,
|
||||||
|
Full
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,30 +10,48 @@ namespace Kav
|
||||||
public Vector2 Origin { get; }
|
public Vector2 Origin { get; }
|
||||||
public float Rotation { get; }
|
public float Rotation { get; }
|
||||||
public Vector2 Scale { get; }
|
public Vector2 Scale { get; }
|
||||||
|
public SpriteBillboardConstraint BillboardConstraint { get; }
|
||||||
|
|
||||||
|
public Matrix TransformMatrix { get; }
|
||||||
|
|
||||||
public Sprite(
|
public Sprite(
|
||||||
Texture2D texture,
|
Texture2D texture,
|
||||||
Vector3 position,
|
Vector3 position,
|
||||||
Vector2 origin,
|
Vector2 origin,
|
||||||
float rotation,
|
float rotation,
|
||||||
Vector2 scale
|
Vector2 scale,
|
||||||
|
SpriteBillboardConstraint billboardConstraint = SpriteBillboardConstraint.None
|
||||||
) {
|
) {
|
||||||
Texture = texture;
|
Texture = texture;
|
||||||
Position = position;
|
Position = position;
|
||||||
Origin = origin;
|
Origin = origin;
|
||||||
Rotation = rotation;
|
Rotation = rotation;
|
||||||
Scale = scale;
|
Scale = scale;
|
||||||
|
BillboardConstraint = billboardConstraint;
|
||||||
|
TransformMatrix = ConstructTransformMatrix(Position, Scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sprite(
|
public Sprite(
|
||||||
Texture2D texture,
|
Texture2D texture,
|
||||||
Vector3 position
|
Vector3 position,
|
||||||
|
SpriteBillboardConstraint billboardConstraint = SpriteBillboardConstraint.None
|
||||||
) {
|
) {
|
||||||
Texture = texture;
|
Texture = texture;
|
||||||
Position = position;
|
Position = position;
|
||||||
Origin = Vector2.Zero;
|
Origin = Vector2.Zero;
|
||||||
Rotation = 0f;
|
Rotation = 0;
|
||||||
Scale = Vector2.One;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
54
Renderer.cs
54
Renderer.cs
|
@ -254,35 +254,53 @@ namespace Kav
|
||||||
DepthRender(camera, modelTransforms);
|
DepthRender(camera, modelTransforms);
|
||||||
GraphicsDevice.Clear(ClearOptions.Target, new Color(0, 0, 0, 0), 1f, 0);
|
GraphicsDevice.Clear(ClearOptions.Target, new Color(0, 0, 0, 0), 1f, 0);
|
||||||
|
|
||||||
Matrix invertY = Matrix.CreateScale(1, -1, 1);
|
BasicEffect.View = camera.View;
|
||||||
|
|
||||||
BasicEffect.World = invertY;
|
|
||||||
BasicEffect.View = Matrix.Identity;
|
|
||||||
BasicEffect.Projection = camera.Projection;
|
BasicEffect.Projection = camera.Projection;
|
||||||
BasicEffect.TextureEnabled = true;
|
BasicEffect.TextureEnabled = true;
|
||||||
BasicEffect.VertexColorEnabled = true;
|
BasicEffect.VertexColorEnabled = true;
|
||||||
|
|
||||||
SpriteBatch.Begin(0, null, null, DepthStencilState.DepthRead, RasterizerState.CullNone, BasicEffect);
|
|
||||||
|
|
||||||
foreach (var sprite in sprites)
|
foreach (var sprite in sprites)
|
||||||
{
|
{
|
||||||
// transform view space on CPU so we don't have to break the batch
|
if (sprite.BillboardConstraint == SpriteBillboardConstraint.None)
|
||||||
Vector3 viewSpacePosition = Vector3.Transform(sprite.Position, camera.View * invertY);
|
{
|
||||||
|
BasicEffect.World = sprite.TransformMatrix;
|
||||||
SpriteBatch.Draw(
|
}
|
||||||
sprite.Texture,
|
else if (sprite.BillboardConstraint == SpriteBillboardConstraint.Horizontal)
|
||||||
new Vector2(viewSpacePosition.X, viewSpacePosition.Y),
|
{
|
||||||
|
BasicEffect.World = Matrix.CreateConstrainedBillboard(
|
||||||
|
sprite.Position,
|
||||||
|
camera.Position,
|
||||||
|
Vector3.Up,
|
||||||
|
camera.Forward,
|
||||||
|
camera.Position - sprite.Position
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BasicEffect.World = Matrix.CreateConstrainedBillboard(
|
||||||
|
sprite.Position,
|
||||||
|
camera.Position,
|
||||||
|
Vector3.Up,
|
||||||
null,
|
null,
|
||||||
Color.White,
|
null
|
||||||
0,
|
|
||||||
sprite.Origin,
|
|
||||||
sprite.Scale / new Vector2(sprite.Texture.Width, sprite.Texture.Height),
|
|
||||||
0,
|
|
||||||
viewSpacePosition.Z
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpriteBatch.Begin(0, null, null, DepthStencilState.DepthRead, RasterizerState.CullNone, BasicEffect);
|
||||||
|
SpriteBatch.Draw(
|
||||||
|
sprite.Texture,
|
||||||
|
Vector2.Zero,
|
||||||
|
null,
|
||||||
|
Color.White,
|
||||||
|
sprite.Rotation,
|
||||||
|
sprite.Origin,
|
||||||
|
sprite.Scale / new Vector2(sprite.Texture.Width, -sprite.Texture.Height),
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
SpriteBatch.End();
|
SpriteBatch.End();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GraphicsDevice.SetRenderTarget(renderTarget);
|
GraphicsDevice.SetRenderTarget(renderTarget);
|
||||||
GraphicsDevice.Clear(new Color(0, 0, 0, 0));
|
GraphicsDevice.Clear(new Color(0, 0, 0, 0));
|
||||||
|
|
Loading…
Reference in New Issue