HD lights rendering in interiors

This commit is contained in:
dexy
2019-12-05 03:40:52 +11:00
Unverified
parent f333e64812
commit c6aa4c7baf
15 changed files with 412 additions and 87 deletions
@@ -434,6 +434,16 @@
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4.0</ShaderModel>
</FxCompile>
<FxCompile Include="LightPS_MS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">4.1</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.1</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.1</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4.1</ShaderModel>
</FxCompile>
<FxCompile Include="LightVS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Vertex</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">4.0</ShaderModel>
@@ -268,6 +268,9 @@
<FxCompile Include="LodLightsPS_MS.hlsl">
<Filter>Lights</Filter>
</FxCompile>
<FxCompile Include="LightPS_MS.hlsl">
<Filter>Lights</Filter>
</FxCompile>
</ItemGroup>
<ItemGroup>
<None Include="BasicPS.hlsli">
+3 -32
View File
@@ -1,9 +1,6 @@
#include "LightPS.hlsli"
//currently unused - TODO: implement individual HD lights here
Texture2D DepthTex : register(t0);
Texture2D DiffuseTex : register(t2);
Texture2D NormalTex : register(t3);
@@ -14,11 +11,10 @@ struct VS_Output
{
float4 Pos : SV_POSITION;
float4 Screen : TEXCOORD0;
uint IID : SV_INSTANCEID;
};
PS_OUTPUT main(VS_Output input)
float4 main(VS_Output input) : SV_TARGET
{
uint3 ssloc = uint3(input.Pos.xy, 0); //pixel location
float depth = DepthTex.Load(ssloc).r;
@@ -29,39 +25,14 @@ PS_OUTPUT main(VS_Output input)
float4 specular = SpecularTex.Load(ssloc);
float4 irradiance = IrradianceTex.Load(ssloc);
PS_OUTPUT output;
output.Depth = input.Pos.z;
switch (RenderMode)
{
case 5: output.Colour = float4(diffuse.rgb, 1); return output;
case 6: output.Colour = float4(normal.rgb, 1); return output;
case 7: output.Colour = float4(specular.rgb, 1); return output;
}
float4 spos = float4(input.Screen.xy/input.Screen.w, depth, 1);
float4 cpos = mul(spos, ViewProjInv);
float3 camRel = cpos.xyz * (1/cpos.w);
float3 norm = normal.xyz * 2 - 1;
if (LightType == 0) //directional light
{
float3 c = DeferredDirectionalLight(camRel, norm, diffuse, specular, irradiance);
PS_OUTPUT output;
output.Colour = float4(c, 1);
output.Depth = depth;
return output;
}
float4 lcol = DeferredLODLight(camRel, norm, diffuse, specular, irradiance, input.IID);
float4 lcol = DeferredLight(camRel, norm, diffuse, specular, irradiance);
if (lcol.a <= 0) discard;
output.Colour = lcol;
return output;
return lcol;
}
+65 -3
View File
@@ -22,6 +22,23 @@ cbuffer PSLightVars : register(b0)
float SampleMult;//for MSAA
}
cbuffer PSLightInstVars : register(b2)
{
float3 InstPosition;//camera relative
float InstIntensity;
float3 InstColour;
float InstFalloff;
float3 InstDirection;
float InstFalloffExponent;
float3 InstTangentX;
float InstConeInnerAngle;
float3 InstTangentY;
float InstConeOuterAngle;
float3 InstCapsuleExtent;
uint InstType;
float3 InstCullingPlaneNormal;
float InstCullingPlaneOffset;
}
@@ -52,8 +69,6 @@ float3 GetReflectedDir(float3 camRel, float3 norm)
}
float3 DeferredDirectionalLight(float3 camRel, float3 norm, float4 diffuse, float4 specular, float4 irradiance)
{
float3 refl = GetReflectedDir(camRel, norm);
@@ -88,7 +103,7 @@ float4 DeferredLODLight(float3 camRel, float3 norm, float4 diffuse, float4 specu
else if (LightType == 2)//spot (cone)
{
float ang = acos(-dot(ldir, lodlight.Direction));
float iang = lodlight.InnerAngle * 0.01745329;
float iang = lodlight.InnerAngle * 0.01745329 * 0.5;
float oang = lodlight.OuterAngleOrCapExt * 0.01745329 * 0.5;
if (ang > oang) return 0;
lamt *= saturate(1 - ((ang - iang) / (oang - iang)));
@@ -113,5 +128,52 @@ float4 DeferredLODLight(float3 camRel, float3 norm, float4 diffuse, float4 specu
return float4(lcol, 1);
}
float4 DeferredLight(float3 camRel, float3 norm, float4 diffuse, float4 specular, float4 irradiance)
{
float3 srpos = InstPosition - camRel; //light position relative to surface position
float ldist = length(srpos);
if (ldist > InstFalloff) return 0; //out of range of the light... TODO: capsules!
if (ldist <= 0) return 0;
float4 rgbi = float4(InstColour, InstIntensity);
float3 lcol = rgbi.rgb;// * rgbi.a; // * 5.0f;
float3 ldir = srpos / ldist;
float pclit = saturate(dot(ldir, norm));
float lamt = 1;
if (InstType == 1)//point (sphere)
{
lamt *= pow(saturate(1 - (ldist / InstFalloff)), InstFalloffExponent);
}
else if (InstType == 2)//spot (cone)
{
float ang = acos(-dot(ldir, InstDirection));
float iang = InstConeInnerAngle * 0.01745329 * 0.5;
float oang = InstConeOuterAngle * 0.01745329 * 0.5;
if (ang > oang) return 0;
lamt *= saturate(1 - ((ang - iang) / (oang - iang)));
lamt *= pow(saturate(1 - (ldist / InstFalloff)), InstFalloffExponent);
}
else if (InstType == 4)//capsule
{
lamt *= pow(saturate(1 - (ldist / InstFalloff)), InstFalloffExponent); //TODO! proper capsule lighting... (use point-line dist!)
}
pclit *= lamt;
if (pclit <= 0) return 0;
float3 refl = GetReflectedDir(camRel, norm);
float specb = saturate(dot(refl, ldir));
float specp = max(exp(specb * 10) - 1, 0);
float3 spec = lcol * (0.00006 * specp * specular.r * lamt);
lcol = lcol * diffuse.rgb * pclit + spec;
return float4(lcol, 1);
}
+52
View File
@@ -0,0 +1,52 @@
#include "LightPS.hlsli"
Texture2DMS<float> DepthTex : register(t0);
Texture2DMS<float4> DiffuseTex : register(t2);
Texture2DMS<float4> NormalTex : register(t3);
Texture2DMS<float4> SpecularTex : register(t4);
Texture2DMS<float4> IrradianceTex : register(t5);
struct VS_Output
{
float4 Pos : SV_POSITION;
float4 Screen : TEXCOORD0;
};
float4 main(VS_Output input) : SV_TARGET
{
uint2 ssloc = uint2(input.Pos.xy); //pixel location
float2 spos = float2(input.Screen.xy / input.Screen.w);
float4 c = 0;
float d = 0;
int sc = min(SampleCount, 8);
[unroll]
for (int i = 0; i < sc; i++)
{
float depth = DepthTex.Load(ssloc, i);
if (depth == 0) continue; //no existing subpixel rendered here
float4 diffuse = DiffuseTex.Load(ssloc, i);
float4 normal = NormalTex.Load(ssloc, i);
float4 specular = SpecularTex.Load(ssloc, i);
float4 irradiance = IrradianceTex.Load(ssloc, i);
float4 cpos = mul(float4(spos, depth, 1), ViewProjInv);
float3 camRel = cpos.xyz * (1 / cpos.w);
float3 norm = normal.xyz * 2 - 1;
float4 colour = DeferredLight(camRel, norm, diffuse, specular, irradiance);
c += colour;
d += depth;
}
c *= SampleMult;
d *= SampleMult;
if (d <= 0) discard;
return c;
}
+34 -45
View File
@@ -1,28 +1,10 @@
#include "Common.hlsli"
//currently unused - TODO: implement individual HD lights here
struct LODLight
{
float3 Position;
uint Colour;
float3 Direction;
uint TimeAndStateFlags;
float4 TangentX;
float4 TangentY;
float Falloff;
float FalloffExponent;
float InnerAngle; //for cone
float OuterAngleOrCapExt; //outer angle for cone, cap extent for capsule
};
struct VS_Output
{
float4 Pos : SV_POSITION;
float4 Screen : TEXCOORD0;
uint IID : SV_INSTANCEID;
};
@@ -36,44 +18,51 @@ cbuffer VSLightVars : register(b0)
uint Pad1;
}
StructuredBuffer<LODLight> LODLights : register(t0);
cbuffer VSLightInstVars : register(b1)
{
float3 InstPosition;//camera relative
float InstIntensity;
float3 InstColour;
float InstFalloff;
float3 InstDirection;
float InstFalloffExponent;
float3 InstTangentX;
float InstConeInnerAngle;
float3 InstTangentY;
float InstConeOuterAngle;
float3 InstCapsuleExtent;
uint InstType;
float3 InstCullingPlaneNormal;
float InstCullingPlaneOffset;
}
VS_Output main(float4 ipos : POSITION, uint iid : SV_InstanceID)
{
float3 opos = 0;
if (LightType > 0)
float extent = InstFalloff;
if (InstType == 1)//point (sphere)
{
LODLight lodlight = LODLights[iid];
float extent = lodlight.Falloff;
if (LightType == 1)//point (sphere)
{
opos = ipos.xyz * extent;
}
else if (LightType == 2)//spot (cone)
{
float arads = lodlight.OuterAngleOrCapExt * 0.01745329 * 0.5; // deg -> rad
float3 cpos = ipos.xyz * (tan(arads) * extent);
cpos.y += ipos.w * extent;
opos = (cpos.x * lodlight.TangentX.xyz) + (cpos.y * lodlight.Direction.xyz) + (cpos.z * lodlight.TangentY.xyz);
}
else if (LightType == 4)//capsule
{
float3 cpos = ipos.xyz * extent;
cpos.y += (ipos.w*2-1) * lodlight.OuterAngleOrCapExt * 0.1;
opos = (cpos.x * lodlight.TangentX.xyz) + (cpos.y * lodlight.Direction.xyz) + (cpos.z * lodlight.TangentY.xyz);
}
opos += (lodlight.Position - CameraPos.xyz);
opos = ipos.xyz * extent;
}
else
else if (InstType == 2)//spot (cone)
{
opos = ipos.xyz;
float arads = InstConeOuterAngle * 0.01745329 * 0.5; // deg -> rad
float3 cpos = ipos.xyz * (tan(arads) * extent);
cpos.y += ipos.w * extent;
opos = (cpos.x * InstTangentX) + (cpos.y * InstDirection) + (cpos.z * InstTangentY);
}
float4 spos = mul(float4(opos, 1), ViewProj);
else if (InstType == 4)//capsule
{
float3 cpos = ipos.xyz * extent;
cpos += InstCapsuleExtent * (ipos.w * 2 - 1) * 0.1;
opos = (cpos.x * InstTangentX.xyz) + (cpos.y * InstDirection.xyz) + (cpos.z * InstTangentY.xyz);
}
float4 spos = mul(float4(opos + InstPosition, 1), ViewProj);
VS_Output output;
output.Pos = spos;
output.Screen = spos;
output.IID = iid;
return output;
}