Starting to add cascading shadow maps
This commit is contained in:
@@ -3,6 +3,18 @@ import LightEnv;
|
|||||||
import MaterialParameter;
|
import MaterialParameter;
|
||||||
import MATERIAL_FILE_NAME;
|
import MATERIAL_FILE_NAME;
|
||||||
|
|
||||||
|
const static uint64_t NUM_CASCADES = 4;
|
||||||
|
|
||||||
|
/*struct ShadowMappingData
|
||||||
|
{
|
||||||
|
Texture2DArray shadowMaps[NUM_CASCADES];
|
||||||
|
|
||||||
|
ConstantBuffer<float4x4> lightSpaceMatrices[NUM_CASCADES];
|
||||||
|
|
||||||
|
ConstantBuffer<float[NUM_CASCADES]> cascadeSplits;
|
||||||
|
};
|
||||||
|
ParameterBlock<ShadowMappingData> pShadowMapping;
|
||||||
|
*/
|
||||||
struct LightCullingData
|
struct LightCullingData
|
||||||
{
|
{
|
||||||
RWStructuredBuffer<uint> lightIndexList;
|
RWStructuredBuffer<uint> lightIndexList;
|
||||||
@@ -30,7 +42,13 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
float3 result = float3(0, 0, 0);
|
float3 result = float3(0, 0, 0);
|
||||||
for(int i = 0; i < pLightEnv.numDirectionalLights; ++i)
|
for(int i = 0; i < pLightEnv.numDirectionalLights; ++i)
|
||||||
{
|
{
|
||||||
float4 lightSpacePos = mul(biasMat, mul(pLightEnv.directionalLights[i].lightSpaceMatrix, float4(params.position_WS, 1)));
|
/*uint cascadeIndex = 0;
|
||||||
|
for (uint c = 0; c < NUM_CASCADES - 1; ++c) {
|
||||||
|
if (params.position_VS.z < pShadowMapping.cascadeSplits[c]) {
|
||||||
|
cascadeIndex = c + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float4 lightSpacePos = mul(biasMat, mul(pShadowMapping.lightSpaceMatrices[i], float4(params.position_WS, 1)));
|
||||||
float4 shadowCoord = lightSpacePos / lightSpacePos.w;
|
float4 shadowCoord = lightSpacePos / lightSpacePos.w;
|
||||||
int2 texDim;
|
int2 texDim;
|
||||||
pLightEnv.shadowMap.GetDimensions(texDim.x, texDim.y);
|
pLightEnv.shadowMap.GetDimensions(texDim.x, texDim.y);
|
||||||
@@ -55,9 +73,9 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
shadowFactor += shadow;
|
shadowFactor += shadow;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
result += (shadowFactor / count) * pLightEnv.directionalLights[i].illuminate(lightingParams, brdf);
|
result += /*(shadowFactor / count) **/ pLightEnv.directionalLights[i].illuminate(lightingParams, brdf);
|
||||||
}
|
}
|
||||||
for (uint i = 0; i < pLightEnv.numPointLights; ++i)
|
for (uint i = 0; i < pLightEnv.numPointLights; ++i)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ struct DirectionalLight : ILightEnv
|
|||||||
{
|
{
|
||||||
float4 color;
|
float4 color;
|
||||||
float4 direction;
|
float4 direction;
|
||||||
float4x4 lightSpaceMatrix;
|
|
||||||
|
|
||||||
float3 illuminate<B:IBRDF>(LightingParameter params, B brdf)
|
float3 illuminate<B:IBRDF>(LightingParameter params, B brdf)
|
||||||
{
|
{
|
||||||
@@ -369,4 +368,3 @@ struct CookTorrance : IBRDF
|
|||||||
}
|
}
|
||||||
[mutating] void setNormal(float3 n) { normal = n; }
|
[mutating] void setNormal(float3 n) { normal = n; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ struct FragmentParameter
|
|||||||
float3 normal_WS : NORMALWS;
|
float3 normal_WS : NORMALWS;
|
||||||
float3 tangent_WS : TANGENTWS;
|
float3 tangent_WS : TANGENTWS;
|
||||||
float3 biTangent_WS : BITANGENTWS;
|
float3 biTangent_WS : BITANGENTWS;
|
||||||
float3 position_WS : POSITIONWS;
|
float3 position_WS : POSITIONWS;
|
||||||
|
float3 position_VS : POSITIONVS;
|
||||||
float3 vertexColor : COLOR;
|
float3 vertexColor : COLOR;
|
||||||
float4 texCoords0 : TEXCOORDS0;
|
float4 texCoords0 : TEXCOORDS0;
|
||||||
float4 texCoords1 : TEXCOORDS1;
|
float4 texCoords1 : TEXCOORDS1;
|
||||||
@@ -109,7 +110,8 @@ struct FragmentParameter
|
|||||||
result.normal_WS = f0.normal_WS * barycentricCoords.x + f1.normal_WS * barycentricCoords.y + f2.normal_WS * barycentricCoords.z;
|
result.normal_WS = f0.normal_WS * barycentricCoords.x + f1.normal_WS * barycentricCoords.y + f2.normal_WS * barycentricCoords.z;
|
||||||
result.tangent_WS = f0.tangent_WS * barycentricCoords.x + f1.tangent_WS * barycentricCoords.y + f2.tangent_WS * barycentricCoords.z;
|
result.tangent_WS = f0.tangent_WS * barycentricCoords.x + f1.tangent_WS * barycentricCoords.y + f2.tangent_WS * barycentricCoords.z;
|
||||||
result.biTangent_WS = f0.biTangent_WS * barycentricCoords.x + f1.biTangent_WS * barycentricCoords.y + f2.biTangent_WS * barycentricCoords.z;
|
result.biTangent_WS = f0.biTangent_WS * barycentricCoords.x + f1.biTangent_WS * barycentricCoords.y + f2.biTangent_WS * barycentricCoords.z;
|
||||||
result.position_WS = f0.position_WS * barycentricCoords.x + f1.position_WS * barycentricCoords.y + f2.position_WS * barycentricCoords.z;
|
result.position_WS = f0.position_WS * barycentricCoords.x + f1.position_WS * barycentricCoords.y + f2.position_WS * barycentricCoords.z;
|
||||||
|
result.position_VS = f0.position_VS * barycentricCoords.x + f1.position_VS * barycentricCoords.y + f2.position_VS * barycentricCoords.z;
|
||||||
result.vertexColor = f0.vertexColor * barycentricCoords.x + f1.vertexColor * barycentricCoords.y + f2.vertexColor * barycentricCoords.z;
|
result.vertexColor = f0.vertexColor * barycentricCoords.x + f1.vertexColor * barycentricCoords.y + f2.vertexColor * barycentricCoords.z;
|
||||||
result.texCoords0 = f0.texCoords0 * barycentricCoords.x + f1.texCoords0 * barycentricCoords.y + f2.texCoords0 * barycentricCoords.z;
|
result.texCoords0 = f0.texCoords0 * barycentricCoords.x + f1.texCoords0 * barycentricCoords.y + f2.texCoords0 * barycentricCoords.z;
|
||||||
result.texCoords1 = f0.texCoords1 * barycentricCoords.x + f1.texCoords1 * barycentricCoords.y + f2.texCoords1 * barycentricCoords.z;
|
result.texCoords1 = f0.texCoords1 * barycentricCoords.x + f1.texCoords1 * barycentricCoords.y + f2.texCoords1 * barycentricCoords.z;
|
||||||
@@ -135,7 +137,8 @@ struct VertexAttributes
|
|||||||
FragmentParameter getParameter(float4x4 transformMatrix, float4x4 inverseTransformMatrix)
|
FragmentParameter getParameter(float4x4 transformMatrix, float4x4 inverseTransformMatrix)
|
||||||
{
|
{
|
||||||
float4 modelPos = float4(position_MS, 1);
|
float4 modelPos = float4(position_MS, 1);
|
||||||
float4 worldPos = mul(transformMatrix, modelPos);
|
float4 worldPos = mul(transformMatrix, modelPos);
|
||||||
|
float4 viewPos = mul(pViewParams.viewMatrix, worldPos);
|
||||||
float4 clipPos = mul(pViewParams.viewProjectionMatrix, worldPos);
|
float4 clipPos = mul(pViewParams.viewProjectionMatrix, worldPos);
|
||||||
FragmentParameter result;
|
FragmentParameter result;
|
||||||
result.position_CS = clipPos;
|
result.position_CS = clipPos;
|
||||||
@@ -145,7 +148,8 @@ struct VertexAttributes
|
|||||||
result.biTangent_WS = mul(transformMatrix, float4(biTangent_MS, 0)).xyz;
|
result.biTangent_WS = mul(transformMatrix, float4(biTangent_MS, 0)).xyz;
|
||||||
result.normal_WS = mul(transformMatrix, float4(normal_MS, 0)).xyz;
|
result.normal_WS = mul(transformMatrix, float4(normal_MS, 0)).xyz;
|
||||||
result.vertexColor = vertexColor;
|
result.vertexColor = vertexColor;
|
||||||
result.position_WS = worldPos.xyz;
|
result.position_WS = worldPos.xyz;
|
||||||
|
result.position_VS = viewPos.xyz;
|
||||||
result.texCoords0 = float4(texCoords[0], texCoords[1]);
|
result.texCoords0 = float4(texCoords[0], texCoords[1]);
|
||||||
result.texCoords1 = float4(texCoords[2], texCoords[3]);
|
result.texCoords1 = float4(texCoords[2], texCoords[3]);
|
||||||
result.texCoords2 = float4(texCoords[4], texCoords[5]);
|
result.texCoords2 = float4(texCoords[4], texCoords[5]);
|
||||||
|
|||||||
@@ -535,8 +535,11 @@ template <typename T, size_t N> struct StaticArray {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
constexpr StaticArray(const StaticArray& other) = default;
|
||||||
|
constexpr StaticArray(StaticArray&& other) = default;
|
||||||
constexpr ~StaticArray() {}
|
constexpr ~StaticArray() {}
|
||||||
|
constexpr StaticArray& operator=(const StaticArray& other) = default;
|
||||||
|
constexpr StaticArray& operator=(StaticArray&& other) = default;
|
||||||
constexpr size_type size() const { return N; }
|
constexpr size_type size() const { return N; }
|
||||||
constexpr pointer data() { return _data; }
|
constexpr pointer data() { return _data; }
|
||||||
constexpr const_pointer data() const { return _data; }
|
constexpr const_pointer data() const { return _data; }
|
||||||
|
|||||||
@@ -84,7 +84,8 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics)
|
|||||||
BasePass::~BasePass() {}
|
BasePass::~BasePass() {}
|
||||||
|
|
||||||
void BasePass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
void BasePass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||||
viewParamsSet = createViewParamsSet(cam, transform);
|
updateViewParameters(cam, transform);
|
||||||
|
viewParamsSet = createViewParamsSet();
|
||||||
|
|
||||||
cameraPos = transform.getPosition();
|
cameraPos = transform.getPosition();
|
||||||
cameraForward = transform.getForward();
|
cameraForward = transform.getForward();
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) : Render
|
|||||||
CachedDepthPass::~CachedDepthPass() {}
|
CachedDepthPass::~CachedDepthPass() {}
|
||||||
|
|
||||||
void CachedDepthPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
void CachedDepthPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||||
viewParamsSet = createViewParamsSet(cam, transform);
|
updateViewParameters(cam, transform);
|
||||||
|
viewParamsSet = createViewParamsSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CachedDepthPass::render() {
|
void CachedDepthPass::render() {
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ DepthCullingPass::DepthCullingPass(Gfx::PGraphics graphics, PScene scene) : Rend
|
|||||||
DepthCullingPass::~DepthCullingPass() {}
|
DepthCullingPass::~DepthCullingPass() {}
|
||||||
|
|
||||||
void DepthCullingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
void DepthCullingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||||
viewParamsSet = createViewParamsSet(cam, transform);
|
updateViewParameters(cam, transform);
|
||||||
|
viewParamsSet = createViewParamsSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthCullingPass::render() {
|
void DepthCullingPass::render() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "LightCullingPass.h"
|
#include "LightCullingPass.h"
|
||||||
#include "Actor/CameraActor.h"
|
#include "Actor/CameraActor.h"
|
||||||
#include "Component/Camera.h"
|
#include "Component/Camera.h"
|
||||||
|
#include "Component/Transform.h"
|
||||||
#include "Graphics/Command.h"
|
#include "Graphics/Command.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Graphics/Pipeline.h"
|
#include "Graphics/Pipeline.h"
|
||||||
@@ -15,7 +16,8 @@ LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene) : Rend
|
|||||||
LightCullingPass::~LightCullingPass() {}
|
LightCullingPass::~LightCullingPass() {}
|
||||||
|
|
||||||
void LightCullingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
void LightCullingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||||
viewParamsSet = createViewParamsSet(cam, transform);
|
updateViewParameters(cam, transform);
|
||||||
|
viewParamsSet = createViewParamsSet();
|
||||||
|
|
||||||
oLightIndexCounter->pipelineBarrier(Gfx::SE_ACCESS_MEMORY_WRITE_BIT | Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
oLightIndexCounter->pipelineBarrier(Gfx::SE_ACCESS_MEMORY_WRITE_BIT | Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_MEMORY_WRITE_BIT,
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_MEMORY_WRITE_BIT,
|
||||||
@@ -232,7 +234,8 @@ void LightCullingPass::setupFrustums() {
|
|||||||
numThreads = glm::ceil(glm::vec4(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1, 0));
|
numThreads = glm::ceil(glm::vec4(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1, 0));
|
||||||
numThreadGroups = glm::ceil(glm::vec4(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1, 0));
|
numThreadGroups = glm::ceil(glm::vec4(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1, 0));
|
||||||
|
|
||||||
viewParamsSet = createViewParamsSet(Component::Camera(), Component::Transform());
|
updateViewParameters(Component::Camera(), Component::Transform());
|
||||||
|
viewParamsSet = createViewParamsSet();
|
||||||
|
|
||||||
dispatchParamsLayout = graphics->createDescriptorLayout("pDispatchParams");
|
dispatchParamsLayout = graphics->createDescriptorLayout("pDispatchParams");
|
||||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
|||||||
@@ -65,8 +65,8 @@ RayTracingPass::RayTracingPass(Gfx::PGraphics graphics, PScene scene) : RenderPa
|
|||||||
static uint32 pass = 0;
|
static uint32 pass = 0;
|
||||||
static Component::Transform lastCam;
|
static Component::Transform lastCam;
|
||||||
void RayTracingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
void RayTracingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||||
viewParamsSet = createViewParamsSet(cam, transform);
|
updateViewParameters(cam, transform);
|
||||||
if (lastCam.getPosition() != transform.getPosition() || lastCam.getForward() != transform.getForward()) {
|
viewParamsSet = createViewParamsSet(); if (lastCam.getPosition() != transform.getPosition() || lastCam.getForward() != transform.getForward()) {
|
||||||
lastCam = transform;
|
lastCam = transform;
|
||||||
pass = 0;
|
pass = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ void RenderPass::setResources(PRenderGraphResources _resources) { resources = _r
|
|||||||
|
|
||||||
void RenderPass::setViewport(Gfx::PViewport _viewport) { viewport = _viewport; }
|
void RenderPass::setViewport(Gfx::PViewport _viewport) { viewport = _viewport; }
|
||||||
|
|
||||||
Gfx::PDescriptorSet RenderPass::createViewParamsSet(const Component::Camera& cam, const Component::Transform& transform)
|
void RenderPass::updateViewParameters(const Component::Camera& cam, const Component::Transform& transform) {
|
||||||
{
|
|
||||||
auto screenDim = Vector2(static_cast<float>(viewport->getWidth()), static_cast<float>(viewport->getHeight()));
|
auto screenDim = Vector2(static_cast<float>(viewport->getWidth()), static_cast<float>(viewport->getHeight()));
|
||||||
Vector eyePos = transform.getPosition();
|
Vector eyePos = transform.getPosition();
|
||||||
Vector lookAt = eyePos + transform.getForward();
|
Vector lookAt = eyePos + transform.getForward();
|
||||||
@@ -48,24 +47,27 @@ Gfx::PDescriptorSet RenderPass::createViewParamsSet(const Component::Camera& cam
|
|||||||
.frameIndex = Gfx::getCurrentFrameIndex(),
|
.frameIndex = Gfx::getCurrentFrameIndex(),
|
||||||
.time = static_cast<float>(Gfx::getCurrentFrameTime()),
|
.time = static_cast<float>(Gfx::getCurrentFrameTime()),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Gfx::PDescriptorSet RenderPass::createViewParamsSet()
|
||||||
|
{
|
||||||
// screen space
|
// screen space
|
||||||
StaticArray<Vector4, 4> corners = {
|
//StaticArray<Vector4, 4> corners = {
|
||||||
Vector4(0, 0, -1, 1),
|
// Vector4(0, 0, -1, 1),
|
||||||
Vector4(screenDim.x, 0, -1, 1),
|
// Vector4(screenDim.x, 0, -1, 1),
|
||||||
Vector4(screenDim.y, 0, -1, 1),
|
// Vector4(screenDim.y, 0, -1, 1),
|
||||||
Vector4(screenDim.x, screenDim.y, -1, 1),
|
// Vector4(screenDim.x, screenDim.y, -1, 1),
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
for (uint32 i = 0; i < corners.size(); ++i) {
|
//for (uint32 i = 0; i < corners.size(); ++i) {
|
||||||
Vector2 texCoord = Vector2(corners[i].x, corners[i].y) / screenDim;
|
// Vector2 texCoord = Vector2(corners[i].x, corners[i].y) / screenDim;
|
||||||
|
//
|
||||||
Vector4 clip = Vector4(Vector2(texCoord.x, 1 - texCoord.y) * 2.0f - 1.0f, corners[i].z, corners[i].w);
|
// Vector4 clip = Vector4(Vector2(texCoord.x, 1 - texCoord.y) * 2.0f - 1.0f, corners[i].z, corners[i].w);
|
||||||
|
//
|
||||||
Vector4 world = viewParams.inverseViewProjectionMatrix * clip;
|
// Vector4 world = viewParams.inverseViewProjectionMatrix * clip;
|
||||||
|
//
|
||||||
corners[i] = world / world.w;
|
// corners[i] = world / world.w;
|
||||||
}
|
//}
|
||||||
|
|
||||||
// extract_planes_from_view_projection_matrix(viewParams.viewProjectionMatrix, viewParams.viewFrustum);
|
// extract_planes_from_view_projection_matrix(viewParams.viewProjectionMatrix, viewParams.viewFrustum);
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ class RenderPass {
|
|||||||
void setViewport(Gfx::PViewport _viewport);
|
void setViewport(Gfx::PViewport _viewport);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Gfx::PDescriptorSet createViewParamsSet(const Component::Camera& cam, const Component::Transform& transform);
|
void updateViewParameters(const Component::Camera& cam, const Component::Transform& transform);
|
||||||
|
Gfx::PDescriptorSet createViewParamsSet();
|
||||||
struct Plane {
|
struct Plane {
|
||||||
Vector n;
|
Vector n;
|
||||||
float d;
|
float d;
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
#include "ShadowPass.h"
|
#include "ShadowPass.h"
|
||||||
|
#include "Graphics/Enums.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
|
#include "Graphics/Initializer.h"
|
||||||
#include "Graphics/Shader.h"
|
#include "Graphics/Shader.h"
|
||||||
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
|
#include <glm/matrix.hpp>
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -39,126 +43,214 @@ ShadowPass::ShadowPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graph
|
|||||||
|
|
||||||
ShadowPass::~ShadowPass() {}
|
ShadowPass::~ShadowPass() {}
|
||||||
|
|
||||||
void ShadowPass::beginFrame(const Component::Camera&, const Component::Transform&) {}
|
void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Transform& transform) {
|
||||||
|
uint32 cascadeDim = SHADOW_MAP_SIZE;
|
||||||
|
float cascadeSplits[NUM_CASCADES];
|
||||||
|
|
||||||
|
float nearClip = camera.nearPlane;
|
||||||
|
float farClip = camera.farPlane;
|
||||||
|
float clipRange = farClip - nearClip;
|
||||||
|
|
||||||
|
float minZ = nearClip;
|
||||||
|
float maxZ = nearClip + clipRange;
|
||||||
|
|
||||||
|
float range = maxZ - minZ;
|
||||||
|
float ratio = maxZ / minZ;
|
||||||
|
constexpr float cascadeSplitLambda = 0.95f;
|
||||||
|
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
||||||
|
cascades[i].shadowMaps = graphics->createTexture2D(TextureCreateInfo{
|
||||||
|
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||||
|
.width = cascadeDim,
|
||||||
|
.height = cascadeDim,
|
||||||
|
.elements = (uint32)scene->getLightEnvironment()->getNumDirectionalLights(),
|
||||||
|
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
|
.name = "ShadowMapCascade",
|
||||||
|
});
|
||||||
|
cascades[i].views.clear();
|
||||||
|
for (uint32 j = 0; j < cascades[i].shadowMaps->getNumLayers(); ++j) {
|
||||||
|
cascades[i].views.add(cascades[i].shadowMaps->createTextureView(0, 1, j, 1));
|
||||||
|
}
|
||||||
|
cascadeDim /= 2;
|
||||||
|
float p = (i + 1) / static_cast<float>(NUM_CASCADES);
|
||||||
|
float log = minZ * std::pow(ratio, p);
|
||||||
|
float uniform = minZ + range * p;
|
||||||
|
float d = cascadeSplitLambda * (log - uniform) + uniform;
|
||||||
|
cascadeSplits[i] = (d - nearClip) / clipRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
// call this to update view params member, ignore descriptor set
|
||||||
|
updateViewParameters(camera, transform);
|
||||||
|
Array<Vector> frustumCorners = {
|
||||||
|
Vector(-1.0f, 1.0f, 0.0f), Vector(1.0f, 1.0f, 0.0f), Vector(1.0f, -1.0f, 0.0f), Vector(-1.0f, -1.0f, 0.0f),
|
||||||
|
Vector(-1.0f, 1.0f, 1.0f), Vector(1.0f, 1.0f, 1.0f), Vector(1.0f, -1.0f, 1.0f), Vector(-1.0f, -1.0f, 1.0f),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& c : frustumCorners) {
|
||||||
|
Vector4 invCorner = viewParams.inverseViewProjectionMatrix * Vector4(c, 1);
|
||||||
|
c = invCorner / invCorner.w;
|
||||||
|
}
|
||||||
|
for (uint32 s = 0; s < scene->getLightEnvironment()->getNumDirectionalLights(); ++s) {
|
||||||
|
float lastSplitDist = 0.0;
|
||||||
|
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
||||||
|
float splitDist = cascadeSplits[i];
|
||||||
|
|
||||||
|
Array<Vector> cascadeCorners(8);
|
||||||
|
for (uint32 j = 0; j < 4; j++) {
|
||||||
|
Vector dist = frustumCorners[j + 4] - frustumCorners[j];
|
||||||
|
cascadeCorners[j + 4] = frustumCorners[j] + (dist * splitDist);
|
||||||
|
cascadeCorners[j] = frustumCorners[j] + (dist * lastSplitDist);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector frustumCenter = Vector(0);
|
||||||
|
for (uint32 j = 0; j < 8; j++) {
|
||||||
|
frustumCenter += cascadeCorners[j];
|
||||||
|
}
|
||||||
|
frustumCenter /= 8.0f;
|
||||||
|
|
||||||
|
float radius = 0.0f;
|
||||||
|
for (uint j = 0; j < 8; j++) {
|
||||||
|
float distance = glm::length(cascadeCorners[j] - frustumCenter);
|
||||||
|
radius = glm::max(radius, distance);
|
||||||
|
}
|
||||||
|
radius = std::ceil(radius * 16.0f) / 16.0f;
|
||||||
|
|
||||||
|
Vector maxExtents = Vector(radius);
|
||||||
|
Vector minExtents = -maxExtents;
|
||||||
|
|
||||||
|
Vector lightDir = glm::normalize(scene->getLightEnvironment()->getDirectionalLight(s).direction);
|
||||||
|
Matrix4 viewMatrix = glm::lookAt(frustumCenter - lightDir * -minExtents.z, frustumCenter, Vector(0, 1, 0));
|
||||||
|
Matrix4 projectionMatrix =
|
||||||
|
glm::ortho(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f, maxExtents.z - minExtents.z);
|
||||||
|
Matrix4 viewProjectionMatrix = projectionMatrix * viewMatrix;
|
||||||
|
viewParams.viewMatrix = viewMatrix;
|
||||||
|
viewParams.inverseViewMatrix = glm::inverse(viewMatrix);
|
||||||
|
viewParams.projectionMatrix = projectionMatrix;
|
||||||
|
viewParams.inverseProjection = glm::inverse(projectionMatrix);
|
||||||
|
viewParams.viewProjectionMatrix = viewProjectionMatrix;
|
||||||
|
viewParams.inverseViewProjectionMatrix = glm::inverse(viewProjectionMatrix);
|
||||||
|
viewParams.screenDimensions = Vector2(maxExtents.x - minExtents.x, maxExtents.y - minExtents.y);
|
||||||
|
viewParams.invScreenDimensions = 1.0f / viewParams.screenDimensions;
|
||||||
|
cascades[i].viewParams.add(createViewParamsSet());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShadowPass::render() {
|
void ShadowPass::render() {
|
||||||
graphics->beginDebugRegion("ShadowPass");
|
graphics->beginDebugRegion("ShadowPass");
|
||||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("ShadowPass");
|
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("ShadowPass");
|
||||||
permutation.setDepthCulling(true);
|
permutation.setDepthCulling(true);
|
||||||
permutation.setPositionOnly(true);
|
permutation.setPositionOnly(true);
|
||||||
const auto& shadowMaps = scene->getLightEnvironment()->getShadowMaps();
|
for (uint32 c = 0; c < NUM_CASCADES; ++c) {
|
||||||
for (uint32 shadowIndex = 0; shadowIndex < scene->getLightEnvironment()->getNumDirectionalLights(); ++shadowIndex) {
|
graphics->beginDebugRegion("Cascade");
|
||||||
Array<Gfx::ORenderCommand> commands;
|
for (uint32 shadowIndex = 0; shadowIndex < cascades[c].shadowMaps->getNumLayers(); ++shadowIndex) {
|
||||||
renderPass = graphics->createRenderPass(
|
Array<Gfx::ORenderCommand> commands;
|
||||||
Gfx::RenderTargetLayout{
|
renderPass = graphics->createRenderPass(
|
||||||
.depthAttachment = Gfx::RenderTargetAttachment(shadowMaps[shadowIndex]->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
Gfx::RenderTargetLayout{
|
||||||
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
.depthAttachment = Gfx::RenderTargetAttachment(
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE),
|
cascades[c].views[shadowIndex], Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE),
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Gfx::SubPassDependency{
|
|
||||||
.srcSubpass = ~0U,
|
|
||||||
.dstSubpass = 0,
|
|
||||||
.srcStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
|
||||||
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
|
||||||
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
|
||||||
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
|
||||||
},
|
},
|
||||||
Gfx::SubPassDependency{
|
{
|
||||||
.srcSubpass = 0,
|
Gfx::SubPassDependency{
|
||||||
.dstSubpass = ~0U,
|
.srcSubpass = ~0U,
|
||||||
.srcStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
.dstSubpass = 0,
|
||||||
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
.srcStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
},
|
||||||
|
Gfx::SubPassDependency{
|
||||||
|
.srcSubpass = 0,
|
||||||
|
.dstSubpass = ~0U,
|
||||||
|
.srcStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
.size = {cascades[c].shadowMaps->getWidth(), cascades[c].shadowMaps->getHeight()},
|
||||||
.size = {shadowMaps[shadowIndex]->getWidth(), shadowMaps[shadowIndex]->getHeight()},
|
.offset = {0, 0},
|
||||||
.offset = {0, 0},
|
},
|
||||||
},
|
"Shadow");
|
||||||
"Shadow");
|
graphics->beginRenderPass(renderPass);
|
||||||
Component::Camera lightCamera = Component::Camera{
|
for (VertexData* vertexData : VertexData::getList()) {
|
||||||
.nearPlane = -100.f,
|
permutation.setVertexData(vertexData->getTypeName());
|
||||||
.farPlane = 100.0f,
|
Gfx::PermutationId id(permutation);
|
||||||
};
|
|
||||||
Gfx::PDescriptorSet viewParamsSet = createViewParamsSet(lightCamera, scene->getLightEnvironment()->getDirectionalTransform(shadowIndex));
|
|
||||||
graphics->beginRenderPass(renderPass);
|
|
||||||
for (VertexData* vertexData : VertexData::getList()) {
|
|
||||||
permutation.setVertexData(vertexData->getTypeName());
|
|
||||||
Gfx::PermutationId id(permutation);
|
|
||||||
|
|
||||||
Gfx::ORenderCommand command = graphics->createRenderCommand("ShadowRender");
|
Gfx::ORenderCommand command = graphics->createRenderCommand("ShadowRender");
|
||||||
command->setViewport(shadowViewport);
|
command->setViewport(shadowViewport);
|
||||||
|
|
||||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||||
constexpr float depthBiasConstant = -1.25f;
|
constexpr float depthBiasConstant = -1.25f;
|
||||||
constexpr float depthBiasSlope = -1.75f;
|
constexpr float depthBiasSlope = -1.75f;
|
||||||
if (graphics->supportMeshShading()) {
|
if (graphics->supportMeshShading()) {
|
||||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||||
.taskShader = collection->taskShader,
|
.taskShader = collection->taskShader,
|
||||||
.meshShader = collection->meshShader,
|
.meshShader = collection->meshShader,
|
||||||
.fragmentShader = collection->fragmentShader,
|
.fragmentShader = collection->fragmentShader,
|
||||||
.renderPass = renderPass,
|
.renderPass = renderPass,
|
||||||
.pipelineLayout = collection->pipelineLayout,
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
.rasterizationState =
|
.rasterizationState =
|
||||||
{
|
{
|
||||||
.cullMode = Gfx::SE_CULL_MODE_FRONT_BIT,
|
.cullMode = Gfx::SE_CULL_MODE_FRONT_BIT,
|
||||||
.depthBiasEnable = true,
|
.depthBiasEnable = true,
|
||||||
.depthBiasConstantFactor = depthBiasConstant,
|
.depthBiasConstantFactor = depthBiasConstant,
|
||||||
.depthBiasSlopeFactor = depthBiasSlope,
|
.depthBiasSlopeFactor = depthBiasSlope,
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
|
command->bindPipeline(pipeline);
|
||||||
|
} else {
|
||||||
|
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||||
|
.vertexShader = collection->vertexShader,
|
||||||
|
.fragmentShader = collection->fragmentShader,
|
||||||
|
.renderPass = renderPass,
|
||||||
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
|
.rasterizationState =
|
||||||
|
{
|
||||||
|
.cullMode = Gfx::SE_CULL_MODE_FRONT_BIT,
|
||||||
|
.depthBiasEnable = true,
|
||||||
|
.depthBiasConstantFactor = depthBiasConstant,
|
||||||
|
.depthBiasSlopeFactor = depthBiasSlope,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
|
command->bindPipeline(pipeline);
|
||||||
|
}
|
||||||
|
command->bindDescriptor({cascades[c].viewParams[shadowIndex], vertexData->getVertexDataSet(), vertexData->getInstanceDataSet()});
|
||||||
|
VertexData::DrawCallOffsets offsets = {
|
||||||
|
.instanceOffset = 0,
|
||||||
};
|
};
|
||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0,
|
||||||
command->bindPipeline(pipeline);
|
sizeof(VertexData::DrawCallOffsets), &offsets);
|
||||||
} else {
|
if (graphics->supportMeshShading()) {
|
||||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
command->drawMesh((uint32)vertexData->getNumInstances(), 1, 1);
|
||||||
.vertexShader = collection->vertexShader,
|
} else {
|
||||||
.fragmentShader = collection->fragmentShader,
|
const auto& materials = vertexData->getMaterialData();
|
||||||
.renderPass = renderPass,
|
for (const auto& materialData : materials) {
|
||||||
.pipelineLayout = collection->pipelineLayout,
|
// material not used for any active meshes, skip
|
||||||
.rasterizationState =
|
if (materialData.instances.size() == 0)
|
||||||
{
|
continue;
|
||||||
.cullMode = Gfx::SE_CULL_MODE_FRONT_BIT,
|
for (const auto& drawCall : materialData.instances) {
|
||||||
.depthBiasEnable = true,
|
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||||
.depthBiasConstantFactor = depthBiasConstant,
|
uint32 inst = drawCall.offsets.instanceOffset;
|
||||||
.depthBiasSlopeFactor = depthBiasSlope,
|
for (const auto& meshData : drawCall.instanceMeshData) {
|
||||||
},
|
// all meshlets of a mesh share the same indices offset
|
||||||
};
|
command->drawIndexed(meshData.indicesRange.size, 1, meshData.indicesRange.offset,
|
||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
vertexData->getIndicesOffset(meshData.meshletRange.offset), inst++);
|
||||||
command->bindPipeline(pipeline);
|
}
|
||||||
}
|
|
||||||
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet()});
|
|
||||||
VertexData::DrawCallOffsets offsets = {
|
|
||||||
.instanceOffset = 0,
|
|
||||||
};
|
|
||||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0,
|
|
||||||
sizeof(VertexData::DrawCallOffsets), &offsets);
|
|
||||||
if (graphics->supportMeshShading()) {
|
|
||||||
command->drawMesh((uint32)vertexData->getNumInstances(), 1, 1);
|
|
||||||
} else {
|
|
||||||
const auto& materials = vertexData->getMaterialData();
|
|
||||||
for (const auto& materialData : materials) {
|
|
||||||
// material not used for any active meshes, skip
|
|
||||||
if (materialData.instances.size() == 0)
|
|
||||||
continue;
|
|
||||||
for (const auto& drawCall : materialData.instances) {
|
|
||||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
|
||||||
uint32 inst = drawCall.offsets.instanceOffset;
|
|
||||||
for (const auto& meshData : drawCall.instanceMeshData) {
|
|
||||||
// all meshlets of a mesh share the same indices offset
|
|
||||||
command->drawIndexed(meshData.indicesRange.size, 1, meshData.indicesRange.offset,
|
|
||||||
vertexData->getIndicesOffset(meshData.meshletRange.offset), inst++);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
commands.add(std::move(command));
|
||||||
}
|
}
|
||||||
commands.add(std::move(command));
|
graphics->executeCommands(std::move(commands));
|
||||||
|
graphics->endRenderPass();
|
||||||
|
graphics->waitDeviceIdle();
|
||||||
}
|
}
|
||||||
graphics->executeCommands(std::move(commands));
|
graphics->endDebugRegion();
|
||||||
graphics->endRenderPass();
|
|
||||||
graphics->waitDeviceIdle();
|
|
||||||
}
|
}
|
||||||
graphics->endDebugRegion();
|
graphics->endDebugRegion();
|
||||||
}
|
}
|
||||||
@@ -168,7 +260,7 @@ void ShadowPass::endFrame() {}
|
|||||||
void ShadowPass::publishOutputs() {
|
void ShadowPass::publishOutputs() {
|
||||||
shadowViewport = graphics->createViewport(nullptr, ViewportCreateInfo{.dimensions =
|
shadowViewport = graphics->createViewport(nullptr, ViewportCreateInfo{.dimensions =
|
||||||
{
|
{
|
||||||
.size = {8192, 8192},
|
.size = {SHADOW_MAP_SIZE, SHADOW_MAP_SIZE},
|
||||||
.offset = {0, 0},
|
.offset = {0, 0},
|
||||||
},
|
},
|
||||||
.fieldOfView = 0,
|
.fieldOfView = 0,
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Graphics/Buffer.h"
|
||||||
|
#include "Graphics/Descriptor.h"
|
||||||
#include "RenderPass.h"
|
#include "RenderPass.h"
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
|
|
||||||
|
static constexpr uint64 SHADOW_MAP_SIZE = 8192;
|
||||||
|
|
||||||
class ShadowPass : public RenderPass {
|
class ShadowPass : public RenderPass {
|
||||||
public:
|
public:
|
||||||
ShadowPass(Gfx::PGraphics graphics, PScene scene);
|
ShadowPass(Gfx::PGraphics graphics, PScene scene);
|
||||||
@@ -15,6 +20,13 @@ class ShadowPass : public RenderPass {
|
|||||||
virtual void createRenderPass() override;
|
virtual void createRenderPass() override;
|
||||||
private:
|
private:
|
||||||
AABB cameraFrustumBox;
|
AABB cameraFrustumBox;
|
||||||
|
static constexpr uint64 NUM_CASCADES = 4;
|
||||||
|
struct Cascade {
|
||||||
|
Gfx::OTexture2D shadowMaps;
|
||||||
|
Array<Gfx::OTextureView> views;
|
||||||
|
Array<Gfx::PDescriptorSet> viewParams;
|
||||||
|
};
|
||||||
|
StaticArray<Cascade, NUM_CASCADES> cascades;
|
||||||
Gfx::OPipelineLayout shadowLayout;
|
Gfx::OPipelineLayout shadowLayout;
|
||||||
Gfx::PShaderBuffer cullingBuffer;
|
Gfx::PShaderBuffer cullingBuffer;
|
||||||
Gfx::OViewport shadowViewport;
|
Gfx::OViewport shadowViewport;
|
||||||
|
|||||||
@@ -124,7 +124,8 @@ ToneMappingPass::ToneMappingPass(Gfx::PGraphics graphics) : RenderPass(graphics)
|
|||||||
ToneMappingPass::~ToneMappingPass() {}
|
ToneMappingPass::~ToneMappingPass() {}
|
||||||
|
|
||||||
void ToneMappingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
void ToneMappingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||||
viewParamsSet = createViewParamsSet(cam, transform);
|
updateViewParameters(cam, transform);
|
||||||
|
viewParamsSet = createViewParamsSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToneMappingPass::render() {
|
void ToneMappingPass::render() {
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ UIPass::UIPass(Gfx::PGraphics graphics, UI::PSystem system) : RenderPass(graphic
|
|||||||
UIPass::~UIPass() {}
|
UIPass::~UIPass() {}
|
||||||
|
|
||||||
void UIPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
void UIPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||||
viewParamsSet = createViewParamsSet(cam, transform);
|
updateViewParameters(cam, transform);
|
||||||
|
viewParamsSet = createViewParamsSet();
|
||||||
glyphs.clear();
|
glyphs.clear();
|
||||||
usedTextures.clear();
|
usedTextures.clear();
|
||||||
elements.clear();
|
elements.clear();
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ VisibilityPass::VisibilityPass(Gfx::PGraphics graphics) : RenderPass(graphics) {
|
|||||||
VisibilityPass::~VisibilityPass() {}
|
VisibilityPass::~VisibilityPass() {}
|
||||||
|
|
||||||
void VisibilityPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
void VisibilityPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||||
viewParamsSet = createViewParamsSet(cam, transform);
|
updateViewParameters(cam, transform);
|
||||||
|
viewParamsSet = createViewParamsSet();
|
||||||
cullingBuffer->rotateBuffer(VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo), true);
|
cullingBuffer->rotateBuffer(VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,34 +82,11 @@ void LightEnvironment::reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LightEnvironment::addDirectionalLight(const Component::DirectionalLight& dirLight, const Component::Transform& transform) {
|
void LightEnvironment::addDirectionalLight(const Component::DirectionalLight& dirLight, const Component::Transform& transform) {
|
||||||
Vector eyePos = transform.getPosition();
|
|
||||||
Vector lookAt = eyePos + transform.getForward();
|
|
||||||
Matrix4 cameraMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0));
|
|
||||||
Matrix4 correctionMatrix = Matrix4(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1 / 2.f, 0, 0, 0, 1 / 2.f, 1);
|
|
||||||
dirs.add(ShaderDirectionalLight{
|
dirs.add(ShaderDirectionalLight{
|
||||||
.color = Vector4(dirLight.color, dirLight.intensity),
|
.color = Vector4(dirLight.color, dirLight.intensity),
|
||||||
.direction = Vector4(transform.getForward(), 0),
|
.direction = Vector4(transform.getForward(), 0),
|
||||||
.lightSpaceMatrix = correctionMatrix * glm::ortho(-100.0f, 100.0f, -100.0f, 100.0f, 100.0f, -100.0f) * cameraMatrix,
|
|
||||||
});
|
});
|
||||||
directionalTransforms.add(transform);
|
directionalTransforms.add(transform);
|
||||||
if (shadowMaps.size() < dirs.size()) {
|
|
||||||
shadowMaps.add(graphics->createTexture2D(TextureCreateInfo{
|
|
||||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
|
||||||
.width = 8192,
|
|
||||||
.height = 8192,
|
|
||||||
.elements = (uint32)dirs.size(),
|
|
||||||
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
|
||||||
.name = "ShadowMap",
|
|
||||||
}));
|
|
||||||
shadowMaps.back()->changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, Gfx::SE_ACCESS_NONE, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
|
||||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
|
|
||||||
shadowSamplers.add(graphics->createSampler(SamplerCreateInfo{
|
|
||||||
.addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
|
||||||
.addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
|
||||||
.addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
|
||||||
.name = "ShadowSampler",
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightEnvironment::addPointLight(const Component::PointLight& pointLight, const Component::Transform& transform) {
|
void LightEnvironment::addPointLight(const Component::PointLight& pointLight, const Component::Transform& transform) {
|
||||||
@@ -136,8 +113,6 @@ void LightEnvironment::commit() {
|
|||||||
uint32 numDirectionalLights = (uint32)dirs.size();
|
uint32 numDirectionalLights = (uint32)dirs.size();
|
||||||
set->updateConstants("numDirectionalLights", 0, &numDirectionalLights);
|
set->updateConstants("numDirectionalLights", 0, &numDirectionalLights);
|
||||||
set->updateBuffer("directionalLights", 0, directionalLights);
|
set->updateBuffer("directionalLights", 0, directionalLights);
|
||||||
set->updateTexture("shadowMap", 0, shadowMaps[0]->getDefaultView());
|
|
||||||
set->updateSampler("shadowSampler", 0, Gfx::PSampler(shadowSamplers[0]));
|
|
||||||
set->updateConstants("numPointLights", 0, &numPointLights);
|
set->updateConstants("numPointLights", 0, &numPointLights);
|
||||||
set->updateBuffer("pointLights", 0, pointLights);
|
set->updateBuffer("pointLights", 0, pointLights);
|
||||||
set->updateTexture("irradianceMap", 0, environment->getIrradianceMap()->getDefaultView());
|
set->updateTexture("irradianceMap", 0, environment->getIrradianceMap()->getDefaultView());
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "Component/Transform.h"
|
#include "Component/Transform.h"
|
||||||
#include "Graphics/Buffer.h"
|
#include "Graphics/Buffer.h"
|
||||||
#include "Graphics/Descriptor.h"
|
#include "Graphics/Descriptor.h"
|
||||||
#include "Graphics/Texture.h"
|
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
DECLARE_REF(EnvironmentMapAsset)
|
DECLARE_REF(EnvironmentMapAsset)
|
||||||
@@ -13,7 +12,6 @@ class LightEnvironment {
|
|||||||
struct ShaderDirectionalLight {
|
struct ShaderDirectionalLight {
|
||||||
Vector4 color;
|
Vector4 color;
|
||||||
Vector4 direction;
|
Vector4 direction;
|
||||||
Matrix4 lightSpaceMatrix;
|
|
||||||
};
|
};
|
||||||
struct ShaderPointLight {
|
struct ShaderPointLight {
|
||||||
Vector4 position_WS;
|
Vector4 position_WS;
|
||||||
@@ -31,12 +29,10 @@ class LightEnvironment {
|
|||||||
Gfx::PDescriptorSet getDescriptorSet();
|
Gfx::PDescriptorSet getDescriptorSet();
|
||||||
PEnvironmentMapAsset getEnvironmentMap() { return environment; }
|
PEnvironmentMapAsset getEnvironmentMap() { return environment; }
|
||||||
uint64 getNumDirectionalLights() const { return dirs.size(); }
|
uint64 getNumDirectionalLights() const { return dirs.size(); }
|
||||||
const Array<Gfx::OTexture2D>& getShadowMaps() const { return shadowMaps; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
Gfx::OShaderBuffer directionalLights;
|
Gfx::OShaderBuffer directionalLights;
|
||||||
Array<Gfx::OTexture2D> shadowMaps;
|
|
||||||
Array<Gfx::OSampler> shadowSamplers;
|
Array<Gfx::OSampler> shadowSamplers;
|
||||||
Gfx::OShaderBuffer pointLights;
|
Gfx::OShaderBuffer pointLights;
|
||||||
Array<ShaderDirectionalLight> dirs;
|
Array<ShaderDirectionalLight> dirs;
|
||||||
|
|||||||
Reference in New Issue
Block a user