Fix voxelize pass
This commit is contained in:
parent
27a423fd23
commit
4c10c37396
|
@ -10,7 +10,9 @@ precision mediump float;
|
|||
// #ifdef _PolyLight
|
||||
#include "../std/ltc.glsl"
|
||||
// #endif
|
||||
// ...
|
||||
#ifdef _VoxelGI
|
||||
#include "../std/conetrace.glsl"
|
||||
#endif
|
||||
#ifndef _NoShadows
|
||||
#ifdef _PCSS
|
||||
#include "../std/shadows_pcss.glsl"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
uniform sampler3D voxels;
|
||||
const float voxelGridWorldSize = 150.0;
|
||||
const int voxelDimensions = 512;
|
||||
const int voxelDimensions = 128;
|
||||
const float maxDist = 30.0;
|
||||
const float alphaThreshold = 0.95;
|
||||
const int numCones = 6;
|
||||
|
@ -45,12 +45,12 @@ vec4 coneTrace(vec3 posWorld, vec3 direction, vec3 norWorld, float tanHalfAngle,
|
|||
}
|
||||
|
||||
vec4 coneTraceIndirect(vec3 posWorld, mat3 tanToWorld, vec3 norWorld, out float occlusion) {
|
||||
vec4 color = vec4(0);
|
||||
vec4 color = vec4(0.0);
|
||||
occlusion = 0.0;
|
||||
|
||||
for (int i = 0; i < numCones; i++) {
|
||||
float coneOcclusion;
|
||||
const float tanangle = tan(30):
|
||||
const float tanangle = tan(30.0);
|
||||
color += coneWeights[i] * coneTrace(posWorld, tanToWorld * coneDirections[i], norWorld, tanangle, coneOcclusion);
|
||||
occlusion += coneWeights[i] * coneOcclusion;
|
||||
}
|
||||
|
|
|
@ -424,9 +424,9 @@ 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=['tex', 'gbufferD'], 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='deferred_light/deferred_light/deferred_light')
|
||||
# Draw lamp volume - TODO: properly generate stage
|
||||
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3], bind_target_constants=['gbuffer', 'shadowMap'], shader_context='deferred_light/deferred_light/deferred_light')
|
||||
# make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3], bind_target_constants=['gbuffer', 'shadowMap'], shader_context='deferred_light/deferred_light/deferred_light')
|
||||
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3, 4], bind_target_constants=['gbuffer', 'shadowMap', 'voxels'], shader_context='deferred_light/deferred_light/deferred_light')
|
||||
stages[-1]['command'] = 'draw_lamp_volume'
|
||||
|
||||
def make_volumetric_light_pass(stages, node_group, node):
|
||||
|
|
|
@ -12,6 +12,7 @@ import material.make_transluc as make_transluc
|
|||
import material.make_overlay as make_overlay
|
||||
import material.make_depth as make_depth
|
||||
import material.make_decal as make_decal
|
||||
import material.make_voxel as make_voxel
|
||||
|
||||
rpass_hook = None
|
||||
mesh_make = make_mesh.make
|
||||
|
@ -83,6 +84,9 @@ def parse(material, mat_data, mat_users, mat_armusers, rid):
|
|||
elif rp == 'depth':
|
||||
con = make_depth.make(rp)
|
||||
|
||||
elif rp == 'voxel':
|
||||
con = make_voxel.make(rp)
|
||||
|
||||
elif rpass_hook != None:
|
||||
con = rpass_hook(rp)
|
||||
|
||||
|
|
110
blender/material/make_voxel.py
Normal file
110
blender/material/make_voxel.py
Normal file
|
@ -0,0 +1,110 @@
|
|||
# http://simonstechblog.blogspot.sk/2013/01/implementing-voxel-cone-tracing.html
|
||||
# http://leifnode.com/2015/05/voxel-cone-traced-global-illumination/
|
||||
# http://www.seas.upenn.edu/%7Epcozzi/OpenGLInsights/OpenGLInsights-SparseVoxelization.pdf
|
||||
# https://github.com/Cigg/Voxel-Cone-Tracing
|
||||
# https://research.nvidia.com/sites/default/files/publications/GIVoxels-pg2011-authors.pdf
|
||||
|
||||
import material.cycles as cycles
|
||||
import material.mat_state as mat_state
|
||||
import material.mat_utils as mat_utils
|
||||
|
||||
def make(context_id):
|
||||
con_voxel = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'always', 'cull_mode': 'none' })
|
||||
|
||||
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
|
||||
|
||||
vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrix')
|
||||
vert.add_uniform('mat4 W', '_worldMatrix')
|
||||
|
||||
vert.add_out('vec4 lampPos')
|
||||
# vert.add_out('vec2 texuv')
|
||||
|
||||
# vert.write('texuv = tex;')
|
||||
vert.write('lampPos = LWVP * vec4(pos, 1.0);')
|
||||
vert.write('gl_Position = W * vec4(pos, 1.0);')
|
||||
|
||||
geom.add_uniform('mat4 PX', '_projectionXMatrix')
|
||||
geom.add_uniform('mat4 PY', '_projectionYMatrix')
|
||||
geom.add_uniform('mat4 PZ', '_projectionZMatrix')
|
||||
|
||||
#geom.add_out('vec2 geom_texuv')
|
||||
geom.add_out('flat int geom_axis')
|
||||
geom.add_out('vec4 geom_lampPos')
|
||||
|
||||
geom.write('vec3 p1 = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz;')
|
||||
geom.write('vec3 p2 = gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz;')
|
||||
geom.write('vec3 absnor = abs(normalize(cross(p1, p2)));')
|
||||
|
||||
geom.write('mat4 P; // Dominant axis')
|
||||
geom.write('if (absnor.x >= absnor.y && absnor.x >= absnor.z) {')
|
||||
geom.write(' geom_axis = 1;')
|
||||
geom.write(' P = PX;')
|
||||
geom.write('}')
|
||||
geom.write('else if (absnor.y >= absnor.x && absnor.y >= absnor.z) {')
|
||||
geom.write(' geom_axis = 2;')
|
||||
geom.write(' P = PY;')
|
||||
geom.write('}')
|
||||
geom.write('else {')
|
||||
geom.write(' geom_axis = 3;')
|
||||
geom.write(' P = PZ;')
|
||||
geom.write('}')
|
||||
|
||||
geom.write('for (int i = 0; i < gl_in.length(); i++) {')
|
||||
geom.write(' vec3 middlePos = gl_in[0].gl_Position.xyz / 3.0 + gl_in[1].gl_Position.xyz / 3.0 + gl_in[2].gl_Position.xyz / 3.0;')
|
||||
#geom.write(' geom_texuv = texuv[i];')
|
||||
geom.write(' geom_lampPos = lampPos[i];')
|
||||
geom.write(' gl_Position = P * gl_in[i].gl_Position;')
|
||||
geom.write(' EmitVertex();')
|
||||
geom.write('}')
|
||||
geom.write('EndPrimitive();')
|
||||
|
||||
frag.write_header('#extension GL_ARB_shader_image_load_store : enable')
|
||||
|
||||
frag.add_uniform('layout(RGBA8) image3D voxels')
|
||||
#frag.add_uniform('sampler2D sbase')
|
||||
#frag.add_uniform('vec4 baseCol')
|
||||
#frag.add_uniform('sampler2D shadowMap')
|
||||
|
||||
frag.write('const int voxelDimensions = 128;')
|
||||
|
||||
|
||||
frag.write('vec3 basecol;')
|
||||
frag.write('float roughness;')
|
||||
frag.write('float metallic;')
|
||||
frag.write('float occlusion;')
|
||||
cycles.parse(mat_state.nodes, vert, frag, geom, tesc, tese, parse_opacity=False, parse_displacement=False)
|
||||
frag.write('vec4 matCol = vec4(basecol, 1.0);')
|
||||
|
||||
# vec3 lampPos = geom_lampPos.xyz / geom_lampPos.w;
|
||||
# lampPos.xy = lampPos.xy * 0.5 + 0.5;
|
||||
# float distanceFromLight = texture(shadowMap, lampPos.xy).r * 2.0 - 1.0;
|
||||
# const float shadowsBias = 0.0001;
|
||||
# float visibility = float(distanceFromLight > lampPos.z - shadowsBias);
|
||||
frag.write('float visibility = 1.0;')
|
||||
|
||||
frag.write('ivec3 camPos = ivec3(gl_FragCoord.x, gl_FragCoord.y, voxelDimensions * gl_FragCoord.z);')
|
||||
frag.write('ivec3 texPos;')
|
||||
frag.write('if (geom_axis == 1) {')
|
||||
frag.write(' texPos.x = voxelDimensions - camPos.z;')
|
||||
frag.write(' texPos.z = camPos.x;')
|
||||
frag.write(' texPos.y = camPos.y;')
|
||||
frag.write('}')
|
||||
frag.write('else if (geom_axis == 2) {')
|
||||
frag.write(' texPos.z = camPos.y;')
|
||||
frag.write(' texPos.y = voxelDimensions - camPos.z;')
|
||||
frag.write(' texPos.x = camPos.x;')
|
||||
frag.write('}')
|
||||
frag.write('else {')
|
||||
frag.write(' texPos = camPos;')
|
||||
frag.write('}')
|
||||
frag.write('texPos.z = voxelDimensions - texPos.z - 1;')
|
||||
frag.write('imageStore(voxels, texPos, vec4(matCol.rgb * visibility, 1.0));')
|
||||
|
||||
return con_voxel
|
|
@ -36,6 +36,8 @@ def get_rpasses(material):
|
|||
ar.append('mesh')
|
||||
for con in add_mesh_contexts:
|
||||
ar.append(con)
|
||||
if bpy.data.worlds['Arm'].voxelgi:
|
||||
ar.append('voxel')
|
||||
|
||||
shadows_enabled = False
|
||||
for cam in bpy.data.cameras:
|
||||
|
|
|
@ -13,6 +13,7 @@ class Shader:
|
|||
self.functions = {}
|
||||
self.main = ''
|
||||
self.main_pre = ''
|
||||
self.header = ''
|
||||
self.write_pre = False
|
||||
self.tab = 1
|
||||
|
||||
|
@ -27,8 +28,12 @@ class Shader:
|
|||
|
||||
def add_uniform(self, s, link=None, included=False):
|
||||
ar = s.split(' ')
|
||||
if ar[0] == 'sampler2D':
|
||||
self.context.add_texture_unit(ar[0], ar[1], link=link)
|
||||
# layout(RGBA8) image3D voxels
|
||||
utype = ar[-2]
|
||||
uname = ar[-1]
|
||||
if utype.startswith('sampler') or utype.startswith('image'):
|
||||
is_image = True if utype.startswith('image') else None
|
||||
self.context.add_texture_unit(utype, uname, link=link, is_image=is_image)
|
||||
else:
|
||||
# Prefer vec4[] for d3d to avoid padding
|
||||
if ar[0] == 'float' and '[' in ar[1]:
|
||||
|
@ -56,9 +61,14 @@ class Shader:
|
|||
else:
|
||||
self.main += '\t' * self.tab + s + '\n'
|
||||
|
||||
def write_header(self, s):
|
||||
self.header += s + '\n'
|
||||
|
||||
def get(self):
|
||||
s = '#version 450\n'
|
||||
|
||||
s += self.header
|
||||
|
||||
defs = make_utils.def_strings_to_array(bpy.data.worlds['Arm'].world_defs)
|
||||
for a in defs:
|
||||
s += '#define {0}\n'.format(a)
|
||||
|
@ -77,7 +87,7 @@ class Shader:
|
|||
s += 'layout(vertices = 3) out;\n'
|
||||
# Gen outs
|
||||
for sin in self.ins:
|
||||
ar = sin.split(' ') # vec3 wnormal
|
||||
ar = sin.rsplit(' ', 1) # vec3 wnormal
|
||||
tc_s = 'tc_' + ar[1]
|
||||
self.add_out(ar[0] + ' ' + tc_s)
|
||||
# Pass data
|
||||
|
@ -87,6 +97,11 @@ class Shader:
|
|||
in_ext = '[]'
|
||||
s += 'layout(triangles, equal_spacing, ccw) in;\n'
|
||||
|
||||
elif self.shader_type == 'geom':
|
||||
in_ext = '[]'
|
||||
s += 'layout(triangles) in;\n'
|
||||
s += 'layout(triangle_strip, max_vertices = 3) out;\n'
|
||||
|
||||
for a in self.includes:
|
||||
s += '#include "' + a + '"\n'
|
||||
for a in self.ins:
|
||||
|
|
|
@ -104,7 +104,7 @@ class ShaderContext:
|
|||
c['link'] = link
|
||||
self.constants.append(c)
|
||||
|
||||
def add_texture_unit(self, ctype, name, link=None):
|
||||
def add_texture_unit(self, ctype, name, link=None, is_image=None):
|
||||
for c in self.tunits:
|
||||
if c['name'] == name:
|
||||
return
|
||||
|
@ -112,6 +112,8 @@ class ShaderContext:
|
|||
c = { 'name': name }
|
||||
if link != None:
|
||||
c['link'] = link
|
||||
if is_image != None:
|
||||
c['is_image'] = is_image
|
||||
self.tunits.append(c)
|
||||
|
||||
def make_vert(self):
|
||||
|
|
|
@ -295,6 +295,8 @@ class DeferredLightPassNode(Node, CGPipelineTreeNode):
|
|||
self.inputs.new('NodeSocketShader', "Target")
|
||||
self.inputs.new('NodeSocketShader', "GBuffer")
|
||||
self.inputs.new('NodeSocketShader', "Shadow Map")
|
||||
# Testing voxels
|
||||
self.inputs.new('NodeSocketShader', "Voxels")
|
||||
|
||||
self.outputs.new('NodeSocketShader', "Stage")
|
||||
|
||||
|
|
|
@ -432,7 +432,7 @@ def init_properties():
|
|||
items=[('Lambert', 'Lambert', 'Lambert'),
|
||||
('Oren Nayar', 'Oren Nayar', 'Oren Nayar')],
|
||||
name="Diffuse", description="Diffuse model", default='Lambert', update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.voxelgi = bpy.props.BoolProperty(name="VGI", description="Voxel-based Global Illumination", default=False, update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.voxelgi = bpy.props.BoolProperty(name="Voxel GI", description="Voxel-based Global Illumination", default=False, update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.voxelgi_dimensions = bpy.props.FloatVectorProperty(name="Dimensions", description="3D texture size", size=3, default=[128, 128, 128], update=assets.invalidate_shader_cache)
|
||||
# For material
|
||||
bpy.types.Material.is_cached = bpy.props.BoolProperty(name="Material Cached", description="No need to reexport material data", default=False, update=update_mat_cache)
|
||||
|
|
Loading…
Reference in a new issue