Skip to content

Instantly share code, notes, and snippets.

@josemorval
Last active January 26, 2024 01:11
Show Gist options
  • Save josemorval/0051c5e912b60e57786a5467c0873954 to your computer and use it in GitHub Desktop.
Save josemorval/0051c5e912b60e57786a5467c0873954 to your computer and use it in GitHub Desktop.

Revisions

  1. josemorval renamed this gist Jan 26, 2024. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. josemorval created this gist Jan 26, 2024.
    57 changes: 57 additions & 0 deletions common.hlsl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,57 @@
    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;
    }
    29 changes: 29 additions & 0 deletions gi_common.hlsl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,29 @@
    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;
    }
    255 changes: 255 additions & 0 deletions main.lua
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,255 @@
    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
    41 changes: 41 additions & 0 deletions standard.hlsl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,41 @@
    #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);
    }
    36 changes: 36 additions & 0 deletions standard_shadow.hlsl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    #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);
    }
    73 changes: 73 additions & 0 deletions voxelize.hlsl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    #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);
    }
    47 changes: 47 additions & 0 deletions voxelviewer.hlsl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    #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);
    }