2017-03-12 17:29:22 +01:00
|
|
|
import bpy
|
2017-08-21 20:30:39 +02:00
|
|
|
import arm.utils
|
2017-12-20 15:37:58 +01:00
|
|
|
import arm.assets as assets
|
2017-03-15 12:30:14 +01:00
|
|
|
import arm.material.cycles as cycles
|
|
|
|
import arm.material.mat_state as mat_state
|
|
|
|
import arm.material.mat_utils as mat_utils
|
2017-10-16 09:25:18 +02:00
|
|
|
import arm.material.make_particle as make_particle
|
2018-02-16 17:12:19 +01:00
|
|
|
import arm.make_state as state
|
2017-02-18 20:18:38 +01:00
|
|
|
|
|
|
|
def make(context_id):
|
2017-08-22 10:04:13 +02:00
|
|
|
rpdat = arm.utils.get_rp()
|
2017-10-12 12:12:48 +02:00
|
|
|
if rpdat.rp_gi == 'Voxel GI':
|
2018-02-16 17:12:19 +01:00
|
|
|
if state.target == "native":
|
|
|
|
con = make_gi(context_id)
|
|
|
|
else:
|
|
|
|
con = make_gi_legacy(context_id)
|
2017-08-22 10:04:13 +02:00
|
|
|
else:
|
2017-12-20 15:37:58 +01:00
|
|
|
con = make_ao(context_id)
|
|
|
|
|
|
|
|
assets.vs_equal(con, assets.shader_cons['voxel_vert'])
|
|
|
|
assets.gs_equal(con, assets.shader_cons['voxel_frag'])
|
|
|
|
assets.fs_equal(con, assets.shader_cons['voxel_geom'])
|
|
|
|
|
|
|
|
return con
|
2017-08-22 10:04:13 +02:00
|
|
|
|
|
|
|
def make_gi(context_id):
|
2017-05-20 19:07:15 +02:00
|
|
|
con_voxel = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'always', 'cull_mode': 'none', 'color_write_red': False, 'color_write_green': False, 'color_write_blue': False, 'color_write_alpha': False, 'conservative_raster': True })
|
2017-03-12 17:29:22 +01:00
|
|
|
wrd = bpy.data.worlds['Arm']
|
|
|
|
|
2017-02-18 20:18:38 +01:00
|
|
|
vert = con_voxel.make_vert()
|
|
|
|
frag = con_voxel.make_frag()
|
|
|
|
geom = con_voxel.make_geom()
|
|
|
|
tesc = None
|
|
|
|
tese = None
|
|
|
|
geom.ins = vert.outs
|
|
|
|
frag.ins = geom.outs
|
|
|
|
|
2017-12-20 10:19:44 +01:00
|
|
|
frag.add_include('compiled.glsl')
|
|
|
|
frag.add_include('std/math.glsl')
|
|
|
|
frag.add_include('std/imageatomic.glsl')
|
2018-02-16 17:12:19 +01:00
|
|
|
frag.add_include('std/gbuffer.glsl')
|
2017-10-05 11:56:40 +02:00
|
|
|
frag.write_header('#extension GL_ARB_shader_image_load_store : enable')
|
|
|
|
|
|
|
|
rpdat = arm.utils.get_rp()
|
2018-02-16 17:12:19 +01:00
|
|
|
frag.add_uniform('layout(r32ui) uimage3D voxels')
|
|
|
|
frag.add_uniform('layout(r32ui) uimage3D voxelsNor')
|
2017-10-05 11:56:40 +02:00
|
|
|
|
2017-10-23 01:55:47 +02:00
|
|
|
frag.write('if (abs(voxposition.z) > ' + rpdat.rp_voxelgi_resolution_z + ' || abs(voxposition.x) > 1 || abs(voxposition.y) > 1) return;')
|
2017-10-12 12:12:48 +02:00
|
|
|
frag.write('vec3 wposition = voxposition * voxelgiHalfExtents;')
|
2017-10-13 15:21:36 +02:00
|
|
|
if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
|
2017-10-12 12:32:08 +02:00
|
|
|
frag.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
|
|
|
|
frag.write('wposition += eyeSnap;')
|
2017-05-26 00:22:00 +02:00
|
|
|
|
|
|
|
frag.write('vec3 basecol;')
|
|
|
|
frag.write('float roughness;') #
|
|
|
|
frag.write('float metallic;') #
|
|
|
|
frag.write('float occlusion;') #
|
2017-08-21 20:30:39 +02:00
|
|
|
parse_opacity = rpdat.arm_voxelgi_refraction
|
2017-08-13 20:28:06 +02:00
|
|
|
if parse_opacity:
|
|
|
|
frag.write('float opacity;')
|
2017-05-26 00:22:00 +02:00
|
|
|
frag.write('float dotNV = 0.0;')
|
2017-10-03 16:08:29 +02:00
|
|
|
cycles.parse(mat_state.nodes, con_voxel, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity, parse_displacement=False, basecol_only=True)
|
2017-05-26 00:22:00 +02:00
|
|
|
|
2017-10-16 09:25:18 +02:00
|
|
|
# Voxelized particles
|
2017-10-24 17:02:24 +02:00
|
|
|
particle = mat_state.material.arm_particle
|
|
|
|
if particle == 'gpu':
|
2017-10-16 09:25:18 +02:00
|
|
|
# make_particle.write(vert, particle_info=cycles.particle_info)
|
2017-10-24 17:02:24 +02:00
|
|
|
frag.write_pre = True
|
|
|
|
frag.write('const float p_index = 0;')
|
|
|
|
frag.write('const float p_age = 0;')
|
|
|
|
frag.write('const float p_lifetime = 0;')
|
|
|
|
frag.write('const vec3 p_location = vec3(0);')
|
|
|
|
frag.write('const float p_size = 0;')
|
|
|
|
frag.write('const vec3 p_velocity = vec3(0);')
|
|
|
|
frag.write('const vec3 p_angular_velocity = vec3(0);')
|
|
|
|
frag.write_pre = False
|
2017-10-16 09:25:18 +02:00
|
|
|
|
2017-08-05 22:49:25 +02:00
|
|
|
if not frag.contains('vec3 n ='):
|
|
|
|
frag.write_pre = True
|
|
|
|
frag.write('vec3 n;')
|
|
|
|
frag.write_pre = False
|
2017-05-26 00:22:00 +02:00
|
|
|
|
2017-10-03 16:08:29 +02:00
|
|
|
export_mpos = frag.contains('mposition') and not frag.contains('vec3 mposition')
|
|
|
|
if export_mpos:
|
|
|
|
vert.add_out('vec3 mpositionGeom')
|
|
|
|
vert.write_pre = True
|
|
|
|
vert.write('mpositionGeom = pos;')
|
|
|
|
vert.write_pre = False
|
|
|
|
|
2017-02-18 20:18:38 +01:00
|
|
|
vert.add_uniform('mat4 W', '_worldMatrix')
|
2017-03-11 01:50:47 +01:00
|
|
|
vert.add_uniform('mat3 N', '_normalMatrix')
|
2017-02-22 15:50:19 +01:00
|
|
|
|
2017-10-12 12:12:48 +02:00
|
|
|
vert.add_out('vec3 voxpositionGeom')
|
2017-02-22 15:50:19 +01:00
|
|
|
vert.add_out('vec3 wnormalGeom')
|
|
|
|
|
2017-12-20 10:19:44 +01:00
|
|
|
vert.add_include('compiled.glsl')
|
2017-02-22 15:50:19 +01:00
|
|
|
|
2017-10-03 15:11:15 +02:00
|
|
|
if con_voxel.is_elem('col'):
|
|
|
|
vert.add_out('vec3 vcolorGeom')
|
|
|
|
vert.write('vcolorGeom = col;')
|
|
|
|
|
2017-05-25 16:48:41 +02:00
|
|
|
if con_voxel.is_elem('tex'):
|
2017-02-22 15:50:19 +01:00
|
|
|
vert.add_out('vec2 texCoordGeom')
|
|
|
|
vert.write('texCoordGeom = tex;')
|
|
|
|
|
2017-10-13 15:21:36 +02:00
|
|
|
if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
|
2017-10-12 12:12:48 +02:00
|
|
|
vert.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
|
|
|
|
vert.write('voxpositionGeom = (vec3(W * vec4(pos, 1.0)) - eyeSnap) / voxelgiHalfExtents;')
|
2017-08-03 14:01:04 +02:00
|
|
|
else:
|
2017-10-12 12:12:48 +02:00
|
|
|
vert.write('voxpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiHalfExtents;')
|
2017-03-11 01:50:47 +01:00
|
|
|
vert.write('wnormalGeom = normalize(N * nor);')
|
2017-10-12 12:12:48 +02:00
|
|
|
# vert.write('gl_Position = vec4(0.0, 0.0, 0.0, 1.0);')
|
2017-02-22 15:50:19 +01:00
|
|
|
|
2017-10-12 12:12:48 +02:00
|
|
|
geom.add_out('vec3 voxposition')
|
2017-02-22 15:50:19 +01:00
|
|
|
geom.add_out('vec3 wnormal')
|
2017-10-03 15:11:15 +02:00
|
|
|
if con_voxel.is_elem('col'):
|
|
|
|
geom.add_out('vec3 vcolor')
|
2017-05-25 16:48:41 +02:00
|
|
|
if con_voxel.is_elem('tex'):
|
2017-02-22 15:50:19 +01:00
|
|
|
geom.add_out('vec2 texCoord')
|
2017-10-03 16:08:29 +02:00
|
|
|
if export_mpos:
|
|
|
|
geom.add_out('vec3 mposition')
|
2017-02-22 15:50:19 +01:00
|
|
|
|
2018-01-29 23:52:42 +01:00
|
|
|
geom.write('vec3 p1 = voxpositionGeom[1] - voxpositionGeom[0];')
|
|
|
|
geom.write('vec3 p2 = voxpositionGeom[2] - voxpositionGeom[0];')
|
|
|
|
geom.write('vec3 p = abs(cross(p1, p2));')
|
2017-02-22 15:50:19 +01:00
|
|
|
geom.write('for (uint i = 0; i < 3; ++i) {')
|
2017-10-12 12:12:48 +02:00
|
|
|
geom.write(' voxposition = voxpositionGeom[i];')
|
2017-02-22 15:50:19 +01:00
|
|
|
geom.write(' wnormal = wnormalGeom[i];')
|
2017-10-03 15:11:15 +02:00
|
|
|
if con_voxel.is_elem('col'):
|
|
|
|
geom.write(' vcolor = vcolorGeom[i];')
|
2017-05-25 16:48:41 +02:00
|
|
|
if con_voxel.is_elem('tex'):
|
2017-02-22 15:50:19 +01:00
|
|
|
geom.write(' texCoord = texCoordGeom[i];')
|
2017-10-03 16:08:29 +02:00
|
|
|
if export_mpos:
|
|
|
|
geom.write(' mposition = mpositionGeom[i];')
|
2017-02-22 15:50:19 +01:00
|
|
|
geom.write(' if (p.z > p.x && p.z > p.y) {')
|
2017-10-12 12:12:48 +02:00
|
|
|
geom.write(' gl_Position = vec4(voxposition.x, voxposition.y, 0.0, 1.0);')
|
2017-02-22 15:50:19 +01:00
|
|
|
geom.write(' }')
|
|
|
|
geom.write(' else if (p.x > p.y && p.x > p.z) {')
|
2017-10-12 12:12:48 +02:00
|
|
|
geom.write(' gl_Position = vec4(voxposition.y, voxposition.z, 0.0, 1.0);')
|
2017-02-22 15:50:19 +01:00
|
|
|
geom.write(' }')
|
|
|
|
geom.write(' else {')
|
2017-10-12 12:12:48 +02:00
|
|
|
geom.write(' gl_Position = vec4(voxposition.x, voxposition.z, 0.0, 1.0);')
|
2017-02-22 15:50:19 +01:00
|
|
|
geom.write(' }')
|
2017-02-18 20:18:38 +01:00
|
|
|
geom.write(' EmitVertex();')
|
|
|
|
geom.write('}')
|
|
|
|
geom.write('EndPrimitive();')
|
|
|
|
|
2017-10-12 12:12:48 +02:00
|
|
|
frag.write('vec3 voxel = voxposition * 0.5 + 0.5;')
|
2018-02-16 17:12:19 +01:00
|
|
|
frag.write('uint val = convVec4ToRGBA8(vec4(basecol, 1.0) * 255);')
|
|
|
|
frag.write('imageAtomicMax(voxels, ivec3(voxelgiResolution * voxel), val);')
|
2017-06-27 14:10:26 +02:00
|
|
|
|
2018-02-16 17:12:19 +01:00
|
|
|
frag.write('val = encNor(wnormal);');
|
|
|
|
frag.write('imageAtomicMax(voxelsNor, ivec3(voxelgiResolution * voxel), val);')
|
2017-10-23 16:24:57 +02:00
|
|
|
|
|
|
|
# frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
|
|
|
|
# frag.write('imageAtomicRGBA8Avg(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
|
|
|
|
|
|
|
|
# frag.write('ivec3 coords = ivec3(voxelgiResolution * voxel);')
|
|
|
|
# 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;')
|
|
|
|
# frag.write('uint currStoredVal;')
|
|
|
|
# # frag.write('int counter = 0;')
|
|
|
|
# # frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal && counter < 16) {')
|
|
|
|
# frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal) {')
|
|
|
|
# frag.write(' vec4 rval = convRGBA8ToVec4(currStoredVal & 0xFEFEFEFE);')
|
|
|
|
# frag.write(' uint n = decUnsignedNibble(currStoredVal);')
|
|
|
|
# frag.write(' rval = rval * n + val;')
|
|
|
|
# frag.write(' rval /= ++n;')
|
|
|
|
# frag.write(' rval = round(rval / 2) * 2;')
|
|
|
|
# frag.write(' newVal = encUnsignedNibble(convVec4ToRGBA8(rval), n);')
|
|
|
|
# frag.write(' prevStoredVal = currStoredVal;')
|
|
|
|
# # frag.write(' counter++;')
|
|
|
|
# frag.write('}')
|
|
|
|
|
|
|
|
# frag.write('val.rgb *= 255.0f;')
|
|
|
|
# frag.write('uint newVal = convVec4ToRGBA8(val);')
|
|
|
|
# frag.write('uint prevStoredVal = 0;')
|
|
|
|
# frag.write('uint curStoredVal;')
|
|
|
|
# frag.write('while ((curStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal) {')
|
|
|
|
# frag.write(' prevStoredVal = curStoredVal;')
|
|
|
|
# frag.write(' vec4 rval = convRGBA8ToVec4(curStoredVal);')
|
|
|
|
# frag.write(' rval.xyz = (rval.xyz * rval.w);')
|
|
|
|
# frag.write(' vec4 curValF = rval + val;')
|
|
|
|
# frag.write(' curValF.xyz /= (curValF.w);')
|
|
|
|
# frag.write(' newVal = convVec4ToRGBA8(curValF);')
|
|
|
|
# frag.write('}')
|
2017-02-18 20:18:38 +01:00
|
|
|
|
|
|
|
return con_voxel
|
2017-08-22 10:04:13 +02:00
|
|
|
|
|
|
|
def make_ao(context_id):
|
|
|
|
con_voxel = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'always', 'cull_mode': 'none', 'color_write_red': False, 'color_write_green': False, 'color_write_blue': False, 'color_write_alpha': False, 'conservative_raster': True })
|
|
|
|
wrd = bpy.data.worlds['Arm']
|
|
|
|
|
|
|
|
vert = con_voxel.make_vert()
|
|
|
|
frag = con_voxel.make_frag()
|
|
|
|
geom = con_voxel.make_geom()
|
|
|
|
tesc = None
|
|
|
|
tese = None
|
|
|
|
|
|
|
|
geom.ins = vert.outs
|
|
|
|
frag.ins = geom.outs
|
|
|
|
|
2017-12-20 10:19:44 +01:00
|
|
|
frag.add_include('compiled.glsl')
|
|
|
|
frag.add_include('std/math.glsl')
|
|
|
|
frag.add_include('std/imageatomic.glsl')
|
2017-08-22 10:04:13 +02:00
|
|
|
frag.write_header('#extension GL_ARB_shader_image_load_store : enable')
|
|
|
|
|
|
|
|
rpdat = arm.utils.get_rp()
|
2017-10-23 16:24:57 +02:00
|
|
|
# frag.add_uniform('layout(r32ui) uimage3D voxels')
|
2018-02-16 17:12:19 +01:00
|
|
|
frag.add_uniform('layout(r8) writeonly image3D voxels')
|
2017-08-22 10:04:13 +02:00
|
|
|
|
2017-12-20 10:19:44 +01:00
|
|
|
vert.add_include('compiled.glsl')
|
2017-08-22 10:04:13 +02:00
|
|
|
vert.add_uniform('mat4 W', '_worldMatrix')
|
2017-10-12 12:12:48 +02:00
|
|
|
vert.add_out('vec3 voxpositionGeom')
|
2017-08-22 10:04:13 +02:00
|
|
|
|
2017-10-13 15:21:36 +02:00
|
|
|
if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
|
2017-10-12 22:40:30 +02:00
|
|
|
vert.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
|
|
|
|
vert.write('voxpositionGeom = (vec3(W * vec4(pos, 1.0)) - eyeSnap) / voxelgiHalfExtents;')
|
|
|
|
else:
|
|
|
|
vert.write('voxpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiHalfExtents;')
|
|
|
|
|
2017-10-12 12:12:48 +02:00
|
|
|
# vert.write('gl_Position = vec4(0.0, 0.0, 0.0, 1.0);')
|
2017-08-22 10:04:13 +02:00
|
|
|
|
2017-10-26 22:13:21 +02:00
|
|
|
if False: # Maxwell
|
|
|
|
# https://developer.nvidia.com/sites/default/files/akamai/opengl/specs/GL_NV_geometry_shader_passthrough.txt
|
|
|
|
# https://www.khronos.org/registry/OpenGL/extensions/NV/NV_viewport_swizzle.txt
|
|
|
|
vert.write('gl_Position = vec4(voxpositionGeom.x, voxpositionGeom.y, 0.0, 1.0);')
|
|
|
|
geom.write_header('#extension GL_NV_geometry_shader_passthrough : require')
|
|
|
|
geom.geom_passthrough = True
|
|
|
|
# geom.add_out('vec3 voxposition')
|
2018-01-29 23:52:42 +01:00
|
|
|
geom.write('vec3 p1 = voxpositionGeom[1] - voxpositionGeom[0];')
|
|
|
|
geom.write('vec3 p2 = voxpositionGeom[2] - voxpositionGeom[0];')
|
|
|
|
geom.write('vec3 n = abs(cross(p1, p2));')
|
2017-10-26 22:13:21 +02:00
|
|
|
geom.write('gl_ViewportIndex = 1;')
|
|
|
|
geom.write_header('out int gl_ViewportIndex;')
|
|
|
|
# g4.setViewport():
|
|
|
|
#glViewportIndexedf(0, x, _renderTargetHeight - y - height, width, height);
|
|
|
|
#glViewportIndexedf(1, x, _renderTargetHeight - y - height, width, height);
|
|
|
|
#glViewportSwizzleNV(1, GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV, GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV, GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV, GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV);
|
|
|
|
frag.add_in('vec3 voxpositionGeom')
|
|
|
|
frag.write('if (abs(voxpositionGeom.z) > ' + rpdat.rp_voxelgi_resolution_z + ' || abs(voxpositionGeom.x) > 1 || abs(voxpositionGeom.y) > 1) return;')
|
|
|
|
frag.write('imageStore(voxels, ivec3(voxelgiResolution * (voxpositionGeom * 0.5 + 0.5)), vec4(1.0));')
|
|
|
|
else:
|
|
|
|
geom.add_out('vec3 voxposition')
|
2018-01-29 23:52:42 +01:00
|
|
|
geom.write('vec3 p1 = voxpositionGeom[1] - voxpositionGeom[0];')
|
|
|
|
geom.write('vec3 p2 = voxpositionGeom[2] - voxpositionGeom[0];')
|
|
|
|
geom.write('vec3 p = abs(cross(p1, p2));')
|
2017-10-26 22:13:21 +02:00
|
|
|
geom.write('for (uint i = 0; i < 3; ++i) {')
|
|
|
|
geom.write(' voxposition = voxpositionGeom[i];')
|
|
|
|
geom.write(' if (p.z > p.x && p.z > p.y) {')
|
|
|
|
geom.write(' gl_Position = vec4(voxposition.x, voxposition.y, 0.0, 1.0);')
|
|
|
|
geom.write(' }')
|
|
|
|
geom.write(' else if (p.x > p.y && p.x > p.z) {')
|
|
|
|
geom.write(' gl_Position = vec4(voxposition.y, voxposition.z, 0.0, 1.0);')
|
|
|
|
geom.write(' }')
|
|
|
|
geom.write(' else {')
|
|
|
|
geom.write(' gl_Position = vec4(voxposition.x, voxposition.z, 0.0, 1.0);')
|
|
|
|
geom.write(' }')
|
|
|
|
geom.write(' EmitVertex();')
|
|
|
|
geom.write('}')
|
|
|
|
geom.write('EndPrimitive();')
|
|
|
|
|
|
|
|
frag.write('if (abs(voxposition.z) > ' + rpdat.rp_voxelgi_resolution_z + ' || abs(voxposition.x) > 1 || abs(voxposition.y) > 1) return;')
|
|
|
|
frag.write('imageStore(voxels, ivec3(voxelgiResolution * (voxposition * 0.5 + 0.5)), vec4(1.0));')
|
2017-08-22 10:04:13 +02:00
|
|
|
|
|
|
|
return con_voxel
|
2018-02-16 17:12:19 +01:00
|
|
|
|
|
|
|
def make_gi_legacy(context_id):
|
|
|
|
con_voxel = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'always', 'cull_mode': 'none', 'color_write_red': False, 'color_write_green': False, 'color_write_blue': False, 'color_write_alpha': False, 'conservative_raster': True })
|
|
|
|
wrd = bpy.data.worlds['Arm']
|
|
|
|
|
|
|
|
is_shadows = not '_NoShadows' in wrd.world_defs
|
|
|
|
|
|
|
|
vert = con_voxel.make_vert()
|
|
|
|
frag = con_voxel.make_frag()
|
|
|
|
geom = con_voxel.make_geom()
|
|
|
|
tesc = None
|
|
|
|
tese = None
|
|
|
|
|
|
|
|
geom.ins = vert.outs
|
|
|
|
frag.ins = geom.outs
|
|
|
|
|
|
|
|
frag.add_include('compiled.glsl')
|
|
|
|
frag.add_include('std/math.glsl')
|
|
|
|
frag.add_include('std/imageatomic.glsl')
|
|
|
|
frag.write_header('#extension GL_ARB_shader_image_load_store : enable')
|
|
|
|
|
|
|
|
rpdat = arm.utils.get_rp()
|
|
|
|
if rpdat.rp_voxelgi_hdr:
|
|
|
|
frag.add_uniform('layout(rgba16) image3D voxels')
|
|
|
|
else:
|
|
|
|
frag.add_uniform('layout(r32ui) uimage3D voxels')
|
|
|
|
|
|
|
|
frag.add_uniform('vec3 lightPos', '_lampPosition')
|
2018-02-16 17:14:30 +01:00
|
|
|
frag.add_uniform('vec3 lightColor', '_lampColor')
|
2018-02-16 17:12:19 +01:00
|
|
|
frag.add_uniform('int lightType', '_lampType')
|
|
|
|
frag.add_uniform('vec3 lightDir', '_lampDirection')
|
|
|
|
|
|
|
|
frag.write('if (abs(voxposition.z) > ' + rpdat.rp_voxelgi_resolution_z + ' || abs(voxposition.x) > 1 || abs(voxposition.y) > 1) return;')
|
|
|
|
frag.write('vec3 wposition = voxposition * voxelgiHalfExtents;')
|
|
|
|
if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
|
|
|
|
frag.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
|
|
|
|
frag.write('wposition += eyeSnap;')
|
|
|
|
|
|
|
|
frag.write('float visibility = 1.0;')
|
|
|
|
frag.write('vec3 lp = lightPos - wposition;')
|
|
|
|
frag.write('vec3 l;')
|
|
|
|
frag.write('if (lightType == 0) l = lightDir;')
|
|
|
|
frag.write('else { l = normalize(lp); visibility *= attenuate(distance(wposition, lightPos)); }')
|
|
|
|
|
|
|
|
frag.write('float dotNL = max(dot(wnormal, l), 0.0);')
|
|
|
|
frag.write('if (dotNL == 0.0) return;')
|
|
|
|
|
|
|
|
if is_shadows:
|
|
|
|
frag.add_include('std/shadows.glsl')
|
|
|
|
frag.add_uniform('sampler2D shadowMap')
|
|
|
|
frag.add_uniform('samplerCube shadowMapCube')
|
|
|
|
frag.add_uniform('int lightShadow', '_lampCastShadow')
|
|
|
|
frag.add_uniform('vec2 lightProj', '_lampPlaneProj')
|
|
|
|
frag.add_uniform('float shadowsBias', '_lampShadowsBias')
|
|
|
|
frag.write('if (lightShadow == 1 && lampPos.w > 0.0) {')
|
|
|
|
frag.write(' vec3 lpos = lampPos.xyz / lampPos.w;')
|
|
|
|
frag.write(' if (texture(shadowMap, lpos.xy).r < lpos.z - shadowsBias) visibility = 0.0;')
|
|
|
|
frag.write('}')
|
|
|
|
frag.write('else if (lightShadow == 2) visibility *= float(texture(shadowMapCube, -l).r + shadowsBias > lpToDepth(lp, lightProj));')
|
|
|
|
|
|
|
|
frag.write('vec3 basecol;')
|
|
|
|
frag.write('float roughness;') #
|
|
|
|
frag.write('float metallic;') #
|
|
|
|
frag.write('float occlusion;') #
|
|
|
|
parse_opacity = rpdat.arm_voxelgi_refraction
|
|
|
|
if parse_opacity:
|
|
|
|
frag.write('float opacity;')
|
|
|
|
frag.write('float dotNV = 0.0;')
|
|
|
|
cycles.parse(mat_state.nodes, con_voxel, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity, parse_displacement=False, basecol_only=True)
|
|
|
|
|
|
|
|
# Voxelized particles
|
|
|
|
particle = mat_state.material.arm_particle
|
|
|
|
if particle == 'gpu':
|
|
|
|
frag.write_pre = True
|
|
|
|
frag.write('const float p_index = 0;')
|
|
|
|
frag.write('const float p_age = 0;')
|
|
|
|
frag.write('const float p_lifetime = 0;')
|
|
|
|
frag.write('const vec3 p_location = vec3(0);')
|
|
|
|
frag.write('const float p_size = 0;')
|
|
|
|
frag.write('const vec3 p_velocity = vec3(0);')
|
|
|
|
frag.write('const vec3 p_angular_velocity = vec3(0);')
|
|
|
|
frag.write_pre = False
|
|
|
|
|
|
|
|
if not frag.contains('vec3 n ='):
|
|
|
|
frag.write_pre = True
|
|
|
|
frag.write('vec3 n;')
|
|
|
|
frag.write_pre = False
|
|
|
|
|
|
|
|
export_mpos = frag.contains('mposition') and not frag.contains('vec3 mposition')
|
|
|
|
if export_mpos:
|
|
|
|
vert.add_out('vec3 mpositionGeom')
|
|
|
|
vert.write_pre = True
|
|
|
|
vert.write('mpositionGeom = pos;')
|
|
|
|
vert.write_pre = False
|
|
|
|
|
|
|
|
vert.add_uniform('mat4 W', '_worldMatrix')
|
|
|
|
vert.add_uniform('mat3 N', '_normalMatrix')
|
|
|
|
|
|
|
|
vert.add_out('vec3 voxpositionGeom')
|
|
|
|
vert.add_out('vec3 wnormalGeom')
|
|
|
|
|
|
|
|
vert.add_include('compiled.glsl')
|
|
|
|
|
|
|
|
if con_voxel.is_elem('col'):
|
|
|
|
vert.add_out('vec3 vcolorGeom')
|
|
|
|
vert.write('vcolorGeom = col;')
|
|
|
|
|
|
|
|
if con_voxel.is_elem('tex'):
|
|
|
|
vert.add_out('vec2 texCoordGeom')
|
|
|
|
vert.write('texCoordGeom = tex;')
|
|
|
|
|
|
|
|
if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
|
|
|
|
vert.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
|
|
|
|
vert.write('voxpositionGeom = (vec3(W * vec4(pos, 1.0)) - eyeSnap) / voxelgiHalfExtents;')
|
|
|
|
else:
|
|
|
|
vert.write('voxpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiHalfExtents;')
|
|
|
|
vert.write('wnormalGeom = normalize(N * nor);')
|
|
|
|
|
|
|
|
if is_shadows:
|
|
|
|
vert.add_out('vec4 lampPosGeom')
|
|
|
|
vert.add_uniform('mat4 LWVP', '_biasLampWorldViewProjectionMatrix')
|
|
|
|
vert.write('lampPosGeom = LWVP * vec4(pos, 1.0);')
|
|
|
|
|
|
|
|
geom.add_out('vec3 voxposition')
|
|
|
|
geom.add_out('vec3 wnormal')
|
|
|
|
if is_shadows:
|
|
|
|
geom.add_out('vec4 lampPos')
|
|
|
|
if con_voxel.is_elem('col'):
|
|
|
|
geom.add_out('vec3 vcolor')
|
|
|
|
if con_voxel.is_elem('tex'):
|
|
|
|
geom.add_out('vec2 texCoord')
|
|
|
|
if export_mpos:
|
|
|
|
geom.add_out('vec3 mposition')
|
|
|
|
|
|
|
|
geom.write('vec3 p1 = voxpositionGeom[1] - voxpositionGeom[0];')
|
|
|
|
geom.write('vec3 p2 = voxpositionGeom[2] - voxpositionGeom[0];')
|
|
|
|
geom.write('vec3 p = abs(cross(p1, p2));')
|
|
|
|
geom.write('for (uint i = 0; i < 3; ++i) {')
|
|
|
|
geom.write(' voxposition = voxpositionGeom[i];')
|
|
|
|
geom.write(' wnormal = wnormalGeom[i];')
|
|
|
|
if is_shadows:
|
|
|
|
geom.write(' lampPos = lampPosGeom[i];')
|
|
|
|
if con_voxel.is_elem('col'):
|
|
|
|
geom.write(' vcolor = vcolorGeom[i];')
|
|
|
|
if con_voxel.is_elem('tex'):
|
|
|
|
geom.write(' texCoord = texCoordGeom[i];')
|
|
|
|
if export_mpos:
|
|
|
|
geom.write(' mposition = mpositionGeom[i];')
|
|
|
|
geom.write(' if (p.z > p.x && p.z > p.y) {')
|
|
|
|
geom.write(' gl_Position = vec4(voxposition.x, voxposition.y, 0.0, 1.0);')
|
|
|
|
geom.write(' }')
|
|
|
|
geom.write(' else if (p.x > p.y && p.x > p.z) {')
|
|
|
|
geom.write(' gl_Position = vec4(voxposition.y, voxposition.z, 0.0, 1.0);')
|
|
|
|
geom.write(' }')
|
|
|
|
geom.write(' else {')
|
|
|
|
geom.write(' gl_Position = vec4(voxposition.x, voxposition.z, 0.0, 1.0);')
|
|
|
|
geom.write(' }')
|
|
|
|
geom.write(' EmitVertex();')
|
|
|
|
geom.write('}')
|
|
|
|
geom.write('EndPrimitive();')
|
|
|
|
|
|
|
|
if cycles.emission_found:
|
|
|
|
frag.write('vec3 color = basecol;')
|
|
|
|
else:
|
|
|
|
frag.write('vec3 color = basecol * visibility * lightColor * dotNL;')
|
|
|
|
frag.write('vec3 voxel = voxposition * 0.5 + 0.5;')
|
|
|
|
|
|
|
|
if rpdat.arm_voxelgi_emission:
|
|
|
|
frag.write('color = min(color * 0.9, vec3(0.9)) + min(color / 200.0, 0.1);') # Higher range to allow emission
|
|
|
|
|
|
|
|
frag.write('color = clamp(color, vec3(0.0), vec3(1.0));')
|
|
|
|
|
|
|
|
if rpdat.rp_voxelgi_hdr:
|
|
|
|
frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
|
|
|
|
else:
|
|
|
|
frag.write('uint val = convVec4ToRGBA8(vec4(color, 1.0) * 255);')
|
|
|
|
frag.write('imageAtomicMax(voxels, ivec3(voxelgiResolution * voxel), val);')
|
|
|
|
|
|
|
|
return con_voxel
|