Transluc + sss fixes

This commit is contained in:
luboslenco 2019-01-24 12:47:51 +01:00
parent 89cad4e25e
commit 9ba53d172d
15 changed files with 71 additions and 63 deletions

View File

@ -345,28 +345,28 @@ void main() {
#endif
fragColor.rgb += sdirect * svisibility * sunCol;
#endif
// #ifdef _Hair // Aniso
// if (textureLod(gbuffer2, texCoord, 0.0).a == 2) {
// #ifdef _Hair // Aniso
// if (g0.a == 2.0) {
// const float shinyParallel = metrough.y;
// const float shinyPerpendicular = 0.1;
// const vec3 v = vec3(0.99146, 0.11664, 0.05832);
// vec3 T = abs(dot(n, v)) > 0.99999 ? cross(n, vec3(0.0, 1.0, 0.0)) : cross(n, v);
// fragColor.rgb = orenNayarDiffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH) + wardSpecular(n, h, dotNL, dotNV, dotNH, T, shinyParallel, shinyPerpendicular) * spec;
// }
// else fragColor.rgb = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH) * spec;
// #endif
// #endif
#ifdef _SSS
if (textureLod(gbuffer2, texCoord, 0.0).a == 2) {
#ifdef _SSS
if (g0.a == 2.0) {
#ifdef _CSM
int casi, casindex;
mat4 LWVP = getCascadeMat(distance(eye, p), casi, casindex);
#endif
fragColor.rgb += fragColor.rgb * SSSSTransmittance(LWVP, p, n, l, lightPlane.y, shadowMap);
fragColor.rgb += fragColor.rgb * SSSSTransmittance(LWVP, p, n, sunDir, lightPlane.y, shadowMap);
}
#endif
#endif
#endif // _Sun
#ifdef _SinglePoint
fragColor.rgb += sampleLight(
@ -378,6 +378,11 @@ void main() {
, true, spotData.x, spotData.y, spotDir
#endif
);
#ifdef _Spot
#ifdef _SSS
if (g0.a == 2.0) fragColor.rgb += fragColor.rgb * SSSSTransmittance(LWVPSpot0, p, n, normalize(pointPos - p), lightPlane.y, shadowMapSpot[0]);
#endif
#endif
#endif
#ifdef _Clusters

View File

@ -38,7 +38,7 @@
#include "compiled.inc"
uniform sampler2D gbufferD;
uniform sampler2D gbuffer2;
uniform sampler2D gbuffer0;
uniform sampler2D tex;
uniform vec2 dir;
@ -85,6 +85,8 @@ vec4 SSSSBlur() {
vec2 finalStep = sssWidth * scale * dir;
// finalStep *= 1.0;//SSSS_STREGTH_SOURCE; // Modulate it using the alpha channel.
finalStep *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3.
finalStep *= 0.05; //
// Accumulate the center sample:
vec4 colorBlurred = colorM;
@ -111,7 +113,7 @@ vec4 SSSSBlur() {
void main() {
// SSS only masked objects
if (textureLod(gbuffer2, texCoord, 0.0).a == 2) {
if (textureLod(gbuffer0, texCoord, 0.0).a == 2.0) {
fragColor = clamp(SSSSBlur(), 0.0, 1.0);
}
else {

View File

@ -15,6 +15,7 @@ vec3 getNor(const vec2 enc) {
vec3 getPosView(const vec3 viewRay, const float depth, const vec2 cameraProj) {
float linearDepth = cameraProj.y / (cameraProj.x - depth);
// float linearDepth = cameraProj.y / ((depth * 0.5 + 0.5) - cameraProj.x);
return viewRay * linearDepth;
}

View File

@ -1,11 +1,11 @@
// Separable SSS Transmittance Function, ref to sss_pass
vec3 SSSSTransmittance(mat4 LWVP, vec3 p, vec3 n, vec3 l, float lightFar, sampler2D shadowMap) {
vec3 SSSSTransmittance(mat4 LWVP, vec3 p, vec3 n, vec3 l, float lightFar, sampler2DShadow shadowMap) {
const float translucency = 1.0;
vec4 shrinkedPos = vec4(p - 0.005 * n, 1.0);
vec4 shadowPos = LWVP * shrinkedPos;
float scale = 8.25 * (1.0 - translucency) / (sssWidth / 10.0);
float d1 = texture(shadowMap, shadowPos.xy / shadowPos.w).r; // 'd1' has a range of 0..1
float d1 = texture(shadowMap, vec3(shadowPos.xy / shadowPos.w, shadowPos.z)).r; // 'd1' has a range of 0..1
float d2 = shadowPos.z; // 'd2' has a range of 0..'lightFarPlane'
d1 *= lightFar; // So we scale 'd1' accordingly:
float d = scale * abs(d1 - d2);

View File

@ -11,10 +11,6 @@ uniform vec2 texSize;
in vec2 texCoord;
out vec4 fragColor;
float maxComponent(vec4 v) {
return max(max(max(v.x, v.y), v.z), v.w);
}
void main() {
vec4 accum = texelFetch(gbuffer0, ivec2(texCoord * texSize), 0);
float revealage = 1.0 - accum.a;
@ -22,13 +18,8 @@ void main() {
// Save the blending and color texture fetch cost
if (revealage == 0.0) {
discard;
return;
}
if (isinf(maxComponent(abs(accum)))) {
accum.rgb = vec3(revealage);
}
float f = texelFetch(gbuffer1, ivec2(texCoord * texSize), 0).r;
fragColor = vec4(accum.rgb / clamp(f, 1e-4, 5e4), revealage);
fragColor = vec4(accum.rgb / clamp(f, 0.0001, 5000), revealage);
}

View File

@ -614,9 +614,6 @@ class RenderPathDeferred {
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbuffer0", "gbuffer0");
path.bindTarget("gbuffer1", "gbuffer1");
// #if rp_gbuffer2_direct
// path.bindTarget("gbuffer2", "gbuffer2");
// #end
#if (rp_ssgi != "Off")
{
if (armory.data.Config.raw.rp_ssgi != false) {
@ -786,14 +783,13 @@ class RenderPathDeferred {
path.setTarget("buf");
path.bindTarget("tex", "tex");
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbuffer2", "gbuffer2");
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/sss_pass/sss_pass_x");
path.setTarget("tex");
// TODO: can not bind tex
path.bindTarget("tex", "tex");
path.bindTarget("buf", "tex");
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbuffer2", "gbuffer2");
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/sss_pass/sss_pass_y");
}
#end

View File

@ -348,14 +348,10 @@ def build():
# else:
# log.warn('Disabling soft shadows - "Armory Render Path - Cascades" requires to be set to 1 for now')
gbuffer2_direct = '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs
gbuffer2 = '_Veloc' in wrd.world_defs or gbuffer2_direct
gbuffer2 = '_Veloc' in wrd.world_defs
if gbuffer2:
assets.add_khafile_def('rp_gbuffer2')
wrd.world_defs += '_gbuffer2'
if gbuffer2_direct:
assets.add_khafile_def('rp_gbuffer2_direct')
wrd.world_defs += '_gbuffer2direct'
if callback != None:
callback()

View File

@ -86,11 +86,13 @@ def parse(material, mat_data, mat_users, mat_armusers):
sss_node = arm.node_utils.get_node_armorypbr(material.node_tree)
if sss_node != None and sss_node.outputs[0].is_linked and (sss_node.inputs[8].is_linked or sss_node.inputs[8].default_value != 0.0):
sss = True
const = {}
const['name'] = 'materialID'
if sss:
const = {}
const['name'] = 'materialID'
const['int'] = 2
c['bind_constants'].append(const)
else:
const['int'] = 0
c['bind_constants'].append(const)
# TODO: Mesh only material batching
if wrd.arm_batch_materials:

View File

@ -157,7 +157,10 @@ def make(context_id, rpasses, shadowmap=False):
vert.write('vcolor = col.rgb;')
if parse_opacity:
opac = mat_state.material.arm_discard_opacity_shadows
if mat_state.material.arm_discard:
opac = mat_state.material.arm_discard_opacity_shadows
else:
opac = '1.0'
frag.write('if (opacity < {0}) discard;'.format(opac))
make_finalize.make(con_depth)

View File

@ -15,7 +15,7 @@ write_material_attribs = None
write_material_attribs_post = None
write_vertex_attribs = None
def make(context_id):
def make(context_id, rpasses):
rpdat = arm.utils.get_rp()
rid = rpdat.rp_renderer
@ -53,7 +53,7 @@ def make(context_id):
else:
make_forward(con_mesh)
elif rid == 'Deferred':
make_deferred(con_mesh)
make_deferred(con_mesh, rpasses)
elif rid == 'Raytracer':
make_raytracer(con_mesh)
@ -183,12 +183,12 @@ def make_base(con_mesh, parse_opacity):
sh.write('wposition += wnormal * disp * 0.1;')
sh.write('gl_Position = VP * vec4(wposition, 1.0);')
def make_deferred(con_mesh):
def make_deferred(con_mesh, rpasses):
wrd = bpy.data.worlds['Arm']
rpdat = arm.utils.get_rp()
arm_discard = mat_state.material.arm_discard
parse_opacity = arm_discard
parse_opacity = arm_discard or 'translucent' in rpasses
make_base(con_mesh, parse_opacity=parse_opacity)
@ -196,8 +196,11 @@ def make_deferred(con_mesh):
vert = con_mesh.vert
tese = con_mesh.tese
if arm_discard:
opac = mat_state.material.arm_discard_opacity
if parse_opacity:
if arm_discard:
opac = mat_state.material.arm_discard_opacity
else:
opac = '1.0'
frag.write('if (opacity < {0}) discard;'.format(opac))
gapi = arm.utils.get_gapi()
@ -245,11 +248,17 @@ def make_deferred(con_mesh):
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);')
if '_Emission' in wrd.world_defs:
if '_Emission' in wrd.world_defs or '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs:
frag.write('float matid = 0.0;')
frag.write('if (emission > 0) matid = 1.0;')
if '_Emission' in wrd.world_defs:
frag.write('if (emission > 0) matid = 1.0;')
if '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs:
frag.add_uniform('int materialID')
frag.write('if (materialID == 2) matid = 2.0;')
else:
frag.write('const float matid = 0.0;')
frag.write('fragColor[0] = vec4(n.xy, packFloat(metallic, roughness), matid);')
frag.write('fragColor[1] = vec4(basecol.rgb, packFloat2(occlusion, specular));')
@ -258,9 +267,6 @@ def make_deferred(con_mesh):
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('fragColor[2].rg = vec2(posa - posb);')
if '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs:
frag.add_uniform('int materialID')
frag.write('fragColor[2].a = materialID;')
return con_mesh
@ -488,7 +494,7 @@ def make_forward(con_mesh):
wrd = bpy.data.worlds['Arm']
rpdat = arm.utils.get_rp()
blend = mat_state.material.arm_blending
parse_opacity = blend and mat_utils.is_transluc(mat_state.material)
parse_opacity = blend or mat_utils.is_transluc(mat_state.material)
make_forward_base(con_mesh, parse_opacity=parse_opacity)
@ -527,8 +533,11 @@ def make_forward_base(con_mesh, parse_opacity=False):
frag = con_mesh.frag
tese = con_mesh.tese
if arm_discard:
opac = mat_state.material.arm_discard_opacity
if parse_opacity or arm_discard:
if arm_discard:
opac = mat_state.material.arm_discard_opacity
else:
opac = '1.0'
frag.write('if (opacity < {0}) discard;'.format(opac))
blend = mat_state.material.arm_blending

View File

@ -78,7 +78,7 @@ def build(material, mat_users, mat_armusers):
pass
elif rp == 'mesh':
con = make_mesh.make(rp)
con = make_mesh.make(rp, rpasses)
elif rp == 'shadowmap':
con = make_depth.make(rp, rpasses, shadowmap=True)

View File

@ -24,6 +24,9 @@ def make(context_id):
# Remove fragColor = ...;
frag.main = frag.main[:frag.main.rfind('fragColor')]
frag.write('\n')
frag.write('if (opacity == 1.0) discard;');
frag.write('\n')
frag.add_uniform('vec3 lightColor', link='_lightColor')
frag.write('float visibility = 1.0;')

View File

@ -32,18 +32,18 @@ def get_rpasses(material):
ar.append('decal')
elif material.arm_overlay:
ar.append('overlay')
elif is_transluc(material) and not material.arm_discard and rpdat.rp_translucency_state != 'Off' and not material.arm_blending:
ar.append('translucent')
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:
ar.append('translucent')
if (rpdat.rp_gi == 'Voxel GI' or rpdat.rp_gi == 'Voxel AO') 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:
ar.append('depth')
if material.arm_cast_shadow and rpdat.rp_shadows and ('mesh' in ar or 'translucent' in ar):
if material.arm_cast_shadow and rpdat.rp_shadows and ('mesh' in ar):
ar.append('shadowmap')
return ar

View File

@ -218,7 +218,7 @@ class ArmRPListItem(bpy.types.PropertyGroup):
# ('Raytracer', 'Raytracer', 'Raytracer'),
],
name="Renderer", description="Renderer type", default='Deferred', update=update_renderpath)
rp_depthprepass: BoolProperty(name="Depth Prepass", description="Depth Prepass for mesh context", default=True, update=update_renderpath)
rp_depthprepass: BoolProperty(name="Depth Prepass", description="Depth Prepass for mesh context", default=False, update=update_renderpath)
rp_hdr: BoolProperty(name="HDR", description="Render in HDR Space", default=True, update=update_renderpath)
rp_render_to_texture: BoolProperty(name="Post Process", description="Render scene to texture for further processing", default=True, update=update_renderpath)
rp_background: EnumProperty(

View File

@ -782,11 +782,11 @@ class ArmRenderPathShadowsPanel(bpy.types.Panel):
col2.enabled = rpdat.rp_shadowmap_cascades != '1'
col2.prop(rpdat, 'arm_shadowmap_split')
col.prop(rpdat, 'arm_shadowmap_bounds')
col.prop(rpdat, 'arm_soft_shadows')
col2 = col.column()
col2.enabled = rpdat.arm_soft_shadows != 'Off'
col2.prop(rpdat, 'arm_soft_shadows_penumbra')
col2.prop(rpdat, 'arm_soft_shadows_distance')
# col.prop(rpdat, 'arm_soft_shadows')
# col2 = col.column()
# col2.enabled = rpdat.arm_soft_shadows != 'Off'
# col2.prop(rpdat, 'arm_soft_shadows_penumbra')
# col2.prop(rpdat, 'arm_soft_shadows_distance')
col.prop(rpdat, 'arm_pcfsize')
class ArmRenderPathVoxelsPanel(bpy.types.Panel):