diff --git a/enginecustom/CelShadingShader.cpp b/enginecustom/CelShadingShader.cpp index 3745b30..29bbc17 100644 --- a/enginecustom/CelShadingShader.cpp +++ b/enginecustom/CelShadingShader.cpp @@ -1,4 +1,5 @@ #include "CelShadingShader.h" +#include CelShadingShader::CelShadingShader() { @@ -63,14 +64,14 @@ void CelShadingShader::Shutdown() } bool CelShadingShader::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, - ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor[]) + ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor, XMFLOAT3 lightPosition) { bool result; - // Set the shader parameters that it will use for rendering. - result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, lightDirection, diffuseColor); + result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, lightDirection, diffuseColor, lightPosition); if (!result) { + Logger::Get().Log("CelShading Error", __FILE__, __LINE__, Logger::LogLevel::Error); return false; } @@ -86,7 +87,7 @@ bool CelShadingShader::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* ID3D10Blob* errorMessage = nullptr; ID3D10Blob* vertexShaderBuffer = nullptr; ID3D10Blob* pixelShaderBuffer = nullptr; - D3D11_INPUT_ELEMENT_DESC polygonLayout[2]; + D3D11_INPUT_ELEMENT_DESC polygonLayout[3]; unsigned int numElements; D3D11_BUFFER_DESC matrixBufferDesc; D3D11_SAMPLER_DESC samplerDesc; @@ -146,20 +147,28 @@ bool CelShadingShader::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* // This setup needs to match the VertexType structure in the ModelClass and in the shader. polygonLayout[0].SemanticName = "POSITION"; polygonLayout[0].SemanticIndex = 0; - polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; + polygonLayout[0].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; polygonLayout[0].InputSlot = 0; polygonLayout[0].AlignedByteOffset = 0; polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; polygonLayout[0].InstanceDataStepRate = 0; - polygonLayout[1].SemanticName = "TEXCOORD"; + polygonLayout[1].SemanticName = "NORMAL"; polygonLayout[1].SemanticIndex = 0; - polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT; + polygonLayout[1].Format = DXGI_FORMAT_R32G32B32_FLOAT; polygonLayout[1].InputSlot = 0; polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; polygonLayout[1].InstanceDataStepRate = 0; + polygonLayout[2].SemanticName = "TEXCOORD"; + polygonLayout[2].SemanticIndex = 0; + polygonLayout[2].Format = DXGI_FORMAT_R32G32_FLOAT; + polygonLayout[2].InputSlot = 0; + polygonLayout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; + polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + polygonLayout[2].InstanceDataStepRate = 0; + // Get a count of the elements in the layout. numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]); @@ -312,7 +321,7 @@ void CelShadingShader::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND h bool CelShadingShader::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, - ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor[]) + ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor, XMFLOAT3 lightPosition) { HRESULT result; D3D11_MAPPED_SUBRESOURCE mappedResource; @@ -320,6 +329,7 @@ bool CelShadingShader::SetShaderParameters(ID3D11DeviceContext* deviceContext, X LightBufferType* dataPtr2; unsigned int bufferNumber; + // Transpose the matrices to prepare them for the shader. worldMatrix = XMMatrixTranspose(worldMatrix); viewMatrix = XMMatrixTranspose(viewMatrix); @@ -363,9 +373,16 @@ bool CelShadingShader::SetShaderParameters(ID3D11DeviceContext* deviceContext, X dataPtr2 = (LightBufferType*)mappedResource.pData; // Copy the lighting variables into the constant buffer. - dataPtr2->diffuseColor = diffuseColor[0]; + dataPtr2->diffuseColor = diffuseColor; dataPtr2->lightDirection = lightDirection; + dataPtr2->lightPosition = lightPosition; dataPtr2->padding = 0.0f; + dataPtr2->padding2 = 0.0f; + + // store the light direction in a string + std::string lightDirectionString = std::to_string(lightDirection.x) + ", " + std::to_string(lightDirection.y) + ", " + std::to_string(lightDirection.z); + Logger::Get().Log(lightDirectionString, __FILE__, __LINE__, Logger::LogLevel::Debug); + // Unlock the constant buffer. deviceContext->Unmap(m_lightBuffer, 0); diff --git a/enginecustom/CelShadingShader.h b/enginecustom/CelShadingShader.h index a675f34..6e0c4f3 100644 --- a/enginecustom/CelShadingShader.h +++ b/enginecustom/CelShadingShader.h @@ -29,7 +29,9 @@ private: { XMFLOAT4 diffuseColor; XMFLOAT3 lightDirection; - float padding; + float padding; // Padding to ensure the structure is a multiple of 16 bytes. + XMFLOAT3 lightPosition; // Add light position + float padding2; // Padding to ensure the structure is a multiple of 16 bytes. }; public: @@ -39,14 +41,14 @@ public: bool Initialize(ID3D11Device*, HWND); void Shutdown(); - bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4[]); + bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4, XMFLOAT3); private: bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*); void ShutdownShader(); void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*); - bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4[]); + bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4, XMFLOAT3); void RenderShader(ID3D11DeviceContext*, int); private: diff --git a/enginecustom/applicationclass.cpp b/enginecustom/applicationclass.cpp index b32234f..9b45de2 100644 --- a/enginecustom/applicationclass.cpp +++ b/enginecustom/applicationclass.cpp @@ -1006,6 +1006,11 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t ambientColor[i] = m_Lights[i]->GetPosition(); } + //Add the 3 first value of the light position to the TrueLightPosition XMFLOAT3 + TrueLightPosition.x = lightPosition[0].x; + TrueLightPosition.y = lightPosition[0].y; + TrueLightPosition.z = lightPosition[0].z; + scaleMatrix = XMMatrixScaling(0.5f, 0.5f, 0.5f); // Build the scaling matrix. rotateMatrix = XMMatrixRotationY(rotation); // Build the rotation matrix. translateMatrix = XMMatrixTranslation(x, y, z); // Build the translation matrix. @@ -1021,17 +1026,6 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0), diffuseColor, lightPosition, ambientColor); - // Render cel shading globally to the scene using the cel shader if the checkbox is checked. - if (m_enableCelShading) { - result = m_ShaderManager->RenderCelShadingShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0), - m_Lights[0]->GetDirection(), ambientColor); - if (!result) - { - Logger::Get().Log("Could not render the model using the cel shader", __FILE__, __LINE__, Logger::LogLevel::Error); - return false; - } - } - for (auto cube : m_cubes) { @@ -1051,20 +1045,26 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t cube->Render(m_Direct3D->GetDeviceContext()); - // render the texture using the texture shader. - result = m_ShaderManager->RenderTextureShader(m_Direct3D->GetDeviceContext(), cube->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, cube->GetTexture(0)); - if (!result) - { - Logger::Get().Log("Could not render the cube model using the texture shader", __FILE__, __LINE__, Logger::LogLevel::Error); - return false; + + if (!m_enableCelShading) { + result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), cube->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, cube->GetTexture(0), + diffuseColor, lightPosition, ambientColor); + if (!result) + { + Logger::Get().Log("Could not render the cube model using the light shader", __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } } - result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, cube->GetTexture(0), - diffuseColor, lightPosition,ambientColor); - if (!result) - { - Logger::Get().Log("Could not render the cube model using the light shader", __FILE__, __LINE__, Logger::LogLevel::Error); - return false; + // Render cel shading globally to the scene using the cel shader if the checkbox is checked. + if (m_enableCelShading) { + result = m_ShaderManager->RenderCelShadingShader(m_Direct3D->GetDeviceContext(), cube->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, cube->GetTexture(0), + m_Lights[0]->GetDirection(), m_Lights[0]->GetDiffuseColor(), TrueLightPosition); + if (!result) + { + Logger::Get().Log("Could not render the model using the cel shader", __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } } } @@ -1084,21 +1084,26 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t object->Render(m_Direct3D->GetDeviceContext()); - // render the texture using the texture shader. - result = m_ShaderManager->RenderTextureShader(m_Direct3D->GetDeviceContext(), object->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, object->GetTexture(0)); - if (!result) - { - Logger::Get().Log("Could not render the cube model using the texture shader", __FILE__, __LINE__, Logger::LogLevel::Error); - return false; + if (!m_enableCelShading) { + result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, object->GetTexture(0), + diffuseColor, lightPosition, ambientColor); + + if (!result) + { + Logger::Get().Log("Could not render the object model using the light shader", __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } } - result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0), - diffuseColor, lightPosition, ambientColor); - - if (!result) - { - Logger::Get().Log("Could not render the object model using the light shader", __FILE__, __LINE__, Logger::LogLevel::Error); - return false; + // Render cel shading globally to the scene using the cel shader if the checkbox is checked. + if (m_enableCelShading) { + result = m_ShaderManager->RenderCelShadingShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, object->GetTexture(0), + m_Lights[0]->GetDirection(), m_Lights[0]->GetDiffuseColor(), TrueLightPosition); + if (!result) + { + Logger::Get().Log("Could not render the model using the cel shader", __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } } } @@ -1114,14 +1119,27 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t worldMatrix = XMMatrixMultiply(srMatrix, translateMatrix); chunk->Render(m_Direct3D->GetDeviceContext()); + if (!m_enableCelShading) { + result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), chunk->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, chunk->GetTexture(5), + diffuseColor, lightPosition, ambientColor); - result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), chunk->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, chunk->GetTexture(5), - diffuseColor, lightPosition, ambientColor); - - if (!result) - { - Logger::Get().Log("Could not render the terrain model using the light shader", __FILE__, __LINE__, Logger::LogLevel::Error); - return false; + if (!result) + { + Logger::Get().Log("Could not render the terrain model using the light shader", __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } + } + + + // Render cel shading globally to the scene using the cel shader if the checkbox is checked. + if (m_enableCelShading) { + result = m_ShaderManager->RenderCelShadingShader(m_Direct3D->GetDeviceContext(), chunk->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, chunk->GetTexture(5), + m_Lights[0]->GetDirection(), m_Lights[0]->GetDiffuseColor(), TrueLightPosition); + if (!result) + { + Logger::Get().Log("Could not render the model using the cel shader", __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } } } diff --git a/enginecustom/applicationclass.h b/enginecustom/applicationclass.h index c4357e9..ff9bcee 100644 --- a/enginecustom/applicationclass.h +++ b/enginecustom/applicationclass.h @@ -136,6 +136,8 @@ private : std::vector m_Lights; int m_numLights; + XMFLOAT3 TrueLightPosition; + // ----------------------------------- // // ------------- SHADERS ------------- // // ----------------------------------- // diff --git a/enginecustom/celshading.ps b/enginecustom/celshading.ps index 08b0a87..520ed49 100644 --- a/enginecustom/celshading.ps +++ b/enginecustom/celshading.ps @@ -1,9 +1,10 @@ -// celshading.ps cbuffer LightBuffer { float4 diffuseColor; float3 lightDirection; float padding; // Padding to ensure the structure is a multiple of 16 bytes. + float3 lightPosition; // Add light position + float padding2; // Padding to ensure the structure is a multiple of 16 bytes. }; Texture2D shaderTexture; @@ -12,7 +13,9 @@ SamplerState SampleType; struct PixelInputType { float4 position : SV_POSITION; + float3 normal : NORMAL; float2 tex : TEXCOORD0; + float3 worldPos : TEXCOORD1; // Add world position }; float4 CelShadingPixelShader(PixelInputType input) : SV_TARGET @@ -24,8 +27,16 @@ float4 CelShadingPixelShader(PixelInputType input) : SV_TARGET // Sample the pixel color from the texture. textureColor = shaderTexture.Sample(SampleType, input.tex); + // Normalize the normal + float3 normal = normalize(input.normal); + + // Calculate the vector from the pixel to the light source + float3 lightVector = lightPosition - input.worldPos; + float distance = length(lightVector); + lightVector = normalize(lightVector); + // Calculate the light intensity based on the light direction. - lightIntensity = saturate(dot(normalize(lightDirection), float3(0.0f, 0.0f, -1.0f))); + lightIntensity = saturate(dot(normal, lightVector)); // Apply a step function to create the cel shading effect. if (lightIntensity > 0.5f) @@ -41,4 +52,4 @@ float4 CelShadingPixelShader(PixelInputType input) : SV_TARGET finalColor = textureColor * diffuseColor * lightIntensity; return finalColor; -} +} \ No newline at end of file diff --git a/enginecustom/celshading.vs b/enginecustom/celshading.vs index 4b4e8b8..fe58dbc 100644 --- a/enginecustom/celshading.vs +++ b/enginecustom/celshading.vs @@ -1,4 +1,3 @@ -// celshading.vs cbuffer MatrixBuffer { matrix worldMatrix; @@ -9,13 +8,16 @@ cbuffer MatrixBuffer struct VertexInputType { float4 position : POSITION; + float3 normal : NORMAL; float2 tex : TEXCOORD0; }; struct PixelInputType { float4 position : SV_POSITION; + float3 normal : NORMAL; float2 tex : TEXCOORD0; + float3 worldPos : TEXCOORD1; // Add world position }; PixelInputType CelShadingVertexShader(VertexInputType input) @@ -30,8 +32,14 @@ PixelInputType CelShadingVertexShader(VertexInputType input) output.position = mul(output.position, viewMatrix); output.position = mul(output.position, projectionMatrix); + // Pass the normal to the pixel shader + output.normal = mul(input.normal, (float3x3)worldMatrix); + + // Pass the world position to the pixel shader + output.worldPos = mul(input.position, worldMatrix).xyz; + // Store the texture coordinates for the pixel shader. output.tex = input.tex; return output; -} +} \ No newline at end of file diff --git a/enginecustom/imgui.ini b/enginecustom/imgui.ini index d7b8118..3b43e0d 100644 --- a/enginecustom/imgui.ini +++ b/enginecustom/imgui.ini @@ -3,22 +3,22 @@ Pos=60,60 Size=400,400 [Window][Khaotic Engine] -Pos=429,57 +Pos=430,-13 Size=392,218 [Window][Objects] -Pos=39,222 -Size=589,294 +Pos=998,87 +Size=457,294 [Window][Terrain] Pos=60,60 Size=342,82 [Window][Light] -Pos=95,296 -Size=345,230 +Pos=1197,66 +Size=345,519 [Window][Shader Manager] -Pos=60,60 +Pos=33,253 Size=172,284 diff --git a/enginecustom/imguiManager.cpp b/enginecustom/imguiManager.cpp index e781373..002e579 100644 --- a/enginecustom/imguiManager.cpp +++ b/enginecustom/imguiManager.cpp @@ -118,7 +118,7 @@ void imguiManager::WidgetShaderWindow(ApplicationClass* app) // Checkbox for toggling cel shading globally in the application class by calling the SetCelShading function in the application class when the checkbox state changes ImGui::Checkbox("Enable Cel Shading", &m_EnableCelShading); app->SetCelShading(m_EnableCelShading); - + ImGui::End(); } @@ -373,7 +373,6 @@ void imguiManager::WidgetLightWindow(ApplicationClass* app) app->SetLightColor(index, XMVectorSet(col[0], col[1], col[2], 0.0f)); } - ImGui::Separator(); } index++; }; diff --git a/enginecustom/shadermanagerclass.cpp b/enginecustom/shadermanagerclass.cpp index a66e8b1..4ad7658 100644 --- a/enginecustom/shadermanagerclass.cpp +++ b/enginecustom/shadermanagerclass.cpp @@ -429,11 +429,11 @@ bool ShaderManagerClass::RenderWaterShader(ID3D11DeviceContext* deviceContext, i } bool ShaderManagerClass::RenderCelShadingShader(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, - ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor[]) + ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor, XMFLOAT3 lightPosition) { bool result; - result = m_CelShadingShader->Render(deviceContext, indexCount, worldMatrix, viewMatrix, projectionMatrix, texture, lightDirection, diffuseColor); + result = m_CelShadingShader->Render(deviceContext, indexCount, worldMatrix, viewMatrix, projectionMatrix, texture, lightDirection, diffuseColor, lightPosition); if (!result) { return false; diff --git a/enginecustom/shadermanagerclass.h b/enginecustom/shadermanagerclass.h index e2362e2..c0aa0ba 100644 --- a/enginecustom/shadermanagerclass.h +++ b/enginecustom/shadermanagerclass.h @@ -44,7 +44,7 @@ public: XMFLOAT3, XMFLOAT4[], XMFLOAT4[], XMFLOAT4[], XMFLOAT4); bool RenderWaterShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, float, float); - bool RenderCelShadingShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4[]); + bool RenderCelShadingShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4, XMFLOAT3); private: TextureShaderClass* m_TextureShader; NormalMapShaderClass* m_NormalMapShader;