Reverse depth is now working in the shadow pass
This commit is contained in:
@@ -27,7 +27,7 @@ ParameterBlock<LightCullingData> pLightCullingData;
|
|||||||
|
|
||||||
static const float4x4 biasMat = float4x4(
|
static const float4x4 biasMat = float4x4(
|
||||||
0.5, 0.0, 0.0, 0.5,
|
0.5, 0.0, 0.0, 0.5,
|
||||||
0.0, -0.5, 0.0, 0.5,
|
0.0, 0.5, 0.0, 0.5,
|
||||||
0.0, 0.0, 1.0, 0.0,
|
0.0, 0.0, 1.0, 0.0,
|
||||||
0.0, 0.0, 0.0, 1.0);
|
0.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
{
|
{
|
||||||
uint cascadeIndex = 0;
|
uint cascadeIndex = 0;
|
||||||
for (uint c = 0; c < NUM_CASCADES - 1; ++c) {
|
for (uint c = 0; c < NUM_CASCADES - 1; ++c) {
|
||||||
if (params.position_VS.z > pShadowMapping.cascadeSplits[c]) {
|
if (params.position_VS.z < pShadowMapping.cascadeSplits[c]) {
|
||||||
cascadeIndex = c + 1;
|
cascadeIndex = c + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
if (shadowCoord.z > 0.0 && shadowCoord.z < 1.0)
|
if (shadowCoord.z > 0.0 && shadowCoord.z < 1.0)
|
||||||
{
|
{
|
||||||
float dist = pShadowMapping.shadowMaps[cascadeIndex].Sample(pShadowMapping.shadowSampler, float3(shadowCoord.xy + float2(dx * x, dy * y), i)).r;
|
float dist = pShadowMapping.shadowMaps[cascadeIndex].Sample(pShadowMapping.shadowSampler, float3(shadowCoord.xy + float2(dx * x, dy * y), i)).r;
|
||||||
if (shadowCoord.w > 0 && dist > shadowCoord.z)
|
if (shadowCoord.w > 0 && dist < shadowCoord.z)
|
||||||
{
|
{
|
||||||
shadow = 0;
|
shadow = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Graphics/Initializer.h"
|
#include "Graphics/Initializer.h"
|
||||||
#include "Graphics/RenderTarget.h"
|
#include "Graphics/RenderTarget.h"
|
||||||
|
#include "Math/Matrix.h"
|
||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
@@ -20,7 +21,6 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
|
|||||||
.size = {SOURCE_RESOLUTION, SOURCE_RESOLUTION},
|
.size = {SOURCE_RESOLUTION, SOURCE_RESOLUTION},
|
||||||
.offset = {0, 0},
|
.offset = {0, 0},
|
||||||
},
|
},
|
||||||
.fieldOfView = glm::radians(90.0f),
|
|
||||||
});
|
});
|
||||||
convolutionViewport = graphics->createViewport(nullptr, ViewportCreateInfo{
|
convolutionViewport = graphics->createViewport(nullptr, ViewportCreateInfo{
|
||||||
.dimensions =
|
.dimensions =
|
||||||
@@ -28,7 +28,6 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
|
|||||||
.size = {CONVOLUTED_RESOLUTION, CONVOLUTED_RESOLUTION},
|
.size = {CONVOLUTED_RESOLUTION, CONVOLUTED_RESOLUTION},
|
||||||
.offset = {0, 0},
|
.offset = {0, 0},
|
||||||
},
|
},
|
||||||
.fieldOfView = glm::radians(90.0f),
|
|
||||||
});
|
});
|
||||||
for (uint32 i = 0; i < prefilterViewports.size(); ++i) {
|
for (uint32 i = 0; i < prefilterViewports.size(); ++i) {
|
||||||
prefilterViewports[i] = graphics->createViewport(nullptr, ViewportCreateInfo{
|
prefilterViewports[i] = graphics->createViewport(nullptr, ViewportCreateInfo{
|
||||||
@@ -37,7 +36,6 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
|
|||||||
.size = {128 * std::pow(0.5, i), 128 * std::pow(0.5, i)},
|
.size = {128 * std::pow(0.5, i), 128 * std::pow(0.5, i)},
|
||||||
.offset = {0, 0},
|
.offset = {0, 0},
|
||||||
},
|
},
|
||||||
.fieldOfView = glm::radians(90.0f),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
cubeSampler = graphics->createSampler({
|
cubeSampler = graphics->createSampler({
|
||||||
@@ -127,7 +125,6 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
|
|||||||
.size = {512, 512},
|
.size = {512, 512},
|
||||||
.offset = {0, 0},
|
.offset = {0, 0},
|
||||||
},
|
},
|
||||||
.fieldOfView = glm::radians(90.0f),
|
|
||||||
});
|
});
|
||||||
Gfx::ORenderPass lutPass = graphics->createRenderPass(
|
Gfx::ORenderPass lutPass = graphics->createRenderPass(
|
||||||
Gfx::RenderTargetLayout{
|
Gfx::RenderTargetLayout{
|
||||||
@@ -195,7 +192,7 @@ void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset
|
|||||||
.height = (uint32)height,
|
.height = (uint32)height,
|
||||||
.name = "HDRRaw",
|
.name = "HDRRaw",
|
||||||
});
|
});
|
||||||
Matrix4 captureProjection = cubeRenderViewport->getProjectionMatrix(0.1f, 10.0f);
|
Matrix4 captureProjection = perspectiveProjection(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
|
||||||
Matrix4 captureViews[] = {
|
Matrix4 captureViews[] = {
|
||||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)),
|
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)),
|
||||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(-1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)),
|
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(-1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)),
|
||||||
|
|||||||
@@ -2,13 +2,31 @@
|
|||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
#include "Math/Matrix.h"
|
#include "Math/Matrix.h"
|
||||||
#include "Transform.h"
|
#include "Transform.h"
|
||||||
|
#include <glm/trigonometric.hpp>
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
namespace Component {
|
namespace Component {
|
||||||
struct Camera {
|
struct Camera {
|
||||||
|
float fieldOfView = glm::radians(70.0f);
|
||||||
|
float aspectRatio = 16.0f / 9.0f;
|
||||||
float nearPlane = 0.1f;
|
float nearPlane = 0.1f;
|
||||||
float farPlane = 10000.0f;
|
float farPlane = 1000.0f;
|
||||||
bool mainCamera = false;
|
bool mainCamera = false;
|
||||||
|
constexpr Matrix4 getProjectionMatrix() const {
|
||||||
|
if(fieldOfView > 0.0f) {
|
||||||
|
return perspectiveProjection(fieldOfView, aspectRatio, nearPlane, farPlane);
|
||||||
|
} else {
|
||||||
|
float orthoHeight = 10.0f;
|
||||||
|
float orthoWidth = orthoHeight * aspectRatio;
|
||||||
|
return orthographicProjection(-orthoWidth / 2.0f, orthoWidth / 2.0f, -orthoHeight / 2.0f, orthoHeight / 2.0f, nearPlane, farPlane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constexpr Matrix4 getPerspectiveMatrix() const {
|
||||||
|
return perspectiveProjection(fieldOfView, aspectRatio, nearPlane, farPlane);
|
||||||
|
}
|
||||||
|
constexpr Matrix4 getOrthographicMatrix(float left, float right, float bottom, float top) const {
|
||||||
|
return orthographicProjection(left, right, bottom, top, nearPlane, farPlane);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // namespace Component
|
} // namespace Component
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -31,12 +31,6 @@ struct WindowCreateInfo {
|
|||||||
};
|
};
|
||||||
struct ViewportCreateInfo {
|
struct ViewportCreateInfo {
|
||||||
URect dimensions;
|
URect dimensions;
|
||||||
float fieldOfView = glm::radians(70.0f);
|
|
||||||
// ortho params
|
|
||||||
float left = 0;
|
|
||||||
float right = 0;
|
|
||||||
float top = 0;
|
|
||||||
float bottom = 0;
|
|
||||||
};
|
};
|
||||||
// doesnt own the data, only proxy it
|
// doesnt own the data, only proxy it
|
||||||
struct DataSource {
|
struct DataSource {
|
||||||
|
|||||||
@@ -114,7 +114,6 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics)
|
|||||||
.mipLodBias = 0.0f,
|
.mipLodBias = 0.0f,
|
||||||
.maxAnisotropy = 1.0f,
|
.maxAnisotropy = 1.0f,
|
||||||
.minLod = 0.0f,
|
.minLod = 0.0f,
|
||||||
.maxLod = 1.0f,
|
|
||||||
.borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
|
.borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ void RenderPass::updateViewParameters(const Component::Camera& cam, const Compon
|
|||||||
Vector eyePos = transform.getPosition();
|
Vector eyePos = transform.getPosition();
|
||||||
Vector lookAt = eyePos + transform.getForward();
|
Vector lookAt = eyePos + transform.getForward();
|
||||||
Matrix4 cameraMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0));
|
Matrix4 cameraMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0));
|
||||||
Matrix4 projectionMatrix = viewport->getProjectionMatrix(cam.nearPlane, cam.farPlane);
|
Matrix4 projectionMatrix = cam.getProjectionMatrix();
|
||||||
viewParams = {
|
viewParams = {
|
||||||
.viewMatrix = cameraMatrix,
|
.viewMatrix = cameraMatrix,
|
||||||
.inverseViewMatrix = glm::inverse(cameraMatrix),
|
.inverseViewMatrix = glm::inverse(cameraMatrix),
|
||||||
|
|||||||
@@ -50,10 +50,10 @@ void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Tr
|
|||||||
|
|
||||||
float nearClip = camera.nearPlane;
|
float nearClip = camera.nearPlane;
|
||||||
float farClip = camera.farPlane;
|
float farClip = camera.farPlane;
|
||||||
float clipRange = farClip - nearClip;
|
float clipRange = nearClip - farClip;
|
||||||
|
|
||||||
float minZ = nearClip;
|
float minZ = farClip;
|
||||||
float maxZ = nearClip + clipRange;
|
float maxZ = nearClip;
|
||||||
|
|
||||||
float range = maxZ - minZ;
|
float range = maxZ - minZ;
|
||||||
float ratio = maxZ / minZ;
|
float ratio = maxZ / minZ;
|
||||||
@@ -63,23 +63,21 @@ void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Tr
|
|||||||
float log = minZ * std::pow(ratio, p);
|
float log = minZ * std::pow(ratio, p);
|
||||||
float uniform = minZ + range * p;
|
float uniform = minZ + range * p;
|
||||||
float d = cascadeSplitLambda * (log - uniform) + uniform;
|
float d = cascadeSplitLambda * (log - uniform) + uniform;
|
||||||
cascadeSplits[i] = (d - nearClip) / clipRange;
|
cascadeSplits[i] = (d - farClip) / clipRange;
|
||||||
splitDepths[i] = (camera.nearPlane + cascadeSplits[i] * clipRange) * -1.0f;
|
splitDepths[i] = farClip + cascadeSplits[i] * clipRange;
|
||||||
cascades[i].viewParams.clear();
|
cascades[i].viewParams.clear();
|
||||||
}
|
}
|
||||||
cascadeSplitsBuffer->updateContents(0, sizeof(float) * NUM_CASCADES, splitDepths);
|
cascadeSplitsBuffer->updateContents(0, sizeof(float) * NUM_CASCADES, splitDepths);
|
||||||
|
|
||||||
// call this to update view params member, ignore descriptor set
|
|
||||||
updateViewParameters(camera, transform);
|
updateViewParameters(camera, transform);
|
||||||
Matrix4 invCam = viewParams.inverseViewProjectionMatrix;
|
Matrix4 invCam = viewParams.inverseViewProjectionMatrix;
|
||||||
for (uint32 s = 0; s < scene->getLightEnvironment()->getNumDirectionalLights(); ++s) {
|
|
||||||
float lastSplitDist = 0.0;
|
float lastSplitDist = 0.0;
|
||||||
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
||||||
float splitDist = cascadeSplits[i];
|
float splitDist = cascadeSplits[i];
|
||||||
|
|
||||||
Array<Vector> frustumCorners = {
|
Array<Vector> frustumCorners = {
|
||||||
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),
|
|
||||||
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, 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) {
|
for (auto& c : frustumCorners) {
|
||||||
@@ -108,27 +106,31 @@ void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Tr
|
|||||||
Vector maxExtents = Vector(radius);
|
Vector maxExtents = Vector(radius);
|
||||||
Vector minExtents = -maxExtents;
|
Vector minExtents = -maxExtents;
|
||||||
|
|
||||||
|
for (uint32 s = 0; s < scene->getLightEnvironment()->getNumDirectionalLights(); ++s) {
|
||||||
Vector lightDir = glm::normalize(scene->getLightEnvironment()->getDirectionalLight(s).direction);
|
Vector lightDir = glm::normalize(scene->getLightEnvironment()->getDirectionalLight(s).direction);
|
||||||
Vector cameraPos = frustumCenter - lightDir * -minExtents.z;
|
Vector cameraPos = frustumCenter - lightDir * -minExtents.z;
|
||||||
Matrix4 viewMatrix = glm::lookAt(cameraPos, frustumCenter, Vector(0, 1, 0));
|
Matrix4 viewMatrix = glm::lookAt(cameraPos, frustumCenter, Vector(0, 1, 0));
|
||||||
Matrix4 projectionMatrix =
|
Matrix4 projectionMatrix =
|
||||||
orthographicProjection(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f, maxExtents.z - minExtents.z);
|
orthographicProjection(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f, maxExtents.z - minExtents.z);
|
||||||
Matrix4 viewProjectionMatrix = projectionMatrix * viewMatrix;
|
Matrix4 viewProjectionMatrix = projectionMatrix * viewMatrix;
|
||||||
viewParams.viewMatrix = viewMatrix;
|
viewParams = {
|
||||||
viewParams.inverseViewMatrix = glm::inverse(viewMatrix);
|
.viewMatrix = viewMatrix,
|
||||||
viewParams.projectionMatrix = projectionMatrix;
|
.inverseViewMatrix = glm::inverse(viewMatrix),
|
||||||
viewParams.inverseProjection = glm::inverse(projectionMatrix);
|
.projectionMatrix = projectionMatrix,
|
||||||
viewParams.viewProjectionMatrix = viewProjectionMatrix;
|
.inverseProjection = glm::inverse(projectionMatrix),
|
||||||
viewParams.inverseViewProjectionMatrix = glm::inverse(viewProjectionMatrix);
|
.viewProjectionMatrix = viewProjectionMatrix,
|
||||||
viewParams.cameraPosition_WS = Vector4(cameraPos, 1);
|
.inverseViewProjectionMatrix = glm::inverse(viewProjectionMatrix),
|
||||||
viewParams.cameraForward_WS = Vector4(frustumCenter - cameraPos, 0);
|
.cameraPosition_WS = Vector4(cameraPos, 1),
|
||||||
viewParams.screenDimensions = Vector2(maxExtents.x - minExtents.x, maxExtents.y - minExtents.y);
|
.cameraForward_WS = Vector4(frustumCenter - cameraPos, 0),
|
||||||
viewParams.invScreenDimensions = 1.0f / viewParams.screenDimensions;
|
.screenDimensions = Vector2(maxExtents.x - minExtents.x, maxExtents.y - minExtents.y),
|
||||||
|
.invScreenDimensions = 1.0f / Vector2(maxExtents.x - minExtents.x, maxExtents.y - minExtents.y),
|
||||||
|
.frameIndex = Gfx::getCurrentFrameIndex(),
|
||||||
|
.time = (float)Gfx::getCurrentFrameTime(),
|
||||||
|
};
|
||||||
cascades[i].viewParams.add(createViewParamsSet());
|
cascades[i].viewParams.add(createViewParamsSet());
|
||||||
cascades[i].lightSpaceBuffer->updateContents(0, sizeof(Matrix4), &viewProjectionMatrix);
|
cascades[i].lightSpaceBuffer->updateContents(0, sizeof(Matrix4), &viewProjectionMatrix);
|
||||||
|
|
||||||
lastSplitDist = cascadeSplits[i];
|
|
||||||
}
|
}
|
||||||
|
lastSplitDist = cascadeSplits[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +179,7 @@ void ShadowPass::render() {
|
|||||||
Gfx::PermutationId id(permutation);
|
Gfx::PermutationId id(permutation);
|
||||||
|
|
||||||
Gfx::ORenderCommand command = graphics->createRenderCommand("ShadowRender");
|
Gfx::ORenderCommand command = graphics->createRenderCommand("ShadowRender");
|
||||||
command->setViewport(shadowViewport);
|
command->setViewport(cascades[c].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;
|
||||||
@@ -262,19 +264,9 @@ void ShadowPass::publishOutputs() {
|
|||||||
.data = nullptr,
|
.data = nullptr,
|
||||||
},
|
},
|
||||||
.name = "CascadeSplits"});
|
.name = "CascadeSplits"});
|
||||||
shadowViewport = graphics->createViewport(nullptr, ViewportCreateInfo{.dimensions =
|
|
||||||
{
|
|
||||||
.size = {SHADOW_MAP_SIZE, SHADOW_MAP_SIZE},
|
|
||||||
.offset = {0, 0},
|
|
||||||
},
|
|
||||||
.fieldOfView = 0,
|
|
||||||
.left = -100,
|
|
||||||
.right = 100,
|
|
||||||
.top = 100,
|
|
||||||
.bottom = -100});
|
|
||||||
uint32 cascadeDim = SHADOW_MAP_SIZE;
|
uint32 cascadeDim = SHADOW_MAP_SIZE;
|
||||||
for (uint32 s = 0; s < NUM_CASCADES; ++s) {
|
for (uint32 c = 0; c < NUM_CASCADES; ++c) {
|
||||||
cascades[s].shadowMaps = graphics->createTexture2DArray(TextureCreateInfo{
|
cascades[c].shadowMaps = graphics->createTexture2DArray(TextureCreateInfo{
|
||||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||||
.width = cascadeDim,
|
.width = cascadeDim,
|
||||||
.height = cascadeDim,
|
.height = cascadeDim,
|
||||||
@@ -282,19 +274,26 @@ void ShadowPass::publishOutputs() {
|
|||||||
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
.name = "ShadowMapCascade",
|
.name = "ShadowMapCascade",
|
||||||
});
|
});
|
||||||
cascades[s].lightSpaceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.sourceData =
|
cascades[c].lightSpaceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.sourceData =
|
||||||
{
|
{
|
||||||
.size = sizeof(Matrix4),
|
.size = sizeof(Matrix4),
|
||||||
.data = nullptr,
|
.data = nullptr,
|
||||||
},
|
},
|
||||||
.name = "LightSpaceBuffer"});
|
.name = "LightSpaceBuffer"});
|
||||||
cascades[s].views.clear();
|
cascades[c].views.clear();
|
||||||
for (uint32 j = 0; j < cascades[s].shadowMaps->getNumLayers(); ++j) {
|
for (uint32 j = 0; j < cascades[c].shadowMaps->getNumLayers(); ++j) {
|
||||||
cascades[s].views.add(cascades[s].shadowMaps->createTextureView(0, 1, j, 1));
|
cascades[c].views.add(cascades[c].shadowMaps->createTextureView(0, 1, j, 1));
|
||||||
}
|
}
|
||||||
|
cascades[c].shadowViewport = graphics->createViewport(nullptr, ViewportCreateInfo{
|
||||||
|
.dimensions =
|
||||||
|
{
|
||||||
|
.size = {cascadeDim, cascadeDim},
|
||||||
|
.offset = {0, 0},
|
||||||
|
},
|
||||||
|
});
|
||||||
cascadeDim /= 2;
|
cascadeDim /= 2;
|
||||||
resources->registerTextureOutput(fmt::format("SHADOWMAP_TEXTURE{0}", s), Gfx::PTexture2DArray(cascades[s].shadowMaps));
|
resources->registerTextureOutput(fmt::format("SHADOWMAP_TEXTURE{0}", c), Gfx::PTexture2DArray(cascades[c].shadowMaps));
|
||||||
resources->registerBufferOutput(fmt::format("SHADOWMAP_LIGHTSPACE{0}", s), cascades[s].lightSpaceBuffer);
|
resources->registerBufferOutput(fmt::format("SHADOWMAP_LIGHTSPACE{0}", c), cascades[c].lightSpaceBuffer);
|
||||||
}
|
}
|
||||||
cascadeSplitsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{.sourceData =
|
cascadeSplitsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{.sourceData =
|
||||||
{
|
{
|
||||||
@@ -303,7 +302,7 @@ void ShadowPass::publishOutputs() {
|
|||||||
},
|
},
|
||||||
.name = "CASCADE_SPLITS"});
|
.name = "CASCADE_SPLITS"});
|
||||||
resources->registerUniformOutput("SHADOWMAP_CASCADESPLITS", cascadeSplitsBuffer);
|
resources->registerUniformOutput("SHADOWMAP_CASCADESPLITS", cascadeSplitsBuffer);
|
||||||
viewport = shadowViewport;
|
viewport = cascades[0].shadowViewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowPass::createRenderPass() { cullingBuffer = resources->requestBuffer("CULLINGBUFFER"); }
|
void ShadowPass::createRenderPass() { cullingBuffer = resources->requestBuffer("CULLINGBUFFER"); }
|
||||||
|
|||||||
@@ -27,12 +27,12 @@ class ShadowPass : public RenderPass {
|
|||||||
Array<Matrix4> lightSpaceMatrices;
|
Array<Matrix4> lightSpaceMatrices;
|
||||||
Gfx::OShaderBuffer lightSpaceBuffer;
|
Gfx::OShaderBuffer lightSpaceBuffer;
|
||||||
Array<Gfx::ODescriptorSet> viewParams;
|
Array<Gfx::ODescriptorSet> viewParams;
|
||||||
|
Gfx::OViewport shadowViewport;
|
||||||
};
|
};
|
||||||
StaticArray<Cascade, NUM_CASCADES> cascades;
|
StaticArray<Cascade, NUM_CASCADES> cascades;
|
||||||
Gfx::OUniformBuffer cascadeSplitsBuffer;
|
Gfx::OUniformBuffer cascadeSplitsBuffer;
|
||||||
Gfx::OPipelineLayout shadowLayout;
|
Gfx::OPipelineLayout shadowLayout;
|
||||||
Gfx::PShaderBuffer cullingBuffer;
|
Gfx::PShaderBuffer cullingBuffer;
|
||||||
Gfx::OViewport shadowViewport;
|
|
||||||
PScene scene;
|
PScene scene;
|
||||||
};
|
};
|
||||||
DEFINE_REF(ShadowPass)
|
DEFINE_REF(ShadowPass)
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ Window::~Window() {}
|
|||||||
|
|
||||||
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
|
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
|
||||||
: sizeX(viewportInfo.dimensions.size.x), sizeY(viewportInfo.dimensions.size.y), offsetX(viewportInfo.dimensions.offset.x),
|
: sizeX(viewportInfo.dimensions.size.x), sizeY(viewportInfo.dimensions.size.y), offsetX(viewportInfo.dimensions.offset.x),
|
||||||
offsetY(viewportInfo.dimensions.offset.y), fieldOfView(viewportInfo.fieldOfView), orthoLeft(viewportInfo.left),
|
offsetY(viewportInfo.dimensions.offset.y), owner(owner) {
|
||||||
orthoRight(viewportInfo.right), orthoTop(viewportInfo.top), orthoBottom(viewportInfo.bottom), owner(owner) {
|
|
||||||
if (owner != nullptr) {
|
if (owner != nullptr) {
|
||||||
sizeX = std::min(owner->getFramebufferWidth(), sizeX);
|
sizeX = std::min(owner->getFramebufferWidth(), sizeX);
|
||||||
sizeY = std::min(owner->getFramebufferHeight(), sizeY);
|
sizeY = std::min(owner->getFramebufferHeight(), sizeY);
|
||||||
@@ -19,11 +18,3 @@ Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Viewport::~Viewport() {}
|
Viewport::~Viewport() {}
|
||||||
|
|
||||||
Matrix4 Viewport::getProjectionMatrix(float nearPlane, float farPlane) const {
|
|
||||||
if (fieldOfView > 0.0f) {
|
|
||||||
return perspectiveProjection(fieldOfView, static_cast<float>(sizeX) / sizeY, nearPlane, farPlane);
|
|
||||||
} else {
|
|
||||||
return orthographicProjection(orthoLeft, orthoRight, orthoBottom, orthoTop, nearPlane, farPlane);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -52,7 +52,6 @@ class Viewport {
|
|||||||
constexpr uint32 getOffsetY() const { return offsetY; }
|
constexpr uint32 getOffsetY() const { return offsetY; }
|
||||||
constexpr float getContentScaleX() const { return owner->getContentScaleX(); }
|
constexpr float getContentScaleX() const { return owner->getContentScaleX(); }
|
||||||
constexpr float getContentScaleY() const { return owner->getContentScaleY(); }
|
constexpr float getContentScaleY() const { return owner->getContentScaleY(); }
|
||||||
Matrix4 getProjectionMatrix(float nearPlane, float farPlane) const;
|
|
||||||
URect getRenderArea() const {
|
URect getRenderArea() const {
|
||||||
return URect{
|
return URect{
|
||||||
.size = {sizeX, sizeY},
|
.size = {sizeX, sizeY},
|
||||||
@@ -65,11 +64,6 @@ class Viewport {
|
|||||||
uint32 sizeY;
|
uint32 sizeY;
|
||||||
uint32 offsetX;
|
uint32 offsetX;
|
||||||
uint32 offsetY;
|
uint32 offsetY;
|
||||||
float fieldOfView;
|
|
||||||
float orthoLeft;
|
|
||||||
float orthoRight;
|
|
||||||
float orthoTop;
|
|
||||||
float orthoBottom;
|
|
||||||
PWindow owner;
|
PWindow owner;
|
||||||
};
|
};
|
||||||
DEFINE_REF(Viewport)
|
DEFINE_REF(Viewport)
|
||||||
|
|||||||
@@ -1,6 +1,35 @@
|
|||||||
#include "Matrix.h"
|
#include "Matrix.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
Matrix4 Seele::perspectiveProjection(float fov, float aspect, float nearPlane, float farPlane) {
|
||||||
|
const float e = 1.0f / std::tan(fov * 0.5f);
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
e / aspect,
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0.0f,
|
||||||
|
-e,
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
(nearPlane + farPlane) / (nearPlane - farPlane),
|
||||||
|
-1.0f,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
(farPlane * nearPlane) / (nearPlane - farPlane),
|
||||||
|
0.0f,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Matrix4 Seele::orthographicProjection(float left, float right, float bottom, float top, float nearPlane, float farPlane) {
|
Matrix4 Seele::orthographicProjection(float left, float right, float bottom, float top, float nearPlane, float farPlane) {
|
||||||
return Matrix4{
|
return Matrix4{
|
||||||
@@ -12,20 +41,20 @@ Matrix4 Seele::orthographicProjection(float left, float right, float bottom, flo
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
0.0f,
|
0.0f,
|
||||||
2.0f / (top - bottom),
|
-2.0f / (top - bottom),
|
||||||
0.0f,
|
0.0f,
|
||||||
0.0f,
|
0.0f,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0.0f,
|
0.0f,
|
||||||
0.0f,
|
0.0f,
|
||||||
1.0f / (farPlane - nearPlane),
|
1.0f / (nearPlane - farPlane),
|
||||||
0.0f,
|
0.0f,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
-(right + left) / (right - left),
|
-(right + left) / (right - left),
|
||||||
-(top + bottom) / (top - bottom),
|
-(top + bottom) / (top - bottom),
|
||||||
farPlane / (farPlane - nearPlane),
|
nearPlane / (nearPlane - farPlane),
|
||||||
1.0f,
|
1.0f,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,34 +8,6 @@ typedef glm::mat2 Matrix2;
|
|||||||
typedef glm::mat3 Matrix3;
|
typedef glm::mat3 Matrix3;
|
||||||
typedef glm::mat4 Matrix4;
|
typedef glm::mat4 Matrix4;
|
||||||
|
|
||||||
static Matrix4 perspectiveProjection(float fov, float aspect, float nearPlane, float farPlane) {
|
Matrix4 perspectiveProjection(float fov, float aspect, float nearPlane, float farPlane);
|
||||||
const float e = 1.0f / std::tan(fov * 0.5f);
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
e / aspect,
|
|
||||||
0.0f,
|
|
||||||
0.0f,
|
|
||||||
0.0f,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0.0f,
|
|
||||||
-e,
|
|
||||||
0.0f,
|
|
||||||
0.0f,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0.0f,
|
|
||||||
0.0f,
|
|
||||||
(nearPlane + farPlane) / (nearPlane - farPlane),
|
|
||||||
-1.0f,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0.0f,
|
|
||||||
0.0f,
|
|
||||||
(farPlane * nearPlane) / (nearPlane - farPlane),
|
|
||||||
0.0f,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Matrix4 orthographicProjection(float left, float right, float bottom, float top, float nearPlane, float farPlane);
|
Matrix4 orthographicProjection(float left, float right, float bottom, float top, float nearPlane, float farPlane);
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
Reference in New Issue
Block a user