Basic shadow mapping rendering
This commit is contained in:
@@ -26,7 +26,7 @@ void taskMain(
|
||||
uint cull = p.cullingOffset + i;
|
||||
MeshletDescription meshlet = pScene.meshletInfos[m];
|
||||
MeshletCullingInfo culling = pScene.cullingInfos[cull];
|
||||
if(culling.wasVisible())
|
||||
//if(culling.wasVisible())
|
||||
{
|
||||
uint index;
|
||||
InterlockedAdd(head, 1, index);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"slang.predefinedMacros": [
|
||||
],
|
||||
"slang.additionalSearchPaths": [
|
||||
"res/shaders/lib",
|
||||
"c:\\Program Files\\Seele\\res\\shaders\\lib"
|
||||
]
|
||||
}
|
||||
@@ -129,18 +129,22 @@ void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset
|
||||
});
|
||||
Gfx::ORenderPass cubeRenderPass = graphics->createRenderPass(
|
||||
Gfx::RenderTargetLayout{
|
||||
.colorAttachments = {Gfx::RenderTargetAttachment(cubeMap, Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE)},
|
||||
.colorAttachments =
|
||||
{
|
||||
Gfx::RenderTargetAttachment(cubeMap, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE),
|
||||
},
|
||||
{Gfx::SubPassDependency{
|
||||
},
|
||||
{
|
||||
Gfx::SubPassDependency{
|
||||
.srcSubpass = 0,
|
||||
.dstSubpass = ~0U,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
.size = {SOURCE_RESOLUTION, SOURCE_RESOLUTION},
|
||||
.offset = {0, 0},
|
||||
|
||||
@@ -155,7 +155,6 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array<PTextureAsset>&
|
||||
if (material->GetTexture(type, index, &texPath, &mapping, &uvIndex, &blend, &op, &mapMode) != AI_SUCCESS) {
|
||||
std::cout << "fuck" << std::endl;
|
||||
}
|
||||
uvIndex = 1;
|
||||
std::string textureKey = fmt::format("{0}Texture{1}", paramKey, index);
|
||||
auto texFilename = std::filesystem::path(texPath.C_Str());
|
||||
PTextureAsset texture;
|
||||
|
||||
@@ -5,7 +5,7 @@ using namespace Seele;
|
||||
DirectionalLightActor::DirectionalLightActor(PScene scene) : Actor(scene) { attachComponent<Component::DirectionalLight>(); }
|
||||
|
||||
DirectionalLightActor::DirectionalLightActor(PScene scene, Vector color, float intensity, Vector direction) : Actor(scene) {
|
||||
attachComponent<Component::DirectionalLight>(Vector4(color, intensity), Vector4(direction, 0));
|
||||
attachComponent<Component::DirectionalLight>(Vector4(color, intensity), Vector4(glm::normalize(direction), 0));
|
||||
}
|
||||
|
||||
DirectionalLightActor::~DirectionalLightActor() {}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
namespace Seele {
|
||||
namespace Component {
|
||||
struct Camera {
|
||||
Matrix4 viewMatrix;
|
||||
float nearPlane = 0.001f;
|
||||
float farPlane = 10000.0f;
|
||||
bool mainCamera = false;
|
||||
};
|
||||
} // namespace Component
|
||||
|
||||
@@ -35,6 +35,11 @@ struct WindowCreateInfo {
|
||||
struct ViewportCreateInfo {
|
||||
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
|
||||
struct DataSource {
|
||||
|
||||
@@ -89,7 +89,7 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics)
|
||||
BasePass::~BasePass() {}
|
||||
|
||||
void BasePass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||
RenderPass::beginFrame(cam, transform);
|
||||
viewParamsSet = createViewParamsSet(cam, transform);
|
||||
|
||||
cameraPos = transform.getPosition();
|
||||
cameraForward = transform.getForward();
|
||||
@@ -136,6 +136,7 @@ void BasePass::beginFrame(const Component::Camera& cam, const Component::Transfo
|
||||
}
|
||||
|
||||
void BasePass::render() {
|
||||
graphics->beginDebugRegion("BasePass");
|
||||
opaqueCulling->updateBuffer(LIGHTINDEX_NAME, 0, oLightIndexList);
|
||||
opaqueCulling->updateTexture(LIGHTGRID_NAME, 0, oLightGrid);
|
||||
transparentCulling->updateBuffer(LIGHTINDEX_NAME, 0, tLightIndexList);
|
||||
@@ -151,6 +152,8 @@ void BasePass::render() {
|
||||
permutation.setDepthCulling(true); // always use the culling info
|
||||
permutation.setPositionOnly(false);
|
||||
Array<VertexData::TransparentDraw> transparentData;
|
||||
{
|
||||
graphics->beginDebugRegion("Opaque");
|
||||
// Base Rendering
|
||||
for (VertexData* vertexData : VertexData::getList()) {
|
||||
transparentData.addAll(vertexData->getTransparentData());
|
||||
@@ -211,7 +214,7 @@ void BasePass::render() {
|
||||
},
|
||||
.rasterizationState =
|
||||
{
|
||||
.cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT),
|
||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
@@ -240,21 +243,27 @@ void BasePass::render() {
|
||||
commands.add(std::move(command));
|
||||
}
|
||||
}
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
|
||||
|
||||
//commands.add(waterRenderer->render(viewParamsSet));
|
||||
//commands.add(terrainRenderer->render(viewParamsSet));
|
||||
|
||||
// Skybox
|
||||
{
|
||||
graphics->beginDebugRegion("Skybox");
|
||||
Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender");
|
||||
skyboxCommand->setViewport(viewport);
|
||||
skyboxCommand->bindPipeline(skyboxPipeline);
|
||||
skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
||||
skyboxCommand->draw(36, 1, 0, 0);
|
||||
graphics->executeCommands(std::move(skyboxCommand));
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
// Transparent rendering
|
||||
{
|
||||
graphics->beginDebugRegion("Transparent");
|
||||
permutation.setDepthCulling(false); // ignore visibility infos for transparency
|
||||
Map<float, VertexData::TransparentDraw> sortedDraws;
|
||||
for (const auto& t : transparentData) {
|
||||
@@ -352,9 +361,11 @@ void BasePass::render() {
|
||||
}
|
||||
}
|
||||
commands.add(std::move(transparentCommand));
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
// Debug vertices
|
||||
if (gDebugVertices.size() > 0) {
|
||||
graphics->beginDebugRegion("Debug");
|
||||
Gfx::ORenderCommand debugCommand = graphics->createRenderCommand("DebugRender");
|
||||
debugCommand->setViewport(viewport);
|
||||
debugCommand->bindPipeline(debugPipeline);
|
||||
@@ -362,6 +373,7 @@ void BasePass::render() {
|
||||
debugCommand->bindVertexBuffer({debugVertices});
|
||||
debugCommand->draw((uint32)gDebugVertices.size(), 1, 0, 0);
|
||||
commands.add(std::move(debugCommand));
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
|
||||
graphics->executeCommands(std::move(commands));
|
||||
@@ -369,6 +381,7 @@ void BasePass::render() {
|
||||
query->endQuery();
|
||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "BaseEnd");
|
||||
gDebugVertices.clear();
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
|
||||
void BasePass::endFrame() {}
|
||||
|
||||
@@ -44,6 +44,7 @@ class BasePass : public RenderPass {
|
||||
// used for transparency sorting
|
||||
Vector cameraPos;
|
||||
Vector cameraForward;
|
||||
Gfx::PDescriptorSet viewParamsSet;
|
||||
|
||||
PCameraActor source;
|
||||
Gfx::OPipelineLayout basePassLayout;
|
||||
|
||||
@@ -15,6 +15,8 @@ target_sources(Engine
|
||||
RenderGraphResources.cpp
|
||||
RenderPass.h
|
||||
RenderPass.cpp
|
||||
ShadowPass.h
|
||||
ShadowPass.cpp
|
||||
#TerrainRenderer.h
|
||||
#TerrainRenderer.cpp
|
||||
ToneMappingPass.h
|
||||
@@ -38,6 +40,7 @@ target_sources(Engine
|
||||
RenderGraph.h
|
||||
RenderGraphResources.h
|
||||
RenderPass.h
|
||||
ShadowPass.h
|
||||
#TerrainRenderer.h
|
||||
UIPass.h
|
||||
VisibilityPass.h)
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "CachedDepthPass.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "Graphics/Pipeline.h"
|
||||
#include "Graphics/Shader.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -41,9 +41,12 @@ CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) : Render
|
||||
|
||||
CachedDepthPass::~CachedDepthPass() {}
|
||||
|
||||
void CachedDepthPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) { RenderPass::beginFrame(cam, transform); }
|
||||
void CachedDepthPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||
viewParamsSet = createViewParamsSet(cam, transform);
|
||||
}
|
||||
|
||||
void CachedDepthPass::render() {
|
||||
graphics->beginDebugRegion("CachedDepth");
|
||||
query->beginQuery();
|
||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "CachedBegin");
|
||||
graphics->beginRenderPass(renderPass);
|
||||
@@ -78,7 +81,7 @@ void CachedDepthPass::render() {
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.rasterizationState =
|
||||
{
|
||||
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
@@ -95,7 +98,7 @@ void CachedDepthPass::render() {
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.rasterizationState =
|
||||
{
|
||||
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
@@ -137,6 +140,7 @@ void CachedDepthPass::render() {
|
||||
graphics->endRenderPass();
|
||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CachedEnd");
|
||||
query->endQuery();
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
|
||||
void CachedDepthPass::endFrame() {}
|
||||
|
||||
@@ -24,6 +24,7 @@ class CachedDepthPass : public RenderPass {
|
||||
Gfx::OPipelineStatisticsQuery query;
|
||||
Gfx::OTimestampQuery timestamps;
|
||||
|
||||
Gfx::PDescriptorSet viewParamsSet;
|
||||
Gfx::PShaderBuffer cullingBuffer;
|
||||
PScene scene;
|
||||
};
|
||||
|
||||
@@ -65,9 +65,14 @@ DepthCullingPass::DepthCullingPass(Gfx::PGraphics graphics, PScene scene) : Rend
|
||||
|
||||
DepthCullingPass::~DepthCullingPass() {}
|
||||
|
||||
void DepthCullingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) { RenderPass::beginFrame(cam, transform); }
|
||||
void DepthCullingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||
viewParamsSet = createViewParamsSet(cam, transform);
|
||||
}
|
||||
|
||||
void DepthCullingPass::render() {
|
||||
graphics->beginDebugRegion("DepthCullingPass");
|
||||
{
|
||||
graphics->beginDebugRegion("MipGeneration");
|
||||
query->beginQuery();
|
||||
depthAttachment.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
@@ -85,11 +90,10 @@ void DepthCullingPass::render() {
|
||||
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("MipGen");
|
||||
computeCommand->bindPipeline(depthSourceCopy);
|
||||
computeCommand->bindDescriptor({viewParamsSet, set});
|
||||
computeCommand->dispatch((viewport->getWidth() + BLOCK_SIZE - 1) / BLOCK_SIZE, (viewport->getHeight() + BLOCK_SIZE - 1) / BLOCK_SIZE,
|
||||
1);
|
||||
computeCommand->dispatch((viewport->getWidth() + BLOCK_SIZE - 1) / BLOCK_SIZE,
|
||||
(viewport->getHeight() + BLOCK_SIZE - 1) / BLOCK_SIZE, 1);
|
||||
graphics->executeCommands(std::move(computeCommand));
|
||||
for (uint32 i = 0; i < mipOffsets.size() - 1; ++i)
|
||||
{
|
||||
for (uint32 i = 0; i < mipOffsets.size() - 1; ++i) {
|
||||
depthMipBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
@@ -117,9 +121,16 @@ void DepthCullingPass::render() {
|
||||
Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
|
||||
|
||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "CullingBegin");
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
{
|
||||
graphics->beginDebugRegion("DepthCulling");
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
|
||||
Gfx::PDescriptorSet set = depthAttachmentLayout->allocateDescriptorSet();
|
||||
set->updateTexture(DEPTHTEXTURE_NAME, 0, depthAttachment.getTexture());
|
||||
set->updateBuffer(DEPTHMIP_NAME, 0, depthMipBuffer);
|
||||
set->writeChanges();
|
||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("DepthPass");
|
||||
permutation.setPositionOnly(true);
|
||||
permutation.setDepthCulling(getGlobals().useDepthCulling);
|
||||
@@ -146,7 +157,7 @@ void DepthCullingPass::render() {
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.rasterizationState =
|
||||
{
|
||||
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
@@ -163,7 +174,7 @@ void DepthCullingPass::render() {
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.rasterizationState =
|
||||
{
|
||||
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
@@ -180,8 +191,8 @@ void DepthCullingPass::render() {
|
||||
.samplerOffset = 0,
|
||||
.floatOffset = 0,
|
||||
};
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets),
|
||||
&offsets);
|
||||
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 {
|
||||
@@ -214,8 +225,11 @@ void DepthCullingPass::render() {
|
||||
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
// Sync visibility write with compute read
|
||||
visibilityAttachment.getTexture()->pipelineBarrier(Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
|
||||
void DepthCullingPass::endFrame() {}
|
||||
|
||||
@@ -44,6 +44,7 @@ class DepthCullingPass : public RenderPass {
|
||||
Gfx::PComputePipeline depthSourceCopy;
|
||||
Gfx::OComputeShader depthReduceLevelShader;
|
||||
Gfx::PComputePipeline depthReduceLevel;
|
||||
Gfx::PDescriptorSet viewParamsSet;
|
||||
|
||||
Gfx::PShaderBuffer cullingBuffer;
|
||||
PScene scene;
|
||||
|
||||
@@ -15,7 +15,7 @@ LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene) : Rend
|
||||
LightCullingPass::~LightCullingPass() {}
|
||||
|
||||
void LightCullingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||
RenderPass::beginFrame(cam, transform);
|
||||
viewParamsSet = createViewParamsSet(cam, transform);
|
||||
|
||||
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,
|
||||
@@ -38,6 +38,7 @@ void LightCullingPass::beginFrame(const Component::Camera& cam, const Component:
|
||||
}
|
||||
|
||||
void LightCullingPass::render() {
|
||||
graphics->beginDebugRegion("LightCulling");
|
||||
query->beginQuery();
|
||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "LightCullBegin");
|
||||
oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
@@ -74,6 +75,7 @@ void LightCullingPass::render() {
|
||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
tLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
|
||||
void LightCullingPass::endFrame() {}
|
||||
@@ -223,13 +225,14 @@ void LightCullingPass::createRenderPass() {
|
||||
}
|
||||
|
||||
void LightCullingPass::setupFrustums() {
|
||||
graphics->beginDebugRegion("SetupFrustums");
|
||||
uint32_t viewportWidth = viewport->getWidth();
|
||||
uint32_t viewportHeight = viewport->getHeight();
|
||||
|
||||
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));
|
||||
|
||||
RenderPass::beginFrame(Component::Camera(), Component::Transform());
|
||||
viewParamsSet = createViewParamsSet(Component::Camera(), Component::Transform());
|
||||
|
||||
dispatchParamsLayout = graphics->createDescriptorLayout("pDispatchParams");
|
||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
@@ -294,4 +297,5 @@ void LightCullingPass::setupFrustums() {
|
||||
graphics->executeCommands(std::move(commands));
|
||||
frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ class LightCullingPass : public RenderPass {
|
||||
Gfx::OComputeShader frustumShader;
|
||||
Gfx::PComputePipeline frustumPipeline;
|
||||
Gfx::OPipelineLayout frustumLayout;
|
||||
Gfx::PDescriptorSet viewParamsSet;
|
||||
|
||||
PLightEnvironment lightEnv;
|
||||
Gfx::PTexture2D depthAttachment;
|
||||
|
||||
@@ -67,7 +67,7 @@ RayTracingPass::RayTracingPass(Gfx::PGraphics graphics, PScene scene) : RenderPa
|
||||
static uint32 pass = 0;
|
||||
static Component::Transform lastCam;
|
||||
void RayTracingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||
RenderPass::beginFrame(cam, transform);
|
||||
viewParamsSet = createViewParamsSet(cam, transform);
|
||||
if (lastCam.getPosition() != transform.getPosition() || lastCam.getForward() != transform.getForward()) {
|
||||
lastCam = transform;
|
||||
pass = 0;
|
||||
@@ -75,6 +75,7 @@ void RayTracingPass::beginFrame(const Component::Camera& cam, const Component::T
|
||||
}
|
||||
|
||||
void RayTracingPass::render() {
|
||||
graphics->beginDebugRegion("RayTracingPass");
|
||||
texture->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
Array<Gfx::RayTracingHitGroup> callableGroups;
|
||||
@@ -185,6 +186,7 @@ void RayTracingPass::render() {
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
commands.add(std::move(command));
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
|
||||
void RayTracingPass::endFrame() {}
|
||||
|
||||
@@ -32,6 +32,7 @@ class RayTracingPass : public RenderPass {
|
||||
Gfx::OAnyHitShader anyhit;
|
||||
Gfx::OMissShader miss;
|
||||
Gfx::PRayTracingPipeline pipeline;
|
||||
Gfx::PDescriptorSet viewParamsSet;
|
||||
PScene scene;
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -23,10 +23,17 @@ RenderPass::RenderPass(Gfx::PGraphics graphics) : graphics(graphics) {
|
||||
|
||||
RenderPass::~RenderPass() {}
|
||||
|
||||
void RenderPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||
void RenderPass::setResources(PRenderGraphResources _resources) { resources = _resources; }
|
||||
|
||||
void RenderPass::setViewport(Gfx::PViewport _viewport) { viewport = _viewport; }
|
||||
|
||||
Gfx::PDescriptorSet RenderPass::createViewParamsSet(const Component::Camera& cam, const Component::Transform& transform)
|
||||
{
|
||||
auto screenDim = Vector2(static_cast<float>(viewport->getWidth()), static_cast<float>(viewport->getHeight()));
|
||||
Matrix4 cameraMatrix = cam.viewMatrix;
|
||||
Matrix4 projectionMatrix = viewport->getProjectionMatrix();
|
||||
Vector eyePos = transform.getPosition();
|
||||
Vector lookAt = eyePos + transform.getForward();
|
||||
Matrix4 cameraMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0));
|
||||
Matrix4 projectionMatrix = viewport->getProjectionMatrix(cam.nearPlane, cam.farPlane);
|
||||
viewParams = {
|
||||
.viewMatrix = cameraMatrix,
|
||||
.inverseViewMatrix = glm::inverse(cameraMatrix),
|
||||
@@ -60,10 +67,10 @@ void RenderPass::beginFrame(const Component::Camera& cam, const Component::Trans
|
||||
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);
|
||||
|
||||
viewParamsLayout->reset();
|
||||
viewParamsSet = viewParamsLayout->allocateDescriptorSet();
|
||||
Gfx::PDescriptorSet viewParamsSet = viewParamsLayout->allocateDescriptorSet();
|
||||
viewParamsSet->updateConstants("viewMatrix", 0, &viewParams.viewMatrix);
|
||||
viewParamsSet->updateConstants("inverseViewMatrix", 0, &viewParams.inverseViewMatrix);
|
||||
viewParamsSet->updateConstants("projectionMatrix", 0, &viewParams.projectionMatrix);
|
||||
@@ -79,12 +86,9 @@ void RenderPass::beginFrame(const Component::Camera& cam, const Component::Trans
|
||||
viewParamsSet->updateConstants("pad0", 0, &viewParams.pad0);
|
||||
viewParamsSet->updateConstants("pad1", 0, &viewParams.pad1);
|
||||
viewParamsSet->writeChanges();
|
||||
return viewParamsSet;
|
||||
}
|
||||
|
||||
void RenderPass::setResources(PRenderGraphResources _resources) { resources = _resources; }
|
||||
|
||||
void RenderPass::setViewport(Gfx::PViewport _viewport) { viewport = _viewport; }
|
||||
|
||||
void RenderPass::normalize_plane(Plane& plane) {
|
||||
float l = sqrtf(plane.n.x * plane.n.x + plane.n.y * plane.n.y + plane.n.z * plane.n.z);
|
||||
plane.n.x /= l;
|
||||
|
||||
@@ -18,7 +18,7 @@ class RenderPass {
|
||||
RenderPass(RenderPass&&) = default;
|
||||
RenderPass& operator=(RenderPass&&) = default;
|
||||
virtual ~RenderPass();
|
||||
virtual void beginFrame(const Component::Camera& cam, const Component::Transform& transform);
|
||||
virtual void beginFrame(const Component::Camera& cam, const Component::Transform& transform) = 0;
|
||||
virtual void render() = 0;
|
||||
virtual void endFrame() = 0;
|
||||
virtual void publishOutputs() = 0;
|
||||
@@ -27,6 +27,7 @@ class RenderPass {
|
||||
void setViewport(Gfx::PViewport _viewport);
|
||||
|
||||
protected:
|
||||
Gfx::PDescriptorSet createViewParamsSet(const Component::Camera& cam, const Component::Transform& transform);
|
||||
struct Plane {
|
||||
Vector n;
|
||||
float d;
|
||||
@@ -67,7 +68,6 @@ class RenderPass {
|
||||
} viewParams;
|
||||
PRenderGraphResources resources;
|
||||
Gfx::ODescriptorLayout viewParamsLayout;
|
||||
Gfx::PDescriptorSet viewParamsSet;
|
||||
Gfx::ORenderPass renderPass;
|
||||
Gfx::PGraphics graphics;
|
||||
Gfx::PViewport viewport;
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
#include "ShadowPass.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Shader.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
ShadowPass::ShadowPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) {
|
||||
shadowLayout = graphics->createPipelineLayout("ShadowLayout");
|
||||
shadowLayout->addDescriptorLayout(viewParamsLayout);
|
||||
shadowLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT,
|
||||
.offset = 0,
|
||||
.size = sizeof(VertexData::DrawCallOffsets),
|
||||
});
|
||||
if (graphics->supportMeshShading()) {
|
||||
graphics->getShaderCompiler()->registerRenderPass("ShadowPass", Gfx::PassConfig{
|
||||
.baseLayout = shadowLayout,
|
||||
.taskFile = "DrawListTask",
|
||||
.mainFile = "DrawListMesh",
|
||||
.hasFragmentShader = false,
|
||||
.useMeshShading = true,
|
||||
.hasTaskShader = true,
|
||||
.useMaterial = false,
|
||||
.useVisibility = false,
|
||||
});
|
||||
} else {
|
||||
graphics->getShaderCompiler()->registerRenderPass("ShadowPass", Gfx::PassConfig{
|
||||
.baseLayout = shadowLayout,
|
||||
.taskFile = "",
|
||||
.mainFile = "LegacyPass",
|
||||
.hasFragmentShader = false,
|
||||
.useMeshShading = false,
|
||||
.hasTaskShader = false,
|
||||
.useMaterial = false,
|
||||
.useVisibility = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ShadowPass::~ShadowPass() {}
|
||||
|
||||
void ShadowPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {}
|
||||
|
||||
void ShadowPass::render() {
|
||||
graphics->beginDebugRegion("ShadowPass");
|
||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("ShadowPass");
|
||||
permutation.setDepthCulling(true);
|
||||
permutation.setPositionOnly(true);
|
||||
const auto& shadowMaps = scene->getLightEnvironment()->getShadowMaps();
|
||||
for (uint32 shadowIndex = 0; shadowIndex < scene->getLightEnvironment()->getNumDirectionalLights(); ++shadowIndex) {
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
renderPass = graphics->createRenderPass(
|
||||
Gfx::RenderTargetLayout{
|
||||
.depthAttachment = Gfx::RenderTargetAttachment(shadowMaps[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,
|
||||
.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 = {shadowMaps[shadowIndex]->getWidth(), shadowMaps[shadowIndex]->getHeight()},
|
||||
.offset = {0, 0},
|
||||
},
|
||||
"Shadow");
|
||||
graphics->beginRenderPass(renderPass);
|
||||
auto light = scene->getLightEnvironment()->getDirectionalLight(shadowIndex);
|
||||
Vector lightDirection = Vector(light.direction);
|
||||
Vector lightPosition = -light.direction * 100.0f;
|
||||
float dot = glm::dot(lightDirection, Math::Transform::FORWARD);
|
||||
Quaternion rotation = Quaternion(1, 0, 0, 0);
|
||||
// Handle the edge cases first
|
||||
if (glm::epsilonEqual(dot, 1.0f, 0.00001f)) {
|
||||
// Vectors are the same, no rotation
|
||||
} else if (glm::epsilonEqual(dot, -1.0f, 0.00001f)) {
|
||||
// Vectors are opposite need 180-degree rotation around any perpendicular axis
|
||||
rotation = glm::angleAxis(glm::pi<float>(), Vector(0, 1, 0));
|
||||
} else {
|
||||
// Normal case
|
||||
Vector axis = glm::normalize(glm::cross(lightDirection, Math::Transform::FORWARD));
|
||||
float angle = std::acos(dot); // angle between vectors
|
||||
rotation = glm::angleAxis(angle, axis);
|
||||
}
|
||||
Component::Transform lightTransform = Component::Transform{
|
||||
.transform = Math::Transform(lightPosition, rotation),
|
||||
};
|
||||
|
||||
Component::Camera lightCamera = Component::Camera{
|
||||
.nearPlane = -1000.f,
|
||||
.farPlane = 1000.0f,
|
||||
};
|
||||
Gfx::PDescriptorSet viewParamsSet = createViewParamsSet(lightCamera, lightTransform);
|
||||
for (VertexData* vertexData : VertexData::getList()) {
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
Gfx::PermutationId id(permutation);
|
||||
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("ShadowRender");
|
||||
command->setViewport(shadowViewport);
|
||||
|
||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
if (graphics->supportMeshShading()) {
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = collection->taskShader,
|
||||
.meshShader = collection->meshShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.rasterizationState =
|
||||
{
|
||||
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
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_NONE,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
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));
|
||||
}
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
}
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
|
||||
void ShadowPass::endFrame() {}
|
||||
|
||||
void ShadowPass::publishOutputs() {
|
||||
shadowViewport = graphics->createViewport(nullptr, ViewportCreateInfo{.dimensions =
|
||||
{
|
||||
.size = {2048, 2048},
|
||||
.offset = {0, 0},
|
||||
},
|
||||
.fieldOfView = 0,
|
||||
.left = -10,
|
||||
.right = 10,
|
||||
.top = -10,
|
||||
.bottom = 10});
|
||||
viewport = shadowViewport;
|
||||
}
|
||||
|
||||
void ShadowPass::createRenderPass() { cullingBuffer = resources->requestBuffer("CULLINGBUFFER"); }
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
|
||||
namespace Seele {
|
||||
class ShadowPass : public RenderPass {
|
||||
public:
|
||||
ShadowPass(Gfx::PGraphics graphics, PScene scene);
|
||||
ShadowPass(ShadowPass&& other) = default;
|
||||
ShadowPass& operator=(ShadowPass&& other) = default;
|
||||
virtual ~ShadowPass();
|
||||
virtual void beginFrame(const Component::Camera& cam, const Component::Transform& transform) override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
AABB cameraFrustumBox;
|
||||
Gfx::OPipelineLayout shadowLayout;
|
||||
Gfx::PShaderBuffer cullingBuffer;
|
||||
Gfx::OViewport shadowViewport;
|
||||
PScene scene;
|
||||
};
|
||||
DEFINE_REF(ShadowPass)
|
||||
} // namespace Seele
|
||||
@@ -123,9 +123,12 @@ ToneMappingPass::ToneMappingPass(Gfx::PGraphics graphics) : RenderPass(graphics)
|
||||
|
||||
ToneMappingPass::~ToneMappingPass() {}
|
||||
|
||||
void ToneMappingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) { RenderPass::beginFrame(cam, transform); }
|
||||
void ToneMappingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||
viewParamsSet = createViewParamsSet(cam, transform);
|
||||
}
|
||||
|
||||
void ToneMappingPass::render() {
|
||||
graphics->beginDebugRegion("ToneMapping");
|
||||
hdrInputTexture.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
@@ -181,6 +184,7 @@ void ToneMappingPass::render() {
|
||||
command->draw(3, 1, 0, 0);
|
||||
graphics->executeCommands(std::move(command));
|
||||
graphics->endRenderPass();
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
|
||||
void ToneMappingPass::endFrame() {}
|
||||
|
||||
@@ -47,5 +47,7 @@ class ToneMappingPass : public RenderPass {
|
||||
Gfx::OVertexShader vert;
|
||||
Gfx::OFragmentShader frag;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
|
||||
Gfx::PDescriptorSet viewParamsSet;
|
||||
};
|
||||
}
|
||||
@@ -54,7 +54,7 @@ UIPass::UIPass(Gfx::PGraphics graphics, UI::PSystem system) : RenderPass(graphic
|
||||
UIPass::~UIPass() {}
|
||||
|
||||
void UIPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||
RenderPass::beginFrame(cam, transform);
|
||||
viewParamsSet = createViewParamsSet(cam, transform);
|
||||
glyphs.clear();
|
||||
usedTextures.clear();
|
||||
elements.clear();
|
||||
|
||||
@@ -62,6 +62,8 @@ class UIPass : public RenderPass {
|
||||
Gfx::ODescriptorLayout uiDescriptorLayout;
|
||||
Gfx::PDescriptorSet uiDescriptorSet;
|
||||
|
||||
Gfx::PDescriptorSet viewParamsSet;
|
||||
|
||||
Gfx::OVertexShader uiVertexShader;
|
||||
Gfx::OFragmentShader uiFragmentShader;
|
||||
Gfx::OPipelineLayout uiPipelineLayout;
|
||||
|
||||
@@ -8,11 +8,12 @@ VisibilityPass::VisibilityPass(Gfx::PGraphics graphics) : RenderPass(graphics) {
|
||||
VisibilityPass::~VisibilityPass() {}
|
||||
|
||||
void VisibilityPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||
RenderPass::beginFrame(cam, transform);
|
||||
viewParamsSet = createViewParamsSet(cam, transform);
|
||||
cullingBuffer->rotateBuffer(VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo), true);
|
||||
}
|
||||
|
||||
void VisibilityPass::render() {
|
||||
graphics->beginDebugRegion("VisibilityPass");
|
||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
|
||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
cullingBuffer->clear();
|
||||
@@ -40,6 +41,7 @@ void VisibilityPass::render() {
|
||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT);
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
|
||||
void VisibilityPass::endFrame() {}
|
||||
|
||||
@@ -26,6 +26,7 @@ class VisibilityPass : public RenderPass {
|
||||
Gfx::PComputePipeline visibilityPipeline;
|
||||
Gfx::OPipelineStatisticsQuery query;
|
||||
Gfx::PTimestampQuery timestamps;
|
||||
Gfx::PDescriptorSet viewParamsSet;
|
||||
|
||||
constexpr static const char* VISIBILITY_NAME = "visibilityTexture";
|
||||
// Holds culling information for every meshlet for each instance
|
||||
|
||||
@@ -6,19 +6,20 @@ using namespace Seele::Gfx;
|
||||
RenderTargetAttachment::RenderTargetAttachment(PTexture2D texture, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
||||
SeAttachmentStoreOp stencilStoreOp)
|
||||
: clear(), componentFlags(0), texture(texture), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp),
|
||||
: componentFlags(0), texture(texture), initialLayout(initialLayout), finalLayout(finalLayout),
|
||||
loadOp(loadOp),
|
||||
storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {}
|
||||
|
||||
RenderTargetAttachment::RenderTargetAttachment(PTextureCube texture, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
||||
SeAttachmentStoreOp stencilStoreOp)
|
||||
: clear(), componentFlags(0), texture(texture), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp),
|
||||
: componentFlags(0), texture(texture), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp),
|
||||
storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {}
|
||||
|
||||
RenderTargetAttachment::RenderTargetAttachment(PViewport viewport, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
||||
SeAttachmentStoreOp stencilStoreOp)
|
||||
: clear(), componentFlags(0), viewport(viewport), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp),
|
||||
: componentFlags(0), viewport(viewport), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp),
|
||||
storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {}
|
||||
|
||||
RenderTargetAttachment::~RenderTargetAttachment() {}
|
||||
|
||||
@@ -12,7 +12,6 @@ class Texture : public QueueOwnedResource {
|
||||
virtual uint32 getWidth() const = 0;
|
||||
virtual uint32 getHeight() const = 0;
|
||||
virtual uint32 getDepth() const = 0;
|
||||
virtual uint32 getNumFaces() const { return 1; }
|
||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||
virtual uint32 getMipLevels() const = 0;
|
||||
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
@@ -36,6 +35,7 @@ class Texture2D : public Texture {
|
||||
virtual uint32 getWidth() const = 0;
|
||||
virtual uint32 getHeight() const = 0;
|
||||
virtual uint32 getDepth() const = 0;
|
||||
virtual uint32 getNumLayers() const = 0;
|
||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||
virtual uint32 getMipLevels() const = 0;
|
||||
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
@@ -59,6 +59,7 @@ class Texture3D : public Texture {
|
||||
virtual uint32 getWidth() const = 0;
|
||||
virtual uint32 getHeight() const = 0;
|
||||
virtual uint32 getDepth() const = 0;
|
||||
virtual uint32 getNumLayers() const = 0;
|
||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||
virtual uint32 getMipLevels() const = 0;
|
||||
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
@@ -82,7 +83,7 @@ class TextureCube : public Texture {
|
||||
virtual uint32 getWidth() const = 0;
|
||||
virtual uint32 getHeight() const = 0;
|
||||
virtual uint32 getDepth() const = 0;
|
||||
virtual uint32 getNumFaces() const { return 6; }
|
||||
virtual uint32 getNumLayers() const = 0;
|
||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||
virtual uint32 getMipLevels() const = 0;
|
||||
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> _dependencies,
|
||||
std::string name, Array<uint32> viewMasks, Array<uint32> correlationMasks)
|
||||
: Gfx::RenderPass(std::move(_layout), std::move(_dependencies)), graphics(graphics) {
|
||||
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> _dependencies, std::string name,
|
||||
Array<uint32> viewMasks, Array<uint32> correlationMasks)
|
||||
: Gfx::RenderPass(std::move(_layout), std::move(_dependencies)), name(name), graphics(graphics) {
|
||||
subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
|
||||
Array<VkAttachmentDescription2> attachments;
|
||||
Array<VkAttachmentReference2> inputRefs;
|
||||
|
||||
@@ -15,8 +15,10 @@ class RenderPass : public Gfx::RenderPass {
|
||||
constexpr size_t getClearValueCount() const { return clearValues.size(); }
|
||||
constexpr VkClearValue* getClearValues() const { return clearValues.data(); }
|
||||
constexpr VkSubpassContents getSubpassContents() const { return subpassContents; }
|
||||
constexpr const std::string& getName() const { return name; }
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
PGraphics graphics;
|
||||
VkRenderPass renderPass;
|
||||
Array<VkClearValue> clearValues;
|
||||
|
||||
@@ -83,6 +83,7 @@ class Texture2D : public Gfx::Texture2D, public TextureBase {
|
||||
virtual uint32 getWidth() const override { return handle->width; }
|
||||
virtual uint32 getHeight() const override { return handle->height; }
|
||||
virtual uint32 getDepth() const override { return handle->depth; }
|
||||
virtual uint32 getNumLayers() const override { return handle->layerCount; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
||||
@@ -106,6 +107,7 @@ class Texture3D : public Gfx::Texture3D, public TextureBase {
|
||||
virtual uint32 getWidth() const override { return handle->width; }
|
||||
virtual uint32 getHeight() const override { return handle->height; }
|
||||
virtual uint32 getDepth() const override { return handle->depth; }
|
||||
virtual uint32 getNumLayers() const override { return handle->layerCount; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
||||
@@ -129,6 +131,7 @@ class TextureCube : public Gfx::TextureCube, public TextureBase {
|
||||
virtual uint32 getWidth() const override { return handle->width; }
|
||||
virtual uint32 getHeight() const override { return handle->height; }
|
||||
virtual uint32 getDepth() const override { return handle->depth; }
|
||||
virtual uint32 getNumLayers() const override { return handle->layerCount; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
||||
|
||||
@@ -9,7 +9,9 @@ Window::~Window() {}
|
||||
|
||||
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
|
||||
: sizeX(viewportInfo.dimensions.size.x), sizeY(viewportInfo.dimensions.size.y), offsetX(viewportInfo.dimensions.offset.x),
|
||||
offsetY(viewportInfo.dimensions.offset.y), fieldOfView(viewportInfo.fieldOfView), owner(owner) {
|
||||
offsetY(viewportInfo.dimensions.offset.y), fieldOfView(viewportInfo.fieldOfView), orthoLeft(viewportInfo.left),
|
||||
orthoRight(viewportInfo.right), orthoTop(viewportInfo.top), orthoBottom(viewportInfo.bottom),
|
||||
owner(owner) {
|
||||
if (owner != nullptr) {
|
||||
sizeX = std::min(owner->getFramebufferWidth(), sizeX);
|
||||
sizeY = std::min(owner->getFramebufferHeight(), sizeY);
|
||||
@@ -18,16 +20,12 @@ Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
|
||||
|
||||
Viewport::~Viewport() {}
|
||||
|
||||
Matrix4 Viewport::getProjectionMatrix() const {
|
||||
Matrix4 Viewport::getProjectionMatrix(float nearPlane, float farPlane) const {
|
||||
if (fieldOfView > 0.0f) {
|
||||
Matrix4 projectionMatrix = glm::perspective(fieldOfView, sizeX / static_cast<float>(sizeY), 0.1f, 1000.0f);
|
||||
Matrix4 correctionMatrix = Matrix4(
|
||||
1, 0, 0, 0,
|
||||
0, -1, 0, 0,
|
||||
0, 0, 1 / 2.f, 0,
|
||||
0, 0, 1 / 2.f, 1);
|
||||
Matrix4 projectionMatrix = glm::perspective(fieldOfView, sizeX / static_cast<float>(sizeY), nearPlane, farPlane);
|
||||
Matrix4 correctionMatrix = Matrix4(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1 / 2.f, 0, 0, 0, 1 / 2.f, 1);
|
||||
return correctionMatrix * projectionMatrix;
|
||||
} else {
|
||||
return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f);
|
||||
return glm::ortho(orthoLeft, orthoRight, orthoTop, orthoBottom, nearPlane, farPlane);
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ class Viewport {
|
||||
constexpr uint32 getOffsetY() const { return offsetY; }
|
||||
constexpr float getContentScaleX() const { return owner->getContentScaleX(); }
|
||||
constexpr float getContentScaleY() const { return owner->getContentScaleY(); }
|
||||
Matrix4 getProjectionMatrix() const;
|
||||
Matrix4 getProjectionMatrix(float nearPlane, float farPlane) const;
|
||||
URect getRenderArea() const {
|
||||
return URect{
|
||||
.size = {sizeX, sizeY},
|
||||
@@ -66,6 +66,10 @@ class Viewport {
|
||||
uint32 offsetX;
|
||||
uint32 offsetY;
|
||||
float fieldOfView;
|
||||
float orthoLeft;
|
||||
float orthoRight;
|
||||
float orthoTop;
|
||||
float orthoBottom;
|
||||
PWindow owner;
|
||||
};
|
||||
DEFINE_REF(Viewport)
|
||||
|
||||
@@ -30,6 +30,10 @@ class Transform {
|
||||
Vector getRight() const;
|
||||
Vector getUp() const;
|
||||
|
||||
constexpr static Vector FORWARD = Vector(0, 0, 1);
|
||||
constexpr static Vector RIGHT = Vector(-1, 0, 0);
|
||||
constexpr static Vector UP = Vector(0, 1, 0);
|
||||
|
||||
bool equals(const Transform& other, float tolerance = 0.000000001f);
|
||||
static void multiply(Transform* outTransform, const Transform* a, const Transform* b);
|
||||
static void add(Transform* outTransform, const Transform* a, const Transform* b);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "LightEnvironment.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Asset/EnvironmentMapAsset.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -84,6 +84,17 @@ void LightEnvironment::commit() {
|
||||
set->updateTexture("irradianceMap", 0, environment->getIrradianceMap());
|
||||
set->updateSampler("irradianceSampler", 0, environmentSampler);
|
||||
set->writeChanges();
|
||||
|
||||
while (shadowMapArray.size() < dirs.size()) {
|
||||
shadowMapArray.add(graphics->createTexture2D(TextureCreateInfo{
|
||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||
.width = 2048,
|
||||
.height = 2048,
|
||||
.elements = (uint32)dirs.size(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
||||
.name = "ShadowMap",
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
const Gfx::PDescriptorLayout LightEnvironment::getDescriptorLayout() const { return layout; }
|
||||
|
||||
@@ -15,11 +15,15 @@ class LightEnvironment {
|
||||
void addPointLight(Component::PointLight pointLight);
|
||||
void commit();
|
||||
const Gfx::PDescriptorLayout getDescriptorLayout() const;
|
||||
const Component::DirectionalLight& getDirectionalLight(uint32 lightIndex) const { return dirs[lightIndex]; }
|
||||
Gfx::PDescriptorSet getDescriptorSet();
|
||||
PEnvironmentMapAsset getEnvironmentMap() { return environment; }
|
||||
uint64 getNumDirectionalLights() const { return dirs.size(); }
|
||||
const Array<Gfx::OTexture2D>& getShadowMaps() const { return shadowMapArray; }
|
||||
|
||||
private:
|
||||
Gfx::OShaderBuffer directionalLights;
|
||||
Array<Gfx::OTexture2D> shadowMapArray;
|
||||
Gfx::OShaderBuffer pointLights;
|
||||
Array<Component::DirectionalLight> dirs;
|
||||
Array<Component::PointLight> points;
|
||||
|
||||
@@ -10,5 +10,4 @@ CameraUpdater::~CameraUpdater() {}
|
||||
void CameraUpdater::update(Component::Camera& camera, Component::Transform& transform) {
|
||||
Vector eyePos = transform.getPosition();
|
||||
Vector lookAt = eyePos + transform.getForward();
|
||||
camera.viewMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0));
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "Graphics/RenderPass/RenderGraphResources.h"
|
||||
#include "Graphics/RenderPass/ToneMappingPass.h"
|
||||
#include "Graphics/RenderPass/VisibilityPass.h"
|
||||
#include "Graphics/RenderPass/ShadowPass.h"
|
||||
#include "System/CameraUpdater.h"
|
||||
#include "System/LightGather.h"
|
||||
#include "System/MeshUpdater.h"
|
||||
@@ -26,6 +27,7 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
|
||||
renderGraph.addPass(new DepthCullingPass(graphics, scene));
|
||||
renderGraph.addPass(new VisibilityPass(graphics));
|
||||
renderGraph.addPass(new LightCullingPass(graphics, scene));
|
||||
renderGraph.addPass(new ShadowPass(graphics, scene));
|
||||
renderGraph.addPass(new BasePass(graphics, scene));
|
||||
renderGraph.addPass(new ToneMappingPass(graphics));
|
||||
renderGraph.setViewport(viewport);
|
||||
|
||||
Reference in New Issue
Block a user