ADD: multi light system

This commit is contained in:
2025-11-26 16:36:24 +09:00
parent 3c3137258d
commit 12cab048d8
9 changed files with 235 additions and 170 deletions

View File

@@ -3,6 +3,7 @@
#extension GL_EXT_ray_query : require
#include "input_structures.glsl"
#include "ibl_common.glsl"
#include "lighting_common.glsl"
layout(location=0) in vec2 inUV;
layout(location=0) out vec4 outColor;
@@ -33,8 +34,6 @@ const float SHADOW_MIN_BIAS = 1e-5;
const float SHADOW_RAY_TMIN = 0.02;// start a bit away from the surface
const float SHADOW_RAY_ORIGIN_BIAS = 0.01;// world units
const float PI = 3.14159265359;
float hash12(vec2 p)
{
vec3 p3 = fract(vec3(p.xyx) * 0.1031);
@@ -263,41 +262,6 @@ float calcShadowVisibility(vec3 worldPos, vec3 N, vec3 L)
return vis;
}
vec3 fresnelSchlick(float cosTheta, vec3 F0)
{
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
}
float DistributionGGX(vec3 N, vec3 H, float roughness)
{
float a = roughness * roughness;
float a2 = a * a;
float NdotH = max(dot(N, H), 0.0);
float NdotH2 = NdotH * NdotH;
float num = a2;
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
denom = PI * denom * denom;
return num / max(denom, 0.001);
}
float GeometrySchlickGGX(float NdotV, float roughness)
{
float r = (roughness + 1.0);
float k = (r * r) / 8.0;
float denom = NdotV * (1.0 - k) + k;
return NdotV / max(denom, 0.001);
}
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
{
float ggx2 = GeometrySchlickGGX(max(dot(N, V), 0.0), roughness);
float ggx1 = GeometrySchlickGGX(max(dot(N, L), 0.0), roughness);
return ggx1 * ggx2;
}
void main(){
vec4 posSample = texture(posTex, inUV);
if (posSample.w == 0.0)
@@ -317,28 +281,53 @@ void main(){
vec3 camPos = vec3(inverse(sceneData.view)[3]);
vec3 V = normalize(camPos - pos);
vec3 L = normalize(-sceneData.sunlightDirection.xyz);
vec3 H = normalize(V + L);
vec3 F0 = mix(vec3(0.04), albedo, metallic);
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
float NDF = DistributionGGX(N, H, roughness);
float G = GeometrySmith(N, V, L, roughness);
// Directional sun term using evaluate_brdf + cascaded shadowing
vec3 Lsun = normalize(-sceneData.sunlightDirection.xyz);
float sunVis = calcShadowVisibility(pos, N, Lsun);
vec3 sunBRDF = evaluate_brdf(N, V, Lsun, albedo, roughness, metallic);
vec3 direct = sunBRDF * sceneData.sunlightColor.rgb * sceneData.sunlightColor.a * sunVis;
vec3 numerator = NDF * G * F;
float denom = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0);
vec3 specular = numerator / max(denom, 0.001);
// Punctual point lights
uint pointCount = sceneData.lightCounts.x;
for (uint i = 0u; i < pointCount; ++i)
{
vec3 contrib = eval_point_light(sceneData.punctualLights[i], pos, N, V, albedo, roughness, metallic);
vec3 kS = F;
vec3 kD = (1.0 - kS) * (1.0 - metallic);
// Optional RT shadow for the first few point lights (hybrid mode)
#ifdef GL_EXT_ray_query
if (sceneData.rtOptions.x == 1u && i < 4u)
{
vec3 toL = sceneData.punctualLights[i].position_radius.xyz - pos;
float maxT = length(toL);
if (maxT > 0.01)
{
vec3 dir = toL / maxT;
vec3 origin = pos + N * SHADOW_RAY_ORIGIN_BIAS;
float NdotL = max(dot(N, L), 0.0);
// Shadowing (directional, forward-Z shadow map)
float visibility = calcShadowVisibility(pos, N, L);
rayQueryEXT rq;
rayQueryInitializeEXT(
rq,
topLevelAS,
gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT,
0xFF,
origin,
SHADOW_RAY_TMIN,
dir,
maxT
);
while (rayQueryProceedEXT(rq)) { }
bool hit = (rayQueryGetIntersectionTypeEXT(rq, true) != gl_RayQueryCommittedIntersectionNoneEXT);
if (hit)
{
contrib = vec3(0.0);
}
}
}
#endif
vec3 irradiance = sceneData.sunlightColor.rgb * sceneData.sunlightColor.a * NdotL * visibility;
vec3 color = (kD * albedo / PI + specular) * irradiance;
direct += contrib;
}
// Image-Based Lighting: split-sum approximation
vec3 R = reflect(-V, N);
@@ -347,9 +336,11 @@ void main(){
vec2 uv = dir_to_equirect(R);
vec3 prefiltered = textureLod(iblSpec2D, uv, lod).rgb;
vec2 brdf = texture(iblBRDF, vec2(max(dot(N, V), 0.0), roughness)).rg;
vec3 F0 = mix(vec3(0.04), albedo, metallic);
vec3 specIBL = prefiltered * (F0 * brdf.x + brdf.y);
vec3 diffIBL = (1.0 - metallic) * albedo * sh_eval_irradiance(N);
color += diffIBL + specIBL;
vec3 color = direct + diffIBL + specIBL;
outColor = vec4(color, 1.0);
}