Skip to content

Commit

Permalink
Created render instance buffer for all objects, root constant to emul…
Browse files Browse the repository at this point in the history
…ate instance id, still need to fix material id handling
  • Loading branch information
krupitskas committed Nov 21, 2024
1 parent 8e3dc11 commit 72688fe
Show file tree
Hide file tree
Showing 12 changed files with 304 additions and 182 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div align="center">
s<div align="center">

# `🌩️ Yasno`

**Personal DirectX 12 research renderer oriented for fast iterations and easy usage**
**Personal DirectX 12 research p_renderer->GetDevice()-> oriented for fast iterations and easy usage**

</div>
## Features
Expand Down
25 changes: 20 additions & 5 deletions Shaders/ForwardPassPS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct RS2PS
#define OCCLUSION_ENABLED_BITMASK 3
#define EMISSIVE_ENABLED_BITMASK 4

struct PBRMetallicRoughness
struct SurfaceShaderParameters
{
float4 base_color_factor;
float metallic_factor;
Expand All @@ -39,7 +39,7 @@ cbuffer CameraParameters : register(b0)
float3 camera_position;
};

cbuffer SceneParameters : register(b2)
cbuffer SceneParameters : register(b1)
{
float4x4 shadow_matrix;
float4 directional_light_color;
Expand All @@ -49,13 +49,24 @@ cbuffer SceneParameters : register(b2)
uint shadows_enabled;
};

cbuffer Material : register(b3)
cbuffer InstanceId : register(b2)
{
PBRMetallicRoughness pbr_material;
uint instance_id;
};

struct PerInstanceData
{
float4x4 model_matrix;
int material_id;
int pad[3];
};
StructuredBuffer<PerInstanceData> per_instance_data : register(t0);

// Global material buffer
StructuredBuffer<SurfaceShaderParameters> materials_buffer : register(t1);

// Input textures
Texture2D ShadowMap : register(t0);
Texture2D ShadowMap : register(t2);

// Samplers
SamplerState ShadowSampler : register(s0);
Expand Down Expand Up @@ -100,6 +111,10 @@ float4 main(RS2PS input) : SV_Target
normal = input.normal;
tangent = input.tangent;

PerInstanceData instance_data = per_instance_data[instance_id];

SurfaceShaderParameters pbr_material = materials_buffer[instance_data.material_id];

float4 base_color = pbr_material.base_color_factor;
float metallicResult = pbr_material.metallic_factor;
float roughnessResult = pbr_material.roughness_factor;
Expand Down
30 changes: 18 additions & 12 deletions Shaders/ForwardPassVS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct VS2RS
#ifndef SHADOW_PASS
float4 position_shadow_space : POSITION;
#endif

float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 texcoord_0: TEXCOORD_0;
Expand All @@ -35,12 +36,7 @@ cbuffer CameraParameters : register(b0)
};
#endif

cbuffer SceneNodeParameters : register(b1)
{
float4x4 model_matrix;
};

cbuffer SceneParameters : register(b2)
cbuffer SceneParameters : register(b1)
{
float4x4 shadow_matrix;
float4 directional_light_color;
Expand All @@ -50,23 +46,33 @@ cbuffer SceneParameters : register(b2)
uint shadows_enabled;
};

cbuffer InstanceId : register(b2)
{
uint instance_id;
};

// TODO: Implement vertex pulling
//ByteAddressBuffer IndicesBuffer : register(t1);
//ByteAddressBuffer VerticesBuffer : register(t2);
struct PerInstanceData
{
float4x4 model_matrix;
int material_id;
int pad[3];
};
StructuredBuffer<PerInstanceData> per_instance_data : register(t0);

VS2RS main(IA2VS input)
{
PerInstanceData instance_data = per_instance_data[instance_id];

VS2RS output;
output.position = mul(float4(input.position, 1.0), model_matrix);
output.position = mul(float4(input.position, 1.0), instance_data.model_matrix);

#ifndef SHADOW_PASS
output.position_shadow_space = mul(shadow_matrix, output.position);
#endif

output.position = mul(view_projection, output.position);
output.normal = mul(float4(input.normal, 1.0), model_matrix);
output.tangent.xyz = mul(float4(input.tangent.xyz, 1.0), model_matrix);
output.normal = mul(float4(input.normal, 1.0), instance_data.model_matrix).xyz;
output.tangent.xyz = mul(float4(input.tangent.xyz, 1.0), instance_data.model_matrix).xyz;
output.tangent.w = input.tangent.w;
output.texcoord_0 = input.texcoord_0;

Expand Down
3 changes: 2 additions & 1 deletion Yasno/Graphics/Material.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <Renderer/PSO.hpp>
#include <Renderer/GpuResource.hpp>
#include <Graphics/SurfaceMaterial.hpp>

namespace ysn
{
Expand All @@ -14,6 +15,6 @@ namespace ysn
D3D12_BLEND_DESC blend_desc = {};
D3D12_RASTERIZER_DESC rasterizer_desc = {};

GpuResource gpu_material_parameters;
SurfaceShaderParameters shader_parameters;
};
}
23 changes: 21 additions & 2 deletions Yasno/Graphics/RenderScene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,17 @@ namespace ysn
std::vector<GpuTexture> textures;

// Not sure about that x2
std::vector<GpuResource> node_buffers; // Per node GPU data
std::vector<D3D12_SAMPLER_DESC> sampler_descs;
};

// Per instance data for rendering
YSN_SHADER_STRUCT RenderInstanceData
{
DirectX::XMMATRIX model_matrix;
int32_t material_id;
int32_t pad[3];
};

struct RenderScene
{
std::shared_ptr<Camera> camera;
Expand All @@ -58,9 +65,21 @@ namespace ysn

// Temp GPU resources for indices and vertices
uint32_t indices_count = 0;
uint32_t vertices_count = 0;
GpuBuffer indices_buffer;

// Vertices
uint32_t vertices_count = 0;
GpuBuffer vertices_buffer;

// Materials
uint32_t materials_count = 0;
GpuBuffer materials_buffer;
DescriptorHandle materials_buffer_srv;

// Per instance data
uint32_t primitives_count = 0;
GpuBuffer instance_buffer;
DescriptorHandle instance_buffer_srv;
};
}

16 changes: 8 additions & 8 deletions Yasno/Graphics/SurfaceMaterial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ namespace ysn
YSN_SHADER_STRUCT SurfaceShaderParameters
{
DirectX::XMFLOAT4 base_color_factor;
float metallic_factor;
float roughness_factor;
float metallic_factor = 0.0f;
float roughness_factor = 0.0f;

// Encods which textures are active
int32_t texture_enable_bitmask;
int32_t texture_enable_bitmask = 0;

int32_t albedo_texture_index;
int32_t metallic_roughness_texture_index;
int32_t normal_texture_index;
int32_t occlusion_texture_index;
int32_t emissive_texture_index;
int32_t albedo_texture_index = 0;
int32_t metallic_roughness_texture_index = 0;
int32_t normal_texture_index = 0;
int32_t occlusion_texture_index = 0;
int32_t emissive_texture_index = 0;
};
}
75 changes: 57 additions & 18 deletions Yasno/Graphics/Techniques/ForwardPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,30 +68,62 @@ namespace ysn
{
bool result = false;

D3D12_DESCRIPTOR_RANGE instance_data_input_range = {};
instance_data_input_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
instance_data_input_range.NumDescriptors = 1;
instance_data_input_range.BaseShaderRegister = 0;

D3D12_ROOT_PARAMETER instance_buffer_parameter;
instance_buffer_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
instance_buffer_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
instance_buffer_parameter.DescriptorTable.NumDescriptorRanges = 1;
instance_buffer_parameter.DescriptorTable.pDescriptorRanges = &instance_data_input_range;

D3D12_DESCRIPTOR_RANGE materials_input_range = {};
materials_input_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
materials_input_range.NumDescriptors = 1;
materials_input_range.BaseShaderRegister = 1;

D3D12_ROOT_PARAMETER materials_buffer_parameter;
materials_buffer_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
materials_buffer_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
materials_buffer_parameter.DescriptorTable.NumDescriptorRanges = 1;
materials_buffer_parameter.DescriptorTable.pDescriptorRanges = &materials_input_range;

D3D12_DESCRIPTOR_RANGE shadow_input_range = {};
shadow_input_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
shadow_input_range.NumDescriptors = 1;
shadow_input_range.BaseShaderRegister = 0;
shadow_input_range.BaseShaderRegister = 2;

D3D12_ROOT_PARAMETER shadow_parameter;
shadow_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
shadow_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
shadow_parameter.DescriptorTable.NumDescriptorRanges = 1;
shadow_parameter.DescriptorTable.pDescriptorRanges = &shadow_input_range;

D3D12_ROOT_PARAMETER rootParams[5] = {
{ D3D12_ROOT_PARAMETER_TYPE_CBV, { 0, 0 }, D3D12_SHADER_VISIBILITY_ALL },
{ D3D12_ROOT_PARAMETER_TYPE_CBV, { 1, 0 }, D3D12_SHADER_VISIBILITY_VERTEX },
{ D3D12_ROOT_PARAMETER_TYPE_CBV, { 2, 0 }, D3D12_SHADER_VISIBILITY_ALL },
{ D3D12_ROOT_PARAMETER_TYPE_CBV, { 3, 0 }, D3D12_SHADER_VISIBILITY_PIXEL },
shadow_parameter
D3D12_ROOT_PARAMETER rootParams[6] = {
{ D3D12_ROOT_PARAMETER_TYPE_CBV, { 0, 0 }, D3D12_SHADER_VISIBILITY_ALL }, // CameraParameters
{ D3D12_ROOT_PARAMETER_TYPE_CBV, { 1, 0 }, D3D12_SHADER_VISIBILITY_ALL }, // SceneParameters

// InstanceID
{
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
.Constants = {
.ShaderRegister = 2,
.RegisterSpace = 0,
.Num32BitValues = 1
},
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL
},

instance_buffer_parameter, // PerInstanceData
materials_buffer_parameter, // Materials buffer
shadow_parameter // Shadow Map input
};

// TEMP
rootParams[0].Descriptor.RegisterSpace = 0;
rootParams[1].Descriptor.RegisterSpace = 0;
rootParams[2].Descriptor.RegisterSpace = 0;
rootParams[3].Descriptor.RegisterSpace = 0;

// 0 ShadowSampler
// 1 LinearSampler
Expand All @@ -100,7 +132,7 @@ namespace ysn
static_sampler[1] = CD3DX12_STATIC_SAMPLER_DESC(1, D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_WRAP, D3D12_TEXTURE_ADDRESS_MODE_WRAP, D3D12_TEXTURE_ADDRESS_MODE_WRAP, 0, 0, D3D12_COMPARISON_FUNC_NONE);

D3D12_ROOT_SIGNATURE_DESC RootSignatureDesc = {};
RootSignatureDesc.NumParameters = 5;
RootSignatureDesc.NumParameters = 6;
RootSignatureDesc.pParameters = &rootParams[0];
RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT
| D3D12_ROOT_SIGNATURE_FLAG_CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED // For bindless rendering
Expand Down Expand Up @@ -224,15 +256,18 @@ namespace ysn
command_list->ResourceBarrier(1, &barrier);
}

uint32_t instance_id = 0;

for(auto& model : render_scene.models)
{
for(int mesh_id = 0; mesh_id < model.meshes.size(); mesh_id++)
{
const Mesh& mesh = model.meshes[mesh_id];
const GpuResource& node_gpu_buffer = model.node_buffers[mesh_id];

for(auto& primitive : mesh.primitives)
for(int primitive_id = 0; primitive_id < mesh.primitives.size(); primitive_id++)
{
const Primitive& primitive = mesh.primitives[primitive_id];

command_list->IASetVertexBuffers(0, 1, &primitive.vertex_buffer_view);

// TODO: check for -1 as pso_id
Expand All @@ -246,12 +281,14 @@ namespace ysn
command_list->SetPipelineState(pso.value().pso.get());

command_list->IASetPrimitiveTopology(primitive.topology);
command_list->SetGraphicsRootConstantBufferView(2, render_parameters.scene_parameters_gpu_buffer->GetGPUVirtualAddress());
command_list->SetGraphicsRootConstantBufferView(3, material.gpu_material_parameters.GetGPUVirtualAddress());
command_list->SetGraphicsRootDescriptorTable(4, render_parameters.shadow_map_buffer.srv_handle.gpu);

command_list->SetGraphicsRootConstantBufferView(0, render_parameters.camera_gpu_buffer->GetGPUVirtualAddress());
command_list->SetGraphicsRootConstantBufferView(1, node_gpu_buffer.GetGPUVirtualAddress());
command_list->SetGraphicsRootConstantBufferView(1, render_parameters.scene_parameters_gpu_buffer->GetGPUVirtualAddress());
command_list->SetGraphicsRoot32BitConstant(2, instance_id, 0); // InstanceID

command_list->SetGraphicsRootDescriptorTable(3, render_scene.instance_buffer_srv.gpu);
command_list->SetGraphicsRootDescriptorTable(4, render_scene.materials_buffer_srv.gpu);
command_list->SetGraphicsRootDescriptorTable(5, render_parameters.shadow_map_buffer.srv_handle.gpu);

if (primitive.index_count)
{
Expand All @@ -265,8 +302,10 @@ namespace ysn
}
else
{
LogWarning << "Can't render primitive because it has't any pso attached\n";
LogWarning << "Can't render primitive because it haven't any PSO\n";
}

instance_id++;
}
}
}
Expand Down Expand Up @@ -349,7 +388,7 @@ namespace ysn
for(int mesh_id = 0; mesh_id < model.meshes.size(); mesh_id++)
{
const Mesh& mesh = model.meshes[mesh_id];
const GpuResource& node_gpu_buffer = model.node_buffers[mesh_id];
//const GpuResource& node_gpu_buffer = model.node_buffers[mesh_id];

if (m_enable_culling)
{
Expand Down
Loading

0 comments on commit 72688fe

Please sign in to comment.