Support lighting using a graphics buffer that is kep open!
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,13 @@
|
||||
#ifndef ROOT_CONSTANTS_HLSL
|
||||
#define ROOT_CONSTANTS_HLSL
|
||||
|
||||
struct PointLight
|
||||
{
|
||||
float3 Position;
|
||||
float Radius;
|
||||
float3 Color;
|
||||
float Intensity;
|
||||
};
|
||||
|
||||
cbuffer RootConstants : register(b0, space0)
|
||||
{
|
||||
@@ -16,6 +24,9 @@ cbuffer RootConstants : register(b0, space0)
|
||||
float LightPad;
|
||||
float3 LightColor;
|
||||
float AmbientIntensity;
|
||||
|
||||
uint LightBufferIndex;
|
||||
uint ActiveLightCount;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,46 @@
|
||||
#include "RootConstants.hlsl"
|
||||
|
||||
float4 main(float4 Color : TEXCOORD0, float3 WorldNormal : TEXCOORD1) : SV_Target0
|
||||
struct Input
|
||||
{
|
||||
float3 N = normalize(WorldNormal);
|
||||
float NdotL = saturate(dot(N, -LightDirection));
|
||||
float3 diffuse = Color.rgb * LightColor * NdotL;
|
||||
float3 ambient = Color.rgb * AmbientIntensity;
|
||||
return float4(diffuse + ambient, Color.a);
|
||||
float4 Color : TEXCOORD0;
|
||||
float3 WorldNormal : TEXCOORD1;
|
||||
float3 WorldPosition : TEXCOORD2;
|
||||
};
|
||||
|
||||
float4 main(Input input) : SV_Target0
|
||||
{
|
||||
float3 normal = normalize(input.WorldNormal);
|
||||
|
||||
// Initial ambient component
|
||||
float3 result = input.Color.rgb * LightColor * AmbientIntensity;
|
||||
|
||||
// Directional light contribution
|
||||
float ndotl = max(dot(normal, -LightDirection), 0.0);
|
||||
result += input.Color.rgb * LightColor * ndotl;
|
||||
|
||||
// Point lights
|
||||
if (ActiveLightCount > 0)
|
||||
{
|
||||
StructuredBuffer<PointLight> pointLights = ResourceDescriptorHeap[LightBufferIndex];
|
||||
|
||||
for (uint i = 0; i < ActiveLightCount; ++i)
|
||||
{
|
||||
PointLight light = pointLights[i];
|
||||
|
||||
float3 lightDir = light.Position - input.WorldPosition;
|
||||
float dist = length(lightDir);
|
||||
|
||||
if (dist < light.Radius)
|
||||
{
|
||||
lightDir = normalize(lightDir);
|
||||
float attenuation = 1.0 - (dist / light.Radius);
|
||||
attenuation = max(attenuation, 0.0);
|
||||
|
||||
float pndotl = max(dot(normal, lightDir), 0.0);
|
||||
result += light.Color * input.Color.rgb * pndotl * attenuation * light.Intensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return float4(result, input.Color.a);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ struct Output
|
||||
{
|
||||
float4 Color : TEXCOORD0;
|
||||
float3 WorldNormal : TEXCOORD1;
|
||||
float3 WorldPosition : TEXCOORD2;
|
||||
float4 Position : SV_Position;
|
||||
};
|
||||
|
||||
@@ -20,8 +21,10 @@ Output main(uint vertexIndex : SV_VertexID)
|
||||
float3 normal = asfloat(buffer.Load3(offset + 12));
|
||||
float4 col = asfloat(buffer.Load4(offset + 24));
|
||||
|
||||
output.Position = mul(ViewProjection, mul(Model, float4(pos, 1.0f)));
|
||||
float4 worldPos = mul(Model, float4(pos, 1.0f));
|
||||
output.Position = mul(ViewProjection, worldPos);
|
||||
output.Color = col;
|
||||
output.WorldPosition = worldPos.xyz;
|
||||
|
||||
float3 worldNormal = mul((float3x3)Model, normal);
|
||||
output.WorldNormal = worldNormal;
|
||||
|
||||
Reference in New Issue
Block a user