Basic shadow mapping rendering
This commit is contained in:
@@ -26,7 +26,7 @@ void taskMain(
|
|||||||
uint cull = p.cullingOffset + i;
|
uint cull = p.cullingOffset + i;
|
||||||
MeshletDescription meshlet = pScene.meshletInfos[m];
|
MeshletDescription meshlet = pScene.meshletInfos[m];
|
||||||
MeshletCullingInfo culling = pScene.cullingInfos[cull];
|
MeshletCullingInfo culling = pScene.cullingInfos[cull];
|
||||||
if(culling.wasVisible())
|
//if(culling.wasVisible())
|
||||||
{
|
{
|
||||||
uint index;
|
uint index;
|
||||||
InterlockedAdd(head, 1, 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::ORenderPass cubeRenderPass = graphics->createRenderPass(
|
||||||
Gfx::RenderTargetLayout{
|
Gfx::RenderTargetLayout{
|
||||||
.colorAttachments = {Gfx::RenderTargetAttachment(cubeMap, Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
.colorAttachments =
|
||||||
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
{
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE)},
|
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{
|
||||||
|
.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,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{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},
|
.size = {SOURCE_RESOLUTION, SOURCE_RESOLUTION},
|
||||||
.offset = {0, 0},
|
.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) {
|
if (material->GetTexture(type, index, &texPath, &mapping, &uvIndex, &blend, &op, &mapMode) != AI_SUCCESS) {
|
||||||
std::cout << "fuck" << std::endl;
|
std::cout << "fuck" << std::endl;
|
||||||
}
|
}
|
||||||
uvIndex = 1;
|
|
||||||
std::string textureKey = fmt::format("{0}Texture{1}", paramKey, index);
|
std::string textureKey = fmt::format("{0}Texture{1}", paramKey, index);
|
||||||
auto texFilename = std::filesystem::path(texPath.C_Str());
|
auto texFilename = std::filesystem::path(texPath.C_Str());
|
||||||
PTextureAsset texture;
|
PTextureAsset texture;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using namespace Seele;
|
|||||||
DirectionalLightActor::DirectionalLightActor(PScene scene) : Actor(scene) { attachComponent<Component::DirectionalLight>(); }
|
DirectionalLightActor::DirectionalLightActor(PScene scene) : Actor(scene) { attachComponent<Component::DirectionalLight>(); }
|
||||||
|
|
||||||
DirectionalLightActor::DirectionalLightActor(PScene scene, Vector color, float intensity, Vector direction) : Actor(scene) {
|
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() {}
|
DirectionalLightActor::~DirectionalLightActor() {}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
namespace Seele {
|
namespace Seele {
|
||||||
namespace Component {
|
namespace Component {
|
||||||
struct Camera {
|
struct Camera {
|
||||||
Matrix4 viewMatrix;
|
float nearPlane = 0.001f;
|
||||||
|
float farPlane = 10000.0f;
|
||||||
bool mainCamera = false;
|
bool mainCamera = false;
|
||||||
};
|
};
|
||||||
} // namespace Component
|
} // namespace Component
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ struct WindowCreateInfo {
|
|||||||
struct ViewportCreateInfo {
|
struct ViewportCreateInfo {
|
||||||
URect dimensions;
|
URect dimensions;
|
||||||
float fieldOfView = glm::radians(70.0f);
|
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 {
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ 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) {
|
||||||
RenderPass::beginFrame(cam, transform);
|
viewParamsSet = createViewParamsSet(cam, transform);
|
||||||
|
|
||||||
cameraPos = transform.getPosition();
|
cameraPos = transform.getPosition();
|
||||||
cameraForward = transform.getForward();
|
cameraForward = transform.getForward();
|
||||||
@@ -136,6 +136,7 @@ void BasePass::beginFrame(const Component::Camera& cam, const Component::Transfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BasePass::render() {
|
void BasePass::render() {
|
||||||
|
graphics->beginDebugRegion("BasePass");
|
||||||
opaqueCulling->updateBuffer(LIGHTINDEX_NAME, 0, oLightIndexList);
|
opaqueCulling->updateBuffer(LIGHTINDEX_NAME, 0, oLightIndexList);
|
||||||
opaqueCulling->updateTexture(LIGHTGRID_NAME, 0, oLightGrid);
|
opaqueCulling->updateTexture(LIGHTGRID_NAME, 0, oLightGrid);
|
||||||
transparentCulling->updateBuffer(LIGHTINDEX_NAME, 0, tLightIndexList);
|
transparentCulling->updateBuffer(LIGHTINDEX_NAME, 0, tLightIndexList);
|
||||||
@@ -151,110 +152,118 @@ void BasePass::render() {
|
|||||||
permutation.setDepthCulling(true); // always use the culling info
|
permutation.setDepthCulling(true); // always use the culling info
|
||||||
permutation.setPositionOnly(false);
|
permutation.setPositionOnly(false);
|
||||||
Array<VertexData::TransparentDraw> transparentData;
|
Array<VertexData::TransparentDraw> transparentData;
|
||||||
// Base Rendering
|
{
|
||||||
for (VertexData* vertexData : VertexData::getList()) {
|
graphics->beginDebugRegion("Opaque");
|
||||||
transparentData.addAll(vertexData->getTransparentData());
|
// Base Rendering
|
||||||
permutation.setVertexData(vertexData->getTypeName());
|
for (VertexData* vertexData : VertexData::getList()) {
|
||||||
for (const auto& materialData : vertexData->getMaterialData()) {
|
transparentData.addAll(vertexData->getTransparentData());
|
||||||
// material not used for any active meshes, skip
|
permutation.setVertexData(vertexData->getTypeName());
|
||||||
if (materialData.instances.size() == 0)
|
for (const auto& materialData : vertexData->getMaterialData()) {
|
||||||
continue;
|
// material not used for any active meshes, skip
|
||||||
// Create Pipeline(Material, VertexData)
|
if (materialData.instances.size() == 0)
|
||||||
// Descriptors:
|
continue;
|
||||||
// ViewData => global, static
|
// Create Pipeline(Material, VertexData)
|
||||||
// VertexData => per meshtype
|
// Descriptors:
|
||||||
// SceneData => per material instance
|
// ViewData => global, static
|
||||||
// LightEnv => provided by scene
|
// VertexData => per meshtype
|
||||||
// Material => per material
|
// SceneData => per material instance
|
||||||
// LightCulling => calculated by pass
|
// LightEnv => provided by scene
|
||||||
permutation.setMaterial(materialData.material->getName(), materialData.material->getProfile());
|
// Material => per material
|
||||||
Gfx::PermutationId id(permutation);
|
// LightCulling => calculated by pass
|
||||||
|
permutation.setMaterial(materialData.material->getName(), materialData.material->getProfile());
|
||||||
|
Gfx::PermutationId id(permutation);
|
||||||
|
|
||||||
Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender");
|
Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender");
|
||||||
command->setViewport(viewport);
|
command->setViewport(viewport);
|
||||||
|
|
||||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||||
assert(collection != nullptr);
|
assert(collection != nullptr);
|
||||||
|
|
||||||
bool twoSided = materialData.material->isTwoSided();
|
bool twoSided = materialData.material->isTwoSided();
|
||||||
|
|
||||||
if (graphics->supportMeshShading()) {
|
|
||||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
|
||||||
.taskShader = collection->taskShader,
|
|
||||||
.meshShader = collection->meshShader,
|
|
||||||
.fragmentShader = collection->fragmentShader,
|
|
||||||
.renderPass = renderPass,
|
|
||||||
.pipelineLayout = collection->pipelineLayout,
|
|
||||||
.multisampleState =
|
|
||||||
{
|
|
||||||
.samples = msColorAttachment.getNumSamples(),
|
|
||||||
},
|
|
||||||
.rasterizationState =
|
|
||||||
{
|
|
||||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
|
||||||
},
|
|
||||||
.colorBlend =
|
|
||||||
{
|
|
||||||
.attachmentCount = 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo)));
|
|
||||||
} else {
|
|
||||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
|
||||||
.vertexShader = collection->vertexShader,
|
|
||||||
.fragmentShader = collection->fragmentShader,
|
|
||||||
.renderPass = renderPass,
|
|
||||||
.pipelineLayout = collection->pipelineLayout,
|
|
||||||
.multisampleState =
|
|
||||||
{
|
|
||||||
.samples = msColorAttachment.getNumSamples(),
|
|
||||||
},
|
|
||||||
.rasterizationState =
|
|
||||||
{
|
|
||||||
.cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT),
|
|
||||||
},
|
|
||||||
.colorBlend =
|
|
||||||
{
|
|
||||||
.attachmentCount = 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo)));
|
|
||||||
}
|
|
||||||
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(),
|
|
||||||
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), opaqueCulling});
|
|
||||||
for (const auto& drawCall : materialData.instances) {
|
|
||||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
|
|
||||||
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
|
||||||
0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets);
|
|
||||||
if (graphics->supportMeshShading()) {
|
if (graphics->supportMeshShading()) {
|
||||||
command->drawMesh((uint32)drawCall.instanceMeshData.size(), 1, 1);
|
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||||
|
.taskShader = collection->taskShader,
|
||||||
|
.meshShader = collection->meshShader,
|
||||||
|
.fragmentShader = collection->fragmentShader,
|
||||||
|
.renderPass = renderPass,
|
||||||
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
|
.multisampleState =
|
||||||
|
{
|
||||||
|
.samples = msColorAttachment.getNumSamples(),
|
||||||
|
},
|
||||||
|
.rasterizationState =
|
||||||
|
{
|
||||||
|
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||||
|
},
|
||||||
|
.colorBlend =
|
||||||
|
{
|
||||||
|
.attachmentCount = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo)));
|
||||||
} else {
|
} else {
|
||||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||||
for (const auto& meshData : drawCall.instanceMeshData) {
|
.vertexShader = collection->vertexShader,
|
||||||
// all meshlets of a mesh share the same indices offset
|
.fragmentShader = collection->fragmentShader,
|
||||||
command->drawIndexed(meshData.indicesRange.size, 1, meshData.indicesRange.offset,
|
.renderPass = renderPass,
|
||||||
vertexData->getIndicesOffset(meshData.meshletRange.offset), 0);
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
|
.multisampleState =
|
||||||
|
{
|
||||||
|
.samples = msColorAttachment.getNumSamples(),
|
||||||
|
},
|
||||||
|
.rasterizationState =
|
||||||
|
{
|
||||||
|
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||||
|
},
|
||||||
|
.colorBlend =
|
||||||
|
{
|
||||||
|
.attachmentCount = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo)));
|
||||||
|
}
|
||||||
|
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(),
|
||||||
|
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), opaqueCulling});
|
||||||
|
for (const auto& drawCall : materialData.instances) {
|
||||||
|
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
|
||||||
|
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
|
0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets);
|
||||||
|
if (graphics->supportMeshShading()) {
|
||||||
|
command->drawMesh((uint32)drawCall.instanceMeshData.size(), 1, 1);
|
||||||
|
} else {
|
||||||
|
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||||
|
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), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
commands.add(std::move(command));
|
||||||
}
|
}
|
||||||
commands.add(std::move(command));
|
|
||||||
}
|
}
|
||||||
|
graphics->endDebugRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//commands.add(waterRenderer->render(viewParamsSet));
|
//commands.add(waterRenderer->render(viewParamsSet));
|
||||||
//commands.add(terrainRenderer->render(viewParamsSet));
|
//commands.add(terrainRenderer->render(viewParamsSet));
|
||||||
|
|
||||||
// Skybox
|
// Skybox
|
||||||
{
|
{
|
||||||
|
graphics->beginDebugRegion("Skybox");
|
||||||
Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender");
|
Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender");
|
||||||
skyboxCommand->setViewport(viewport);
|
skyboxCommand->setViewport(viewport);
|
||||||
skyboxCommand->bindPipeline(skyboxPipeline);
|
skyboxCommand->bindPipeline(skyboxPipeline);
|
||||||
skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
||||||
skyboxCommand->draw(36, 1, 0, 0);
|
skyboxCommand->draw(36, 1, 0, 0);
|
||||||
graphics->executeCommands(std::move(skyboxCommand));
|
graphics->executeCommands(std::move(skyboxCommand));
|
||||||
|
graphics->endDebugRegion();
|
||||||
}
|
}
|
||||||
// Transparent rendering
|
// Transparent rendering
|
||||||
{
|
{
|
||||||
|
graphics->beginDebugRegion("Transparent");
|
||||||
permutation.setDepthCulling(false); // ignore visibility infos for transparency
|
permutation.setDepthCulling(false); // ignore visibility infos for transparency
|
||||||
Map<float, VertexData::TransparentDraw> sortedDraws;
|
Map<float, VertexData::TransparentDraw> sortedDraws;
|
||||||
for (const auto& t : transparentData) {
|
for (const auto& t : transparentData) {
|
||||||
@@ -352,9 +361,11 @@ void BasePass::render() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
commands.add(std::move(transparentCommand));
|
commands.add(std::move(transparentCommand));
|
||||||
|
graphics->endDebugRegion();
|
||||||
}
|
}
|
||||||
// Debug vertices
|
// Debug vertices
|
||||||
if (gDebugVertices.size() > 0) {
|
if (gDebugVertices.size() > 0) {
|
||||||
|
graphics->beginDebugRegion("Debug");
|
||||||
Gfx::ORenderCommand debugCommand = graphics->createRenderCommand("DebugRender");
|
Gfx::ORenderCommand debugCommand = graphics->createRenderCommand("DebugRender");
|
||||||
debugCommand->setViewport(viewport);
|
debugCommand->setViewport(viewport);
|
||||||
debugCommand->bindPipeline(debugPipeline);
|
debugCommand->bindPipeline(debugPipeline);
|
||||||
@@ -362,6 +373,7 @@ void BasePass::render() {
|
|||||||
debugCommand->bindVertexBuffer({debugVertices});
|
debugCommand->bindVertexBuffer({debugVertices});
|
||||||
debugCommand->draw((uint32)gDebugVertices.size(), 1, 0, 0);
|
debugCommand->draw((uint32)gDebugVertices.size(), 1, 0, 0);
|
||||||
commands.add(std::move(debugCommand));
|
commands.add(std::move(debugCommand));
|
||||||
|
graphics->endDebugRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics->executeCommands(std::move(commands));
|
graphics->executeCommands(std::move(commands));
|
||||||
@@ -369,6 +381,7 @@ void BasePass::render() {
|
|||||||
query->endQuery();
|
query->endQuery();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "BaseEnd");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "BaseEnd");
|
||||||
gDebugVertices.clear();
|
gDebugVertices.clear();
|
||||||
|
graphics->endDebugRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasePass::endFrame() {}
|
void BasePass::endFrame() {}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class BasePass : public RenderPass {
|
|||||||
// used for transparency sorting
|
// used for transparency sorting
|
||||||
Vector cameraPos;
|
Vector cameraPos;
|
||||||
Vector cameraForward;
|
Vector cameraForward;
|
||||||
|
Gfx::PDescriptorSet viewParamsSet;
|
||||||
|
|
||||||
PCameraActor source;
|
PCameraActor source;
|
||||||
Gfx::OPipelineLayout basePassLayout;
|
Gfx::OPipelineLayout basePassLayout;
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ target_sources(Engine
|
|||||||
RenderGraphResources.cpp
|
RenderGraphResources.cpp
|
||||||
RenderPass.h
|
RenderPass.h
|
||||||
RenderPass.cpp
|
RenderPass.cpp
|
||||||
|
ShadowPass.h
|
||||||
|
ShadowPass.cpp
|
||||||
#TerrainRenderer.h
|
#TerrainRenderer.h
|
||||||
#TerrainRenderer.cpp
|
#TerrainRenderer.cpp
|
||||||
ToneMappingPass.h
|
ToneMappingPass.h
|
||||||
@@ -38,6 +40,7 @@ target_sources(Engine
|
|||||||
RenderGraph.h
|
RenderGraph.h
|
||||||
RenderGraphResources.h
|
RenderGraphResources.h
|
||||||
RenderPass.h
|
RenderPass.h
|
||||||
|
ShadowPass.h
|
||||||
#TerrainRenderer.h
|
#TerrainRenderer.h
|
||||||
UIPass.h
|
UIPass.h
|
||||||
VisibilityPass.h)
|
VisibilityPass.h)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "CachedDepthPass.h"
|
#include "CachedDepthPass.h"
|
||||||
#include "Graphics/Shader.h"
|
|
||||||
#include "Graphics/Pipeline.h"
|
#include "Graphics/Pipeline.h"
|
||||||
|
#include "Graphics/Shader.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -41,9 +41,12 @@ CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) : Render
|
|||||||
|
|
||||||
CachedDepthPass::~CachedDepthPass() {}
|
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() {
|
void CachedDepthPass::render() {
|
||||||
|
graphics->beginDebugRegion("CachedDepth");
|
||||||
query->beginQuery();
|
query->beginQuery();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "CachedBegin");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "CachedBegin");
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
@@ -78,7 +81,7 @@ void CachedDepthPass::render() {
|
|||||||
.pipelineLayout = collection->pipelineLayout,
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
.rasterizationState =
|
.rasterizationState =
|
||||||
{
|
{
|
||||||
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||||
},
|
},
|
||||||
.colorBlend =
|
.colorBlend =
|
||||||
{
|
{
|
||||||
@@ -95,7 +98,7 @@ void CachedDepthPass::render() {
|
|||||||
.pipelineLayout = collection->pipelineLayout,
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
.rasterizationState =
|
.rasterizationState =
|
||||||
{
|
{
|
||||||
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||||
},
|
},
|
||||||
.colorBlend =
|
.colorBlend =
|
||||||
{
|
{
|
||||||
@@ -125,7 +128,7 @@ void CachedDepthPass::render() {
|
|||||||
for (const auto& meshData : drawCall.instanceMeshData) {
|
for (const auto& meshData : drawCall.instanceMeshData) {
|
||||||
// all meshlets of a mesh share the same indices offset
|
// all meshlets of a mesh share the same indices offset
|
||||||
command->drawIndexed(meshData.indicesRange.size, 1, meshData.indicesRange.offset,
|
command->drawIndexed(meshData.indicesRange.size, 1, meshData.indicesRange.offset,
|
||||||
vertexData->getIndicesOffset(meshData.meshletRange.offset), inst++);
|
vertexData->getIndicesOffset(meshData.meshletRange.offset), inst++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,6 +140,7 @@ void CachedDepthPass::render() {
|
|||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CachedEnd");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CachedEnd");
|
||||||
query->endQuery();
|
query->endQuery();
|
||||||
|
graphics->endDebugRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CachedDepthPass::endFrame() {}
|
void CachedDepthPass::endFrame() {}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ class CachedDepthPass : public RenderPass {
|
|||||||
Gfx::OPipelineStatisticsQuery query;
|
Gfx::OPipelineStatisticsQuery query;
|
||||||
Gfx::OTimestampQuery timestamps;
|
Gfx::OTimestampQuery timestamps;
|
||||||
|
|
||||||
|
Gfx::PDescriptorSet viewParamsSet;
|
||||||
Gfx::PShaderBuffer cullingBuffer;
|
Gfx::PShaderBuffer cullingBuffer;
|
||||||
PScene scene;
|
PScene scene;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -65,157 +65,171 @@ DepthCullingPass::DepthCullingPass(Gfx::PGraphics graphics, PScene scene) : Rend
|
|||||||
|
|
||||||
DepthCullingPass::~DepthCullingPass() {}
|
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() {
|
void DepthCullingPass::render() {
|
||||||
query->beginQuery();
|
graphics->beginDebugRegion("DepthCullingPass");
|
||||||
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,
|
|
||||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
|
||||||
|
|
||||||
depthMipBuffer->rotateBuffer(depthMipBuffer->getNumElements() * sizeof(uint32));
|
|
||||||
Gfx::PDescriptorSet set = depthAttachmentLayout->allocateDescriptorSet();
|
|
||||||
set->updateTexture(DEPTHTEXTURE_NAME, 0, depthAttachment.getTexture());
|
|
||||||
set->updateBuffer(DEPTHMIP_NAME, 0, depthMipBuffer);
|
|
||||||
set->writeChanges();
|
|
||||||
|
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "MipBegin");
|
|
||||||
// First we generate a pixel value per thread, while using a whole threadgroup
|
|
||||||
// for a single one would be a waste
|
|
||||||
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);
|
|
||||||
graphics->executeCommands(std::move(computeCommand));
|
|
||||||
for (uint32 i = 0; i < mipOffsets.size() - 1; ++i)
|
|
||||||
{
|
{
|
||||||
depthMipBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
graphics->beginDebugRegion("MipGeneration");
|
||||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
query->beginQuery();
|
||||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
depthAttachment.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
MipParam param = {
|
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
.sourceOffset = mipOffsets[i],
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
.destOffset = mipOffsets[i + 1],
|
|
||||||
.sourceDim = mipDims[i],
|
|
||||||
.destDim = mipDims[i + 1],
|
|
||||||
};
|
|
||||||
Gfx::OComputeCommand reduceCommand = graphics->createComputeCommand("ReduceCommand");
|
|
||||||
reduceCommand->bindPipeline(depthReduceLevel);
|
|
||||||
reduceCommand->bindDescriptor({viewParamsSet, set});
|
|
||||||
reduceCommand->pushConstants(Gfx::SE_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(MipParam), ¶m);
|
|
||||||
auto dispatchDim = (mipDims[i + 1] + uint32(BLOCK_SIZE) - 1u) / uint32(BLOCK_SIZE);
|
|
||||||
reduceCommand->dispatch(dispatchDim.x, dispatchDim.y, 1);
|
|
||||||
graphics->executeCommands(std::move(reduceCommand));
|
|
||||||
}
|
|
||||||
|
|
||||||
depthMipBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
depthMipBuffer->rotateBuffer(depthMipBuffer->getNumElements() * sizeof(uint32));
|
||||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT);
|
Gfx::PDescriptorSet set = depthAttachmentLayout->allocateDescriptorSet();
|
||||||
|
set->updateTexture(DEPTHTEXTURE_NAME, 0, depthAttachment.getTexture());
|
||||||
|
set->updateBuffer(DEPTHMIP_NAME, 0, depthMipBuffer);
|
||||||
|
set->writeChanges();
|
||||||
|
|
||||||
depthAttachment.getTexture()->changeLayout(
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "MipBegin");
|
||||||
Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, Gfx::SE_ACCESS_TRANSFER_READ_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
// First we generate a pixel value per thread, while using a whole threadgroup
|
||||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
// for a single one would be a waste
|
||||||
Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
|
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("MipGen");
|
||||||
|
computeCommand->bindPipeline(depthSourceCopy);
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "CullingBegin");
|
computeCommand->bindDescriptor({viewParamsSet, set});
|
||||||
graphics->beginRenderPass(renderPass);
|
computeCommand->dispatch((viewport->getWidth() + BLOCK_SIZE - 1) / BLOCK_SIZE,
|
||||||
Array<Gfx::ORenderCommand> commands;
|
(viewport->getHeight() + BLOCK_SIZE - 1) / BLOCK_SIZE, 1);
|
||||||
|
graphics->executeCommands(std::move(computeCommand));
|
||||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("DepthPass");
|
for (uint32 i = 0; i < mipOffsets.size() - 1; ++i) {
|
||||||
permutation.setPositionOnly(true);
|
depthMipBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
permutation.setDepthCulling(getGlobals().useDepthCulling);
|
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||||
for (VertexData* vertexData : VertexData::getList()) {
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
permutation.setVertexData(vertexData->getTypeName());
|
MipParam param = {
|
||||||
// Create Pipeline(VertexData)
|
.sourceOffset = mipOffsets[i],
|
||||||
// Descriptors:
|
.destOffset = mipOffsets[i + 1],
|
||||||
// ViewData => global, static
|
.sourceDim = mipDims[i],
|
||||||
// VertexData => per meshtype
|
.destDim = mipDims[i + 1],
|
||||||
// SceneData => per meshtype
|
|
||||||
Gfx::PermutationId id(permutation);
|
|
||||||
|
|
||||||
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
|
|
||||||
command->setViewport(viewport);
|
|
||||||
|
|
||||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
|
||||||
assert(collection != nullptr);
|
|
||||||
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));
|
Gfx::OComputeCommand reduceCommand = graphics->createComputeCommand("ReduceCommand");
|
||||||
command->bindPipeline(pipeline);
|
reduceCommand->bindPipeline(depthReduceLevel);
|
||||||
} else {
|
reduceCommand->bindDescriptor({viewParamsSet, set});
|
||||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
reduceCommand->pushConstants(Gfx::SE_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(MipParam), ¶m);
|
||||||
.vertexShader = collection->vertexShader,
|
auto dispatchDim = (mipDims[i + 1] + uint32(BLOCK_SIZE) - 1u) / uint32(BLOCK_SIZE);
|
||||||
.fragmentShader = collection->fragmentShader,
|
reduceCommand->dispatch(dispatchDim.x, dispatchDim.y, 1);
|
||||||
.renderPass = renderPass,
|
graphics->executeCommands(std::move(reduceCommand));
|
||||||
.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(), set});
|
|
||||||
VertexData::DrawCallOffsets offsets = {
|
depthMipBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
.instanceOffset = 0,
|
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT);
|
||||||
.textureOffset = 0,
|
|
||||||
.samplerOffset = 0,
|
depthAttachment.getTexture()->changeLayout(
|
||||||
.floatOffset = 0,
|
Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, Gfx::SE_ACCESS_TRANSFER_READ_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
};
|
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets),
|
Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
|
||||||
&offsets);
|
|
||||||
if (graphics->supportMeshShading()) {
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "CullingBegin");
|
||||||
command->drawMesh((uint32)vertexData->getNumInstances(), 1, 1);
|
graphics->endDebugRegion();
|
||||||
} else {
|
}
|
||||||
const auto& materials = vertexData->getMaterialData();
|
{
|
||||||
for (const auto& materialData : materials) {
|
graphics->beginDebugRegion("DepthCulling");
|
||||||
for (const auto& drawCall : materialData.instances) {
|
graphics->beginRenderPass(renderPass);
|
||||||
// material not used for any active meshes, skip
|
Array<Gfx::ORenderCommand> commands;
|
||||||
if (materialData.instances.size() == 0)
|
Gfx::PDescriptorSet set = depthAttachmentLayout->allocateDescriptorSet();
|
||||||
continue;
|
set->updateTexture(DEPTHTEXTURE_NAME, 0, depthAttachment.getTexture());
|
||||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
set->updateBuffer(DEPTHMIP_NAME, 0, depthMipBuffer);
|
||||||
uint32 inst = drawCall.offsets.instanceOffset;
|
set->writeChanges();
|
||||||
for (const auto& meshData : drawCall.instanceMeshData) {
|
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("DepthPass");
|
||||||
// all meshlets of a mesh share the same indices offset
|
permutation.setPositionOnly(true);
|
||||||
command->drawIndexed(meshData.indicesRange.size, 1, meshData.indicesRange.offset,
|
permutation.setDepthCulling(getGlobals().useDepthCulling);
|
||||||
vertexData->getIndicesOffset(meshData.meshletRange.offset), inst++);
|
for (VertexData* vertexData : VertexData::getList()) {
|
||||||
|
permutation.setVertexData(vertexData->getTypeName());
|
||||||
|
// Create Pipeline(VertexData)
|
||||||
|
// Descriptors:
|
||||||
|
// ViewData => global, static
|
||||||
|
// VertexData => per meshtype
|
||||||
|
// SceneData => per meshtype
|
||||||
|
Gfx::PermutationId id(permutation);
|
||||||
|
|
||||||
|
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||||
|
command->setViewport(viewport);
|
||||||
|
|
||||||
|
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||||
|
assert(collection != nullptr);
|
||||||
|
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_BACK_BIT,
|
||||||
|
},
|
||||||
|
.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_BACK_BIT,
|
||||||
|
},
|
||||||
|
.colorBlend =
|
||||||
|
{
|
||||||
|
.attachmentCount = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
|
command->bindPipeline(pipeline);
|
||||||
|
}
|
||||||
|
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(), set});
|
||||||
|
VertexData::DrawCallOffsets offsets = {
|
||||||
|
.instanceOffset = 0,
|
||||||
|
.textureOffset = 0,
|
||||||
|
.samplerOffset = 0,
|
||||||
|
.floatOffset = 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) {
|
||||||
|
for (const auto& drawCall : materialData.instances) {
|
||||||
|
// material not used for any active meshes, skip
|
||||||
|
if (materialData.instances.size() == 0)
|
||||||
|
continue;
|
||||||
|
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->executeCommands(std::move(commands));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CullingEnd");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CullingEnd");
|
||||||
query->endQuery();
|
query->endQuery();
|
||||||
// Sync depth read/write with compute read
|
// Sync depth read/write with compute read
|
||||||
depthAttachment.getTexture()->pipelineBarrier(
|
depthAttachment.getTexture()->pipelineBarrier(
|
||||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
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
|
// Sync visibility write with compute read
|
||||||
visibilityAttachment.getTexture()->pipelineBarrier(Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
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_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
graphics->endDebugRegion();
|
||||||
|
}
|
||||||
|
graphics->endDebugRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthCullingPass::endFrame() {}
|
void DepthCullingPass::endFrame() {}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class DepthCullingPass : public RenderPass {
|
|||||||
Gfx::PComputePipeline depthSourceCopy;
|
Gfx::PComputePipeline depthSourceCopy;
|
||||||
Gfx::OComputeShader depthReduceLevelShader;
|
Gfx::OComputeShader depthReduceLevelShader;
|
||||||
Gfx::PComputePipeline depthReduceLevel;
|
Gfx::PComputePipeline depthReduceLevel;
|
||||||
|
Gfx::PDescriptorSet viewParamsSet;
|
||||||
|
|
||||||
Gfx::PShaderBuffer cullingBuffer;
|
Gfx::PShaderBuffer cullingBuffer;
|
||||||
PScene scene;
|
PScene scene;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ 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) {
|
||||||
RenderPass::beginFrame(cam, transform);
|
viewParamsSet = createViewParamsSet(cam, transform);
|
||||||
|
|
||||||
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,
|
||||||
@@ -38,6 +38,7 @@ void LightCullingPass::beginFrame(const Component::Camera& cam, const Component:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LightCullingPass::render() {
|
void LightCullingPass::render() {
|
||||||
|
graphics->beginDebugRegion("LightCulling");
|
||||||
query->beginQuery();
|
query->beginQuery();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "LightCullBegin");
|
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,
|
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);
|
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,
|
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);
|
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
graphics->endDebugRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightCullingPass::endFrame() {}
|
void LightCullingPass::endFrame() {}
|
||||||
@@ -223,13 +225,14 @@ void LightCullingPass::createRenderPass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LightCullingPass::setupFrustums() {
|
void LightCullingPass::setupFrustums() {
|
||||||
|
graphics->beginDebugRegion("SetupFrustums");
|
||||||
uint32_t viewportWidth = viewport->getWidth();
|
uint32_t viewportWidth = viewport->getWidth();
|
||||||
uint32_t viewportHeight = viewport->getHeight();
|
uint32_t viewportHeight = viewport->getHeight();
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
RenderPass::beginFrame(Component::Camera(), Component::Transform());
|
viewParamsSet = createViewParamsSet(Component::Camera(), Component::Transform());
|
||||||
|
|
||||||
dispatchParamsLayout = graphics->createDescriptorLayout("pDispatchParams");
|
dispatchParamsLayout = graphics->createDescriptorLayout("pDispatchParams");
|
||||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
@@ -294,4 +297,5 @@ void LightCullingPass::setupFrustums() {
|
|||||||
graphics->executeCommands(std::move(commands));
|
graphics->executeCommands(std::move(commands));
|
||||||
frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
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);
|
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::OComputeShader frustumShader;
|
||||||
Gfx::PComputePipeline frustumPipeline;
|
Gfx::PComputePipeline frustumPipeline;
|
||||||
Gfx::OPipelineLayout frustumLayout;
|
Gfx::OPipelineLayout frustumLayout;
|
||||||
|
Gfx::PDescriptorSet viewParamsSet;
|
||||||
|
|
||||||
PLightEnvironment lightEnv;
|
PLightEnvironment lightEnv;
|
||||||
Gfx::PTexture2D depthAttachment;
|
Gfx::PTexture2D depthAttachment;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ 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) {
|
||||||
RenderPass::beginFrame(cam, transform);
|
viewParamsSet = createViewParamsSet(cam, transform);
|
||||||
if (lastCam.getPosition() != transform.getPosition() || lastCam.getForward() != transform.getForward()) {
|
if (lastCam.getPosition() != transform.getPosition() || lastCam.getForward() != transform.getForward()) {
|
||||||
lastCam = transform;
|
lastCam = transform;
|
||||||
pass = 0;
|
pass = 0;
|
||||||
@@ -75,6 +75,7 @@ void RayTracingPass::beginFrame(const Component::Camera& cam, const Component::T
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RayTracingPass::render() {
|
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,
|
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);
|
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||||
Array<Gfx::RayTracingHitGroup> callableGroups;
|
Array<Gfx::RayTracingHitGroup> callableGroups;
|
||||||
@@ -185,6 +186,7 @@ void RayTracingPass::render() {
|
|||||||
Array<Gfx::ORenderCommand> commands;
|
Array<Gfx::ORenderCommand> commands;
|
||||||
commands.add(std::move(command));
|
commands.add(std::move(command));
|
||||||
graphics->executeCommands(std::move(commands));
|
graphics->executeCommands(std::move(commands));
|
||||||
|
graphics->endDebugRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayTracingPass::endFrame() {}
|
void RayTracingPass::endFrame() {}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ class RayTracingPass : public RenderPass {
|
|||||||
Gfx::OAnyHitShader anyhit;
|
Gfx::OAnyHitShader anyhit;
|
||||||
Gfx::OMissShader miss;
|
Gfx::OMissShader miss;
|
||||||
Gfx::PRayTracingPipeline pipeline;
|
Gfx::PRayTracingPipeline pipeline;
|
||||||
|
Gfx::PDescriptorSet viewParamsSet;
|
||||||
PScene scene;
|
PScene scene;
|
||||||
};
|
};
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -23,10 +23,17 @@ RenderPass::RenderPass(Gfx::PGraphics graphics) : graphics(graphics) {
|
|||||||
|
|
||||||
RenderPass::~RenderPass() {}
|
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()));
|
auto screenDim = Vector2(static_cast<float>(viewport->getWidth()), static_cast<float>(viewport->getHeight()));
|
||||||
Matrix4 cameraMatrix = cam.viewMatrix;
|
Vector eyePos = transform.getPosition();
|
||||||
Matrix4 projectionMatrix = viewport->getProjectionMatrix();
|
Vector lookAt = eyePos + transform.getForward();
|
||||||
|
Matrix4 cameraMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0));
|
||||||
|
Matrix4 projectionMatrix = viewport->getProjectionMatrix(cam.nearPlane, cam.farPlane);
|
||||||
viewParams = {
|
viewParams = {
|
||||||
.viewMatrix = cameraMatrix,
|
.viewMatrix = cameraMatrix,
|
||||||
.inverseViewMatrix = glm::inverse(cameraMatrix),
|
.inverseViewMatrix = glm::inverse(cameraMatrix),
|
||||||
@@ -60,10 +67,10 @@ void RenderPass::beginFrame(const Component::Camera& cam, const Component::Trans
|
|||||||
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);
|
||||||
|
|
||||||
viewParamsLayout->reset();
|
viewParamsLayout->reset();
|
||||||
viewParamsSet = viewParamsLayout->allocateDescriptorSet();
|
Gfx::PDescriptorSet viewParamsSet = viewParamsLayout->allocateDescriptorSet();
|
||||||
viewParamsSet->updateConstants("viewMatrix", 0, &viewParams.viewMatrix);
|
viewParamsSet->updateConstants("viewMatrix", 0, &viewParams.viewMatrix);
|
||||||
viewParamsSet->updateConstants("inverseViewMatrix", 0, &viewParams.inverseViewMatrix);
|
viewParamsSet->updateConstants("inverseViewMatrix", 0, &viewParams.inverseViewMatrix);
|
||||||
viewParamsSet->updateConstants("projectionMatrix", 0, &viewParams.projectionMatrix);
|
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("pad0", 0, &viewParams.pad0);
|
||||||
viewParamsSet->updateConstants("pad1", 0, &viewParams.pad1);
|
viewParamsSet->updateConstants("pad1", 0, &viewParams.pad1);
|
||||||
viewParamsSet->writeChanges();
|
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) {
|
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);
|
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;
|
plane.n.x /= l;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class RenderPass {
|
|||||||
RenderPass(RenderPass&&) = default;
|
RenderPass(RenderPass&&) = default;
|
||||||
RenderPass& operator=(RenderPass&&) = default;
|
RenderPass& operator=(RenderPass&&) = default;
|
||||||
virtual ~RenderPass();
|
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 render() = 0;
|
||||||
virtual void endFrame() = 0;
|
virtual void endFrame() = 0;
|
||||||
virtual void publishOutputs() = 0;
|
virtual void publishOutputs() = 0;
|
||||||
@@ -27,6 +27,7 @@ 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);
|
||||||
struct Plane {
|
struct Plane {
|
||||||
Vector n;
|
Vector n;
|
||||||
float d;
|
float d;
|
||||||
@@ -67,7 +68,6 @@ class RenderPass {
|
|||||||
} viewParams;
|
} viewParams;
|
||||||
PRenderGraphResources resources;
|
PRenderGraphResources resources;
|
||||||
Gfx::ODescriptorLayout viewParamsLayout;
|
Gfx::ODescriptorLayout viewParamsLayout;
|
||||||
Gfx::PDescriptorSet viewParamsSet;
|
|
||||||
Gfx::ORenderPass renderPass;
|
Gfx::ORenderPass renderPass;
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
Gfx::PViewport viewport;
|
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() {}
|
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() {
|
void ToneMappingPass::render() {
|
||||||
|
graphics->beginDebugRegion("ToneMapping");
|
||||||
hdrInputTexture.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
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_COLOR_ATTACHMENT_OUTPUT_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_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);
|
command->draw(3, 1, 0, 0);
|
||||||
graphics->executeCommands(std::move(command));
|
graphics->executeCommands(std::move(command));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
|
graphics->endDebugRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToneMappingPass::endFrame() {}
|
void ToneMappingPass::endFrame() {}
|
||||||
|
|||||||
@@ -47,5 +47,7 @@ class ToneMappingPass : public RenderPass {
|
|||||||
Gfx::OVertexShader vert;
|
Gfx::OVertexShader vert;
|
||||||
Gfx::OFragmentShader frag;
|
Gfx::OFragmentShader frag;
|
||||||
Gfx::PGraphicsPipeline pipeline;
|
Gfx::PGraphicsPipeline pipeline;
|
||||||
|
|
||||||
|
Gfx::PDescriptorSet viewParamsSet;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ 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) {
|
||||||
RenderPass::beginFrame(cam, transform);
|
viewParamsSet = createViewParamsSet(cam, transform);
|
||||||
glyphs.clear();
|
glyphs.clear();
|
||||||
usedTextures.clear();
|
usedTextures.clear();
|
||||||
elements.clear();
|
elements.clear();
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ class UIPass : public RenderPass {
|
|||||||
Gfx::ODescriptorLayout uiDescriptorLayout;
|
Gfx::ODescriptorLayout uiDescriptorLayout;
|
||||||
Gfx::PDescriptorSet uiDescriptorSet;
|
Gfx::PDescriptorSet uiDescriptorSet;
|
||||||
|
|
||||||
|
Gfx::PDescriptorSet viewParamsSet;
|
||||||
|
|
||||||
Gfx::OVertexShader uiVertexShader;
|
Gfx::OVertexShader uiVertexShader;
|
||||||
Gfx::OFragmentShader uiFragmentShader;
|
Gfx::OFragmentShader uiFragmentShader;
|
||||||
Gfx::OPipelineLayout uiPipelineLayout;
|
Gfx::OPipelineLayout uiPipelineLayout;
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ 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) {
|
||||||
RenderPass::beginFrame(cam, transform);
|
viewParamsSet = createViewParamsSet(cam, transform);
|
||||||
cullingBuffer->rotateBuffer(VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo), true);
|
cullingBuffer->rotateBuffer(VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisibilityPass::render() {
|
void VisibilityPass::render() {
|
||||||
|
graphics->beginDebugRegion("VisibilityPass");
|
||||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
|
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);
|
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
||||||
cullingBuffer->clear();
|
cullingBuffer->clear();
|
||||||
@@ -40,6 +41,7 @@ void VisibilityPass::render() {
|
|||||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT);
|
Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT);
|
||||||
|
graphics->endDebugRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisibilityPass::endFrame() {}
|
void VisibilityPass::endFrame() {}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class VisibilityPass : public RenderPass {
|
|||||||
Gfx::PComputePipeline visibilityPipeline;
|
Gfx::PComputePipeline visibilityPipeline;
|
||||||
Gfx::OPipelineStatisticsQuery query;
|
Gfx::OPipelineStatisticsQuery query;
|
||||||
Gfx::PTimestampQuery timestamps;
|
Gfx::PTimestampQuery timestamps;
|
||||||
|
Gfx::PDescriptorSet viewParamsSet;
|
||||||
|
|
||||||
constexpr static const char* VISIBILITY_NAME = "visibilityTexture";
|
constexpr static const char* VISIBILITY_NAME = "visibilityTexture";
|
||||||
// Holds culling information for every meshlet for each instance
|
// 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,
|
RenderTargetAttachment::RenderTargetAttachment(PTexture2D texture, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||||
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
||||||
SeAttachmentStoreOp stencilStoreOp)
|
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) {}
|
storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {}
|
||||||
|
|
||||||
RenderTargetAttachment::RenderTargetAttachment(PTextureCube texture, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
RenderTargetAttachment::RenderTargetAttachment(PTextureCube texture, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||||
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
||||||
SeAttachmentStoreOp stencilStoreOp)
|
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) {}
|
storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {}
|
||||||
|
|
||||||
RenderTargetAttachment::RenderTargetAttachment(PViewport viewport, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
RenderTargetAttachment::RenderTargetAttachment(PViewport viewport, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||||
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
||||||
SeAttachmentStoreOp stencilStoreOp)
|
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) {}
|
storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {}
|
||||||
|
|
||||||
RenderTargetAttachment::~RenderTargetAttachment() {}
|
RenderTargetAttachment::~RenderTargetAttachment() {}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ class Texture : public QueueOwnedResource {
|
|||||||
virtual uint32 getWidth() const = 0;
|
virtual uint32 getWidth() const = 0;
|
||||||
virtual uint32 getHeight() const = 0;
|
virtual uint32 getHeight() const = 0;
|
||||||
virtual uint32 getDepth() const = 0;
|
virtual uint32 getDepth() const = 0;
|
||||||
virtual uint32 getNumFaces() const { return 1; }
|
|
||||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||||
virtual uint32 getMipLevels() const = 0;
|
virtual uint32 getMipLevels() const = 0;
|
||||||
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
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 getWidth() const = 0;
|
||||||
virtual uint32 getHeight() const = 0;
|
virtual uint32 getHeight() const = 0;
|
||||||
virtual uint32 getDepth() const = 0;
|
virtual uint32 getDepth() const = 0;
|
||||||
|
virtual uint32 getNumLayers() const = 0;
|
||||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||||
virtual uint32 getMipLevels() const = 0;
|
virtual uint32 getMipLevels() const = 0;
|
||||||
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
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 getWidth() const = 0;
|
||||||
virtual uint32 getHeight() const = 0;
|
virtual uint32 getHeight() const = 0;
|
||||||
virtual uint32 getDepth() const = 0;
|
virtual uint32 getDepth() const = 0;
|
||||||
|
virtual uint32 getNumLayers() const = 0;
|
||||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||||
virtual uint32 getMipLevels() const = 0;
|
virtual uint32 getMipLevels() const = 0;
|
||||||
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
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 getWidth() const = 0;
|
||||||
virtual uint32 getHeight() const = 0;
|
virtual uint32 getHeight() const = 0;
|
||||||
virtual uint32 getDepth() const = 0;
|
virtual uint32 getDepth() const = 0;
|
||||||
virtual uint32 getNumFaces() const { return 6; }
|
virtual uint32 getNumLayers() const = 0;
|
||||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||||
virtual uint32 getMipLevels() const = 0;
|
virtual uint32 getMipLevels() const = 0;
|
||||||
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Vulkan;
|
using namespace Seele::Vulkan;
|
||||||
|
|
||||||
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> _dependencies,
|
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> _dependencies, std::string name,
|
||||||
std::string name, Array<uint32> viewMasks, Array<uint32> correlationMasks)
|
Array<uint32> viewMasks, Array<uint32> correlationMasks)
|
||||||
: Gfx::RenderPass(std::move(_layout), std::move(_dependencies)), graphics(graphics) {
|
: Gfx::RenderPass(std::move(_layout), std::move(_dependencies)), name(name), graphics(graphics) {
|
||||||
subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
|
subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
|
||||||
Array<VkAttachmentDescription2> attachments;
|
Array<VkAttachmentDescription2> attachments;
|
||||||
Array<VkAttachmentReference2> inputRefs;
|
Array<VkAttachmentReference2> inputRefs;
|
||||||
|
|||||||
@@ -15,8 +15,10 @@ class RenderPass : public Gfx::RenderPass {
|
|||||||
constexpr size_t getClearValueCount() const { return clearValues.size(); }
|
constexpr size_t getClearValueCount() const { return clearValues.size(); }
|
||||||
constexpr VkClearValue* getClearValues() const { return clearValues.data(); }
|
constexpr VkClearValue* getClearValues() const { return clearValues.data(); }
|
||||||
constexpr VkSubpassContents getSubpassContents() const { return subpassContents; }
|
constexpr VkSubpassContents getSubpassContents() const { return subpassContents; }
|
||||||
|
constexpr const std::string& getName() const { return name; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::string name;
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
VkRenderPass renderPass;
|
VkRenderPass renderPass;
|
||||||
Array<VkClearValue> clearValues;
|
Array<VkClearValue> clearValues;
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ class Texture2D : public Gfx::Texture2D, public TextureBase {
|
|||||||
virtual uint32 getWidth() const override { return handle->width; }
|
virtual uint32 getWidth() const override { return handle->width; }
|
||||||
virtual uint32 getHeight() const override { return handle->height; }
|
virtual uint32 getHeight() const override { return handle->height; }
|
||||||
virtual uint32 getDepth() const override { return handle->depth; }
|
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::SeFormat getFormat() const override { return handle->format; }
|
||||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||||
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
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 getWidth() const override { return handle->width; }
|
||||||
virtual uint32 getHeight() const override { return handle->height; }
|
virtual uint32 getHeight() const override { return handle->height; }
|
||||||
virtual uint32 getDepth() const override { return handle->depth; }
|
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::SeFormat getFormat() const override { return handle->format; }
|
||||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||||
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
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 getWidth() const override { return handle->width; }
|
||||||
virtual uint32 getHeight() const override { return handle->height; }
|
virtual uint32 getHeight() const override { return handle->height; }
|
||||||
virtual uint32 getDepth() const override { return handle->depth; }
|
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::SeFormat getFormat() const override { return handle->format; }
|
||||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||||
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ 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), 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) {
|
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);
|
||||||
@@ -18,16 +20,12 @@ Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
|
|||||||
|
|
||||||
Viewport::~Viewport() {}
|
Viewport::~Viewport() {}
|
||||||
|
|
||||||
Matrix4 Viewport::getProjectionMatrix() const {
|
Matrix4 Viewport::getProjectionMatrix(float nearPlane, float farPlane) const {
|
||||||
if (fieldOfView > 0.0f) {
|
if (fieldOfView > 0.0f) {
|
||||||
Matrix4 projectionMatrix = glm::perspective(fieldOfView, sizeX / static_cast<float>(sizeY), 0.1f, 1000.0f);
|
Matrix4 projectionMatrix = glm::perspective(fieldOfView, sizeX / static_cast<float>(sizeY), nearPlane, farPlane);
|
||||||
Matrix4 correctionMatrix = Matrix4(
|
Matrix4 correctionMatrix = Matrix4(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1 / 2.f, 0, 0, 0, 1 / 2.f, 1);
|
||||||
1, 0, 0, 0,
|
|
||||||
0, -1, 0, 0,
|
|
||||||
0, 0, 1 / 2.f, 0,
|
|
||||||
0, 0, 1 / 2.f, 1);
|
|
||||||
return correctionMatrix * projectionMatrix;
|
return correctionMatrix * projectionMatrix;
|
||||||
} else {
|
} 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 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() const;
|
Matrix4 getProjectionMatrix(float nearPlane, float farPlane) const;
|
||||||
URect getRenderArea() const {
|
URect getRenderArea() const {
|
||||||
return URect{
|
return URect{
|
||||||
.size = {sizeX, sizeY},
|
.size = {sizeX, sizeY},
|
||||||
@@ -66,6 +66,10 @@ class Viewport {
|
|||||||
uint32 offsetX;
|
uint32 offsetX;
|
||||||
uint32 offsetY;
|
uint32 offsetY;
|
||||||
float fieldOfView;
|
float fieldOfView;
|
||||||
|
float orthoLeft;
|
||||||
|
float orthoRight;
|
||||||
|
float orthoTop;
|
||||||
|
float orthoBottom;
|
||||||
PWindow owner;
|
PWindow owner;
|
||||||
};
|
};
|
||||||
DEFINE_REF(Viewport)
|
DEFINE_REF(Viewport)
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ class Transform {
|
|||||||
Vector getRight() const;
|
Vector getRight() const;
|
||||||
Vector getUp() 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);
|
bool equals(const Transform& other, float tolerance = 0.000000001f);
|
||||||
static void multiply(Transform* outTransform, const Transform* a, const Transform* b);
|
static void multiply(Transform* outTransform, const Transform* a, const Transform* b);
|
||||||
static void add(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 "LightEnvironment.h"
|
||||||
|
#include "Asset/AssetRegistry.h"
|
||||||
#include "Asset/EnvironmentMapAsset.h"
|
#include "Asset/EnvironmentMapAsset.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Asset/AssetRegistry.h"
|
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -84,6 +84,17 @@ void LightEnvironment::commit() {
|
|||||||
set->updateTexture("irradianceMap", 0, environment->getIrradianceMap());
|
set->updateTexture("irradianceMap", 0, environment->getIrradianceMap());
|
||||||
set->updateSampler("irradianceSampler", 0, environmentSampler);
|
set->updateSampler("irradianceSampler", 0, environmentSampler);
|
||||||
set->writeChanges();
|
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; }
|
const Gfx::PDescriptorLayout LightEnvironment::getDescriptorLayout() const { return layout; }
|
||||||
|
|||||||
@@ -15,11 +15,15 @@ class LightEnvironment {
|
|||||||
void addPointLight(Component::PointLight pointLight);
|
void addPointLight(Component::PointLight pointLight);
|
||||||
void commit();
|
void commit();
|
||||||
const Gfx::PDescriptorLayout getDescriptorLayout() const;
|
const Gfx::PDescriptorLayout getDescriptorLayout() const;
|
||||||
|
const Component::DirectionalLight& getDirectionalLight(uint32 lightIndex) const { return dirs[lightIndex]; }
|
||||||
Gfx::PDescriptorSet getDescriptorSet();
|
Gfx::PDescriptorSet getDescriptorSet();
|
||||||
PEnvironmentMapAsset getEnvironmentMap() { return environment; }
|
PEnvironmentMapAsset getEnvironmentMap() { return environment; }
|
||||||
|
uint64 getNumDirectionalLights() const { return dirs.size(); }
|
||||||
|
const Array<Gfx::OTexture2D>& getShadowMaps() const { return shadowMapArray; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Gfx::OShaderBuffer directionalLights;
|
Gfx::OShaderBuffer directionalLights;
|
||||||
|
Array<Gfx::OTexture2D> shadowMapArray;
|
||||||
Gfx::OShaderBuffer pointLights;
|
Gfx::OShaderBuffer pointLights;
|
||||||
Array<Component::DirectionalLight> dirs;
|
Array<Component::DirectionalLight> dirs;
|
||||||
Array<Component::PointLight> points;
|
Array<Component::PointLight> points;
|
||||||
|
|||||||
@@ -10,5 +10,4 @@ CameraUpdater::~CameraUpdater() {}
|
|||||||
void CameraUpdater::update(Component::Camera& camera, Component::Transform& transform) {
|
void CameraUpdater::update(Component::Camera& camera, Component::Transform& transform) {
|
||||||
Vector eyePos = transform.getPosition();
|
Vector eyePos = transform.getPosition();
|
||||||
Vector lookAt = eyePos + transform.getForward();
|
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/RenderGraphResources.h"
|
||||||
#include "Graphics/RenderPass/ToneMappingPass.h"
|
#include "Graphics/RenderPass/ToneMappingPass.h"
|
||||||
#include "Graphics/RenderPass/VisibilityPass.h"
|
#include "Graphics/RenderPass/VisibilityPass.h"
|
||||||
|
#include "Graphics/RenderPass/ShadowPass.h"
|
||||||
#include "System/CameraUpdater.h"
|
#include "System/CameraUpdater.h"
|
||||||
#include "System/LightGather.h"
|
#include "System/LightGather.h"
|
||||||
#include "System/MeshUpdater.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 DepthCullingPass(graphics, scene));
|
||||||
renderGraph.addPass(new VisibilityPass(graphics));
|
renderGraph.addPass(new VisibilityPass(graphics));
|
||||||
renderGraph.addPass(new LightCullingPass(graphics, scene));
|
renderGraph.addPass(new LightCullingPass(graphics, scene));
|
||||||
|
renderGraph.addPass(new ShadowPass(graphics, scene));
|
||||||
renderGraph.addPass(new BasePass(graphics, scene));
|
renderGraph.addPass(new BasePass(graphics, scene));
|
||||||
renderGraph.addPass(new ToneMappingPass(graphics));
|
renderGraph.addPass(new ToneMappingPass(graphics));
|
||||||
renderGraph.setViewport(viewport);
|
renderGraph.setViewport(viewport);
|
||||||
|
|||||||
Reference in New Issue
Block a user