armory/blender/arm/material/make_voxel.py

142 lines
7 KiB
Python
Raw Normal View History

2017-03-12 17:29:22 +01:00
import bpy
2021-08-04 22:49:38 +02:00
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.mat_state as mat_state
2021-08-04 22:49:38 +02:00
if arm.is_reload(__name__):
2021-08-04 22:49:38 +02:00
arm.utils = arm.reload_module(arm.utils)
assets = arm.reload_module(assets)
mat_state = arm.reload_module(mat_state)
else:
arm.enable_reload(__name__)
2021-08-04 22:49:38 +02:00
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()
con = make_ao(context_id)
2017-12-20 15:37:58 +01:00
assets.vs_equal(con, assets.shader_cons['voxel_vert'])
2018-12-04 19:06:01 +01:00
assets.fs_equal(con, assets.shader_cons['voxel_frag'])
assets.gs_equal(con, assets.shader_cons['voxel_geom'])
2017-12-20 15:37:58 +01:00
return con
2017-08-22 10:04:13 +02:00
def make_ao(context_id):
2019-04-06 13:03:04 +02:00
con_voxel = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'always', 'cull_mode': 'none', 'color_writes_red': [False], 'color_writes_green': [False], 'color_writes_blue': [False], 'color_writes_alpha': [False], 'conservative_raster': False })
2017-08-22 10:04:13 +02:00
wrd = bpy.data.worlds['Arm']
2018-12-04 19:06:01 +01:00
rpdat = arm.utils.get_rp()
2017-08-22 10:04:13 +02:00
vert = con_voxel.make_vert()
frag = con_voxel.make_frag()
geom = con_voxel.make_geom()
tesc = None
tese = None
2018-12-04 19:06:01 +01:00
if arm.utils.get_gapi() == 'direct3d11':
2018-12-14 15:27:43 +01:00
for e in con_voxel.data['vertex_elements']:
2018-12-04 19:06:01 +01:00
if e['name'] == 'nor':
2018-12-14 15:27:43 +01:00
con_voxel.data['vertex_elements'].remove(e)
2018-12-04 19:06:01 +01:00
break
# No geom shader compiler for hlsl yet
vert.noprocessing = True
frag.noprocessing = True
geom.noprocessing = True
vert.add_uniform('mat4 W', '_worldMatrix')
vert.write('uniform float4x4 W;')
2018-12-20 22:37:39 +01:00
if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
vert.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
vert.write('uniform float3 eyeSnap;')
2018-12-14 15:27:43 +01:00
vert.write('struct SPIRV_Cross_Input { float4 pos : TEXCOORD0; };')
2018-12-04 19:06:01 +01:00
vert.write('struct SPIRV_Cross_Output { float4 svpos : SV_POSITION; };')
vert.write('SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) {')
vert.write(' SPIRV_Cross_Output stage_output;')
voxHalfExt = str(round(rpdat.arm_voxelgi_dimensions / 2.0))
if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
2019-01-11 20:42:16 +01:00
vert.write(' stage_output.svpos.xyz = (mul(float4(stage_input.pos.xyz, 1.0), W).xyz - eyeSnap) / float3(' + voxHalfExt + ', ' + voxHalfExt + ', ' + voxHalfExt + ');')
2018-12-04 19:06:01 +01:00
else:
vert.write(' stage_output.svpos.xyz = mul(float4(stage_input.pos.xyz, 1.0), W).xyz / float3(' + voxHalfExt + ', ' + voxHalfExt + ', ' + voxHalfExt + ');')
vert.write(' stage_output.svpos.w = 1.0;')
vert.write(' return stage_output;')
vert.write('}')
geom.write('struct SPIRV_Cross_Input { float4 svpos : SV_POSITION; };')
geom.write('struct SPIRV_Cross_Output { float3 wpos : TEXCOORD0; float4 svpos : SV_POSITION; };')
geom.write('[maxvertexcount(3)]')
geom.write('void main(triangle SPIRV_Cross_Input stage_input[3], inout TriangleStream<SPIRV_Cross_Output> output) {')
geom.write(' float3 p1 = stage_input[1].svpos.xyz - stage_input[0].svpos.xyz;')
geom.write(' float3 p2 = stage_input[2].svpos.xyz - stage_input[0].svpos.xyz;')
geom.write(' float3 p = abs(cross(p1, p2));')
geom.write(' for (int i = 0; i < 3; ++i) {')
geom.write(' SPIRV_Cross_Output stage_output;')
geom.write(' stage_output.wpos = stage_input[i].svpos.xyz;')
2017-10-26 22:13:21 +02:00
geom.write(' if (p.z > p.x && p.z > p.y) {')
2018-12-04 19:06:01 +01:00
geom.write(' stage_output.svpos = float4(stage_input[i].svpos.x, stage_input[i].svpos.y, 0.0, 1.0);')
2017-10-26 22:13:21 +02:00
geom.write(' }')
geom.write(' else if (p.x > p.y && p.x > p.z) {')
2018-12-04 19:06:01 +01:00
geom.write(' stage_output.svpos = float4(stage_input[i].svpos.y, stage_input[i].svpos.z, 0.0, 1.0);')
2017-10-26 22:13:21 +02:00
geom.write(' }')
geom.write(' else {')
2018-12-04 19:06:01 +01:00
geom.write(' stage_output.svpos = float4(stage_input[i].svpos.x, stage_input[i].svpos.z, 0.0, 1.0);')
2017-10-26 22:13:21 +02:00
geom.write(' }')
2018-12-04 19:06:01 +01:00
geom.write(' output.Append(stage_output);')
geom.write(' }')
2017-10-26 22:13:21 +02:00
geom.write('}')
2018-12-04 19:06:01 +01:00
frag.add_uniform('layout(r8) writeonly image3D voxels')
frag.write('RWTexture3D<float> voxels;')
frag.write('struct SPIRV_Cross_Input { float3 wpos : TEXCOORD0; };')
frag.write('struct SPIRV_Cross_Output { float4 FragColor : SV_TARGET0; };')
frag.write('void main(SPIRV_Cross_Input stage_input) {')
2018-12-07 13:48:40 +01:00
frag.write(' if (abs(stage_input.wpos.z) > ' + rpdat.rp_voxelgi_resolution_z + ' || abs(stage_input.wpos.x) > 1 || abs(stage_input.wpos.y) > 1) return;')
2018-12-04 19:06:01 +01:00
voxRes = str(rpdat.rp_voxelgi_resolution)
voxResZ = str(int(int(rpdat.rp_voxelgi_resolution) * float(rpdat.rp_voxelgi_resolution_z)))
frag.write(' voxels[int3(' + voxRes + ', ' + voxRes + ', ' + voxResZ + ') * (stage_input.wpos * 0.5 + 0.5)] = 1.0;')
frag.write('')
frag.write('}')
else:
geom.ins = vert.outs
frag.ins = geom.outs
frag.add_include('compiled.inc')
frag.add_include('std/math.glsl')
frag.add_include('std/imageatomic.glsl')
frag.write_header('#extension GL_ARB_shader_image_load_store : enable')
frag.add_uniform('layout(r8) writeonly image3D voxels')
vert.add_include('compiled.inc')
vert.add_uniform('mat4 W', '_worldMatrix')
vert.add_out('vec3 voxpositionGeom')
if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
vert.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
2018-12-14 15:27:43 +01:00
vert.write('voxpositionGeom = (vec3(W * vec4(pos.xyz, 1.0)) - eyeSnap) / voxelgiHalfExtents;')
2021-08-04 22:49:38 +02:00
else:
2018-12-14 15:27:43 +01:00
vert.write('voxpositionGeom = vec3(W * vec4(pos.xyz, 1.0)) / voxelgiHalfExtents;')
2018-12-04 19:06:01 +01:00
2019-01-11 20:42:16 +01:00
geom.add_out('vec3 voxposition')
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(' 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