@@ -1368,6 +1368,36 @@ void fragment_shader(in SceneData scene_data) {
1368
1368
#if ! defined(MODE_RENDER_DEPTH) && ! defined(MODE_UNSHADED)
1369
1369
1370
1370
#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;
1371
1401
1372
1402
// lightmap
1373
1403
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) {
1393
1423
scene_data.emissive_exposure_normalization;
1394
1424
1395
1425
#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
1397
1427
specular_occlusion = min (1.0 , specular_occlusion * scene_data.emissive_exposure_normalization);
1398
1428
1399
1429
#if defined(SPECULAR_OCCLUSION_CONSERVATIVE)
@@ -1440,7 +1470,7 @@ void fragment_shader(in SceneData scene_data) {
1440
1470
#if defined(SPECULAR_OCCLUSION) || defined(SPECULAR_OCCLUSION_CONSERVATIVE)
1441
1471
vec3 c = textureLod(sampler2DArray (lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw, 0.0 ).rgb * lightmaps.data[ofs].exposure_normalization;
1442
1472
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
1444
1474
specular_occlusion = min (1.0 , specular_occlusion * lightmaps.data[ofs].exposure_normalization);
1445
1475
1446
1476
#if defined(SPECULAR_OCCLUSION_CONSERVATIVE)
@@ -1457,6 +1487,49 @@ void fragment_shader(in SceneData scene_data) {
1457
1487
#endif // defined(SPECULAR_OCCLUSION) || defined(SPECULAR_OCCLUSION_CONSERVATIVE)
1458
1488
}
1459
1489
}
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
+
1460
1533
#else
1461
1534
1462
1535
if (sc_use_forward_gi && bool (instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SDFGI)) { // has lightmap capture
0 commit comments