diff --git a/CodeWalker.Shaders/LightPS.hlsli b/CodeWalker.Shaders/LightPS.hlsli index 6866d9a..acafeec 100644 --- a/CodeWalker.Shaders/LightPS.hlsli +++ b/CodeWalker.Shaders/LightPS.hlsli @@ -68,6 +68,30 @@ float3 GetReflectedDir(float3 camRel, float3 norm) return refl; } +float4 GetLineSegmentNearestPoint(float3 v, float3 a, float3 b) +{ + float3 ab = b - a; + float3 av = v - a; + if (dot(av, ab) <= 0.0f)// Point is lagging behind start of the segment, so perpendicular distance is not viable. + { + return float4(av, length(av)); + } + else + { + float3 bv = v - b; + if (dot(bv, ab) >= 0.0f)// Point is advanced past the end of the segment, so perpendicular distance is not viable. + { + return float4(bv, length(bv)); + } + else + { + float3 abv = cross(ab, av); + float d = length(abv) / length(ab); + return float4(normalize(cross(abv, ab)) * d, d); //improve this! + } + } +} + float3 DeferredDirectionalLight(float3 camRel, float3 norm, float4 diffuse, float4 specular, float4 irradiance) { @@ -87,7 +111,15 @@ float4 DeferredLODLight(float3 camRel, float3 norm, float4 diffuse, float4 specu LODLight lodlight = LODLights[iid]; float3 srpos = lodlight.Position - (camRel + CameraPos.xyz); //light position relative to surface position float ldist = length(srpos); - if (ldist > lodlight.Falloff) return 0; //out of range of the light... TODO: capsules! + if (LightType == 4)//capsule + { + float3 ext = lodlight.Direction.xyz * lodlight.OuterAngleOrCapExt; + float4 lsn = GetLineSegmentNearestPoint(srpos, ext, -ext); + ldist = lsn.w; + srpos.xyz = lsn.xyz; + } + + if (ldist > lodlight.Falloff) return 0; //out of range of the light... if (ldist <= 0) return 0; float4 rgbi = Unpack4x8UNF(lodlight.Colour).gbar; @@ -132,7 +164,14 @@ float4 DeferredLight(float3 camRel, float3 norm, float4 diffuse, float4 specular { 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 (InstType == 4)//capsule + { + float3 ext = InstDirection.xyz * (InstCapsuleExtent.y * 0.5); + float4 lsn = GetLineSegmentNearestPoint(srpos, ext, -ext); + ldist = lsn.w; + srpos.xyz = lsn.xyz; + } + if (ldist > InstFalloff) return 0; if (ldist <= 0) return 0; float d = dot(srpos, InstCullingPlaneNormal) - InstCullingPlaneOffset; @@ -159,7 +198,7 @@ float4 DeferredLight(float3 camRel, float3 norm, float4 diffuse, float4 specular } else if (InstType == 4)//capsule { - lamt *= pow(saturate(1 - (ldist / InstFalloff)), InstFalloffExponent); //TODO! proper capsule lighting... (use point-line dist!) + lamt *= pow(saturate(1 - (ldist / InstFalloff)), InstFalloffExponent); } pclit *= lamt; diff --git a/CodeWalker.Shaders/LightVS.hlsl b/CodeWalker.Shaders/LightVS.hlsl index 221933d..5949730 100644 --- a/CodeWalker.Shaders/LightVS.hlsl +++ b/CodeWalker.Shaders/LightVS.hlsl @@ -56,7 +56,7 @@ VS_Output main(float4 ipos : POSITION, uint iid : SV_InstanceID) else if (InstType == 4)//capsule { float3 cpos = ipos.xyz * extent; - cpos += InstCapsuleExtent * (ipos.w * 2 - 1) * 0.1; + cpos.y += abs(InstCapsuleExtent.y) * (ipos.w - 0.5); opos = (cpos.x * InstTangentX.xyz) + (cpos.y * InstDirection.xyz) + (cpos.z * InstTangentY.xyz); } diff --git a/Rendering/Renderable.cs b/Rendering/Renderable.cs index e3e31b9..643bb5a 100644 --- a/Rendering/Renderable.cs +++ b/Rendering/Renderable.cs @@ -1503,7 +1503,7 @@ namespace CodeWalker.Rendering spots.Add(light); break; case LightType.Capsule: - light.OuterAngleOrCapExt = ll.coneOuterAngleOrCapExt[i] * 0.1f;//is this right? + light.OuterAngleOrCapExt = ll.coneOuterAngleOrCapExt[i] * 0.25f; caps.Add(light); break; default: break;//just checking... diff --git a/Shaders/LightPS.cso b/Shaders/LightPS.cso index a03653d..a86bfd2 100644 Binary files a/Shaders/LightPS.cso and b/Shaders/LightPS.cso differ diff --git a/Shaders/LightPS_MS.cso b/Shaders/LightPS_MS.cso index 9e73d91..29cd4bb 100644 Binary files a/Shaders/LightPS_MS.cso and b/Shaders/LightPS_MS.cso differ diff --git a/Shaders/LightVS.cso b/Shaders/LightVS.cso index 379b340..37e2164 100644 Binary files a/Shaders/LightVS.cso and b/Shaders/LightVS.cso differ diff --git a/Shaders/LodLightsPS.cso b/Shaders/LodLightsPS.cso index 44cc1fb..e869742 100644 Binary files a/Shaders/LodLightsPS.cso and b/Shaders/LodLightsPS.cso differ diff --git a/Shaders/LodLightsPS_MS.cso b/Shaders/LodLightsPS_MS.cso index 8c66a64..2145a6f 100644 Binary files a/Shaders/LodLightsPS_MS.cso and b/Shaders/LodLightsPS_MS.cso differ