draw zero alpha pixels in g buffer
parent
c468d6276d
commit
3a0aa8894d
|
@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
namespace Kav.Data
|
namespace Kav.Data
|
||||||
{
|
{
|
||||||
public struct MeshSpriteDrawData
|
public struct MeshSpriteDrawData : IIndexDrawable, ICullable, ITransformable
|
||||||
{
|
{
|
||||||
public SpriteMesh MeshSprite { get; }
|
public SpriteMesh MeshSprite { get; }
|
||||||
public Texture2D Texture { get; }
|
public Texture2D Texture { get; }
|
||||||
|
@ -12,6 +12,10 @@ namespace Kav.Data
|
||||||
public Matrix TransformMatrix { get; }
|
public Matrix TransformMatrix { get; }
|
||||||
public UVData UVOffset { get; }
|
public UVData UVOffset { get; }
|
||||||
|
|
||||||
|
public IndexBuffer IndexBuffer => MeshSprite.IndexBuffer;
|
||||||
|
public VertexBuffer VertexBuffer => MeshSprite.VertexBuffer;
|
||||||
|
public BoundingBox BoundingBox => MeshSprite.BoundingBox;
|
||||||
|
|
||||||
public MeshSpriteDrawData(
|
public MeshSpriteDrawData(
|
||||||
SpriteMesh meshSprite,
|
SpriteMesh meshSprite,
|
||||||
Texture2D texture,
|
Texture2D texture,
|
||||||
|
|
|
@ -16,6 +16,8 @@ namespace Kav
|
||||||
EffectParameter metallicParam;
|
EffectParameter metallicParam;
|
||||||
EffectParameter roughnessParam;
|
EffectParameter roughnessParam;
|
||||||
|
|
||||||
|
EffectParameter uvOffsetAndDimensionsParam;
|
||||||
|
|
||||||
EffectParameter numTextureRowsParam;
|
EffectParameter numTextureRowsParam;
|
||||||
EffectParameter numTextureColumnsParam;
|
EffectParameter numTextureColumnsParam;
|
||||||
|
|
||||||
|
@ -30,6 +32,9 @@ namespace Kav
|
||||||
float metallic;
|
float metallic;
|
||||||
float roughness;
|
float roughness;
|
||||||
|
|
||||||
|
Vector2 uvOffset;
|
||||||
|
Vector2 subTextureDimensions;
|
||||||
|
|
||||||
int numTextureRows = 1;
|
int numTextureRows = 1;
|
||||||
int numTextureColumns = 1;
|
int numTextureColumns = 1;
|
||||||
|
|
||||||
|
@ -153,6 +158,26 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 HardwareInstancingEnabled
|
public bool HardwareInstancingEnabled
|
||||||
{
|
{
|
||||||
get { return hardwareInstancingEnabled; }
|
get { return hardwareInstancingEnabled; }
|
||||||
|
@ -210,6 +235,16 @@ namespace Kav
|
||||||
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((dirtyFlags & EffectDirtyFlags.UVOrDimensions) != 0)
|
||||||
|
{
|
||||||
|
uvOffsetAndDimensionsParam.SetValue(new Vector4(
|
||||||
|
UVOffset.X, UVOffset.Y,
|
||||||
|
SubTextureDimensions.X, SubTextureDimensions.Y
|
||||||
|
));
|
||||||
|
|
||||||
|
dirtyFlags &= ~EffectDirtyFlags.UVOrDimensions;
|
||||||
|
}
|
||||||
|
|
||||||
if ((dirtyFlags & EffectDirtyFlags.VertexShaderIndex) != 0)
|
if ((dirtyFlags & EffectDirtyFlags.VertexShaderIndex) != 0)
|
||||||
{
|
{
|
||||||
int vertexShaderIndex = 0;
|
int vertexShaderIndex = 0;
|
||||||
|
@ -277,6 +312,8 @@ namespace Kav
|
||||||
numTextureRowsParam = Parameters["NumTextureRows"];
|
numTextureRowsParam = Parameters["NumTextureRows"];
|
||||||
numTextureColumnsParam = Parameters["NumTextureColumns"];
|
numTextureColumnsParam = Parameters["NumTextureColumns"];
|
||||||
|
|
||||||
|
uvOffsetAndDimensionsParam = Parameters["UVOffsetAndDimensions"];
|
||||||
|
|
||||||
shaderIndexParam = Parameters["PixelShaderIndex"];
|
shaderIndexParam = Parameters["PixelShaderIndex"];
|
||||||
vertexShaderIndexParam = Parameters["VertexShaderIndex"];
|
vertexShaderIndexParam = Parameters["VertexShaderIndex"];
|
||||||
}
|
}
|
||||||
|
|
BIN
Effects/FXB/DeferredPBR_GBufferEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/DeferredPBR_GBufferEffect.fxb (Stored with Git LFS)
Binary file not shown.
|
@ -4,6 +4,8 @@ DECLARE_TEXTURE(AlbedoTexture, 0);
|
||||||
DECLARE_TEXTURE(NormalTexture, 1);
|
DECLARE_TEXTURE(NormalTexture, 1);
|
||||||
DECLARE_TEXTURE(MetallicRoughnessTexture, 2);
|
DECLARE_TEXTURE(MetallicRoughnessTexture, 2);
|
||||||
|
|
||||||
|
float4 UVOffsetAndDimensions;
|
||||||
|
|
||||||
BEGIN_CONSTANTS
|
BEGIN_CONSTANTS
|
||||||
|
|
||||||
float3 AlbedoValue _ps(c0) _cb(c0);
|
float3 AlbedoValue _ps(c0) _cb(c0);
|
||||||
|
@ -51,7 +53,11 @@ PixelInput main_vs(VertexInput input)
|
||||||
|
|
||||||
output.PositionWorld = mul(input.Position, World).xyz;
|
output.PositionWorld = mul(input.Position, World).xyz;
|
||||||
output.NormalWorld = normalize(mul(input.Normal, World));
|
output.NormalWorld = normalize(mul(input.Normal, World));
|
||||||
output.TexCoord = input.TexCoord;
|
|
||||||
|
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);
|
float4x4 worldViewProjection = mul(World, ViewProjection);
|
||||||
output.Position = mul(input.Position, worldViewProjection);
|
output.Position = mul(input.Position, worldViewProjection);
|
||||||
|
@ -129,6 +135,8 @@ PixelOutput AlbedoPS(PixelInput input)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,6 +173,8 @@ PixelOutput AlbedoMetallicRoughnessPS(PixelInput input)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,6 +187,8 @@ PixelOutput AlbedoNormalPS(PixelInput input)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +213,8 @@ PixelOutput AlbedoMetallicRoughnessNormalMapPS(PixelInput input)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface ITransformable
|
||||||
|
{
|
||||||
|
Matrix TransformMatrix { get; }
|
||||||
|
}
|
||||||
|
}
|
57
Renderer.cs
57
Renderer.cs
|
@ -196,6 +196,48 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RenderMeshSpriteGBuffer(
|
||||||
|
RenderTargetBinding[] gBuffer,
|
||||||
|
PerspectiveCamera camera,
|
||||||
|
IEnumerable<MeshSpriteDrawData> meshSpriteDrawDatas
|
||||||
|
) {
|
||||||
|
GraphicsDevice.SetRenderTargets(gBuffer);
|
||||||
|
GraphicsDevice.RasterizerState = RasterizerState.CullNone;
|
||||||
|
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||||
|
GraphicsDevice.BlendState = BlendState.AlphaBlend;
|
||||||
|
|
||||||
|
Deferred_GBufferEffect.HardwareInstancingEnabled = false;
|
||||||
|
Deferred_GBufferEffect.View = camera.View;
|
||||||
|
Deferred_GBufferEffect.Projection = camera.Projection;
|
||||||
|
|
||||||
|
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
|
||||||
|
|
||||||
|
foreach (var data in meshSpriteDrawDatas)
|
||||||
|
{
|
||||||
|
var matrix = BillboardTransforms(camera, data.TransformMatrix, data.BillboardConstraint);
|
||||||
|
|
||||||
|
if (FrustumCull(boundingFrustum, data.MeshSprite, matrix))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Deferred_GBufferEffect.World = matrix;
|
||||||
|
|
||||||
|
Deferred_GBufferEffect.UVOffset = data.UVOffset.Offset;
|
||||||
|
Deferred_GBufferEffect.SubTextureDimensions = data.UVOffset.Percentage;
|
||||||
|
|
||||||
|
Deferred_GBufferEffect.Albedo = Color.White.ToVector3();
|
||||||
|
Deferred_GBufferEffect.Metallic = 0f;
|
||||||
|
Deferred_GBufferEffect.Roughness = 1f;
|
||||||
|
|
||||||
|
Deferred_GBufferEffect.AlbedoTexture = data.Texture;
|
||||||
|
Deferred_GBufferEffect.NormalTexture = data.Normal;
|
||||||
|
Deferred_GBufferEffect.MetallicRoughnessTexture = null;
|
||||||
|
|
||||||
|
RenderIndexed(GraphicsDevice, data, Deferred_GBufferEffect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Matrix BillboardTransforms(
|
private static Matrix BillboardTransforms(
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
Matrix transform,
|
Matrix transform,
|
||||||
|
@ -942,6 +984,21 @@ namespace Kav
|
||||||
return (containment == ContainmentType.Disjoint);
|
return (containment == ContainmentType.Disjoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<T> FrustumCull<T>(
|
||||||
|
BoundingFrustum boundingFrustum,
|
||||||
|
IEnumerable<T> cullableTransformables
|
||||||
|
) where T : ICullable, ITransformable {
|
||||||
|
foreach (var cullableTransformable in cullableTransformables)
|
||||||
|
{
|
||||||
|
var boundingBox = TransformedBoundingBox(cullableTransformable.BoundingBox, cullableTransformable.TransformMatrix);
|
||||||
|
var containment = boundingFrustum.Contains(boundingBox);
|
||||||
|
if (containment != ContainmentType.Disjoint)
|
||||||
|
{
|
||||||
|
yield return cullableTransformable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static BoundingBox TransformedBoundingBox(BoundingBox boundingBox, Matrix matrix)
|
private static BoundingBox TransformedBoundingBox(BoundingBox boundingBox, Matrix matrix)
|
||||||
{
|
{
|
||||||
var center = (boundingBox.Min + boundingBox.Max) / 2f;
|
var center = (boundingBox.Min + boundingBox.Max) / 2f;
|
||||||
|
|
Loading…
Reference in New Issue