127 Commits

Author SHA1 Message Date
2434ad07f2 merge upstream 2025-06-10 20:28:46 +00:00
00493bed9c merge upstream 2025-06-07 21:35:02 +00:00
7b17633c28 Update leenkx/blender/lnx/material/make_cluster.py 2025-06-07 19:47:12 +00:00
1ef805eb0b Update leenkx/blender/lnx/material/make_mesh.py 2025-06-06 20:01:29 +00:00
cb7b041fea merge upstream 2025-06-06 19:44:32 +00:00
a0e8e1a1a6 merge upstream 2025-06-05 17:49:54 +00:00
846c3b2c11 Update leenkx/blender/lnx/material/make_mesh.py 2025-06-03 16:18:05 +00:00
b5af208766 Update leenkx/Shaders/std/shadows.glsl 2025-06-03 03:09:32 +00:00
63565052e3 Disable BayerMatrix momentaraily 2025-06-02 20:37:45 +00:00
38eb66a0b5 Update leenkx/blender/lnx/material/make_cluster.py 2025-06-02 20:35:28 +00:00
908efdd554 Update leenkx/blender/lnx/material/make_mesh.py 2025-06-02 20:33:49 +00:00
e014484d27 merge upstream 2025-06-02 20:16:04 +00:00
872433cafb Update leenkx/Shaders/voxel_temporal/voxel_temporal.comp.glsl 2025-06-01 03:42:22 +00:00
74bbb6ca87 Update leenkx/Shaders/voxel_sdf_jumpflood/voxel_sdf_jumpflood.comp.glsl 2025-06-01 03:41:14 +00:00
cbbd6fe495 Update leenkx/Shaders/voxel_offsetprev/voxel_offsetprev.comp.glsl 2025-06-01 03:40:37 +00:00
45a48acf8a Update leenkx/Sources/leenkx/renderpath/Inc.hx 2025-06-01 03:39:35 +00:00
c769b3ca26 merge upstream 2025-05-30 21:46:34 +00:00
c4378be891 Update leenkx/Shaders/voxel_temporal/voxel_temporal.comp.glsl 2025-05-30 19:19:33 +00:00
6ad615a961 Update leenkx/Shaders/std/constants.glsl 2025-05-30 19:18:06 +00:00
1e4510ba56 Update leenkx/Shaders/std/conetrace.glsl 2025-05-30 19:16:59 +00:00
a2714bf101 merge upstream 2025-05-30 19:10:59 +00:00
5639234eb9 Update leenkx/Shaders/std/light.glsl 2025-05-29 21:22:25 +00:00
1591ccdae5 Update leenkx/Shaders/deferred_light/deferred_light.json 2025-05-29 16:56:38 +00:00
9cb5232187 Update leenkx/Shaders/deferred_light/deferred_light.frag.glsl 2025-05-29 16:53:10 +00:00
6b25d8c8ad revert 13ca31f480
revert Update leenkx/Sources/leenkx/renderpath/Inc.hx
2025-05-28 01:36:04 +00:00
13ca31f480 Update leenkx/Sources/leenkx/renderpath/Inc.hx 2025-05-28 01:28:14 +00:00
d102e59040 Update leenkx/blender/lnx/material/make_voxel.py 2025-05-27 18:53:36 +00:00
df0e24c307 Update leenkx/Shaders/voxel_temporal/voxel_temporal.comp.glsl 2025-05-27 18:42:41 +00:00
2df86850f8 Update leenkx/Shaders/std/constants.glsl 2025-05-27 17:51:56 +00:00
02ff259860 Update leenkx/blender/lnx/material/make_finalize.py 2025-05-27 17:23:03 +00:00
2e6de515ef Update leenkx/Shaders/voxel_temporal/voxel_temporal.comp.glsl 2025-05-26 23:29:54 +00:00
41b840212c Update leenkx/blender/lnx/props_ui.py 2025-05-26 23:25:50 +00:00
429e6d6768 Update leenkx/Shaders/std/constants.glsl 2025-05-22 19:30:19 +00:00
2d8bfbf181 Update leenkx/Sources/leenkx/renderpath/RenderPathForward.hx 2025-05-22 03:07:01 +00:00
1ad7e0eaf4 Update leenkx/Sources/leenkx/renderpath/RenderPathDeferred.hx 2025-05-22 03:03:50 +00:00
ae72401657 Update leenkx/Sources/leenkx/renderpath/Inc.hx 2025-05-22 02:57:45 +00:00
58b9000305 Update leenkx/Shaders/voxel_temporal/voxel_temporal.comp.glsl 2025-05-22 02:27:46 +00:00
0cc86c41b8 Update leenkx/Shaders/voxel_resolve_specular/voxel_resolve_specular.comp.glsl 2025-05-22 02:25:46 +00:00
25f8c5f64c Update leenkx/Shaders/voxel_resolve_ao/voxel_resolve_ao.comp.glsl 2025-05-22 02:24:58 +00:00
109544cea9 Update leenkx/Shaders/std/light.glsl 2025-05-22 02:20:28 +00:00
4c92c4bcc9 Update leenkx/Shaders/std/conetrace.glsl 2025-05-22 02:16:35 +00:00
3433afb1c3 Update leenkx/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl 2025-05-22 02:14:06 +00:00
e22b522059 Update leenkx/Shaders/deferred_light/deferred_light.frag.glsl 2025-05-22 02:10:45 +00:00
200af34740 Update leenkx/Shaders/blur_edge_pass/blur_edge_pass.frag.glsl 2025-05-22 02:07:44 +00:00
6d7b0078b4 Update leenkx/blender/lnx/props_renderpath.py 2025-05-21 23:26:42 +00:00
fa501cb09b Update leenkx/blender/lnx/write_data.py 2025-05-21 23:18:53 +00:00
62a4bbb714 Update leenkx/blender/lnx/props_ui.py 2025-05-21 23:14:37 +00:00
eab3e3b30c Update leenkx/blender/lnx/props_renderpath.py 2025-05-21 23:07:11 +00:00
3be7528a6c Update leenkx/blender/lnx/material/make_voxel.py 2025-05-21 22:58:06 +00:00
c9dd46c5e3 Update leenkx/blender/lnx/material/make_shader.py 2025-05-21 22:56:05 +00:00
99806b8069 revert e98bfb125d
revert Update leenkx/blender/lnx/material/make_shader.py
2025-05-21 22:51:16 +00:00
e98bfb125d Update leenkx/blender/lnx/material/make_shader.py 2025-05-21 22:47:03 +00:00
c4c0e2beaa Delete leenkx/blender/lnx/material/make_refraction_buffer.py 2025-05-21 22:43:18 +00:00
36cbc934ba Update leenkx/blender/lnx/material/make_finalize.py 2025-05-21 22:42:11 +00:00
210d5ea532 Update leenkx/blender/lnx/material/make_finalize.py 2025-05-21 22:39:52 +00:00
dab9a38424 Update leenkx/blender/lnx/material/make_mesh.py 2025-05-21 22:37:15 +00:00
b7bbe40348 Update leenkx/blender/lnx/material/make_cluster.py 2025-05-21 22:33:01 +00:00
8b084156ff Update leenkx/blender/lnx/make_world.py 2025-05-21 22:29:40 +00:00
538c364f33 Update leenkx/blender/lnx/make_renderpath.py 2025-05-21 22:26:58 +00:00
09eee93ac9 Update leenkx/Sources/iron/object/Uniforms.hx 2025-05-21 16:25:58 +00:00
8b5a77c001 Update leenkx/Sources/leenkx/renderpath/RenderPathForward.hx 2025-05-21 16:23:20 +00:00
436b7fac02 Update leenkx/Sources/leenkx/renderpath/RenderPathDeferred.hx 2025-05-21 16:21:05 +00:00
9ef9f5a637 Update leenkx/Sources/leenkx/renderpath/Inc.hx 2025-05-21 16:15:50 +00:00
b8ca4be56a Update leenkx/Shaders/voxel_temporal/voxel_temporal.comp.glsl 2025-05-21 16:08:14 +00:00
29e4993f06 Update leenkx/Shaders/voxel_sdf_jumpflood/voxel_sdf_jumpflood.comp.glsl 2025-05-21 16:05:53 +00:00
4134352688 Update leenkx/Shaders/voxel_resolve_specular/voxel_resolve_specular.comp.glsl 2025-05-21 02:10:21 +00:00
25cf758a33 Update leenkx/Shaders/voxel_resolve_diffuse/voxel_resolve_diffuse.comp.glsl 2025-05-21 02:08:50 +00:00
23af038a16 Update leenkx/Shaders/voxel_resolve_ao/voxel_resolve_ao.comp.glsl 2025-05-21 02:07:21 +00:00
7f7878aaa6 Update leenkx/Shaders/voxel_offsetprev/voxel_offsetprev.comp.glsl 2025-05-21 02:05:33 +00:00
d7e076fb56 Add leenkx/Shaders/voxel_light/voxel_light.comp.glsl 2025-05-21 02:02:05 +00:00
dab915b60d Delete leenkx/Shaders/voxel_light.comp.glsl 2025-05-21 02:01:43 +00:00
74389ba76a Add leenkx/Shaders/voxel_light.comp.glsl 2025-05-21 02:01:35 +00:00
bd5afc797d Update leenkx/Shaders/std/shadows.glsl 2025-05-21 01:05:37 +00:00
27b4ec42a8 Update leenkx/Shaders/std/light.glsl 2025-05-21 01:04:30 +00:00
ab7edaa9e3 Update leenkx/Shaders/std/constants.glsl 2025-05-21 01:02:56 +00:00
27540ac7e9 Update leenkx/Shaders/std/conetrace.glsl 2025-05-21 01:01:47 +00:00
a5b512f20b Update leenkx/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl 2025-05-21 00:55:14 +00:00
f8d0e67f33 Update leenkx/Shaders/ssr_pass/ssr_pass.frag.glsl 2025-05-21 00:51:33 +00:00
915118617d Update leenkx/Shaders/ssgi_pass/ssgi_pass.json 2025-05-21 00:50:45 +00:00
ea69511e67 Update leenkx/Shaders/ssgi_pass/ssgi_pass.frag.glsl 2025-05-21 00:47:22 +00:00
3926a7f83e Update leenkx/Shaders/deferred_light/deferred_light.json 2025-05-21 00:42:00 +00:00
0eafd14ae2 Update leenkx/Shaders/deferred_light/deferred_light.frag.glsl 2025-05-21 00:40:56 +00:00
08614512d7 Update leenkx/Shaders/blur_edge_pass/blur_edge_pass.frag.glsl 2025-05-21 00:19:31 +00:00
08261a9335 Update leenkx/Shaders/blur_edge_pass/blur_edge_pass.frag.glsl 2025-05-21 00:16:55 +00:00
ce3c1cea6a Delete leenkx/Shaders/voxel_resolve_shadows/voxel_resolve_shadows.comp.glsl 2025-05-21 00:00:40 +00:00
392d12a816 Delete leenkx/Shaders/voxel_resolve_refraction/voxel_resolve_refraction.comp.glsl 2025-05-21 00:00:32 +00:00
6b423038d4 Delete leenkx/Shaders/voxel_light/voxel_light.comp.glsl 2025-05-21 00:00:02 +00:00
76628fc010 Add leenkx/Shaders/std/aabb.glsl 2025-05-20 23:57:25 +00:00
99f687b10c Update leenkx/Shaders/std/constants.glsl 2025-05-20 23:55:32 +00:00
316441b954 merge upstream 2025-05-20 20:00:31 +00:00
9bf83bc49f Update leenkx/blender/lnx/material/make_mesh.py 2025-04-18 22:52:53 +00:00
d88e1f0f42 Update leenkx/blender/lnx/material/make_cluster.py 2025-04-18 22:52:03 +00:00
96f4e29778 Update leenkx/blender/lnx/material/make_mesh.py 2025-04-12 08:49:04 +00:00
1d705d2ca2 Update leenkx/blender/lnx/material/make_cluster.py 2025-04-12 08:48:33 +00:00
0979cd976f Update leenkx/blender/lnx/write_data.py 2025-04-11 22:20:24 +00:00
db6d786ee4 merge upstream 2025-04-11 22:06:01 +00:00
106e36e30d merge upstream 2025-04-10 17:16:12 +00:00
2bb296028f merge upstream 2025-04-09 17:30:27 +00:00
25d7ba3e72 merge upstream 2025-04-08 06:33:53 +00:00
bf7b4416ec Update leenkx/blender/lnx/make_renderpath.py 2025-04-07 17:29:09 +00:00
a2d03cfe6e Update leenkx/Shaders/std/light.glsl 2025-04-07 17:26:00 +00:00
95f0ecfc54 Update leenkx/Sources/leenkx/system/Starter.hx 2025-04-07 17:07:52 +00:00
07f59224fc Update leenkx/blender/lnx/write_data.py 2025-04-07 16:50:46 +00:00
02259985be Update leenkx/blender/lnx/props.py 2025-04-07 16:46:33 +00:00
6b8585c81a Update leenkx/blender/lnx/props_renderpath.py 2025-04-07 16:43:01 +00:00
5d78eabf94 Update leenkx/blender/lnx/material/cycles_nodes/nodes_texture.py 2025-04-07 16:39:49 +00:00
41c1459c4e Update leenkx/blender/lnx/material/make_voxel.py 2025-04-07 16:34:12 +00:00
304a497565 Update leenkx/blender/lnx/make_renderpath.py 2025-04-07 16:27:25 +00:00
9fa399371a Update leenkx/blender/lnx/material/make_mesh.py 2025-04-07 16:25:06 +00:00
4625fdb6b2 Update leenkx/blender/lnx/material/make_cluster.py 2025-04-07 16:13:16 +00:00
79553927aa Update leenkx/Shaders/water_pass/water_pass.frag.glsl 2025-04-07 16:06:53 +00:00
86661c1012 Update leenkx/Shaders/voxel_light/voxel_light.comp.glsl 2025-04-07 16:04:17 +00:00
03967c7a2b Update leenkx/Sources/leenkx/system/Starter.hx 2025-04-07 15:50:41 +00:00
61fd48a12f Update leenkx/Shaders/ssr_pass/ssr_pass.frag.glsl 2025-04-07 15:47:22 +00:00
519039b8b6 Update leenkx/Shaders/std/light.glsl 2025-04-07 15:45:04 +00:00
5244b1b3e8 Update leenkx/Sources/leenkx/renderpath/RenderPathForward.hx 2025-04-07 15:41:41 +00:00
7ae3bbe496 Update leenkx/Sources/leenkx/renderpath/RenderPathDeferred.hx 2025-04-07 15:39:38 +00:00
001be2f8da Update leenkx/Sources/leenkx/renderpath/Inc.hx 2025-04-07 15:35:22 +00:00
6a25b3c5d7 Update leenkx/Shaders/deferred_light/deferred_light.frag.glsl 2025-04-07 15:28:46 +00:00
8d4ac7251a Update leenkx/Shaders/voxel_temporal/voxel_temporal.comp.glsl 2025-04-07 15:22:49 +00:00
ae63b252c6 Update leenkx/Shaders/voxel_sdf_jumpflood/voxel_sdf_jumpflood.comp.glsl 2025-04-07 15:19:03 +00:00
ee73823206 Update leenkx/Shaders/voxel_resolve_specular/voxel_resolve_specular.comp.glsl 2025-04-07 15:17:43 +00:00
af2850e20c Update leenkx/Shaders/voxel_resolve_diffuse/voxel_resolve_diffuse.comp.glsl 2025-04-07 14:49:37 +00:00
bc4a31d415 Update leenkx/Shaders/voxel_resolve_ao/voxel_resolve_ao.comp.glsl 2025-04-07 14:47:58 +00:00
5303ad3ac6 Update leenkx/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl 2025-04-07 14:44:14 +00:00
5153cff790 Update leenkx/Shaders/std/shadows.glsl 2025-04-07 14:41:53 +00:00
abe17870ce Update leenkx/Shaders/std/conetrace.glsl 2025-04-07 14:38:30 +00:00
36 changed files with 3502 additions and 2093 deletions

View File

@ -29,10 +29,11 @@ uniform sampler2D gbuffer1;
#ifdef _VoxelGI #ifdef _VoxelGI
uniform sampler2D voxels_diffuse; uniform sampler2D voxels_diffuse;
uniform sampler2D voxels_specular; uniform sampler2D voxels_specular;
#endif #else
#ifdef _VoxelAOvar #ifdef _VoxelAOvar
uniform sampler2D voxels_ao; uniform sampler2D voxels_ao;
#endif #endif
#endif
#ifdef _VoxelShadow #ifdef _VoxelShadow
uniform sampler3D voxels; uniform sampler3D voxels;
uniform sampler3D voxelsSDF; uniform sampler3D voxelsSDF;
@ -56,6 +57,10 @@ uniform vec3 backgroundCol;
#ifdef _SSAO #ifdef _SSAO
uniform sampler2D ssaotex; uniform sampler2D ssaotex;
#else
#ifdef _SSGI
uniform sampler2D ssaotex;
#endif
#endif #endif
#ifdef _SSS #ifdef _SSS
@ -113,11 +118,15 @@ uniform vec2 cameraPlane;
#ifdef _SinglePoint #ifdef _SinglePoint
#ifdef _Spot #ifdef _Spot
//!uniform sampler2DShadow shadowMapSpot[1]; //!uniform sampler2DShadow shadowMapSpot[1];
#ifdef _ShadowMapTransparent
//!uniform sampler2D shadowMapSpotTransparent[1]; //!uniform sampler2D shadowMapSpotTransparent[1];
#endif
//!uniform mat4 LWVPSpot[1]; //!uniform mat4 LWVPSpot[1];
#else #else
//!uniform samplerCubeShadow shadowMapPoint[1]; //!uniform samplerCubeShadow shadowMapPoint[1];
#ifdef _ShadowMapTransparent
//!uniform samplerCube shadowMapPointTransparent[1]; //!uniform samplerCube shadowMapPointTransparent[1];
#endif
//!uniform vec2 lightProj; //!uniform vec2 lightProj;
#endif #endif
#endif #endif
@ -125,30 +134,40 @@ uniform vec2 cameraPlane;
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
#ifdef _SingleAtlas #ifdef _SingleAtlas
uniform sampler2DShadow shadowMapAtlas; uniform sampler2DShadow shadowMapAtlas;
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapAtlasTransparent; uniform sampler2D shadowMapAtlasTransparent;
#endif #endif
#endif
#endif #endif
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
#ifndef _SingleAtlas #ifndef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlasPoint; //!uniform sampler2DShadow shadowMapAtlasPoint;
#ifdef _ShadowMapTransparent
//!uniform sampler2D shadowMapAtlasPointTransparent; //!uniform sampler2D shadowMapAtlasPointTransparent;
#endif #endif
//!uniform vec4 pointLightDataArray[4]; #endif
//!uniform vec4 pointLightDataArray[maxLightsCluster * 6];
#else #else
//!uniform samplerCubeShadow shadowMapPoint[4]; //!uniform samplerCubeShadow shadowMapPoint[4];
#ifdef _ShadowMapTransparent
//!uniform samplerCube shadowMapPointTransparent[4]; //!uniform samplerCube shadowMapPointTransparent[4];
#endif
#endif #endif
//!uniform vec2 lightProj; //!uniform vec2 lightProj;
#ifdef _Spot #ifdef _Spot
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
#ifndef _SingleAtlas #ifndef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlasSpot; //!uniform sampler2DShadow shadowMapAtlasSpot;
#ifdef _ShadowMapTransparent
//!uniform sampler2D shadowMapAtlasSpotTransparent; //!uniform sampler2D shadowMapAtlasSpotTransparent;
#endif #endif
#endif
#else #else
//!uniform sampler2DShadow shadowMapSpot[4]; //!uniform sampler2DShadow shadowMapSpot[4];
#ifdef _ShadowMapTransparent
//!uniform sampler2D shadowMapSpotTransparent[4]; //!uniform sampler2D shadowMapSpotTransparent[4];
#endif #endif
#endif
//!uniform mat4 LWVPSpotArray[maxLightsCluster]; //!uniform mat4 LWVPSpotArray[maxLightsCluster];
#endif #endif
#endif #endif
@ -161,12 +180,16 @@ uniform vec3 sunCol;
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
#ifndef _SingleAtlas #ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSun; uniform sampler2DShadow shadowMapAtlasSun;
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapAtlasSunTransparent; uniform sampler2D shadowMapAtlasSunTransparent;
#endif #endif
#endif
#else #else
uniform sampler2DShadow shadowMap; uniform sampler2DShadow shadowMap;
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapTransparent; uniform sampler2D shadowMapTransparent;
#endif #endif
#endif
uniform float shadowsBias; uniform float shadowsBias;
#ifdef _CSM #ifdef _CSM
//!uniform vec4 casData[shadowmapCascades * 4 + 4]; //!uniform vec4 casData[shadowmapCascades * 4 + 4];
@ -227,17 +250,22 @@ void main() {
vec4 g2 = textureLod(gbuffer2, texCoord, 0.0); vec4 g2 = textureLod(gbuffer2, texCoord, 0.0);
#endif #endif
#ifdef _MicroShadowing #ifdef _MicroShadowing
occspec.x = mix(1.0, occspec.x, dotNV); // AO Fresnel occspec.x = mix(1.0, occspec.x, dotNV); // AO Fresnel
#endif #endif
#ifdef _Brdf #ifdef _Brdf
vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy; vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy;
vec3 F = f0 * envBRDF.x + envBRDF.y;
#else
vec3 F = f0;
#endif #endif
#ifndef _VoxelAOvar
#ifndef _VoxelGI
// Envmap // Envmap
#ifdef _Irr #ifdef _Irr
vec3 envl = shIrradiance(n, shirr); vec3 envl = shIrradiance(n, shirr);
#ifdef _gbuffer2 #ifdef _gbuffer2
@ -271,33 +299,33 @@ void main() {
envl.rgb *= albedo; envl.rgb *= albedo;
#ifdef _Brdf #ifdef _Brdf
envl.rgb *= 1.0 - (f0 * envBRDF.x + envBRDF.y); //LV: We should take refracted light into account envl.rgb *= 1.0 - F; //LV: We should take refracted light into account
#endif #endif
#ifdef _Rad // Indirect specular #ifdef _Rad // Indirect specular
envl.rgb += prefilteredColor * (f0 * envBRDF.x + envBRDF.y); //LV: Removed "1.5 * occspec.y". Specular should be weighted only by FV LUT envl.rgb += prefilteredColor * F; //LV: Removed "1.5 * occspec.y". Specular should be weighted only by FV LUT
#else #else
#ifdef _EnvCol #ifdef _EnvCol
envl.rgb += backgroundCol * (f0 * envBRDF.x + envBRDF.y); //LV: Eh, what's the point of weighting it only by F0? envl.rgb += backgroundCol * F; //LV: Eh, what's the point of weighting it only by F0?
#endif #endif
#endif #endif
envl.rgb *= envmapStrength * occspec.x; envl.rgb *= envmapStrength * occspec.x;
#ifdef _VoxelGI
vec4 indirect_diffuse = textureLod(voxels_diffuse, texCoord, 0.0);
fragColor.rgb = (indirect_diffuse.rgb * albedo + envl.rgb * (1.0 - indirect_diffuse.a)) * voxelgiDiff;
if(roughness < 1.0 && occspec.y > 0.0)
fragColor.rgb += textureLod(voxels_specular, texCoord, 0.0).rgb * occspec.y * voxelgiRefl;
#endif
#ifdef _VoxelAOvar
envl.rgb *= textureLod(voxels_ao, texCoord, 0.0).r;
#endif
#ifndef _VoxelGI
fragColor.rgb = envl; fragColor.rgb = envl;
#endif #endif
#endif
#ifdef _VoxelGI
fragColor.rgb = textureLod(voxels_diffuse, texCoord, 0.0).rgb * voxelgiDiff;
if(roughness < 1.0 && occspec.y > 0.0)
fragColor.rgb += textureLod(voxels_specular, texCoord, 0.0).rgb * F * voxelgiRefl;
#else
#ifdef _VoxelAOvar
fragColor.rgb = textureLod(voxels_ao, texCoord, 0.0).rgb * voxelgiOcc;
#endif
#endif
// Show voxels // Show voxels
// vec3 origin = vec3(texCoord * 2.0 - 1.0, 0.99); // vec3 origin = vec3(texCoord * 2.0 - 1.0, 0.99);
// vec3 direction = vec3(0.0, 0.0, -1.0); // vec3 direction = vec3(0.0, 0.0, -1.0);
@ -317,6 +345,10 @@ void main() {
// #else // #else
fragColor.rgb *= textureLod(ssaotex, texCoord, 0.0).r; fragColor.rgb *= textureLod(ssaotex, texCoord, 0.0).r;
// #endif // #endif
#else
#ifdef _SSGI
fragColor.rgb += textureLod(ssaotex, texCoord, 0.0).rgb;
#endif
#endif #endif
#ifdef _EmissionShadeless #ifdef _EmissionShadeless
@ -349,40 +381,70 @@ void main() {
#ifdef _ShadowMap #ifdef _ShadowMap
#ifdef _CSM #ifdef _CSM
svisibility = shadowTestCascade( svisibility = shadowTestCascade(
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
#ifndef _SingleAtlas #ifdef _ShadowMapTransparent
shadowMapAtlasSun, shadowMapAtlasSunTransparent #ifndef _SingleAtlas
#else shadowMapAtlasSun, shadowMapAtlasSunTransparent
shadowMapAtlas, shadowMapAtlasTransparent #else
#endif shadowMapAtlas, shadowMapAtlasTransparent
#else #endif
shadowMap, shadowMapTransparent #else
#endif #ifndef _SingleAtlas
, eye, p + n * shadowsBias * 10, shadowsBias, false shadowMapAtlasSun
); #else
shadowMapAtlas
#endif
#endif
#else
#ifdef _ShadowMapTransparent
shadowMap, shadowMapTransparent
#else
shadowMap
#endif
#endif
, eye, p + n * shadowsBias * 10, shadowsBias
#ifdef _ShadowMapTransparent
, false
#endif
);
#else #else
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0); vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
if (lPos.w > 0.0) { if (lPos.w > 0.0) {
svisibility = shadowTest( svisibility = shadowTest(
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
#ifndef _SingleAtlas #ifdef _ShadowMapTransparent
shadowMapAtlasSun, shadowMapAtlasSunTransparent #ifndef _SingleAtlas
#else shadowMapAtlasSun, shadowMapAtlasSunTransparent
shadowMapAtlas, shadowMapAtlasTransparent #else
#endif shadowMapAtlas, shadowMapAtlasTransparent
#else #endif
shadowMap, shadowMapTransparent #else
#endif #ifndef _SingleAtlas
, lPos.xyz / lPos.w, shadowsBias, false shadowMapAtlasSun
); #else
shadowMapAtlas
#endif
#endif
#else
#ifdef _ShadowMapTransparent
shadowMap, shadowMapTransparent
#else
shadowMap
#endif
#endif
, lPos.xyz / lPos.w, shadowsBias
#ifdef _ShadowMapTransparent
, false
#endif
);
} }
#endif #endif
#endif #endif
#ifdef _VoxelShadow #ifdef _VoxelShadow
svisibility *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy).r) * voxelgiShad; svisibility *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy, -g2.rg).r) * voxelgiShad;
#endif #endif
#ifdef _SSRS #ifdef _SSRS
// vec2 coords = getProjectedCoord(hitCoord); // vec2 coords = getProjectedCoord(hitCoord);
// vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy); // vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy);
@ -439,13 +501,16 @@ void main() {
fragColor.rgb += sampleLight( fragColor.rgb += sampleLight(
p, n, v, dotNV, pointPos, pointCol, albedo, roughness, occspec.y, f0 p, n, v, dotNV, pointPos, pointCol, albedo, roughness, occspec.y, f0
#ifdef _ShadowMap #ifdef _ShadowMap
, 0, pointBias, true, false , 0, pointBias, true
#ifdef _ShadowMapTransparent
, false
#endif
#endif #endif
#ifdef _Spot #ifdef _Spot
, true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight , true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight
#endif #endif
#ifdef _VoxelShadow #ifdef _VoxelShadow
, voxels, voxelsSDF, clipmaps , voxels, voxelsSDF, clipmaps, -g2.rg
#endif #endif
#ifdef _MicroShadowing #ifdef _MicroShadowing
, occspec.x , occspec.x
@ -492,7 +557,10 @@ void main() {
f0 f0
#ifdef _ShadowMap #ifdef _ShadowMap
// light index, shadow bias, cast_shadows // light index, shadow bias, cast_shadows
, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0, false , li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0
#ifdef _ShadowMapTransparent
, false
#endif
#endif #endif
#ifdef _Spot #ifdef _Spot
, lightsArray[li * 3 + 2].y != 0.0 , lightsArray[li * 3 + 2].y != 0.0
@ -503,7 +571,7 @@ void main() {
, lightsArraySpot[li * 2 + 1].xyz // right , lightsArraySpot[li * 2 + 1].xyz // right
#endif #endif
#ifdef _VoxelShadow #ifdef _VoxelShadow
, voxels, voxelsSDF, clipmaps , voxels, voxelsSDF, clipmaps, -g2.rg
#endif #endif
#ifdef _MicroShadowing #ifdef _MicroShadowing
, occspec.x , occspec.x
@ -514,14 +582,5 @@ void main() {
); );
} }
#endif // _Clusters #endif // _Clusters
/*
#ifdef _VoxelRefract
if(opac < 1.0) {
vec3 refraction = traceRefraction(p, n, voxels, v, ior, roughness, eye) * voxelgiRefr;
fragColor.rgb = mix(refraction, fragColor.rgb, opac);
}
#endif
*/
fragColor.a = 1.0; // Mark as opaque fragColor.a = 1.0; // Mark as opaque
} }

View File

@ -1,107 +1,506 @@
#version 450 #version 450
#include "compiled.inc" #include "compiled.inc"
#include "std/math.glsl"
#include "std/gbuffer.glsl" #include "std/gbuffer.glsl"
#include "std/brdf.glsl"
#include "std/math.glsl"
#ifdef _Clusters
#include "std/clusters.glsl"
#endif
#ifdef _ShadowMap
#include "std/shadows.glsl"
#endif
#ifdef _LTC
#include "std/ltc.glsl"
#endif
#ifdef _LightIES
#include "std/ies.glsl"
#endif
#ifdef _Spot
#include "std/light_common.glsl"
#endif
#include "std/constants.glsl"
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbufferD; uniform sampler2D gbufferD;
uniform sampler2D gbuffer0; // Normal #ifdef _EmissionShaded
// #ifdef _RTGI uniform sampler2D gbufferEmission;
// uniform sampler2D gbuffer1; // Basecol #endif
// #endif uniform sampler2D sveloc;
uniform mat4 P;
uniform mat3 V3;
uniform vec2 cameraProj; uniform vec2 cameraProj;
uniform vec3 eye;
uniform vec3 eyeLook;
uniform vec2 screenSize;
uniform mat4 invVP;
const float angleMix = 0.5f; in vec2 texCoord;
#ifdef _SSGICone9 in vec3 viewRay;
const float strength = 2.0 * (1.0 / ssgiStrength); out vec3 fragColor;
#else
const float strength = 2.0 * (1.0 / ssgiStrength) * 1.8; float metallic;
uint matid;
#ifdef _SMSizeUniform
//!uniform vec2 smSizeUniform;
#endif #endif
in vec3 viewRay; #ifdef _Clusters
in vec2 texCoord; uniform vec4 lightsArray[maxLights * 3];
out float fragColor; #ifdef _Spot
uniform vec4 lightsArraySpot[maxLights * 2];
vec3 hitCoord;
vec2 coord;
float depth;
// #ifdef _RTGI
// vec3 col = vec3(0.0);
// #endif
vec3 vpos;
vec2 getProjectedCoord(vec3 hitCoord) {
vec4 projectedCoord = P * vec4(hitCoord, 1.0);
projectedCoord.xy /= projectedCoord.w;
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
#ifdef _InvY
projectedCoord.y = 1.0 - projectedCoord.y;
#endif #endif
return projectedCoord.xy; uniform sampler2D clustersData;
} uniform vec2 cameraPlane;
#endif
float getDeltaDepth(vec3 hitCoord) { #ifdef _SinglePoint // Fast path for single light
coord = getProjectedCoord(hitCoord); uniform vec3 pointPos;
depth = textureLod(gbufferD, coord, 0.0).r * 2.0 - 1.0; uniform vec3 pointCol;
vec3 p = getPosView(viewRay, depth, cameraProj); #ifdef _ShadowMap
return p.z - hitCoord.z; uniform float pointBias;
} #endif
#ifdef _Spot
uniform vec3 spotDir;
uniform vec3 spotRight;
uniform vec4 spotData;
#endif
#endif
void rayCast(vec3 dir) { #ifdef _CPostprocess
hitCoord = vpos; uniform vec3 PPComp12;
dir *= ssgiRayStep * 2; #endif
float dist = 0.15;
for (int i = 0; i < ssgiMaxSteps; i++) { #ifdef _ShadowMap
hitCoord += dir; #ifdef _SinglePoint
float delta = getDeltaDepth(hitCoord); #ifdef _Spot
if (delta > 0.0 && delta < 0.2) { #ifndef _LTC
dist = distance(vpos, hitCoord); uniform sampler2DShadow shadowMapSpot[1];
break; uniform sampler2D shadowMapSpotTransparent[1];
uniform mat4 LWVPSpot[1];
#endif
#else
uniform samplerCubeShadow shadowMapPoint[1];
uniform samplerCube shadowMapPointTransparent[1];
uniform vec2 lightProj;
#endif
#endif
#ifdef _Clusters
#ifdef _SingleAtlas
uniform sampler2DShadow shadowMapAtlas;
uniform sampler2D shadowMapAtlasTransparent;
#endif
uniform vec2 lightProj;
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasPoint;
uniform sampler2D shadowMapAtlasPointTransparent;
//!uniform vec4 pointLightDataArray[maxLightsCluster * 6];
#else
uniform samplerCubeShadow shadowMapPoint[4];
uniform samplerCube shadowMapPointTransparent[4];
#endif
#endif
#ifdef _Spot
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSpot;
uniform sampler2D shadowMapAtlasSpotTransparent;
#endif
#else
uniform sampler2DShadow shadowMapSpot[4];
uniform sampler2D shadowMapSpotTransparent[4];
#endif
uniform mat4 LWVPSpotArray[maxLightsCluster];
#endif
#endif
#endif
#ifdef _LTC
uniform vec3 lightArea0;
uniform vec3 lightArea1;
uniform vec3 lightArea2;
uniform vec3 lightArea3;
uniform sampler2D sltcMat;
uniform sampler2D sltcMag;
#ifdef _ShadowMap
#ifndef _Spot
#ifdef _SinglePoint
uniform sampler2DShadow shadowMapSpot[1];
uniform sampler2D shadowMapSpotTransparent[1];
uniform mat4 LWVPSpot[1];
#endif
#ifdef _Clusters
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
uniform mat4 LWVPSpotArray[maxLightsCluster];
#endif
#endif
#endif
#endif
#ifdef _Sun
uniform vec3 sunDir;
uniform vec3 sunCol;
#ifdef _ShadowMap
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSun;
uniform sampler2D shadowMapAtlasSunTransparent;
#endif
#else
uniform sampler2DShadow shadowMap;
uniform sampler2D shadowMapTransparent;
#endif
uniform float shadowsBias;
#ifdef _CSM
//!uniform vec4 casData[shadowmapCascades * 4 + 4];
#else
uniform mat4 LWVP;
#endif
#endif // _ShadowMap
#endif
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 lp, const vec3 lightCol
#ifdef _ShadowMap
, int index, float bias, bool receiveShadow, bool transparent
#endif
#ifdef _Spot
, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
#endif
) {
vec3 ld = lp - p;
vec3 l = normalize(ld);
vec3 visibility = lightCol;
visibility *= attenuate(distance(p, lp));
#ifdef _LTC
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
visibility *= shadowTest(shadowMapSpot[0],
shadowMapSpotTransparent[0],
lPos.xyz / lPos.w, bias, transparent);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
if (index == 0) visibility *= shadowTest(shadowMapSpot[0],
shadowMapSpotTransparent[0],
lPos.xyz / lPos.w, bias, transparent);
else if (index == 1) visibility *= shadowTest(shadowMapSpot[1],
shadowMapSpotTransparent[1],
, lPos.xyz / lPos.w, bias, transparent);
else if (index == 2) visibility *= shadowTest(shadowMapSpot[2],
shadowMapSpotTransparent[2],
lPos.xyz / lPos.w, bias, transparent);
else if (index == 3) visibility *= shadowTest(shadowMapSpot[3],
shadowMapSpotTransparent[3],
lPos.xyz / lPos.w, bias, transparent);
#endif
} }
#endif
return visibility;
#endif
#ifdef _Spot
if (isSpot) {
visibility *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
visibility *= shadowTest(shadowMapSpot[0],
shadowMapSpotTransparent[0],
lPos.xyz / lPos.w, bias, transparent);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
#ifdef _ShadowMapAtlas
visibility *= shadowTest(
#ifndef _SingleAtlas
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
#endif
, lPos.xyz / lPos.w, bias, transparent
);
#else
if (index == 0) visibility *= shadowTest(shadowMapSpot[0],
shadowMapSpotTransparent[0],
lPos.xyz / lPos.w, bias, transparent);
else if (index == 1) visibility *= shadowTest(shadowMapSpot[1],
shadowMapSpotTransparent[1],
lPos.xyz / lPos.w, bias, transparent);
else if (index == 2) visibility *= shadowTest(shadowMapSpot[2],
shadowMapSpotTransparent[2],
lPos.xyz / lPos.w, bias, transparent);
else if (index == 3) visibility *= shadowTest(shadowMapSpot[3],
shadowMapSpotTransparent[3],
lPos.xyz / lPos.w, bias, transparent);
#endif
#endif
}
#endif
return visibility;
} }
fragColor += dist; #endif
// #ifdef _RTGI
// col += textureLod(gbuffer1, coord, 0.0).rgb * ((ssgiRayStep * ssgiMaxSteps) - dist); #ifdef _LightIES
// #endif visibility *= iesAttenuation(-l);
#endif
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
#ifndef _Spot
visibility *= PCFCube(shadowMapPoint[0],
shadowMapPointTransparent[0],
ld, -l, bias, lightProj, n, transparent);
#endif
#endif
#ifdef _Clusters
#ifdef _ShadowMapAtlas
visibility *= PCFFakeCube(
#ifndef _SingleAtlas
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
#endif
, ld, -l, bias, lightProj, n, index, transparent
);
#else
if (index == 0) visibility *= PCFCube(shadowMapPoint[0],
shadowMapPointTransparent[0],
ld, -l, bias, lightProj, n, transparent);
else if (index == 1) visibility *= PCFCube(shadowMapPoint[1],
shadowMapPointTransparent[1],
ld, -l, bias, lightProj, n, transparent);
else if (index == 2) visibility *= PCFCube(shadowMapPoint[2],
shadowMapPointTransparent[2],
ld, -l, bias, lightProj, n, transparent);
else if (index == 3) visibility *= PCFCube(shadowMapPoint[3],
shadowMapPointTransparent[3],
ld, -l, bias, lightProj, n, transparent);
#endif
#endif
}
#endif
return visibility;
} }
vec3 tangent(const vec3 n) { vec3 getVisibility(vec3 p, vec3 n, float depth, vec2 uv) {
vec3 t1 = cross(n, vec3(0, 0, 1)); vec3 visibility = vec3(0.0);
vec3 t2 = cross(n, vec3(0, 1, 0)); #ifdef _Sun
if (length(t1) > length(t2)) return normalize(t1); #ifdef _ShadowMap
else return normalize(t2); #ifdef _CSM
visibility = shadowTestCascade(
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
shadowMapAtlasSun, shadowMapAtlasSunTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
#endif
#else
shadowMap, shadowMapTransparent
#endif
, eye, p + n * shadowsBias * 10, shadowsBias, false
);
#else
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
if (lPos.w > 0.0) {
visibility = shadowTest(
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
shadowMapAtlasSun, shadowMapAtlasSunTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
#endif
#else
shadowMap, shadowMapTransparent
#endif
, lPos.xyz / lPos.w, shadowsBias, false
);
}
#endif
#endif
#endif
#ifdef _SinglePoint
visibility += sampleLight(
p, n, pointPos, pointCol
#ifdef _ShadowMap
, 0, pointBias, true, false
#endif
#ifdef _Spot
, true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight
#endif
);
#endif
#ifdef _Clusters
float viewz = linearize(depth, cameraProj);
int clusterI = getClusterI(uv, viewz, cameraPlane);
int numLights = int(texelFetch(clustersData, ivec2(clusterI, 0), 0).r * 255);
#ifdef HLSL
viewz += textureLod(clustersData, vec2(0.0), 0.0).r * 1e-9; // TODO: krafix bug, needs to generate sampler
#endif
#ifdef _Spot
int numSpots = int(texelFetch(clustersData, ivec2(clusterI, 1 + maxLightsCluster), 0).r * 255);
int numPoints = numLights - numSpots;
#endif
for (int i = 0; i < min(numLights, maxLightsCluster); i++) {
int li = int(texelFetch(clustersData, ivec2(clusterI, i + 1), 0).r * 255);
visibility += sampleLight(
p,
n,
lightsArray[li * 3].xyz, // lp
lightsArray[li * 3 + 1].xyz // lightCol
#ifdef _ShadowMap
// light index, shadow bias, cast_shadows
, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0, false
#endif
#ifdef _Spot
, lightsArray[li * 3 + 2].y != 0.0
, lightsArray[li * 3 + 2].y // spot size (cutoff)
, lightsArraySpot[li * 2].w // spot blend (exponent)
, lightsArraySpot[li * 2].xyz // spotDir
, vec2(lightsArray[li * 3].w, lightsArray[li * 3 + 1].w) // scale
, lightsArraySpot[li * 2 + 1].xyz // right
#endif
);
}
#endif // _Clusters
return visibility;
} }
vec3 getWorldPos(vec2 uv, float depth) {
vec4 pos = invVP * vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
return pos.xyz / pos.w;
}
vec3 getNormal(vec2 uv) {
vec4 g0 = textureLod(gbuffer0, uv, 0.0);
vec2 enc = g0.rg;
vec3 n;
n.z = 1.0 - abs(enc.x) - abs(enc.y);
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
return normalize(n);
}
vec3 calculateIndirectLight(vec2 uv, vec3 pos, vec3 normal, float depth) {
// Simplified visibility - replace with your full visibility function if needed
vec3 sampleColor = textureLod(gbuffer1, uv, 0.0).rgb * getVisibility(pos, normal, depth, uv);
#ifdef _EmissionShadeless
if (matid == 1) { // pure emissive material, color stored in basecol
sampleColor += textureLod(gbuffer1, uv, 0.0).rgb;
}
#endif
#ifdef _EmissionShaded
#ifdef _EmissionShadeless
else {
#endif
vec3 sampleEmission = textureLod(gbufferEmission, uv, 0.0).rgb;
sampleColor += sampleEmission; // Emission should be added directly
#ifdef _EmissionShadeless
}
#endif
#endif
return sampleColor;
}
// Improved sampling parameters
const float GOLDEN_ANGLE = 2.39996323;
const float MAX_DEPTH_DIFFERENCE = 0.9; // More conservative depth threshold
const float SAMPLE_BIAS = 0.01; // Small offset to avoid self-occlusion
void main() { void main() {
fragColor = 0; float depth = textureLod(gbufferD, texCoord, 0.0).r;
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0); if (depth >= 1.0) {
float d = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0; fragColor = vec3(0.0);
return;
}
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0); // Normal.xy, roughness, metallic/matid
unpackFloatInt16(g0.a, metallic, matid);
vec2 velocity = -textureLod(sveloc, texCoord, 0.0).rg;
vec2 enc = g0.rg;
vec3 n; vec3 n;
n.z = 1.0 - abs(enc.x) - abs(enc.y); n.z = 1.0 - abs(g0.x) - abs(g0.y);
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy); n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
n = normalize(V3 * n); n = normalize(n);
vpos = getPosView(viewRay, d, cameraProj); vec3 pos = getWorldPos(texCoord, depth);
vec3 normal = getNormal(texCoord);
vec3 centerColor = textureLod(gbuffer1, texCoord, 0.0).rgb;
rayCast(n); float radius = ssaoRadius;
vec3 o1 = normalize(tangent(n));
vec3 o2 = (cross(o1, n));
vec3 c1 = 0.5f * (o1 + o2);
vec3 c2 = 0.5f * (o1 - o2);
rayCast(mix(n, o1, angleMix));
rayCast(mix(n, o2, angleMix));
rayCast(mix(n, -c1, angleMix));
rayCast(mix(n, -c2, angleMix));
#ifdef _SSGICone9 vec3 gi = vec3(0.0);
rayCast(mix(n, -o1, angleMix)); float totalWeight = 0.0;
rayCast(mix(n, -o2, angleMix)); float angle = fract(sin(dot(texCoord, vec2(12.9898, 78.233))) * 100.0);
rayCast(mix(n, c1, angleMix));
rayCast(mix(n, c2, angleMix)); for (int i = 0; i < ssgiSamples; i++) {
// Use quasi-random sequence for better coverage
float r = sqrt((float(i) + 0.5) / float(ssgiSamples)) * radius;
float a = (float(i) * GOLDEN_ANGLE) + angle;
vec2 offset = vec2(cos(a), sin(a)) * r * radius;
vec2 sampleUV = clamp(texCoord + offset * (BayerMatrix8[int(gl_FragCoord.x + velocity.x) % 8][int(gl_FragCoord.y + velocity.y) % 8] - 0.5) / screenSize, vec2(0.001), vec2(0.999));
float sampleDepth = textureLod(gbufferD, sampleUV, 0.0).r;
if (sampleDepth >= 1.0) continue;
vec3 samplePos = getWorldPos(sampleUV, sampleDepth);
vec3 sampleNormal = getNormal(sampleUV);
// Apply small bias to sample position to avoid self-occlusion
samplePos += sampleNormal * SAMPLE_BIAS;
vec3 dir = pos - samplePos;
float dist = length(dir);
if (abs(pos.z - samplePos.z) > MAX_DEPTH_DIFFERENCE) continue;;
vec3 sampleColor = calculateIndirectLight(sampleUV, samplePos, sampleNormal, sampleDepth);
float weight = 1.0 / (1.0 + dist * dist * 2.0) * max(dot(sampleNormal, n), 0.0);
gi += sampleColor * weight;
totalWeight += weight;
}
// Normalize and apply intensity
if (totalWeight > 0.0) {
gi /= totalWeight;
#ifdef _CPostprocess
gi *= PPComp12.x;
#else
gi *= ssaoStrength;
#endif
}
#ifdef _EmissionShadeless
if (matid == 1) { // pure emissive material, color stored in basecol
gi += textureLod(gbuffer1, texCoord, 0.0).rgb;
}
#endif #endif
#ifdef _EmissionShaded
#ifdef _EmissionShadeless
else {
#endif
gi += textureLod(gbufferEmission, texCoord, 0.0).rgb;
#ifdef _EmissionShadeless
}
#endif
#endif
fragColor = gi / (gi + vec3(1.0)); // Reinhard tone mapping
} }

View File

@ -6,6 +6,10 @@
"compare_mode": "always", "compare_mode": "always",
"cull_mode": "none", "cull_mode": "none",
"links": [ "links": [
{
"name": "invVP",
"link": "_inverseViewProjectionMatrix"
},
{ {
"name": "P", "name": "P",
"link": "_projectionMatrix" "link": "_projectionMatrix"
@ -15,16 +19,180 @@
"link": "_viewMatrix3" "link": "_viewMatrix3"
}, },
{ {
"name": "invP", "name": "eye",
"link": "_inverseProjectionMatrix" "link": "_cameraPosition"
},
{
"name": "eyeLook",
"link": "_cameraLook"
}, },
{ {
"name": "cameraProj", "name": "cameraProj",
"link": "_cameraPlaneProj" "link": "_cameraPlaneProj"
},
{
"name": "screenSize",
"link": "_screenSize"
},
{
"name": "PPComp12",
"link": "_PPComp12",
"ifdef": ["_CPostprocess"]
},
{
"name": "lightsArraySpot",
"link": "_lightsArraySpot",
"ifdef": ["_Clusters", "_Spot"]
},
{
"name": "lightsArray",
"link": "_lightsArray",
"ifdef": ["_Clusters"]
},
{
"name": "clustersData",
"link": "_clustersData",
"ifdef": ["_Clusters"]
},
{
"name": "cameraPlane",
"link": "_cameraPlane",
"ifdef": ["_Clusters"]
},
{
"name": "sunDir",
"link": "_sunDirection",
"ifdef": ["_Sun"]
},
{
"name": "sunCol",
"link": "_sunColor",
"ifdef": ["_Sun"]
},
{
"name": "shadowsBias",
"link": "_sunShadowsBias",
"ifdef": ["_Sun", "_ShadowMap"]
},
{
"name": "LWVP",
"link": "_biasLightWorldViewProjectionMatrixSun",
"ifndef": ["_CSM"],
"ifdef": ["_Sun", "_ShadowMap"]
},
{
"name": "casData",
"link": "_cascadeData",
"ifdef": ["_Sun", "_ShadowMap", "_CSM"]
},
{
"name": "lightArea0",
"link": "_lightArea0",
"ifdef": ["_LTC"]
},
{
"name": "lightArea1",
"link": "_lightArea1",
"ifdef": ["_LTC"]
},
{
"name": "lightArea2",
"link": "_lightArea2",
"ifdef": ["_LTC"]
},
{
"name": "lightArea3",
"link": "_lightArea3",
"ifdef": ["_LTC"]
},
{
"name": "sltcMat",
"link": "_ltcMat",
"ifdef": ["_LTC"]
},
{
"name": "sltcMag",
"link": "_ltcMag",
"ifdef": ["_LTC"]
},
{
"name": "smSizeUniform",
"link": "_shadowMapSize",
"ifdef": ["_SMSizeUniform"]
},
{
"name": "lightProj",
"link": "_lightPlaneProj",
"ifdef": ["_ShadowMap"]
},
{
"name": "pointPos",
"link": "_pointPosition",
"ifdef": ["_SinglePoint"]
},
{
"name": "pointCol",
"link": "_pointColor",
"ifdef": ["_SinglePoint"]
},
{
"name": "pointBias",
"link": "_pointShadowsBias",
"ifdef": ["_SinglePoint", "_ShadowMap"]
},
{
"name": "spotDir",
"link": "_spotDirection",
"ifdef": ["_SinglePoint", "_Spot"]
},
{
"name": "spotData",
"link": "_spotData",
"ifdef": ["_SinglePoint", "_Spot"]
},
{
"name": "spotRight",
"link": "_spotRight",
"ifdef": ["_SinglePoint", "_Spot"]
},
{
"name": "LWVPSpotArray",
"link": "_biasLightWorldViewProjectionMatrixSpotArray",
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
},
{
"name": "pointLightDataArray",
"link": "_pointLightsAtlasArray",
"ifdef": ["_Clusters", "_ShadowMap", "_ShadowMapAtlas"]
},
{
"name": "LWVPSpot[0]",
"link": "_biasLightWorldViewProjectionMatrixSpot0",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_LTC", "_ShadowMap"]
},
{
"name": "LWVPSpot[1]",
"link": "_biasLightWorldViewProjectionMatrixSpot1",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_LTC", "_ShadowMap"]
},
{
"name": "LWVPSpot[2]",
"link": "_biasLightWorldViewProjectionMatrixSpot2",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_LTC", "_ShadowMap"]
},
{
"name": "LWVPSpot[3]",
"link": "_biasLightWorldViewProjectionMatrixSpot3",
"ifndef": ["_ShadowMapAtlas"],
"ifdef": ["_LTC", "_ShadowMap"]
} }
], ],
"texture_params": [], "texture_params": [],
"vertex_shader": "../include/pass_viewray2.vert.glsl", "vertex_shader": "../include/pass_viewray.vert.glsl",
"fragment_shader": "ssgi_pass.frag.glsl" "fragment_shader": "ssgi_pass.frag.glsl"
} }
] ]

View File

@ -64,7 +64,7 @@ vec4 rayCast(vec3 dir) {
ddepth = getDeltaDepth(hitCoord); ddepth = getDeltaDepth(hitCoord);
if (ddepth > 0.0) return binarySearch(dir); if (ddepth > 0.0) return binarySearch(dir);
} }
return vec4(texCoord, 0.0, 1.0); return vec4(getProjectedCoord(hitCoord), 0.0, 1.0);
} }
void main() { void main() {
@ -86,7 +86,7 @@ void main() {
vec3 viewNormal = V3 * n; vec3 viewNormal = V3 * n;
vec3 viewPos = getPosView(viewRay, d, cameraProj); vec3 viewPos = getPosView(viewRay, d, cameraProj);
vec3 refracted = refract(normalize(viewPos), viewNormal, 1.0 / ior); vec3 refracted = refract(viewPos, viewNormal, 1.0 / ior);
hitCoord = viewPos; hitCoord = viewPos;
vec3 dir = refracted * (1.0 - rand(texCoord) * ss_refractionJitter * roughness) * 2.0; vec3 dir = refracted * (1.0 - rand(texCoord) * ss_refractionJitter * roughness) * 2.0;

View File

@ -0,0 +1,18 @@
#ifndef _AABB_GLSL
#define _AABB_GLSL
bool IntersectAABB(vec3[2] a, vec3[2] b) {
const float EPSILON = 0.001; // Small tolerance to prevent false negatives
if (abs(a[0].x - b[0].x) > (a[1].x + b[1].x + EPSILON)) return false;
if (abs(a[0].y - b[0].y) > (a[1].y + b[1].y + EPSILON)) return false;
if (abs(a[0].z - b[0].z) > (a[1].z + b[1].z + EPSILON)) return false;
return true;
}
void AABBfromMinMax(inout vec3[2] aabb, vec3 _min, vec3 _max)
{
aabb[0] = (_min + _max) * 0.5f;
aabb[1] = abs(_max - aabb[0]);
}
#endif

View File

@ -22,7 +22,7 @@ THE SOFTWARE.
#ifndef _CONETRACE_GLSL_ #ifndef _CONETRACE_GLSL_
#define _CONETRACE_GLSL_ #define _CONETRACE_GLSL_
#include "std/voxels_constants.glsl" #include "std/constants.glsl"
// References // References
// https://github.com/Friduric/voxel-cone-tracing // https://github.com/Friduric/voxel-cone-tracing
@ -92,7 +92,7 @@ vec4 traceCone(const sampler3D voxels, const sampler3D voxelsSDF, const vec3 ori
float dist = voxelSize0; float dist = voxelSize0;
float step_dist = dist; float step_dist = dist;
vec3 samplePos; vec3 samplePos;
vec3 start_pos = origin + n * voxelSize0 * voxelgiOffset; vec3 start_pos = origin + n * voxelSize0;
int clipmap_index0 = 0; int clipmap_index0 = 0;
vec3 aniso_direction = -dir; vec3 aniso_direction = -dir;
@ -125,7 +125,7 @@ vec4 traceCone(const sampler3D voxels, const sampler3D voxelsSDF, const vec3 ori
if(clipmap_blend > 0.0 && clipmap_index < voxelgiClipmapCount - 1) { if(clipmap_blend > 0.0 && clipmap_index < voxelgiClipmapCount - 1) {
vec4 mipSampleNext = sampleVoxel(voxels, p0, clipmaps, clipmap_index + 1.0, step_dist, precomputed_direction, face_offset, direction_weight); vec4 mipSampleNext = sampleVoxel(voxels, p0, clipmaps, clipmap_index + 1.0, step_dist, precomputed_direction, face_offset, direction_weight);
mipSample = mix(mipSample, mipSampleNext, smoothstep(0.0, 1.0, clipmap_blend)); mipSample = mix(mipSample, mipSampleNext, clipmap_blend);
} }
sampleCol += (1.0 - sampleCol.a) * mipSample; sampleCol += (1.0 - sampleCol.a) * mipSample;
@ -148,8 +148,9 @@ vec4 traceCone(const sampler3D voxels, const sampler3D voxelsSDF, const vec3 ori
vec4 traceDiffuse(const vec3 origin, const vec3 normal, const sampler3D voxels, const float clipmaps[voxelgiClipmapCount * 10]) { vec4 traceDiffuse(const vec3 origin, const vec3 normal, const sampler3D voxels, const float clipmaps[voxelgiClipmapCount * 10]) {
float sum = 0.0; float sum = 0.0;
vec4 amount = vec4(0.0); vec4 amount = vec4(0.0);
mat3 TBN = makeTangentBasis(normal);
for (int i = 0; i < DIFFUSE_CONE_COUNT; ++i) { for (int i = 0; i < DIFFUSE_CONE_COUNT; ++i) {
vec3 coneDir = DIFFUSE_CONE_DIRECTIONS[i]; vec3 coneDir = TBN * DIFFUSE_CONE_DIRECTIONS[i];
const float cosTheta = dot(normal, coneDir); const float cosTheta = dot(normal, coneDir);
if (cosTheta <= 0) if (cosTheta <= 0)
continue; continue;
@ -166,7 +167,7 @@ vec4 traceDiffuse(const vec3 origin, const vec3 normal, const sampler3D voxels,
} }
vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 viewDir, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) { vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 viewDir, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) {
vec3 specularDir = reflect(-viewDir, normal); vec3 specularDir = reflect(normalize(-viewDir), normal);
vec3 P = origin + specularDir * ((BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5)) * voxelgiStep; vec3 P = origin + specularDir * ((BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5)) * voxelgiStep;
vec4 amount = traceCone(voxels, voxelsSDF, P, normal, specularDir, 0, true, roughness, voxelgiStep, clipmaps); vec4 amount = traceCone(voxels, voxelsSDF, P, normal, specularDir, 0, true, roughness, voxelgiStep, clipmaps);
@ -176,9 +177,9 @@ vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels,
return amount * voxelgiOcc; return amount * voxelgiOcc;
} }
vec4 traceRefraction(const vec3 origin, const vec3 normal, sampler3D voxels, sampler3D voxelsSDF, const vec3 viewDir, const float ior, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) { vec4 traceRefraction(const vec3 origin, const vec3 normal, sampler3D voxels, sampler3D voxelsSDF, const vec3 viewDir, const float ior, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity, const float opacity) {
const float transmittance = 1.0; const float transmittance = 1.0 - opacity;
vec3 refractionDir = refract(-viewDir, normal, 1.0 / ior); vec3 refractionDir = refract(normalize(-viewDir), normal, 1.0 / ior);
vec3 P = origin + refractionDir * (BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep; vec3 P = origin + refractionDir * (BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep;
vec4 amount = transmittance * traceCone(voxels, voxelsSDF, P, normal, refractionDir, 0, true, roughness, voxelgiStep, clipmaps); vec4 amount = transmittance * traceCone(voxels, voxelsSDF, P, normal, refractionDir, 0, true, roughness, voxelgiStep, clipmaps);
@ -196,7 +197,7 @@ float traceConeAO(const sampler3D voxels, const vec3 origin, const vec3 n, const
float dist = voxelSize0; float dist = voxelSize0;
float step_dist = dist; float step_dist = dist;
vec3 samplePos; vec3 samplePos;
vec3 start_pos = origin + n * voxelSize0 * voxelgiOffset; vec3 start_pos = origin + n * voxelSize0;
int clipmap_index0 = 0; int clipmap_index0 = 0;
vec3 aniso_direction = -dir; vec3 aniso_direction = -dir;
@ -259,7 +260,6 @@ float traceAO(const vec3 origin, const vec3 normal, const sampler3D voxels, cons
} }
#endif #endif
#ifdef _VoxelShadow #ifdef _VoxelShadow
float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const vec3 origin, const vec3 n, const vec3 dir, const float aperture, const float step_size, const float clipmaps[voxelgiClipmapCount * 10]) { float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const vec3 origin, const vec3 n, const vec3 dir, const float aperture, const float step_size, const float clipmaps[voxelgiClipmapCount * 10]) {
float sampleCol = 0.0; float sampleCol = 0.0;
@ -267,7 +267,7 @@ float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const v
float dist = voxelSize0; float dist = voxelSize0;
float step_dist = dist; float step_dist = dist;
vec3 samplePos; vec3 samplePos;
vec3 start_pos = origin + n * voxelSize0 * voxelgiOffset; vec3 start_pos = origin + n * voxelSize0;
int clipmap_index0 = 0; int clipmap_index0 = 0;
vec3 aniso_direction = -dir; vec3 aniso_direction = -dir;
@ -287,7 +287,7 @@ float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const v
float clipmap_blend = fract(lod); float clipmap_blend = fract(lod);
vec3 p0 = start_pos + dir * dist; vec3 p0 = start_pos + dir * dist;
samplePos = (p0 - vec3(clipmaps[int(clipmap_index * 10 + 4)], clipmaps[int(clipmap_index * 10 + 5)], clipmaps[int(clipmap_index * 10 + 6)])) / (float(clipmaps[int(clipmap_index * 10)]) * voxelgiResolution.x); samplePos = (p0 - vec3(clipmaps[int(clipmap_index * 10 + 4)], clipmaps[int(clipmap_index * 10 + 5)], clipmaps[int(clipmap_index * 10 + 6)])) / (float(clipmaps[int(clipmap_index * 10)]) * voxelgiResolution);
samplePos = samplePos * 0.5 + 0.5; samplePos = samplePos * 0.5 + 0.5;
if ((any(notEqual(samplePos, clamp(samplePos, 0.0, 1.0))))) { if ((any(notEqual(samplePos, clamp(samplePos, 0.0, 1.0))))) {
@ -328,9 +328,9 @@ float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const v
} }
float traceShadow(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 dir, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel) { float traceShadow(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 dir, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) {
vec3 P = origin + dir * (BayerMatrix8[int(pixel.x) % 8][int(pixel.y) % 8] - 0.5) * voxelgiStep; vec3 P = origin + dir * (BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep;
float amount = traceConeShadow(voxels, voxelsSDF, P, normal, dir, DIFFUSE_CONE_APERTURE, voxelgiStep, clipmaps); float amount = traceConeShadow(voxels, voxelsSDF, P, normal, dir, SHADOW_CONE_APERTURE, voxelgiStep, clipmaps);
amount = clamp(amount, 0.0, 1.0); amount = clamp(amount, 0.0, 1.0);
return amount * voxelgiOcc; return amount * voxelgiOcc;
} }

View File

@ -21,29 +21,42 @@ THE SOFTWARE.
*/ */
const int DIFFUSE_CONE_COUNT = 16; const int DIFFUSE_CONE_COUNT = 16;
const float DIFFUSE_CONE_APERTURE = radians(45.0);
const vec3 DIFFUSE_CONE_DIRECTIONS[16] = { const float SHADOW_CONE_APERTURE = radians(15.0);
vec3(0.0000, 0.0000, 1.0000), // Central direction
vec3(0.3827, 0.0000, 0.9239), // Ring 1
vec3(-0.3827, 0.0000, 0.9239),
vec3(0.0000, 0.3827, 0.9239),
vec3(0.0000, -0.3827, 0.9239),
vec3(0.2706, 0.2706, 0.9239), // Ring 2
vec3(-0.2706, 0.2706, 0.9239),
vec3(0.2706, -0.2706, 0.9239),
vec3(-0.2706, -0.2706, 0.9239),
vec3(0.1802, 0.3604, 0.9239), // Ring 3
vec3(-0.1802, 0.3604, 0.9239),
vec3(0.1802, -0.3604, 0.9239),
vec3(-0.1802, -0.3604, 0.9239),
vec3(0.3604, 0.1802, 0.9239),
vec3(-0.3604, 0.1802, 0.9239),
vec3(0.3604, -0.1802, 0.9239)
};
const float DIFFUSE_CONE_APERTURE = radians(50.0);
const float BayerMatrix8[8][8] = const vec3 DIFFUSE_CONE_DIRECTIONS[DIFFUSE_CONE_COUNT] = vec3[](
vec3(0.0, 0.0, 1.0), // center
vec3(0.0, 0.5, 0.866),
vec3(0.5, 0.0, 0.866),
vec3(0.0, -0.5, 0.866),
vec3(-0.5, 0.0, 0.866),
vec3(0.353, 0.353, 0.866),
vec3(0.353, -0.353, 0.866),
vec3(-0.353, -0.353, 0.866),
vec3(-0.353, 0.353, 0.866),
vec3(0.707, 0.0, 0.707),
vec3(0.0, 0.707, 0.707),
vec3(-0.707, 0.0, 0.707),
vec3(0.0, -0.707, 0.707),
vec3(0.5, 0.5, 0.707),
vec3(-0.5, 0.5, 0.707),
vec3(-0.5, -0.5, 0.707)
);
mat3 makeTangentBasis(vec3 normal) {
vec3 tangent = normalize(abs(normal.y) < 0.999 ? cross(normal, vec3(0, 1, 0)) : cross(normal, vec3(1, 0, 0)));
vec3 bitangent = cross(normal, tangent);
return mat3(tangent, bitangent, normal);
}
// TO DO - Disabled momentarily instead of changing formulas
const float off_BayerMatrix8[8][8] =
{ {
{ 1.0 / 65.0, 49.0 / 65.0, 13.0 / 65.0, 61.0 / 65.0, 4.0 / 65.0, 52.0 / 65.0, 16.0 / 65.0, 64.0 / 65.0 }, { 1.0 / 65.0, 49.0 / 65.0, 13.0 / 65.0, 61.0 / 65.0, 4.0 / 65.0, 52.0 / 65.0, 16.0 / 65.0, 64.0 / 65.0 },
{ 33.0 / 65.0, 17.0 / 65.0, 45.0 / 65.0, 29.0 / 65.0, 36.0 / 65.0, 20.0 / 65.0, 48.0 / 65.0, 32.0 / 65.0 }, { 33.0 / 65.0, 17.0 / 65.0, 45.0 / 65.0, 29.0 / 65.0, 36.0 / 65.0, 20.0 / 65.0, 48.0 / 65.0, 32.0 / 65.0 },
@ -54,3 +67,15 @@ const float BayerMatrix8[8][8] =
{ 11.0 / 65.0, 59.0 / 65.0, 7.0 / 65.0, 55.0 / 65.0, 10.0 / 65.0, 58.0 / 65.0, 6.0 / 65.0, 54.0 / 65.0 }, { 11.0 / 65.0, 59.0 / 65.0, 7.0 / 65.0, 55.0 / 65.0, 10.0 / 65.0, 58.0 / 65.0, 6.0 / 65.0, 54.0 / 65.0 },
{ 43.0 / 65.0, 27.0 / 65.0, 39.0 / 65.0, 23.0 / 65.0, 42.0 / 65.0, 26.0 / 65.0, 38.0 / 65.0, 22.0 / 65.0 } { 43.0 / 65.0, 27.0 / 65.0, 39.0 / 65.0, 23.0 / 65.0, 42.0 / 65.0, 26.0 / 65.0, 38.0 / 65.0, 22.0 / 65.0 }
}; };
const float BayerMatrix8[8][8] =
{
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 },
{ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 }
};

View File

@ -1,239 +1,679 @@
#ifndef _LIGHT_GLSL_ #ifndef _LIGHT_GLSL_
#define _LIGHT_GLSL_ #define _LIGHT_GLSL_
#include "compiled.inc" #include "compiled.inc"
#include "std/brdf.glsl" #include "std/brdf.glsl"
#include "std/math.glsl" #include "std/math.glsl"
#ifdef _ShadowMap #ifdef _ShadowMap
#include "std/shadows.glsl" #include "std/shadows.glsl"
#endif #endif
#ifdef _VoxelShadow #ifdef _VoxelShadow
#include "std/conetrace.glsl" #include "std/conetrace.glsl"
//!uniform sampler2D voxels_shadows; #endif
#endif #ifdef _LTC
#ifdef _LTC #include "std/ltc.glsl"
#include "std/ltc.glsl" #endif
#endif #ifdef _LightIES
#ifdef _LightIES #include "std/ies.glsl"
#include "std/ies.glsl" #endif
#endif #ifdef _SSRS
#ifdef _SSRS #include "std/ssrs.glsl"
#include "std/ssrs.glsl" #endif
#endif #ifdef _Spot
#ifdef _Spot #include "std/light_common.glsl"
#include "std/light_common.glsl" #endif
#endif #ifdef _VoxelShadow
#include "std/conetrace.glsl"
#ifdef _ShadowMap #endif
#ifdef _SinglePoint
#ifdef _Spot #ifdef _ShadowMap
#ifndef _LTC #ifdef _SinglePoint
uniform sampler2DShadow shadowMapSpot[1]; #ifdef _Spot
uniform sampler2D shadowMapSpotTransparent[1]; #ifndef _LTC
uniform mat4 LWVPSpot[1]; uniform sampler2DShadow shadowMapSpot[1];
#endif #ifdef _ShadowMapTransparent
#else uniform sampler2D shadowMapSpotTransparent[1];
uniform samplerCubeShadow shadowMapPoint[1]; #endif
uniform samplerCube shadowMapPointTransparent[1]; uniform mat4 LWVPSpotArray[1];
uniform vec2 lightProj; #endif
#endif #else
#endif uniform samplerCubeShadow shadowMapPoint[1];
#ifdef _Clusters #ifdef _ShadowMapTransparent
#ifdef _SingleAtlas uniform samplerCube shadowMapPointTransparent[1];
//!uniform sampler2DShadow shadowMapAtlas; #endif
//!uniform sampler2D shadowMapAtlasTransparent; uniform vec2 lightProj;
#endif #endif
uniform vec2 lightProj; #endif
#ifdef _ShadowMapAtlas #ifdef _Clusters
#ifndef _SingleAtlas #ifdef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasPoint; //!uniform sampler2DShadow shadowMapAtlas;
uniform sampler2D shadowMapAtlasPointTransparent; #ifdef _ShadowMapTransparent
#endif //!uniform sampler2D shadowMapAtlasTransparent;
#else #endif
uniform samplerCubeShadow shadowMapPoint[4]; #endif
uniform samplerCube shadowMapPointTransparent[4]; uniform vec2 lightProj;
#endif #ifdef _ShadowMapAtlas
#ifdef _Spot #ifndef _SingleAtlas
#ifdef _ShadowMapAtlas uniform sampler2DShadow shadowMapAtlasPoint;
#ifndef _SingleAtlas #ifdef _ShadowMapTransparent
uniform sampler2DShadow shadowMapAtlasSpot; uniform sampler2D shadowMapAtlasPointTransparent;
uniform sampler2D shadowMapAtlasSpotTransparent; #endif
#endif #endif
#else #else
uniform sampler2DShadow shadowMapSpot[4]; uniform samplerCubeShadow shadowMapPoint[4];
uniform sampler2D shadowMapSpotTransparent[4]; #ifdef _ShadowMapTransparent
#endif uniform samplerCube shadowMapPointTransparent[4];
uniform mat4 LWVPSpotArray[maxLightsCluster]; #endif
#endif #endif
#endif #ifdef _Spot
#endif #ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
#ifdef _LTC uniform sampler2DShadow shadowMapAtlasSpot;
uniform vec3 lightArea0; #ifdef _ShadowMapTransparent
uniform vec3 lightArea1; uniform sampler2D shadowMapAtlasSpotTransparent;
uniform vec3 lightArea2; #endif
uniform vec3 lightArea3; #endif
uniform sampler2D sltcMat; #else
uniform sampler2D sltcMag; uniform sampler2DShadow shadowMapSpot[4];
#ifdef _ShadowMap #ifdef _ShadowMapTransparent
#ifndef _Spot uniform sampler2D shadowMapSpotTransparent[4];
#ifdef _SinglePoint #endif
uniform sampler2DShadow shadowMapSpot[1]; #endif
uniform sampler2D shadowMapSpotTransparent[1]; uniform mat4 LWVPSpotArray[maxLightsCluster];
uniform mat4 LWVPSpot[1]; #endif
#endif #endif
#ifdef _Clusters #endif
uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
uniform sampler2D shadowMapSpotTransparent[maxLightsCluster]; #ifdef _LTC
uniform mat4 LWVPSpotArray[maxLightsCluster]; uniform vec3 lightArea0;
#endif uniform vec3 lightArea1;
#endif uniform vec3 lightArea2;
#endif uniform vec3 lightArea3;
#endif uniform sampler2D sltcMat;
uniform sampler2D sltcMag;
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol, #ifdef _ShadowMap
const vec3 albedo, const float rough, const float spec, const vec3 f0 #ifndef _Spot
#ifdef _ShadowMap #ifdef _SinglePoint
, int index, float bias, bool receiveShadow, bool transparent uniform sampler2DShadow shadowMapSpot[1];
#endif #ifdef _ShadowMapTransparent
#ifdef _Spot uniform sampler2D shadowMapSpotTransparent[1];
, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right #endif
#endif uniform mat4 LWVPSpotArray[1];
#ifdef _VoxelShadow #endif
, sampler3D voxels, sampler3D voxelsSDF, float clipmaps[10 * voxelgiClipmapCount] #ifdef _Clusters
#endif uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
#ifdef _MicroShadowing #ifdef _ShadowMapTransparent
, float occ uniform sampler2D shadowMapSpotTransparent[maxLightsCluster];
#endif #endif
#ifdef _SSRS uniform mat4 LWVPSpotArray[maxLightsCluster];
, sampler2D gbufferD, mat4 invVP, vec3 eye #endif
#endif #endif
) { #endif
vec3 ld = lp - p; #endif
vec3 l = normalize(ld);
vec3 h = normalize(v + l); vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
float dotNH = max(0.0, dot(n, h)); const vec3 albedo, const float rough, const float spec, const vec3 f0
float dotVH = max(0.0, dot(v, h)); #ifdef _ShadowMap
float dotNL = max(0.0, dot(n, l)); , int index, float bias, bool receiveShadow
#ifdef _ShadowMapTransparent
#ifdef _LTC , bool transparent
float theta = acos(dotNV); #endif
vec2 tuv = vec2(rough, theta / (0.5 * PI)); #endif
tuv = tuv * LUT_SCALE + LUT_BIAS; #ifdef _Spot
vec4 t = textureLod(sltcMat, tuv, 0.0); , const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
mat3 invM = mat3( #endif
vec3(1.0, 0.0, t.y), #ifdef _VoxelShadow
vec3(0.0, t.z, 0.0), , sampler3D voxels, sampler3D voxelsSDF, float clipmaps[10 * voxelgiClipmapCount], vec2 velocity
vec3(t.w, 0.0, t.x)); #endif
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3); #ifdef _MicroShadowing
ltcspec *= textureLod(sltcMag, tuv, 0.0).a; , float occ
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3); #endif
vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05; #ifdef _SSRS
#else , sampler2D gbufferD, mat4 invVP, vec3 eye
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) + #endif
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec; ) {
#endif vec3 ld = lp - p;
vec3 l = normalize(ld);
direct *= attenuate(distance(p, lp)); vec3 h = normalize(v + l);
direct *= lightCol; float dotNH = max(0.0, dot(n, h));
float dotVH = max(0.0, dot(v, h));
#ifdef _MicroShadowing float dotNL = max(0.0, dot(n, l));
direct *= clamp(dotNL + 2.0 * occ * occ - 1.0, 0.0, 1.0);
#endif #ifdef _LTC
float theta = acos(dotNV);
#ifdef _SSRS vec2 tuv = vec2(rough, theta / (0.5 * PI));
direct *= traceShadowSS(l, p, gbufferD, invVP, eye); tuv = tuv * LUT_SCALE + LUT_BIAS;
#endif vec4 t = textureLod(sltcMat, tuv, 0.0);
mat3 invM = mat3(
#ifdef _VoxelShadow vec3(1.0, 0.0, t.y),
direct *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, l, clipmaps, gl_FragCoord.xy).r) * voxelgiShad; vec3(0.0, t.z, 0.0),
#endif vec3(t.w, 0.0, t.x));
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
#ifdef _LTC ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
#ifdef _ShadowMap float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
if (receiveShadow) { vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
#ifdef _SinglePoint #else
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0); vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent); specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
#endif #endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0); direct *= attenuate(distance(p, lp));
if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent); direct *= lightCol;
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent); #ifdef _MicroShadowing
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent); direct *= clamp(dotNL + 2.0 * occ * occ - 1.0, 0.0, 1.0);
#endif #endif
}
#endif #ifdef _SSRS
return direct; direct *= traceShadowSS(l, p, gbufferD, invVP, eye);
#endif #endif
#ifdef _Spot #ifdef _VoxelShadow
if (isSpot) { vec3 lightDir = l;
direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend); #ifdef _Spot
if (isSpot)
#ifdef _ShadowMap lightDir = spotDir;
if (receiveShadow) { #endif
#ifdef _SinglePoint direct *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, lightDir, clipmaps, gl_FragCoord.xy, velocity).r) * voxelgiShad;
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0); #endif
direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
#endif #ifdef _LTC
#ifdef _Clusters #ifdef _ShadowMap
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0); if (receiveShadow) {
#ifdef _ShadowMapAtlas #ifdef _SinglePoint
direct *= shadowTest( vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
#ifndef _SingleAtlas direct *= shadowTest(shadowMapSpot[0],
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent #ifdef _ShadowMapTransparent
#else shadowMapSpotTransparent[0],
shadowMapAtlas, shadowMapAtlasTransparent #endif
#endif lPos.xyz / lPos.w, bias
, lPos.xyz / lPos.w, bias, transparent #ifdef _ShadowMapTransparent
); , transparent
#else #endif
if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent); );
else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent); #endif
else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent); #ifdef _Clusters
else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent); vec4 lPos = LWVPSpot[index] * vec4(p + n * bias * 10, 1.0);
#endif if (index == 0) direct *= shadowTest(shadowMapSpot[0],
#endif #ifdef _ShadowMapTransparent
} shadowMapSpotTransparent[0],
#endif #endif
return direct; lPos.xyz / lPos.w, bias
} #ifdef _ShadowMapTransparent
#endif , transparent
#endif
#ifdef _LightIES );
direct *= iesAttenuation(-l); else if (index == 1) direct *= shadowTest(shadowMapSpot[1],
#endif #ifdef _ShadowMapTransparent
shadowMapSpotTransparent[1],
#ifdef _ShadowMap #endif
if (receiveShadow) { lPos.xyz / lPos.w, bias
#ifdef _SinglePoint #ifdef _ShadowMapTransparent
#ifndef _Spot , transparent
direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent); #endif
#endif );
#endif else if (index == 2) direct *= shadowTest(shadowMapSpot[2],
#ifdef _Clusters #ifdef _ShadowMapTransparent
#ifdef _ShadowMapAtlas shadowMapSpotTransparent[2],
direct *= PCFFakeCube( #endif
#ifndef _SingleAtlas lPos.xyz / lPos.w, bias
shadowMapAtlasPoint, shadowMapAtlasPointTransparent #ifdef _ShadowMapTransparent
#else , transparent
shadowMapAtlas, shadowMapAtlasTransparent #endif
#endif );
, ld, -l, bias, lightProj, n, index, transparent else if (index == 3) direct *= shadowTest(shadowMapSpot[3],
); #ifdef _ShadowMapTransparent
#else shadowMapSpotTransparent[3],
if (index == 0) direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent); #endif
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], shadowMapPointTransparent[1], ld, -l, bias, lightProj, n, transparent); lPos.xyz / lPos.w, bias
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], shadowMapPointTransparent[2], ld, -l, bias, lightProj, n, transparent); #ifdef _ShadowMapTransparent
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], shadowMapPointTransparent[3], ld, -l, bias, lightProj, n, transparent); , transparent
#endif #endif
#endif );
} #endif
#endif }
#endif
return direct; return direct;
} #endif
#endif #ifdef _Spot
if (isSpot) {
direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[0],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
#ifdef _ShadowMapAtlas
direct *= shadowTest(
#ifdef _ShadowMapTransparent
#ifndef _SingleAtlas
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
#endif
#else
#ifndef _SingleAtlas
shadowMapAtlasSpot
#else
shadowMapAtlas
#endif
#endif
, lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#else
if (index == 0) direct *= shadowTest(shadowMapSpot[0],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[0],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 1) direct *= shadowTest(shadowMapSpot[1],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[1],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 2) direct *= shadowTest(shadowMapSpot[2],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[2],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 3) direct *= shadowTest(shadowMapSpot[3],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[3],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#endif
}
#endif
return direct;
}
#endif
#ifdef _LightIES
direct *= iesAttenuation(-l);
#endif
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
#ifndef _Spot
direct *= PCFCube(shadowMapPoint[0],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[0],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#endif
#ifdef _Clusters
#ifdef _ShadowMapAtlas
direct *= PCFFakeCube(
#ifdef _ShadowMapTransparent
#ifndef _SingleAtlas
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
#endif
#else
#ifndef _SingleAtlas
shadowMapAtlasPoint
#else
shadowMapAtlas
#endif
#endif
, ld, -l, bias, lightProj, n, index
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#else
if (index == 0) direct *= PCFCube(shadowMapPoint[0],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[0],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[1],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[2],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[3],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#endif
}
#endif
return direct;
}
#ifdef _VoxelGI
vec3 sampleLightVoxels(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
const vec3 albedo, const float rough, const float spec, const vec3 f0
#ifdef _ShadowMap
, int index, float bias, bool receiveShadow
#ifdef _ShadowMapTransparent
, bool transparent
#endif
#endif
#ifdef _Spot
, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
#endif
) {
vec3 ld = lp - p;
vec3 l = normalize(ld);
vec3 h = normalize(v + l);
float dotNH = max(0.0, dot(n, h));
float dotVH = max(0.0, dot(v, h));
float dotNL = max(0.0, dot(n, l));
#ifdef _LTC
float theta = acos(dotNV);
vec2 tuv = vec2(rough, theta / (0.5 * PI));
tuv = tuv * LUT_SCALE + LUT_BIAS;
vec4 t = textureLod(sltcMat, tuv, 0.0);
mat3 invM = mat3(
vec3(1.0, 0.0, t.y),
vec3(0.0, t.z, 0.0),
vec3(t.w, 0.0, t.x));
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
#else
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
#endif
direct *= attenuate(distance(p, lp));
direct *= lightCol;
#ifdef _LTC
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[0],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpot[index] * vec4(p + n * bias * 10, 1.0);
if (index == 0) direct *= shadowTest(shadowMapSpot[0],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[0],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 1) direct *= shadowTest(shadowMapSpot[1],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[1],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 2) direct *= shadowTest(shadowMapSpot[2],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[2],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 3) direct *= shadowTest(shadowMapSpot[3],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[3],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
}
#endif
return direct;
#endif
#ifdef _Spot
if (isSpot) {
direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[0],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
#ifdef _ShadowMapAtlas
direct *= shadowTest(
#ifdef _ShadowMapTransparent
#ifndef _SingleAtlas
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
#endif
#else
#ifndef _SingleAtlas
shadowMapAtlasSpot
#else
shadowMapAtlas
#endif
#endif
, lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#else
if (index == 0) direct *= shadowTest(shadowMapSpot[0],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[0],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 1) direct *= shadowTest(shadowMapSpot[1],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[1],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 2) direct *= shadowTest(shadowMapSpot[2],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[2],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 3) direct *= shadowTest(shadowMapSpot[3],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[3],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#endif
}
#endif
return direct;
}
#endif
#ifdef _LightIES
direct *= iesAttenuation(-l);
#endif
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
#ifndef _Spot
direct *= PCFCube(shadowMapPoint[0],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[0],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#endif
#ifdef _Clusters
#ifdef _ShadowMapAtlas
direct *= PCFFakeCube(
#ifdef _ShadowMapTransparent
#ifndef _SingleAtlas
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
#endif
#else
#ifndef _SingleAtlas
shadowMapAtlasPoint
#else
shadowMapAtlas
#endif
#endif
, ld, -l, bias, lightProj, n, index
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#else
if (index == 0) direct *= PCFCube(shadowMapPoint[0],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[0],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[1],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[2],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[3],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#endif
}
#endif
return direct;
}
#endif
#endif

View File

@ -58,7 +58,15 @@ vec2 sampleCube(vec3 dir, out int faceIndex) {
} }
#endif #endif
vec3 PCF(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec2 uv, const float compare, const vec2 smSize, const bool transparent) { vec3 PCF(sampler2DShadow shadowMap,
#ifdef _ShadowMapTransparent
sampler2D shadowMapTransparent,
#endif
const vec2 uv, const float compare, const vec2 smSize
#ifdef _ShadowMapTransparent
, const bool transparent
#endif
) {
vec3 result = vec3(0.0); vec3 result = vec3(0.0);
result.x = texture(shadowMap, vec3(uv + (vec2(-1.0, -1.0) / smSize), compare)); result.x = texture(shadowMap, vec3(uv + (vec2(-1.0, -1.0) / smSize), compare));
result.x += texture(shadowMap, vec3(uv + (vec2(-1.0, 0.0) / smSize), compare)); result.x += texture(shadowMap, vec3(uv + (vec2(-1.0, 0.0) / smSize), compare));
@ -71,11 +79,13 @@ vec3 PCF(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec2 u
result.x += texture(shadowMap, vec3(uv + (vec2(1.0, 1.0) / smSize), compare)); result.x += texture(shadowMap, vec3(uv + (vec2(1.0, 1.0) / smSize), compare));
result = result.xxx / 9.0; result = result.xxx / 9.0;
#ifdef _ShadowMapTransparent
if (transparent == false) { if (transparent == false) {
vec4 shadowmap_transparent = texture(shadowMapTransparent, uv); vec4 shadowmap_transparent = texture(shadowMapTransparent, uv);
if (shadowmap_transparent.a < compare) if (shadowmap_transparent.a < compare)
result *= shadowmap_transparent.rgb; result *= shadowmap_transparent.rgb;
} }
#endif
return result; return result;
} }
@ -87,41 +97,15 @@ float lpToDepth(vec3 lp, const vec2 lightProj) {
return zcomp * 0.5 + 0.5; return zcomp * 0.5 + 0.5;
} }
#ifndef _ShadowMapAtlas vec3 PCFCube(samplerCubeShadow shadowMapCube,
vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTransparent, vec3 lp, vec3 ml, float bias, vec2 lightProj, vec3 n, const bool transparent) { #ifdef _ShadowMapTransparent
const float s = shadowmapCubePcfSize; samplerCube shadowMapCubeTransparent,
float compare = lpToDepth(lp, lightProj) - bias * 1.5; #endif
ml = ml + n * bias * 20; const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n
#ifdef _InvY #ifdef _ShadowMapTransparent
ml.y = -ml.y; , const bool transparent
#endif #endif
) {
float shadowFactor = 0.0;
shadowFactor = texture(shadowMapCube, vec4(ml, compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, s, s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, s, s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, -s, s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, s, -s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, -s, s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, -s, -s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, s, -s), compare));
shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, -s, -s), compare));
shadowFactor /= 9.0;
vec3 result = vec3(shadowFactor);
if (transparent == false) {
vec4 shadowmap_transparent = texture(shadowMapCubeTransparent, ml);
if (shadowmap_transparent.a < compare)
result *= shadowmap_transparent.rgb;
}
return result;
}
#endif
#ifdef _ShadowMapAtlas
vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTransparent, const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n, const bool transparent) {
const float s = shadowmapCubePcfSize; // TODO: incorrect... const float s = shadowmapCubePcfSize; // TODO: incorrect...
float compare = lpToDepth(lp, lightProj) - bias * 1.5; float compare = lpToDepth(lp, lightProj) - bias * 1.5;
ml = ml + n * bias * 20; ml = ml + n * bias * 20;
@ -140,16 +124,18 @@ vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTranspare
result.x += texture(shadowMapCube, vec4(ml + vec3(-s, -s, -s), compare)); result.x += texture(shadowMapCube, vec4(ml + vec3(-s, -s, -s), compare));
result = result.xxx / 9.0; result = result.xxx / 9.0;
#ifdef _ShadowMapTransparent
if (transparent == false) { if (transparent == false) {
vec4 shadowmap_transparent = texture(shadowMapCubeTransparent, ml); vec4 shadowmap_transparent = texture(shadowMapCubeTransparent, ml);
if (shadowmap_transparent.a < compare) if (shadowmap_transparent.a < compare)
result *= shadowmap_transparent.rgb; result *= shadowmap_transparent.rgb;
} }
#endif
return result; return result;
} }
#ifdef _ShadowMapAtlas
// transform "out-of-bounds" coordinates to the correct face/coordinate system // transform "out-of-bounds" coordinates to the correct face/coordinate system
// https://www.khronos.org/opengl/wiki/File:CubeMapAxes.png // https://www.khronos.org/opengl/wiki/File:CubeMapAxes.png
vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) { vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) {
@ -243,89 +229,50 @@ vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) {
return uv; return uv;
} }
vec3 PCFFakeCube(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n, const int index, const bool transparent) { vec3 PCFFakeCube(sampler2DShadow shadowMap,
#ifdef _ShadowMapTransparent
sampler2D shadowMapTransparent,
#endif
const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n, const int index
#ifdef _ShadowMapTransparent
, const bool transparent
#endif
) {
const vec2 smSize = smSizeUniform; // TODO: incorrect... const vec2 smSize = smSizeUniform; // TODO: incorrect...
const float compare = lpToDepth(lp, lightProj) - bias * 1.5; const float compare = lpToDepth(lp, lightProj) - bias * 1.5;
ml = ml + n * bias * 20; ml = ml + n * bias * 20;
int faceIndex = 0; int faceIndex = 0;
const int lightIndex = index * 6; const int lightIndex = index * 6;
const vec2 uv = sampleCube(ml, faceIndex); const vec2 uv = sampleCube(ml, faceIndex);
vec4 pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas vec4 pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas
vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy; vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy;
#ifdef _FlipY #ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif #endif
if (any(lessThan(uvtiled, vec2(0.0))) || any(greaterThan(uvtiled, vec2(1.0)))) {
return vec3(1.0); // Or handle edge cases differently
}
vec3 result = vec3(0.0); vec3 result = vec3(0.0);
result.x += texture(shadowMap, vec3(uvtiled, compare)); // In PCFFakeCube(), modify the sampling pattern to be more robust:
// soft shadowing const vec2 offsets[9] = vec2[](
int newFaceIndex = 0; vec2(0, 0),
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, 0.0) / smSize))); vec2(1, 0), vec2(-1, 0), vec2(0, 1), vec2(0, -1),
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex]; vec2(1, 1), vec2(-1, 1), vec2(1, -1), vec2(-1, -1)
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy; );
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result.x += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, 1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result.x += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(0.0, -1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result.x += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, -1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result.x += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(0.0, 1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result.x += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(1.0, -1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result.x += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(1.0, 0.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result.x += texture(shadowMap, vec3(uvtiled, compare));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(1.0, 1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result.x += texture(shadowMap, vec3(uvtiled, compare));
for (int i = 0; i < 9; i++) {
vec2 sampleUV = uv + offsets[i] / smSize;
int newFaceIndex;
vec2 transformedUV = transformOffsetedUV(faceIndex, newFaceIndex, sampleUV);
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * transformedUV + pointLightTile.xy;
#ifdef _FlipY
uvtiled.y = 1.0 - uvtiled.y;
#endif
result.x += texture(shadowMap, vec3(uvtiled, compare));
}
result = result.xxx / 9.0; result = result.xxx / 9.0;
pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas
@ -334,30 +281,47 @@ vec3 PCFFakeCube(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, cons
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif #endif
#ifdef _ShadowMapTransparent
if (transparent == false) { if (transparent == false) {
vec4 shadowmap_transparent = texture(shadowMapTransparent, uvtiled); vec4 shadowmap_transparent = texture(shadowMapTransparent, uvtiled);
if (shadowmap_transparent.a < compare) if (shadowmap_transparent.a < compare)
result *= shadowmap_transparent.rgb; result *= shadowmap_transparent.rgb;
} }
#endif
return result; return result;
} }
#endif #endif
vec3 shadowTest(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec3 lPos, const float shadowsBias, const bool transparent) { vec3 shadowTest(sampler2DShadow shadowMap,
#ifdef _ShadowMapTransparent
sampler2D shadowMapTransparent,
#endif
const vec3 lPos, const float shadowsBias
#ifdef _ShadowMapTransparent
, const bool transparent
#endif
) {
#ifdef _SMSizeUniform #ifdef _SMSizeUniform
vec2 smSize = smSizeUniform; vec2 smSize = smSizeUniform;
#else #else
const vec2 smSize = shadowmapSize; const vec2 smSize = shadowmapSize;
#endif #endif
if (lPos.x < 0.0 || lPos.y < 0.0 || lPos.x > 1.0 || lPos.y > 1.0) return vec3(1.0); if (lPos.x < 0.0 || lPos.y < 0.0 || lPos.x > 1.0 || lPos.y > 1.0) return vec3(1.0);
return PCF(shadowMap, shadowMapTransparent, lPos.xy, lPos.z - shadowsBias, smSize, transparent); return PCF(shadowMap,
#ifdef _ShadowMapTransparent
shadowMapTransparent,
#endif
lPos.xy, lPos.z - shadowsBias, smSize
#ifdef _ShadowMapTransparent
, transparent
#endif
);
} }
#ifdef _CSM #ifdef _CSM
mat4 getCascadeMat(const float d, out int casi, out int casIndex) { mat4 getCascadeMat(const float d, out int casi, out int casIndex) {
const int c = shadowmapCascades; const int c = shadowmapCascades;
// Get cascade index // Get cascade index
// TODO: use bounding box slice selection instead of sphere // TODO: use bounding box slice selection instead of sphere
const vec4 ci = vec4(float(c > 0), float(c > 1), float(c > 2), float(c > 3)); const vec4 ci = vec4(float(c > 0), float(c > 1), float(c > 2), float(c > 3));
@ -373,21 +337,26 @@ mat4 getCascadeMat(const float d, out int casi, out int casIndex) {
float(d > casData[c * 4].z), float(d > casData[c * 4].z),
float(d > casData[c * 4].w)); float(d > casData[c * 4].w));
casi = int(min(dot(ci, comp), c)); casi = int(min(dot(ci, comp), c));
// Get cascade mat // Get cascade mat
casIndex = casi * 4; casIndex = casi * 4;
return mat4( return mat4(
casData[casIndex ], casData[casIndex ],
casData[casIndex + 1], casData[casIndex + 1],
casData[casIndex + 2], casData[casIndex + 2],
casData[casIndex + 3]); casData[casIndex + 3]);
// if (casIndex == 0) return mat4(casData[0], casData[1], casData[2], casData[3]); // if (casIndex == 0) return mat4(casData[0], casData[1], casData[2], casData[3]);
// .. // ..
} }
vec3 shadowTestCascade(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec3 eye, const vec3 p, const float shadowsBias, const bool transparent) { vec3 shadowTestCascade(sampler2DShadow shadowMap,
#ifdef _ShadowMapTransparent
sampler2D shadowMapTransparent,
#endif
const vec3 eye, const vec3 p, const float shadowsBias
#ifdef _ShadowMapTransparent
, const bool transparent
#endif
) {
#ifdef _SMSizeUniform #ifdef _SMSizeUniform
vec2 smSize = smSizeUniform; vec2 smSize = smSizeUniform;
#else #else
@ -395,16 +364,22 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap, sampler2D shadowMapTransparent
#endif #endif
const int c = shadowmapCascades; const int c = shadowmapCascades;
float d = distance(eye, p); float d = distance(eye, p);
int casi; int casi;
int casIndex; int casIndex;
mat4 LWVP = getCascadeMat(d, casi, casIndex); mat4 LWVP = getCascadeMat(d, casi, casIndex);
vec4 lPos = LWVP * vec4(p, 1.0); vec4 lPos = LWVP * vec4(p, 1.0);
lPos.xyz /= lPos.w; lPos.xyz /= lPos.w;
vec3 visibility = vec3(1.0); vec3 visibility = vec3(1.0);
if (lPos.w > 0.0) visibility = PCF(shadowMap, shadowMapTransparent, lPos.xy, lPos.z - shadowsBias, smSize, transparent); if (lPos.w > 0.0) visibility = PCF(shadowMap,
#ifdef _ShadowMapTransparent
shadowMapTransparent,
#endif
lPos.xy, lPos.z - shadowsBias, smSize
#ifdef _ShadowMapTransparent
, transparent
#endif
);
// Blend cascade // Blend cascade
// https://github.com/TheRealMJP/Shadows // https://github.com/TheRealMJP/Shadows
@ -423,13 +398,20 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap, sampler2D shadowMapTransparent
vec4 lPos2 = LWVP2 * vec4(p, 1.0); vec4 lPos2 = LWVP2 * vec4(p, 1.0);
lPos2.xyz /= lPos2.w; lPos2.xyz /= lPos2.w;
vec3 visibility2 = vec3(1.0); vec3 visibility2 = vec3(1.0);
if (lPos2.w > 0.0) visibility2 = PCF(shadowMap, shadowMapTransparent, lPos2.xy, lPos2.z - shadowsBias, smSize, transparent); if (lPos2.w > 0.0) visibility2 = PCF(shadowMap,
#ifdef _ShadowMapTransparent
shadowMapTransparent,
#endif
lPos.xy, lPos.z - shadowsBias, smSize
#ifdef _ShadowMapTransparent
, transparent
#endif
);
float lerpAmt = smoothstep(0.0, blendThres, splitDist); float lerpAmt = smoothstep(0.0, blendThres, splitDist);
return mix(visibility2, visibility, lerpAmt); return mix(visibility2, visibility, lerpAmt);
} }
return visibility; return visibility;
// Visualize cascades // Visualize cascades
// if (ci == 0) albedo.rgb = vec3(1.0, 0.0, 0.0); // if (ci == 0) albedo.rgb = vec3(1.0, 0.0, 0.0);
// if (ci == 4) albedo.rgb = vec3(0.0, 1.0, 0.0); // if (ci == 4) albedo.rgb = vec3(0.0, 1.0, 0.0);
@ -437,4 +419,4 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap, sampler2D shadowMapTransparent
// if (ci == 12) albedo.rgb = vec3(1.0, 1.0, 0.0); // if (ci == 12) albedo.rgb = vec3(1.0, 1.0, 0.0);
} }
#endif #endif
#endif #endif

View File

@ -33,6 +33,7 @@ uniform layout(r32ui) uimage3D voxelsLight;
#ifdef _ShadowMap #ifdef _ShadowMap
uniform sampler2DShadow shadowMap; uniform sampler2DShadow shadowMap;
uniform sampler2D shadowMapTransparent;
uniform sampler2DShadow shadowMapSpot; uniform sampler2DShadow shadowMapSpot;
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
uniform sampler2DShadow shadowMapPoint; uniform sampler2DShadow shadowMapPoint;
@ -86,30 +87,28 @@ float lpToDepth(vec3 lp, const vec2 lightProj) {
void main() { void main() {
int res = voxelgiResolution.x; int res = voxelgiResolution.x;
ivec3 dst = ivec3(gl_GlobalInvocationID.xyz); ivec3 dst = ivec3(gl_GlobalInvocationID.xyz);
dst.y += clipmapLevel * res;
vec3 P = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution; vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x;
P = P * 2.0 - 1.0; wposition = wposition * 2.0 - 1.0;
P *= clipmaps[int(clipmapLevel * 10)]; wposition *= float(clipmaps[int(clipmapLevel * 10)]);
P *= voxelgiResolution; wposition *= voxelgiResolution.x;
P += vec3(clipmaps[int(clipmapLevel * 10 + 4)], clipmaps[int(clipmapLevel * 10 + 5)], clipmaps[int(clipmapLevel * 10 + 6)]); wposition += vec3(clipmaps[clipmapLevel * 10 + 4], clipmaps[clipmapLevel * 10 + 5], clipmaps[clipmapLevel * 10 + 6]);
vec3 visibility; float visibility;
vec3 lp = lightPos - P; vec3 lp = lightPos -wposition;
vec3 l; vec3 l;
if (lightType == 0) { l = lightDir; visibility = vec3(1.0); } if (lightType == 0) { l = lightDir; visibility = 1.0; }
else { l = normalize(lp); visibility = vec3(attenuate(distance(P, lightPos))); } else { l = normalize(lp); visibility = attenuate(distance(wposition, lightPos)); }
#ifdef _ShadowMap #ifdef _ShadowMap
if (lightShadow == 1) { if (lightShadow == 1) {
vec4 lightPosition = LVP * vec4(P, 1.0); vec4 lightPosition = LVP * vec4(wposition, 1.0);
vec3 lPos = lightPosition.xyz / lightPosition.w; vec3 lPos = lightPosition.xyz / lightPosition.w;
visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).rrr; visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).r;
} }
else if (lightShadow == 2) { else if (lightShadow == 2) {
vec4 lightPosition = LVP * vec4(P, 1.0); vec4 lightPosition = LVP * vec4(wposition, 1.0);
vec3 lPos = lightPosition.xyz / lightPosition.w; vec3 lPos = lightPosition.xyz / lightPosition.w;
visibility *= texture(shadowMapSpot, vec3(lPos.xy, lPos.z - shadowsBias)).r; visibility *= texture(shadowMapSpot, vec3(lPos.xy, lPos.z - shadowsBias)).r;
} }
@ -130,9 +129,7 @@ void main() {
} }
#endif #endif
vec3 light = visibility * lightColor; imageAtomicAdd(voxelsLight, dst, uint(visibility * lightColor.r * 255));
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x), uint(visibility * lightColor.g * 255));
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, 0), uint(light.r * 255)); imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x * 2), uint(visibility * lightColor.b * 255));
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x), uint(light.g * 255));
imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x * 2), uint(light.b * 255));
} }

View File

@ -27,14 +27,14 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
#include "std/math.glsl" #include "std/math.glsl"
#include "std/gbuffer.glsl" #include "std/gbuffer.glsl"
#include "std/imageatomic.glsl" #include "std/imageatomic.glsl"
#include "std/voxels_constants.glsl" #include "std/constants.glsl"
#ifdef _VoxelGI #ifdef _VoxelGI
uniform layout(rgba8) image3D voxelsB; uniform layout(rgba8) image3D voxelsB;
uniform layout(rgba8) image3D voxelsOut; uniform layout(rgba8) image3D voxelsOut;
#else #else
uniform layout(r16) image3D voxelsB; uniform layout(r8) image3D voxelsB;
uniform layout(r16) image3D voxelsOut; uniform layout(r8) image3D voxelsOut;
#endif #endif
uniform int clipmapLevel; uniform int clipmapLevel;

View File

@ -29,19 +29,38 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#include "std/gbuffer.glsl" #include "std/gbuffer.glsl"
#include "std/imageatomic.glsl" #include "std/imageatomic.glsl"
#include "std/conetrace.glsl" #include "std/conetrace.glsl"
#include "std/brdf.glsl"
#include "std/shirr.glsl"
uniform sampler3D voxels; uniform sampler3D voxels;
uniform sampler2D gbufferD; uniform sampler2D gbufferD;
uniform sampler2D gbuffer0; uniform sampler2D gbuffer0;
uniform layout(r8) image2D voxels_ao; uniform layout(rgba8) image2D voxels_ao;
uniform float clipmaps[voxelgiClipmapCount * 10]; uniform float clipmaps[voxelgiClipmapCount * 10];
uniform mat4 InvVP; uniform mat4 InvVP;
uniform vec2 cameraProj;
uniform vec3 eye; uniform vec3 eye;
uniform vec3 eyeLook;
uniform vec2 postprocess_resolution; uniform vec2 postprocess_resolution;
uniform sampler2D gbuffer1;
#ifdef _gbuffer2
uniform sampler2D gbuffer2;
#endif
uniform float envmapStrength;
#ifdef _Irr
uniform float shirr[7 * 4];
#endif
#ifdef _Brdf
uniform sampler2D senvmapBrdf;
#endif
#ifdef _Rad
uniform sampler2D senvmapRadiance;
uniform int envmapNumMipmaps;
#endif
#ifdef _EnvCol
uniform vec3 backgroundCol;
#endif
void main() { void main() {
const vec2 pixel = gl_GlobalInvocationID.xy; const vec2 pixel = gl_GlobalInvocationID.xy;
vec2 uv = (pixel + 0.5) / postprocess_resolution; vec2 uv = (pixel + 0.5) / postprocess_resolution;
@ -54,12 +73,11 @@ void main() {
float x = uv.x * 2 - 1; float x = uv.x * 2 - 1;
float y = uv.y * 2 - 1; float y = uv.y * 2 - 1;
vec4 v = vec4(x, y, 1.0, 1.0); vec4 clipPos = vec4(x, y, depth, 1.0);
v = vec4(InvVP * v); vec4 worldPos = InvVP * clipPos;
v.xyz /= v.w; vec3 P = worldPos.xyz / worldPos.w;
vec3 viewRay = v.xyz - eye;
vec3 P = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj); vec3 v = normalize(eye - P);
vec4 g0 = textureLod(gbuffer0, uv, 0.0); vec4 g0 = textureLod(gbuffer0, uv, 0.0);
vec3 n; vec3 n;
@ -67,7 +85,89 @@ void main() {
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy); n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
n = normalize(n); n = normalize(n);
float occ = 1.0 - traceAO(P, n, voxels, clipmaps); float roughness = g0.b;
float metallic;
uint matid;
unpackFloatInt16(g0.a, metallic, matid);
imageStore(voxels_ao, ivec2(pixel), vec4(occ)); vec4 g1 = textureLod(gbuffer1, uv, 0.0); // Basecolor.rgb, spec/occ
vec2 occspec = unpackFloat2(g1.a);
vec3 albedo = surfaceAlbedo(g1.rgb, metallic); // g1.rgb - basecolor
vec3 f0 = surfaceF0(g1.rgb, metallic);
float dotNV = max(dot(n, v), 0.0);
#ifdef _gbuffer2
vec4 g2 = textureLod(gbuffer2, uv, 0.0);
#endif
#ifdef _MicroShadowing
occspec.x = mix(1.0, occspec.x, dotNV); // AO Fresnel
#endif
#ifdef _Brdf
vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy;
vec3 F = f0 * envBRDF.x + envBRDF.y;
#endif
// Envmap
#ifdef _Irr
vec4 shPacked[7];
for (int i = 0; i < 7; i++) {
int base = i * 4;
shPacked[i] = vec4(
shirr[base],
shirr[base + 1],
shirr[base + 2],
shirr[base + 3]
);
}
vec3 envl = shIrradiance(n, shPacked);
#ifdef _gbuffer2
if (g2.b < 0.5) {
envl = envl;
} else {
envl = vec3(0.0);
}
#endif
#ifdef _EnvTex
envl /= PI;
#endif
#else
vec3 envl = vec3(0.0);
#endif
#ifdef _Rad
vec3 reflectionWorld = reflect(-v, n);
float lod = getMipFromRoughness(roughness, envmapNumMipmaps);
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
#endif
#ifdef _EnvLDR
envl.rgb = pow(envl.rgb, vec3(2.2));
#ifdef _Rad
prefilteredColor = pow(prefilteredColor, vec3(2.2));
#endif
#endif
envl.rgb *= albedo;
#ifdef _Brdf
envl.rgb *= 1.0 - F; //LV: We should take refracted light into account
#endif
#ifdef _Rad // Indirect specular
envl.rgb += prefilteredColor * F; //LV: Removed "1.5 * occspec.y". Specular should be weighted only by FV LUT
#else
#ifdef _EnvCol
envl.rgb += backgroundCol * F; //LV: Eh, what's the point of weighting it only by F0?
#endif
#endif
envl.rgb *= envmapStrength * occspec.x;
vec3 occ = envl * (1.0 - traceAO(P, n, voxels, clipmaps));
imageStore(voxels_ao, ivec2(pixel), vec4(occ, 1.0));
} }

View File

@ -29,6 +29,8 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#include "std/gbuffer.glsl" #include "std/gbuffer.glsl"
#include "std/imageatomic.glsl" #include "std/imageatomic.glsl"
#include "std/conetrace.glsl" #include "std/conetrace.glsl"
#include "std/brdf.glsl"
#include "std/shirr.glsl"
uniform sampler3D voxels; uniform sampler3D voxels;
uniform sampler2D gbufferD; uniform sampler2D gbufferD;
@ -37,29 +39,44 @@ uniform layout(rgba8) image2D voxels_diffuse;
uniform float clipmaps[voxelgiClipmapCount * 10]; uniform float clipmaps[voxelgiClipmapCount * 10];
uniform mat4 InvVP; uniform mat4 InvVP;
uniform vec2 cameraProj;
uniform vec3 eye; uniform vec3 eye;
uniform vec3 eyeLook;
uniform vec2 postprocess_resolution; uniform vec2 postprocess_resolution;
uniform sampler2D gbuffer1;
#ifdef _gbuffer2
uniform sampler2D gbuffer2;
#endif
uniform float envmapStrength;
#ifdef _Irr
uniform float shirr[7 * 4];
#endif
#ifdef _Brdf
uniform sampler2D senvmapBrdf;
#endif
#ifdef _Rad
uniform sampler2D senvmapRadiance;
uniform int envmapNumMipmaps;
#endif
#ifdef _EnvCol
uniform vec3 backgroundCol;
#endif
void main() { void main() {
const vec2 pixel = gl_GlobalInvocationID.xy; const vec2 pixel = gl_GlobalInvocationID.xy;
vec2 uv = (pixel + 0.5) / postprocess_resolution; vec2 uv = (pixel + 0.5) / postprocess_resolution;
#ifdef _InvY #ifdef _InvY
uv.y = 1.0 - uv.y uv.y = 1.0 - uv.y;
#endif #endif
float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0; float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
if (depth == 0) return; if (depth == 0.0) return;
float x = uv.x * 2 - 1; float x = uv.x * 2 - 1;
float y = uv.y * 2 - 1; float y = uv.y * 2 - 1;
vec4 v = vec4(x, y, 1.0, 1.0); vec4 clipPos = vec4(x, y, depth, 1.0);
v = vec4(InvVP * v); vec4 worldPos = InvVP * clipPos;
v.xyz /= v.w; vec3 P = worldPos.xyz / worldPos.w;
vec3 viewRay = v.xyz - eye; vec3 v = normalize(eye - P);
vec3 P = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
vec4 g0 = textureLod(gbuffer0, uv, 0.0); vec4 g0 = textureLod(gbuffer0, uv, 0.0);
vec3 n; vec3 n;
@ -67,7 +84,91 @@ void main() {
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy); n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
n = normalize(n); n = normalize(n);
vec4 color = traceDiffuse(P, n, voxels, clipmaps); float roughness = g0.b;
float metallic;
uint matid;
unpackFloatInt16(g0.a, metallic, matid);
imageStore(voxels_diffuse, ivec2(pixel), color); vec4 g1 = textureLod(gbuffer1, uv, 0.0); // Basecolor.rgb, spec/occ
vec2 occspec = unpackFloat2(g1.a);
vec3 albedo = surfaceAlbedo(g1.rgb, metallic); // g1.rgb - basecolor
vec3 f0 = surfaceF0(g1.rgb, metallic);
float dotNV = max(dot(n, v), 0.0);
#ifdef _gbuffer2
vec4 g2 = textureLod(gbuffer2, uv, 0.0);
#endif
#ifdef _MicroShadowing
occspec.x = mix(1.0, occspec.x, dotNV); // AO Fresnel
#endif
#ifdef _Brdf
vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy;
vec3 F = f0 * envBRDF.x + envBRDF.y;
#endif
// Envmap
#ifdef _Irr
vec4 shPacked[7];
for (int i = 0; i < 7; i++) {
int base = i * 4;
shPacked[i] = vec4(
shirr[base],
shirr[base + 1],
shirr[base + 2],
shirr[base + 3]
);
}
vec3 envl = shIrradiance(n, shPacked);
#ifdef _gbuffer2
if (g2.b < 0.5) {
envl = envl;
} else {
envl = vec3(0.0);
}
#endif
#ifdef _EnvTex
envl /= PI;
#endif
#else
vec3 envl = vec3(0.0);
#endif
#ifdef _Rad
vec3 reflectionWorld = reflect(-v, n);
float lod = getMipFromRoughness(roughness, envmapNumMipmaps);
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
#endif
#ifdef _EnvLDR
envl.rgb = pow(envl.rgb, vec3(2.2));
#ifdef _Rad
prefilteredColor = pow(prefilteredColor, vec3(2.2));
#endif
#endif
envl.rgb *= albedo;
#ifdef _Brdf
envl.rgb *= 1.0 - F; //LV: We should take refracted light into account
#endif
#ifdef _Rad // Indirect specular
envl.rgb += prefilteredColor * F; //LV: Removed "1.5 * occspec.y". Specular should be weighted only by FV LUT
#else
#ifdef _EnvCol
envl.rgb += backgroundCol * F; //LV: Eh, what's the point of weighting it only by F0?
#endif
#endif
envl.rgb *= envmapStrength * occspec.x;
vec4 trace = traceDiffuse(P, n, voxels, clipmaps);
vec3 color = trace.rgb * albedo * (1.0 - F);
color += envl * (1.0 - trace.a);
imageStore(voxels_diffuse, ivec2(pixel), vec4(color, 1.0));
} }

View File

@ -1,79 +0,0 @@
/*
Copyright (c) 2024 Turánszki János
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#version 450
layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#include "compiled.inc"
#include "std/math.glsl"
#include "std/gbuffer.glsl"
#include "std/imageatomic.glsl"
#include "std/conetrace.glsl"
uniform sampler2D gbufferD;
uniform sampler2D gbuffer0;
uniform sampler3D voxels;
uniform sampler3D voxelsSDF;
uniform sampler2D gbuffer_refraction;
uniform layout(rgba8) image2D voxels_refraction;
uniform float clipmaps[voxelgiClipmapCount * 10];
uniform mat4 InvVP;
uniform vec2 cameraProj;
uniform vec3 eye;
uniform vec3 eyeLook;
uniform vec2 postprocess_resolution;
void main() {
const vec2 pixel = gl_GlobalInvocationID.xy;
vec2 uv = (pixel + 0.5) / postprocess_resolution;
#ifdef _InvY
uv.y = 1.0 - uv.y
#endif
float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
if (depth == 0) return;
vec2 ior_opac = textureLod(gbuffer_refraction, uv, 0.0).xy;
float x = uv.x * 2 - 1;
float y = uv.y * 2 - 1;
vec4 v = vec4(x, y, 1.0, 1.0);
v = vec4(InvVP * v);
v.xyz /= v.w;
vec3 viewRay = v.xyz - eye;
vec3 P = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
vec4 g0 = textureLod(gbuffer0, uv, 0.0);
vec3 n;
n.z = 1.0 - abs(g0.x) - abs(g0.y);
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
n = normalize(n);
vec3 color = vec3(0.0);
if(ior_opac.y < 1.0)
color = traceRefraction(P, n, voxels, voxelsSDF, normalize(eye - P), ior_opac.x, g0.b, clipmaps, pixel).rgb;
imageStore(voxels_refraction, ivec2(pixel), vec4(color, 1.0));
}

View File

@ -1,75 +0,0 @@
/*
Copyright (c) 2024 Turánszki János
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#version 450
layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#include "compiled.inc"
#include "std/math.glsl"
#include "std/gbuffer.glsl"
#include "std/imageatomic.glsl"
#include "std/conetrace.glsl"
uniform sampler3D voxels;
uniform sampler3D voxelsSDF;
uniform sampler2D gbufferD;
uniform sampler2D gbuffer0;
uniform layout(r16) image2D voxels_shadows;
uniform float clipmaps[voxelgiClipmapCount * 10];
uniform mat4 InvVP;
uniform vec2 cameraProj;
uniform vec3 eye;
uniform vec3 eyeLook;
uniform vec2 postprocess_resolution;
uniform vec3 lPos;
void main() {
const vec2 pixel = gl_GlobalInvocationID.xy;
vec2 uv = (pixel + 0.5) / postprocess_resolution;
#ifdef _InvY
uv.y = 1.0 - uv.y;
#endif
float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
if (depth == 0) return;
float x = uv.x * 2 - 1;
float y = uv.y * 2 - 1;
vec4 v = vec4(x, y, 1.0, 1.0);
v = vec4(InvVP * v);
v.xyz /= v.w;
vec3 viewRay = v.xyz - eye;
vec3 P = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
vec4 g0 = textureLod(gbuffer0, uv, 0.0);
vec3 n;
n.z = 1.0 - abs(g0.x) - abs(g0.y);
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
n = normalize(n);
float occ = 1.0 - traceShadow(P, n, voxels, voxelsSDF, normalize(lPos - P), clipmaps, pixel);
imageStore(voxels_shadows, ivec2(pixel), vec4(occ));
}

View File

@ -29,6 +29,7 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#include "std/gbuffer.glsl" #include "std/gbuffer.glsl"
#include "std/imageatomic.glsl" #include "std/imageatomic.glsl"
#include "std/conetrace.glsl" #include "std/conetrace.glsl"
#include "std/brdf.glsl"
uniform sampler2D gbufferD; uniform sampler2D gbufferD;
uniform sampler2D gbuffer0; uniform sampler2D gbuffer0;
@ -38,9 +39,7 @@ uniform layout(rgba8) image2D voxels_specular;
uniform float clipmaps[voxelgiClipmapCount * 10]; uniform float clipmaps[voxelgiClipmapCount * 10];
uniform mat4 InvVP; uniform mat4 InvVP;
uniform vec2 cameraProj;
uniform vec3 eye; uniform vec3 eye;
uniform vec3 eyeLook;
uniform vec2 postprocess_resolution; uniform vec2 postprocess_resolution;
uniform sampler2D sveloc; uniform sampler2D sveloc;
@ -56,12 +55,10 @@ void main() {
float x = uv.x * 2 - 1; float x = uv.x * 2 - 1;
float y = uv.y * 2 - 1; float y = uv.y * 2 - 1;
vec4 v = vec4(x, y, 1.0, 1.0); vec4 clipPos = vec4(x, y, depth, 1.0);
v = vec4(InvVP * v); vec4 worldPos = InvVP * clipPos;
v.xyz /= v.w; vec3 P = worldPos.xyz / worldPos.w;
vec3 viewRay = v.xyz - eye;
vec3 P = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
vec4 g0 = textureLod(gbuffer0, uv, 0.0); vec4 g0 = textureLod(gbuffer0, uv, 0.0);
vec3 n; vec3 n;
@ -71,7 +68,7 @@ void main() {
vec2 velocity = -textureLod(sveloc, uv, 0.0).rg; vec2 velocity = -textureLod(sveloc, uv, 0.0).rg;
vec3 color = traceSpecular(P, n, voxels, voxelsSDF, normalize(eye - P), g0.z, clipmaps, pixel, velocity).rgb; vec3 color = traceSpecular(P, n, voxels, voxelsSDF, normalize(eye - P), g0.z * g0.z, clipmaps, pixel, velocity).rgb;
imageStore(voxels_specular, ivec2(pixel), vec4(color, 1.0)); imageStore(voxels_specular, ivec2(pixel), vec4(color, 1.0));
} }

View File

@ -23,8 +23,8 @@ THE SOFTWARE.
#include "compiled.inc" #include "compiled.inc"
uniform layout(r16) image3D input_sdf; uniform layout(r8) image3D input_sdf;
uniform layout(r16) image3D output_sdf; uniform layout(r8) image3D output_sdf;
uniform float jump_size; uniform float jump_size;
uniform int clipmapLevel; uniform int clipmapLevel;

View File

@ -46,15 +46,15 @@ uniform layout(r32ui) uimage3D voxels;
uniform layout(r32ui) uimage3D voxelsLight; uniform layout(r32ui) uimage3D voxelsLight;
uniform layout(rgba8) image3D voxelsB; uniform layout(rgba8) image3D voxelsB;
uniform layout(rgba8) image3D voxelsOut; uniform layout(rgba8) image3D voxelsOut;
uniform layout(r16) image3D SDF; uniform layout(r8) image3D SDF;
#else #else
#ifdef _VoxelAOvar #ifdef _VoxelAOvar
#ifdef _VoxelShadow #ifdef _VoxelShadow
uniform layout(r16) image3D SDF; uniform layout(r8) image3D SDF;
#endif #endif
uniform layout(r32ui) uimage3D voxels; uniform layout(r32ui) uimage3D voxels;
uniform layout(r16) image3D voxelsB; uniform layout(r8) image3D voxelsB;
uniform layout(r16) image3D voxelsOut; uniform layout(r8) image3D voxelsOut;
#endif #endif
#endif #endif
@ -74,14 +74,8 @@ void main() {
#endif #endif
#endif #endif
ivec3 src = ivec3(gl_GlobalInvocationID.xyz); mat3 TBN = mat3(1.0);
#ifdef _VoxelGI vec3 avgNormal = vec3(0.0);
vec3 light = vec3(0.0);
light.r = float(imageLoad(voxelsLight, src)) / 255;
light.g = float(imageLoad(voxelsLight, src + ivec3(0, 0, voxelgiResolution.x))) / 255;
light.b = float(imageLoad(voxelsLight, src + ivec3(0, 0, voxelgiResolution.x * 2))) / 255;
light /= 3;
#endif
for (int i = 0; i < 6 + DIFFUSE_CONE_COUNT; i++) for (int i = 0; i < 6 + DIFFUSE_CONE_COUNT; i++)
{ {
@ -91,7 +85,7 @@ void main() {
float aniso_colors[6]; float aniso_colors[6];
#endif #endif
src = ivec3(gl_GlobalInvocationID.xyz); ivec3 src = ivec3(gl_GlobalInvocationID.xyz);
src.x += i * res; src.x += i * res;
ivec3 dst = src; ivec3 dst = src;
dst.y += clipmapLevel * res; dst.y += clipmapLevel * res;
@ -104,44 +98,59 @@ void main() {
if (i < 6) { if (i < 6) {
#ifdef _VoxelGI #ifdef _VoxelGI
vec4 basecol = vec4(0.0); int count = int(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 15)));
basecol.r = float(imageLoad(voxels, src)) / 255; if (count > 0) {
basecol.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x))) / 255; vec4 basecol = vec4(0.0);
basecol.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 2))) / 255; basecol.r = float(imageLoad(voxels, src)) / 255;
basecol.a = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 3))) / 255; basecol.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x))) / 255;
basecol /= 4; basecol.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 2))) / 255;
vec3 emission = vec3(0.0); basecol.a = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 3))) / 255;
emission.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 4))) / 255; basecol /= count;
emission.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 5))) / 255; vec3 emission = vec3(0.0);
emission.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 6))) / 255; emission.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 4))) / 255;
emission /= 3; emission.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 5))) / 255;
vec3 N = vec3(0.0); emission.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 6))) / 255;
N.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 7))) / 255; emission /= count;
N.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 8))) / 255; vec3 N = vec3(0.0);
N /= 2; N.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 7))) / 255;
vec3 wnormal = decode_oct(N.rg * 2 - 1); N.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 8))) / 255;
vec3 envl = vec3(0.0); N /= count;
envl.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 9))) / 255; N = decode_oct(N.rg * 2.0 - 1.0);
envl.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 10))) / 255; avgNormal += N;
envl.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 11))) / 255;
envl /= 3;
envl *= 100;
//clipmap to world if (i == 5)
vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x; TBN = makeTangentBasis(normalize(avgNormal));
wposition = wposition * 2.0 - 1.0;
wposition *= float(clipmaps[int(clipmapLevel * 10)]);
wposition *= voxelgiResolution.x;
wposition += vec3(clipmaps[clipmapLevel * 10 + 4], clipmaps[clipmapLevel * 10 + 5], clipmaps[clipmapLevel * 10 + 6]);
radiance = basecol; vec3 envl = vec3(0.0);
vec4 trace = traceDiffuse(wposition, wnormal, voxelsSampler, clipmaps); envl.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 9))) / 255;
vec3 indirect = trace.rgb + envl.rgb * (1.0 - trace.a); envl.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 10))) / 255;
radiance.rgb *= light + indirect; envl.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 11))) / 255;
radiance.rgb += emission.rgb; envl /= count;
vec3 light = vec3(0.0);
light.r = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 12))) / 255;
light.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 13))) / 255;
light.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 14))) / 255;
light /= count;
//clipmap to world
vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x;
wposition = wposition * 2.0 - 1.0;
wposition *= float(clipmaps[int(clipmapLevel * 10)]);
wposition *= voxelgiResolution.x;
wposition += vec3(clipmaps[clipmapLevel * 10 + 4], clipmaps[clipmapLevel * 10 + 5], clipmaps[clipmapLevel * 10 + 6]);
radiance = basecol;
vec4 trace = traceDiffuse(wposition, N, voxelsSampler, clipmaps);
vec3 indirect = trace.rgb + envl.rgb * (1.0 - trace.a);
radiance.rgb *= light + indirect;
radiance.rgb += emission.rgb;
}
#else #else
opac = float(imageLoad(voxels, src)) / 255; int count = int(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x)));
if (count > 0) {
opac = float(imageLoad(voxels, src)) / 255;
opac /= count;
}
#endif #endif
#ifdef _VoxelGI #ifdef _VoxelGI
@ -195,7 +204,7 @@ void main() {
} }
else { else {
// precompute cone sampling: // precompute cone sampling:
vec3 coneDirection = DIFFUSE_CONE_DIRECTIONS[i - 6]; vec3 coneDirection = TBN * DIFFUSE_CONE_DIRECTIONS[i - 6];
vec3 aniso_direction = -coneDirection; vec3 aniso_direction = -coneDirection;
uvec3 face_offsets = uvec3( uvec3 face_offsets = uvec3(
aniso_direction.x > 0 ? 0 : 1, aniso_direction.x > 0 ? 0 : 1,

View File

@ -75,16 +75,17 @@ vec4 binarySearch(vec3 dir) {
} }
vec4 rayCast(vec3 dir) { vec4 rayCast(vec3 dir) {
#ifdef _CPostprocess float ddepth;
dir *= PPComp9.x; dir *= ss_refractionRayStep;
#else for (int i = 0; i < maxSteps; i++) {
dir *= ssrRayStep; hitCoord += dir;
#endif ddepth = getDeltaDepth(hitCoord);
for (int i = 0; i < maxSteps; i++) { if (ddepth > 0.0)
hitCoord += dir; return binarySearch(dir);
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir); }
} // No hit — fallback to projecting the ray to UV space
return vec4(0.0); vec2 fallbackUV = getProjectedCoord(hitCoord);
return vec4(fallbackUV, 0.0, 0.5); // We set .w lower to indicate fallback
} }
#endif //SSR #endif //SSR

View File

@ -181,11 +181,15 @@ class Uniforms {
// Multiple voxel volumes, always set params // Multiple voxel volumes, always set params
g.setImageTexture(context.textureUnits[j], rt.image); // image2D/3D g.setImageTexture(context.textureUnits[j], rt.image); // image2D/3D
if (rt.raw.name.startsWith("voxels_")) { if (rt.raw.name.startsWith("voxels_")) {
g.setTextureParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.LinearFilter, TextureFilter.LinearFilter, MipMapFilter.NoMipFilter); g.setTextureParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.LinearFilter, TextureFilter.LinearFilter, MipMapFilter.LinearMipFilter);
}
else if (rt.raw.name.startsWith("voxelsSDF"))
{
g.setTexture3DParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.PointFilter, TextureFilter.PointFilter, MipMapFilter.NoMipFilter);
} }
else if (rt.raw.name.startsWith("voxels")) else if (rt.raw.name.startsWith("voxels"))
{ {
g.setTexture3DParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.LinearFilter, TextureFilter.LinearFilter, MipMapFilter.NoMipFilter); g.setTexture3DParameters(context.textureUnits[j], TextureAddressing.Clamp, TextureAddressing.Clamp, TextureAddressing.Clamp, TextureFilter.LinearFilter, TextureFilter.LinearFilter, MipMapFilter.PointMipFilter);
} }
else else
{ {

View File

@ -34,10 +34,10 @@ class Inc {
#if (rp_voxels == "Voxel GI") #if (rp_voxels == "Voxel GI")
static var voxel_td1:kha.compute.TextureUnit; static var voxel_td1:kha.compute.TextureUnit;
static var voxel_te1:kha.compute.TextureUnit; static var voxel_te1:kha.compute.TextureUnit;
static var voxel_tf1:kha.compute.TextureUnit; static var voxel_cc1:kha.compute.ConstantLocation;
#else #else
#if lnx_voxelgi_shadows #if lnx_voxelgi_shadows
static var voxel_tf1:kha.compute.TextureUnit; static var voxel_te1:kha.compute.TextureUnit;
#end #end
#end #end
#if (lnx_voxelgi_shadows || rp_voxels == "Voxel GI") #if (lnx_voxelgi_shadows || rp_voxels == "Voxel GI")
@ -53,12 +53,28 @@ class Inc {
static var voxel_tb3:kha.compute.TextureUnit; static var voxel_tb3:kha.compute.TextureUnit;
static var voxel_tc3:kha.compute.TextureUnit; static var voxel_tc3:kha.compute.TextureUnit;
static var voxel_td3:kha.compute.TextureUnit; static var voxel_td3:kha.compute.TextureUnit;
static var voxel_te3:kha.compute.TextureUnit;
static var voxel_tf3:kha.compute.TextureUnit;
#if lnx_brdf
static var voxel_tg3:kha.compute.TextureUnit;
#end
#if lnx_radiance
static var voxel_th3:kha.compute.TextureUnit;
#end
static var voxel_ca3:kha.compute.ConstantLocation; static var voxel_ca3:kha.compute.ConstantLocation;
static var voxel_cb3:kha.compute.ConstantLocation; static var voxel_cb3:kha.compute.ConstantLocation;
static var voxel_cc3:kha.compute.ConstantLocation; static var voxel_cc3:kha.compute.ConstantLocation;
static var voxel_cd3:kha.compute.ConstantLocation; static var voxel_cd3:kha.compute.ConstantLocation;
static var voxel_ce3:kha.compute.ConstantLocation; static var voxel_ce3:kha.compute.ConstantLocation;
#if lnx_irradiance
static var voxel_cf3:kha.compute.ConstantLocation; static var voxel_cf3:kha.compute.ConstantLocation;
#end
#if lnx_radiance
static var voxel_cg3:kha.compute.ConstantLocation;
#end
#if lnx_envcol
static var voxel_ch3:kha.compute.ConstantLocation;
#end
#if (rp_voxels == "Voxel GI") #if (rp_voxels == "Voxel GI")
static var voxel_sh4:kha.compute.Shader = null; static var voxel_sh4:kha.compute.Shader = null;
static var voxel_ta4:kha.compute.TextureUnit; static var voxel_ta4:kha.compute.TextureUnit;
@ -71,33 +87,6 @@ class Inc {
static var voxel_cb4:kha.compute.ConstantLocation; static var voxel_cb4:kha.compute.ConstantLocation;
static var voxel_cc4:kha.compute.ConstantLocation; static var voxel_cc4:kha.compute.ConstantLocation;
static var voxel_cd4:kha.compute.ConstantLocation; static var voxel_cd4:kha.compute.ConstantLocation;
static var voxel_ce4:kha.compute.ConstantLocation;
static var voxel_cf4:kha.compute.ConstantLocation;
#end
#if (rp_voxels == "Voxel GI")
static var voxel_sh5:kha.compute.Shader = null;
static var voxel_ta5:kha.compute.TextureUnit;
static var voxel_ca5:kha.compute.ConstantLocation;
static var voxel_cb5:kha.compute.ConstantLocation;
static var voxel_cc5:kha.compute.ConstantLocation;
static var voxel_cd5:kha.compute.ConstantLocation;
static var voxel_ce5:kha.compute.ConstantLocation;
static var voxel_cf5:kha.compute.ConstantLocation;
static var voxel_cg5:kha.compute.ConstantLocation;
#if rp_shadowmap
static var voxel_tb5:kha.compute.TextureUnit;
static var voxel_tc5:kha.compute.TextureUnit;
static var voxel_td5:kha.compute.TextureUnit;
static var voxel_ch5:kha.compute.ConstantLocation;
static var voxel_ci5:kha.compute.ConstantLocation;
static var voxel_cj5:kha.compute.ConstantLocation;
static var voxel_ck5:kha.compute.ConstantLocation;
static var voxel_cl5:kha.compute.ConstantLocation;
static var voxel_cm5:kha.compute.ConstantLocation;
#if lnx_shadowmap_atlas
static var m2 = iron.math.Mat4.identity();
#end
#end
#end #end
#end //rp_voxels #end //rp_voxels
@ -163,9 +152,11 @@ class Inc {
for (atlas in ShadowMapAtlas.shadowMapAtlases) { for (atlas in ShadowMapAtlas.shadowMapAtlases) {
path.bindTarget(atlas.target, atlas.target); path.bindTarget(atlas.target, atlas.target);
} }
#if rp_shadowmap_transparent
for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) { for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) {
path.bindTarget(atlas.target, atlas.target); path.bindTarget(atlas.target, atlas.target);
} }
#end
} }
static function getShadowMapAtlas(atlas:ShadowMapAtlas, transparent: Bool):String { static function getShadowMapAtlas(atlas:ShadowMapAtlas, transparent: Bool):String {
@ -206,24 +197,30 @@ class Inc {
for (atlas in ShadowMapAtlas.shadowMapAtlases) { for (atlas in ShadowMapAtlas.shadowMapAtlases) {
atlas.rejectedLights = []; atlas.rejectedLights = [];
} }
#if rp_shadowmap_transparent
for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) { for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) {
atlas.rejectedLights = []; atlas.rejectedLights = [];
} }
#end #end
#end
for (light in iron.Scene.active.lights) { for (light in iron.Scene.active.lights) {
if (!light.lightInAtlas && !light.culledLight && light.visible && light.shadowMapScale > 0.0 if (!light.lightInAtlas && !light.culledLight && light.visible && light.shadowMapScale > 0.0
&& light.data.raw.strength > 0.0 && light.data.raw.cast_shadow) { && light.data.raw.strength > 0.0 && light.data.raw.cast_shadow) {
ShadowMapAtlas.addLight(light, false); ShadowMapAtlas.addLight(light, false);
} }
#if rp_shadowmap_transparent
if (!light.lightInAtlasTransparent && !light.culledLight && light.visible && light.shadowMapScale > 0.0 if (!light.lightInAtlasTransparent && !light.culledLight && light.visible && light.shadowMapScale > 0.0
&& light.data.raw.strength > 0.0 && light.data.raw.cast_shadow) { && light.data.raw.strength > 0.0 && light.data.raw.cast_shadow) {
ShadowMapAtlas.addLight(light, true); ShadowMapAtlas.addLight(light, true);
} }
#end
} }
// update point light data before rendering // update point light data before rendering
updatePointLightAtlasData(true);
updatePointLightAtlasData(false); updatePointLightAtlasData(false);
#if rp_shadowmap_transparent
updatePointLightAtlasData(true);
#end
for (atlas in ShadowMapAtlas.shadowMapAtlases) { for (atlas in ShadowMapAtlas.shadowMapAtlases) {
var tilesToRemove = []; var tilesToRemove = [];
@ -301,6 +298,7 @@ class Inc {
path.endStream(); path.endStream();
} }
#if rp_shadowmap_transparent
for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) { for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) {
var tilesToRemove = []; var tilesToRemove = [];
#if lnx_shadowmap_atlas_lod #if lnx_shadowmap_atlas_lod
@ -395,10 +393,8 @@ class Inc {
tile.freeTile(); tile.freeTile();
} }
} }
#if lnx_debug
endShadowsLogicProfile();
#end #end
#end // rp_shadowmap #end
} }
#else #else
public static function bindShadowMap() { public static function bindShadowMap() {
@ -501,6 +497,7 @@ class Inc {
else if (l.data.raw.type == "spot" || l.data.raw.type == "area") spotIndex++; else if (l.data.raw.type == "spot" || l.data.raw.type == "area") spotIndex++;
} }
#if rp_shadowmap_transparent
pointIndex = 0; pointIndex = 0;
spotIndex = 0; spotIndex = 0;
for (l in iron.Scene.active.lights) { for (l in iron.Scene.active.lights) {
@ -522,6 +519,7 @@ class Inc {
if (l.data.raw.type == "point") pointIndex++; if (l.data.raw.type == "point") pointIndex++;
else if (l.data.raw.type == "spot" || l.data.raw.type == "area") spotIndex++; else if (l.data.raw.type == "spot" || l.data.raw.type == "area") spotIndex++;
} }
#end
#end // rp_shadowmap #end // rp_shadowmap
} }
#end #end
@ -589,7 +587,7 @@ class Inc {
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = getDisplayp(); t.displayp = getDisplayp();
t.format = "R32"; t.format = "R16";
t.scale = getSuperSampling(); t.scale = getSuperSampling();
t.depth_buffer = "main"; t.depth_buffer = "main";
path.createRenderTarget(t); path.createRenderTarget(t);
@ -615,10 +613,14 @@ class Inc {
#end #end
#if (rp_voxels != "Off") #if (rp_voxels != "Off")
{ path.bindTarget("voxelsOut", "voxels");
path.bindTarget("voxelsOut", "voxels"); #if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
path.bindTarget("voxelsSDF", "voxelsSDF"); path.bindTarget("voxelsSDF", "voxelsSDF");
} #end
#end
#if rp_ssrs
path.bindTarget("_main", "gbufferD");
#end #end
path.drawMeshes("translucent"); path.drawMeshes("translucent");
@ -679,12 +681,11 @@ class Inc {
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = getDisplayp(); t.displayp = getDisplayp();
//t.scale = Inc.getSuperSampling(); t.format = "RGBA32";
t.format = t.name == "voxels_ao" ? "R8" : "RGBA32";
} }
else { else {
if (t.name == "voxelsSDF" || t.name == "voxelsSDFtmp") { if (t.name == "voxelsSDF" || t.name == "voxelsSDFtmp") {
t.format = "R16"; t.format = "R8";
t.width = res; t.width = res;
t.height = res * Main.voxelgiClipmapCount; t.height = res * Main.voxelgiClipmapCount;
t.depth = res; t.depth = res;
@ -693,16 +694,16 @@ class Inc {
#if (rp_voxels == "Voxel AO") #if (rp_voxels == "Voxel AO")
{ {
if (t.name == "voxelsOut" || t.name == "voxelsOutB") { if (t.name == "voxelsOut" || t.name == "voxelsOutB") {
t.format = "R16"; t.format = "R8";
t.width = res * (6 + 16); t.width = res * (6 + 16);
t.height = res * Main.voxelgiClipmapCount; t.height = res * Main.voxelgiClipmapCount;
t.depth = res; t.depth = res;
} }
else { else {
t.format = "R32"; t.format = "R32UI";
t.width = res * 6; t.width = res * 6;
t.height = res; t.height = res;
t.depth = res; t.depth = res * 2;
} }
} }
#else #else
@ -713,17 +714,11 @@ class Inc {
t.height = res * Main.voxelgiClipmapCount; t.height = res * Main.voxelgiClipmapCount;
t.depth = res; t.depth = res;
} }
else if (t.name == "voxelsLight") {
t.format = "R32";
t.width = res;
t.height = res;
t.depth = res * 3;
}
else { else {
t.format = "R32"; t.format = "R32UI";
t.width = res * 6; t.width = res * 6;
t.height = res; t.height = res;
t.depth = res * 12; t.depth = res * 16;
} }
} }
#end #end
@ -835,14 +830,15 @@ class Inc {
voxel_ca1 = voxel_sh1.getConstantLocation("clipmaps"); voxel_ca1 = voxel_sh1.getConstantLocation("clipmaps");
voxel_cb1 = voxel_sh1.getConstantLocation("clipmapLevel"); voxel_cb1 = voxel_sh1.getConstantLocation("clipmapLevel");
voxel_cc1 = voxel_sh1.getConstantLocation("envmapStrength");
#if (rp_voxels == "Voxel GI") #if (rp_voxels == "Voxel GI")
voxel_td1 = voxel_sh1.getTextureUnit("voxelsSampler"); voxel_td1 = voxel_sh1.getTextureUnit("voxelsSampler");
voxel_te1 = voxel_sh1.getTextureUnit("voxelsLight"); voxel_te1 = voxel_sh1.getTextureUnit("SDF");
voxel_tf1 = voxel_sh1.getTextureUnit("SDF"); voxel_cc1 = voxel_sh1.getConstantLocation("envmapStrength");
#else #else
#if lnx_voxelgi_shadows #if lnx_voxelgi_shadows
voxel_tf1 = voxel_sh1.getTextureUnit("SDF"); voxel_te1 = voxel_sh1.getTextureUnit("SDF");
#end #end
#end #end
} }
@ -873,12 +869,28 @@ class Inc {
#else #else
voxel_td3 = voxel_sh3.getTextureUnit("voxels_diffuse"); voxel_td3 = voxel_sh3.getTextureUnit("voxels_diffuse");
#end #end
voxel_ca3 = voxel_sh3.getConstantLocation("clipmaps"); voxel_te3 = voxel_sh3.getTextureUnit("gbuffer1");
voxel_tf3 = voxel_sh3.getTextureUnit("gbuffer2");
#if lnx_brdf
voxel_tg3 = voxel_sh3.getTextureUnit("senvmapBrdf");
#end
#if lnx_radiance
voxel_th3 = voxel_sh3.getTextureUnit("senvmapRadiance");
#end
voxel_ca3 = voxel_sh3.getConstantLocation("clipmaps");
voxel_cb3 = voxel_sh3.getConstantLocation("InvVP"); voxel_cb3 = voxel_sh3.getConstantLocation("InvVP");
voxel_cc3 = voxel_sh3.getConstantLocation("cameraProj"); voxel_cc3 = voxel_sh3.getConstantLocation("eye");
voxel_cd3 = voxel_sh3.getConstantLocation("eye"); voxel_cd3 = voxel_sh3.getConstantLocation("postprocess_resolution");
voxel_ce3 = voxel_sh3.getConstantLocation("eyeLook"); voxel_ce3 = voxel_sh3.getConstantLocation("envmapStrength");
voxel_cf3 = voxel_sh3.getConstantLocation("postprocess_resolution"); #if lnx_irradiance
voxel_cf3 = voxel_sh3.getConstantLocation("shirr");
#end
#if lnx_radiance
voxel_cg3 = voxel_sh3.getConstantLocation("envmapNumMipmaps");
#end
#if lnx_envcol
voxel_ch3 = voxel_sh3.getConstantLocation("backgroundCol");
#end
} }
#if (rp_voxels == "Voxel GI") #if (rp_voxels == "Voxel GI")
if (voxel_sh4 == null) if (voxel_sh4 == null)
@ -892,40 +904,8 @@ class Inc {
voxel_tf4 = voxel_sh4.getTextureUnit("sveloc"); voxel_tf4 = voxel_sh4.getTextureUnit("sveloc");
voxel_ca4 = voxel_sh4.getConstantLocation("clipmaps"); voxel_ca4 = voxel_sh4.getConstantLocation("clipmaps");
voxel_cb4 = voxel_sh4.getConstantLocation("InvVP"); voxel_cb4 = voxel_sh4.getConstantLocation("InvVP");
voxel_cc4 = voxel_sh4.getConstantLocation("cameraProj"); voxel_cc4 = voxel_sh4.getConstantLocation("eye");
voxel_cd4 = voxel_sh4.getConstantLocation("eye"); voxel_cd4 = voxel_sh4.getConstantLocation("postprocess_resolution");
voxel_ce4 = voxel_sh4.getConstantLocation("eyeLook");
voxel_cf4 = voxel_sh4.getConstantLocation("postprocess_resolution");
}
#end
#if (rp_voxels == "Voxel GI")
if (voxel_sh5 == null)
{
voxel_sh5 = path.getComputeShader("voxel_light");
voxel_ta5 = voxel_sh5.getTextureUnit("voxelsLight");
voxel_ca5 = voxel_sh5.getConstantLocation("clipmaps");
voxel_cb5 = voxel_sh5.getConstantLocation("clipmapLevel");
voxel_cc5 = voxel_sh5.getConstantLocation("lightPos");
voxel_cd5 = voxel_sh5.getConstantLocation("lightColor");
voxel_ce5 = voxel_sh5.getConstantLocation("lightType");
voxel_cf5 = voxel_sh5.getConstantLocation("lightDir");
voxel_cg5 = voxel_sh5.getConstantLocation("spotData");
#if rp_shadowmap
voxel_tb5 = voxel_sh5.getTextureUnit("shadowMap");
voxel_tc5 = voxel_sh5.getTextureUnit("shadowMapSpot");
voxel_td5 = voxel_sh5.getTextureUnit("shadowMapPoint");
voxel_ch5 = voxel_sh5.getConstantLocation("lightShadow");
voxel_ci5 = voxel_sh5.getConstantLocation("lightProj");
voxel_cj5 = voxel_sh5.getConstantLocation("LVP");
voxel_ck5 = voxel_sh5.getConstantLocation("shadowsBias");
#if lnx_shadowmap_atlas
voxel_cl5 = voxel_sh5.getConstantLocation("index");
voxel_cm5 = voxel_sh5.getConstantLocation("pointLightDataArray");
#end
#end
} }
#end #end
} }
@ -976,11 +956,11 @@ class Inc {
kha.compute.Compute.setTexture(voxel_tc1, rts.get("voxelsOut").image, kha.compute.Access.Write); kha.compute.Compute.setTexture(voxel_tc1, rts.get("voxelsOut").image, kha.compute.Access.Write);
#if (rp_voxels == "Voxel GI") #if (rp_voxels == "Voxel GI")
kha.compute.Compute.setSampledTexture(voxel_td1, rts.get("voxelsOutB").image); kha.compute.Compute.setSampledTexture(voxel_td1, rts.get("voxelsOutB").image);
kha.compute.Compute.setTexture(voxel_te1, rts.get("voxelsLight").image, kha.compute.Access.Read); kha.compute.Compute.setTexture(voxel_te1, rts.get("voxelsSDF").image, kha.compute.Access.Write);
kha.compute.Compute.setTexture(voxel_tf1, rts.get("voxelsSDF").image, kha.compute.Access.Write); kha.compute.Compute.setFloat(voxel_cc1, iron.Scene.active.world == null ? 0.0 : iron.Scene.active.world.probe.raw.strength);
#else #else
#if lnx_voxelgi_shadows #if lnx_voxelgi_shadows
kha.compute.Compute.setTexture(voxel_tf1, rts.get("voxelsSDF").image, kha.compute.Access.Write); kha.compute.Compute.setTexture(voxel_te1, rts.get("voxelsSDF").image, kha.compute.Access.Write);
#end #end
#end #end
@ -1002,6 +982,8 @@ class Inc {
kha.compute.Compute.setInt(voxel_cb1, iron.RenderPath.clipmapLevel); kha.compute.Compute.setInt(voxel_cb1, iron.RenderPath.clipmapLevel);
kha.compute.Compute.setFloat(voxel_cc1, iron.Scene.active.world == null ? 0.0 : iron.Scene.active.world.probe.raw.strength);
kha.compute.Compute.compute(Std.int(res / 8), Std.int(res / 8), Std.int(res / 8)); kha.compute.Compute.compute(Std.int(res / 8), Std.int(res / 8), Std.int(res / 8));
} }
@ -1054,6 +1036,7 @@ class Inc {
} }
} }
#end #end
#if (rp_voxels == "Voxel AO") #if (rp_voxels == "Voxel AO")
public static function resolveAO() { public static function resolveAO() {
var rts = path.renderTargets; var rts = path.renderTargets;
@ -1066,13 +1049,20 @@ class Inc {
kha.compute.Compute.setSampledTexture(voxel_ta3, rts.get("voxelsOut").image); kha.compute.Compute.setSampledTexture(voxel_ta3, rts.get("voxelsOut").image);
kha.compute.Compute.setSampledTexture(voxel_tb3, rts.get("half").image); kha.compute.Compute.setSampledTexture(voxel_tb3, rts.get("half").image);
#if lnx_deferred
kha.compute.Compute.setSampledTexture(voxel_tc3, rts.get("gbuffer0").image); kha.compute.Compute.setSampledTexture(voxel_tc3, rts.get("gbuffer0").image);
#else
kha.compute.Compute.setSampledTexture(voxel_tc3, rts.get("lbuffer1").image);
#end
kha.compute.Compute.setTexture(voxel_td3, rts.get("voxels_ao").image, kha.compute.Access.Write); kha.compute.Compute.setTexture(voxel_td3, rts.get("voxels_ao").image, kha.compute.Access.Write);
kha.compute.Compute.setSampledTexture(voxel_te3, rts.get("gbuffer1").image);
#if rp_gbuffer2
kha.compute.Compute.setSampledTexture(voxel_tf3, rts.get("gbuffer2").image);
#end
#if lnx_brdf
kha.compute.Compute.setSampledTexture(voxel_tg3, iron.Scene.active.embedded.get("brdf.png"));
#end
#if lnx_radiance
kha.compute.Compute.setSampledTexture(voxel_th3, iron.Scene.active.world.probe.radiance);
#end
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10); var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
for (i in 0...Main.voxelgiClipmapCount) { for (i in 0...Main.voxelgiClipmapCount) {
fa[i * 10] = clipmaps[i].voxelSize; fa[i * 10] = clipmaps[i].voxelSize;
@ -1099,18 +1089,7 @@ class Inc {
kha.compute.Compute.setMatrix(voxel_cb3, m.self); kha.compute.Compute.setMatrix(voxel_cb3, m.self);
var near = camera.data.raw.near_plane; kha.compute.Compute.setFloat3(voxel_cc3, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz());
var far = camera.data.raw.far_plane;
var v = new iron.math.Vec2();
v.x = far / (far - near);
v.y = (-far * near) / (far - near);
kha.compute.Compute.setFloat2(voxel_cc3, v.x, v.y);
kha.compute.Compute.setFloat3(voxel_cd3, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz());
var eyeLook = camera.lookWorld().normalize();
kha.compute.Compute.setFloat3(voxel_ce3, eyeLook.x, eyeLook.y, eyeLook.z);
var width = iron.App.w(); var width = iron.App.w();
var height = iron.App.h(); var height = iron.App.h();
@ -1125,7 +1104,32 @@ class Inc {
width = Std.int(dp * Inc.getSuperSampling()); width = Std.int(dp * Inc.getSuperSampling());
} }
} }
kha.compute.Compute.setFloat2(voxel_cf3, width, height); kha.compute.Compute.setFloat2(voxel_cd3, width, height);
kha.compute.Compute.setFloat(voxel_ce3, iron.Scene.active.world == null ? 0.0 : iron.Scene.active.world.probe.raw.strength);
#if lnx_irradiance
var irradiance = iron.Scene.active.world == null ?
iron.data.WorldData.getEmptyIrradiance() :
iron.Scene.active.world.probe.irradiance;
kha.compute.Compute.setFloats(voxel_cf3, irradiance);
#end
#if lnx_radiance
kha.compute.Compute.setFloat(voxel_cg3, iron.Scene.active.world != null ? iron.Scene.active.world.probe.raw.radiance_mipmaps + 1 - 2 : 1);
#end
#if lnx_envcol
var x: kha.FastFloat = 0.0;
var y: kha.FastFloat = 0.0;
var z: kha.FastFloat = 0.0;
if (camera.data.raw.clear_color != null) {
x = camera.data.raw.clear_color[0];
y = camera.data.raw.clear_color[1];
z = camera.data.raw.clear_color[2];
}
kha.compute.Compute.setFloat3(voxel_ch3, x, y, z);
#end
kha.compute.Compute.compute(Std.int((width + 7) / 8), Std.int((height + 7) / 8), 1); kha.compute.Compute.compute(Std.int((width + 7) / 8), Std.int((height + 7) / 8), 1);
} }
@ -1141,12 +1145,18 @@ class Inc {
kha.compute.Compute.setSampledTexture(voxel_ta3, rts.get("voxelsOut").image); kha.compute.Compute.setSampledTexture(voxel_ta3, rts.get("voxelsOut").image);
kha.compute.Compute.setSampledTexture(voxel_tb3, rts.get("half").image); kha.compute.Compute.setSampledTexture(voxel_tb3, rts.get("half").image);
#if lnx_deferred
kha.compute.Compute.setSampledTexture(voxel_tc3, rts.get("gbuffer0").image); kha.compute.Compute.setSampledTexture(voxel_tc3, rts.get("gbuffer0").image);
#else
kha.compute.Compute.setSampledTexture(voxel_tc3, rts.get("lbuffer1").image);
#end
kha.compute.Compute.setTexture(voxel_td3, rts.get("voxels_diffuse").image, kha.compute.Access.Write); kha.compute.Compute.setTexture(voxel_td3, rts.get("voxels_diffuse").image, kha.compute.Access.Write);
kha.compute.Compute.setSampledTexture(voxel_te3, rts.get("gbuffer1").image);
#if rp_gbuffer2
kha.compute.Compute.setSampledTexture(voxel_tf3, rts.get("gbuffer2").image);
#end
#if lnx_brdf
kha.compute.Compute.setSampledTexture(voxel_tg3, iron.Scene.active.embedded.get("brdf.png"));
#end
#if lnx_radiance
kha.compute.Compute.setSampledTexture(voxel_th3, iron.Scene.active.world.probe.radiance);
#end
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10); var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
for (i in 0...Main.voxelgiClipmapCount) { for (i in 0...Main.voxelgiClipmapCount) {
@ -1174,18 +1184,7 @@ class Inc {
kha.compute.Compute.setMatrix(voxel_cb3, m.self); kha.compute.Compute.setMatrix(voxel_cb3, m.self);
var near = camera.data.raw.near_plane; kha.compute.Compute.setFloat3(voxel_cc3, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz());
var far = camera.data.raw.far_plane;
var v = new iron.math.Vec2();
v.x = far / (far - near);
v.y = (-far * near) / (far - near);
kha.compute.Compute.setFloat2(voxel_cc3, v.x, v.y);
kha.compute.Compute.setFloat3(voxel_cd3, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz());
var eyeLook = camera.lookWorld().normalize();
kha.compute.Compute.setFloat3(voxel_ce3, eyeLook.x, eyeLook.y, eyeLook.z);
var width = iron.App.w(); var width = iron.App.w();
var height = iron.App.h(); var height = iron.App.h();
@ -1200,7 +1199,32 @@ class Inc {
width = Std.int(dp * Inc.getSuperSampling()); width = Std.int(dp * Inc.getSuperSampling());
} }
} }
kha.compute.Compute.setFloat2(voxel_cf3, width, height); kha.compute.Compute.setFloat2(voxel_cd3, width, height);
kha.compute.Compute.setFloat(voxel_ce3, iron.Scene.active.world == null ? 0.0 : iron.Scene.active.world.probe.raw.strength);
#if lnx_irradiance
var irradiance = iron.Scene.active.world == null ?
iron.data.WorldData.getEmptyIrradiance() :
iron.Scene.active.world.probe.irradiance;
kha.compute.Compute.setFloats(voxel_cf3, irradiance);
#end
#if lnx_radiance
kha.compute.Compute.setFloat(voxel_cg3, iron.Scene.active.world != null ? iron.Scene.active.world.probe.raw.radiance_mipmaps + 1 - 2 : 1);
#end
#if lnx_envcol
var x: kha.FastFloat = 0.0;
var y: kha.FastFloat = 0.0;
var z: kha.FastFloat = 0.0;
if (camera.data.raw.clear_color != null) {
x = camera.data.raw.clear_color[0];
y = camera.data.raw.clear_color[1];
z = camera.data.raw.clear_color[2];
}
kha.compute.Compute.setFloat3(voxel_ch3, x, y, z);
#end
kha.compute.Compute.compute(Std.int((width + 7) / 8), Std.int((height + 7) / 8), 1); kha.compute.Compute.compute(Std.int((width + 7) / 8), Std.int((height + 7) / 8), 1);
} }
@ -1216,15 +1240,12 @@ class Inc {
kha.compute.Compute.setSampledTexture(voxel_ta4, rts.get("voxelsOut").image); kha.compute.Compute.setSampledTexture(voxel_ta4, rts.get("voxelsOut").image);
kha.compute.Compute.setSampledTexture(voxel_tb4, rts.get("half").image); kha.compute.Compute.setSampledTexture(voxel_tb4, rts.get("half").image);
#if lnx_deferred
kha.compute.Compute.setSampledTexture(voxel_tc4, rts.get("gbuffer0").image); kha.compute.Compute.setSampledTexture(voxel_tc4, rts.get("gbuffer0").image);
#else
kha.compute.Compute.setSampledTexture(voxel_tc4, rts.get("lbuffer1").image);
#end
kha.compute.Compute.setSampledTexture(voxel_td4, rts.get("voxelsSDF").image); kha.compute.Compute.setSampledTexture(voxel_td4, rts.get("voxelsSDF").image);
kha.compute.Compute.setTexture(voxel_te4, rts.get("voxels_specular").image, kha.compute.Access.Write); kha.compute.Compute.setTexture(voxel_te4, rts.get("voxels_specular").image, kha.compute.Access.Write);
#if rp_gbuffer2
//kha.compute.Compute.setSampledTexture(voxel_tf4, rts.get("gbuffer2").image); kha.compute.Compute.setSampledTexture(voxel_tf4, rts.get("gbuffer2").image);
#end
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10); var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
for (i in 0...Main.voxelgiClipmapCount) { for (i in 0...Main.voxelgiClipmapCount) {
@ -1252,18 +1273,7 @@ class Inc {
kha.compute.Compute.setMatrix(voxel_cb4, m.self); kha.compute.Compute.setMatrix(voxel_cb4, m.self);
var near = camera.data.raw.near_plane; kha.compute.Compute.setFloat3(voxel_cc4, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz());
var far = camera.data.raw.far_plane;
var v = new iron.math.Vec2();
v.x = far / (far - near);
v.y = (-far * near) / (far - near);
kha.compute.Compute.setFloat2(voxel_cc4, v.x, v.y);
kha.compute.Compute.setFloat3(voxel_cd4, camera.transform.worldx(), camera.transform.worldy(), camera.transform.worldz());
var eyeLook = camera.lookWorld().normalize();
kha.compute.Compute.setFloat3(voxel_ce4, eyeLook.x, eyeLook.y, eyeLook.z);
var width = iron.App.w(); var width = iron.App.w();
var height = iron.App.h(); var height = iron.App.h();
@ -1278,146 +1288,10 @@ class Inc {
width = Std.int(dp * Inc.getSuperSampling()); width = Std.int(dp * Inc.getSuperSampling());
} }
} }
kha.compute.Compute.setFloat2(voxel_cf4, width, height); kha.compute.Compute.setFloat2(voxel_cd4, width, height);
kha.compute.Compute.compute(Std.int((width + 7) / 8), Std.int((height + 7) / 8), 1); kha.compute.Compute.compute(Std.int((width + 7) / 8), Std.int((height + 7) / 8), 1);
} }
public static function computeVoxelsLight() {
var rts = path.renderTargets;
var res = iron.RenderPath.getVoxelRes();
var camera = iron.Scene.active.camera;
var clipmaps = iron.RenderPath.clipmaps;
var clipmap = clipmaps[iron.RenderPath.clipmapLevel];
var lights = iron.Scene.active.lights;
pointIndex = spotIndex = 0;
for (i in 0...lights.length) {
var l = lights[i];
if (!l.visible) continue;
path.light = l;
kha.compute.Compute.setShader(voxel_sh5);
kha.compute.Compute.setTexture(voxel_ta5, rts.get("voxelsLight").image, kha.compute.Access.Write);
var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
for (i in 0...Main.voxelgiClipmapCount) {
fa[i * 10] = clipmaps[i].voxelSize;
fa[i * 10 + 1] = clipmaps[i].extents.x;
fa[i * 10 + 2] = clipmaps[i].extents.y;
fa[i * 10 + 3] = clipmaps[i].extents.z;
fa[i * 10 + 4] = clipmaps[i].center.x;
fa[i * 10 + 5] = clipmaps[i].center.y;
fa[i * 10 + 6] = clipmaps[i].center.z;
fa[i * 10 + 7] = clipmaps[i].offset_prev.x;
fa[i * 10 + 8] = clipmaps[i].offset_prev.y;
fa[i * 10 + 9] = clipmaps[i].offset_prev.z;
}
kha.compute.Compute.setFloats(voxel_ca5, fa);
kha.compute.Compute.setInt(voxel_cb5, iron.RenderPath.clipmapLevel);
#if rp_shadowmap
if (l.data.raw.type == "sun") {
#if lnx_shadowmap_atlas
#if lnx_shadowmap_atlas_single_map
kha.compute.Compute.setSampledTexture(voxel_tb5, rts.get("shadowMapAtlas").image);
#else
kha.compute.Compute.setSampledTexture(voxel_tb5, rts.get("shadowMapAtlasSun").image);
#end
#else
kha.compute.Compute.setSampledTexture(voxel_tb5, rts.get("shadowMap").image);
#end
kha.compute.Compute.setInt(voxel_ch5, 1); // lightShadow
}
else if (l.data.raw.type == "spot" || l.data.raw.type == "area") {
#if lnx_shadowmap_atlas
#if lnx_shadowmap_atlas_single_map
kha.compute.Compute.setSampledTexture(voxel_tc5, rts.get("shadowMapAtlas").image);
#else
kha.compute.Compute.setSampledTexture(voxel_tc5, rts.get("shadowMapAtlasSpot").image);
#end
#else
kha.compute.Compute.setSampledTexture(voxel_tc5, rts.get("shadowMapSpot[" + spotIndex + "]").image);
spotIndex++;
#end
kha.compute.Compute.setInt(voxel_ch5, 2);
}
else {
#if lnx_shadowmap_atlas
#if lnx_shadowmap_atlas_single_map
kha.compute.Compute.setSampledTexture(voxel_td5, rts.get("shadowMapAtlas").image);
#else
kha.compute.Compute.setSampledTexture(voxel_td5, rts.get("shadowMapAtlasPoint").image);
kha.compute.Compute.setInt(voxel_cl5, i);
kha.compute.Compute.setFloats(voxel_cm5, iron.object.LightObject.pointLightsData);
#end
#else
kha.compute.Compute.setSampledCubeMap(voxel_td5, rts.get("shadowMapPoint[" + pointIndex + "]").cubeMap);
pointIndex++;
#end
kha.compute.Compute.setInt(voxel_ch5, 3);
}
// lightProj
var near = l.data.raw.near_plane;
var far = l.data.raw.far_plane;
var a:kha.FastFloat = far + near;
var b:kha.FastFloat = far - near;
var f2:kha.FastFloat = 2.0;
var c:kha.FastFloat = f2 * far * near;
var vx:kha.FastFloat = a / b;
var vy:kha.FastFloat = c / b;
kha.compute.Compute.setFloat2(voxel_ci5, vx, vy);
// LVP
m.setFrom(l.VP);
m.multmat(iron.object.Uniforms.biasMat);
#if lnx_shadowmap_atlas
if (l.data.raw.type == "sun")
{
// tile matrix
m.setIdentity();
// scale [0-1] coords to [0-tilescale]
m2._00 = l.tileScale[0];
m2._11 = l.tileScale[0];
// offset coordinate start from [0, 0] to [tile-start-x, tile-start-y]
m2._30 = l.tileOffsetX[0];
m2._31 = l.tileOffsetY[0];
m.multmat(m2);
#if (!kha_opengl)
m2.setIdentity();
m2._11 = -1.0;
m2._31 = 1.0;
m.multmat(m2);
#end
}
#end
kha.compute.Compute.setMatrix(voxel_cj5, m.self);
// shadowsBias
kha.compute.Compute.setFloat(voxel_ck5, l.data.raw.shadows_bias);
#end // rp_shadowmap
// lightPos
kha.compute.Compute.setFloat3(voxel_cc5, l.transform.worldx(), l.transform.worldy(), l.transform.worldz());
// lightCol
var f = l.data.raw.strength;
kha.compute.Compute.setFloat3(voxel_cd5, l.data.raw.color[0] * f, l.data.raw.color[1] * f, l.data.raw.color[2] * f);
// lightType
kha.compute.Compute.setInt(voxel_ce5, iron.data.LightData.typeToInt(l.data.raw.type));
// lightDir
var v = l.look();
kha.compute.Compute.setFloat3(voxel_cf5, v.x, v.y, v.z);
// spotData
if (l.data.raw.type == "spot") {
var vx = l.data.raw.spot_size;
var vy = vx - l.data.raw.spot_blend;
kha.compute.Compute.setFloat2(voxel_cg5, vx, vy);
}
kha.compute.Compute.compute(Std.int(res / 8), Std.int(res / 8), Std.int(res / 8));
}
}
#end // GI #end // GI
#end // Voxels #end // Voxels
} }

View File

@ -15,6 +15,11 @@ class RenderPathDeferred {
static var bloomUpsampler: Upsampler; static var bloomUpsampler: Upsampler;
#end #end
#if (rp_ssgi == "SSGI")
static var ssgitex = "singleb";
static var ssgitexb = "singleb";
#end
public static inline function setTargetMeshes() { public static inline function setTargetMeshes() {
//Always keep the order of render targets the same as defined in compiled.inc //Always keep the order of render targets the same as defined in compiled.inc
path.setTarget("gbuffer0", [ path.setTarget("gbuffer0", [
@ -57,12 +62,11 @@ class RenderPathDeferred {
Inc.initGI("voxels"); Inc.initGI("voxels");
Inc.initGI("voxelsOut"); Inc.initGI("voxelsOut");
Inc.initGI("voxelsOutB"); Inc.initGI("voxelsOutB");
#if (lnx_voxelgi_shadows || rp_voxels == "Voxel GI") #if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
Inc.initGI("voxelsSDF"); Inc.initGI("voxelsSDF");
Inc.initGI("voxelsSDFtmp"); Inc.initGI("voxelsSDFtmp");
#end #end
#if (rp_voxels == "Voxel GI") #if (rp_voxels == "Voxel GI")
Inc.initGI("voxelsLight");
Inc.initGI("voxels_diffuse"); Inc.initGI("voxels_diffuse");
Inc.initGI("voxels_specular"); Inc.initGI("voxels_specular");
#else #else
@ -195,24 +199,94 @@ class RenderPathDeferred {
path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_x"); path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_x");
path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_y"); path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_y");
} }
#elseif (rp_ssgi == "SSGI")
{
path.loadShader("shader_datas/ssgi_pass/ssgi_pass");
path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_x");
path.loadShader("shader_datas/blur_edge_pass/blur_edge_pass_y");
}
#end #end
#if ((rp_ssgi != "Off") || rp_volumetriclight) #if (rp_ssgi != "Off")
{ {
var t = new RenderTargetRaw(); var t = new RenderTargetRaw();
t.name = "singlea"; t.name = "singlea";
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = Inc.getDisplayp(); t.displayp = Inc.getDisplayp();
#if (rp_ssgi == "SSGI")
t.format = "RGBA32";
#else
t.format = "R8";
#end
t.scale = Inc.getSuperSampling();
#if rp_ssgi_half
t.scale *= 0.5;
#end
path.createRenderTarget(t);
var t = new RenderTargetRaw();
t.name = "singleb";
t.width = 0;
t.height = 0;
t.displayp = Inc.getDisplayp();
#if (rp_ssgi == "SSGI")
t.format = "RGBA32";
#else
t.format = "R8";
#end
t.scale = Inc.getSuperSampling();
#if rp_ssgi_half
t.scale *= 0.5;
#end
path.createRenderTarget(t);
}
#end
#if rp_volumetriclight
{
var t = new RenderTargetRaw();
t.name = "volumetrica";
t.width = 0;
t.height = 0;
t.displayp = Inc.getDisplayp();
t.format = "R8";
t.scale = Inc.getSuperSampling();
#if rp_ssgi_half // Do we keep this ?
t.scale *= 0.5;
#end
path.createRenderTarget(t);
var t = new RenderTargetRaw();
t.name = "volumetricb";
t.width = 0;
t.height = 0;
t.displayp = Inc.getDisplayp();
t.format = "R8"; t.format = "R8";
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
#if rp_ssgi_half #if rp_ssgi_half
t.scale *= 0.5; t.scale *= 0.5;
#end #end
path.createRenderTarget(t); path.createRenderTarget(t);
}
#end
#if rp_volumetriclight
{
var t = new RenderTargetRaw();
t.name = "volumetrica";
t.width = 0;
t.height = 0;
t.displayp = Inc.getDisplayp();
t.format = "R8";
t.scale = Inc.getSuperSampling();
#if rp_ssgi_half // Do we keep this ?
t.scale *= 0.5;
#end
path.createRenderTarget(t);
var t = new RenderTargetRaw(); var t = new RenderTargetRaw();
t.name = "singleb"; t.name = "volumetricb";
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = Inc.getDisplayp(); t.displayp = Inc.getDisplayp();
@ -368,7 +442,7 @@ class RenderPathDeferred {
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
path.createRenderTarget(t); path.createRenderTarget(t);
// holds background depth // holds background color
var t = new RenderTargetRaw(); var t = new RenderTargetRaw();
t.name = "refr"; t.name = "refr";
t.width = 0; t.width = 0;
@ -461,7 +535,7 @@ class RenderPathDeferred {
#if (rp_ssrefr || lnx_voxelgi_refract) #if (rp_ssrefr || lnx_voxelgi_refract)
{ {
path.setTarget("gbuffer_refraction"); // Only clear gbuffer0 path.setTarget("gbuffer_refraction");
path.clearTarget(0xffffff00); path.clearTarget(0xffffff00);
} }
#end #end
@ -517,30 +591,16 @@ class RenderPathDeferred {
path.drawShader("shader_datas/downsample_depth/downsample_depth"); path.drawShader("shader_datas/downsample_depth/downsample_depth");
#end #end
#if ((rp_ssgi == "RTGI") || (rp_ssgi == "RTAO")) #if (rp_shadowmap)
{ // atlasing is exclusive for now
if (leenkx.data.Config.raw.rp_ssgi != false) { #if lnx_shadowmap_atlas
path.setTarget("singlea"); Inc.drawShadowMapAtlas();
#if rp_ssgi_half #else
path.bindTarget("half", "gbufferD"); Inc.drawShadowMap();
#else #end
path.bindTarget("_main", "gbufferD"); #end
#end
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/ssgi_pass/ssgi_pass");
path.setTarget("singleb"); #if (rp_ssgi == "SSAO")
path.bindTarget("singlea", "tex");
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_x");
path.setTarget("singlea");
path.bindTarget("singleb", "tex");
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_y");
}
}
#elseif (rp_ssgi == "SSAO")
{ {
if (leenkx.data.Config.raw.rp_ssgi != false) { if (leenkx.data.Config.raw.rp_ssgi != false) {
path.setTarget("singlea"); path.setTarget("singlea");
@ -559,15 +619,43 @@ class RenderPathDeferred {
path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_y"); path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_y");
} }
} }
#end #elseif (rp_ssgi == "SSGI")
{
if (leenkx.data.Config.raw.rp_ssgi != false) {
path.setTarget("singlea");
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbuffer0", "gbuffer0");
path.bindTarget("gbuffer1", "gbuffer1");
#if rp_gbuffer_emission
{
path.bindTarget("gbuffer_emission", "gbufferEmission");
}
#end
#if rp_gbuffer2
path.bindTarget("gbuffer2", "sveloc");
#end
#if rp_shadowmap
{
#if lnx_shadowmap_atlas
Inc.bindShadowMapAtlas();
#else
Inc.bindShadowMap();
#end
}
#end
#if (rp_shadowmap) path.drawShader("shader_datas/ssgi_pass/ssgi_pass");
// atlasing is exclusive for now path.setTarget("singleb");
#if lnx_shadowmap_atlas path.bindTarget("singlea", "tex");
Inc.drawShadowMapAtlas(); path.bindTarget("gbuffer0", "gbuffer0");
#else path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_x");
Inc.drawShadowMap();
#end path.setTarget("singlea");
path.bindTarget("singleb", "tex");
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/blur_edge_pass/blur_edge_pass_y");
}
}
#end #end
// Voxels // Voxels
@ -580,9 +668,6 @@ class RenderPathDeferred {
if (iron.RenderPath.pre_clear == true) if (iron.RenderPath.pre_clear == true)
{ {
#if (rp_voxels == "Voxel GI")
path.clearImage("voxelsLight", 0x00000000);
#end
path.clearImage("voxels", 0x00000000); path.clearImage("voxels", 0x00000000);
path.clearImage("voxelsOut", 0x00000000); path.clearImage("voxelsOut", 0x00000000);
path.clearImage("voxelsOutB", 0x00000000); path.clearImage("voxelsOutB", 0x00000000);
@ -594,26 +679,30 @@ class RenderPathDeferred {
} }
else else
{ {
#if (rp_voxels == "Voxel GI")
path.clearImage("voxelsLight", 0x00000000);
#end
path.clearImage("voxels", 0x00000000); path.clearImage("voxels", 0x00000000);
Inc.computeVoxelsOffsetPrev(); Inc.computeVoxelsOffsetPrev();
} }
path.setTarget(""); path.setTarget("");
path.bindTarget("voxels", "voxels");
#if rp_shadowmap
{
#if lnx_shadowmap_atlas
Inc.bindShadowMapAtlas();
#else
Inc.bindShadowMap();
#end
}
#end
var res = iron.RenderPath.getVoxelRes(); var res = iron.RenderPath.getVoxelRes();
path.setViewport(res, res); path.setViewport(res, res);
path.bindTarget("voxels", "voxels");
path.drawMeshes("voxel"); path.drawMeshes("voxel");
#if (rp_voxels == "Voxel GI")
Inc.computeVoxelsLight();
#end
Inc.computeVoxelsTemporal(); Inc.computeVoxelsTemporal();
#if (lnx_voxelgi_shadows || rp_voxels == "Voxel GI") #if (rp_voxels == "Voxel GI")
Inc.computeVoxelsSDF(); Inc.computeVoxelsSDF();
#end #end
@ -628,7 +717,6 @@ class RenderPathDeferred {
} }
} }
#end #end
// --- // ---
// Deferred light // Deferred light
// --- // ---
@ -760,15 +848,9 @@ class RenderPathDeferred {
} }
#end #end
#if (rp_translucency && !rp_ssrefr)
{
Inc.drawTranslucency("tex");
}
#end
#if rp_volumetriclight #if rp_volumetriclight
{ {
path.setTarget("singlea"); path.setTarget("volumetrica");
path.bindTarget("_main", "gbufferD"); path.bindTarget("_main", "gbufferD");
#if lnx_shadowmap_atlas #if lnx_shadowmap_atlas
Inc.bindShadowMapAtlas(); Inc.bindShadowMapAtlas();
@ -777,85 +859,16 @@ class RenderPathDeferred {
#end #end
path.drawShader("shader_datas/volumetric_light/volumetric_light"); path.drawShader("shader_datas/volumetric_light/volumetric_light");
path.setTarget("singleb"); path.setTarget("volumetricb");
path.bindTarget("singlea", "tex"); path.bindTarget("volumetrica", "tex");
path.drawShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x"); path.drawShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x");
path.setTarget("tex"); path.setTarget("tex");
path.bindTarget("singleb", "tex"); path.bindTarget("volumetricb", "tex");
path.drawShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y"); path.drawShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y");
} }
#end #end
#if rp_bloom
{
inline Inc.drawBloom("tex", bloomDownsampler, bloomUpsampler);
}
#end
#if rp_sss
{
#if (!kha_opengl)
path.setDepthFrom("tex", "gbuffer1"); // Unbind depth so we can read it
#end
path.setTarget("buf");
path.bindTarget("tex", "tex");
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/sss_pass/sss_pass_x");
path.setTarget("tex");
path.bindTarget("buf", "tex");
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/sss_pass/sss_pass_y");
#if (!kha_opengl)
path.setDepthFrom("tex", "gbuffer0");
#end
}
#end
#if rp_ssrefr
{
if (leenkx.data.Config.raw.rp_ssrefr != false)
{
//save depth
path.setTarget("gbufferD1");
path.bindTarget("_main", "tex");
path.drawShader("shader_datas/copy_pass/copy_pass");
//save background color
path.setTarget("refr");
path.bindTarget("tex", "tex");
path.drawShader("shader_datas/copy_pass/copy_pass");
path.setTarget("gbuffer0", ["tex", "gbuffer_refraction"]);
#if (rp_voxels != "Off")
{
path.bindTarget("voxelsOut", "voxels");
path.bindTarget("voxelsSDF", "voxelsSDF");
path.bindTarget("gbuffer2", "sveloc");
}
#end
path.drawMeshes("refraction");
path.setTarget("tex");
path.bindTarget("tex", "tex");
path.bindTarget("refr", "tex1");
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbufferD1", "gbufferD1");
path.bindTarget("gbuffer0", "gbuffer0");
path.bindTarget("gbuffer_refraction", "gbuffer_refraction");
path.drawShader("shader_datas/ssrefr_pass/ssrefr_pass");
}
}
#end
#if rp_ssr #if rp_ssr
{ {
if (leenkx.data.Config.raw.rp_ssr != false) { if (leenkx.data.Config.raw.rp_ssr != false) {
@ -900,6 +913,88 @@ class RenderPathDeferred {
} }
#end #end
#if rp_sss
{
#if (!kha_opengl)
path.setDepthFrom("tex", "gbuffer1"); // Unbind depth so we can read it
#end
path.setTarget("buf");
path.bindTarget("tex", "tex");
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/sss_pass/sss_pass_x");
path.setTarget("tex");
path.bindTarget("buf", "tex");
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/sss_pass/sss_pass_y");
#if (!kha_opengl)
path.setDepthFrom("tex", "gbuffer0");
#end
}
#end
#if (rp_translucency && !rp_ssrefr)
{
Inc.drawTranslucency("tex");
}
#end
#if rp_ssrefr
{
if (leenkx.data.Config.raw.rp_ssrefr != false)
{
//save depth
path.setTarget("gbufferD1");
path.bindTarget("_main", "tex");
path.drawShader("shader_datas/copy_pass/copy_pass");
//save background color
path.setTarget("refr");
path.bindTarget("tex", "tex");
path.drawShader("shader_datas/copy_pass/copy_pass");
path.setTarget("gbuffer0", ["tex", "gbuffer_refraction"]);
#if rp_shadowmap
{
#if lnx_shadowmap_atlas
Inc.bindShadowMapAtlas();
#else
Inc.bindShadowMap();
#end
}
#end
#if (rp_voxels != "Off")
path.bindTarget("voxelsOut", "voxels");
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
path.bindTarget("voxelsSDF", "voxelsSDF");
#end
#end
#if rp_ssrs
path.bindTarget("_main", "gbufferD");
#end
path.drawMeshes("refraction");
path.setTarget("tex");
path.bindTarget("tex", "tex");
path.bindTarget("refr", "tex1");
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbufferD1", "gbufferD1");
path.bindTarget("gbuffer0", "gbuffer0");
path.bindTarget("gbuffer_refraction", "gbuffer_refraction");
path.drawShader("shader_datas/ssrefr_pass/ssrefr_pass");
}
}
#end
#if ((rp_motionblur == "Camera") || (rp_motionblur == "Object")) #if ((rp_motionblur == "Camera") || (rp_motionblur == "Object"))
{ {
if (leenkx.data.Config.raw.rp_motionblur != false) { if (leenkx.data.Config.raw.rp_motionblur != false) {
@ -964,6 +1059,12 @@ class RenderPathDeferred {
} }
#end #end
#if rp_bloom
{
inline Inc.drawBloom("tex", bloomDownsampler, bloomUpsampler);
}
#end
#if (rp_supersampling == 4) #if (rp_supersampling == 4)
var framebuffer = "buf"; var framebuffer = "buf";
#else #else

View File

@ -142,16 +142,17 @@ class RenderPathForward {
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = Inc.getDisplayp(); t.displayp = Inc.getDisplayp();
t.format = "R32"; t.format = "DEPTH24";
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
path.createRenderTarget(t); path.createRenderTarget(t);
//holds colors before refractive meshes are drawn
var t = new RenderTargetRaw(); var t = new RenderTargetRaw();
t.name = "refr"; t.name = "refr";
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = Inc.getDisplayp(); t.displayp = Inc.getDisplayp();
t.format = "RGBA64"; t.format = Inc.getHdrFormat();
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
path.createRenderTarget(t); path.createRenderTarget(t);
} }
@ -200,17 +201,10 @@ class RenderPathForward {
Inc.initGI("voxels"); Inc.initGI("voxels");
Inc.initGI("voxelsOut"); Inc.initGI("voxelsOut");
Inc.initGI("voxelsOutB"); Inc.initGI("voxelsOutB");
#if (lnx_voxelgi_shadows || (rp_voxels == "Voxel GI")) #if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
Inc.initGI("voxelsSDF"); Inc.initGI("voxelsSDF");
Inc.initGI("voxelsSDFtmp"); Inc.initGI("voxelsSDFtmp");
#end #end
#if (rp_voxels == "Voxel GI")
Inc.initGI("voxelsLight");
Inc.initGI("voxels_diffuse");
Inc.initGI("voxels_specular");
#else
Inc.initGI("voxels_ao");
#end
iron.RenderPath.clipmaps = new Array<Clipmap>(); iron.RenderPath.clipmaps = new Array<Clipmap>();
for (i in 0...Main.voxelgiClipmapCount) { for (i in 0...Main.voxelgiClipmapCount) {
var clipmap = new iron.object.Clipmap(); var clipmap = new iron.object.Clipmap();
@ -257,18 +251,25 @@ class RenderPathForward {
#end #end
#end #end
#if rp_volumetriclight #if (rp_volumetriclight || rp_ssgi != "Off")
{ {
#if (rp_volumetriclight)
path.loadShader("shader_datas/volumetric_light/volumetric_light"); path.loadShader("shader_datas/volumetric_light/volumetric_light");
path.loadShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x"); path.loadShader("shader_datas/blur_bilat_pass/blur_bilat_pass_x");
path.loadShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y"); path.loadShader("shader_datas/blur_bilat_blend_pass/blur_bilat_blend_pass_y");
#end
var t = new RenderTargetRaw(); var t = new RenderTargetRaw();
t.name = "singlea"; t.name = "singlea";
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = Inc.getDisplayp(); t.displayp = Inc.getDisplayp();
#if (rp_ssgi == "SSGI")
t.format = "RGBA32";
#else
t.format = "R8"; t.format = "R8";
#end
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
path.createRenderTarget(t); path.createRenderTarget(t);
@ -277,7 +278,11 @@ class RenderPathForward {
t.width = 0; t.width = 0;
t.height = 0; t.height = 0;
t.displayp = Inc.getDisplayp(); t.displayp = Inc.getDisplayp();
#if (rp_ssgi == "SSGI")
t.format = "RGBA32";
#else
t.format = "R8"; t.format = "R8";
#end
t.scale = Inc.getSuperSampling(); t.scale = Inc.getSuperSampling();
path.createRenderTarget(t); path.createRenderTarget(t);
} }
@ -374,9 +379,6 @@ class RenderPathForward {
if (iron.RenderPath.pre_clear == true) if (iron.RenderPath.pre_clear == true)
{ {
#if (rp_voxels == "Voxel GI")
path.clearImage("voxelsLight", 0x00000000);
#end
path.clearImage("voxels", 0x00000000); path.clearImage("voxels", 0x00000000);
path.clearImage("voxelsOut", 0x00000000); path.clearImage("voxelsOut", 0x00000000);
path.clearImage("voxelsOutB", 0x00000000); path.clearImage("voxelsOutB", 0x00000000);
@ -388,9 +390,6 @@ class RenderPathForward {
} }
else else
{ {
#if (rp_voxels == "Voxel GI")
path.clearImage("voxelsLight", 0x00000000);
#end
path.clearImage("voxels", 0x00000000); path.clearImage("voxels", 0x00000000);
Inc.computeVoxelsOffsetPrev(); Inc.computeVoxelsOffsetPrev();
} }
@ -400,27 +399,12 @@ class RenderPathForward {
path.setViewport(res, res); path.setViewport(res, res);
path.bindTarget("voxels", "voxels"); path.bindTarget("voxels", "voxels");
path.drawMeshes("voxel");
#if (rp_voxels == "Voxel GI")
Inc.computeVoxelsLight();
#end
Inc.computeVoxelsTemporal(); Inc.computeVoxelsTemporal();
#if (lnx_voxelgi_shadows || (rp_voxels == "Voxel GI")) #if (lnx_voxelgi_shadows || (rp_voxels == "Voxel GI"))
Inc.computeVoxelsSDF(); Inc.computeVoxelsSDF();
#end #end
if (iron.RenderPath.res_pre_clear == true)
{
iron.RenderPath.res_pre_clear = false;
#if (rp_voxels == "Voxel GI")
path.clearImage("voxels_diffuse", 0x00000000);
path.clearImage("voxels_specular", 0x00000000);
#else
path.clearImage("voxels_ao", 0x00000000);
#end
}
} }
#end #end
@ -439,7 +423,7 @@ class RenderPathForward {
#if (rp_ssrefr || lnx_voxelgi_refract) #if (rp_ssrefr || lnx_voxelgi_refract)
{ {
path.setTarget("gbuffer_refraction"); // Only clear gbuffer0 path.setTarget("gbuffer_refraction"); // Only clear gbuffer0
path.clearTarget(0xff000000); path.clearTarget(0xffffff00);
} }
#end #end
@ -449,13 +433,6 @@ class RenderPathForward {
} }
#end #end
#if rp_ssrefr
{
path.setTarget("gbuffer_refraction");
path.clearTarget(0xffffff00);
}
#end
RenderPathCreator.setTargetMeshes(); RenderPathCreator.setTargetMeshes();
#if rp_shadowmap #if rp_shadowmap
@ -472,19 +449,12 @@ class RenderPathForward {
#if (rp_voxels != "Off") #if (rp_voxels != "Off")
if (leenkx.data.Config.raw.rp_gi != false) if (leenkx.data.Config.raw.rp_gi != false)
{ {
#if (rp_voxels == "Voxel AO") #if (rp_voxels != "Off")
Inc.resolveAO();
path.bindTarget("voxels_ao", "voxels_ao");
#else
Inc.resolveDiffuse();
Inc.resolveSpecular();
path.bindTarget("voxels_diffuse", "voxels_diffuse");
path.bindTarget("voxels_specular", "voxels_specular");
#end
#if lnx_voxelgi_shadows
path.bindTarget("voxelsOut", "voxels"); path.bindTarget("voxelsOut", "voxels");
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
path.bindTarget("voxelsSDF", "voxelsSDF"); path.bindTarget("voxelsSDF", "voxelsSDF");
#end #end
#end
} }
#end #end
@ -522,14 +492,31 @@ class RenderPathForward {
path.setTarget("lbuffer0", ["lbuffer1", "gbuffer_refraction"]); path.setTarget("lbuffer0", ["lbuffer1", "gbuffer_refraction"]);
#if rp_shadowmap
{
#if lnx_shadowmap_atlas
Inc.bindShadowMapAtlas();
#else
Inc.bindShadowMap();
#end
}
#end
#if (rp_voxels != "Off") #if (rp_voxels != "Off")
path.bindTarget("voxelsOut", "voxels"); path.bindTarget("voxelsOut", "voxels");
#if (rp_voxels == "Voxel GI" || lnx_voxelgi_shadows)
path.bindTarget("voxelsSDF", "voxelsSDF"); path.bindTarget("voxelsSDF", "voxelsSDF");
#end #end
#end
#if rp_ssrs
path.bindTarget("_main", "gbufferD");
#end
path.drawMeshes("refraction"); path.drawMeshes("refraction");
path.setTarget("lbuffer0"); path.setTarget("lbuffer0");
path.bindTarget("lbuffer0", "tex"); path.bindTarget("lbuffer0", "tex");
path.bindTarget("refr", "tex1"); path.bindTarget("refr", "tex1");
path.bindTarget("_main", "gbufferD"); path.bindTarget("_main", "gbufferD");
@ -577,6 +564,50 @@ class RenderPathForward {
} }
#end #end
#if rp_ssrefr
{
if (leenkx.data.Config.raw.rp_ssrefr != false)
{
path.setTarget("gbufferD1");
path.bindTarget("_main", "tex");
path.drawShader("shader_datas/copy_pass/copy_pass");
path.setTarget("refr");
path.bindTarget("lbuffer0", "tex");
path.drawShader("shader_datas/copy_pass/copy_pass");
path.setTarget("lbuffer0", ["lbuffer1", "gbuffer_refraction"]);
#if rp_shadowmap
{
#if lnx_shadowmap_atlas
Inc.bindShadowMapAtlas();
#else
Inc.bindShadowMap();
#end
}
#end
#if (rp_voxels != "Off")
path.bindTarget("voxelsOut", "voxels");
path.bindTarget("voxelsSDF", "voxelsSDF");
#end
path.drawMeshes("refraction");
path.setTarget("lbuffer0");
path.bindTarget("lbuffer0", "tex");
path.bindTarget("refr", "tex1");
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbufferD1", "gbufferD1");
path.bindTarget("lbuffer1", "gbuffer0");
path.bindTarget("gbuffer_refraction", "gbuffer_refraction");
path.drawShader("shader_datas/ssrefr_pass/ssrefr_pass");
}
}
#end
#if rp_bloom #if rp_bloom
{ {
inline Inc.drawBloom("lbuffer0", bloomDownsampler, bloomUpsampler); inline Inc.drawBloom("lbuffer0", bloomDownsampler, bloomUpsampler);

View File

@ -41,7 +41,11 @@ class Starter {
try { try {
#end #end
kha.System.start({title: Main.projectName, width: c.window_w, height: c.window_h, window: {mode: windowMode, windowFeatures: windowFeatures}, framebuffer: {samplesPerPixel: c.window_msaa, verticalSync: c.window_vsync}}, function(window: kha.Window) { kha.System.start({title: Main.projectName, width: c.window_w, height: c.window_h, window: {
#if lnx_render_viewport
visible: false,
#end
mode: windowMode, windowFeatures: windowFeatures}, framebuffer: {samplesPerPixel: c.window_msaa, verticalSync: c.window_vsync}}, function(window: kha.Window) {
iron.App.init(function() { iron.App.init(function() {
#if lnx_loadscreen #if lnx_loadscreen

View File

@ -58,6 +58,9 @@ def add_world_defs():
if rpdat.rp_shadowmap_cascades != '1': if rpdat.rp_shadowmap_cascades != '1':
wrd.world_defs += '_CSM' wrd.world_defs += '_CSM'
assets.add_khafile_def('lnx_csm') assets.add_khafile_def('lnx_csm')
if rpdat.rp_shadowmap_transparent:
wrd.world_defs += '_ShadowMapTransparent'
assets.add_khafile_def('rp_shadowmap_transparent')
if rpdat.rp_shadowmap_atlas: if rpdat.rp_shadowmap_atlas:
assets.add_khafile_def('lnx_shadowmap_atlas') assets.add_khafile_def('lnx_shadowmap_atlas')
wrd.world_defs += '_ShadowMapAtlas' wrd.world_defs += '_ShadowMapAtlas'
@ -118,17 +121,15 @@ def add_world_defs():
if rpdat.lnx_voxelgi_shadows and (point_lights > 0 or '_Sun' in wrd.world_defs): if rpdat.lnx_voxelgi_shadows and (point_lights > 0 or '_Sun' in wrd.world_defs):
wrd.world_defs += '_VoxelShadow' wrd.world_defs += '_VoxelShadow'
assets.add_khafile_def('lnx_voxelgi_shadows') assets.add_khafile_def('lnx_voxelgi_shadows')
#assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_shadows/voxel_resolve_shadows.comp.glsl')
if voxelgi: if voxelgi:
assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_light/voxel_light.comp.glsl')
assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_diffuse/voxel_resolve_diffuse.comp.glsl') assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_diffuse/voxel_resolve_diffuse.comp.glsl')
assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_specular/voxel_resolve_specular.comp.glsl') assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_specular/voxel_resolve_specular.comp.glsl')
assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_light/voxel_light.comp.glsl')
wrd.world_defs += '_VoxelGI' wrd.world_defs += '_VoxelGI'
if rpdat.lnx_voxelgi_refract: if rpdat.lnx_voxelgi_refract:
wrd.world_defs += '_VoxelRefract' wrd.world_defs += '_VoxelRefract'
assets.add_khafile_def('lnx_voxelgi_refract') assets.add_khafile_def('lnx_voxelgi_refract')
#assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_refraction/voxel_resolve_refraction.comp.glsl')
elif voxelao: elif voxelao:
assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_ao/voxel_resolve_ao.comp.glsl') assets.add_shader_external(lnx.utils.get_sdk_path() + '/leenkx/Shaders/voxel_resolve_ao/voxel_resolve_ao.comp.glsl')
@ -306,10 +307,14 @@ def build():
assets.add_khafile_def('rp_ssgi={0}'.format(rpdat.rp_ssgi)) assets.add_khafile_def('rp_ssgi={0}'.format(rpdat.rp_ssgi))
if rpdat.rp_ssgi != 'Off': if rpdat.rp_ssgi != 'Off':
wrd.world_defs += '_SSAO'
if rpdat.rp_ssgi == 'SSAO': if rpdat.rp_ssgi == 'SSAO':
wrd.world_defs += '_SSAO'
assets.add_shader_pass('ssao_pass') assets.add_shader_pass('ssao_pass')
assets.add_shader_pass('blur_edge_pass') assets.add_shader_pass('blur_edge_pass')
elif rpdat.rp_ssgi == 'SSGI':
wrd.world_defs += '_SSGI'
assets.add_shader_pass('ssgi_pass')
assets.add_shader_pass('blur_edge_pass')
else: else:
assets.add_shader_pass('ssgi_pass') assets.add_shader_pass('ssgi_pass')
assets.add_shader_pass('blur_edge_pass') assets.add_shader_pass('blur_edge_pass')
@ -456,7 +461,8 @@ def build():
if ignoreIrr: if ignoreIrr:
wrd.world_defs += '_IgnoreIrr' wrd.world_defs += '_IgnoreIrr'
gbuffer2 = '_Veloc' in wrd.world_defs or '_IgnoreIrr' in wrd.world_defs gbuffer2 = '_Veloc' in wrd.world_defs or '_IgnoreIrr' in wrd.world_defs or '_VoxelGI' in wrd.world_defs or '_VoxelShadow' in wrd.world_defs or '_SSGI' in wrd.world_defs
if gbuffer2: if gbuffer2:
assets.add_khafile_def('rp_gbuffer2') assets.add_khafile_def('rp_gbuffer2')
wrd.world_defs += '_gbuffer2' wrd.world_defs += '_gbuffer2'

View File

@ -199,6 +199,7 @@ def build_node_tree(world: bpy.types.World, frag: Shader, vert: Shader, con: Sha
world.lnx_envtex_color = [col[0], col[1], col[2], 1.0] world.lnx_envtex_color = [col[0], col[1], col[2], 1.0]
world.lnx_envtex_strength = 1.0 world.lnx_envtex_strength = 1.0
world.world_defs += '_EnvCol' world.world_defs += '_EnvCol'
assets.add_khafile_def("lnx_envcol")
# Clouds enabled # Clouds enabled
if rpdat.lnx_clouds and world.lnx_use_clouds: if rpdat.lnx_clouds and world.lnx_use_clouds:
@ -280,6 +281,7 @@ def parse_surface(world: bpy.types.World, node_surface: bpy.types.Node, frag: Sh
# Append irradiance define # Append irradiance define
if rpdat.lnx_irradiance and not solid_mat: if rpdat.lnx_irradiance and not solid_mat:
wrd.world_defs += '_Irr' wrd.world_defs += '_Irr'
assets.add_khafile_def("lnx_irradiance")
# Extract environment strength # Extract environment strength
# Todo: follow/parse strength input # Todo: follow/parse strength input
@ -293,6 +295,7 @@ def parse_surface(world: bpy.types.World, node_surface: bpy.types.Node, frag: Sh
solid_mat = rpdat.lnx_material_model == 'Solid' solid_mat = rpdat.lnx_material_model == 'Solid'
if rpdat.lnx_irradiance and not solid_mat: if rpdat.lnx_irradiance and not solid_mat:
world.world_defs += '_Irr' world.world_defs += '_Irr'
assets.add_khafile_def("lnx_irradiance")
world.lnx_envtex_color = node_surface.inputs[0].default_value world.lnx_envtex_color = node_surface.inputs[0].default_value
world.lnx_envtex_strength = 1.0 world.lnx_envtex_strength = 1.0

View File

@ -342,9 +342,6 @@ def parse_sky_hosekwilkie(node: bpy.types.ShaderNodeTexSky, state: ParserState)
world = state.world world = state.world
curshader = state.curshader curshader = state.curshader
# Match to cycles
world.lnx_envtex_strength *= 0.1
assets.add_khafile_def('lnx_hosek') assets.add_khafile_def('lnx_hosek')
curshader.add_uniform('vec3 A', link="_hosekA") curshader.add_uniform('vec3 A', link="_hosekA")
curshader.add_uniform('vec3 B', link="_hosekB") curshader.add_uniform('vec3 B', link="_hosekB")

View File

@ -19,6 +19,7 @@ def write(vert: shader.Shader, frag: shader.Shader):
parse_opacity = blend or mat_utils.is_transluc(mat_state.material) parse_opacity = blend or mat_utils.is_transluc(mat_state.material)
is_mobile = rpdat.lnx_material_model == 'Mobile' is_mobile = rpdat.lnx_material_model == 'Mobile'
is_shadows = '_ShadowMap' in wrd.world_defs is_shadows = '_ShadowMap' in wrd.world_defs
is_transparent_shadows = '_ShadowMapTransparent' in wrd.world_defs
is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs
is_single_atlas = '_SingleAtlas' in wrd.world_defs is_single_atlas = '_SingleAtlas' in wrd.world_defs
@ -33,14 +34,17 @@ def write(vert: shader.Shader, frag: shader.Shader):
if is_shadows_atlas: if is_shadows_atlas:
if not is_single_atlas: if not is_single_atlas:
frag.add_uniform('sampler2DShadow shadowMapAtlasPoint', included=True) frag.add_uniform('sampler2DShadow shadowMapAtlasPoint', included=True)
frag.add_uniform('sampler2D shadowMapAtlasPointTransparent', included=True) if is_transparent_shadows:
frag.add_uniform('sampler2D shadowMapAtlasPointTransparent', included=True)
else: else:
frag.add_uniform('sampler2DShadow shadowMapAtlas', top=True) frag.add_uniform('sampler2DShadow shadowMapAtlas', top=True)
frag.add_uniform('sampler2D shadowMapAtlasTransparent', top=True) if is_transparent_shadows:
frag.add_uniform('sampler2D shadowMapAtlasTransparent', top=True)
frag.add_uniform('vec4 pointLightDataArray[maxLightsCluster]', link='_pointLightsAtlasArray', included=True) frag.add_uniform('vec4 pointLightDataArray[maxLightsCluster]', link='_pointLightsAtlasArray', included=True)
else: else:
frag.add_uniform('samplerCubeShadow shadowMapPoint[4]', included=True) frag.add_uniform('samplerCubeShadow shadowMapPoint[4]', included=True)
frag.add_uniform('samplerCube shadowMapPointTransparent[4]', included=True) if is_transparent_shadows:
frag.add_uniform('samplerCube shadowMapPointTransparent[4]', included=True)
if not '_VoxelAOvar' in wrd.world_defs and not '_VoxelGI' in wrd.world_defs or ((parse_opacity or '_VoxelShadow' in wrd.world_defs) and ('_VoxelAOvar' in wrd.world_defs or '_VoxelGI' in wrd.world_defs)): if not '_VoxelAOvar' in wrd.world_defs and not '_VoxelGI' in wrd.world_defs or ((parse_opacity or '_VoxelShadow' in wrd.world_defs) and ('_VoxelAOvar' in wrd.world_defs or '_VoxelGI' in wrd.world_defs)):
vert.add_out('vec4 wvpposition') vert.add_out('vec4 wvpposition')
@ -62,13 +66,16 @@ def write(vert: shader.Shader, frag: shader.Shader):
if is_shadows_atlas: if is_shadows_atlas:
if not is_single_atlas: if not is_single_atlas:
frag.add_uniform('sampler2DShadow shadowMapAtlasSpot', included=True) frag.add_uniform('sampler2DShadow shadowMapAtlasSpot', included=True)
frag.add_uniform('sampler2D shadowMapAtlasSpotTransparent', included=True) if is_transparent_shadows:
frag.add_uniform('sampler2D shadowMapAtlasSpotTransparent', included=True)
else: else:
frag.add_uniform('sampler2DShadow shadowMapAtlas', top=True) frag.add_uniform('sampler2DShadow shadowMapAtlas', top=True)
frag.add_uniform('sampler2D shadowMapAtlasTransparent', top=True) if is_transparent_shadows:
frag.add_uniform('sampler2D shadowMapAtlasTransparent', top=True)
else: else:
frag.add_uniform('sampler2DShadow shadowMapSpot[4]', included=True) frag.add_uniform('sampler2DShadow shadowMapSpot[4]', included=True)
frag.add_uniform('sampler2D shadowMapSpotTransparent[4]', included=True) if is_transparent_shadows:
frag.add_uniform('sampler2D shadowMapSpotTransparent[4]', included=True)
frag.add_uniform('mat4 LWVPSpotArray[maxLightsCluster]', link='_biasLightWorldViewProjectionMatrixSpotArray', included=True) frag.add_uniform('mat4 LWVPSpotArray[maxLightsCluster]', link='_biasLightWorldViewProjectionMatrixSpotArray', included=True)
frag.write('for (int i = 0; i < min(numLights, maxLightsCluster); i++) {') frag.write('for (int i = 0; i < min(numLights, maxLightsCluster); i++) {')
@ -84,12 +91,10 @@ def write(vert: shader.Shader, frag: shader.Shader):
frag.write(' roughness,') frag.write(' roughness,')
frag.write(' specular,') frag.write(' specular,')
frag.write(' f0') frag.write(' f0')
if is_shadows: if is_shadows:
if parse_opacity: frag.write('\t, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0') # bias
frag.write('\t, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0, opacity != 1.0') # bias if is_transparent_shadows:
else: frag.write('\t, opacity != 1.0')
frag.write('\t, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0, false') # bias
if '_Spot' in wrd.world_defs: if '_Spot' in wrd.world_defs:
frag.write('\t, lightsArray[li * 3 + 2].y != 0.0') frag.write('\t, lightsArray[li * 3 + 2].y != 0.0')
frag.write('\t, lightsArray[li * 3 + 2].y') # spot size (cutoff) frag.write('\t, lightsArray[li * 3 + 2].y') # spot size (cutoff)
@ -98,13 +103,13 @@ def write(vert: shader.Shader, frag: shader.Shader):
frag.write('\t, vec2(lightsArray[li * 3].w, lightsArray[li * 3 + 1].w)') # scale frag.write('\t, vec2(lightsArray[li * 3].w, lightsArray[li * 3 + 1].w)') # scale
frag.write('\t, lightsArraySpot[li * 2 + 1].xyz') # right frag.write('\t, lightsArraySpot[li * 2 + 1].xyz') # right
if '_VoxelShadow' in wrd.world_defs: if '_VoxelShadow' in wrd.world_defs:
frag.write(', voxels, voxelsSDF, clipmaps') frag.write(', voxels, voxelsSDF, clipmaps, velocity')
if '_MicroShadowing' in wrd.world_defs and not is_mobile: if '_MicroShadowing' in wrd.world_defs and not is_mobile:
frag.write('\t, occlusion') frag.write('\t, occlusion')
if '_SSRS' in wrd.world_defs: if '_SSRS' in wrd.world_defs:
frag.add_uniform('sampler2D gbufferD')
frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix') frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix')
frag.add_uniform('vec3 eye', '_cameraPosition') frag.add_uniform('vec3 eye', '_cameraPosition')
frag.add_uniform('sampler2D gbufferD', link='_gbufferD', top=True)
frag.write(', gbufferD, invVP, eye') frag.write(', gbufferD, invVP, eye')
frag.write(');') frag.write(');')

View File

@ -1,155 +1,161 @@
import bpy import bpy
import lnx import lnx
import lnx.material.mat_state as mat_state import lnx.material.mat_state as mat_state
import lnx.material.make_tess as make_tess import lnx.material.make_tess as make_tess
from lnx.material.shader import ShaderContext from lnx.material.shader import ShaderContext
if lnx.is_reload(__name__): if lnx.is_reload(__name__):
mat_state = lnx.reload_module(mat_state) mat_state = lnx.reload_module(mat_state)
make_tess = lnx.reload_module(make_tess) make_tess = lnx.reload_module(make_tess)
lnx.material.shader = lnx.reload_module(lnx.material.shader) lnx.material.shader = lnx.reload_module(lnx.material.shader)
from lnx.material.shader import ShaderContext from lnx.material.shader import ShaderContext
else: else:
lnx.enable_reload(__name__) lnx.enable_reload(__name__)
def make(con_mesh: ShaderContext): def make(con_mesh: ShaderContext):
vert = con_mesh.vert vert = con_mesh.vert
frag = con_mesh.frag frag = con_mesh.frag
geom = con_mesh.geom geom = con_mesh.geom
tesc = con_mesh.tesc tesc = con_mesh.tesc
tese = con_mesh.tese tese = con_mesh.tese
# Additional values referenced in cycles # Additional values referenced in cycles
# TODO: enable from cycles.py # TODO: enable from cycles.py
if frag.contains('dotNV') and not frag.contains('float dotNV'): if frag.contains('dotNV') and not frag.contains('float dotNV'):
frag.write_init('float dotNV = max(dot(n, vVec), 0.0);') frag.write_init('float dotNV = max(dot(n, vVec), 0.0);')
# n is not always defined yet (in some shadowmap shaders e.g.) # n is not always defined yet (in some shadowmap shaders e.g.)
if not frag.contains('vec3 n'): if not frag.contains('vec3 n'):
vert.add_out('vec3 wnormal') vert.add_out('vec3 wnormal')
billboard = mat_state.material.lnx_billboard billboard = mat_state.material.lnx_billboard
if billboard == 'spherical': if billboard == 'spherical':
vert.add_uniform('mat3 N', '_normalMatrixSphere') vert.add_uniform('mat3 N', '_normalMatrixSphere')
elif billboard == 'cylindrical': elif billboard == 'cylindrical':
vert.add_uniform('mat3 N', '_normalMatrixCylinder') vert.add_uniform('mat3 N', '_normalMatrixCylinder')
else: else:
vert.add_uniform('mat3 N', '_normalMatrix') vert.add_uniform('mat3 N', '_normalMatrix')
vert.write_attrib('wnormal = normalize(N * vec3(nor.xy, pos.w));') vert.write_attrib('wnormal = normalize(N * vec3(nor.xy, pos.w));')
frag.write_attrib('vec3 n = normalize(wnormal);') frag.write_attrib('vec3 n = normalize(wnormal);')
# If not yet added, add nor vertex data # If not yet added, add nor vertex data
vertex_elems = con_mesh.data['vertex_elements'] vertex_elems = con_mesh.data['vertex_elements']
has_normals = False has_normals = False
for elem in vertex_elems: for elem in vertex_elems:
if elem['name'] == 'nor': if elem['name'] == 'nor':
has_normals = True has_normals = True
break break
if not has_normals: if not has_normals:
vertex_elems.append({'name': 'nor', 'data': 'short2norm'}) vertex_elems.append({'name': 'nor', 'data': 'short2norm'})
write_wpos = False write_wpos = False
if frag.contains('vVec') and not frag.contains('vec3 vVec'): export_wpos = False
if tese is not None: if frag.contains('wposition') and not frag.contains('vec3 wposition'):
tese.add_out('vec3 eyeDir') export_wpos = True
tese.add_uniform('vec3 eye', '_cameraPosition') if tese is not None:
tese.write('eyeDir = eye - wposition;') export_wpos = True
if vert.contains('wposition'):
else: write_wpos = True
if not vert.contains('wposition'):
write_wpos = True
vert.add_out('vec3 eyeDir')
vert.add_uniform('vec3 eye', '_cameraPosition')
vert.write('eyeDir = eye - wposition;') if frag.contains('vVec') and not frag.contains('vec3 vVec'):
frag.write_attrib('vec3 vVec = normalize(eyeDir);') if tese is not None:
tese.add_out('vec3 eyeDir')
export_wpos = False tese.add_uniform('vec3 eye', '_cameraPosition')
if frag.contains('wposition') and not frag.contains('vec3 wposition'): tese.write('eyeDir = eye - wposition;')
export_wpos = True
if tese is not None: else:
export_wpos = True if not vert.contains('wposition'):
if vert.contains('wposition'): write_wpos = True
write_wpos = True vert.add_out('vec3 eyeDir')
vert.add_uniform('vec3 eye', '_cameraPosition')
if export_wpos: vert.write('eyeDir = eye - wposition;')
vert.add_uniform('mat4 W', '_worldMatrix') frag.write_attrib('vec3 vVec = normalize(eyeDir);')
vert.add_out('vec3 wposition')
vert.write('wposition = vec4(W * spos).xyz;') if export_wpos:
elif write_wpos: vert.add_uniform('mat4 W', '_worldMatrix')
vert.add_uniform('mat4 W', '_worldMatrix') vert.add_out('vec3 wposition')
vert.write_attrib('vec3 wposition = vec4(W * spos).xyz;') vert.write_attrib('wposition = vec4(W * spos).xyz;')
elif write_wpos:
frag_mpos = (frag.contains('mposition') and not frag.contains('vec3 mposition')) or vert.contains('mposition') vert.add_uniform('mat4 W', '_worldMatrix')
if frag_mpos: vert.write_attrib('vec3 wposition = vec4(W * spos).xyz;')
vert.add_out('vec3 mposition')
vert.add_uniform('float posUnpack', link='_posUnpack') if frag.contains('dotNV') and not frag.contains('float dotNV'):
vert.write_attrib('mposition = spos.xyz * posUnpack;') frag.write_attrib('float dotNV = max(dot(n, vVec), 0.0);')
if tese is not None: frag_mpos = (frag.contains('mposition') and not frag.contains('vec3 mposition')) or vert.contains('mposition')
if frag_mpos: if frag_mpos:
make_tess.interpolate(tese, 'mposition', 3, declare_out=True) vert.add_out('vec3 mposition')
elif tese.contains('mposition') and not tese.contains('vec3 mposition'): vert.add_uniform('float posUnpack', link='_posUnpack')
vert.add_out('vec3 mposition') vert.write_attrib('mposition = spos.xyz * posUnpack;')
vert.write_pre = True
vert.add_uniform('float posUnpack', link='_posUnpack') if tese is not None:
vert.write('mposition = spos.xyz * posUnpack;') if frag_mpos:
vert.write_pre = False make_tess.interpolate(tese, 'mposition', 3, declare_out=True)
make_tess.interpolate(tese, 'mposition', 3, declare_out=False) elif tese.contains('mposition') and not tese.contains('vec3 mposition'):
vert.add_out('vec3 mposition')
frag_bpos = (frag.contains('bposition') and not frag.contains('vec3 bposition')) or vert.contains('bposition') vert.write_pre = True
if frag_bpos: vert.add_uniform('float posUnpack', link='_posUnpack')
vert.add_out('vec3 bposition') vert.write('mposition = spos.xyz * posUnpack;')
vert.add_uniform('vec3 dim', link='_dim') vert.write_pre = False
vert.add_uniform('vec3 hdim', link='_halfDim') make_tess.interpolate(tese, 'mposition', 3, declare_out=False)
vert.add_uniform('float posUnpack', link='_posUnpack')
vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;') frag_bpos = (frag.contains('bposition') and not frag.contains('vec3 bposition')) or vert.contains('bposition')
vert.write_attrib('if (dim.z == 0) bposition.z = 0;') if frag_bpos:
vert.write_attrib('if (dim.y == 0) bposition.y = 0;') vert.add_out('vec3 bposition')
vert.write_attrib('if (dim.x == 0) bposition.x = 0;') vert.add_uniform('vec3 dim', link='_dim')
vert.add_uniform('vec3 hdim', link='_halfDim')
if tese is not None: vert.add_uniform('float posUnpack', link='_posUnpack')
if frag_bpos: vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;')
make_tess.interpolate(tese, 'bposition', 3, declare_out=True) vert.write_attrib('if (dim.z == 0) bposition.z = 0;')
elif tese.contains('bposition') and not tese.contains('vec3 bposition'): vert.write_attrib('if (dim.y == 0) bposition.y = 0;')
vert.add_out('vec3 bposition') vert.write_attrib('if (dim.x == 0) bposition.x = 0;')
vert.add_uniform('vec3 dim', link='_dim')
vert.add_uniform('vec3 hdim', link='_halfDim') if tese is not None:
vert.add_uniform('float posUnpack', link='_posUnpack') if frag_bpos:
vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;') make_tess.interpolate(tese, 'bposition', 3, declare_out=True)
make_tess.interpolate(tese, 'bposition', 3, declare_out=False) elif tese.contains('bposition') and not tese.contains('vec3 bposition'):
vert.add_out('vec3 bposition')
frag_wtan = (frag.contains('wtangent') and not frag.contains('vec3 wtangent')) or vert.contains('wtangent') vert.add_uniform('vec3 dim', link='_dim')
if frag_wtan: vert.add_uniform('vec3 hdim', link='_halfDim')
# Indicate we want tang attrib in finalizer to prevent TBN generation vert.add_uniform('float posUnpack', link='_posUnpack')
con_mesh.add_elem('tex', 'short2norm') vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;')
con_mesh.add_elem('tang', 'short4norm') make_tess.interpolate(tese, 'bposition', 3, declare_out=False)
vert.add_out('vec3 wtangent')
vert.write_pre = True frag_wtan = (frag.contains('wtangent') and not frag.contains('vec3 wtangent')) or vert.contains('wtangent')
vert.write('wtangent = normalize(N * tang.xyz);') if frag_wtan:
vert.write_pre = False # Indicate we want tang attrib in finalizer to prevent TBN generation
con_mesh.add_elem('tex', 'short2norm')
if tese is not None: con_mesh.add_elem('tang', 'short4norm')
if frag_wtan: vert.add_out('vec3 wtangent')
make_tess.interpolate(tese, 'wtangent', 3, declare_out=True) vert.write_pre = True
elif tese.contains('wtangent') and not tese.contains('vec3 wtangent'): vert.write('wtangent = normalize(N * tang.xyz);')
vert.add_out('vec3 wtangent') vert.write_pre = False
vert.write_pre = True
vert.write('wtangent = normalize(N * tang.xyz);') if tese is not None:
vert.write_pre = False if frag_wtan:
make_tess.interpolate(tese, 'wtangent', 3, declare_out=False) make_tess.interpolate(tese, 'wtangent', 3, declare_out=True)
elif tese.contains('wtangent') and not tese.contains('vec3 wtangent'):
if frag.contains('vVecCam'): vert.add_out('vec3 wtangent')
vert.add_out('vec3 eyeDirCam') vert.write_pre = True
vert.add_uniform('mat4 WV', '_worldViewMatrix') vert.write('wtangent = normalize(N * tang.xyz);')
vert.write('eyeDirCam = vec4(WV * spos).xyz; eyeDirCam.z *= -1;') vert.write_pre = False
frag.write_attrib('vec3 vVecCam = normalize(eyeDirCam);') make_tess.interpolate(tese, 'wtangent', 3, declare_out=False)
if frag.contains('nAttr'): if frag.contains('vVecCam'):
vert.add_out('vec3 nAttr') vert.add_out('vec3 eyeDirCam')
vert.write_attrib('nAttr = vec3(nor.xy, pos.w);') vert.add_uniform('mat4 WV', '_worldViewMatrix')
vert.write('eyeDirCam = vec4(WV * spos).xyz; eyeDirCam.z *= -1;')
wrd = bpy.data.worlds['Lnx'] frag.write_attrib('vec3 vVecCam = normalize(eyeDirCam);')
if '_Legacy' in wrd.world_defs:
frag.replace('sampler2DShadow', 'sampler2D') if frag.contains('nAttr'):
frag.replace('samplerCubeShadow', 'samplerCube') vert.add_out('vec3 nAttr')
vert.write_attrib('nAttr = vec3(nor.xy, pos.w);')
wrd = bpy.data.worlds['Lnx']
if '_Legacy' in wrd.world_defs:
frag.replace('sampler2DShadow', 'sampler2D')
frag.replace('samplerCubeShadow', 'samplerCube')

View File

@ -557,7 +557,7 @@ def make_forward(con_mesh):
frag.write('fragColor[0] = vec4(direct + indirect, packFloat2(occlusion, specular));') frag.write('fragColor[0] = vec4(direct + indirect, packFloat2(occlusion, specular));')
frag.write('fragColor[1] = vec4(n.xy, roughness, metallic);') frag.write('fragColor[1] = vec4(n.xy, roughness, metallic);')
if rpdat.rp_ss_refraction or rpdat.lnx_voxelgi_refract: if rpdat.rp_ss_refraction or rpdat.lnx_voxelgi_refract:
frag.write(f'fragColor[2] = vec4(1.0, 1.0, 0.0, 1.0);') frag.write(f'fragColor[2] = vec4(1.0, 1.0, 0.0, 0.0);')
else: else:
frag.add_out('vec4 fragColor[1]') frag.add_out('vec4 fragColor[1]')
@ -611,10 +611,42 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
sh = tese if tese is not None else vert sh = tese if tese is not None else vert
sh.add_out('vec3 eyeDir') sh.add_out('vec3 eyeDir')
sh.add_uniform('vec3 eye', '_cameraPosition') sh.add_uniform('vec3 eye', '_cameraPosition')
sh.write('eyeDir = eye - spos.xyz;') sh.write('eyeDir = eye - wposition;')
if '_VoxelGI' in wrd.world_defs or '_VoxelShadow' in wrd.world_defs:
if '_gbuffer2' in wrd.world_defs:
if '_Veloc' in wrd.world_defs:
if tese is None:
vert.add_uniform('mat4 prevWVP', link='_prevWorldViewProjectionMatrix')
vert.add_out('vec4 wvpposition')
vert.add_out('vec4 prevwvpposition')
vert.write('wvpposition = gl_Position;')
if is_displacement:
vert.add_uniform('mat4 invW', link='_inverseWorldMatrix')
vert.write('prevwvpposition = prevWVP * (invW * vec4(wposition, 1.0));')
else:
vert.write('prevwvpposition = prevWVP * spos;')
else:
tese.add_out('vec4 wvpposition')
tese.add_out('vec4 prevwvpposition')
tese.write('wvpposition = gl_Position;')
if is_displacement:
tese.add_uniform('mat4 invW', link='_inverseWorldMatrix')
tese.add_uniform('mat4 prevWVP', '_prevWorldViewProjectionMatrix')
tese.write('prevwvpposition = prevWVP * (invW * vec4(wposition, 1.0));')
else:
vert.add_uniform('mat4 prevW', link='_prevWorldMatrix')
vert.add_out('vec3 prevwposition')
vert.write('prevwposition = vec4(prevW * spos).xyz;')
tese.add_uniform('mat4 prevVP', '_prevViewProjectionMatrix')
make_tess.interpolate(tese, 'prevwposition', 3)
tese.write('prevwvpposition = prevVP * vec4(prevwposition, 1.0);')
frag.write('vec2 posa = (wvpposition.xy / wvpposition.w) * 0.5 + 0.5;')
frag.write('vec2 posb = (prevwvpposition.xy / prevwvpposition.w) * 0.5 + 0.5;')
frag.write('vec2 velocity = -vec2(posa - posb);')
frag.add_include('std/light.glsl') frag.add_include('std/light.glsl')
is_shadows = '_ShadowMap' in wrd.world_defs is_shadows = '_ShadowMap' in wrd.world_defs
is_transparent_shadows = '_ShadowMapTransparent' in wrd.world_defs
is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs
is_single_atlas = is_shadows_atlas and '_SingleAtlas' in wrd.world_defs is_single_atlas = is_shadows_atlas and '_SingleAtlas' in wrd.world_defs
shadowmap_sun = 'shadowMap' shadowmap_sun = 'shadowMap'
@ -630,7 +662,10 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
if '_Brdf' in wrd.world_defs: if '_Brdf' in wrd.world_defs:
frag.add_uniform('sampler2D senvmapBrdf', link='$brdf.png') frag.add_uniform('sampler2D senvmapBrdf', link='$brdf.png')
frag.write('vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy;') frag.write('vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy;')
frag.write('vec3 F = f0 * envBRDF.x + envBRDF.y;')
else:
frag.write('vec3 F = f0;')
if '_Irr' in wrd.world_defs: if '_Irr' in wrd.world_defs:
frag.add_include('std/shirr.glsl') frag.add_include('std/shirr.glsl')
frag.add_uniform('vec4 shirr[7]', link='_envmapIrradiance') frag.add_uniform('vec4 shirr[7]', link='_envmapIrradiance')
@ -655,51 +690,36 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag.write('envl *= albedo;') frag.write('envl *= albedo;')
if '_Brdf' in wrd.world_defs: if '_Brdf' in wrd.world_defs:
frag.write('envl.rgb *= 1.0 - (f0 * envBRDF.x + envBRDF.y);') frag.write('envl.rgb *= 1.0 - F;')
if '_Rad' in wrd.world_defs: if '_Rad' in wrd.world_defs:
frag.write('envl += prefilteredColor * (f0 * envBRDF.x + envBRDF.y);') frag.write('envl += prefilteredColor * F;')
elif '_EnvCol' in wrd.world_defs: elif '_EnvCol' in wrd.world_defs:
frag.add_uniform('vec3 backgroundCol', link='_backgroundCol') frag.add_uniform('vec3 backgroundCol', link='_backgroundCol')
frag.write('envl += backgroundCol * (f0 * envBRDF.x + envBRDF.y);') frag.write('envl += backgroundCol * F;')
frag.add_uniform('float envmapStrength', link='_envmapStrength') frag.add_uniform('float envmapStrength', link='_envmapStrength')
frag.write('envl *= envmapStrength * occlusion;') frag.write('envl *= envmapStrength * occlusion;')
if '_VoxelAOvar' in wrd.world_defs or '_VoxelGI' in wrd.world_defs: if '_VoxelAOvar' in wrd.world_defs or '_VoxelGI' in wrd.world_defs:
if parse_opacity or '_VoxelShadow' in wrd.world_defs: frag.add_include('std/conetrace.glsl')
frag.add_include('std/conetrace.glsl') frag.add_uniform('sampler3D voxels')
frag.add_uniform('sampler3D voxels') frag.add_uniform('sampler3D voxelsSDF')
frag.add_uniform('sampler3D voxelsSDF') frag.add_uniform('float clipmaps[10 * voxelgiClipmapCount]', '_clipmaps')
frag.add_uniform('vec3 eye', "_cameraPosition")
frag.add_uniform('float clipmaps[10 * voxelgiClipmapCount]', '_clipmaps')
vert.add_out('vec4 wvpposition')
vert.write('wvpposition = gl_Position;')
frag.write('vec2 texCoord = (wvpposition.xy / wvpposition.w) * 0.5 + 0.5;')
if '_VoxelAOvar' in wrd.world_defs and not parse_opacity: if '_VoxelAOvar' in wrd.world_defs:
frag.add_uniform("sampler2D voxels_ao"); frag.write('envl *= (1.0 - traceAO(wposition, n, voxels, clipmaps));')
frag.write('envl *= textureLod(voxels_ao, texCoord, 0.0).rrr;')
if '_VoxelGI' in wrd.world_defs: if '_VoxelGI' in wrd.world_defs:
frag.write('vec3 indirect = vec3(0.0);') frag.write('vec3 indirect = vec3(0.0);')
else: else:
frag.write('vec3 indirect = envl;') frag.write('vec3 indirect = envl;')
if '_VoxelGI' in wrd.world_defs:
if parse_opacity:
frag.write('vec4 trace = traceDiffuse(wposition, wnormal, voxels, clipmaps);')
frag.write('indirect = ((trace.rgb * albedo + envl * (1.0 - trace.a)) * voxelgiDiff);')
frag.write('if (roughness < 1.0 && specular > 0.0){')
frag.add_uniform('sampler2D sveloc')
frag.write(' vec2 velocity = -textureLod(sveloc, gl_FragCoord.xy, 0.0).rg;')
frag.write(' indirect += traceSpecular(wposition, n, voxels, voxelsSDF, vVec, roughness, clipmaps, gl_FragCoord.xy, velocity).rgb * specular * voxelgiRefl;}')
else:
frag.add_uniform("sampler2D voxels_diffuse")
frag.add_uniform("sampler2D voxels_specular")
frag.write("indirect = textureLod(voxels_diffuse, texCoord, 0.0).rgb * albedo * voxelgiDiff;")
frag.write("if (roughness < 1.0 && specular > 0.0)")
frag.write(" indirect += textureLod(voxels_specular, texCoord, 0.0).rgb * specular * voxelgiRefl;")
if '_VoxelGI' in wrd.world_defs:
frag.write('vec4 diffuse_indirect = traceDiffuse(wposition, n, voxels, clipmaps);')
frag.write('indirect = (diffuse_indirect.rgb * albedo * (1.0 - F) + envl * (1.0 - diffuse_indirect.a)) * voxelgiDiff;')
frag.write('if (roughness < 1.0 && specular > 0.0) {')
frag.write(' indirect += traceSpecular(wposition, n, voxels, voxelsSDF, vVec, roughness * roughness, clipmaps, gl_FragCoord.xy, velocity).rgb * F * voxelgiRefl;')
frag.write('}')
frag.write('vec3 direct = vec3(0.0);') frag.write('vec3 direct = vec3(0.0);')
if '_Sun' in wrd.world_defs: if '_Sun' in wrd.world_defs:
@ -713,18 +733,21 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
if is_shadows: if is_shadows:
frag.add_uniform('bool receiveShadow') frag.add_uniform('bool receiveShadow')
frag.add_uniform(f'sampler2DShadow {shadowmap_sun}', top=True) frag.add_uniform(f'sampler2DShadow {shadowmap_sun}', top=True)
frag.add_uniform(f'sampler2D {shadowmap_sun_tr}', top=True) if is_transparent_shadows:
frag.add_uniform(f'sampler2D {shadowmap_sun_tr}', top=True)
frag.add_uniform('float shadowsBias', '_sunShadowsBias') frag.add_uniform('float shadowsBias', '_sunShadowsBias')
frag.write('if (receiveShadow) {') frag.write('if (receiveShadow) {')
if '_CSM' in wrd.world_defs: if '_CSM' in wrd.world_defs:
frag.add_include('std/shadows.glsl') frag.add_include('std/shadows.glsl')
frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]', '_cascadeData', included=True) frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]', '_cascadeData', included=True)
frag.add_uniform('vec3 eye', '_cameraPosition') frag.add_uniform('vec3 eye', '_cameraPosition')
if parse_opacity: frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun}, {shadowmap_sun_tr}, eye, wposition + n * shadowsBias * 10, shadowsBias, true);') if is_transparent_shadows:
else: frag.write(f'{shadowmap_sun_tr},')
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun}, {shadowmap_sun_tr}, eye, wposition + n * shadowsBias * 10, shadowsBias, false);') frag.write('eye, wposition + n * shadowsBias * 10, shadowsBias')
if is_transparent_shadows:
frag.write(', false')
frag.write(');')
else: else:
if tese is not None: if tese is not None:
tese.add_out('vec4 lightPosition') tese.add_out('vec4 lightPosition')
@ -738,15 +761,18 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
else: else:
vert.add_out('vec4 lightPosition') vert.add_out('vec4 lightPosition')
vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrixSun') vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrixSun')
vert.write('lightPosition = LWVP * lightPosition;') vert.write('lightPosition = LWVP * pos;')
frag.write('vec3 lPos = lightPosition.xyz / lightPosition.w;') frag.write('vec3 lPos = lightPosition.xyz / lightPosition.w;')
frag.write('const vec2 smSize = shadowmapSize;') frag.write('const vec2 smSize = shadowmapSize;')
if parse_opacity: frag.write(f'svisibility = PCF({shadowmap_sun},')
frag.write(f'svisibility = PCF({shadowmap_sun}, {shadowmap_sun_tr}, lPos.xy, lPos.z - shadowsBias, smSize, true);') if is_transparent_shadows:
else: frag.write(f'{shadowmap_sun_tr},')
frag.write(f'svisibility = PCF({shadowmap_sun}, {shadowmap_sun_tr}, lPos.xy, lPos.z - shadowsBias, smSize, false);') frag.write('lPos.xy, lPos.z - shadowsBias, smSize')
if is_transparent_shadows:
frag.write(', false')
frag.write(');')
if '_VoxelShadow' in wrd.world_defs: if '_VoxelShadow' in wrd.world_defs:
frag.write('svisibility *= (1.0 - traceShadow(wposition, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;') frag.write('svisibility *= (1.0 - traceShadow(wposition, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy, velocity).r) * voxelgiShad;')
frag.write('}') # receiveShadow frag.write('}') # receiveShadow
frag.write('direct += (lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular) * sunCol * svisibility;') frag.write('direct += (lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular) * sunCol * svisibility;')
# sun # sun
@ -765,7 +791,8 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
# Skip world matrix, already in world-space # Skip world matrix, already in world-space
frag.add_uniform('mat4 LWVPSpot[1]', link='_biasLightViewProjectionMatrixSpotArray', included=True) frag.add_uniform('mat4 LWVPSpot[1]', link='_biasLightViewProjectionMatrixSpotArray', included=True)
frag.add_uniform('sampler2DShadow shadowMapSpot[1]', included=True) frag.add_uniform('sampler2DShadow shadowMapSpot[1]', included=True)
frag.add_uniform('sampler2D shadowMapSpotTransparent[1]', included=True) if is_transparent_shadows:
frag.add_uniform('sampler2D shadowMapSpotTransparent[1]', included=True)
else: else:
frag.add_uniform('vec2 lightProj', link='_lightPlaneProj', included=True) frag.add_uniform('vec2 lightProj', link='_lightPlaneProj', included=True)
frag.add_uniform('samplerCubeShadow shadowMapPoint[1]', included=True) frag.add_uniform('samplerCubeShadow shadowMapPoint[1]', included=True)
@ -773,18 +800,19 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag.write('direct += sampleLight(') frag.write('direct += sampleLight(')
frag.write(' wposition, n, vVec, dotNV, pointPos, pointCol, albedo, roughness, specular, f0') frag.write(' wposition, n, vVec, dotNV, pointPos, pointCol, albedo, roughness, specular, f0')
if is_shadows: if is_shadows:
if parse_opacity: frag.write(', 0, pointBias, receiveShadow')
frag.write(', 0, pointBias, receiveShadow, opacity != 1.0') if is_transparent_shadows:
else: frag.write(', opacity != 1.0')
frag.write(', 0, pointBias, receiveShadow, false')
if '_Spot' in wrd.world_defs: if '_Spot' in wrd.world_defs:
frag.write(', true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight') frag.write(', true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight')
if '_VoxelShadow' in wrd.world_defs: if '_VoxelShadow' in wrd.world_defs:
frag.write(', voxels, voxelsSDF, clipmaps') frag.write(', voxels, voxelsSDF, clipmaps')
if '_Veloc' in wrd.world_defs or '_VoxelShadow' in wrd.world_defs:
frag.write(', velocity')
if '_MicroShadowing' in wrd.world_defs: if '_MicroShadowing' in wrd.world_defs:
frag.write(', occlusion') frag.write(', occlusion')
if '_SSRS' in wrd.world_defs: if '_SSRS' in wrd.world_defs:
frag.add_uniform('sampler2D gbufferD', top=True) frag.add_uniform('sampler2D gbufferD')
frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix') frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix')
frag.add_uniform('vec3 eye', '_cameraPosition') frag.add_uniform('vec3 eye', '_cameraPosition')
frag.write(', gbufferD, invVP, eye') frag.write(', gbufferD, invVP, eye')
@ -800,10 +828,9 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
if '_VoxelRefract' in wrd.world_defs and parse_opacity: if '_VoxelRefract' in wrd.world_defs and parse_opacity:
frag.write('if (opacity < 1.0) {') frag.write('if (opacity < 1.0) {')
frag.write(' vec2 velocity = -textureLod(sveloc, gl_FragCoord.xy, 0.0).rg;') frag.write(' vec3 refraction = traceRefraction(wposition, n, voxels, voxelsSDF, vVec, ior, roughness * roughness, clipmaps, gl_FragCoord.xy, velocity, opacity).rgb * (1.0 - F) * voxelgiRefr;')
frag.write(' vec3 refraction = traceRefraction(wposition, n, voxels, voxelsSDF, vVec, ior, roughness, clipmaps, gl_FragCoord.xy,velocity).rgb;') frag.write(' indirect = mix(refraction, indirect, opacity);')
frag.write(' indirect = mix(refraction, indirect, opacity) * voxelgiRefr;') frag.write(' direct = mix(refraction, direct, opacity);')
frag.write(' direct = mix(refraction, direct, opacity) * voxelgiRefr;')
frag.write('}') frag.write('}')
def _write_material_attribs_default(frag: shader.Shader, parse_opacity: bool): def _write_material_attribs_default(frag: shader.Shader, parse_opacity: bool):
@ -817,4 +844,4 @@ def _write_material_attribs_default(frag: shader.Shader, parse_opacity: bool):
frag.write('vec3 emissionCol;') frag.write('vec3 emissionCol;')
if parse_opacity: if parse_opacity:
frag.write('float opacity;') frag.write('float opacity;')
frag.write('float ior;') frag.write('float ior = 1.45;')

View File

@ -1,49 +0,0 @@
import bpy
import lnx
import lnx.material.cycles as cycles
import lnx.material.mat_state as mat_state
import lnx.material.mat_utils as mat_utils
import lnx.material.make_mesh as make_mesh
import lnx.material.make_finalize as make_finalize
import lnx.assets as assets
if lnx.is_reload(__name__):
cycles = lnx.reload_module(cycles)
mat_state = lnx.reload_module(mat_state)
make_mesh = lnx.reload_module(make_mesh)
make_finalize = lnx.reload_module(make_finalize)
assets = lnx.reload_module(assets)
else:
lnx.enable_reload(__name__)
def make(context_id):
con_refraction_buffer = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'less', 'cull_mode': 'clockwise' })
lnx_discard = mat_state.material.lnx_discard
blend = mat_state.material.lnx_blending
parse_opacity = blend or mat_utils.is_transluc(mat_state.material) or lnx_discard
make_mesh.make_base(con_refraction_buffer, parse_opacity)
vert = con_refraction_buffer.vert
frag = con_refraction_buffer.frag
frag.add_out('vec4 fragColor')
# Remove fragColor = ...;
frag.main = frag.main[:frag.main.rfind('fragColor')]
frag.write('\n')
if parse_opacity:
frag.write('fragColor = vec4(ior, opacity, 0.0, 1.0);')
else:
frag.write('fragColor = vec4(1.0, 1.0, 0.0, 1.0);')
make_finalize.make(con_refraction_buffer)
# assets.vs_equal(con_refract, assets.shader_cons['transluc_vert']) # shader_cons has no transluc yet
# assets.fs_equal(con_refract, assets.shader_cons['transluc_frag'])
return con_refraction_buffer

File diff suppressed because it is too large Load Diff

View File

@ -295,6 +295,7 @@ def init_properties():
name="Assertion Level", description="Ignore all assertions below this level (assertions are turned off completely for published builds)", default='Warning', update=assets.invalidate_compiler_cache) name="Assertion Level", description="Ignore all assertions below this level (assertions are turned off completely for published builds)", default='Warning', update=assets.invalidate_compiler_cache)
bpy.types.World.lnx_assert_quit = BoolProperty(name="Quit On Assertion Fail", description="Whether to close the game when an 'Error' level assertion fails", default=False, update=assets.invalidate_compiler_cache) bpy.types.World.lnx_assert_quit = BoolProperty(name="Quit On Assertion Fail", description="Whether to close the game when an 'Error' level assertion fails", default=False, update=assets.invalidate_compiler_cache)
bpy.types.World.lnx_live_patch = BoolProperty(name="Live Patch", description="Live patching for Krom", default=False) bpy.types.World.lnx_live_patch = BoolProperty(name="Live Patch", description="Live patching for Krom", default=False)
bpy.types.World.lnx_render_viewport = BoolProperty(name="Viewport Render", description="Viewport rendering", default=False)
bpy.types.World.lnx_clear_on_compile = BoolProperty(name="Clear Console", description="Clears the system console on compile", default=False) bpy.types.World.lnx_clear_on_compile = BoolProperty(name="Clear Console", description="Clears the system console on compile", default=False)
bpy.types.World.lnx_play_camera = EnumProperty( bpy.types.World.lnx_play_camera = EnumProperty(
items=[('Scene', 'Scene', 'Scene'), items=[('Scene', 'Scene', 'Scene'),

View File

@ -65,8 +65,8 @@ def update_preset(self, context):
rpdat.rp_background = 'World' rpdat.rp_background = 'World'
rpdat.rp_stereo = False rpdat.rp_stereo = False
rpdat.rp_voxelgi_resolution = '32' rpdat.rp_voxelgi_resolution = '32'
rpdat.lnx_voxelgi_size = 0.25 rpdat.lnx_voxelgi_size = 0.125
rpdat.rp_voxels = 'Voxel AO' rpdat.rp_voxels = 'Voxel GI'
rpdat.rp_render_to_texture = True rpdat.rp_render_to_texture = True
rpdat.rp_supersampling = '1' rpdat.rp_supersampling = '1'
rpdat.rp_antialiasing = 'SMAA' rpdat.rp_antialiasing = 'SMAA'
@ -142,8 +142,8 @@ def update_preset(self, context):
rpdat.rp_stereo = False rpdat.rp_stereo = False
rpdat.rp_voxels = 'Voxel GI' rpdat.rp_voxels = 'Voxel GI'
rpdat.rp_voxelgi_resolution = '64' rpdat.rp_voxelgi_resolution = '64'
rpdat.lnx_voxelgi_size = 0.25 rpdat.lnx_voxelgi_size = 0.125
rpdat.lnx_voxelgi_step = 0.25 rpdat.lnx_voxelgi_step = 0.01
rpdat.lnx_voxelgi_revoxelize = False rpdat.lnx_voxelgi_revoxelize = False
rpdat.lnx_voxelgi_camera = False rpdat.lnx_voxelgi_camera = False
rpdat.rp_voxelgi_emission = False rpdat.rp_voxelgi_emission = False
@ -152,7 +152,7 @@ def update_preset(self, context):
rpdat.rp_antialiasing = 'TAA' rpdat.rp_antialiasing = 'TAA'
rpdat.rp_compositornodes = True rpdat.rp_compositornodes = True
rpdat.rp_volumetriclight = False rpdat.rp_volumetriclight = False
rpdat.rp_ssgi = 'RTAO' rpdat.rp_ssgi = 'SSGI'
rpdat.lnx_ssrs = False rpdat.lnx_ssrs = False
rpdat.lnx_micro_shadowing = True rpdat.lnx_micro_shadowing = True
rpdat.rp_ssr = True rpdat.rp_ssr = True
@ -330,6 +330,7 @@ class LnxRPListItem(bpy.types.PropertyGroup):
rp_shadowmap_atlas: BoolProperty(name="Shadow Map Atlasing", description="Group shadow maps of lights of the same type in the same texture", default=False, update=update_renderpath) rp_shadowmap_atlas: BoolProperty(name="Shadow Map Atlasing", description="Group shadow maps of lights of the same type in the same texture", default=False, update=update_renderpath)
rp_shadowmap_atlas_single_map: BoolProperty(name="Shadow Map Atlas single map", description="Use a single texture for all different light types.", default=False, update=update_renderpath) rp_shadowmap_atlas_single_map: BoolProperty(name="Shadow Map Atlas single map", description="Use a single texture for all different light types.", default=False, update=update_renderpath)
rp_shadowmap_atlas_lod: BoolProperty(name="Shadow Map Atlas LOD (Experimental)", description="When enabled, the size of the shadow map will be determined on runtime based on the distance of the light to the camera", default=False, update=update_renderpath) rp_shadowmap_atlas_lod: BoolProperty(name="Shadow Map Atlas LOD (Experimental)", description="When enabled, the size of the shadow map will be determined on runtime based on the distance of the light to the camera", default=False, update=update_renderpath)
rp_shadowmap_transparent: BoolProperty(name="Transparency", description="Enable transparent shadowmaps", default=False, update=update_renderpath)
rp_shadowmap_atlas_lod_subdivisions: EnumProperty( rp_shadowmap_atlas_lod_subdivisions: EnumProperty(
items=[('2', '2', '2'), items=[('2', '2', '2'),
('3', '3', '3'), ('3', '3', '3'),
@ -391,7 +392,8 @@ class LnxRPListItem(bpy.types.PropertyGroup):
rp_ssgi: EnumProperty( rp_ssgi: EnumProperty(
items=[('Off', 'No AO', 'Off'), items=[('Off', 'No AO', 'Off'),
('SSAO', 'SSAO', 'Screen space ambient occlusion'), ('SSAO', 'SSAO', 'Screen space ambient occlusion'),
('RTAO', 'RTAO', 'Ray-traced ambient occlusion') ('SSGI', 'SSGI', 'Screen space global illumination')
#('RTAO', 'RTAO', 'Ray-traced ambient occlusion')
# ('RTGI', 'RTGI', 'Ray-traced global illumination') # ('RTGI', 'RTGI', 'Ray-traced global illumination')
], ],
name="SSGI", description="Screen space global illumination", default='SSAO', update=update_renderpath) name="SSGI", description="Screen space global illumination", default='SSAO', update=update_renderpath)
@ -508,7 +510,7 @@ class LnxRPListItem(bpy.types.PropertyGroup):
('1', '1', '1'), ('1', '1', '1'),
('2', '2', '2')], ('2', '2', '2')],
name="Bounces", description="Trace multiple light bounces", default='1', update=update_renderpath) name="Bounces", description="Trace multiple light bounces", default='1', update=update_renderpath)
lnx_voxelgi_clipmap_count: IntProperty(name="Clipmap count", description="Number of clipmaps", default=3, update=assets.invalidate_compiled_data) lnx_voxelgi_clipmap_count: IntProperty(name="Clipmap count", description="Number of clipmaps", default=5, update=assets.invalidate_compiled_data)
lnx_voxelgi_temporal: BoolProperty(name="Temporal Filter", description="Use temporal filtering to stabilize voxels", default=False, update=assets.invalidate_shader_cache) lnx_voxelgi_temporal: BoolProperty(name="Temporal Filter", description="Use temporal filtering to stabilize voxels", default=False, update=assets.invalidate_shader_cache)
lnx_voxelgi_shadows: BoolProperty(name="Shadows", description="Use voxels to render shadows", default=False, update=update_renderpath) lnx_voxelgi_shadows: BoolProperty(name="Shadows", description="Use voxels to render shadows", default=False, update=update_renderpath)
lnx_samples_per_pixel: EnumProperty( lnx_samples_per_pixel: EnumProperty(
@ -530,9 +532,10 @@ class LnxRPListItem(bpy.types.PropertyGroup):
lnx_voxelgi_spec: FloatProperty(name="Reflection", description="", default=1.0, update=assets.invalidate_shader_cache) lnx_voxelgi_spec: FloatProperty(name="Reflection", description="", default=1.0, update=assets.invalidate_shader_cache)
lnx_voxelgi_refr: FloatProperty(name="Refraction", description="", default=1.0, update=assets.invalidate_shader_cache) lnx_voxelgi_refr: FloatProperty(name="Refraction", description="", default=1.0, update=assets.invalidate_shader_cache)
lnx_voxelgi_shad: FloatProperty(name="Shadows", description="Contrast for voxels shadows", default=1.0, update=assets.invalidate_shader_cache) lnx_voxelgi_shad: FloatProperty(name="Shadows", description="Contrast for voxels shadows", default=1.0, update=assets.invalidate_shader_cache)
lnx_voxelgi_env: FloatProperty(name="Environment", description="", default=1.0, update=assets.invalidate_shader_cache)
lnx_voxelgi_occ: FloatProperty(name="Occlusion", description="", default=1.0, update=assets.invalidate_shader_cache) lnx_voxelgi_occ: FloatProperty(name="Occlusion", description="", default=1.0, update=assets.invalidate_shader_cache)
lnx_voxelgi_size: FloatProperty(name="Size", description="Voxel size", default=0.25, update=assets.invalidate_shader_cache) lnx_voxelgi_size: FloatProperty(name="Size", description="Voxel size", default=0.25, update=assets.invalidate_shader_cache)
lnx_voxelgi_step: FloatProperty(name="Step", description="Step size", default=0.25, update=assets.invalidate_shader_cache) lnx_voxelgi_step: FloatProperty(name="Step", description="Step size", default=1.0, update=assets.invalidate_shader_cache)
lnx_voxelgi_range: FloatProperty(name="Range", description="Maximum range", default=100.0, update=assets.invalidate_shader_cache) lnx_voxelgi_range: FloatProperty(name="Range", description="Maximum range", default=100.0, update=assets.invalidate_shader_cache)
lnx_voxelgi_offset: FloatProperty(name="Offset", description="Multiplicative Offset for dealing with self occlusion", default=1.0, update=assets.invalidate_shader_cache) lnx_voxelgi_offset: FloatProperty(name="Offset", description="Multiplicative Offset for dealing with self occlusion", default=1.0, update=assets.invalidate_shader_cache)
lnx_voxelgi_aperture: FloatProperty(name="Aperture", description="Cone aperture for shadow trace", default=0.0, update=assets.invalidate_shader_cache) lnx_voxelgi_aperture: FloatProperty(name="Aperture", description="Cone aperture for shadow trace", default=0.0, update=assets.invalidate_shader_cache)
@ -545,15 +548,17 @@ class LnxRPListItem(bpy.types.PropertyGroup):
lnx_water_density: FloatProperty(name="Density", default=1.0, update=assets.invalidate_shader_cache) lnx_water_density: FloatProperty(name="Density", default=1.0, update=assets.invalidate_shader_cache)
lnx_water_refract: FloatProperty(name="Refract", default=1.0, update=assets.invalidate_shader_cache) lnx_water_refract: FloatProperty(name="Refract", default=1.0, update=assets.invalidate_shader_cache)
lnx_water_reflect: FloatProperty(name="Reflect", default=1.0, update=assets.invalidate_shader_cache) lnx_water_reflect: FloatProperty(name="Reflect", default=1.0, update=assets.invalidate_shader_cache)
lnx_ssgi_strength: FloatProperty(name="Strength", default=1.0, update=assets.invalidate_shader_cache) lnx_ssgi_strength: FloatProperty(name="Strength", default=8.0, update=assets.invalidate_shader_cache)
lnx_ssgi_radius: FloatProperty(name="Radius", default=1.0, update=assets.invalidate_shader_cache) lnx_ssgi_radius: FloatProperty(name="Radius", default=1.0, update=assets.invalidate_shader_cache)
lnx_ssgi_step: FloatProperty(name="Step", default=2.0, update=assets.invalidate_shader_cache) lnx_ssgi_step: FloatProperty(name="Step", default=2.0, update=assets.invalidate_shader_cache)
lnx_ssgi_max_steps: IntProperty(name="Max Steps", default=8, update=assets.invalidate_shader_cache) lnx_ssgi_samples: IntProperty(name="Samples", default=32, update=assets.invalidate_shader_cache)
"""
lnx_ssgi_rays: EnumProperty( lnx_ssgi_rays: EnumProperty(
items=[('9', '9', '9'), items=[('9', '9', '9'),
('5', '5', '5'), ('5', '5', '5'),
], ],
name="Rays", description="Number of rays to trace for RTAO", default='5', update=assets.invalidate_shader_cache) name="Rays", description="Number of rays to trace for RTAO", default='5', update=assets.invalidate_shader_cache)
"""
lnx_ssgi_half_res: BoolProperty(name="Half Res", description="Trace in half resolution", default=False, update=assets.invalidate_shader_cache) lnx_ssgi_half_res: BoolProperty(name="Half Res", description="Trace in half resolution", default=False, update=assets.invalidate_shader_cache)
lnx_bloom_threshold: FloatProperty(name="Threshold", description="Brightness above which a pixel is contributing to the bloom effect", min=0, default=0.8, update=assets.invalidate_shader_cache) lnx_bloom_threshold: FloatProperty(name="Threshold", description="Brightness above which a pixel is contributing to the bloom effect", min=0, default=0.8, update=assets.invalidate_shader_cache)
lnx_bloom_knee: FloatProperty(name="Knee", description="Smoothen transition around the threshold (higher values = smoother transition)", min=0, max=1, default=0.5, update=assets.invalidate_shader_cache) lnx_bloom_knee: FloatProperty(name="Knee", description="Smoothen transition around the threshold (higher values = smoother transition)", min=0, max=1, default=0.5, update=assets.invalidate_shader_cache)

View File

@ -1629,6 +1629,7 @@ class LNX_PT_RenderPathShadowsPanel(bpy.types.Panel):
col.prop(rpdat, 'rp_shadowmap_cube') col.prop(rpdat, 'rp_shadowmap_cube')
layout.prop(rpdat, 'rp_shadowmap_cascade') layout.prop(rpdat, 'rp_shadowmap_cascade')
layout.prop(rpdat, 'rp_shadowmap_cascades') layout.prop(rpdat, 'rp_shadowmap_cascades')
layout.prop(rpdat, 'rp_shadowmap_transparent')
col = layout.column() col = layout.column()
col2 = col.column() col2 = col.column()
col2.enabled = rpdat.rp_shadowmap_cascades != '1' col2.enabled = rpdat.rp_shadowmap_cascades != '1'
@ -1760,7 +1761,7 @@ class LNX_PT_RenderPathVoxelsPanel(bpy.types.Panel):
col3.enabled = rpdat.rp_voxels == 'Voxel AO' col3.enabled = rpdat.rp_voxels == 'Voxel AO'
col.prop(rpdat, 'lnx_voxelgi_shadows', text='Shadows') col.prop(rpdat, 'lnx_voxelgi_shadows', text='Shadows')
col2.prop(rpdat, 'lnx_voxelgi_refract', text='Refraction') col2.prop(rpdat, 'lnx_voxelgi_refract', text='Refraction')
col.prop(rpdat, 'lnx_voxelgi_clipmap_count') #col.prop(rpdat, 'lnx_voxelgi_clipmap_count')
#col.prop(rpdat, 'lnx_voxelgi_cones') #col.prop(rpdat, 'lnx_voxelgi_cones')
col.prop(rpdat, 'rp_voxelgi_resolution') col.prop(rpdat, 'rp_voxelgi_resolution')
col.prop(rpdat, 'lnx_voxelgi_size') col.prop(rpdat, 'lnx_voxelgi_size')
@ -1774,9 +1775,10 @@ class LNX_PT_RenderPathVoxelsPanel(bpy.types.Panel):
col2.prop(rpdat, 'lnx_voxelgi_spec') col2.prop(rpdat, 'lnx_voxelgi_spec')
col2.prop(rpdat, 'lnx_voxelgi_refr') col2.prop(rpdat, 'lnx_voxelgi_refr')
col.prop(rpdat, 'lnx_voxelgi_shad') col.prop(rpdat, 'lnx_voxelgi_shad')
col.prop(rpdat, 'lnx_voxelgi_env')
col.prop(rpdat, 'lnx_voxelgi_occ') col.prop(rpdat, 'lnx_voxelgi_occ')
col.label(text="Ray") col.label(text="Ray")
col.prop(rpdat, 'lnx_voxelgi_offset') #col.prop(rpdat, 'lnx_voxelgi_offset')
col.prop(rpdat, 'lnx_voxelgi_step') col.prop(rpdat, 'lnx_voxelgi_step')
col.prop(rpdat, 'lnx_voxelgi_range') col.prop(rpdat, 'lnx_voxelgi_range')
#col.prop(rpdat, 'lnx_voxelgi_aperture') #col.prop(rpdat, 'lnx_voxelgi_aperture')
@ -1867,10 +1869,10 @@ class LNX_PT_RenderPathPostProcessPanel(bpy.types.Panel):
sub = col.column() sub = col.column()
sub.enabled = rpdat.rp_ssgi != 'Off' sub.enabled = rpdat.rp_ssgi != 'Off'
sub.prop(rpdat, 'lnx_ssgi_half_res') sub.prop(rpdat, 'lnx_ssgi_half_res')
sub.prop(rpdat, 'lnx_ssgi_rays') #sub.prop(rpdat, 'lnx_ssgi_rays')
sub.prop(rpdat, 'lnx_ssgi_radius') sub.prop(rpdat, 'lnx_ssgi_radius')
sub.prop(rpdat, 'lnx_ssgi_strength') sub.prop(rpdat, 'lnx_ssgi_strength')
sub.prop(rpdat, 'lnx_ssgi_max_steps') sub.prop(rpdat, 'lnx_ssgi_samples')
layout.separator() layout.separator()
row = layout.row() row = layout.row()

View File

@ -207,6 +207,8 @@ project.addSources('Sources');
# get instantiated # get instantiated
khafile.write("""project.addParameter("--macro include('leenkx.logicnode')");\n""") khafile.write("""project.addParameter("--macro include('leenkx.logicnode')");\n""")
if wrd.lnx_render_viewport:
assets.add_khafile_def('lnx_render_viewport')
import_traits = list(set(import_traits)) import_traits = list(set(import_traits))
for i in range(0, len(import_traits)): for i in range(0, len(import_traits)):
khafile.write("project.addParameter('" + import_traits[i] + "');\n") khafile.write("project.addParameter('" + import_traits[i] + "');\n")
@ -625,32 +627,18 @@ def write_compiledglsl(defs, make_variants):
idx_emission = 2 idx_emission = 2
idx_refraction = 2 idx_refraction = 2
if '_gbuffer2' in wrd.world_defs: if '_gbuffer2' in wrd.world_defs:
f.write('#define GBUF_IDX_2 2\n') f.write('#define GBUF_IDX_2 2\n')
idx_emission += 1 idx_emission += 1
idx_refraction += 1 idx_refraction += 1
# Special case for WebGL with both TAA and SSRefraction
webgl_with_taa_refr = ('_kha_webgl' in wrd.world_defs and
('_SSRefraction' in wrd.world_defs or '_VoxelRefract' in wrd.world_defs) and
('_TAA' in wrd.world_defs or '_SMAA' in wrd.world_defs))
if webgl_with_taa_refr:
# WebGL needs refraction to come before emission for correct rendering
if '_SSRefraction' in wrd.world_defs or '_VoxelRefract' in wrd.world_defs:
f.write(f'#define GBUF_IDX_REFRACTION {idx_emission}\n')
idx_emission += 1
if '_EmissionShaded' in wrd.world_defs:
f.write(f'#define GBUF_IDX_EMISSION {idx_emission}\n')
else:
# Standard order for all other platforms
if '_EmissionShaded' in wrd.world_defs:
f.write(f'#define GBUF_IDX_EMISSION {idx_emission}\n')
idx_refraction += 1
if '_SSRefraction' in wrd.world_defs or '_VoxelRefract' in wrd.world_defs: if '_EmissionShaded' in wrd.world_defs:
f.write(f'#define GBUF_IDX_REFRACTION {idx_refraction}\n') f.write(f'#define GBUF_IDX_EMISSION {idx_emission}\n')
idx_refraction += 1
if '_SSRefraction' in wrd.world_defs or '_VoxelRefract' in wrd.world_defs:
f.write(f'#define GBUF_IDX_REFRACTION {idx_refraction}\n')
f.write("""#if defined(HLSL) || defined(METAL) f.write("""#if defined(HLSL) || defined(METAL)
#define _InvY #define _InvY
@ -684,16 +672,16 @@ const float waterReflect = """ + str(round(rpdat.lnx_water_reflect * 100) / 100)
f'const float ditherStrengthValue = {rpdat.lnx_dithering_strength};\n' f'const float ditherStrengthValue = {rpdat.lnx_dithering_strength};\n'
) )
if rpdat.rp_ssgi == 'SSAO' or rpdat.rp_ssgi == 'RTAO' or rpdat.rp_volumetriclight: if rpdat.rp_ssgi == 'SSAO' or rpdat.rp_ssgi == 'SSGI' or rpdat.rp_ssgi == 'RTAO' or rpdat.rp_volumetriclight:
f.write( f.write(
"""const float ssaoRadius = """ + str(round(rpdat.lnx_ssgi_radius * 100) / 100) + """; """const float ssaoRadius = """ + str(round(rpdat.lnx_ssgi_radius * 100) / 100) + """;
const float ssaoStrength = """ + str(round(rpdat.lnx_ssgi_strength * 100) / 100) + """; const float ssaoStrength = """ + str(round(rpdat.lnx_ssgi_strength * 100) / 100) + """;
const float ssaoScale = """ + ("2.0" if rpdat.lnx_ssgi_half_res else "20.0") + """; const float ssaoScale = """ + ("2.0" if rpdat.lnx_ssgi_half_res else "20.0") + """;
""") """)
if rpdat.rp_ssgi == 'RTGI' or rpdat.rp_ssgi == 'RTAO': if rpdat.rp_ssgi == 'RTGI' or rpdat.rp_ssgi == 'RTAO' or rpdat.rp_ssgi == 'SSGI' :
f.write( f.write(
"""const int ssgiMaxSteps = """ + str(rpdat.lnx_ssgi_max_steps) + """; """const int ssgiSamples = """ + str(rpdat.lnx_ssgi_samples) + """;
const float ssgiRayStep = 0.005 * """ + str(round(rpdat.lnx_ssgi_step * 100) / 100) + """; const float ssgiRayStep = 0.005 * """ + str(round(rpdat.lnx_ssgi_step * 100) / 100) + """;
const float ssgiStrength = """ + str(round(rpdat.lnx_ssgi_strength * 100) / 100) + """; const float ssgiStrength = """ + str(round(rpdat.lnx_ssgi_strength * 100) / 100) + """;
""") """)
@ -840,6 +828,7 @@ const float voxelgiRange = """ + str(round(rpdat.lnx_voxelgi_range * 100) / 100)
const float voxelgiOffset = """ + str(round(rpdat.lnx_voxelgi_offset * 1000) / 1000) + """; const float voxelgiOffset = """ + str(round(rpdat.lnx_voxelgi_offset * 1000) / 1000) + """;
const float voxelgiAperture = """ + str(round(rpdat.lnx_voxelgi_aperture * 100) / 100) + """; const float voxelgiAperture = """ + str(round(rpdat.lnx_voxelgi_aperture * 100) / 100) + """;
const float voxelgiShad = """ + str(round(rpdat.lnx_voxelgi_shad * 100) / 100) + """; const float voxelgiShad = """ + str(round(rpdat.lnx_voxelgi_shad * 100) / 100) + """;
const float voxelgiEnv = """ + str(round(rpdat.lnx_voxelgi_env * 100) / 100) + """;
""") """)
if rpdat.rp_voxels == 'Voxel GI': if rpdat.rp_voxels == 'Voxel GI':
f.write(""" f.write("""