Adding transparency support
This commit is contained in:
@@ -75,6 +75,9 @@ BasePass::~BasePass() {}
|
||||
void BasePass::beginFrame(const Component::Camera& cam) {
|
||||
RenderPass::beginFrame(cam);
|
||||
|
||||
cameraPos = cam.getCameraPosition();
|
||||
cameraForward = cam.getCameraForward();
|
||||
|
||||
lightCullingLayout->reset();
|
||||
opaqueCulling = lightCullingLayout->allocateDescriptorSet();
|
||||
transparentCulling = lightCullingLayout->allocateDescriptorSet();
|
||||
@@ -95,7 +98,9 @@ void BasePass::render() {
|
||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
||||
permutation.setDepthCulling(true); // always use the culling info
|
||||
permutation.setPositionOnly(false);
|
||||
Array<VertexData::TransparentDraw> transparentData;
|
||||
for (VertexData* vertexData : VertexData::getList()) {
|
||||
transparentData.addAll(vertexData->getTransparentData());
|
||||
vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->writeChanges();
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
@@ -120,6 +125,9 @@ void BasePass::render() {
|
||||
|
||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
assert(collection != nullptr);
|
||||
|
||||
bool twoSided = materialData.material->isTwoSided();
|
||||
|
||||
if (graphics->supportMeshShading()) {
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = collection->taskShader,
|
||||
@@ -131,6 +139,10 @@ void BasePass::render() {
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.rasterizationState =
|
||||
{
|
||||
.cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
@@ -152,6 +164,10 @@ void BasePass::render() {
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.rasterizationState =
|
||||
{
|
||||
.cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
@@ -184,8 +200,106 @@ void BasePass::render() {
|
||||
commands.add(std::move(command));
|
||||
}
|
||||
}
|
||||
|
||||
graphics->executeCommands(std::move(commands));
|
||||
|
||||
Map<float, VertexData::TransparentDraw> sortedDraws;
|
||||
for (const auto& t : transparentData) {
|
||||
Vector toCenter = Vector(t.worldPosition) - cameraPos;
|
||||
float dist = glm::length(toCenter) * glm::dot(glm::normalize(toCenter), cameraForward);
|
||||
sortedDraws[dist] = t;
|
||||
}
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("TransparentDraw");
|
||||
command->setViewport(viewport);
|
||||
for (const auto& [_, t] : sortedDraws) {
|
||||
permutation.setVertexData(t.vertexData->getTypeName());
|
||||
permutation.setMaterial(t.matInst->getBaseMaterial()->getName());
|
||||
Gfx::PermutationId id(permutation);
|
||||
|
||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
assert(collection != nullptr);
|
||||
|
||||
bool twoSided = t.matInst->getBaseMaterial()->isTwoSided();
|
||||
|
||||
if (graphics->supportMeshShading()) {
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = collection->taskShader,
|
||||
.meshShader = collection->meshShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.rasterizationState =
|
||||
{
|
||||
.cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
.blendAttachments =
|
||||
{
|
||||
Gfx::ColorBlendState::BlendAttachment{
|
||||
.blendEnable = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
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,
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.rasterizationState =
|
||||
{
|
||||
.cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
.blendAttachments =
|
||||
{
|
||||
Gfx::ColorBlendState::BlendAttachment{
|
||||
.blendEnable = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
}
|
||||
command->bindDescriptor({viewParamsSet, t.vertexData->getVertexDataSet(), t.vertexData->getInstanceDataSet(),
|
||||
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), transparentCulling});
|
||||
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), &t.offsets);
|
||||
if (graphics->supportMeshShading()) {
|
||||
command->drawMesh(1, 1, 1);
|
||||
} else {
|
||||
// command->bindIndexBuffer(t.vertexData->getIndexBuffer());
|
||||
// for (const auto& meshData : drawCall.instanceMeshData) {
|
||||
// // all meshlets of a mesh share the same indices offset
|
||||
// command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset),
|
||||
// 0);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
graphics->endRenderPass();
|
||||
query->endQuery();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,10 @@ class BasePass : public RenderPass {
|
||||
// use a different texture here so we can do multisampling
|
||||
Gfx::OTexture2D basePassDepth;
|
||||
|
||||
// used for transparency sorting
|
||||
Vector cameraPos;
|
||||
Vector cameraForward;
|
||||
|
||||
PCameraActor source;
|
||||
Gfx::OPipelineLayout basePassLayout;
|
||||
Gfx::ODescriptorLayout lightCullingLayout;
|
||||
|
||||
@@ -105,7 +105,9 @@ void DepthCullingPass::render() {
|
||||
UVector2 threadGroups = (((mipDims[i] + UVector2(1, 1)) / 2u) + UVector2(BLOCK_SIZE - 1, BLOCK_SIZE - 1)) / uint32(BLOCK_SIZE);
|
||||
computeCommand->dispatch(threadGroups.x, threadGroups.y, 1);
|
||||
}
|
||||
|
||||
Array<Gfx::OComputeCommand> computeCommands;
|
||||
computeCommands.add(std::move(computeCommand));
|
||||
graphics->executeCommands(std::move(computeCommands));
|
||||
depthMipBuffer->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);
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ TextPass::FontData& TextPass::getFontData(PFontAsset font) {
|
||||
const auto& fontGlyphs = font->getGlyphData();
|
||||
FontData& fd = fontData[font];
|
||||
Array<GlyphData> glyphData;
|
||||
Array<Gfx::PTexture> textures;
|
||||
Array<Gfx::PTexture2D> textures;
|
||||
glyphData.reserve(fontGlyphs.size());
|
||||
for (const auto& [key, value] : fontGlyphs) {
|
||||
fd.characterToGlyphIndex[key] = static_cast<uint32>(glyphData.size());
|
||||
|
||||
@@ -37,7 +37,7 @@ class UIPass : public RenderPass {
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
|
||||
Array<UI::RenderElementStyle> renderElements;
|
||||
Array<Gfx::PTexture> usedTextures;
|
||||
Array<Gfx::PTexture2D> usedTextures;
|
||||
};
|
||||
DEFINE_REF(UIPass);
|
||||
} // namespace Seele
|
||||
|
||||
@@ -79,6 +79,7 @@ void VisibilityPass::publishOutputs() {
|
||||
|
||||
cullingBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.clearValue = 0xffffffff,
|
||||
.createCleared = true,
|
||||
.dynamic = true,
|
||||
.name = "CullingBuffer",
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user