Last active
January 26, 2024 01:11
-
-
Save josemorval/0051c5e912b60e57786a5467c0873954 to your computer and use it in GitHub Desktop.
voxelizer in lazyengine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require("lualibs.vec") | |
| function init() | |
| -- get usual variables | |
| global_t = get_time() | |
| delta_t = get_delta_time() | |
| screenx,screeny = get_window_size() | |
| mouseposx,mouseposy = imgui_getmousepos() | |
| deltamouseposx = 0 | |
| deltamouseposy = 0 | |
| -- first person camera controller | |
| main_camera = { | |
| eye = vec.new(-5.0,2.0,5.0), | |
| dir = vec.mul(-1.0,vec.normalize(vec.new(-5.0,2.0,5.0))), | |
| lighteye = vec.new(0.001,1.0,0.001), | |
| lightdir = vec.new(0.0,0.0,0.0), | |
| update = function(self) | |
| if imgui_ismousepressed(1) then | |
| local right = transform_view_to_world(1,0,0,0) | |
| local up = transform_view_to_world(0,1,0,0) | |
| local forward = transform_view_to_world(0,0,1,0) | |
| -- w key | |
| if imgui_iskeypressed(568) then | |
| self.eye = vec.add(self.eye,vec.mul(0.1,forward)) | |
| end | |
| -- a key | |
| if imgui_iskeypressed(546) then | |
| self.eye = vec.add(self.eye,vec.mul(-0.1,right)) | |
| end | |
| -- s key | |
| if imgui_iskeypressed(564) then | |
| self.eye = vec.add(self.eye,vec.mul(-0.1,forward)) | |
| end | |
| -- d key | |
| if imgui_iskeypressed(549) then | |
| self.eye = vec.add(self.eye,vec.mul(0.1,right)) | |
| end | |
| if math.abs(deltamouseposx)>1350.0 then deltamouseposx = 0 end | |
| if math.abs(deltamouseposy)>650.0 then deltamouseposy = 0 end | |
| self.dir = vec.add(self.dir, vec.mul(deltamouseposx*0.001,right)) | |
| self.dir = vec.add(self.dir, vec.mul(-deltamouseposy*0.001,up)) | |
| self.dir = vec.normalize(self.dir) | |
| set_camera(self.eye.x,self.eye.y,self.eye.z,self.dir.x,self.dir.y,self.dir.z) | |
| end | |
| end, | |
| use = function(self) | |
| self.lighteye = vec.new(3.0,5.0,2.0) | |
| self.lightdir = vec.mul(-1.0,vec.normalize(self.lighteye)) | |
| set_camera(self.eye.x,self.eye.y,self.eye.z,self.dir.x,self.dir.y,self.dir.z) | |
| set_perspective(1.0,screenx/screeny,0.1,50.0) | |
| set_light_camera(self.lighteye.x,self.lighteye.y,self.lighteye.z,self.lightdir.x,self.lightdir.y,self.lightdir.z) | |
| set_light_orthographic(10.0*screenx/screeny,10.0,0.1,50.0) | |
| update_globalconstantbuffer() | |
| end | |
| } | |
| -- create depth texture | |
| maindepth_texture = create_renderdepth2D(screenx,screeny) | |
| -- create shadow map | |
| shadowmap_texture = create_renderdepth2D(screenx,screeny) | |
| -- create voxel render target | |
| number_voxels = 100 | |
| voxel_texture = create_rendertarget3D(number_voxels,number_voxels,number_voxels) | |
| -- camera for voxelization | |
| voxel_camera = { | |
| eye = vec.new(0.0,0.0,20.0), | |
| dir = vec.new(0.0,0.0,-1.0), | |
| use = function(self) | |
| set_camera(self.eye.x,self.eye.y,self.eye.z,self.dir.x,self.dir.y,self.dir.z) | |
| set_orthographic(20,20,0.1,100.0) | |
| update_globalconstantbuffer() | |
| end | |
| } | |
| -- standard (+ shadowmap) material | |
| standard_material = create_fx("./shaders/gi/standard.hlsl", false) | |
| standard_shadow_material = create_fx("./shaders/gi/standard_shadow.hlsl", false) | |
| -- voxelizer + voxel viewer material | |
| voxelize_material = create_fx("./shaders/gi/voxelize.hlsl", true) | |
| voxelviewer_material = create_fx("./shaders/gi/voxelviewer.hlsl", false) | |
| -- voxel constant buffer | |
| voxel_constant_buffer = create_constantbuffer( 16*2 ) | |
| update_constantbuffer( | |
| voxel_constant_buffer, | |
| 3, 10.0, 4, number_voxels | |
| ) | |
| attach_constantbuffer(voxel_constant_buffer,3) | |
| -- create two cube entities. defined below | |
| cube = create_cube() | |
| ground = create_cube() | |
| end | |
| function imgui() | |
| end | |
| -- main logic loop | |
| function render() | |
| global_t = get_time() | |
| delta_t = get_delta_time() | |
| update_mousepos() | |
| ----------------------- | |
| -- shadowmap render | |
| ----------------------- | |
| main_camera:update() | |
| main_camera:use() | |
| use_viewport(0,0,screenx,screeny) | |
| use_rasterizer() | |
| use_write_depthstencil() | |
| clear_depth_renderdepth2D(shadowmap_texture) | |
| set_depth_renderdepth2D(shadowmap_texture) | |
| use_fx(standard_shadow_material) | |
| render_scene() | |
| ----------------------- | |
| -- voxelization | |
| ----------------------- | |
| voxel_camera:use() | |
| use_viewport(0,0,number_voxels,number_voxels) | |
| use_nocull_rasterizer() | |
| clear_depthstencil() | |
| --voxelize scene | |
| clear_rendertarget_rendertarget3D(voxel_texture,0.0,0.0,0.0,0.0) | |
| set_rendertarget_depth_and_uavs(false,{},{},{voxel_texture},-1,1) | |
| use_fx(voxelize_material) | |
| attach_srv_renderdepth2D(shadowmap_texture,0) | |
| render_scene() | |
| clean_srv(0) | |
| ----------------------- | |
| -- voxelization viewer | |
| ----------------------- | |
| main_camera:use() | |
| use_viewport(0,0,screenx,screeny) | |
| use_write_depthstencil() | |
| -- ping-pong between normal/wireframe viz | |
| e,f = math.modf(0.2*global_t,1.0) | |
| if f > 0.5 then | |
| use_rasterizer() | |
| else | |
| use_wireframe_rasterizer() | |
| end | |
| -- sky color | |
| clear_rendertarget_backbuffer(0.4,0.7,1.0,1.0) | |
| clear_depth_renderdepth2D(maindepth_texture) | |
| set_rendertarget_and_depth_backbuffer(maindepth_texture) | |
| use_fx(voxelviewer_material) | |
| attach_srv_rendertarget3D(voxel_texture,1) | |
| use_cube() | |
| draw_instances_cube(number_voxels * number_voxels * number_voxels) | |
| clean_srv(1) | |
| end | |
| -- as simple scene | |
| function render_scene() | |
| cube.rotation = vec.new(math.sin(global_t),math.cos(global_t),math.sin(global_t),0.5) | |
| cube.scale = vec.new(2.0,2.0,2.0) | |
| cube.position = vec.new(-2.0,0.0,0.0) | |
| cube:draw() | |
| cube.rotation = vec.new(math.sin(global_t+1.0),math.cos(global_t+1.0),math.sin(global_t+1.0),0.5) | |
| cube.scale = vec.new(1.0,1.0,1.0) | |
| cube.position = vec.new(1.0,0.0,2.0) | |
| cube:draw() | |
| cube.rotation = vec.new(math.sin(global_t+1.0),math.cos(global_t+1.0),math.sin(global_t+1.0),0.5) | |
| cube.scale = vec.new(-1.0,1.0,1.0) | |
| cube.position = vec.new(1.0,0.0,2.0) | |
| cube:draw() | |
| cube.rotation = vec.new(math.sin(global_t+1.0),math.cos(global_t+1.0),math.sin(global_t+1.0),0.5) | |
| cube.scale = vec.new(-1.0,1.0,1.0) | |
| cube.position = vec.new(1.0,0.3,-1.0) | |
| cube:draw() | |
| ground.position = vec.new(0.0,-1.0,0.0) | |
| ground.scale = vec.new(5.0,0.2,5.0) | |
| ground:draw() | |
| end | |
| function cleanup() | |
| end | |
| --------------------- | |
| -- Helpers ---------- | |
| --------------------- | |
| function create_cube() | |
| return { | |
| position = vec.new(0,0,0), | |
| rotation = vec.new(0,1,0,0), | |
| scale = vec.new(1,1,1), | |
| draw = function(self) | |
| use_cube() | |
| set_translation_transform(0,self.position.x,self.position.y,self.position.z) | |
| set_rotation_transform(0,self.rotation.x,self.rotation.y,self.rotation.z,self.rotation.w) | |
| set_scale_transform(0,self.scale.x,self.scale.y,self.scale.z) | |
| update_transformbuffer() | |
| draw_instances_cube(1) | |
| end | |
| } | |
| end | |
| function transform_view_to_world(x,y,z,w) | |
| local vx,vy,vz,vw = inv_transform_point_camera(x,y,z,w) | |
| v = vec.new(vx,vy,vz) | |
| return v | |
| end | |
| function update_mousepos() | |
| newmouseposx, newmouseposy = imgui_getmousepos() | |
| deltamouseposx = newmouseposx - mouseposx | |
| deltamouseposy = newmouseposy - mouseposy | |
| mouseposx = newmouseposx | |
| mouseposy = newmouseposy | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| SamplerState linear_wrap_sampler | |
| { | |
| Filter = MIN_MAG_MIP_LINEAR; | |
| AddressU = WRAP; | |
| AddressV = WRAP; | |
| AddressW = WRAP; | |
| }; | |
| SamplerState point_wrap_sampler | |
| { | |
| Filter = MIN_MAG_MIP_POINT; | |
| AddressU = WRAP; | |
| AddressV = WRAP; | |
| AddressW = WRAP; | |
| }; | |
| SamplerState linear_clamp_sampler | |
| { | |
| Filter = MIN_MAG_MIP_LINEAR; | |
| AddressU = CLAMP; | |
| AddressV = CLAMP; | |
| AddressW = CLAMP; | |
| }; | |
| SamplerState point_clamp_sampler | |
| { | |
| Filter = MIN_MAG_MIP_POINT; | |
| AddressU = CLAMP; | |
| AddressV = CLAMP; | |
| AddressW = CLAMP; | |
| }; | |
| cbuffer constants : register(b0) | |
| { | |
| float4x4 g_view_matrix; | |
| float4x4 g_inv_view_matrix; | |
| float4x4 g_projection_matrix; | |
| float4x4 g_light_view_matrix; | |
| float4x4 g_light_inv_view_matrix; | |
| float4x4 g_light_projection_matrix; | |
| float g_global_time; | |
| float g_delta_time; | |
| }; | |
| cbuffer transform_constants : register(b1) | |
| { | |
| float4x4 translation_matrix[64]; | |
| float4x4 rotation_matrix[64]; | |
| float4x4 scale_matrix[64]; | |
| }; | |
| cbuffer custom_data_constants : register(b2) | |
| { | |
| float4 custom_data0; | |
| float4 custom_data1; | |
| float4 custom_data2; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| cbuffer voxel_constants : register(b3) | |
| { | |
| float4 g_voxel_center_size; | |
| float4 g_voxel_dim; | |
| }; | |
| RWTexture3D<float4> voxelize_scene_render : register(u1); | |
| Texture2D<float4> light_shadowmap_texture : register(t0); | |
| Texture3D<float4> voxelize_scene_texture : register(t1); | |
| float compute_direct_lighting(float3 world_position, float3 world_normal, Texture2D t_texture, SamplerState s_texture) | |
| { | |
| float4 position_light_space = mul(g_light_view_matrix, float4(world_position, 1.0)); | |
| position_light_space = mul(g_light_projection_matrix, position_light_space); | |
| float depth = t_texture.Sample(s_texture, 0.5 - 0.5 * float2(-1.0, 1.0) * position_light_space.xy).r; | |
| float current_depth = position_light_space.z; | |
| float3 light_forward = -(mul(g_light_inv_view_matrix, float4(0.0, 0.0, 1.0, 0.0))).xyz; | |
| float sha = smoothstep(0.001, 0.0, current_depth-depth); | |
| float3 nor = normalize(world_normal); | |
| float dif = clamp(dot(nor, normalize(light_forward)), 0.0, 1.0); | |
| return sha * dif; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "./shaders/common.hlsl" | |
| #include "./shaders/gi/gi_common.hlsl" | |
| struct VS_INPUT { | |
| float3 position : POSITION; | |
| float2 texcoord : TEXCOORD; | |
| float3 normal : NORMAL; | |
| uint instanceid : SV_InstanceID; | |
| }; | |
| struct VS_OUTPUT { | |
| float4 position : SV_POSITION; | |
| float2 texcoord : TEXCOORD0; | |
| float3 world_position: TEXCOORD1; | |
| float3 world_normal : TEXCOORD2; | |
| float3 local_position : TEXCOORD3; | |
| }; | |
| VS_OUTPUT vs_main(VS_INPUT i) | |
| { | |
| VS_OUTPUT o; | |
| float4 local_pos = float4(i.position,1.0); | |
| o.world_position = mul(translation_matrix[i.instanceid],mul(rotation_matrix[i.instanceid],mul(scale_matrix[i.instanceid],float4(local_pos.xyz,1.0)))); | |
| o.position = mul(g_projection_matrix,mul(g_view_matrix,float4(o.world_position,1.0))); | |
| o.world_normal = normalize(mul(rotation_matrix[i.instanceid],float4(i.normal,0.0)).xyz); | |
| o.texcoord = i.texcoord; | |
| o.local_position = mul(scale_matrix[i.instanceid],float4(i.position,1.0)).xyz; | |
| return o; | |
| } | |
| float4 ps_main(VS_OUTPUT i) : SV_TARGET | |
| { | |
| float dili = compute_direct_lighting(i.world_position, i.world_normal, light_shadowmap_texture, linear_wrap_sampler); | |
| float3 color = float3(1.0,0.9,0.8); | |
| color *= dili; | |
| return float4(color,1.0); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "./shaders/common.hlsl" | |
| struct VS_INPUT { | |
| float3 position : POSITION; | |
| float2 texcoord : TEXCOORD; | |
| float3 normal : NORMAL; | |
| uint instanceid : SV_InstanceID; | |
| }; | |
| struct VS_OUTPUT { | |
| float4 position : SV_POSITION; | |
| float2 texcoord : TEXCOORD0; | |
| float3 world_position: TEXCOORD1; | |
| float3 world_normal : TEXCOORD2; | |
| float3 local_position : TEXCOORD3; | |
| }; | |
| VS_OUTPUT vs_main(VS_INPUT i) | |
| { | |
| VS_OUTPUT o; | |
| float4 local_pos = float4(i.position,1.0); | |
| o.world_position = mul(translation_matrix[i.instanceid],mul(rotation_matrix[i.instanceid],mul(scale_matrix[i.instanceid],float4(local_pos.xyz,1.0)))); | |
| o.position = mul(g_light_projection_matrix,mul(g_light_view_matrix,float4(o.world_position,1.0))); | |
| o.world_normal = normalize(mul(rotation_matrix[i.instanceid],float4(i.normal,0.0)).xyz); | |
| o.texcoord = i.texcoord; | |
| o.local_position = mul(scale_matrix[i.instanceid],float4(i.position,1.0)).xyz; | |
| return o; | |
| } | |
| float4 ps_main(VS_OUTPUT i) : SV_TARGET | |
| { | |
| return float4(0.0,0.0,0.0,0.0); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "./shaders/common.hlsl" | |
| #include "./shaders/gi/gi_common.hlsl" | |
| struct VS_INPUT { | |
| float3 position : POSITION; | |
| float2 texcoord : TEXCOORD; | |
| float3 normal : NORMAL; | |
| uint instanceid : SV_InstanceID; | |
| }; | |
| struct VS_OUTPUT { | |
| float4 position : POSITION; | |
| float2 texcoord : TEXCOORD0; | |
| float3 normal : NORMAL; | |
| }; | |
| struct PS_INPUT { | |
| float4 position : SV_POSITION; | |
| float3 world_position : TEXCOORD0; | |
| float3 world_normal : TEXCOORD1; | |
| float2 texcoord : TEXCOORD2; | |
| }; | |
| VS_OUTPUT vs_main(VS_INPUT i) | |
| { | |
| VS_OUTPUT o; | |
| float4 local_pos = float4(i.position,1.0); | |
| o.position = mul(translation_matrix[i.instanceid],mul(rotation_matrix[i.instanceid],mul(scale_matrix[i.instanceid],float4(local_pos.xyz,1.0)))); | |
| o.texcoord = i.texcoord; | |
| o.normal = normalize(mul(rotation_matrix[i.instanceid],float4(i.normal,0.0)).xyz); | |
| return o; | |
| } | |
| [maxvertexcount(3)] | |
| void gs_main(triangle VS_OUTPUT input[3], inout TriangleStream<PS_INPUT> triStream) | |
| { | |
| for (int i = 0; i < 3; i++) | |
| { | |
| PS_INPUT output; | |
| float angle = 2. * 3.1419 * float(i)/3.0; | |
| float2 posxy = 0.7*float2(cos(angle), sin(angle)); | |
| output.position = float4(posxy,1.0,1.0); | |
| output.world_position = input[i].position; | |
| output.world_normal = input[i].normal; | |
| output.texcoord = input[i].texcoord; | |
| triStream.Append(output); | |
| } | |
| triStream.RestartStrip(); | |
| } | |
| float4 ps_main(PS_INPUT i) : SV_TARGET | |
| { | |
| float li = compute_direct_lighting(i.world_position, i.world_normal, light_shadowmap_texture, point_wrap_sampler); | |
| float3 world_position_centered = i.world_position - g_voxel_center_size.xyz; | |
| world_position_centered = floor((world_position_centered/g_voxel_center_size.w + 0.5) * g_voxel_dim.x); | |
| if ( | |
| world_position_centered.x < g_voxel_dim.x && | |
| world_position_centered.y < g_voxel_dim.x && | |
| world_position_centered.z < g_voxel_dim.x | |
| ) | |
| { | |
| voxelize_scene_render[uint3(world_position_centered.x, world_position_centered.y, world_position_centered.z)] = float4(li*float3(1.0,1.0,1.0), 1.0); | |
| } | |
| return float4(0.0,0.0,0.0,0.0); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "./shaders/common.hlsl" | |
| #include "./shaders/gi/gi_common.hlsl" | |
| struct VS_INPUT { | |
| float3 position : POSITION; | |
| float2 texcoord : TEXCOORD; | |
| float3 normal : NORMAL; | |
| uint instanceid : SV_InstanceID; | |
| }; | |
| struct VS_OUTPUT { | |
| float4 position : SV_POSITION; | |
| float3 color : TEXCOORD; | |
| }; | |
| VS_OUTPUT vs_main(VS_INPUT i) | |
| { | |
| VS_OUTPUT o; | |
| float4 local_pos = float4(i.position,1.0); | |
| uint3 voxel_index = uint3(0,0,0); | |
| { | |
| int i_voxel_dim = floor(g_voxel_dim.x); | |
| int x = i.instanceid % i_voxel_dim; | |
| int y = ((i.instanceid - x)/i_voxel_dim) % i_voxel_dim; | |
| int z = (i.instanceid - x - g_voxel_dim * y) / (i_voxel_dim * i_voxel_dim); | |
| voxel_index = uint3(x,y,z); | |
| } | |
| float3 world_position_offset = (voxel_index / g_voxel_dim.x - 0.5) * g_voxel_center_size.w + g_voxel_center_size.xyz; | |
| if( voxelize_scene_texture[ voxel_index ].a < 0.5 ) local_pos.xyz *= 0; | |
| float3 world_position = world_position_offset + local_pos.xyz * g_voxel_center_size.w / g_voxel_dim.x; | |
| o.position = mul(g_projection_matrix,mul(g_view_matrix,float4(world_position,1.0))); | |
| o.color = voxelize_scene_texture[ voxel_index ].rgb; | |
| return o; | |
| } | |
| float4 ps_main(VS_OUTPUT i) : SV_TARGET | |
| { | |
| float3 color = i.color; | |
| return float4(color,1.0); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment