OpenGL: Implement rendering of lightmaps

This commit is contained in:
David Snopek 2023-11-19 21:39:20 -06:00
parent 654132cb9c
commit 749f60ee36
6 changed files with 350 additions and 27 deletions

View file

@ -1,7 +1,7 @@
/* clang-format off */
#[modes]
mode_color =
mode_color =
mode_color_instancing = \n#define USE_INSTANCING
mode_depth = #define MODE_RENDER_DEPTH
mode_depth_instancing = #define MODE_RENDER_DEPTH \n#define USE_INSTANCING
@ -14,6 +14,9 @@ DISABLE_LIGHT_OMNI = false
DISABLE_LIGHT_SPOT = false
DISABLE_FOG = false
USE_RADIANCE_MAP = true
USE_LIGHTMAP = false
USE_SH_LIGHTMAP = false
USE_LIGHTMAP_CAPTURE = false
USE_MULTIVIEW = false
RENDER_SHADOWS = false
RENDER_SHADOWS_LINEAR = false
@ -676,6 +679,10 @@ multiview_data;
/* clang-format on */
#define LIGHT_BAKE_DISABLED 0u
#define LIGHT_BAKE_STATIC 1u
#define LIGHT_BAKE_DYNAMIC 2u
#ifndef MODE_RENDER_DEPTH
// Directional light data.
#if !defined(DISABLE_LIGHT_DIRECTIONAL) || (!defined(ADDITIVE_OMNI) && !defined(ADDITIVE_SPOT))
@ -685,7 +692,8 @@ struct DirectionalLightData {
mediump float energy;
mediump vec3 color;
mediump float size;
mediump vec2 pad;
lowp uint unused;
lowp uint bake_mode;
mediump float shadow_opacity;
mediump float specular;
};
@ -718,6 +726,9 @@ struct LightData { // This structure needs to be as packed as possible.
mediump float cone_angle;
mediump float specular_amount;
mediump float shadow_opacity;
lowp vec3 pad;
lowp uint bake_mode;
};
#if !defined(DISABLE_LIGHT_OMNI) || defined(ADDITIVE_OMNI)
@ -834,6 +845,23 @@ float sample_shadow(highp sampler2DShadow shadow, float shadow_pixel_size, vec4
#endif // !MODE_RENDER_DEPTH
#ifndef DISABLE_LIGHTMAP
#ifdef USE_LIGHTMAP
uniform mediump sampler2DArray lightmap_textures; //texunit:-4
uniform lowp uint lightmap_slice;
uniform highp vec4 lightmap_uv_scale;
uniform float lightmap_exposure_normalization;
#ifdef USE_SH_LIGHTMAP
uniform mediump mat3 lightmap_normal_xform;
#endif // USE_SH_LIGHTMAP
#endif // USE_LIGHTMAP
#ifdef USE_LIGHTMAP_CAPTURE
uniform mediump vec4[9] lightmap_captures;
#endif // USE_LIGHTMAP_CAPTURE
#endif // !DISABLE_LIGHTMAP
#ifdef USE_MULTIVIEW
uniform highp sampler2DArray depth_buffer; // texunit:-6
uniform highp sampler2DArray color_buffer; // texunit:-5
@ -1406,7 +1434,6 @@ void main() {
#endif
// Calculate Reflection probes
// Calculate Lightmaps
#if defined(CUSTOM_RADIANCE_USED)
specular_light = mix(specular_light, custom_radiance.rgb, custom_radiance.a);
@ -1431,6 +1458,61 @@ void main() {
ambient_light = mix(ambient_light, custom_irradiance.rgb, custom_irradiance.a);
#endif // CUSTOM_IRRADIANCE_USED
#ifndef DISABLE_LIGHTMAP
#ifdef USE_LIGHTMAP_CAPTURE
{
vec3 wnormal = mat3(scene_data.inv_view_matrix) * normal;
const float c1 = 0.429043;
const float c2 = 0.511664;
const float c3 = 0.743125;
const float c4 = 0.886227;
const float c5 = 0.247708;
ambient_light += (c1 * lightmap_captures[8].rgb * (wnormal.x * wnormal.x - wnormal.y * wnormal.y) +
c3 * lightmap_captures[6].rgb * wnormal.z * wnormal.z +
c4 * lightmap_captures[0].rgb -
c5 * lightmap_captures[6].rgb +
2.0 * c1 * lightmap_captures[4].rgb * wnormal.x * wnormal.y +
2.0 * c1 * lightmap_captures[7].rgb * wnormal.x * wnormal.z +
2.0 * c1 * lightmap_captures[5].rgb * wnormal.y * wnormal.z +
2.0 * c2 * lightmap_captures[3].rgb * wnormal.x +
2.0 * c2 * lightmap_captures[1].rgb * wnormal.y +
2.0 * c2 * lightmap_captures[2].rgb * wnormal.z) *
scene_data.emissive_exposure_normalization;
}
#else
#ifdef USE_LIGHTMAP
{
vec3 uvw;
uvw.xy = uv2 * lightmap_uv_scale.zw + lightmap_uv_scale.xy;
uvw.z = float(lightmap_slice);
#ifdef USE_SH_LIGHTMAP
uvw.z *= 4.0; // SH textures use 4 times more data.
vec3 lm_light_l0 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 0.0), 0.0).rgb;
vec3 lm_light_l1n1 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb;
vec3 lm_light_l1_0 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb;
vec3 lm_light_l1p1 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb;
vec3 n = normalize(lightmap_normal_xform * normal);
ambient_light += lm_light_l0 * 0.282095f;
ambient_light += lm_light_l1n1 * 0.32573 * n.y * lightmap_exposure_normalization;
ambient_light += lm_light_l1_0 * 0.32573 * n.z * lightmap_exposure_normalization;
ambient_light += lm_light_l1p1 * 0.32573 * n.x * lightmap_exposure_normalization;
if (metallic > 0.01) { // Since the more direct bounced light is lost, we can kind of fake it with this trick.
vec3 r = reflect(normalize(-vertex), normal);
specular_light += lm_light_l1n1 * 0.32573 * r.y * lightmap_exposure_normalization;
specular_light += lm_light_l1_0 * 0.32573 * r.z * lightmap_exposure_normalization;
specular_light += lm_light_l1p1 * 0.32573 * r.x * lightmap_exposure_normalization;
}
#else
ambient_light += textureLod(lightmap_textures, uvw, 0.0).rgb * lightmap_exposure_normalization;
#endif
}
#endif // USE_LIGHTMAP
#endif // USE_LIGHTMAP_CAPTURE
#endif // !DISABLE_LIGHTMAP
{
#if defined(AMBIENT_LIGHT_DISABLED)
ambient_light = vec3(0.0, 0.0, 0.0);
@ -1466,6 +1548,11 @@ void main() {
#ifndef DISABLE_LIGHT_DIRECTIONAL
for (uint i = uint(0); i < scene_data.directional_light_count; i++) {
#if defined(USE_LIGHTMAP) && !defined(DISABLE_LIGHTMAP)
if (directional_lights[i].bake_mode == LIGHT_BAKE_STATIC) {
continue;
}
#endif
light_compute(normal, normalize(directional_lights[i].direction), normalize(view), directional_lights[i].size, directional_lights[i].color * directional_lights[i].energy, true, 1.0, f0, roughness, metallic, 1.0, albedo, alpha,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
@ -1490,6 +1577,11 @@ void main() {
if (i >= omni_light_count) {
break;
}
#if defined(USE_LIGHTMAP) && !defined(DISABLE_LIGHTMAP)
if (omni_lights[omni_light_indices[i]].bake_mode == LIGHT_BAKE_STATIC) {
continue;
}
#endif
light_process_omni(omni_light_indices[i], vertex, view, normal, f0, roughness, metallic, 1.0, albedo, alpha,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
@ -1513,6 +1605,11 @@ void main() {
if (i >= spot_light_count) {
break;
}
#if defined(USE_LIGHTMAP) && !defined(DISABLE_LIGHTMAP)
if (spot_lights[spot_light_indices[i]].bake_mode == LIGHT_BAKE_STATIC) {
continue;
}
#endif
light_process_spot(spot_light_indices[i], vertex, view, normal, f0, roughness, metallic, 1.0, albedo, alpha,
#ifdef LIGHT_BACKLIGHT_USED
backlight,