Voxel refraction
This commit is contained in:
parent
d4d7a265c0
commit
a0d14aed21
|
@ -136,7 +136,9 @@ void main() {
|
|||
#ifdef _SSS
|
||||
envl.rgb *= envmapStrength * fract(g1.a);
|
||||
#else
|
||||
#ifndef _VoxelGIRefract
|
||||
envl.rgb *= envmapStrength * g1.a; // Occlusion
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _DFGI
|
||||
|
|
|
@ -7,9 +7,9 @@ precision mediump float;
|
|||
#include "../compiled.glsl"
|
||||
#include "../std/brdf.glsl"
|
||||
#include "../std/math.glsl"
|
||||
// #ifdef _VoxelGI
|
||||
// #include "../std/conetrace.glsl"
|
||||
// #endif
|
||||
#ifdef _VoxelGIDirect
|
||||
#include "../std/conetrace.glsl"
|
||||
#endif
|
||||
#ifdef _PolyLight
|
||||
#include "../std/ltc.glsl"
|
||||
#endif
|
||||
|
@ -31,9 +31,9 @@ precision mediump float;
|
|||
#endif
|
||||
#include "../std/gbuffer.glsl"
|
||||
|
||||
// #ifdef _VoxelGI
|
||||
//-!uniform sampler3D voxels;
|
||||
// #endif
|
||||
#ifdef _VoxelGIDirect
|
||||
//!uniform sampler3D voxels;
|
||||
#endif
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
|
@ -138,6 +138,10 @@ void main() {
|
|||
|
||||
vec3 lp = lightPos - p;
|
||||
vec3 l = normalize(lp);
|
||||
vec3 h = normalize(v + l);
|
||||
float dotNH = dot(n, h);
|
||||
float dotVH = dot(v, h);
|
||||
float dotNL = dot(n, l);
|
||||
|
||||
float visibility = 1.0;
|
||||
#ifndef _NoShadows
|
||||
|
@ -150,6 +154,11 @@ void main() {
|
|||
visibility = shadowTestCube(lp, l);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelGIShadow // #else
|
||||
if (dotNL > 0.0) visibility = max(0, 1.0 - traceShadow(p / voxelgiDimensions, l, 0.1, length(lp)));
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _DFRS
|
||||
visibility = dfrs(p, l, lightPos);
|
||||
|
@ -167,13 +176,6 @@ void main() {
|
|||
}
|
||||
}
|
||||
|
||||
vec3 h = normalize(v + l);
|
||||
float dotNH = dot(n, h);
|
||||
float dotVH = dot(v, h);
|
||||
float dotNL = dot(n, l);
|
||||
// float dotLV = dot(l, v);
|
||||
// float dotLH = dot(l, h);
|
||||
|
||||
#ifdef _PolyLight
|
||||
if (lightType == 3) { // Area
|
||||
float theta = acos(dotNV);
|
||||
|
@ -238,7 +240,7 @@ void main() {
|
|||
#endif
|
||||
|
||||
#ifdef _SSRS
|
||||
float tvis = traceShadow(-l, p, gbuffer0, invVP, eye);
|
||||
float tvis = traceShadowSS(-l, p, gbuffer0, invVP, eye);
|
||||
// vec2 coords = getProjectedCoord(hitCoord);
|
||||
// vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy);
|
||||
// float screenEdgeFactor = clamp(1.0 - (deltaCoords.x + deltaCoords.y), 0.0, 1.0);
|
||||
|
@ -246,9 +248,9 @@ void main() {
|
|||
visibility *= tvis;
|
||||
#endif
|
||||
|
||||
// #ifdef _VoxelGI
|
||||
// if (dotNL > 0.0) visibility *= traceShadowCone(p / voxelgiResolution, l, distance(p, lightPos) / voxelgiResolution, n);
|
||||
// #endif
|
||||
|
||||
fragColor.rgb *= visibility;
|
||||
|
||||
#ifdef _VoxelGIRefract
|
||||
fragColor.rgb = mix(traceRefraction(p / voxelgiDimensions, n, -v, metrough.y), fragColor.rgb, g1.a);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ vec4 traceDiffuse(const vec3 origin, const vec3 normal) {
|
|||
}
|
||||
|
||||
float traceShadow(const vec3 origin, const vec3 dir, const float aperture, const float targetDistance) {
|
||||
const float offset = 3 * VOXEL_SIZE;
|
||||
const float offset = 4 * VOXEL_SIZE;
|
||||
return traceCone(origin, dir, aperture, targetDistance, offset).a;
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ vec3 traceRefraction(const vec3 pos, const vec3 normal, const vec3 viewDir, cons
|
|||
const float ior = 1.440;
|
||||
const float transmittance = 1.0;
|
||||
vec3 refraction = refract(viewDir, normal, 1.0 / ior);
|
||||
float rough = max(roughness, 0.15);
|
||||
float rough = max(roughness, 0.03);
|
||||
float specularAperture = clamp(tan((3.14159265 / 2) * rough), 0.0174533, 3.14159265);
|
||||
const float offset = 3 * VOXEL_SIZE;
|
||||
return transmittance * traceCone(pos, refraction, specularAperture, MAX_DISTANCE, offset).xyz;
|
||||
|
|
20
Shaders/std/ies.glsl
Normal file
20
Shaders/std/ies.glsl
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
sampler2D texIES;
|
||||
|
||||
// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
|
||||
float iesAttenuation(vec3 L, ShadowLightInfo light) {
|
||||
// Sample direction into light space
|
||||
vec3 iesSampleDirection = mul(light.worldToLight , -L);
|
||||
// Cartesian to spherical
|
||||
// Texture encoded with cos( phi ), scale from -1 - >1 to 0 - >1
|
||||
float phiCoord = (iesSampleDirection.z * 0.5f) + 0.5f;
|
||||
float theta = atan2 (iesSampleDirection.y , iesSampleDirection .x);
|
||||
float thetaCoord = theta * (1.0 / (PI * 2.0));
|
||||
float iesProfileScale = texture(texIES, vec2(thetaCoord, phiCoord)).r;
|
||||
return iesProfileScale;
|
||||
|
||||
// 1D texture
|
||||
vec3 pl = normalize(p - lightPos);
|
||||
float f = asin(dot(pl, l)) / PI + 0.5;
|
||||
return texture(texIES, vec2(f, 0.0)).r;
|
||||
}
|
|
@ -27,7 +27,7 @@ float getDeltaDepth(vec3 hitCoord, sampler2D gbuffer0, mat4 invVP, vec3 eye) {
|
|||
return d1 - d2;
|
||||
}
|
||||
|
||||
float traceShadow(vec3 dir, vec3 hitCoord, sampler2D gbuffer0, mat4 invVP, vec3 eye) {
|
||||
float traceShadowSS(vec3 dir, vec3 hitCoord, sampler2D gbuffer0, mat4 invVP, vec3 eye) {
|
||||
dir *= ssrsRayStep;
|
||||
// for (int i = 0; i < maxSteps; i++) {
|
||||
hitCoord += dir;
|
||||
|
|
|
@ -123,6 +123,10 @@ def make_deferred(cam):
|
|||
n.inputs[1].default_value = res
|
||||
n.inputs[2].default_value = res
|
||||
links.new(nodes['Image 3D Voxels'].outputs[0], nodes['Deferred Indirect'].inputs[4])
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
if wrd.voxelgi_shadows or wrd.voxelgi_refraction:
|
||||
links.new(nodes['Image 3D Voxels'].outputs[0], nodes['Deferred Light'].inputs[4])
|
||||
links.new(nodes['Image 3D Voxels'].outputs[0], nodes['Deferred Light.001'].inputs[4])
|
||||
|
||||
if cam.rp_shadowmap != 'None':
|
||||
n = nodes['Shadow Map']
|
||||
|
|
|
@ -456,7 +456,11 @@ def make_water_pass(stages, node_group, node):
|
|||
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3], bind_target_constants=['gbufferD', 'shadowMap'], shader_context='water_pass/water_pass/water_pass')
|
||||
|
||||
def make_deferred_light_pass(stages, node_group, node):
|
||||
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3], bind_target_constants=['gbuffer', 'shadowMap'], shader_context='', with_draw_quad=False)
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
if wrd.voxelgi_shadows or wrd.voxelgi_refraction:
|
||||
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3, 4], bind_target_constants=['gbuffer', 'shadowMap', 'voxels'], shader_context='', with_draw_quad=False)
|
||||
else:
|
||||
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3], bind_target_constants=['gbuffer', 'shadowMap'], shader_context='', with_draw_quad=False)
|
||||
stage = {}
|
||||
stage['command'] = 'call_function'
|
||||
stage['params'] = ['iron.data.RenderPath.lampIsSun']
|
||||
|
|
|
@ -115,6 +115,12 @@ def build_node_tree(world):
|
|||
wrd.world_defs += '_VoxelGIMulti'
|
||||
if wrd.voxelgi_camera:
|
||||
wrd.world_defs += '_VoxelGICam'
|
||||
if wrd.voxelgi_shadows:
|
||||
wrd.world_defs += '_VoxelGIDirect'
|
||||
wrd.world_defs += '_VoxelGIShadow'
|
||||
if wrd.voxelgi_refraction:
|
||||
wrd.world_defs += '_VoxelGIDirect'
|
||||
wrd.world_defs += '_VoxelGIRefract'
|
||||
wrd.world_defs += '_VoxelGI'
|
||||
wrd.world_defs += '_Rad' # Always do radiance for voxels
|
||||
wrd.world_defs += '_Irr'
|
||||
|
|
|
@ -206,8 +206,9 @@ def make_deferred(con_mesh):
|
|||
wrd = bpy.data.worlds['Arm']
|
||||
|
||||
discard_transparent = mat_state.material.discard_transparent
|
||||
parse_opacity = discard_transparent or wrd.voxelgi_refraction
|
||||
|
||||
make_base(con_mesh, parse_opacity=discard_transparent)
|
||||
make_base(con_mesh, parse_opacity=parse_opacity)
|
||||
|
||||
frag = con_mesh.frag
|
||||
vert = con_mesh.vert
|
||||
|
@ -260,6 +261,8 @@ def make_deferred(con_mesh):
|
|||
if '_SSS' in wrd.rp_defs:
|
||||
frag.add_uniform('int materialID')
|
||||
frag.write('fragColor[1] = vec4(basecol.rgb, materialID + clamp(occlusion, 0.0, 1.0 - 0.001));')
|
||||
elif wrd.voxelgi_refraction:
|
||||
frag.write('fragColor[1] = vec4(basecol.rgb, opacity);')
|
||||
else:
|
||||
frag.write('fragColor[1] = vec4(basecol.rgb, occlusion);')
|
||||
|
||||
|
|
|
@ -60,13 +60,15 @@ def make(context_id):
|
|||
frag.write('float roughness;') #
|
||||
frag.write('float metallic;') #
|
||||
frag.write('float occlusion;') #
|
||||
# frag.write('float opacity;') #
|
||||
parse_opacity = wrd.voxelgi_refraction
|
||||
if parse_opacity:
|
||||
frag.write('float opacity;')
|
||||
frag.write_pre = True
|
||||
frag.write('mat3 TBN;') # TODO: discard, parse basecolor only
|
||||
frag.write_pre = False
|
||||
frag.write('float dotNV = 0.0;')
|
||||
frag.write('float dotNL = max(dot(wnormal, l), 0.0);')
|
||||
cycles.parse(mat_state.nodes, con_voxel, vert, frag, geom, tesc, tese, parse_opacity=False, parse_displacement=False)
|
||||
cycles.parse(mat_state.nodes, con_voxel, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity, parse_displacement=False)
|
||||
|
||||
if not frag.contains('vec3 n ='):
|
||||
frag.write_pre = True
|
||||
|
@ -152,7 +154,10 @@ def make(context_id):
|
|||
# frag.write('imageAtomicRGBA8Avg(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
|
||||
|
||||
frag.write('ivec3 coords = ivec3(voxelgiResolution * voxel);')
|
||||
frag.write('vec4 val = vec4(color, 1.0);')
|
||||
if parse_opacity:
|
||||
frag.write('vec4 val = vec4(color, opacity);')
|
||||
else:
|
||||
frag.write('vec4 val = vec4(color, 1.0);')
|
||||
frag.write('val *= 255.0;')
|
||||
frag.write('uint newVal = encUnsignedNibble(convVec4ToRGBA8(val), 1);')
|
||||
frag.write('uint prevStoredVal = 0;')
|
||||
|
|
|
@ -26,11 +26,14 @@ def get_rpasses(material):
|
|||
# if material.depthpass:
|
||||
# ar.append('depth')
|
||||
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
vgirefract = bpy.data.cameras[0].rp_voxelgi and wrd.voxelgi_refraction
|
||||
|
||||
if material.decal:
|
||||
ar.append('decal')
|
||||
elif material.overlay:
|
||||
ar.append('overlay')
|
||||
elif is_transluc(material) and not material.discard_transparent:
|
||||
elif is_transluc(material) and not material.discard_transparent and not vgirefract:
|
||||
ar.append('translucent')
|
||||
else:
|
||||
ar.append('mesh')
|
||||
|
@ -38,7 +41,7 @@ def get_rpasses(material):
|
|||
ar.append(con)
|
||||
if bpy.data.cameras[0].rp_voxelgi:
|
||||
ar.append('voxel')
|
||||
if bpy.data.worlds['Arm'].voxelgi_multibounce:
|
||||
if wrd.voxelgi_multibounce:
|
||||
ar.append('voxelbounce')
|
||||
if bpy.data.cameras[0].rp_renderer == 'Deferred Plus':
|
||||
ar.append('rect')
|
||||
|
|
|
@ -319,6 +319,7 @@ class DeferredLightPassNode(Node, CGPipelineTreeNode):
|
|||
self.inputs.new('NodeSocketShader', "Target")
|
||||
self.inputs.new('NodeSocketShader', "GBuffer")
|
||||
self.inputs.new('NodeSocketShader', "Shadow Map")
|
||||
self.inputs.new('NodeSocketShader', "Voxels")
|
||||
|
||||
self.outputs.new('NodeSocketShader', "Stage")
|
||||
|
||||
|
|
|
@ -432,6 +432,8 @@ def init_properties():
|
|||
bpy.types.World.voxelgi_multibounce = bpy.props.BoolProperty(name="Multi-bounce", description="Accumulate multiple light bounces", default=False, update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.voxelgi_camera = bpy.props.BoolProperty(name="Camera", description="Use camera as voxelization origin", default=False, update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.voxelgi_anisotropic = bpy.props.BoolProperty(name="Anisotropic", description="Use anisotropic voxels", default=False, update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.voxelgi_shadows = bpy.props.BoolProperty(name="Shadows", description="Use voxels to render shadows", default=False, update=update_renderpath)
|
||||
bpy.types.World.voxelgi_refraction = bpy.props.BoolProperty(name="Refraction", description="Use voxels to render refraction", default=False, update=update_renderpath)
|
||||
bpy.types.World.voxelgi_diff = bpy.props.FloatProperty(name="Diffuse", description="", default=1.0, update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.voxelgi_spec = bpy.props.FloatProperty(name="Specular", description="", default=1.0, update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.voxelgi_occ = bpy.props.FloatProperty(name="Occlussion", description="", default=1.0, update=assets.invalidate_shader_cache)
|
||||
|
|
|
@ -342,6 +342,9 @@ class GenRPDataPropsPanel(bpy.types.Panel):
|
|||
row = layout.row()
|
||||
row.prop(wrd, 'voxelgi_camera')
|
||||
row.prop(wrd, 'voxelgi_anisotropic')
|
||||
row = layout.row()
|
||||
row.prop(wrd, 'voxelgi_shadows')
|
||||
row.prop(wrd, 'voxelgi_refraction')
|
||||
layout.prop(dat, 'rp_voxelgi_hdr')
|
||||
|
||||
layout.separator()
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue