Well it's something ig

This commit is contained in:
2025-01-15 03:40:39 +01:00
parent 9805c7a2c1
commit 8a3bf57d7e
15 changed files with 295 additions and 46 deletions

View File

@@ -13,17 +13,18 @@ DepthBuffer::~DepthBuffer()
bool DepthBuffer::Initialize()
{
// Create a depth buffer
// Create a depth buffer with a typeless format
D3D11_TEXTURE2D_DESC desc = {};
desc.Width = m_width;
desc.Height = m_height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_D32_FLOAT;
desc.Format = DXGI_FORMAT_R32_TYPELESS; // Typeless format
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; // Add shader resource binding
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
HRESULT hr = m_device->CreateTexture2D(&desc, nullptr, &m_depthBuffer);
if (FAILED(hr))
@@ -33,8 +34,9 @@ bool DepthBuffer::Initialize()
// Create DepthStencilView
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT;
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT; // Depth format
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
dsvDesc.Texture2D.MipSlice = 0;
hr = m_device->CreateDepthStencilView(m_depthBuffer, &dsvDesc, &m_depthStencilView);
if (FAILED(hr))
{
@@ -42,4 +44,14 @@ bool DepthBuffer::Initialize()
}
return true;
}
}
ID3D11Texture2D* DepthBuffer::GetDepthBuffer()
{
return m_depthBuffer;
}
ID3D11DepthStencilView* DepthBuffer::GetDepthStencilView()
{
return m_depthStencilView;
}

View File

@@ -13,6 +13,10 @@ public:
ID3D11Texture2D* GetDepthBuffer() const { return m_depthBuffer; }
ID3D11DepthStencilView* GetDepthStencilView() const { return m_depthStencilView; }
ID3D11DepthStencilView *GetDepthStencilView();
ID3D11Texture2D *GetDepthBuffer();
private:
ID3D11Device* m_device;
UINT m_width;
@@ -20,6 +24,7 @@ private:
ID3D11Texture2D* m_depthBuffer;
ID3D11DepthStencilView* m_depthStencilView;
};

View File

@@ -20,16 +20,22 @@ bool ShadowMapBuffer::Initialize() {
// Create ShaderResourceView for the depth buffer
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
srvDesc.Format = DXGI_FORMAT_R32_FLOAT; // Shader-readable format
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = 1;
srvDesc.Texture2D.MostDetailedMip = 0;
HRESULT hr = m_device->CreateShaderResourceView(m_depthBuffer.GetDepthBuffer(), &srvDesc, &m_shaderResourceView);
if (FAILED(hr)) {
if (FAILED(hr))
{
OutputDebugStringA("Failed to create ShaderResourceView for ShadowMapBuffer.\n");
return false;
}
return true;
}
void ShadowMapBuffer::SetRenderTarget(ID3D11DeviceContext *deviceContext) {
deviceContext->OMSetRenderTargets(0, nullptr, m_depthBuffer.GetDepthStencilView());
}

View File

@@ -54,6 +54,7 @@ ID3DX11Effect *BaseEffect::LoadEffect(ID3D11Device *devicePtr, const std::wstrin
ss << errorsPtr[i];
OutputDebugStringW(ss.str().c_str());
errorBlobPtr->Release();
errorBlobPtr = nullptr;
return nullptr;

View File

@@ -52,6 +52,14 @@ Effect::Effect(ID3D11Device *devicePtr, const std::wstring &filePath)
if(!m_RasterizerVariablePtr->IsValid())
std::wcout << L"gRasterizerState Rasterizer is not valid" << std::endl;
m_ShadowMapVariablePtr = m_EffectPtr->GetVariableByName("gShadowMap")->AsShaderResource();
if(!m_ShadowMapVariablePtr->IsValid())
std::wcout << L"gShadowMap ShaderResource is not valid" << std::endl;
m_ShadowMapSamplerVariablePtr = m_EffectPtr->GetVariableByName("gShadowSampler")->AsSampler();
if(!m_ShadowMapSamplerVariablePtr->IsValid())
std::wcout << L"gShadowSampler Sampler is not valid" << std::endl;
m_UseNormalMapVariablePtr->SetBool(m_UseNormalMap);
@@ -202,3 +210,13 @@ void Effect::InitRasterizer(ID3D11Device *devicePtr) {
devicePtr->CreateRasterizerState(&rasterDesc, &m_RasterizerStates[static_cast<int>(CullMode::None)]);
}
void Effect::SetShadowMapSampler(ID3D11SamplerState *pState) {
m_ShadowMapSamplerVariablePtr->SetSampler(0,pState);
}
void Effect::SetShadowMap(ID3D11ShaderResourceView *pView) {
m_ShadowMapVariablePtr->SetResource(pView);
}

View File

@@ -30,6 +30,10 @@ public:
void NextCullMode() override;
void SetShadowMap(ID3D11ShaderResourceView *pView);
void SetShadowMapSampler(ID3D11SamplerState *pState);
private:
void InitSamplers(ID3D11Device* devicePtr);
@@ -52,6 +56,10 @@ private:
ID3DX11EffectRasterizerVariable* m_RasterizerVariablePtr{};
ID3DX11EffectShaderResourceVariable* m_ShadowMapVariablePtr{};
ID3DX11EffectSamplerVariable* m_ShadowMapSamplerVariablePtr{};
TechniqueType m_TechniqueType{TechniqueType::Linear};
std::array<ID3D11SamplerState*, 3> m_SamplerStates{};

View File

@@ -21,6 +21,7 @@ void Light::SetUp(const dae::Vector3 &up) {
}
dae::Matrix Light::GetViewMatrix() const {
auto test = dae::Matrix::CreateLookAtLH(m_Position, m_Target, m_Up);
return dae::Matrix::CreateLookAtLH(m_Position, m_Target, m_Up);
}

View File

@@ -144,24 +144,42 @@ namespace dae {
return out;
}
Matrix Matrix::CreateLookAtLH(const Vector3& origin, const Vector3& forward, const Vector3& up)
{
Vector3 zAxis = (forward - origin).Normalized();
Vector3 xAxis = Vector3::Cross(up, zAxis).Normalized();
Matrix Matrix::CreateLookAtLH(const Vector3& origin, const Vector3& forward, const Vector3& up) {
// Calculate the z-axis (view direction)
Vector3 zAxis = forward - origin;
if (zAxis.SqrMagnitude() < 1e-6f) {
// Avoid NaN by ensuring the forward and origin are not the same
zAxis = Vector3(0, 0, 1); // Default to a valid direction
}
zAxis = zAxis.Normalized();
// Calculate the x-axis (right direction)
Vector3 xAxis = Vector3::Cross(up, zAxis);
if (xAxis.SqrMagnitude() < 1e-6f) {
// Handle the case where up is parallel to zAxis
Vector3 alternateUp = (std::abs(up.x) > 0.9f) ? Vector3(0, 1, 0) : Vector3(1, 0, 0);
xAxis = Vector3::Cross(alternateUp, zAxis);
}
xAxis = xAxis.Normalized();
// Calculate the y-axis (up direction)
Vector3 yAxis = Vector3::Cross(zAxis, xAxis).Normalized();
Vector3 trans =
{
-Vector3::Dot(xAxis, origin),
-Vector3::Dot(yAxis, origin),
-Vector3::Dot(zAxis, origin)
};
return {
{xAxis.x, yAxis.x, zAxis.x},
{xAxis.y, yAxis.y, zAxis.y},
{xAxis.z, yAxis.z, zAxis.z},
{trans.x, trans.y, trans.z}
// Calculate the translation
Vector3 trans = {
-Vector3::Dot(xAxis, origin),
-Vector3::Dot(yAxis, origin),
-Vector3::Dot(zAxis, origin)
};
}
// Return the look-at matrix in row-major order
return {
{xAxis.x, yAxis.x, zAxis.x, 0.0f},
{xAxis.y, yAxis.y, zAxis.y, 0.0f},
{xAxis.z, yAxis.z, zAxis.z, 0.0f},
{trans.x, trans.y, trans.z, 1.0f}
};
}
Matrix Matrix::CreatePerspectiveFovLH(float fovy, float aspect, float zn, float zf)
{

View File

@@ -113,28 +113,49 @@ namespace dae {
}
void Renderer::RenderDirectX() const {
//Clear back buffer
ColorRGB ChosenClearColor = m_UseUniformClearColor ? m_UniformClearColor : DirectXClearColor;
const float clearColor[] = {static_cast<float>(ChosenClearColor.r) / 255.f, static_cast<float>(ChosenClearColor.g) / 255.f,
static_cast<float>(ChosenClearColor.b) / 255.f, 1.f};
// Clear back buffer
ColorRGB chosenClearColor = m_UseUniformClearColor ? m_UniformClearColor : DirectXClearColor;
const float clearColor[] = {
static_cast<float>(chosenClearColor.r) / 255.f,
static_cast<float>(chosenClearColor.g) / 255.f,
static_cast<float>(chosenClearColor.b) / 255.f,
1.0f
};
m_DeviceContextPtr->ClearRenderTargetView(m_RenderTargetViewPtr, clearColor);
// Clear depth and stencil buffer
m_DeviceContextPtr->ClearDepthStencilView(m_DepthStencilViewPtr, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
// Set viewport
D3D11_VIEWPORT viewport = {};
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
viewport.Width = static_cast<float>(m_Width);
viewport.Height = static_cast<float>(m_Height);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
m_DeviceContextPtr->RSSetViewports(1, &viewport);
// Set camera matrix
Matrix viewProjMatrix = m_Camera.GetViewProjectionMatrix();
for (auto mesh: m_pScene->GetMeshes()) {
if (mesh->GetShouldRender()) {
Matrix modelMatrix = mesh->GetWorldMatrix();
Matrix worldViewProjMatrix = modelMatrix * viewProjMatrix;
mesh->Render(m_DeviceContextPtr, worldViewProjMatrix);
}
}
// Render all meshes in the scene
// for (auto mesh : m_pScene->GetMeshes()) {
// if (mesh->GetShouldRender()) {
// Matrix modelMatrix = mesh->GetWorldMatrix();
// Matrix worldViewProjMatrix = modelMatrix * viewProjMatrix;
//
// mesh->Render(m_DeviceContextPtr, worldViewProjMatrix);
// }
// }
// Call additional scene render logic (e.g., shadow rendering or post-processing)
m_pScene->Render(m_DeviceContextPtr, m_RenderTargetViewPtr, m_DepthStencilViewPtr, m_Camera);
//Present
m_SwapChainPtr->Present(0, 0);
// Present the rendered frame
HRESULT result = m_SwapChainPtr->Present(0, 0);
assert(SUCCEEDED(result) && "SwapChain Present failed");
}

View File

@@ -10,26 +10,31 @@
void ShadowTestScene::Initialize(ID3D11Device *DevicePtr, ID3D11DeviceContext *DeviceContextPtr, Camera *camera) {
// Initialize shadow map buffer
m_ShadowMapBuffer = new ShadowMapBuffer(DevicePtr, 1024, 1024); // Example resolution: 1024x1024
m_ShadowMapBuffer->Initialize();
if(!m_ShadowMapBuffer->Initialize()){
assert(true && "Shadow map buffer failed to initialize");
}
// Initialize light source
m_Light.SetPosition({0.0f, 10.0f, 0.0f});
m_Light.SetTarget({0.0f, 0.0f, 0.0f});
m_Light.SetTarget({0, -5, 40});
m_Light.SetUp({0.0f, 1.0f, 0.0f});
std::vector<VertexIn> vertices{};
std::vector<uint32_t> indices{};
if(!Utils::ParseOBJNew("resources/ShadingDemo.obj", vertices, indices, true)){
if(!Utils::ParseOBJNew("resources/scene.obj", vertices, indices, true)){
assert(true && "Model failed to load");
}
auto shadowEffect = new ShadowEffect(DevicePtr, L"resources/shadowEffect.fx");
auto otherEffect = new Effect(DevicePtr, L"resources/SimpleDiffuse.fx");
auto otherEffect = new Effect(DevicePtr, L"resources/SuperSimpleDiffuse.fx");
auto shadowMesh = new ShadowMesh(DevicePtr, vertices, indices, std::make_shared<Material>(), shadowEffect, otherEffect);
//Move forward 100
shadowMesh->SetWorldMatrix(Matrix::CreateTranslation(Vector3(0, -5, 40)));
m_shadowMeshes.push_back(shadowMesh);
// m_shadowMaterials.push_back(material);
}
@@ -41,17 +46,43 @@ void ShadowTestScene::Update() {
void ShadowTestScene::Render(ID3D11DeviceContext *devicePtr, ID3D11RenderTargetView *renderTargetViewPtr,
ID3D11DepthStencilView *depthStencilViewPtr, const Camera &camera) {
// Shadow map pass
// Set the viewport to match the shadow map size
// D3D11_VIEWPORT shadowViewport = {};
// shadowViewport.Width = static_cast<float>(1024);
// shadowViewport.Height = static_cast<float>(1024);
// shadowViewport.MinDepth = 0.0f;
// shadowViewport.MaxDepth = 1.0f;
// devicePtr->RSSetViewports(1, &shadowViewport);
devicePtr->OMSetRenderTargets(0, nullptr, m_ShadowMapBuffer->GetDepthStencilView());
devicePtr->ClearDepthStencilView(m_ShadowMapBuffer->GetDepthStencilView(), D3D11_CLEAR_DEPTH, 1.0f, 0);
ID3D11ShaderResourceView* shadowMap = m_ShadowMapBuffer->GetShaderResourceView();
devicePtr->PSSetShaderResources(0, 1, &shadowMap);
ID3D11SamplerState* shadowSampler = m_ShadowMapBuffer->GetSamplerState();
devicePtr->PSSetSamplers(0, 1, &shadowSampler);
for (auto* mesh : m_shadowMeshes) {
Matrix lightWorldViewProj = mesh->GetWorldMatrix() * m_Light.GetViewProjectionMatrix();
dynamic_cast<ShadowMesh*>(mesh)->RenderShadow(devicePtr, lightWorldViewProj);
}
ID3D11DepthStencilView* nullDepthStencilView = nullptr;
devicePtr->OMSetRenderTargets(1, &renderTargetViewPtr, nullDepthStencilView);
devicePtr->OMSetRenderTargets(1, &renderTargetViewPtr, depthStencilViewPtr);
for (auto* mesh : m_shadowMeshes) {
Matrix worldViewProj = mesh->GetWorldMatrix() * camera.GetViewProjectionMatrix();
auto* effect = dynamic_cast<ShadowMesh*>(mesh)->GetColorEffectPtr() ;
// effect->SetLightWorldViewProjMatrix(m_Light.GetViewProjectionMatrix());
dynamic_cast<Effect*>(effect)->SetWorldMatrix(worldViewProj);
dynamic_cast<Effect*>(effect)->SetShadowMapSampler(shadowSampler);
dynamic_cast<Effect*>(effect)->SetShadowMap(shadowMap);
dynamic_cast<ShadowMesh*>(mesh)->RenderFinal(devicePtr, worldViewProj);
}
}

View File

@@ -17,6 +17,7 @@ ShadowMesh::ShadowMesh(ID3D11Device* devicePtr,
HRESULT result;
// Create input layout
D3D11_INPUT_ELEMENT_DESC vertexDesc[] = {
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
@@ -26,7 +27,7 @@ ShadowMesh::ShadowMesh(ID3D11Device* devicePtr,
};
D3DX11_PASS_DESC passDesc;
ID3DX11EffectTechnique* techniquePtr = m_ShadowEffectPtr->GetTechniquePtr();
ID3DX11EffectTechnique* techniquePtr = m_ColorEffectPtr->GetTechniquePtr();
techniquePtr->GetPassByIndex(0)->GetDesc(&passDesc);
result = devicePtr->CreateInputLayout(vertexDesc, ARRAYSIZE(vertexDesc),
@@ -34,6 +35,7 @@ ShadowMesh::ShadowMesh(ID3D11Device* devicePtr,
&m_InputLayoutPtr);
assert(result == S_OK && "Creating input layout failed");
// Create vertex buffer
D3D11_BUFFER_DESC bufferDesc = {};
bufferDesc.Usage = D3D11_USAGE_IMMUTABLE;

View File

@@ -25,6 +25,10 @@ public:
void SetWorldMatrix(const Matrix& matrix);
Matrix GetWorldMatrix() const;
ShadowEffect* GetShadowEffectPtr(){ return m_ShadowEffectPtr; }
BaseEffect* GetColorEffectPtr(){ return m_ColorEffectPtr; }
private:
// Shadow effect
ShadowEffect* m_ShadowEffectPtr;
@@ -37,6 +41,12 @@ private:
ID3D11Buffer* m_VertexBufferPtr;
ID3D11Buffer* m_IndexBufferPtr;
//Shadow buffers
ID3D11InputLayout* m_ShadowInputLayoutPtr;
ID3D11Buffer* m_ShadowVertexBufferPtr;
ID3D11Buffer* m_ShadowIndexBufferPtr;
// Material and mesh data
std::shared_ptr<Material> m_Material;
std::vector<VertexIn> m_VerticesIn;