Skip to content

Commit

Permalink
Merge pull request #3006 from e2002e/ss_refraction
Browse files Browse the repository at this point in the history
fix normalize issue.
  • Loading branch information
luboslenco committed Apr 1, 2024
2 parents bd1254b + a469aee commit 1b27bf2
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 134 deletions.
45 changes: 9 additions & 36 deletions Shaders/ssrefr_pass/ssrefr_pass.frag.glsl
Expand Up @@ -14,17 +14,12 @@ uniform mat4 P;
uniform mat3 V3;
uniform vec2 cameraProj;

#ifdef _CPostprocess
uniform vec3 PPComp9;
uniform vec3 PPComp10;
#endif

in vec3 viewRay;
in vec2 texCoord;
out vec4 fragColor;

vec3 hitCoord;
float d;
float depth;

const int numBinarySearchSteps = 7;
const int maxSteps = int(ceil(1.0 / ss_refractionRayStep) * ss_refractionSearchDist);
Expand All @@ -39,14 +34,12 @@ vec2 getProjectedCoord(const vec3 hit) {
return projectedCoord.xy;
}


float getDeltaDepth(const vec3 hit) {
d = textureLod(gbufferD, getProjectedCoord(hit), 0.0).r * 2.0 - 1.0;
vec3 viewPos = normalize(getPosView(viewRay, d, cameraProj));
depth = textureLod(gbufferD1, getProjectedCoord(hit), 0.0).r * 2.0 - 1.0;
vec3 viewPos = getPosView(viewRay, depth, cameraProj);
return viewPos.z - hit.z;
}


vec4 binarySearch(vec3 dir) {
float ddepth;
for (int i = 0; i < numBinarySearchSteps; i++) {
Expand All @@ -55,28 +48,17 @@ vec4 binarySearch(vec3 dir) {
ddepth = getDeltaDepth(hitCoord);
if (ddepth < 0.0) hitCoord += dir;
}
// Ugly discard of hits too far away
//using a divider of 500 doesn't work here unless the distance is set to at least 500 for a blender unit.
#ifdef _CPostprocess
if (abs(ddepth) > PPComp9.z) return vec4(texCoord.xy, 0.0, 0.0);
#else
if (abs(ddepth) > ss_refractionSearchDist) return vec4(texCoord.xy, 0.0, 0.0);
#endif
if (abs(ddepth) > ss_refractionSearchDist / 500) return vec4(0.0);
return vec4(getProjectedCoord(hitCoord), 0.0, 1.0);
}


vec4 rayCast(vec3 dir) {
float ddepth;
#ifdef _CPostprocess
dir *= PPComp9.x;
#else
dir *= ss_refractionRayStep;
#endif
dir *= ss_refractionRayStep;
for (int i = 0; i < maxSteps; i++) {
hitCoord += dir;
ddepth = getDeltaDepth(hitCoord);
if (ddepth > d) return binarySearch(dir);
if (ddepth > 0.0) return binarySearch(dir);
}
return vec4(0.0);
}
Expand All @@ -88,7 +70,7 @@ void main() {
float ior = gr.x;
float opac = gr.y;

d = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
float d = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;

if (d == 1.0 || ior == 1.0 || opac == 1.0) {
fragColor.rgb = textureLod(tex1, texCoord, 0.0).rgb;
Expand All @@ -99,30 +81,21 @@ void main() {
vec3 n;
n.z = 1.0 - abs(enc.x) - abs(enc.y);
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
n = normalize(n);

vec3 viewNormal = V3 * n;
vec3 viewPos = normalize(getPosView(viewRay, d, cameraProj));
vec3 refracted = refract(viewPos, viewNormal, 1.0 / ior);
vec3 viewPos = getPosView(viewRay, d, cameraProj);
vec3 refracted = refract(normalize(viewPos), viewNormal, 1.0 / ior);
hitCoord = viewPos;

#ifdef _CPostprocess
vec3 dir = refracted * (1.0 - rand(texCoord) * PPComp10.y * roughness) * 2.0;
#else
vec3 dir = refracted * (1.0 - rand(texCoord) * ss_refractionJitter * roughness) * 2.0;
#endif

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;

#ifdef _CPostprocess
float intensity = pow(refractivity, ss_refractionFalloffExp) * screenEdgeFactor * clamp(-refracted.z, 0.0, 1.0) * clamp((PPComp9.z - length(viewPos - hitCoord)) * (1.0 / PPComp9.z), 0.0, 1.0) * coords.w;
#else
float intensity = pow(refractivity, ss_refractionFalloffExp) * screenEdgeFactor * clamp((ss_refractionSearchDist - length(viewPos - hitCoord)) * (1.0 / ss_refractionSearchDist), 0.0, 1.0) * coords.w;
#endif

intensity = clamp(intensity, 0.0, 1.0);
vec3 refractionCol = textureLod(tex1, coords.xy, 0.0).rgb;
Expand Down
10 changes: 0 additions & 10 deletions Shaders/ssrefr_pass/ssrefr_pass.json
Expand Up @@ -29,16 +29,6 @@
{
"name": "cameraProj",
"link": "_cameraPlaneProj"
},
{
"name": "PPComp9",
"link": "_PPComp9",
"ifdef": ["_CPostprocess"]
},
{
"name": "PPComp10",
"link": "_PPComp10",
"ifdef": ["_CPostprocess"]
}
],
"vertex_shader": "../include/pass_viewray2.vert.glsl",
Expand Down
80 changes: 4 additions & 76 deletions Sources/armory/renderpath/RenderPathDeferred.hx
Expand Up @@ -344,7 +344,7 @@ class RenderPathDeferred {
t.scale = Inc.getSuperSampling();
path.createRenderTarget(t);

//holds colors before refractive meshes are drawn
// holds colors before refractive meshes are drawn
var t = new RenderTargetRaw();
t.name = "refr";
t.width = 0;
Expand All @@ -355,13 +355,13 @@ class RenderPathDeferred {
t.depth_buffer = "main";
path.createRenderTarget(t);

//holds background depth
// holds background depth
var t = new RenderTargetRaw();
t.name = "gbufferD1";
t.width = 0;
t.height = 0;
t.displayp = Inc.getDisplayp();
t.format = "DEPTH16";
t.format = "R32";
t.scale = Inc.getSuperSampling();
path.createRenderTarget(t);
}
Expand Down Expand Up @@ -763,10 +763,6 @@ class RenderPathDeferred {
{
if (armory.data.Config.raw.rp_ssrefr != false)
{
#if (!kha_opengl)
path.setDepthFrom("tex", "gbuffer1"); // Unbind depth so we can read it
#end

//save depth
path.setTarget("gbufferD1");
path.bindTarget("_main", "tex");
Expand All @@ -777,73 +773,9 @@ class RenderPathDeferred {
path.bindTarget("tex", "tex");
path.drawShader("shader_datas/copy_pass/copy_pass");

RenderPathCreator.setTargetMeshes();
path.setTarget("tex", ["gbuffer0", "gbuffer_refraction"]);
path.drawMeshes("refraction");

path.setTarget("tex");
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbuffer0", "gbuffer0");
path.bindTarget("gbuffer1", "gbuffer1");

#if rp_gbuffer2
{
path.bindTarget("gbuffer2", "gbuffer2");
}
#end

#if rp_gbuffer_emission
{
path.bindTarget("gbuffer_emission", "gbufferEmission");
}
#end

#if (rp_ssgi != "Off")
{
if (armory.data.Config.raw.rp_ssgi != false) {
path.bindTarget("singlea", "ssaotex");
}
else {
path.bindTarget("empty_white", "ssaotex");
}
}
#end

var voxelao_pass = false;
#if rp_voxelao
if (armory.data.Config.raw.rp_voxels != false)
{
#if arm_config
voxelao_pass = true;
#end
path.bindTarget(voxels, "voxels");
#if arm_voxelgi_temporal
{
path.bindTarget(voxelsLast, "voxelsLast");
}
#end
}
#end

#if rp_shadowmap
{
#if arm_shadowmap_atlas
Inc.bindShadowMapAtlas();
#else
Inc.bindShadowMap();
#end
}
#end

#if rp_material_solid
path.drawShader("shader_datas/deferred_light_solid/deferred_light");
#elseif rp_material_mobile
path.drawShader("shader_datas/deferred_light_mobile/deferred_light");
#else
voxelao_pass ?
path.drawShader("shader_datas/deferred_light/deferred_light_VoxelAOvar") :
path.drawShader("shader_datas/deferred_light/deferred_light");
#end

path.setTarget("tex");
path.bindTarget("refr", "tex1");
path.bindTarget("tex", "tex");
Expand All @@ -852,10 +784,6 @@ class RenderPathDeferred {
path.bindTarget("gbuffer0", "gbuffer0");
path.bindTarget("gbuffer_refraction", "gbuffer_refraction");
path.drawShader("shader_datas/ssrefr_pass/ssrefr_pass");

#if (!kha_opengl)
path.setDepthFrom("tex", "gbuffer0");
#end
}
}
#end
Expand Down
4 changes: 2 additions & 2 deletions Sources/armory/renderpath/RenderPathForward.hx
Expand Up @@ -111,7 +111,7 @@ class RenderPathForward {
t.name = "lbuffer1";
t.width = 0;
t.height = 0;
t.format = "RGBA64";
t.format = Inc.getHdrFormat();
t.displayp = Inc.getDisplayp();
t.scale = Inc.getSuperSampling();
path.createRenderTarget(t);
Expand Down Expand Up @@ -147,7 +147,7 @@ class RenderPathForward {
t.width = 0;
t.height = 0;
t.displayp = Inc.getDisplayp();
t.format = "DEPTH16";
t.format = "R32";
t.scale = Inc.getSuperSampling();
path.createRenderTarget(t);
}
Expand Down
2 changes: 1 addition & 1 deletion blender/arm/material/cycles_nodes/nodes_shader.py
Expand Up @@ -158,7 +158,7 @@ def parse_bsdfglass(node: bpy.types.ShaderNodeBsdfGlass, out_socket: NodeSocket,
c.write_normal(node.inputs[3])
state.out_roughness = c.parse_value_input(node.inputs[1])
if state.parse_opacity:
state.out_opacity = '0.5' # for refraction mix(refraction, color)
state.out_opacity = '0.0'
state.out_ior = c.parse_value_input(node.inputs[2])


Expand Down
10 changes: 5 additions & 5 deletions blender/arm/material/make_mesh.py
Expand Up @@ -195,15 +195,15 @@ def make_deferred(con_mesh, rpasses):
rpdat = arm.utils.get_rp()

arm_discard = mat_state.material.arm_discard
parse_opacity = arm_discard or 'translucent' in rpasses or 'refraction' in rpasses
parse_opacity = arm_discard or 'translucent'

make_base(con_mesh, parse_opacity=parse_opacity)

frag = con_mesh.frag
vert = con_mesh.vert
tese = con_mesh.tese

if parse_opacity and not 'refraction' in rpasses:
if parse_opacity:
if arm_discard:
opac = mat_state.material.arm_discard_opacity
else:
Expand Down Expand Up @@ -547,9 +547,9 @@ def make_forward(con_mesh):
if not blend:
mrt = 0 # mrt: multiple render targets
if rpdat.rp_ssr:
mrt += 1
mrt = 1
if rpdat.rp_ss_refraction:
mrt += 1
mrt = 2
if mrt != 0:
# Store light gbuffer for post-processing
frag.add_out(f'vec4 fragColor[{mrt}+1]')
Expand Down Expand Up @@ -590,7 +590,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag = con_mesh.frag
tese = con_mesh.tese

if (parse_opacity or arm_discard) and not '_SSRefraction' in wrd.world_defs:
if parse_opacity or arm_discard:
if arm_discard or blend:
opac = mat_state.material.arm_discard_opacity
frag.write('if (opacity < {0}) discard;'.format(opac))
Expand Down
48 changes: 48 additions & 0 deletions blender/arm/material/make_refract.py
@@ -0,0 +1,48 @@
import bpy

import arm
import arm.material.cycles as cycles
import arm.material.mat_state as mat_state
import arm.material.make_mesh as make_mesh
import arm.material.make_finalize as make_finalize
import arm.assets as assets

if arm.is_reload(__name__):
cycles = arm.reload_module(cycles)
mat_state = arm.reload_module(mat_state)
make_mesh = arm.reload_module(make_mesh)
make_finalize = arm.reload_module(make_finalize)
assets = arm.reload_module(assets)
else:
arm.enable_reload(__name__)


def make(context_id):
con_refract = mat_state.data.add_context({ 'name': context_id, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise' })

make_mesh.make_forward_base(con_refract, parse_opacity=True, transluc_pass=True)

vert = con_refract.vert
frag = con_refract.frag
tese = con_refract.tese

frag.add_include('std/gbuffer.glsl')
frag.add_out('vec4 fragColor[3]')

# Remove fragColor = ...;
frag.main = frag.main[:frag.main.rfind('fragColor')]
frag.write('\n')

wrd = bpy.data.worlds['Arm']

frag.write('n /= (abs(n.x) + abs(n.y) + abs(n.z));')
frag.write('n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);')
frag.write('fragColor[0] = vec4(direct + indirect, packFloat2(occlusion, specular));')
frag.write('fragColor[1] = vec4(n.xy, roughness, metallic);')
frag.write('fragColor[2] = vec4(ior, opacity, 0.0, 0.0);')
make_finalize.make(con_refract)

# 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_refract
3 changes: 2 additions & 1 deletion blender/arm/material/make_shader.py
Expand Up @@ -16,6 +16,7 @@
import arm.material.make_mesh as make_mesh
import arm.material.make_overlay as make_overlay
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.mat_state as mat_state
import arm.material.mat_utils as mat_utils
Expand Down Expand Up @@ -96,7 +97,7 @@ def build(material: Material, mat_users: Dict[Material, List[Object]], mat_armus
con = make_transluc.make(rp)

elif rp == 'refraction':
con = make_mesh.make(rp, rpasses)
con = make_refract.make(rp)

elif rp == 'overlay':
con = make_overlay.make(rp)
Expand Down
6 changes: 3 additions & 3 deletions blender/arm/material/mat_utils.py
Expand Up @@ -42,14 +42,14 @@ def get_rpasses(material):
ar.append('decal')
elif material.arm_overlay:
ar.append('overlay')
elif is_transluc(material) and not material.arm_discard and not material.arm_blending and rpdat.rp_ss_refraction:
ar.append('refraction')
else:
ar.append('mesh')
for con in add_mesh_contexts:
ar.append(con)
if is_transluc(material) and not material.arm_discard and rpdat.rp_translucency_state != 'Off' and not material.arm_blending:
if is_transluc(material) and not material.arm_discard and rpdat.rp_translucency_state != 'Off' and not material.arm_blending and not rpdat.rp_ss_refraction:
ar.append('translucent')
elif is_transluc(material) and not material.arm_discard and not material.arm_blending and rpdat.rp_ss_refraction:
ar.append('refraction')
if rpdat.rp_voxelao and has_voxels:
ar.append('voxel')
if rpdat.rp_renderer == 'Forward' and rpdat.rp_depthprepass and not material.arm_blending and not material.arm_particle_flag:
Expand Down

0 comments on commit 1b27bf2

Please sign in to comment.