OpenGL works again, Vulkan can be switched to, fixed most of the vulkan validation errors, better shadows, soft shadows, emissive lighting, and multiple different opacity rendering methods

This commit is contained in:
Halbear 2026-08-31 14:13:59 +01:00
parent 0d41f3e15b
commit 5b231d6920
54 changed files with 1102 additions and 268 deletions

View file

@ -27,7 +27,11 @@ layout(set = 0, binding = 0) uniform sampler2D posSampler;
layout(set = 0, binding = 1) uniform sampler2D albedoSampler;
layout(set = 0, binding = 2) uniform sampler2D normalsSampler;
layout(set = 0, binding = 3) uniform sampler2D pbrSampler;
layout(set = 0, binding = 4) uniform sampler2DArray shadowSampler;
layout(set = 0, binding = 4) uniform sampler2D emissiveSampler;
layout(set = 0, binding = 5) uniform sampler2D TranslucencySampler;
layout(set = 0, binding = 6) uniform sampler2D OpacitySampler;
layout(set = 0, binding = 7) uniform sampler2DArray shadowSampler;
layout(scalar, set = 1, binding = 0) readonly buffer Lights {
Light lights[];
@ -62,7 +66,7 @@ float chebyshevUpperBound(vec2 moments, float t) {
return p_max;
}
float calcVisibility(vec4 worldPosition, uint cascadeIndex) {
float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias) {
vec4 shadowMapPosition = shadows.cascadeshadows[cascadeIndex].projViewMatrix * worldPosition;
shadowMapPosition.xyz /= shadowMapPosition.w;
@ -76,14 +80,25 @@ float calcVisibility(vec4 worldPosition, uint cascadeIndex) {
if (uv.x < 0.0 || uv.x > 1.0 ||
uv.y < 0.0 || uv.y > 1.0 ||
depth < 0.0 || depth > 1.0) {
depth < ShadowBias || depth > 1.0) {
return 1.0;
}
vec2 moments = texture(shadowSampler, vec3(uv, cascadeIndex)).rg;
float shadow = 0.0;
float visibility = chebyshevUpperBound(moments, depth);
return visibility;
vec2 texelSize = 1.0 / textureSize(shadowSampler, 0).rg;
for(int x = -1; x <= 1; ++x)
{
for(int y = -1; y <= 1; ++y)
{
vec2 moments = texture(shadowSampler, vec3((uv + vec2(x, y) * texelSize), cascadeIndex)).rg;
float visibility = chebyshevUpperBound(moments, depth);
shadow += depth - ShadowBias > visibility ? 1.0 : 0.0;
}
}
shadow /= 9.0;
return 1 - shadow;
}
float distributionGGX(vec3 N, vec3 H, float roughness) {
@ -150,7 +165,7 @@ vec3 calculatePointLight(Light light, vec3 worldPos, vec3 V, vec3 N, vec3 F0, ve
return (kD * albedo / PI + specular) * radiance * NdotL;
}
vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo, float metallic, float roughness) {
vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo, float metallic, float roughness, float translucency) {
vec3 L = normalize(-light.position);
vec3 H = normalize(V + L);
@ -170,7 +185,9 @@ vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo
kD *= 1.0 - metallic;
float NdotL = max(dot(N, L), 0.0);
return (kD * albedo / PI + specular) * radiance * NdotL;
vec3 shadowValue = (kD * albedo / PI + specular) * radiance * NdotL;
vec3 lightValue = (kD * albedo / PI + specular) * radiance;
return (shadowValue * (1 - translucency)) + (lightValue * translucency);
}
void main() {
@ -179,6 +196,20 @@ void main() {
vec4 worldPosW = texture(posSampler, inTextCoord);
vec3 worldPos = worldPosW.xyz;
vec3 pbr = texture(pbrSampler, inTextCoord).rgb;
vec3 emissive = texture(emissiveSampler, inTextCoord).rgb;
vec3 Opacity = texture(OpacitySampler, inTextCoord).rgb;
vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb;
float emissiveness = emissive.r;
float translucencyf = translucency.r;
// outFragColor = vec4(emissive,1);
// return;
float ShadowBias = 0.05f;
float opacityf = Opacity.x + Opacity.y + Opacity.z;
opacityf = opacityf/3.0;
float roughness = pbr.g;
float metallic = pbr.b;
@ -186,6 +217,8 @@ void main() {
vec3 N = normalize(normal);
vec3 V = normalize(sceneInfo.camPos - worldPos);
vec3 F0 = vec3(0.04);
F0 = mix(F0, albedo, metallic);
@ -196,18 +229,19 @@ void main() {
cascadeIndex = i + 1;
}
}
float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex);
float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex,ShadowBias);
vec3 Lo = vec3(0.0);
for (uint i = 0; i < sceneInfo.numLights; i++) {
Light light = lights.lights[i];
if (light.directional == 1) {
Lo += calculateDirectionalLight(light, V, N, F0, albedo, metallic, roughness) * shadow;
Lo += calculateDirectionalLight(light, V, N, F0, albedo, metallic, roughness,translucencyf) * shadow;
} else {
Lo += calculatePointLight(light, worldPos, V, N, F0, albedo, metallic, roughness);
}
}
vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity;
if(emissive.x > 0 || emissive.y > 0 || emissive.z > 0) ambient = emissive;
outFragColor = vec4(Lo + ambient, 1.0f);
if (DEBUG_SHADOWS == 1) {