From aea321ae577f9a2674600f93c6651aa2960e00b1 Mon Sep 17 00:00:00 2001 From: yvain Date: Tue, 30 Jul 2024 01:36:04 +0200 Subject: [PATCH] got proper voxels refraction working with ssrefr in deferred. TODO: implement voxels refraction for translucent. --- .../deferred_light/deferred_light.frag.glsl | 5 ++- Shaders/ssrefr_pass/ssrefr_pass.frag.glsl | 13 ++++++ Sources/armory/renderpath/Inc.hx | 18 +------- .../armory/renderpath/RenderPathDeferred.hx | 41 +++++++++---------- blender/arm/material/make_mesh.py | 26 ++++-------- .../arm/material/make_refraction_buffer.py | 15 ++++++- blender/arm/material/make_shader.py | 1 - 7 files changed, 58 insertions(+), 61 deletions(-) diff --git a/Shaders/deferred_light/deferred_light.frag.glsl b/Shaders/deferred_light/deferred_light.frag.glsl index 84531cf19..4b4b76e49 100644 --- a/Shaders/deferred_light/deferred_light.frag.glsl +++ b/Shaders/deferred_light/deferred_light.frag.glsl @@ -37,6 +37,10 @@ uniform sampler2D gbuffer1; #ifdef _VoxelGI uniform sampler2D voxels_diffuse; uniform sampler2D voxels_specular; +#ifdef _VoxelRefract +uniform sampler2D voxels_refraction; +uniform sampler2D gbuffer_refraction; +#endif #endif #ifdef _VoxelAOvar uniform sampler2D voxels_ao; @@ -506,6 +510,5 @@ void main() { ); } #endif // _Clusters - fragColor.a = 1.0; // Mark as opaque } diff --git a/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl b/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl index eeee1feeb..363115b76 100644 --- a/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl +++ b/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl @@ -13,6 +13,10 @@ uniform sampler2D gbufferD; uniform sampler2D gbuffer0; uniform sampler2D gbufferD1; uniform sampler2D gbuffer_refraction; // ior\opacity +uniform sampler2D voxels_refraction; +uniform sampler2D voxels_specular; +uniform sampler2D voxels_diffuse; +uniform sampler2D voxels_shadows; uniform mat4 P; uniform mat3 V3; uniform vec2 cameraProj; @@ -110,5 +114,14 @@ void main() { refractionCol = clamp(refractionCol, 0.0, 1.0); refractionCol *= intensity; vec3 color = textureLod(tex, texCoord.xy, 0.0).rgb; + #ifdef _VoxelGI + vec3 diffuse = textureLod(voxels_diffuse, texCoord, 0.0).rgb; + vec3 specular = textureLod(voxels_specular, texCoord, 0.0).rgb; + color = (color + diffuse + specular) * textureLod(voxels_shadows, texCoord, 0.0).r; + #ifdef _VoxelRefract + vec3 voxelsRefr = textureLod(voxels_refraction, texCoord, 0.0).rgb; + refractionCol = (refractionCol + voxelsRefr) / 2; + #endif + #endif fragColor.rgb = mix(refractionCol, color, opac); } diff --git a/Sources/armory/renderpath/Inc.hx b/Sources/armory/renderpath/Inc.hx index 2a023a5cd..c7c1a765d 100644 --- a/Sources/armory/renderpath/Inc.hx +++ b/Sources/armory/renderpath/Inc.hx @@ -537,19 +537,6 @@ class Inc { } #end - #if (rp_voxels == "Voxel AO") - path.bindTarget("voxels_ao", "voxels_ao"); - #else - path.bindTarget("voxels_diffuse", "voxels_diffuse"); - path.bindTarget("voxels_specular", "voxels_specular"); - #if arm_voxelgi_refract - path.bindTarget("voxels_refraction", "voxels_refraction"); - #end - #end - #if arm_voxelgi_shadows - path.bindTarget("voxels_shadows", "voxels_shadows"); - #end - path.drawMeshes("translucent"); #if rp_render_to_texture @@ -561,7 +548,6 @@ class Inc { path.setTarget(""); } #end - path.bindTarget("accum", "gbuffer0"); path.bindTarget("revealage", "gbuffer1"); path.drawShader("shader_datas/translucent_resolve/translucent_resolve"); @@ -1309,9 +1295,9 @@ class Inc { kha.compute.Compute.setSampledTexture(voxel_ta6, rts.get("voxelsOut").image); kha.compute.Compute.setSampledTexture(voxel_tb6, rts.get("half").image); #if arm_deferred - kha.compute.Compute.setSampledTexture(voxel_tc6, rts.get("gbuffer0").image); + kha.compute.Compute.setSampledTexture(voxel_tc6, rts.get("gbuffer0_refr").image); #else - kha.compute.Compute.setSampledTexture(voxel_tc6, rts.get("lbuffer1").image); + kha.compute.Compute.setSampledTexture(voxel_tc6, rts.get("lbuffer1_refr").image); #end kha.compute.Compute.setSampledTexture(voxel_td6, rts.get("voxelsSDF").image); kha.compute.Compute.setTexture(voxel_te6, rts.get("voxels_refraction").image, kha.compute.Access.Write); diff --git a/Sources/armory/renderpath/RenderPathDeferred.hx b/Sources/armory/renderpath/RenderPathDeferred.hx index abb405bfc..6be210f16 100644 --- a/Sources/armory/renderpath/RenderPathDeferred.hx +++ b/Sources/armory/renderpath/RenderPathDeferred.hx @@ -21,7 +21,7 @@ class RenderPathDeferred { "gbuffer1", #if rp_gbuffer2 "gbuffer2", #end #if rp_gbuffer_emission "gbuffer_emission", #end - #if (rp_ssrefr || arm_voxelgi_refract) "gbuffer_refraction" #end + #if (arm_voxelgi_refract || rp_ssrefr) "gbuffer_refraction" #end ]); } @@ -357,7 +357,7 @@ class RenderPathDeferred { t.width = 0; t.height = 0; t.displayp = Inc.getDisplayp(); - t.depth_buffer = "refraction"; + t.depth_buffer = "main"; t.format = "RGBA64"; t.scale = Inc.getSuperSampling(); path.createRenderTarget(t); @@ -491,19 +491,6 @@ class RenderPathDeferred { } #end - #if (rp_ssrefr || arm_voxelgi_refract) - path.setTarget("gbuffer_refraction"); - #if (rp_background == "Clear") - { - path.clearTarget(-1, 1.0); - } - #else - { - path.clearTarget(null, 1.0); - } - #end - #end - #if rp_gbuffer2 { path.setTarget("gbuffer2"); @@ -511,6 +498,11 @@ class RenderPathDeferred { } #end + #if (arm_voxelgi_refract || rp_ssrefr) + path.setTarget("gbuffer_refraction"); + path.clearTarget(0xff000000); + #end + RenderPathCreator.setTargetMeshes(); #if rp_dynres @@ -674,6 +666,7 @@ class RenderPathDeferred { } } #end + // --- // Deferred light // --- @@ -723,9 +716,6 @@ class RenderPathDeferred { Inc.resolveSpecular(); path.bindTarget("voxels_diffuse", "voxels_diffuse"); path.bindTarget("voxels_specular", "voxels_specular"); - #if arm_voxelgi_refract - Inc.resolveRefraction(); - #end #end #if arm_voxelgi_shadows Inc.resolveShadows(); @@ -880,6 +870,16 @@ class RenderPathDeferred { path.drawShader("shader_datas/copy_pass/copy_pass"); path.setTarget("gbuffer1_refr", ["gbuffer0_refr", "gbuffer_refraction"]); + path.drawMeshes("refraction"); + + #if arm_voxelgi_refract + path.setTarget("half"); + path.bindTarget("_main", "texdepth"); + path.drawShader("shader_datas/downsample_depth/downsample_depth"); + Inc.resolveRefraction(); + #end + path.setTarget("tex"); + #if (rp_voxels == "Voxel AO") path.bindTarget("voxels_ao", "voxels_ao"); #else @@ -892,16 +892,13 @@ class RenderPathDeferred { #if arm_voxelgi_shadows path.bindTarget("voxels_shadows", "voxels_shadows"); #end - - path.drawMeshes("refraction"); - - path.setTarget("tex"); path.bindTarget("refr", "tex1"); path.bindTarget("gbuffer1_refr", "tex"); path.bindTarget("_main", "gbufferD"); path.bindTarget("gbufferD1", "gbufferD1"); path.bindTarget("gbuffer0_refr", "gbuffer0"); path.bindTarget("gbuffer_refraction", "gbuffer_refraction"); + path.drawShader("shader_datas/ssrefr_pass/ssrefr_pass"); } } diff --git a/blender/arm/material/make_mesh.py b/blender/arm/material/make_mesh.py index 20bd5f265..2d9ae3ec5 100644 --- a/blender/arm/material/make_mesh.py +++ b/blender/arm/material/make_mesh.py @@ -279,10 +279,7 @@ def make_deferred(con_mesh, rpasses): frag.write('#endif') if '_SSRefraction' in wrd.world_defs or '_VoxelRefract' in wrd.world_defs: - if parse_opacity: - frag.write('fragColor[GBUF_IDX_REFRACTION] = vec4(ior, opacity, 0.0, 0.0);') - else: - frag.write('fragColor[GBUF_IDX_REFRACTION] = vec4(1.0, 1.0, 0.0, 0.0);') + frag.write('fragColor[GBUF_IDX_REFRACTION] = vec4(1.0, 1.0, 0.0, 0.0);') return con_mesh @@ -560,10 +557,7 @@ def make_forward(con_mesh): frag.write('fragColor[0] = vec4(direct + indirect, packFloat2(occlusion, specular));') frag.write('fragColor[1] = vec4(n.xy, roughness, metallic);') if rpdat.rp_ss_refraction or rpdat.arm_voxelgi_refract: - if parse_opacity: - frag.write(f'fragColor[2] = vec4(1.0, 1.0, 0.0, 0.0);') - else: - frag.write(f'fragColor[2] = vec4(ior, opacity, 0.0, 0.0);') + frag.write(f'fragColor[2] = vec4(1.0, 1.0, 0.0, 0.0);') else: frag.add_out('vec4 fragColor[1]') frag.write('fragColor[0] = vec4(direct + indirect, 1.0);') @@ -674,15 +668,13 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False): frag.write('vec3 indirect = envl;') if '_VoxelAOvar' in wrd.world_defs: - frag.add_uniform("sampler2D voxels_ao"); + frag.add_include("std/conetrace.glsl") + frag.add_uniform("sampler3D voxels") + if '_VoxelShadow' in wrd.world_defs: + frag.add_uniform("sampler3D voxelsSDF") + frag.add_uniform('float clipmaps[10 * voxelgiClipmapCount]', '_clipmaps'); frag.write('indirect *= textureLod(voxels_ao, gl_FragCoord.xy, 0.0).r;') - if '_VoxelGI' in wrd.world_defs: - frag.add_uniform("sampler2D voxels_diffuse") - frag.add_uniform("sampler2D voxels_specular") - frag.write("indirect = textureLod(voxels_diffuse, gl_FragCoord.xy, 0.0).rgb * albedo * voxelgiDiff;") - frag.write("indirect += textureLod(voxels_specular, gl_FragCoord.xy, 0.0).rgb * specular * voxelgiRefl;") - frag.write('vec3 direct = vec3(0.0);') if '_Sun' in wrd.world_defs: @@ -765,10 +757,6 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False): frag.write('direct = vec3(0.0);') frag.write('indirect += emissionCol;') - if '_VoxelRefract' in wrd.world_defs and parse_opacity: - frag.add_uniform("sampler2D voxels_refraction"); - frag.write('direct = mix(textureLod(voxels_refraction, gl_FragCoord.xy, 0.0).rgb * voxelgiRefr, direct, opacity);') - frag.write('indirect = mix(textureLod(voxels_refraction, gl_FragCoord.xy, 0.0).rgb * voxelgiRefr, indirect, opacity);') def _write_material_attribs_default(frag: shader.Shader, parse_opacity: bool): frag.write('vec3 basecol;') diff --git a/blender/arm/material/make_refraction_buffer.py b/blender/arm/material/make_refraction_buffer.py index 31002055f..666bcd52a 100644 --- a/blender/arm/material/make_refraction_buffer.py +++ b/blender/arm/material/make_refraction_buffer.py @@ -3,6 +3,7 @@ import arm import arm.material.cycles as cycles import arm.material.mat_state as mat_state +import arm.material.mat_utils as mat_utils import arm.material.make_mesh as make_mesh import arm.material.make_finalize as make_finalize import arm.assets as assets @@ -19,7 +20,13 @@ def make(context_id): con_refraction_buffer = mat_state.data.add_context({ 'name': context_id, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise' }) - make_mesh.make_base(con_refraction_buffer, True) + + arm_discard = mat_state.material.arm_discard + blend = mat_state.material.arm_blending + is_transluc = mat_utils.is_transluc(mat_state.material) + parse_opacity = (blend and is_transluc) or arm_discard + + make_mesh.make_base(con_refraction_buffer, parse_opacity) vert = con_refraction_buffer.vert frag = con_refraction_buffer.frag @@ -34,7 +41,11 @@ def make(context_id): wrd = bpy.data.worlds['Arm'] - frag.write('fragColor = vec4(ior, opacity, 0.0, 0.0);') + if parse_opacity: + frag.write('fragColor = vec4(ior, opacity, 0.0, 0.0);') + else: + frag.write('fragColor = vec4(1.0, 1.0, 0.0, 0.0);') + make_finalize.make(con_refraction_buffer) # assets.vs_equal(con_refract, assets.shader_cons['transluc_vert']) # shader_cons has no transluc yet diff --git a/blender/arm/material/make_shader.py b/blender/arm/material/make_shader.py index 1ee080793..4126ff663 100644 --- a/blender/arm/material/make_shader.py +++ b/blender/arm/material/make_shader.py @@ -18,7 +18,6 @@ import arm.material.make_transluc as make_transluc import arm.material.make_refract as make_refract import arm.material.make_voxel as make_voxel -import arm.material.make_refraction_buffer as make_refraction_buffer import arm.material.mat_state as mat_state import arm.material.mat_utils as mat_utils from arm.material.shader import Shader, ShaderContext, ShaderData