Skip to content

Commit

Permalink
Scene lights
Browse files Browse the repository at this point in the history
Hlvr lights

Fix aperture desk lights - entire light loop sharing one visibility

Bump max lights to 256
Use correct indices

Trying out dynamic lights in hlvr

Update lighting.glsl
  • Loading branch information
kristiker committed May 13, 2024
1 parent a6b8929 commit 62e531c
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 11 deletions.
5 changes: 5 additions & 0 deletions GUI/Types/Renderer/SceneLight.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ public static SceneLight FromEntityProperties(Scene scene, EntityType type, Enti

var isNewLightType = type is EntityType.Omni2 or EntityType.Barn or EntityType.Rect;

if (isNewLightType && light.Brightness > 15f)
{
light.Brightness = 1f; // todo: findout the correct brightness value
}

if (!isNewLightType)
{
light.AttenuationLinear = entity.GetPropertyUnchecked("attenuation1", 0.0f);
Expand Down
154 changes: 143 additions & 11 deletions GUI/Types/Renderer/Shaders/common/lighting.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ vec3 GetLightDirection(vec3 vPositionWs, uint nLightIndex)
return lightVector;
}

float GetLightRangeInverse(uint nLightIndex)
{
return g_vLightDirection_InvRange[nLightIndex].a;
}

vec3 GetLightColor(uint nLightIndex)
{
vec3 vColor = g_vLightColor_Brightness[nLightIndex].rgb;
Expand All @@ -147,11 +152,110 @@ vec3 GetLightColor(uint nLightIndex)
return vColor * flBrightness;
}

/*
vec3 CalcBaseLight(int layer, vec3 normals, BaseLight base, float attenuation, bool global)
{
//return CalcLight(layer, normals, base.Position, base.Color.rgb * base.Intensity, attenuation, global);
}
vec3 CalcPointLight(int layer, vec3 normals, Light light)
{
float distanceToLight = length(light.Base.Position - vPositionWs);
float attenuation = 1.0 / (1.0 + light.Linear * distanceToLight + light.Quadratic * pow(distanceToLight, 2));
return CalcBaseLight(layer, normals, light.Base, attenuation, true);
}
float CalcSpotLightAtten(vec3 vPositionWs, Light light)
{
vec3 v = normalize(light.Position - vPositionWs);
float inner = cos(radians(light.InnerConeAngle));
float outer = cos(radians(light.OuterConeAngle));
float distanceToLight = length(light.Base.Position - vPositionWs);
float theta = dot(v, normalize(-vec3(0, -1, 0)));
float epsilon = inner - outer;
float attenuation = 1.0 / (1.0 + light.Attenuation * pow(distanceToLight, 2));
light.Base.Intensity *= smoothstep(0.0, 1.0, (theta - outer) / epsilon);
if(theta > outer)
{
return attenuation;
}
else
{
return 0.0;
}
}
*/

float DistanceFalloff(float flDistToLightSq, float flLightInvRadius, vec2 vFalloffParams)
{
flDistToLightSq = max(flDistToLightSq, 1.0); // Can't be inside the light source (assuming radius^2 == 1.0f)

vec2 vInvRadiusAndInvRadiusSq = vec2(flLightInvRadius, flLightInvRadius * flLightInvRadius);
vec2 vLightDistAndLightDistSq = vec2(sqrt(flDistToLightSq), flDistToLightSq);

float flTruncation = dot(vFalloffParams.xy, vInvRadiusAndInvRadiusSq.xy); // Constant amount to subtract to ensure that the light is zero past the light radius
float flFalloff = dot(vFalloffParams.xy, vLightDistAndLightDistSq.xy);

return saturate((1.0 / flFalloff) - flTruncation);
}

// https://lisyarus.github.io/blog/graphics/2022/07/30/point-light-attenuation.html
float attenuate_cusp(float s, float falloff)
{
if (s >= 1.0)
return 0.0;

float s2 = pow2(s);

//return 1.0;
return pow2(1 - s2) / (1 + falloff * s);
}

void CalculateDirectLighting(inout LightingTerms_t lighting, inout MaterialProperties_t mat)
{
const float MIN_ALPHA = 0.0001;

#if (LightmapGameVersionNumber == 1)

for (uint uLightIndex = g_nNumLights.x; uLightIndex < g_nNumLights.y; uLightIndex++)
{
vec3 vPositionToLightRayWs = g_vLightPosition_Type[uLightIndex].xyz - mat.PositionWS.xyz;
float flDistToLightSq = dot(vPositionToLightRayWs.xyz, vPositionToLightRayWs.xyz);

if (flDistToLightSq > pow2(g_vLightFallOff[uLightIndex].y))
{
// Outside light range
continue;
}

if (dot(mat.Normal.xyz, vPositionToLightRayWs.xyz) <= 0.0)
{
// Backface cull pixel to this light
//continue;
}

vec3 lightVector = normalize(vPositionToLightRayWs);
float flOuterConeCos = g_vLightSpotInnerOuterConeCosines[uLightIndex].x;
float flTemp = dot(lightVector, -g_vLightDirection_InvRange[uLightIndex].xyz ) - flOuterConeCos;

if (flTemp <= 0.0)
{
// Outside spotlight cone
//continue;
}

float vSpotAtten = saturate(flTemp * g_vLightSpotInnerOuterConeCosines[uLightIndex].y);
float flLightFalloff = attenuate_cusp(sqrt(flDistToLightSq), max(g_vLightFallOff[uLightIndex].z, g_vLightFallOff[uLightIndex].w));//DistanceFalloff(flDistToLightSq, g_vLightDirection_InvRange[uLightIndex].w, g_vLightFallOff[uLightIndex].zw);
float visibility = flLightFalloff;

if (visibility > MIN_ALPHA)
{
CalculateShading(lighting, lightVector, visibility * GetLightColor(uLightIndex), mat);
}
}

#if (D_BAKED_LIGHTING_FROM_LIGHTMAP == 1)
vec4 dls = texture(g_tDirectLightStrengths, vLightmapUVScaled);
vec4 dli = texture(g_tDirectLightIndices, vLightmapUVScaled);
Expand Down Expand Up @@ -214,20 +318,48 @@ void CalculateDirectLighting(inout LightingTerms_t lighting, inout MaterialPrope
dlsh = textureLod(g_tLPV_Shadows, vLightProbeShadowCoords, 0.0);
#endif

const uint uLightIndex = 0;
for(uint uShadowIndex = 0; uShadowIndex < 4; ++uShadowIndex)
{
float shadowFactor = 1.0 - dlsh[uShadowIndex];
if (shadowFactor <= MIN_ALPHA)
{
continue;
}
uint nLightIndexStart = uShadowIndex == 0 ? 0 : g_nNumLightsPerShadow[uShadowIndex - 1];
uint nLightCount = g_nNumLightsPerShadow[uShadowIndex];

float visibility = 1.0 - dlsh[uLightIndex];
for(uint uLightIndex = nLightIndexStart; uLightIndex < nLightCount; ++uLightIndex)
{
float visibility = shadowFactor;
vec3 lightVector = GetLightDirection(mat.PositionWS, uLightIndex);

if (visibility > MIN_ALPHA && uLightIndex == 0)
{
visibility *= CalculateSunShadowMapVisibility(mat.PositionWS);
}
//if (uLightIndex == 8 && length(GetLightPositionWs(uLightIndex) - mat.PositionWS) < g_vLightFallOff[uLightIndex].y)
//{
// visibility = 1.0;
//}

if (visibility > MIN_ALPHA)
{
vec3 lightColor = GetLightColor(uLightIndex);
vec3 lightVector = GetLightDirection(mat.PositionWS, uLightIndex);
CalculateShading(lighting, lightVector, visibility * lightColor, mat);
if (IsDirectionalLight(uLightIndex))
{
visibility *= CalculateSunShadowMapVisibility(mat.PositionWS);
}
else
{
float flInvRange = GetLightRangeInverse(uLightIndex) / g_vLightPosition_Type[uLightIndex].a;
vec3 vLightPosition = g_vLightPosition_Type[uLightIndex].xyz;
float flDistance = length(vLightPosition - mat.PositionWS);
float flFallOff = g_vLightFallOff[uLightIndex].x;
float flRange = g_vLightFallOff[uLightIndex].y * 2;

//float s = flDistance / flRange;

visibility *= attenuate_cusp(flDistance * flInvRange, flFallOff);
}

if (visibility > MIN_ALPHA)
{
CalculateShading(lighting, lightVector, visibility * GetLightColor(uLightIndex), mat);
}
}
}
#else
// Non lightmapped scene
Expand Down
7 changes: 7 additions & 0 deletions GUI/Types/Renderer/Shaders/complex.frag
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "complex_features.glsl"

// Render modes -- Switched on/off by code
#define renderMode_LightmapShadows 0
#define renderMode_Diffuse 0
#define renderMode_Specular 0
#define renderMode_PBR 0
Expand Down Expand Up @@ -674,6 +675,12 @@ void main()
outputColor = vec4(SrgbLinearToGamma(lighting.DiffuseIndirect), 1.0);
#endif

#if renderMode_LightmapShadows == 1 && (D_BAKED_LIGHTING_FROM_LIGHTMAP == 1)
vec4 dlsh = texture(g_tDirectLightShadows, vLightmapUVScaled);
//outputColor = vec4(vec3(1.0) - min(min(dlsh.x, min(dlsh.y, dlsh.z)), dlsh.a), 1.0);
outputColor = 1.0 - dlsh.gggg;
#endif

#if renderMode_Tint == 1
outputColor = vVertexColorOut;
#endif
Expand Down

0 comments on commit 62e531c

Please sign in to comment.