Skip to content

Commit

Permalink
Add files for dx12lightscatterscene
Browse files Browse the repository at this point in the history
Currently it only clears screen
  • Loading branch information
quadpixels committed Feb 7, 2024
1 parent 9dda232 commit 64d5986
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 1 deletion.
132 changes: 132 additions & 0 deletions dx12helloworld/DX12LightScatterScene.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include "scene.hpp"

#include <assert.h>

#include <d3d12.h>
#include "d3dx12.h"
#include <dxgi1_4.h>
#include <wrl/client.h>

#include "util.hpp"

using Microsoft::WRL::ComPtr;

extern int WIN_W, WIN_H;
extern ID3D12Device* g_device12;
extern int g_frame_index;
extern ID3D12CommandQueue* g_command_queue;
extern IDXGISwapChain3* g_swapchain;
extern ID3D12DescriptorHeap* g_rtv_heap;
extern ID3D12Resource* g_rendertargets[];
extern unsigned g_rtv_descriptor_size;

void WaitForPreviousFrame();

DX12LightScatterScene::DX12LightScatterScene() {
CE(g_device12->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
IID_PPV_ARGS(&command_allocator)));
CE(g_device12->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT,
command_allocator, nullptr, IID_PPV_ARGS(&command_list)));
CE(command_list->Close());

ID3DBlob* error = nullptr;
unsigned compile_flags = 0;
D3DCompileFromFile(L"shaders/shaders_drawlight.hlsl", nullptr, nullptr,
"VSMain", "vs_4_0", compile_flags, 0, &vs_drawlight, &error);
if (error) {
printf("Error compiling VS: %s\n", error->GetBufferPointer());
}
D3DCompileFromFile(L"shaders/shaders_drawlight.hlsl", nullptr, nullptr,
"PSMain", "ps_4_0", compile_flags, 0, &ps_drawlight, &error);
if (error) {
printf("Error compiling PS: %s\n", error->GetBufferPointer());
}

// Root signature
CD3DX12_ROOT_PARAMETER1 root_parameters[1];
root_parameters[0].InitAsConstantBufferView(0, 0,
D3D12_ROOT_DESCRIPTOR_FLAG_NONE, D3D12_SHADER_VISIBILITY_ALL);
CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC root_sig_desc;
root_sig_desc.Init_1_1(_countof(root_parameters), root_parameters, 0,
NULL, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
ComPtr<ID3DBlob> signature;
HRESULT hr = D3DX12SerializeVersionedRootSignature(&root_sig_desc,
D3D_ROOT_SIGNATURE_VERSION_1_1,
&signature, &error);
if (signature == nullptr) {
printf("Could not serialize root signature: %s\n",
(char*)(error->GetBufferPointer()));
}

CE(g_device12->CreateRootSignature(0, signature->GetBufferPointer(),
signature->GetBufferSize(), IID_PPV_ARGS(&root_signature)));
root_signature->SetName(L"Root signature");

D3D12_INPUT_ELEMENT_DESC input_element_desc[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12,
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
};
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = {
.pRootSignature = root_signature,
.VS = CD3DX12_SHADER_BYTECODE(vs_drawlight),
.PS = CD3DX12_SHADER_BYTECODE(ps_drawlight),
.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT),
.SampleMask = UINT_MAX,
.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT),
.DepthStencilState = {
.DepthEnable = false,
.StencilEnable = false,
},
.InputLayout = {
input_element_desc, 2
},
.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
.NumRenderTargets = 1,
.RTVFormats = {
DXGI_FORMAT_R8G8B8A8_UNORM,
},
.DSVFormat = DXGI_FORMAT_UNKNOWN,
.SampleDesc = {
.Count = 1,
}
};

CE(g_device12->CreateGraphicsPipelineState(&pso_desc, IID_PPV_ARGS(&pipeline_state)));
}

void DX12LightScatterScene::Render() {
CE(command_allocator->Reset());
CE(command_list->Reset(command_allocator, pipeline_state));

float bg_color[] = { 1.0f, 0.8f, 0.8f, 1.0f };

CD3DX12_CPU_DESCRIPTOR_HANDLE handle_rtv(
g_rtv_heap->GetCPUDescriptorHandleForHeapStart(),
g_frame_index, g_rtv_descriptor_size);
command_list->ResourceBarrier(1, &keep(CD3DX12_RESOURCE_BARRIER::Transition(
g_rendertargets[g_frame_index],
D3D12_RESOURCE_STATE_PRESENT,
D3D12_RESOURCE_STATE_RENDER_TARGET)));

D3D12_VIEWPORT viewport = CD3DX12_VIEWPORT(0.0f, 0.0f, 1.0f * WIN_W, 1.0f * WIN_H, -100.0f, 100.0f);
D3D12_RECT scissor = CD3DX12_RECT(0, 0, long(WIN_W), long(WIN_H));

command_list->SetGraphicsRootSignature(root_signature);

command_list->ClearRenderTargetView(handle_rtv, bg_color, 0, nullptr);

command_list->ResourceBarrier(1, &keep(CD3DX12_RESOURCE_BARRIER::Transition(
g_rendertargets[g_frame_index],
D3D12_RESOURCE_STATE_PRESENT,
D3D12_RESOURCE_STATE_RENDER_TARGET)));
CE(command_list->Close());
g_command_queue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&command_list);
CE(g_swapchain->Present(1, 0));
WaitForPreviousFrame();
}

void DX12LightScatterScene::Update(float secs) {

}
1 change: 1 addition & 0 deletions dx12helloworld/dx12helloworld.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
<ClCompile Include="DX12ChunksScene.cpp" />
<ClCompile Include="DX12ClearScreenScene.cpp" />
<ClCompile Include="DX12HelloTriangleScene.cpp" />
<ClCompile Include="DX12LightScatterScene.cpp" />
<ClCompile Include="DX12TextScene.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="utils.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions dx12helloworld/dx12helloworld.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
<ClCompile Include="..\textrender.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DX12LightScatterScene.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="scene.hpp">
Expand Down
7 changes: 6 additions & 1 deletion dx12helloworld/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ ID3D12Resource* g_rendertargets[FRAME_COUNT];
unsigned g_rtv_descriptor_size;
int g_frame_index;

static Scene* g_scenes[4];
static Scene* g_scenes[5];
static int g_scene_idx = 0;

// Override the following functions for DX12
Expand Down Expand Up @@ -174,6 +174,10 @@ void OnKeyDown(WPARAM wParam, LPARAM lParam) {
printf("Current scene set to 3\n");
g_scene_idx = 3; break;
}
case '4': {
printf("Current scene set to 4\n");
g_scene_idx = 4; break;
}
default: break;
}
}
Expand Down Expand Up @@ -268,6 +272,7 @@ int main() {
g_scenes[1] = new DX12HelloTriangleScene();
g_scenes[2] = new DX12ChunksScene();
g_scenes[3] = new DX12TextScene();
g_scenes[4] = new DX12LightScatterScene();

// Main message loop
g_last_ms = MillisecondsNow();
Expand Down
13 changes: 13 additions & 0 deletions dx12helloworld/scene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,17 @@ class DX12TextScene : public Scene {
TextPass* text_pass;
};

class DX12LightScatterScene : public Scene {
public:
DX12LightScatterScene();
void Render() override;
void Update(float secs) override;

ID3D12CommandAllocator* command_allocator;
ID3D12GraphicsCommandList* command_list;
ID3DBlob* ps_drawlight, * vs_drawlight;
ID3D12RootSignature* root_signature;
ID3D12PipelineState* pipeline_state;
};

#endif
63 changes: 63 additions & 0 deletions dx12helloworld/shaders/shaders_combine.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// The Light Scattering algorithm is borrowed from here:
// http://fabiensanglard.net/lightScattering/index.php

struct PSInput
{
float4 position_clipspace : SV_POSITION;
float2 position_screenspace : COLOR; // to avoid repeating SV_POSITION.
float2 uv : TEXCOORD;
};

cbuffer PerSceneCB : register(b0)
{
float WIN_W, WIN_H;
float light_x, light_y, light_r;
float4 light_color;
float global_alpha;
}

Texture2D g_src1 : register(t0);
Texture2D g_src2 : register(t1);
SamplerState g_sampler : register(s0);

PSInput VSMain(float4 position : POSITION, float4 uv : TEXCOORD)
{
PSInput result;
result.position_clipspace = position;
result.position_screenspace = position * float2(WIN_W, WIN_H);
result.uv = uv.xy;
return result;
}

float4 PSMain(PSInput input) : SV_TARGET
{
float4 rgba1 = g_src1.Sample(g_sampler, input.uv);

float density = 1.0f;
float decay = 0.99f;
float weight = 1.0f;
float exposure = 0.01f;
int num_samples = 50;

float2 light_clipspace = float2(light_x / WIN_W, light_y / WIN_H);
float2 tex_coord = input.uv;
float2 delta = input.uv - light_clipspace;
delta = delta * (1.0f / num_samples * density);
float illumination_decay = 1.0f;

float4 rgba2 = float4(0.0f, 0.0f, 0.0f, 0.0f);
for (int i=0; i<num_samples && illumination_decay > 0; i++) {
tex_coord -= delta;
float4 sample = g_src2.Sample(g_sampler, tex_coord);
float4 sample1 = g_src1.Sample(g_sampler, tex_coord);
sample = sample * illumination_decay * weight;
if (1 || sample1.a <= 0) {
rgba2 += sample;
}
illumination_decay *= decay;
}

{
return (rgba1 + (rgba2*exposure)) * global_alpha;
}
}
33 changes: 33 additions & 0 deletions dx12helloworld/shaders/shaders_drawlight.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
struct PSInput
{
float4 position : SV_POSITION;
float2 uv : TEXCOORD;
};

cbuffer PerSceneCB : register(b0)
{
float WIN_W, WIN_H;
float light_x, light_y, light_r;
float4 light_color;
}

PSInput VSMain(float4 position : POSITION, float4 uv : TEXCOORD)
{
PSInput result;
result.position = position;
result.uv = uv.xy * float2(WIN_W, WIN_H);
return result;
}

float4 PSMain(PSInput input) : SV_TARGET
{
float dx = input.position.x - light_x;
float dy = input.position.y - light_y;
float rsq = dx*dx + dy*dy;
if (rsq < light_r * light_r) {
return light_color;
} else {
discard;
return float4(0,0,0,0);
}
}

0 comments on commit 64d5986

Please sign in to comment.