Browse Source

point light sphere optimization

mesh_sprite_draw
cosmonaut 5 months ago
parent
commit
0060c22d72
9 changed files with 119 additions and 13 deletions
  1. +47
    -0
      Effects/DeferredPBR_PointLightEffect.cs
  2. BIN
      Effects/FXB/DeferredPBR_PointLightEffect.fxb
  3. +14
    -8
      Effects/HLSL/DeferredPBR_PointLightEffect.fx
  4. +3
    -0
      Kav.Core.csproj
  5. +3
    -0
      Kav.Framework.csproj
  6. +8
    -0
      Lights/PointLight.cs
  7. BIN
      Models/UnitSphere.glb
  8. +29
    -3
      Renderer.cs
  9. +13
    -0
      Resources.cs

+ 47
- 0
Effects/DeferredPBR_PointLightEffect.cs View File

@ -18,6 +18,8 @@ namespace Kav
EffectParameter farPlaneParam;
EffectParameter worldViewProjectionParam;
public Texture2D GPosition { get; set; }
public Texture2D GAlbedo { get; set; }
public Texture2D GNormal { get; set; }
@ -31,6 +33,42 @@ namespace Kav
public float FarPlane { get; set; }
Matrix world = Matrix.Identity;
Matrix view = Matrix.Identity;
Matrix projection = Matrix.Identity;
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
public Matrix World
{
get { return world; }
set
{
world = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
}
}
public Matrix View
{
get { return view; }
set
{
view = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
}
}
public Matrix Projection
{
get { return projection; }
set
{
projection = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
}
}
public DeferredPBR_PointLightEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_PointLightEffect)
{
CacheEffectParameters();
@ -73,6 +111,13 @@ namespace Kav
pointLightColorParam.SetValue(PointLightColor);
farPlaneParam.SetValue(FarPlane);
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
{
worldViewProjectionParam.SetValue(world * view * projection);
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
}
}
void CacheEffectParameters()
@ -89,6 +134,8 @@ namespace Kav
pointLightColorParam = Parameters["PointLightColor"];
farPlaneParam = Parameters["FarPlane"];
worldViewProjectionParam = Parameters["WorldViewProjection"];
}
}
}

BIN
Effects/FXB/DeferredPBR_PointLightEffect.fxb (Stored with Git LFS) View File

size 4076

+ 14
- 8
Effects/HLSL/DeferredPBR_PointLightEffect.fx View File

@ -1,3 +1,5 @@
// Assumes you are drawing a sphere!!
#include "Macros.fxh" //from FNA
#include "Lighting.fxh"
#include "Shadow.fxh"
@ -19,26 +21,27 @@ BEGIN_CONSTANTS
MATRIX_CONSTANTS
float4x4 WorldViewProjection _vs(c0) _cb(c4);
END_CONSTANTS
struct VertexInput
{
float4 Position : POSITION;
float2 TexCoord : TEXCOORD;
};
struct PixelInput
{
float4 Position : SV_POSITION;
float2 TexCoord : TEXCOORD0;
float4 ScreenPosition : TEXCOORD0;
};
PixelInput main_vs(VertexInput input)
{
PixelInput output;
output.Position = input.Position;
output.TexCoord = input.TexCoord;
output.Position = mul(input.Position, WorldViewProjection);
output.ScreenPosition = output.Position;
return output;
}
@ -73,10 +76,13 @@ float4 ComputeColor(
float4 main_ps(PixelInput input) : SV_TARGET0
{
float3 worldPosition = SAMPLE_TEXTURE(gPosition, input.TexCoord).rgb;
float3 normal = SAMPLE_TEXTURE(gNormal, input.TexCoord).xyz;
float3 albedo = SAMPLE_TEXTURE(gAlbedo, input.TexCoord).rgb;
float2 metallicRoughness = SAMPLE_TEXTURE(gMetallicRoughness, input.TexCoord).rg;
input.ScreenPosition.xy /= input.ScreenPosition.w;
float2 texCoord = 0.5f * float2(input.ScreenPosition.x,-input.ScreenPosition.y) + 0.5f;
float3 worldPosition = SAMPLE_TEXTURE(gPosition, texCoord).rgb;
float3 normal = SAMPLE_TEXTURE(gNormal, texCoord).xyz;
float3 albedo = SAMPLE_TEXTURE(gAlbedo, texCoord).rgb;
float2 metallicRoughness = SAMPLE_TEXTURE(gMetallicRoughness, texCoord).rg;
return ComputeColor(
worldPosition,


+ 3
- 0
Kav.Core.csproj View File

@ -64,6 +64,9 @@
<EmbeddedResource Include="Models\UnitCube.glb">
<LogicalName>Kav.Resources.UnitCube.glb</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="Models\UnitSphere.glb">
<LogicalName>Kav.Resources.UnitSphere.glb</LogicalName>
</EmbeddedResource>
</ItemGroup>
</Project>

+ 3
- 0
Kav.Framework.csproj View File

@ -64,6 +64,9 @@
<EmbeddedResource Include="Models\UnitCube.glb">
<LogicalName>Kav.Resources.UnitCube.glb</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="Models\UnitSphere.glb">
<LogicalName>Kav.Resources.UnitSphere.glb</LogicalName>
</EmbeddedResource>
</ItemGroup>
</Project>

+ 8
- 0
Lights/PointLight.cs View File

@ -4,15 +4,23 @@ namespace Kav
{
public struct PointLight
{
public static double ATTENUATION_EPSILON = 0.1;
public Vector3 Position { get; }
public Color Color { get; }
public float Intensity { get; }
public float EffectiveRadius { get; }
public BoundingSphere BoundingSphere { get; }
public PointLight(Vector3 position, Color color, float intensity = 1f)
{
Position = position;
Color = color;
Intensity = intensity;
EffectiveRadius = (float) System.Math.Sqrt(Intensity);
BoundingSphere = new BoundingSphere(position, EffectiveRadius);
}
}
}

BIN
Models/UnitSphere.glb View File


+ 29
- 3
Renderer.cs View File

@ -26,8 +26,9 @@ namespace Kav
private Effect ToneMapEffect { get; }
private SkyboxEffect SkyboxEffect { get; }
private DiffuseLitSpriteEffect DiffuseLitSpriteEffect { get; }
private Kav.Model UnitCube { get; }
private Kav.Model UnitSphere { get; }
public Renderer(
GraphicsDevice graphicsDevice
@ -61,6 +62,11 @@ namespace Kav
GraphicsDevice,
Smuggler.Importer.ImportGLB(GraphicsDevice, new MemoryStream(Resources.UnitCubeModel))
);
UnitSphere = Kav.ModelLoader.Load(
graphicsDevice,
Smuggler.Importer.ImportGLB(graphicsDevice, new MemoryStream(Resources.UnitSphereModel))
);
}
public static (T[], DynamicVertexBuffer) CreateInstanceVertexBuffer<T>(
@ -461,7 +467,16 @@ namespace Kav
PointLight pointLight
) {
GraphicsDevice.SetRenderTarget(renderTarget);
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
if (Vector3.Distance(camera.Position, pointLight.Position) < pointLight.EffectiveRadius)
{
GraphicsDevice.RasterizerState = RasterizerState.CullClockwise;
}
else
{
GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
}
GraphicsDevice.DepthStencilState = DepthStencilState.None;
GraphicsDevice.BlendState = BlendState.Additive;
DeferredPointLightEffect.GPosition = gPosition;
@ -478,7 +493,17 @@ namespace Kav
DeferredPointLightEffect.FarPlane = 25f; // FIXME: magic value
RenderFullscreenEffect(DeferredPointLightEffect);
DeferredPointLightEffect.World =
Matrix.CreateScale(pointLight.EffectiveRadius) *
Matrix.CreateTranslation(pointLight.Position);
DeferredPointLightEffect.View = camera.View;
DeferredPointLightEffect.Projection = camera.Projection;
RenderIndexed(
GraphicsDevice,
UnitSphere.Meshes[0].MeshParts[0],
DeferredPointLightEffect
);
}
public void RenderDirectionalLight(
@ -492,6 +517,7 @@ namespace Kav
DirectionalLight directionalLight
) {
GraphicsDevice.SetRenderTarget(renderTarget);
GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
GraphicsDevice.BlendState = BlendState.Additive;


+ 13
- 0
Resources.cs View File

@ -195,6 +195,18 @@ namespace Kav
}
}
public static byte[] UnitSphereModel
{
get
{
if (unitSphereModel == null)
{
unitSphereModel = GetResource("UnitSphere.glb");
}
return unitSphereModel;
}
}
private static byte[] ambientLightEffect;
private static byte[] pointLightEffect;
private static byte[] directionalLightEffect;
@ -212,6 +224,7 @@ namespace Kav
private static byte[] paletteCrushEffect;
private static byte[] unitCubeModel;
private static byte[] unitSphereModel;
private static byte[] GetResource(string name)
{


Loading…
Cancel
Save