Skip to content

Commit d9ca537

Browse files
committed
Implement Lightmap+GI reflections
1 parent a636046 commit d9ca537

File tree

5 files changed

+129
-2
lines changed

5 files changed

+129
-2
lines changed

drivers/gles3/storage/material_storage.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,8 @@ MaterialStorage::MaterialStorage() {
13601360
actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
13611361
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
13621362
actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n";
1363+
actions.render_mode_defines["specular_occlusion_conservative"] = "#define SPECULAR_OCCLUSION_CONSERVATIVE\n";
1364+
actions.render_mode_defines["specular_occlusion"] = "#define SPECULAR_OCCLUSION\n";
13631365

13641366
int specular_occlusion_mode = GLOBAL_GET("rendering/lightmapping/specular_occlusion/mode");
13651367

servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,16 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
894894
inst->gi_offset_cache = 0xFFFFFFFF;
895895
}
896896

897+
if (p_using_opaque_gi) {
898+
// Inherit Dynamic GI reflections
899+
flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS;
900+
}
901+
902+
if (inst->voxel_gi_instances[0].is_valid()) {
903+
// Inherit VoxelGI reflections
904+
flags |= INSTANCE_DATA_FLAG_USE_VOXEL_GI;
905+
}
906+
897907
} else if (inst->lightmap_sh) {
898908
if (lightmap_captures_used < scene_state.max_lightmap_captures) {
899909
const Color *src_capture = inst->lightmap_sh->sh;
@@ -910,6 +920,16 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
910920
uses_lightmap = true;
911921
}
912922

923+
if (p_using_opaque_gi) {
924+
// Inherit Dynamic GI reflections
925+
flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS;
926+
}
927+
928+
if (inst->voxel_gi_instances[0].is_valid()) {
929+
// Inherit VoxelGI reflections
930+
flags |= INSTANCE_DATA_FLAG_USE_VOXEL_GI;
931+
}
932+
913933
} else {
914934
if (p_using_opaque_gi) {
915935
flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS;

servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,8 @@ void SceneShaderForwardMobile::init(const String p_defines) {
621621
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
622622
actions.render_mode_defines["debug_shadow_splits"] = "#define DEBUG_DRAW_PSSM_SPLITS\n";
623623
actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n";
624+
actions.render_mode_defines["specular_occlusion_conservative"] = "#define SPECULAR_OCCLUSION_CONSERVATIVE\n";
625+
actions.render_mode_defines["specular_occlusion"] = "#define SPECULAR_OCCLUSION\n";
624626

625627
int specular_occlusion_mode = GLOBAL_GET("rendering/lightmapping/specular_occlusion/mode");
626628

servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,36 @@ void fragment_shader(in SceneData scene_data) {
13681368
#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
13691369

13701370
#ifdef USE_LIGHTMAP
1371+
if (sc_use_forward_gi && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // inherit VoxelGI reflections
1372+
uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
1373+
// Make vertex orientation the world one, but still align to camera.
1374+
vec3 cam_pos = mat3(scene_data.inv_view_matrix) * vertex;
1375+
vec3 cam_normal = mat3(scene_data.inv_view_matrix) * normal;
1376+
vec3 ref_vec = mat3(scene_data.inv_view_matrix) * normalize(reflect(-view, normal));
1377+
1378+
//find arbitrary tangent and bitangent, then build a matrix
1379+
vec3 v0 = abs(cam_normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
1380+
vec3 tangent = normalize(cross(v0, cam_normal));
1381+
vec3 bitangent = normalize(cross(tangent, cam_normal));
1382+
mat3 normal_mat = mat3(tangent, bitangent, cam_normal);
1383+
1384+
vec4 spec_accum = vec4(0.0);
1385+
voxel_gi_compute_irradiance_only(index1, cam_pos, cam_normal, ref_vec, normal_mat, roughness * roughness, specular_light, spec_accum);
1386+
1387+
uint index2 = instances.data[instance_index].gi_offset >> 16;
1388+
1389+
if (index2 != 0xFFFF) {
1390+
voxel_gi_compute_irradiance_only(index2, cam_pos, cam_normal, ref_vec, normal_mat, roughness * roughness, specular_light, spec_accum);
1391+
}
1392+
1393+
if (spec_accum.a > 0.0) {
1394+
spec_accum.rgb /= spec_accum.a;
1395+
}
1396+
1397+
specular_light = spec_accum.rgb;
1398+
}
1399+
1400+
float specular_occlusion;
13711401

13721402
//lightmap
13731403
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE)) { //has lightmap capture
@@ -1393,7 +1423,7 @@ void fragment_shader(in SceneData scene_data) {
13931423
scene_data.emissive_exposure_normalization;
13941424

13951425
#if defined(SPECULAR_OCCLUSION) || defined(SPECULAR_OCCLUSION_CONSERVATIVE)
1396-
float specular_occlusion = (c.r * 0.3 + c.g * 0.59 + c.b * 0.11) * 2.0; // brightness from lightmap color
1426+
specular_occlusion = (c.r * 0.3 + c.g * 0.59 + c.b * 0.11) * 2.0; // brightness from lightmap color
13971427
specular_occlusion = min(1.0, specular_occlusion * scene_data.emissive_exposure_normalization);
13981428

13991429
#if defined(SPECULAR_OCCLUSION_CONSERVATIVE)
@@ -1440,7 +1470,7 @@ void fragment_shader(in SceneData scene_data) {
14401470
#if defined(SPECULAR_OCCLUSION) || defined(SPECULAR_OCCLUSION_CONSERVATIVE)
14411471
vec3 c = textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw, 0.0).rgb * lightmaps.data[ofs].exposure_normalization;
14421472

1443-
float specular_occlusion = (c.r * 0.3 + c.g * 0.59 + c.b * 0.11) * 2.0; // brightness from lightmap color
1473+
specular_occlusion = (c.r * 0.3 + c.g * 0.59 + c.b * 0.11) * 2.0; // brightness from lightmap color
14441474
specular_occlusion = min(1.0, specular_occlusion * lightmaps.data[ofs].exposure_normalization);
14451475

14461476
#if defined(SPECULAR_OCCLUSION_CONSERVATIVE)
@@ -1457,6 +1487,49 @@ void fragment_shader(in SceneData scene_data) {
14571487
#endif // defined(SPECULAR_OCCLUSION) || defined(SPECULAR_OCCLUSION_CONSERVATIVE)
14581488
}
14591489
}
1490+
1491+
if (!sc_use_forward_gi && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { // Inherit gi reflections on lightmapped objects
1492+
vec2 coord;
1493+
1494+
if (implementation_data.gi_upscale_for_msaa) {
1495+
vec2 base_coord = screen_uv;
1496+
vec2 closest_coord = base_coord;
1497+
#ifdef USE_MULTIVIEW
1498+
float closest_ang = dot(normal, textureLod(sampler2DArray(normal_roughness_buffer, SAMPLER_LINEAR_CLAMP), vec3(base_coord, ViewIndex), 0.0).xyz * 2.0 - 1.0);
1499+
#else // USE_MULTIVIEW
1500+
float closest_ang = dot(normal, textureLod(sampler2D(normal_roughness_buffer, SAMPLER_LINEAR_CLAMP), base_coord, 0.0).xyz * 2.0 - 1.0);
1501+
#endif // USE_MULTIVIEW
1502+
1503+
for (int i = 0; i < 4; i++) {
1504+
const vec2 neighbors[4] = vec2[](vec2(-1, 0), vec2(1, 0), vec2(0, -1), vec2(0, 1));
1505+
vec2 neighbour_coord = base_coord + neighbors[i] * scene_data.screen_pixel_size;
1506+
#ifdef USE_MULTIVIEW
1507+
float neighbour_ang = dot(normal, textureLod(sampler2DArray(normal_roughness_buffer, SAMPLER_LINEAR_CLAMP), vec3(neighbour_coord, ViewIndex), 0.0).xyz * 2.0 - 1.0);
1508+
#else // USE_MULTIVIEW
1509+
float neighbour_ang = dot(normal, textureLod(sampler2D(normal_roughness_buffer, SAMPLER_LINEAR_CLAMP), neighbour_coord, 0.0).xyz * 2.0 - 1.0);
1510+
#endif // USE_MULTIVIEW
1511+
if (neighbour_ang > closest_ang) {
1512+
closest_ang = neighbour_ang;
1513+
closest_coord = neighbour_coord;
1514+
}
1515+
}
1516+
1517+
coord = closest_coord;
1518+
1519+
} else {
1520+
coord = screen_uv;
1521+
}
1522+
1523+
#ifdef USE_MULTIVIEW
1524+
vec4 buffer_reflection = textureLod(sampler2DArray(reflection_buffer, SAMPLER_LINEAR_CLAMP), vec3(coord, ViewIndex), 0.0);
1525+
#else // USE_MULTIVIEW
1526+
vec4 buffer_reflection = textureLod(sampler2D(reflection_buffer, SAMPLER_LINEAR_CLAMP), coord, 0.0);
1527+
#endif // USE_MULTIVIEW
1528+
1529+
// try to keep SDFGI reflections while making sure dark areas from the lightmap should be dark
1530+
specular_light = mix(specular_light, buffer_reflection.rgb * min(specular_occlusion * specular_occlusion * 8.0, 1.0), buffer_reflection.a);
1531+
}
1532+
14601533
#else
14611534

14621535
if (sc_use_forward_gi && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SDFGI)) { //has lightmap capture

servers/rendering/renderer_rd/shaders/scene_forward_gi_inc.glsl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,36 @@ void voxel_gi_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3
108108
out_spec += vec4(irr_light.rgb * blend, blend);
109109
}
110110

111+
void voxel_gi_compute_irradiance_only(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, vec3 environment, inout vec4 out_spec) {
112+
position = (voxel_gi_instances.data[index].xform * vec4(position, 1.0)).xyz;
113+
ref_vec = normalize((voxel_gi_instances.data[index].xform * vec4(ref_vec, 0.0)).xyz);
114+
normal = normalize((voxel_gi_instances.data[index].xform * vec4(normal, 0.0)).xyz);
115+
116+
position += normal * voxel_gi_instances.data[index].normal_bias;
117+
118+
//this causes corrupted pixels, i have no idea why..
119+
if (any(bvec2(any(lessThan(position, vec3(0.0))), any(greaterThan(position, voxel_gi_instances.data[index].bounds))))) {
120+
return;
121+
}
122+
123+
vec3 blendv = abs(position / voxel_gi_instances.data[index].bounds * 2.0 - 1.0);
124+
float blend = clamp(1.0 - max(blendv.x, max(blendv.y, blendv.z)), 0.0, 1.0);
125+
//float blend=1.0;
126+
127+
float max_distance = length(voxel_gi_instances.data[index].bounds);
128+
vec3 cell_size = 1.0 / voxel_gi_instances.data[index].bounds;
129+
130+
//irradiance
131+
vec4 irr_light = voxel_cone_trace(voxel_gi_textures[index], cell_size, position, ref_vec, tan(roughness * 0.5 * M_PI * 0.99), max_distance, voxel_gi_instances.data[index].bias);
132+
if (voxel_gi_instances.data[index].blend_ambient) {
133+
irr_light.rgb = mix(environment, irr_light.rgb, min(1.0, irr_light.a / 0.95));
134+
}
135+
irr_light.rgb *= voxel_gi_instances.data[index].dynamic_range * voxel_gi_instances.data[index].exposure_normalization;
136+
//irr_light=vec3(0.0);
137+
138+
out_spec += vec4(irr_light.rgb * blend, blend);
139+
}
140+
111141
vec2 octahedron_wrap(vec2 v) {
112142
vec2 signVal;
113143
signVal.x = v.x >= 0.0 ? 1.0 : -1.0;

0 commit comments

Comments
 (0)