Well it's something ig
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user