diff --git a/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl b/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl index 3505cc9e0..a13bfb109 100644 --- a/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl +++ b/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl @@ -79,7 +79,7 @@ void main() { fragColor.rgb = textureLod(tex, texCoord, 0.0).rgb; return; } - if (d == 1.0 || d == 0.0 || ior == 1.0) { + if (d == 0.0) { fragColor.rgb = textureLod(tex1, texCoord, 0.0).rgb; return; } @@ -98,7 +98,15 @@ void main() { vec3 dir = refracted * (1.0 - rand(texCoord) * ss_refractionJitter * roughness) * 2.0; vec4 coords = rayCast(dir); + vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy); + float screenEdgeFactor = clamp(1.0 - (deltaCoords.x + deltaCoords.y), 0.0, 1.0); + + float refractivity = 1.0 - roughness; + float intensity = pow(refractivity, ss_refractionFalloffExp) * screenEdgeFactor * clamp(-refracted.z, 0.0, 1.0) * clamp((length(viewPos - hitCoord)), 0.0, 1.0) * coords.w; + + intensity = clamp(intensity, 0.0, 1.0); + vec3 refractionCol = textureLod(tex1, coords.xy, 0.0).rgb; vec3 color = textureLod(tex, texCoord.xy, 0.0).rgb; - fragColor.rgb = mix(refractionCol, color, opac); + fragColor.rgb = mix(refractionCol * intensity, color, opac); } diff --git a/Shaders/std/conetrace.glsl b/Shaders/std/conetrace.glsl index ea93159d7..d78d2a9d1 100644 --- a/Shaders/std/conetrace.glsl +++ b/Shaders/std/conetrace.glsl @@ -169,7 +169,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) { - vec3 specularDir = normalize(reflect(-viewDir, normal)); + vec3 specularDir = reflect(-viewDir, normal); vec3 P = origin + specularDir * (BayerMatrix8[int(pixel.x) % 8][int(pixel.y) % 8] - 0.5) * voxelgiStep; vec4 amount = traceCone(voxels, voxelsSDF, P, normal, specularDir, 0, true, roughness, voxelgiStep, clipmaps); @@ -181,7 +181,7 @@ vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels, 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 float transmittance = 1.0; - vec3 refractionDir = refract(viewDir, normal, 1.0 / ior); + vec3 refractionDir = refract(-viewDir, normal, 1.0 / ior); vec3 P = origin + refractionDir * (BayerMatrix8[int(pixel.x) % 8][int(pixel.y) % 8] - 0.5) * voxelgiStep; vec4 amount = transmittance * traceCone(voxels, voxelsSDF, P, normal, refractionDir, 0, true, roughness, voxelgiStep, clipmaps); @@ -280,10 +280,11 @@ float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const v aniso_direction.z > 0.0 ? 4 : 5 ) / (6 + DIFFUSE_CONE_COUNT); vec3 direction_weight = abs(dir); + float coneCoefficient = 2.0 * tan(aperture * 0.5); - while (sampleCol < 1.0 && dist < MAX_DISTANCE * 100 && clipmap_index0 < voxelgiClipmapCount) { + while (sampleCol < 1.0 && dist < MAX_DISTANCE && clipmap_index0 < voxelgiClipmapCount) { float mipSample = 0.0; - float diam = max(voxelSize0, dist * 2.0 * tan(aperture * 0.5)); + float diam = max(voxelSize0, dist * coneCoefficient); float lod = clamp(log2(diam / voxelSize0), clipmap_index0, voxelgiClipmapCount - 1); float clipmap_index = floor(lod); float clipmap_blend = fract(lod); diff --git a/Shaders/std/light.glsl b/Shaders/std/light.glsl index b08a2f3fd..064dc2a18 100644 --- a/Shaders/std/light.glsl +++ b/Shaders/std/light.glsl @@ -7,9 +7,6 @@ #ifdef _ShadowMap #include "std/shadows.glsl" #endif -#ifdef _VoxelShadow -//!uniform sampler2D voxels_shadows; -#endif #ifdef _LTC #include "std/ltc.glsl" #endif @@ -134,10 +131,6 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co direct *= traceShadowSS(l, p, gbufferD, invVP, eye); #endif - #ifdef _VoxelShadow - direct *= textureLod(voxels_shadows, texCoord, 0.0).r * voxelgiShad; //TODO: Trace shadows directly for transparent objects. - #endif - #ifdef _LTC #ifdef _ShadowMap if (receiveShadow) { diff --git a/Shaders/voxel_light/voxel_light.comp.glsl b/Shaders/voxel_light/voxel_light.comp.glsl index 15e418e81..73ff1c2c4 100644 --- a/Shaders/voxel_light/voxel_light.comp.glsl +++ b/Shaders/voxel_light/voxel_light.comp.glsl @@ -6,6 +6,9 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in; #include "std/math.glsl" #include "std/gbuffer.glsl" #include "std/imageatomic.glsl" +#ifdef _VoxelShadow +#include "std/conetrace.glsl" +#endif uniform vec3 lightPos; uniform vec3 lightColor; @@ -28,6 +31,8 @@ uniform int clipmapLevel; uniform layout(r32ui) uimage3D voxelsLight; uniform layout(r32ui) uimage3D voxels; +uniform sampler3D voxelsSampler; +uniform sampler3D voxelsSDFSampler; #ifdef _ShadowMap uniform sampler2DShadow shadowMap; @@ -98,6 +103,12 @@ void main() { if (lightType == 0) { l = lightDir; visibility = vec3(1.0); } else { l = normalize(lp); visibility = vec3(attenuate(distance(P, lightPos))); } + vec3 N = vec3(0.0); + N.r = float(imageLoad(voxels, dst + ivec3(0, 0, voxelgiResolution.x * 7))) / 255; + N.g = float(imageLoad(voxels, dst + ivec3(0, 0, voxelgiResolution.x * 8))) / 255; + N /= 2; + vec3 wnormal = decode_oct(N.rg * 2 - 1); + // float dotNL = max(dot(wnormal, l), 0.0); // if (dotNL == 0.0) return; @@ -136,6 +147,10 @@ void main() { } } + const vec2 pixel = gl_GlobalInvocationID.xy; + #ifdef _VoxelShadow + visibility *= traceShadow(P, wnormal, voxelsSampler, voxelsSDFSampler, lp, clipmaps, pixel); + #endif vec3 light = visibility * lightColor; imageAtomicAdd(voxelsLight, dst, uint(light.r * 255)); diff --git a/Shaders/voxel_offsetprev/voxel_offsetprev.comp.glsl b/Shaders/voxel_offsetprev/voxel_offsetprev.comp.glsl index bf6ac52d3..b93e46fda 100644 --- a/Shaders/voxel_offsetprev/voxel_offsetprev.comp.glsl +++ b/Shaders/voxel_offsetprev/voxel_offsetprev.comp.glsl @@ -33,8 +33,8 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in; uniform layout(rgba8) image3D voxelsB; uniform layout(rgba8) image3D voxelsOut; #else -uniform layout(r16) image3D voxelsB; -uniform layout(r16) image3D voxelsOut; +uniform layout(r8) image3D voxelsB; +uniform layout(r8) image3D voxelsOut; #endif uniform int clipmapLevel; diff --git a/Shaders/voxel_sdf_jumpflood/voxel_sdf_jumpflood.comp.glsl b/Shaders/voxel_sdf_jumpflood/voxel_sdf_jumpflood.comp.glsl index 5e6a0ea72..d224df667 100644 --- a/Shaders/voxel_sdf_jumpflood/voxel_sdf_jumpflood.comp.glsl +++ b/Shaders/voxel_sdf_jumpflood/voxel_sdf_jumpflood.comp.glsl @@ -23,8 +23,8 @@ THE SOFTWARE. #include "compiled.inc" -uniform layout(r8) image3D input_sdf; -uniform layout(r8) image3D output_sdf; +uniform layout(r16) image3D input_sdf; +uniform layout(r16) image3D output_sdf; uniform float jump_size; uniform int clipmapLevel; diff --git a/Shaders/voxel_temporal/voxel_temporal.comp.glsl b/Shaders/voxel_temporal/voxel_temporal.comp.glsl index f4538bc88..6bedc030f 100644 --- a/Shaders/voxel_temporal/voxel_temporal.comp.glsl +++ b/Shaders/voxel_temporal/voxel_temporal.comp.glsl @@ -46,15 +46,15 @@ uniform layout(r32ui) uimage3D voxels; uniform layout(r32ui) uimage3D voxelsLight; uniform layout(rgba8) image3D voxelsB; uniform layout(rgba8) image3D voxelsOut; -uniform layout(r8) image3D SDF; +uniform layout(r16) image3D SDF; #else #ifdef _VoxelAOvar #ifdef _VoxelShadow -uniform layout(r8) image3D SDF; +uniform layout(r16) image3D SDF; #endif uniform layout(r32ui) uimage3D voxels; -uniform layout(r16) image3D voxelsB; -uniform layout(r16) image3D voxelsOut; +uniform layout(r8) image3D voxelsB; +uniform layout(r8) image3D voxelsOut; #endif #endif @@ -124,7 +124,6 @@ void main() { envl.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 10))) / 255; envl.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 11))) / 255; envl /= 3; - #ifdef _HOSEK envl *= 100; #endif diff --git a/Sources/armory/renderpath/Inc.hx b/Sources/armory/renderpath/Inc.hx index df1c59de2..d81798448 100644 --- a/Sources/armory/renderpath/Inc.hx +++ b/Sources/armory/renderpath/Inc.hx @@ -106,6 +106,9 @@ class Inc { #if (rp_voxels == "Voxel GI") static var voxel_sh5:kha.compute.Shader = null; static var voxel_ta5:kha.compute.TextureUnit; + static var voxel_te5:kha.compute.TextureUnit; + static var voxel_tf5:kha.compute.TextureUnit; + static var voxel_tg5:kha.compute.TextureUnit; static var voxel_ca5:kha.compute.ConstantLocation; static var voxel_cb5:kha.compute.ConstantLocation; static var voxel_cc5:kha.compute.ConstantLocation; @@ -588,7 +591,7 @@ class Inc { } else { if (t.name == "voxelsSDF" || t.name == "voxelsSDFtmp") { - t.format = "R8"; + t.format = "R16"; t.width = res; t.height = res * Main.voxelgiClipmapCount; t.depth = res; @@ -597,7 +600,7 @@ class Inc { #if (rp_voxels == "Voxel AO") { if (t.name == "voxelsOut" || t.name == "voxelsOutB") { - t.format = "R16"; + t.format = "R8"; t.width = res * (6 + 16); t.height = res * Main.voxelgiClipmapCount; t.depth = res; @@ -835,6 +838,9 @@ class Inc { { voxel_sh5 = path.getComputeShader("voxel_light"); voxel_ta5 = voxel_sh5.getTextureUnit("voxelsLight"); + voxel_te5 = voxel_sh5.getTextureUnit("voxels"); + voxel_tf5 = voxel_sh5.getTextureUnit("voxelsSampler"); + voxel_tg5 = voxel_sh5.getTextureUnit("voxelsSDFSampler"); voxel_ca5 = voxel_sh5.getConstantLocation("clipmaps"); voxel_cb5 = voxel_sh5.getConstantLocation("clipmapLevel"); @@ -1398,6 +1404,9 @@ class Inc { kha.compute.Compute.setShader(voxel_sh5); kha.compute.Compute.setTexture(voxel_ta5, rts.get("voxelsLight").image, kha.compute.Access.Write); + kha.compute.Compute.setTexture(voxel_te5, rts.get("voxels").image, kha.compute.Access.Read); + kha.compute.Compute.setSampledTexture(voxel_tf5, rts.get("voxelsOut").image); + kha.compute.Compute.setSampledTexture(voxel_tg5, rts.get("voxelsSDF").image); var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10); for (i in 0...Main.voxelgiClipmapCount) { diff --git a/Sources/armory/renderpath/RenderPathDeferred.hx b/Sources/armory/renderpath/RenderPathDeferred.hx index d9c58713f..40df7ab3d 100644 --- a/Sources/armory/renderpath/RenderPathDeferred.hx +++ b/Sources/armory/renderpath/RenderPathDeferred.hx @@ -466,6 +466,13 @@ class RenderPathDeferred { } #end + #if rp_ssrefr + { + path.setTarget("gbuffer_refraction"); + path.clearTarget(0xffffff00); + } + #end + RenderPathCreator.setTargetMeshes(); #if rp_dynres @@ -606,7 +613,7 @@ class RenderPathDeferred { Inc.computeVoxelsTemporal(); - #if (arm_voxelgi_shadows || (rp_voxels == "Voxel GI")) + #if (arm_voxelgi_shadows || rp_voxels == "Voxel GI") Inc.computeVoxelsSDF(); #end diff --git a/Sources/armory/renderpath/RenderPathForward.hx b/Sources/armory/renderpath/RenderPathForward.hx index ebafc7c63..b906994c5 100644 --- a/Sources/armory/renderpath/RenderPathForward.hx +++ b/Sources/armory/renderpath/RenderPathForward.hx @@ -449,6 +449,13 @@ class RenderPathForward { } #end + #if rp_ssrefr + { + path.setTarget("gbuffer_refraction"); + path.clearTarget(0xffffff00); + } + #end + RenderPathCreator.setTargetMeshes(); #if rp_shadowmap diff --git a/blender/arm/material/cycles_nodes/nodes_shader.py b/blender/arm/material/cycles_nodes/nodes_shader.py index 5fa0aece0..087d06c17 100644 --- a/blender/arm/material/cycles_nodes/nodes_shader.py +++ b/blender/arm/material/cycles_nodes/nodes_shader.py @@ -244,12 +244,13 @@ def parse_bsdftranslucent(node: bpy.types.ShaderNodeBsdfTranslucent, out_socket: c.write_normal(node.inputs[1]) if state.parse_opacity: state.out_opacity = '(1.0 - {0}.r)'.format(c.parse_vector_input(node.inputs[0])) + state.out_ior = '1.0' def parse_bsdftransparent(node: bpy.types.ShaderNodeBsdfTransparent, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_opacity: state.out_opacity = '(1.0 - {0}.r)'.format(c.parse_vector_input(node.inputs[0])) - + state.out_ior = '1.0' if bpy.app.version < (4, 1, 0): def parse_bsdfvelvet(node: bpy.types.ShaderNodeBsdfVelvet, out_socket: NodeSocket, state: ParserState) -> None: diff --git a/blender/arm/material/make_mesh.py b/blender/arm/material/make_mesh.py index 8564f0c2d..9824b8f6e 100644 --- a/blender/arm/material/make_mesh.py +++ b/blender/arm/material/make_mesh.py @@ -595,9 +595,6 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False): opac = '0.9999' # 1.0 - eps frag.write('if (opacity < {0}) discard;'.format(opac)) - else: - frag.write('float opacity = 1.0;') - if blend: frag.add_out('vec4 fragColor[1]') if parse_opacity: @@ -644,7 +641,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False): if '_Rad' in wrd.world_defs: frag.add_uniform('sampler2D senvmapRadiance', link='_envmapRadiance') frag.add_uniform('int envmapNumMipmaps', link='_envmapNumMipmaps') - frag.write('vec3 reflectionWorld = reflect(-eyeDir, n);') + frag.write('vec3 reflectionWorld = reflect(-vVec, n);') frag.write('float lod = getMipFromRoughness(roughness, envmapNumMipmaps);') frag.write('vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;') @@ -696,9 +693,9 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False): if '_VoxelGI' in wrd.world_defs: if parse_opacity: - frag.write("indirect = traceDiffuse(wposition, wnormal, voxels, clipmaps).rgb * albedo * voxelgiDiff;") + frag.write("indirect = traceDiffuse(wposition, n, voxels, clipmaps).rgb * albedo * voxelgiDiff;") frag.write("if (roughness < 1.0 && specular > 0.0)") - frag.write(" indirect += traceSpecular(wposition, wnormal, voxels, voxelsSDF, eyeDir, roughness, clipmaps, texCoord).rgb * specular * voxelgiRefl;") + frag.write(" indirect += traceSpecular(wposition, n, voxels, voxelsSDF, vVec, roughness, clipmaps, gl_FragCoord.xy).rgb * specular * voxelgiRefl;") else: frag.add_uniform("sampler2D voxels_diffuse") frag.add_uniform("sampler2D voxels_specular") @@ -746,7 +743,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False): frag.write('}') # receiveShadow if '_VoxelShadow' in wrd.world_defs: if parse_opacity: - frag.write('svisibility *= traceShadow(wposition, wnormal, voxels, voxelsSDF, sunDir, clipmaps, texCoord);') + frag.write('svisibility *= traceShadow(wposition, n, voxels, voxelsSDF, sunDir, clipmaps, texCoord);') else: frag.write('svisibility *= textureLod(voxels_shadows, texCoord, 0.0).r * voxelgiShad;') frag.write('direct += (lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular) * sunCol * svisibility;') @@ -802,7 +799,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False): frag.add_uniform('sampler3D voxels') frag.add_uniform('sampler3D voxelsSDF') frag.write('if (opacity < 1.0) {') - frag.write(' vec3 refraction = traceRefraction(wposition, wnormal, voxels, voxelsSDF, eyeDir, ior, roughness, clipmaps, texCoord).rgb * voxelgiRefr;') + frag.write(' vec3 refraction = traceRefraction(wposition, n, voxels, voxelsSDF, vVec, ior, roughness, clipmaps, texCoord).rgb * voxelgiRefr;') frag.write(' indirect = mix(refraction, indirect, opacity);') frag.write(' direct = mix(refraction, direct, opacity);') frag.write('}') @@ -819,4 +816,4 @@ def _write_material_attribs_default(frag: shader.Shader, parse_opacity: bool): frag.write('vec3 emissionCol;') if parse_opacity: frag.write('float opacity;') - frag.write('float ior = 1.450;') # case shader is arm we don't get an ior + frag.write('float ior;')