Skip to content

Commit

Permalink
Merge pull request #167 from GengineJS/v3.8.1-pipeline-0820
Browse files Browse the repository at this point in the history
Complete reflection probes for the native new pipeline
  • Loading branch information
star-e authored Aug 30, 2023
2 parents cee296c + 749bc15 commit f565651
Show file tree
Hide file tree
Showing 13 changed files with 327 additions and 89 deletions.
58 changes: 43 additions & 15 deletions cocos/rendering/custom/custom-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,21 @@ export class TestPipelineBuilder implements PipelineBuilder {
ppl.update(camera);
const info = this.prepareGameCamera(ppl, camera);
this.prepareSceneInfo(camera.scene, camera.frustum, this._sceneInfo);
this.buildForward(ppl, camera,
info.id, info.width, info.height);
this.buildForward(
ppl,
camera,
info.id,
info.width,
info.height,
);
}
}
// implementation
private prepareSceneInfo (scene: Readonly<RenderScene>,
private prepareSceneInfo (
scene: Readonly<RenderScene>,
frustum: geometry.Frustum,
sceneInfo: SceneInfo): void {
sceneInfo: SceneInfo,
): void {
// clear scene info
sceneInfo.reset();
// spot lights
Expand Down Expand Up @@ -259,9 +266,14 @@ export class TestPipelineBuilder implements PipelineBuilder {
ppl.updateDepthStencil(`SpotLightShadowDepth${id}2`, shadowSize.x, shadowSize.y);
ppl.updateDepthStencil(`SpotLightShadowDepth${id}3`, shadowSize.x, shadowSize.y);
}
private buildForwardTiled (ppl: BasicPipeline,
camera: Camera, id: number, width: number, height: number,
sceneInfo: SceneInfo): void {
private buildForwardTiled (
ppl: BasicPipeline,
camera: Camera,
id: number,
width: number,
height: number,
sceneInfo: SceneInfo,
): void {
assert(this._tiled);
assert(camera.scene !== null);
// init
Expand All @@ -288,8 +300,13 @@ export class TestPipelineBuilder implements PipelineBuilder {
.addSceneOfCamera(camera, new LightInfo(), SceneFlags.BLEND);
}
}
private buildForward (ppl: BasicPipeline,
camera: Camera, id: number, width: number, height: number): void {
private buildForward (
ppl: BasicPipeline,
camera: Camera,
id: number,
width: number,
height: number,
): void {
assert(camera.scene !== null);
if (camera.scene === null) {
return;
Expand Down Expand Up @@ -325,8 +342,11 @@ export class TestPipelineBuilder implements PipelineBuilder {
// queue.addSceneCulledByDirectionalLight(camera,
// SceneFlags.OPAQUE | SceneFlags.MASK | SceneFlags.SHADOW_CASTER,
// light, 0);
queue.addSceneOfCamera(camera, new LightInfo(light, 0),
SceneFlags.OPAQUE | SceneFlags.MASK | SceneFlags.SHADOW_CASTER);
queue.addSceneOfCamera(
camera,
new LightInfo(light, 0),
SceneFlags.OPAQUE | SceneFlags.MASK | SceneFlags.SHADOW_CASTER,
);
} else {
const csmLevel = ppl.pipelineSceneData.csmSupported
? light.csmLevel : 1;
Expand All @@ -337,8 +357,11 @@ export class TestPipelineBuilder implements PipelineBuilder {
// queue.addSceneCulledByDirectionalLight(camera,
// SceneFlags.OPAQUE | SceneFlags.MASK | SceneFlags.SHADOW_CASTER,
// light, level);
queue.addSceneOfCamera(camera, new LightInfo(light, level),
SceneFlags.OPAQUE | SceneFlags.MASK | SceneFlags.SHADOW_CASTER);
queue.addSceneOfCamera(
camera,
new LightInfo(light, level),
SceneFlags.OPAQUE | SceneFlags.MASK | SceneFlags.SHADOW_CASTER,
);
}
}
}
Expand All @@ -352,8 +375,13 @@ export class TestPipelineBuilder implements PipelineBuilder {
vp.width = Math.max(1, vp.width);
vp.height = Math.max(1, vp.height);
}
private getMainLightViewport (light: DirectionalLight, w: number, h: number, level: number,
vp: Viewport): void {
private getMainLightViewport (
light: DirectionalLight,
w: number,
h: number,
level: number,
vp: Viewport,
): void {
if (light.shadowFixedArea || light.csmLevel === CSMLevel.LEVEL_1) {
vp.left = 0;
vp.top = 0;
Expand Down
1 change: 1 addition & 0 deletions cocos/rendering/custom/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ import {
getRenderArea,
mergeSrcToTargetDesc,
updateGlobalDescBinding,
validPunctualLightsCulling,
} from './define';
import { RenderReflectionProbeQueue } from '../render-reflection-probe-queue';
import { SceneCulling } from './scene-culling';
Expand Down
2 changes: 1 addition & 1 deletion cocos/rendering/custom/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ export interface BasicPipeline extends PipelineRuntime {
* @param copyPairs @en Array of copy source and target @zh 拷贝来源与目标的数组
*/
addCopyPass (copyPairs: CopyPair[]): void;
addBuiltinReflectionProbePass (width: number, height: number): void;
addBuiltinReflectionProbePass (width: number, height: number, camera: Camera): void;
/**
* @engineInternal
*/
Expand Down
29 changes: 24 additions & 5 deletions cocos/rendering/custom/web-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@

/* eslint-disable max-len */
import { systemInfo } from 'pal/system-info';
import { DEBUG } from 'internal:constants';
import { DEBUG, EDITOR } from 'internal:constants';
import { Buffer, DescriptorSetLayout, Device, Feature, Format, FormatFeatureBit, Sampler, Swapchain, Texture, ClearFlagBit, DescriptorSet, deviceManager, Viewport, API, CommandBuffer, Type, SamplerInfo, Filter, Address, DescriptorSetInfo, LoadOp, StoreOp, ShaderStageFlagBit, BufferInfo, TextureInfo, TextureType, UniformBlock, ResolveMode, SampleCount, Color } from '../../gfx';
import { Mat4, Quat, toRadian, Vec2, Vec3, Vec4, assert, macro, cclegacy, IVec4Like, IMat4Like, IVec2Like, Color as CoreColor } from '../../core';
import { AccessType, AttachmentType, CopyPair, LightInfo, LightingMode, MovePair, QueueHint, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UpdateFrequency } from './types';
import { ComputeView, RasterView, Blit, ClearView, ComputePass, CopyPass, Dispatch, ManagedBuffer, ManagedResource, MovePass, RasterPass, RasterSubpass, RenderData, RenderGraph, RenderGraphComponent, RenderGraphValue, RenderQueue, RenderSwapchain, ResourceDesc, ResourceGraph, ResourceGraphValue, ResourceStates, ResourceTraits, SceneData, Subpass } from './render-graph';
import { ComputePassBuilder, ComputeQueueBuilder, ComputeSubpassBuilder, BasicPipeline, PipelineBuilder, RenderPassBuilder, RenderQueueBuilder, RenderSubpassBuilder, PipelineType, BasicRenderPassBuilder, PipelineCapabilities, BasicMultisampleRenderPassBuilder } from './pipeline';
import { PipelineSceneData } from '../pipeline-scene-data';
import { Model, Camera, ShadowType, CSMLevel, DirectionalLight, SpotLight, PCFType, Shadows, SphereLight, PointLight, RangedDirectionalLight } from '../../render-scene/scene';
import { Model, Camera, ShadowType, CSMLevel, DirectionalLight, SpotLight, PCFType, Shadows, SphereLight, PointLight, RangedDirectionalLight, ProbeType } from '../../render-scene/scene';
import { Light, LightType } from '../../render-scene/scene/light';
import { DescriptorSetData, DescriptorSetLayoutData, LayoutGraphData } from './layout-graph';
import { Executor } from './executor';
Expand All @@ -51,12 +51,13 @@ import { CustomPipelineBuilder } from './custom-pipeline';
import { decideProfilerCamera } from '../pipeline-funcs';
import { DebugViewCompositeType } from '../debug-view';
import { getUBOTypeCount } from './utils';
import { initGlobalDescBinding } from './define';
import { buildReflectionProbePass, initGlobalDescBinding } from './define';
import { createGfxDescriptorSetsAndPipelines } from './layout-graph-utils';
import { Root } from '../../root';
import { CSMLayers, CSMShadowLayer } from '../shadow/csm-layers';
import { Scene } from '../../scene-graph';
import { Director } from '../../game';
import { ReflectionProbeManager } from '../../3d';

const _uboVec = new Vec4();
const _uboVec3 = new Vec3();
Expand Down Expand Up @@ -2011,8 +2012,26 @@ export class WebPipeline implements BasicPipeline {
this.execute();
this.endFrame();
}
addBuiltinReflectionProbePass (width: number, height: number): void {
// TODO
addBuiltinReflectionProbePass (width: number, height: number, camera: Camera): void {
const reflectionProbeManager = cclegacy.internal.reflectionProbeManager as ReflectionProbeManager;
if (!reflectionProbeManager) return;
const probes = reflectionProbeManager.getProbes();
if (probes.length === 0) return;
for (let i = 0; i < probes.length; i++) {
const probe = probes[i];
if (probe.needRender) {
if (probes[i].probeType === ProbeType.PLANAR) {
buildReflectionProbePass(camera, this, probe, probe.realtimePlanarTexture!.window!, 0);
} else if (EDITOR) {
for (let faceIdx = 0; faceIdx < probe.bakedCubeTextures.length; faceIdx++) {
probe.updateCameraDir(faceIdx);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
buildReflectionProbePass(camera, this, probe, probe.bakedCubeTextures[faceIdx].window!, faceIdx);
}
probe.needRender = false;
}
}
}
}
addRenderPassImpl (width: number, height: number, layoutName: string, count = 1, quality = 0): BasicMultisampleRenderPassBuilder {
if (DEBUG) {
Expand Down
2 changes: 1 addition & 1 deletion cocos/rendering/post-process/post-process-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export class PostProcessBuilder implements PipelineBuilder {
this.applyPreviewCamera(camera);
}

buildReflectionProbePasss(camera, ppl);
ppl.addBuiltinReflectionProbePass(0, 0, camera);

passContext.postProcess = camera.postProcess || globalPP;

Expand Down
3 changes: 3 additions & 0 deletions native/cocos/renderer/pipeline/custom/NativeExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,9 @@ struct RenderGraphVisitor : boost::dfs_visitor<> {
ctx.device, camera, ctx.currentPass, ctx.cmdBuff, 0);
queue.transparentInstancingQueue.recordCommandBuffer(
ctx.currentPass, ctx.cmdBuff);
if(any(sceneData.flags & SceneFlags::REFLECTION_PROBE)) {
queue.probeQueue.removeMacro();
}
if (any(sceneData.flags & SceneFlags::UI)) {
submitUICommands(ctx.currentPass,
ctx.currentPassLayoutID, camera, ctx.cmdBuff);
Expand Down
90 changes: 87 additions & 3 deletions native/cocos/renderer/pipeline/custom/NativePipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "cocos/renderer/pipeline/custom/details/GslUtils.h"
#include "cocos/scene/RenderScene.h"
#include "cocos/scene/RenderWindow.h"
#include "cocos/scene/ReflectionProbeManager.h"
#if CC_USE_DEBUG_RENDERER
#include "profiler/DebugRenderer.h"
#endif
Expand Down Expand Up @@ -677,10 +678,93 @@ void NativePipeline::endFrame() {
// noop
}

namespace {

gfx::LoadOp getLoadOpOfClearFlag(gfx::ClearFlagBit clearFlag, AttachmentType attachment) {
gfx::LoadOp loadOp = gfx::LoadOp::CLEAR;
if (!(clearFlag & gfx::ClearFlagBit::COLOR) && attachment == AttachmentType::RENDER_TARGET) {
if (static_cast<uint32_t>(clearFlag) & cc::scene::Camera::SKYBOX_FLAG) {
loadOp = gfx::LoadOp::CLEAR;
} else {
loadOp = gfx::LoadOp::LOAD;
}
}
if ((clearFlag & gfx::ClearFlagBit::DEPTH_STENCIL) != gfx::ClearFlagBit::DEPTH_STENCIL && attachment == AttachmentType::DEPTH_STENCIL) {
if (!(clearFlag & gfx::ClearFlagBit::DEPTH)) {
loadOp = gfx::LoadOp::LOAD;
}
if (!(clearFlag & gfx::ClearFlagBit::STENCIL)) {
loadOp = gfx::LoadOp::LOAD;
}
}
return loadOp;
}
void updateCameraUBO(Setter &setter, const scene::Camera *camera, NativePipeline &ppl) {
auto sceneData = ppl.pipelineSceneData;
auto* skybox = sceneData->getSkybox();
setter.setBuiltinCameraConstants(camera);

}
void buildReflectionProbePass(const scene::Camera *camera,
render::NativePipeline *pipeline,
const scene::ReflectionProbe *probe,
scene::RenderWindow *renderWindow,
int faceIdx) {
const std::string cameraName = "Camera" + std::to_string(faceIdx);
const auto &area = probe->renderArea();
int width = area.x;
int height = area.y;
const auto *probeCamera = probe->getCamera();
const std::string probePassRTName = "reflectionProbePassColor" + cameraName;
const std::string probePassDSName = "reflectionProbePassDS" + cameraName;
if (!pipeline->containsResource(probePassRTName)) {
pipeline->addRenderWindow(probePassRTName, gfx::Format::RGBA8, width, height, renderWindow);
pipeline->addDepthStencil(probePassDSName, gfx::Format::DEPTH_STENCIL, width, height, ResourceResidency::EXTERNAL);
}
pipeline->updateRenderWindow(probePassRTName, renderWindow);
pipeline->updateDepthStencil(probePassDSName, width, height, gfx::Format::DEPTH_STENCIL);
auto *passBuilder = pipeline->addRenderPass(width, height, "default");
passBuilder->setName("ReflectionProbePass"+faceIdx);
gfx::Viewport currViewport{};
currViewport.width = width;
currViewport.height = height;
passBuilder->setViewport(currViewport);
gfx::Color clearColor{};
clearColor.x = probeCamera->getClearColor().x;
clearColor.y = probeCamera->getClearColor().y;
clearColor.z = probeCamera->getClearColor().z;
clearColor.w = probeCamera->getClearColor().w;
passBuilder->addRenderTarget(probePassRTName,
getLoadOpOfClearFlag(probeCamera->getClearFlag(), AttachmentType::RENDER_TARGET),
gfx::StoreOp::STORE,
clearColor);
passBuilder->addDepthStencil(probePassDSName,
getLoadOpOfClearFlag(probeCamera->getClearFlag(), AttachmentType::DEPTH_STENCIL),
gfx::StoreOp::STORE,
probeCamera->getClearDepth(),
probeCamera->getClearStencil(),
probeCamera->getClearFlag());
auto* queueBuilder = passBuilder->addQueue(QueueHint::RENDER_OPAQUE, "reflect-map");
LightInfo lightInfo{};
lightInfo.probe = const_cast<scene::ReflectionProbe*>(probe);
queueBuilder->addSceneOfCamera(const_cast<scene::Camera *>(camera), lightInfo, SceneFlags::REFLECTION_PROBE | SceneFlags::OPAQUE_OBJECT);
updateCameraUBO(*queueBuilder, probeCamera, *pipeline);
}

} // namespace

void NativePipeline::addBuiltinReflectionProbePass(
uint32_t width, uint32_t height) {
std::ignore = width;
std::ignore = height;
uint32_t width, uint32_t height, const scene::Camera *camera) {
const auto* reflectProbeManager = scene::ReflectionProbeManager::getInstance();
if (!reflectProbeManager) return;
const auto &probes = reflectProbeManager->getAllProbes();
for (auto* probe : probes) {
if (probe->needRender()) {
if (probe->getProbeType() == scene::ReflectionProbe::ProbeType::PLANAR) {
buildReflectionProbePass(camera, this, probe, probe->getRealtimePlanarTexture()->getWindow(), 0);
}
}
}
}

RenderPassBuilder *NativePipeline::addRenderPass(
Expand Down
59 changes: 59 additions & 0 deletions native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,65 @@ PipelineCustomization::PipelineCustomization(PipelineCustomization const& rhs, c
renderQueues(rhs.renderQueues, alloc),
renderCommands(rhs.renderCommands, alloc) {}

void ProbeHelperQueue::removeMacro() const
{
for (auto* subModel : probeMap) {
std::vector<cc::scene::IMacroPatch> patches;
patches.insert(patches.end(), subModel->getPatches().begin(), subModel->getPatches().end());

for (size_t j = 0; j < patches.size(); ++j) {
const cc::scene::IMacroPatch& patch = patches[j];
if (patch.name == "CC_USE_RGBE_OUTPUT") {
patches.erase(patches.begin() + j);
break;
}
}

subModel->onMacroPatchesStateChanged(patches);
}
}

int ProbeHelperQueue::getPassIndexFromLayout(const cc::IntrusivePtr<cc::scene::SubModel>& subModel, int phaseLayoutId)
{
const auto& passes = subModel->getPasses();
for (size_t k = 0; k < passes->size(); ++k) {
if (passes->at(k)->getPhaseID() == phaseLayoutId) {
return static_cast<int>(k);
}
}
return -1;
}

void ProbeHelperQueue::applyMacro(const LayoutGraphData & lg, const cc::scene::Model & model, int probeLayoutId)
{
const std::vector<cc::IntrusivePtr<cc::scene::SubModel>>& subModels = model.getSubModels();
for (const auto& subModel : subModels) {
const bool isTransparent = subModel->getPasses()->at(0)->getBlendState()->targets[0].blend;
if (isTransparent) {
continue;
}

int passIdx = getPassIndexFromLayout(subModel, probeLayoutId);
bool bUseReflectPass = true;
if (passIdx < 0) {
probeLayoutId = getDefaultId(lg);
passIdx = getPassIndexFromLayout(subModel, probeLayoutId);
bUseReflectPass = false;
}
if (passIdx < 0) {
continue;
}
if (!bUseReflectPass) {
std::vector<cc::scene::IMacroPatch> patches;
patches.insert(patches.end(), subModel->getPatches().begin(), subModel->getPatches().end());
const cc::scene::IMacroPatch useRGBEPatch = {"CC_USE_RGBE_OUTPUT", true};
patches.emplace_back(useRGBEPatch);
subModel->onMacroPatchesStateChanged(patches);
probeMap.emplace_back(subModel);
}
}
}

} // namespace render

} // namespace cc
Expand Down
Loading

0 comments on commit f565651

Please sign in to comment.