batched billboard implementation
parent
d83aacd57f
commit
acaafdcdcd
|
@ -0,0 +1,39 @@
|
|||
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 Sprite(
|
||||
Texture2D texture,
|
||||
Vector3 position,
|
||||
Vector2 origin,
|
||||
float rotation,
|
||||
Vector2 scale
|
||||
) {
|
||||
Texture = texture;
|
||||
Position = position;
|
||||
Origin = origin;
|
||||
Rotation = rotation;
|
||||
Scale = scale;
|
||||
}
|
||||
|
||||
public Sprite(
|
||||
Texture2D texture,
|
||||
Vector3 position
|
||||
) {
|
||||
Texture = texture;
|
||||
Position = position;
|
||||
Origin = Vector2.Zero;
|
||||
Rotation = 0f;
|
||||
Scale = Vector2.One;
|
||||
}
|
||||
}
|
||||
}
|
57
Renderer.cs
57
Renderer.cs
|
@ -33,6 +33,7 @@ namespace Kav
|
|||
private LinearDepthEffect LinearDepthEffect { get; }
|
||||
private Effect ToneMapEffect { get; }
|
||||
private SkyboxEffect SkyboxEffect { get; }
|
||||
private BasicEffect BasicEffect { get; }
|
||||
|
||||
private RenderTarget2D gPosition { get; }
|
||||
private RenderTarget2D gNormal { get; }
|
||||
|
@ -159,6 +160,7 @@ namespace Kav
|
|||
ToneMapEffect = new Effect(graphicsDevice, Resources.ToneMapEffect);
|
||||
Deferred_ToonEffect = new Deferred_ToonEffect(GraphicsDevice);
|
||||
SkyboxEffect = new SkyboxEffect(GraphicsDevice);
|
||||
BasicEffect = new BasicEffect(GraphicsDevice);
|
||||
|
||||
FullscreenTriangle = new VertexBuffer(GraphicsDevice, typeof(VertexPositionTexture), 3, BufferUsage.WriteOnly);
|
||||
FullscreenTriangle.SetData(new VertexPositionTexture[3] {
|
||||
|
@ -206,6 +208,7 @@ namespace Kav
|
|||
}
|
||||
|
||||
public void DeferredToonRender(
|
||||
RenderTarget2D renderTarget,
|
||||
PerspectiveCamera camera,
|
||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||
AmbientLight ambientLight,
|
||||
|
@ -230,12 +233,64 @@ namespace Kav
|
|||
DirectionalLightToonRender(camera, modelTransforms, directionalLight);
|
||||
SkyboxRender(camera, skybox);
|
||||
|
||||
GraphicsDevice.SetRenderTarget(null);
|
||||
GraphicsDevice.SetRenderTarget(renderTarget);
|
||||
SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, null);
|
||||
SpriteBatch.Draw(ColorRenderTarget, Vector2.Zero, Color.White);
|
||||
SpriteBatch.End();
|
||||
}
|
||||
|
||||
// billboards sprites into the scene
|
||||
// FIXME: we can frustum cull the sprites probably
|
||||
public void BillboardSpriteRender(
|
||||
RenderTarget2D renderTarget,
|
||||
PerspectiveCamera camera,
|
||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
||||
IEnumerable<Sprite> sprites
|
||||
) {
|
||||
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
||||
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1f, 0);
|
||||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||
|
||||
DepthRender(camera, modelTransforms);
|
||||
GraphicsDevice.Clear(ClearOptions.Target, new Color(0, 0, 0, 0), 1f, 0);
|
||||
|
||||
Matrix invertY = Matrix.CreateScale(1, -1, 1);
|
||||
|
||||
BasicEffect.World = invertY;
|
||||
BasicEffect.View = Matrix.Identity;
|
||||
BasicEffect.Projection = camera.Projection;
|
||||
BasicEffect.TextureEnabled = true;
|
||||
BasicEffect.VertexColorEnabled = true;
|
||||
|
||||
SpriteBatch.Begin(0, null, null, DepthStencilState.DepthRead, RasterizerState.CullNone, BasicEffect);
|
||||
|
||||
foreach (var sprite in sprites)
|
||||
{
|
||||
// transform view space on CPU so we don't have to break the batch
|
||||
Vector3 viewSpacePosition = Vector3.Transform(sprite.Position, camera.View * Matrix.CreateRotationX(sprite.Rotation) * invertY);
|
||||
|
||||
SpriteBatch.Draw(
|
||||
sprite.Texture,
|
||||
new Vector2(viewSpacePosition.X, viewSpacePosition.Y),
|
||||
null,
|
||||
Color.White,
|
||||
0,
|
||||
sprite.Origin,
|
||||
sprite.Scale / new Vector2(sprite.Texture.Width, sprite.Texture.Height),
|
||||
0,
|
||||
viewSpacePosition.Z
|
||||
);
|
||||
}
|
||||
|
||||
SpriteBatch.End();
|
||||
|
||||
GraphicsDevice.SetRenderTarget(renderTarget);
|
||||
GraphicsDevice.Clear(new Color(0, 0, 0, 0));
|
||||
SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null);
|
||||
SpriteBatch.Draw(ColorRenderTarget, Vector2.Zero, Color.White);
|
||||
SpriteBatch.End();
|
||||
}
|
||||
|
||||
private void DepthRender(
|
||||
PerspectiveCamera camera,
|
||||
IEnumerable<(Model, Matrix)> modelTransforms
|
||||
|
|
Loading…
Reference in New Issue