Skip to content

Commit

Permalink
refactor lightmap & add shadow for gpu driven
Browse files Browse the repository at this point in the history
  • Loading branch information
stanleyljl committed Oct 8, 2023
1 parent 231c233 commit 2e1f639
Show file tree
Hide file tree
Showing 18 changed files with 170 additions and 151 deletions.
6 changes: 4 additions & 2 deletions cocos/game/director.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,11 @@ export class Director extends EventTarget {
onBeforeLoadScene();
}

if (scene.renderScene) {
scene.renderScene.activate();
if (scene) {
scene.renderScene?.activate();
scene.globals.activate(scene);
}

this.emit(Director.EVENT_BEFORE_SCENE_LAUNCH, scene);

// Run an Entity Scene
Expand Down
1 change: 1 addition & 0 deletions cocos/rendering/custom/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,7 @@ export interface Pipeline extends BasicPipeline {
layoutPath?: string,
hzbName?: string,
light?: Light | null,
level?: number,
bMainPass?: boolean): void;
/**
* @en Add hierarchical z buffer generation pass
Expand Down
6 changes: 0 additions & 6 deletions cocos/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,12 +428,6 @@ export class Root {
//-----------------------------------------------
// pipeline initialization completed
//-----------------------------------------------
const scene = director.getScene();
if (scene) {
scene.globals.activate();
}

this.onGlobalPipelineStateChanged();
if (!this._batcher && internal.Batcher2D) {
this._batcher = new internal.Batcher2D(this);
if (!this._batcher!.initialize()) {
Expand Down
3 changes: 0 additions & 3 deletions cocos/scene-graph/scene.jsb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,6 @@ sceneProto._activate = function (active: boolean) {
}
cclegacy.director._nodeActivator.activateNode(this, active);
// The test environment does not currently support the renderer
if (!TEST || EDITOR) {
this._globals.activate(this);
}
};

sceneProto._instantiate = function(): void {};
Expand Down
3 changes: 0 additions & 3 deletions cocos/scene-graph/scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,6 @@ export class Scene extends Node {
}
cclegacy.director._nodeActivator.activateNode(this, active);
// The test environment does not currently support the renderer
if (!TEST) {
this._globals.activate(this);
}
}
}

Expand Down
10 changes: 2 additions & 8 deletions editor/assets/chunks/builtin/uniforms/cc-light-map.chunk
Original file line number Diff line number Diff line change
@@ -1,8 +1,2 @@
#if CC_USE_GPU_DRIVEN
#pragma rate cc_lightingMap pass
#pragma glBinding(2)
uniform sampler2D cc_lightingMap;
#else
#pragma builtin(local)
layout(set = 2, binding = 11) uniform sampler2D cc_lightingMap;
#endif
#pragma builtin(local)
layout(set = 2, binding = 11) uniform sampler2D cc_lightingMap;
2 changes: 2 additions & 0 deletions native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ void GLES3PrimaryCommandBuffer::insertMarker(const MarkerInfo &marker) {
}

void GLES3PrimaryCommandBuffer::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) {
CC_PROFILE(GLES3PrimaryCmdBufDrawIndirect);
if (_isStateInvalid) {
bindStates();
}
Expand All @@ -100,6 +101,7 @@ void GLES3PrimaryCommandBuffer::drawIndirect(Buffer *buffer, uint32_t offset, ui
}

void GLES3PrimaryCommandBuffer::drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) {
CC_PROFILE(GLES3PrimaryCmdBufDrawIndirect);
if (_isStateInvalid) {
bindStates();
}
Expand Down
2 changes: 2 additions & 0 deletions native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ of this software and associated engine source code (the "Software"), a limited,
}

void CCMTLCommandBuffer::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) {
CC_PROFILE(CCMTLCommandBufferDrawIndirect);
prepareForDraw();
auto mtlEncoder = _renderEncoder.getMTLEncoder();
auto *mtlBuffer = static_cast<CCMTLBuffer *>(buffer);
Expand All @@ -599,6 +600,7 @@ of this software and associated engine source code (the "Software"), a limited,
}

void CCMTLCommandBuffer::drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) {
CC_PROFILE(CCMTLCommandBufferDrawIndirect);
prepareForDraw();
CCMTLInputAssembler *inputAssembler = _gpuCommandBufferObj->inputAssembler;
const auto *indexBuffer = static_cast<CCMTLBuffer *>(inputAssembler->getIndexBuffer());
Expand Down
2 changes: 2 additions & 0 deletions native/cocos/renderer/gfx-vulkan/VKCommandBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ void CCVKCommandBuffer::nextSubpass() {
}

void CCVKCommandBuffer::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) {
CC_PROFILE(CCVKCmdBufDrawIndirect);
if (_firstDirtyDescriptorSet < _curGPUDescriptorSets.size()) {
bindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS);
}
Expand Down Expand Up @@ -487,6 +488,7 @@ void CCVKCommandBuffer::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t c
}

void CCVKCommandBuffer::drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) {
CC_PROFILE(CCVKCmdBufDrawIndirect);
if (_firstDirtyDescriptorSet < _curGPUDescriptorSets.size()) {
bindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS);
}
Expand Down
2 changes: 1 addition & 1 deletion native/cocos/renderer/pipeline/custom/NativeExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1499,10 +1499,10 @@ struct RenderGraphVisitor : boost::dfs_visitor<> {
}

if (pass.showStatistics) {
submitProfilerCommands(ctx, vertID, pass);
#if CC_USE_DEBUG_RENDERER
renderDebugRenderer(ctx.currentPass, ctx.cmdBuff, ctx.ppl->pipelineSceneData, nullptr);
#endif
submitProfilerCommands(ctx, vertID, pass);
}
ctx.cmdBuff->endRenderPass();
ctx.currentPass = nullptr;
Expand Down
78 changes: 52 additions & 26 deletions native/cocos/renderer/pipeline/custom/NativePipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ bool setupGpuDrivenResources(
{
name = "CCVisibilityBuffer";
name.append(std::to_string(cullingID));
const auto bufferSize = gpuScene->getInstanceCount() * static_cast<uint32_t>(sizeof(uint32_t));
const auto bufferSize = std::max(gpuScene->getInstanceCount(), 1U) * static_cast<uint32_t>(sizeof(uint32_t));
auto resID = findVertex(name, resg);
if (resID == ResourceGraph::null_vertex()) {
ppl.addStorageBuffer(std::string(name), gfx::Format::UNKNOWN, bufferSize, ResourceResidency::MANAGED);
Expand Down Expand Up @@ -1059,7 +1059,7 @@ bool setupGpuDrivenResources(

void NativePipeline::addBuiltinGpuCullingPass(uint32_t cullingID,
const scene::Camera *camera, const std::string &layoutPath,
const std::string &hzbName, const scene::Light *light, bool bMainPass) {
const std::string &hzbName, const scene::Light *light, uint32_t level, bool bMainPass) {
auto *scene = camera->getScene();
if (!scene) {
return;
Expand All @@ -1079,11 +1079,6 @@ void NativePipeline::addBuiltinGpuCullingPass(uint32_t cullingID,
const uint32_t sceneID = iter->second;
bool firstPass = setupGpuDrivenResources(*this, camera, gpuScene, sceneID, cullingID, resourceGraph, hzbName);

if (light) {
// build light culling pass
return;
}

const std::string objectBuffer = "CCObjectBuffer" + std::to_string(sceneID);
const std::string instanceBuffer = "CCInstanceBuffer" + std::to_string(sceneID);
const std::string indirectBuffer = "CCIndirectBuffer" + std::to_string(sceneID);
Expand Down Expand Up @@ -1155,26 +1150,57 @@ void NativePipeline::addBuiltinGpuCullingPass(uint32_t cullingID,
std::unique_ptr<NativeComputeQueueBuilder> gpuCullQueue(dynamic_cast<NativeComputeQueueBuilder*>(gpuCullPass->addQueue()));
gpuCullQueue->addDispatch(groupCount, 1, 1, pipelineSceneData->getGPUCullingMaterial(materialIndex), 0);

ccstd::vector<float> planes;
const auto &frustum = camera->getFrustum();
for (auto *plane : frustum.planes) {
planes.push_back(plane->n.x);
planes.push_back(plane->n.y);
planes.push_back(plane->n.z);
planes.push_back(plane->d);
if (light) {
auto *layers = pipelineSceneData->getCSMLayers();
layers->update(pipelineSceneData, camera);

auto *layer = layers->getLayers()[level];
const auto size = pipelineSceneData->getShadows()->getSize();
const auto width = static_cast<uint32_t>(size.x) / 2;
const auto height = static_cast<uint32_t>(size.y) / 2;

ccstd::vector<float> planes;
const auto &frustum = layer->getValidFrustum();
for (auto *plane : frustum.planes) {
planes.push_back(plane->n.x);
planes.push_back(plane->n.y);
planes.push_back(plane->n.z);
planes.push_back(plane->d);
}
ArrayBuffer planesBuffer(reinterpret_cast<uint8_t *>(&planes[0]), sizeof(float) * static_cast<uint32_t>(planes.size()));
gpuCullPass->setMat4("cc_view", layer->getMatShadowView());
gpuCullPass->setMat4("cc_proj", layer->getMatShadowProj());
gpuCullPass->setArrayBuffer("cc_planes", &planesBuffer);
gpuCullPass->setFloat("cc_znear", layer->getSplitCameraNear());
gpuCullPass->setFloat("cc_zfar", layer->getSplitCameraFar());
gpuCullPass->setFloat("cc_depthWidth", static_cast<float>(utils::previousPOT(width)));
gpuCullPass->setFloat("cc_depthHeight", static_cast<float>(utils::previousPOT(height)));
gpuCullPass->setUint("cc_isPerspective", light->getType() == scene::LightType::DIRECTIONAL ? 0 : 1);
gpuCullPass->setUint("cc_orientation", 0);
gpuCullPass->setUint("cc_instanceCount", instanceCount);
gpuCullPass->setUint("cc_phaseId", phaseID);
} else {
ccstd::vector<float> planes;
const auto &frustum = camera->getFrustum();
for (auto *plane : frustum.planes) {
planes.push_back(plane->n.x);
planes.push_back(plane->n.y);
planes.push_back(plane->n.z);
planes.push_back(plane->d);
}
ArrayBuffer planesBuffer(reinterpret_cast<uint8_t *>(&planes[0]), sizeof(float) * static_cast<uint32_t>(planes.size()));
gpuCullPass->setMat4("cc_view", camera->getMatView());
gpuCullPass->setMat4("cc_proj", camera->getMatProj());
gpuCullPass->setArrayBuffer("cc_planes", &planesBuffer);
gpuCullPass->setFloat("cc_znear", camera->getNearClip());
gpuCullPass->setFloat("cc_zfar", camera->getFarClip());
gpuCullPass->setFloat("cc_depthWidth", static_cast<float>(utils::previousPOT(camera->getWidth())));
gpuCullPass->setFloat("cc_depthHeight", static_cast<float>(utils::previousPOT(camera->getHeight())));
gpuCullPass->setUint("cc_isPerspective", static_cast<uint32_t>(camera->getProjectionType()));
gpuCullPass->setUint("cc_orientation", static_cast<uint32_t>(camera->getSurfaceTransform()));
gpuCullPass->setUint("cc_instanceCount", instanceCount);
gpuCullPass->setUint("cc_phaseId", phaseID);
}
ArrayBuffer planesBuffer(reinterpret_cast<uint8_t*>(&planes[0]), sizeof(float) * static_cast<uint32_t>(planes.size()));
gpuCullPass->setMat4("cc_view", camera->getMatView());
gpuCullPass->setMat4("cc_proj", camera->getMatProj());
gpuCullPass->setArrayBuffer("cc_planes", &planesBuffer);
gpuCullPass->setFloat("cc_znear", camera->getNearClip());
gpuCullPass->setFloat("cc_zfar", camera->getFarClip());
gpuCullPass->setFloat("cc_depthWidth", static_cast<float>(utils::previousPOT(camera->getWidth())));
gpuCullPass->setFloat("cc_depthHeight", static_cast<float>(utils::previousPOT(camera->getHeight())));
gpuCullPass->setUint("cc_isPerspective", static_cast<uint32_t>(camera->getProjectionType()));
gpuCullPass->setUint("cc_orientation", static_cast<uint32_t>(camera->getSurfaceTransform()));
gpuCullPass->setUint("cc_instanceCount", instanceCount);
gpuCullPass->setUint("cc_phaseId", phaseID);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1442,7 +1442,7 @@ class NativePipeline final : public Pipeline {
ComputePassBuilder *addComputePass(const ccstd::string &passName) override;
void addUploadPass(ccstd::vector<UploadPair> &uploadPairs) override;
void addMovePass(const ccstd::vector<MovePair> &movePairs) override;
void addBuiltinGpuCullingPass(uint32_t cullingID, const scene::Camera *camera, const std::string &layoutPath, const std::string &hzbName, const scene::Light *light, bool bMainPass) override;
void addBuiltinGpuCullingPass(uint32_t cullingID, const scene::Camera *camera, const std::string &layoutPath, const std::string &hzbName, const scene::Light *light, uint32_t level, bool bMainPass) override;
void addBuiltinHzbGenerationPass(const std::string &sourceDepthStencilName, const std::string &targetHzbName) override;
uint32_t addCustomBuffer(const ccstd::string &name, const gfx::BufferInfo &info, const std::string &type) override;
uint32_t addCustomTexture(const ccstd::string &name, const gfx::TextureInfo &info, const std::string &type) override;
Expand Down
83 changes: 42 additions & 41 deletions native/cocos/renderer/pipeline/custom/NativeRenderQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ void GPUDrivenQueue::recordCommandBuffer(

const bool bDrawBlend = any(sceneFlags & SceneFlags::TRANSPARENT_OBJECT);
const bool bDrawOpaqueOrMask = any(sceneFlags & (SceneFlags::OPAQUE_OBJECT | SceneFlags::CUTOUT_OBJECT));
const bool bDrawShadowCaster = any(sceneFlags & SceneFlags::SHADOW_CASTER);
if (!bDrawShadowCaster && !bDrawBlend && !bDrawOpaqueOrMask) {
return; // nothing to draw
}

CC_EXPECTS(cullingID != 0xFFFFFFFF);
ccstd::pmr::string indirectName("CCDrawIndirectBuffer", get_allocator());
Expand All @@ -211,56 +215,53 @@ void GPUDrivenQueue::recordCommandBuffer(
gfx::PipelineState *lastPSO = nullptr;
const auto indirectStride = scene::GPUBatchPool::getIndirectStride();

for (const auto &lightmapIter : batchPool->getBatches()) {
const auto *lightmap = lightmapIter.first;
// Stanley TODO: bindDescriptorSet for lightmap & sampler here, lightmap can be nullptr.
for (const auto &iter : batchPool->getBatches()) {
const auto *batch = iter.second;
if (batch->empty()) {
continue;
}

for (const auto &passIter : lightmapIter.second) {
const auto *batch = passIter.second;
if (batch->empty()) {
continue;
}
const auto *drawPass = batch->getPass();
if (phaseLayoutID != drawPass->getPhaseID()) {
continue;
}

const auto *drawPass = batch->getPass();
if (phaseLayoutID != drawPass->getPhaseID()) {
continue;
}
const bool bBlend = drawPass->isBlend();
const bool bOpaqueOrMask = !bBlend;
if (!bDrawBlend && bBlend) {
// skip transparent object
continue;
}
if (!bDrawOpaqueOrMask && bOpaqueOrMask) {
// skip opaque object
continue;
}

const bool bBlend = drawPass->isBlend();
const bool bOpaqueOrMask = !bBlend;
if (!bDrawBlend && bBlend) {
// skip transparent object
continue;
}
if (!bDrawOpaqueOrMask && bOpaqueOrMask) {
// skip opaque object
cmdBuffer->bindDescriptorSet(pipeline::materialSet, drawPass->getDescriptorSet());

const auto &items = batch->getItems();
for (const auto &item : items) {
if (!item.count) {
continue;
}

cmdBuffer->bindDescriptorSet(pipeline::materialSet, drawPass->getDescriptorSet());

const auto &items = batch->getItems();
for (const auto &item : items) {
if (!item.count) {
continue;
}
auto *pso = pipeline::PipelineStateManager::getOrCreatePipelineState(
drawPass, item.shader, item.inputAssembler, renderPass);

auto *pso = pipeline::PipelineStateManager::getOrCreatePipelineState(
drawPass, item.shader, item.inputAssembler, renderPass);
if (lastPSO != pso) {
cmdBuffer->bindPipelineState(pso);
lastPSO = pso;
}

if (lastPSO != pso) {
cmdBuffer->bindPipelineState(pso);
lastPSO = pso;
}
cmdBuffer->bindInputAssembler(item.inputAssembler);
cmdBuffer->bindDescriptorSet(pipeline::localSet, item.descriptorSet);

cmdBuffer->bindInputAssembler(item.inputAssembler);
if (supportFirstInstance) {
cmdBuffer->drawIndexedIndirect(indirectBuffer, item.first * indirectStride, item.count, indirectStride);
} else {
for (auto i = 0; i < item.count; i++) {
// Stanley TODO: bindDescriptorSet for cc_drawInstances with dynamicOffsets here.
cmdBuffer->drawIndexedIndirect(indirectBuffer, (item.first + i) * indirectStride, 1, indirectStride);
}
if (supportFirstInstance) {
cmdBuffer->drawIndexedIndirect(indirectBuffer, item.first * indirectStride, item.count, indirectStride);
} else {
for (auto i = 0; i < item.count; i++) {
// Stanley TODO: bindDescriptorSet for cc_drawInstances with dynamicOffsets here.
cmdBuffer->drawIndexedIndirect(indirectBuffer, (item.first + i) * indirectStride, 1, indirectStride);
}
}
}
Expand Down
13 changes: 8 additions & 5 deletions native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1457,7 +1457,7 @@ class Pipeline : public BasicPipeline {
* @param hzbName @en name of hierarchical z buffer @zh 层次深度缓存的名字
* @param light @en light of the culling pass @zh 剔除通道的灯光
*/
virtual void addBuiltinGpuCullingPass(uint32_t cullingID, const scene::Camera *camera, const std::string &layoutPath, const std::string &hzbName, const scene::Light *light, bool bMainPass) = 0;
virtual void addBuiltinGpuCullingPass(uint32_t cullingID, const scene::Camera *camera, const std::string &layoutPath, const std::string &hzbName, const scene::Light *light, uint32_t level, bool bMainPass) = 0;
/**
* @en Add hierarchical z buffer generation pass
* @zh 添加层次化深度缓存生成通道
Expand Down Expand Up @@ -1489,16 +1489,19 @@ class Pipeline : public BasicPipeline {
updateStorageTexture(name, width, height, gfx::Format::UNKNOWN);
}
void addBuiltinGpuCullingPass(uint32_t cullingID, const scene::Camera *camera) {
addBuiltinGpuCullingPass(cullingID, camera, "", "", nullptr, true);
addBuiltinGpuCullingPass(cullingID, camera, "", "", nullptr, 0, true);
}
void addBuiltinGpuCullingPass(uint32_t cullingID, const scene::Camera *camera, const std::string &layoutPath) {
addBuiltinGpuCullingPass(cullingID, camera, layoutPath, "", nullptr, true);
addBuiltinGpuCullingPass(cullingID, camera, layoutPath, "", nullptr, 0, true);
}
void addBuiltinGpuCullingPass(uint32_t cullingID, const scene::Camera *camera, const std::string &layoutPath, const std::string &hzbName) {
addBuiltinGpuCullingPass(cullingID, camera, layoutPath, hzbName, nullptr, true);
addBuiltinGpuCullingPass(cullingID, camera, layoutPath, hzbName, nullptr, 0, true);
}
void addBuiltinGpuCullingPass(uint32_t cullingID, const scene::Camera *camera, const std::string &layoutPath, const std::string &hzbName, const scene::Light *light) {
addBuiltinGpuCullingPass(cullingID, camera, layoutPath, hzbName, light, true);
addBuiltinGpuCullingPass(cullingID, camera, layoutPath, hzbName, light, 0, true);
}
void addBuiltinGpuCullingPass(uint32_t cullingID, const scene::Camera *camera, const std::string &layoutPath, const std::string &hzbName, const scene::Light *light, uint32_t level) {
addBuiltinGpuCullingPass(cullingID, camera, layoutPath, hzbName, light, level, true);
}
};

Expand Down
Loading

0 comments on commit 2e1f639

Please sign in to comment.