Minor update - Sunlight shader

This commit is contained in:
CatChow0 2025-01-23 17:29:29 +01:00
parent d8552d3f91
commit 51b29f77aa
7 changed files with 62 additions and 156 deletions

View File

@ -1944,7 +1944,7 @@ bool ApplicationClass::RenderPass(const std::vector<std::reference_wrapper<std::
case Object::SUNLIGHT:
result = m_ShaderManager->RenderSunlightShader(m_Direct3D->GetDeviceContext(), object->GetIndexCount(), worldMatrix, view, projection,
object->GetTexture(0), m_SunLight->GetDiffuseColor(), m_SunLight->GetPosition(), m_SunLight->GetAmbientColor());
object->GetTexture(0), m_SunLight->GetDiffuseColor(), m_SunLight->GetAmbientColor(), m_SunLight->GetDirection());
if (!result)
{
Logger::Get().Log("Could not render the object model using the sunlight shader", __FILE__, __LINE__, Logger::LogLevel::Error);

View File

@ -436,11 +436,11 @@ bool ShaderManagerClass::RenderCelShadingShader(ID3D11DeviceContext* deviceConte
}
bool ShaderManagerClass::RenderSunlightShader(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT4 ambientColor, XMFLOAT4 diffuseColor, XMFLOAT4 sunColor)
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor, XMFLOAT4 ambientColor, XMFLOAT3 sunDirection)
{
bool result;
result = m_SunlightShader->Render(deviceContext, indexCount, worldMatrix, viewMatrix, projectionMatrix, texture, ambientColor, diffuseColor, sunColor);
result = m_SunlightShader->Render(deviceContext, indexCount, worldMatrix, viewMatrix, projectionMatrix, texture, diffuseColor, ambientColor, sunDirection);
if (!result)
{
return false;

View File

@ -43,7 +43,7 @@ public:
bool RenderRefractionShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, 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, XMFLOAT3);
bool RenderSunlightShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4, XMFLOAT4, XMFLOAT4);
bool RenderSunlightShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4, XMFLOAT4, XMFLOAT3);
private:
TextureShaderClass* m_TextureShader;
NormalMapShaderClass* m_NormalMapShader;

View File

@ -6,10 +6,8 @@ SamplerState SampleType : register(s0);
cbuffer SunLightBuffer
{
float4 ambientColor;
float4 diffuseColor;
float3 lightDirection;
float padding;
float specularPower;
float4 specularColor;
};
cbuffer SunLightColorBuffer
@ -17,7 +15,6 @@ cbuffer SunLightColorBuffer
float4 sunColor;
};
//////////////
// TYPEDEFS //
//////////////
@ -26,10 +23,9 @@ struct PixelInputType
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
float3 sunPos : TEXCOORD1;
float3 lightDir : TEXCOORD1;
};
////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
@ -38,32 +34,29 @@ float4 SunLightPixelShader(PixelInputType input) : SV_TARGET
float4 textureColor;
float3 lightDir;
float4 color;
float3 reflection;
float4 specular;
float lightIntensity;
float4 colorArray;
float4 colorSum;
int i;
// Sample the pixel color from the texture using the sampler at this texture coordinate location.
textureColor = shaderTexture.Sample(SampleType, input.tex);
// Calculate the different amounts of light on this pixel based on the positions of the lights.
lightIntensity = saturate(dot(input.normal, input.sunPos));
// Calculate the different amounts of light on this pixel based on the direction of the light.
lightIntensity = saturate(dot(input.normal, input.lightDir));
// Determine the diffuse color amount of each of the four lights.
colorArray = sunColor * lightIntensity;
// Determine the diffuse color amount of the light.
colorArray = diffuseColor * lightIntensity;
// Initialize the sum of colors.
colorSum = float4(0.0f, 0.0f, 0.0f, 1.0f);
// Add all of the light colors up.
// Add the light color.
colorSum.r += colorArray.r;
colorSum.g += colorArray.g;
colorSum.b += colorArray.b;
// Multiply the texture pixel by the combination of all four light colors to get the final result.
// Multiply the texture pixel by the light color to get the final result.
color = saturate(colorSum) * textureColor;
return color;
}
}

View File

@ -14,9 +14,13 @@ cbuffer CameraBuffer
float padding;
};
cbuffer SunLightPositionBuffer
cbuffer SunLightBuffer
{
float4 sunPosition;
float4 ambientColor;
float4 diffuseColor;
float3 lightDirection;
float specularPower;
float4 specularColor;
};
//////////////
@ -34,18 +38,15 @@ struct PixelInputType
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
float3 lightPos : TEXCOORD1;
float3 lightDir : TEXCOORD1;
};
////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType SunLightVertexShader(VertexInputType input)
{
PixelInputType output;
float4 worldPosition;
int i;
// Change the position vector to be 4 units for proper matrix calculations.
input.position.w = 1.0f;
@ -64,15 +65,8 @@ PixelInputType SunLightVertexShader(VertexInputType input)
// Normalize the normal vector.
output.normal = normalize(output.normal);
// Calculate the position of the vertex in the world.
worldPosition = mul(input.position, worldMatrix);
// Determine the light positions based on the position of the lights and the position of the vertex in the world.
output.lightPos = sunPosition.xyz - worldPosition.xyz;
// Normalize the light position vectors.
output.lightPos = normalize(output.lightPos);
// Use the light direction directly.
output.lightDir = normalize(lightDirection);
return output;
}
}

View File

@ -75,13 +75,13 @@ void SunlightShaderClass::Shutdown()
}
bool SunlightShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor, XMFLOAT4 lightPosition, XMFLOAT4 ambientClor)
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor, XMFLOAT4 ambientColor, XMFLOAT3 sunDirection)
{
bool result;
// Set the shader parameters that it will use for rendering.
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, diffuseColor, lightPosition, ambientClor);
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, diffuseColor, ambientColor, sunDirection);
if (!result)
{
Logger::Get().Log("Failed to set shader parameters", __FILE__, __LINE__, Logger::LogLevel::Error);
@ -107,10 +107,7 @@ bool SunlightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHA
unsigned int numElements;
D3D11_SAMPLER_DESC samplerDesc;
D3D11_BUFFER_DESC matrixBufferDesc;
D3D11_BUFFER_DESC cameraBufferDesc;
D3D11_BUFFER_DESC lightColorBufferDesc;
D3D11_BUFFER_DESC lightPositionBufferDesc;
D3D11_BUFFER_DESC sunlightBufferDesc;
// Initialize the pointers this function will use to null.
errorMessage = 0;
@ -121,17 +118,14 @@ bool SunlightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHA
result = D3DCompileFromFile(vsFilename, NULL, NULL, "SunLightVertexShader", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, &vertexShaderBuffer, &errorMessage);
if (FAILED(result))
{
// If the shader failed to compile it should have writen something to the error message.
if (errorMessage)
{
OutputShaderErrorMessage(errorMessage, hwnd, vsFilename);
}
// If there was nothing in the error message then it simply could not find the shader file itself.
else
{
Logger::Get().Log("Failed to compile shader", __FILE__, __LINE__, Logger::LogLevel::Error);
}
return false;
}
@ -139,17 +133,14 @@ bool SunlightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHA
result = D3DCompileFromFile(psFilename, NULL, NULL, "SunLightPixelShader", "ps_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, &pixelShaderBuffer, &errorMessage);
if (FAILED(result))
{
// If the shader failed to compile it should have writen something to the error message.
if (errorMessage)
{
OutputShaderErrorMessage(errorMessage, hwnd, psFilename);
}
// If there was nothing in the error message then it simply could not find the file itself.
else
{
Logger::Get().Log("Failed to compile shader", __FILE__, __LINE__, Logger::LogLevel::Error);
}
return false;
}
@ -170,7 +161,6 @@ bool SunlightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHA
}
// Create the vertex input layout description.
// This setup needs to match the VertexType stucture in the ModelClass and in the shader.
polygonLayout[0].SemanticName = "POSITION";
polygonLayout[0].SemanticIndex = 0;
polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
@ -199,8 +189,7 @@ bool SunlightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHA
numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);
// Create the vertex input layout.
result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(),
&m_layout);
result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &m_layout);
if (FAILED(result))
{
Logger::Get().Log("Failed to create input layout", __FILE__, __LINE__, Logger::LogLevel::Error);
@ -253,53 +242,19 @@ bool SunlightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHA
return false;
}
// Setup the description of the camera dynamic constant buffer that is in the vertex shader.
cameraBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
cameraBufferDesc.ByteWidth = sizeof(CameraBufferType);
cameraBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cameraBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cameraBufferDesc.MiscFlags = 0;
cameraBufferDesc.StructureByteStride = 0;
// Create the camera constant buffer pointer so we can access the vertex shader constant buffer from within this class.
result = device->CreateBuffer(&cameraBufferDesc, NULL, &m_cameraBuffer);
if (FAILED(result))
{
Logger::Get().Log("Failed to create camera buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
return false;
}
// Setup the description of the dynamic constant buffer that is in the pixel shader.
lightColorBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
lightColorBufferDesc.ByteWidth = sizeof(SunLightColorBufferType);
lightColorBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
lightColorBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
lightColorBufferDesc.MiscFlags = 0;
lightColorBufferDesc.StructureByteStride = 0;
// Setup the description of the dynamic sunlight constant buffer that is in the pixel shader.
sunlightBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
sunlightBufferDesc.ByteWidth = sizeof(SunLightBufferType);
sunlightBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
sunlightBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
sunlightBufferDesc.MiscFlags = 0;
sunlightBufferDesc.StructureByteStride = 0;
// Create the constant buffer pointer so we can access the pixel shader constant buffer from within this class.
result = device->CreateBuffer(&lightColorBufferDesc, NULL, &m_sunlightColorBuffer);
result = device->CreateBuffer(&sunlightBufferDesc, NULL, &m_sunlightBuffer);
if (FAILED(result))
{
Logger::Get().Log("Failed to create sunlight color buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
return false;
}
// Setup the description of the dynamic constant buffer that is in the vertex shader.
lightPositionBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
lightPositionBufferDesc.ByteWidth = sizeof(SunLightPositionBufferType);
lightPositionBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
lightPositionBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
lightPositionBufferDesc.MiscFlags = 0;
lightPositionBufferDesc.StructureByteStride = 0;
// Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class.
result = device->CreateBuffer(&lightPositionBufferDesc, NULL, &m_sunlightPositionBuffer);
if (FAILED(result))
{
Logger::Get().Log("Failed to create sunlight position buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
Logger::Get().Log("Failed to create sunlight buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
return false;
}
@ -309,6 +264,8 @@ bool SunlightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHA
}
void SunlightShaderClass::ShutdownShader()
{
Logger::Get().Log("Shutting down SunLightShaderClass", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
@ -417,15 +374,14 @@ void SunlightShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWN
}
bool SunlightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor, XMFLOAT4 lightPosition, XMFLOAT4 ambientColor)
bool SunlightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, ID3D11ShaderResourceView* texture, XMFLOAT4 ambientColor, XMFLOAT4 diffuseColor, XMFLOAT3 lightDirection)
{
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;
unsigned int bufferNumber;
MatrixBufferType* dataPtr;
SunLightPositionBufferType* dataPtr2;
SunLightColorBufferType* dataPtr3;
CameraBufferType* dataPtr2;
SunLightBufferType* dataPtr3;
unsigned int bufferNumber;
// Transpose the matrices to prepare them for the shader.
worldMatrix = XMMatrixTranspose(worldMatrix);
@ -436,7 +392,6 @@ bool SunlightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext
result = deviceContext->Map(m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
Logger::Get().Log("Failed to map matrix buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
return false;
}
@ -454,71 +409,42 @@ bool SunlightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext
// Set the position of the constant buffer in the vertex shader.
bufferNumber = 0;
// Now set the constant buffer in the vertex shader with the updated values.
// Finally set the constant buffer in the vertex shader with the updated values.
deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_matrixBuffer);
// Lock the camera constant buffer so it can be written to.
result = deviceContext->Map(m_cameraBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
// Lock the sunlight constant buffer so it can be written to.
result = deviceContext->Map(m_sunlightBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
Logger::Get().Log("Failed to map camera buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
return false;
}
// Lock the light position constant buffer so it can be written to.
result = deviceContext->Map(m_sunlightPositionBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
Logger::Get().Log("Failed to map sunlight position buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
return false;
}
// Get a pointer to the data in the constant buffer.
dataPtr2 = (SunLightPositionBufferType*)mappedResource.pData;
dataPtr3 = (SunLightBufferType*)mappedResource.pData;
// Copy the light position variables into the constant buffer.
dataPtr2->sunPosition = lightPosition;
// Copy the lighting variables into the constant buffer.
dataPtr3->ambientColor = ambientColor;
dataPtr3->diffuseColor = diffuseColor;
dataPtr3->sunDirection = lightDirection;
// Unlock the constant buffer.
deviceContext->Unmap(m_sunlightPositionBuffer, 0);
deviceContext->Unmap(m_sunlightBuffer, 0);
// Set the position of the constant buffer in the vertex shader.
bufferNumber = 1;
// Set the position of the sunlight constant buffer in the pixel shader.
bufferNumber = 0;
// Finally set the constant buffer in the vertex shader with the updated values.
deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_sunlightPositionBuffer);
// Finally set the sunlight constant buffer in the pixel shader with the updated values.
deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_sunlightBuffer);
// Set shader texture resource in the pixel shader.
deviceContext->PSSetShaderResources(0, 1, &texture);
// Lock the light color constant buffer so it can be written to.
result = deviceContext->Map(m_sunlightColorBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
Logger::Get().Log("Failed to map sunlight color buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
return false;
}
// Get a pointer to the data in the constant buffer.
dataPtr3 = (SunLightColorBufferType*)mappedResource.pData;
// Copy the light color variables into the constant buffer.
dataPtr3->sunColor = diffuseColor;
// Unlock the constant buffer.
deviceContext->Unmap(m_sunlightColorBuffer, 0);
// Set the position of the constant buffer in the pixel shader.
bufferNumber = 0;
// Finally set the constant buffer in the pixel shader with the updated values.
deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_sunlightColorBuffer);
return true;
}
void SunlightShaderClass::RenderShader(ID3D11DeviceContext* deviceContext, int indexCount)
{
// Set the vertex input layout.

View File

@ -27,12 +27,10 @@ private :
struct SunLightBufferType
{
XMFLOAT4 ambientColor;
XMFLOAT4 diffuseColor;
XMFLOAT3 lightDirection;
float padding; // Added extra padding so structure is a multiple of 16 for CreateBuffer function requirements.
float specularPower;
XMFLOAT4 specularColor;
XMFLOAT4 ambientColor;
XMFLOAT3 sunDirection;
float padding; // Ajoutez un padding pour aligner la structure sur 16 octets
};
struct SunLightColorBufferType
@ -40,11 +38,6 @@ private :
XMFLOAT4 sunColor;
};
struct SunLightPositionBufferType
{
XMFLOAT4 sunPosition;
};
public :
SunlightShaderClass();
SunlightShaderClass(const SunlightShaderClass&);
@ -52,14 +45,14 @@ public :
bool Initialize(ID3D11Device*, HWND);
void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4, XMFLOAT4, XMFLOAT4);
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4, XMFLOAT4, XMFLOAT3);
private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4, XMFLOAT4, XMFLOAT4);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4, XMFLOAT4, XMFLOAT3);
void RenderShader(ID3D11DeviceContext*, int);
private: