Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V3.8.4 pipeline reflection probe #17585

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cocos/rendering/custom/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,7 @@ class DeviceRenderScene implements RecordingInterface {
const renderQueueDesc = sceneCulling.renderQueueIndex.get(this.graphScene.sceneID)!;
const renderQueue = sceneCulling.renderQueues[renderQueueDesc.renderQueueTarget];
const graphSceneData = this.graphScene.scene!;
if (bool(graphSceneData.flags & SceneFlags.REFLECTION_PROBE)) renderQueue.probeQueue.applyMacro();
renderQueue.recordCommands(context.commandBuffer, this._renderPass);
if (bool(graphSceneData.flags & SceneFlags.REFLECTION_PROBE)) renderQueue.probeQueue.removeMacro();
if (graphSceneData.flags & SceneFlags.GEOMETRY) {
Expand Down
2 changes: 2 additions & 0 deletions cocos/rendering/custom/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
*/
/* eslint-disable max-len */
import type { AABB } from '../../core/geometry/aabb';
import type { Material } from '../../asset/assets';
import type { Camera } from '../../render-scene/scene/camera';
import type { DirectionalLight } from '../../render-scene/scene/directional-light';
Expand Down Expand Up @@ -480,6 +481,7 @@ export interface SceneBuilder extends Setter {
light: Light,
csmLevel?: number,
optCamera?: Camera): void;
setCullingWorldBounds (aabb: AABB): void;
}

/**
Expand Down
10 changes: 9 additions & 1 deletion cocos/rendering/custom/render-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
*/
/* eslint-disable max-len */
import { AdjI, AdjacencyGraph, BidirectionalGraph, ComponentGraph, ED, InEI, MutableGraph, MutableReferenceGraph, NamedGraph, OutE, OutEI, PolymorphicGraph, PropertyGraph, ReferenceGraph, UuidGraph, VertexListGraph } from './graph';
import type { AABB } from '../../core/geometry/aabb';
import type { Material } from '../../asset/assets';
import type { Camera } from '../../render-scene/scene/camera';
import type { Buffer, Framebuffer, RenderPass, Sampler, SamplerInfo, Swapchain, Texture } from '../../gfx';
Expand Down Expand Up @@ -990,6 +991,7 @@ export const enum CullingFlags {
CAMERA_FRUSTUM = 0x1,
LIGHT_FRUSTUM = 0x2,
LIGHT_BOUNDS = 0x4,
WORLD_BOUNDS = 0x8,
}

export class SceneData {
Expand All @@ -1000,34 +1002,39 @@ export class SceneData {
light: LightInfo = new LightInfo(),
cullingFlags: CullingFlags = CullingFlags.CAMERA_FRUSTUM,
shadingLight: Light | null = null,
worldBounds: AABB | null = null,
) {
this.scene = scene;
this.camera = camera;
this.light = light;
this.flags = flags;
this.cullingFlags = cullingFlags;
this.shadingLight = shadingLight;
this.worldBounds = worldBounds;
}
reset (
scene: RenderScene | null,
camera: Camera | null,
flags: SceneFlags,
cullingFlags: CullingFlags,
shadingLight: Light | null,
worldBounds: AABB | null,
): void {
this.scene = scene;
this.camera = camera;
this.light.reset(null, 0, false, null);
this.flags = flags;
this.cullingFlags = cullingFlags;
this.shadingLight = shadingLight;
this.worldBounds = worldBounds;
}
declare /*pointer*/ scene: RenderScene | null;
declare /*pointer*/ camera: Camera | null;
declare readonly light: LightInfo;
declare flags: SceneFlags;
declare cullingFlags: CullingFlags;
declare /*refcount*/ shadingLight: Light | null;
declare worldBounds: AABB | null;
}

export class Dispatch {
Expand Down Expand Up @@ -1722,9 +1729,10 @@ export class RenderGraphObjectPool {
flags: SceneFlags = SceneFlags.NONE,
cullingFlags: CullingFlags = CullingFlags.CAMERA_FRUSTUM,
shadingLight: Light | null = null,
worldBounds: AABB | null = null,
): SceneData {
const v = this.sd.add(); // SceneData
v.reset(scene, camera, flags, cullingFlags, shadingLight);
v.reset(scene, camera, flags, cullingFlags, shadingLight, worldBounds);
return v;
}
createDispatch (
Expand Down
67 changes: 39 additions & 28 deletions cocos/rendering/custom/scene-culling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CommandBuffer, Device, Buffer, BufferInfo, BufferViewInfo, MemoryUsageB
import { BatchingSchemes, Pass, RenderScene } from '../../render-scene';
import { CSMLevel, Camera, DirectionalLight, Light, LightType, Model, PointLight, ProbeType,
RangedDirectionalLight,
ReflectionProbe, SKYBOX_FLAG, ShadowType, Shadows, SphereLight, SpotLight } from '../../render-scene/scene';
SKYBOX_FLAG, ShadowType, Shadows, SphereLight, SpotLight } from '../../render-scene/scene';
import { Layers, Node } from '../../scene-graph';
import { PipelineSceneData } from '../pipeline-scene-data';
import { hashCombineStr, getSubpassOrPassID, bool, AlignUp, SetLightUBO } from './define';
Expand Down Expand Up @@ -40,7 +40,8 @@ function computeCullingKey (
const light = sceneData.light.light;
const lightLevel = sceneData.light.level;
const culledByLight = sceneData.light.culledByLight;
const reflectProbe = sceneData.light.probe;
const reflectProbe: boolean = !!(sceneData.flags & SceneFlags.REFLECTION_PROBE);
const worldBounds: boolean = !!(sceneData.cullingFlags & CullingFlags.WORLD_BOUNDS);
const shadeLight = sceneData.shadingLight;
if (camera) {
// camera
Expand Down Expand Up @@ -83,8 +84,9 @@ function computeCullingKey (
hashCode = hashCombineStr(`cast${castShadows}`, hashCode);
hashCode = hashCombineStr(`level${lightLevel}`, hashCode);
if (reflectProbe) {
hashCode = hashCombineStr(`probe${reflectProbe.getProbeId()}`, hashCode);
hashCode = hashCombineStr(`probe${reflectProbe}`, hashCode);
}
hashCode = hashCombineStr(`wb${worldBounds}`, hashCode);
hashCode = hashCombineStr(`refId${refId}`, hashCode);
return hashCode;
}
Expand Down Expand Up @@ -162,7 +164,7 @@ function isReflectProbeMask (model: Model): boolean {
}

const transWorldBounds = new AABB();
function isFrustumVisible (model: Model, frustum: Readonly<Frustum>, castShadow: boolean): boolean {
function isFrustumCulled (model: Model, frustum: Readonly<Frustum>, castShadow: boolean): boolean {
const modelWorldBounds = model.worldBounds;
if (!modelWorldBounds) {
return false;
Expand All @@ -175,7 +177,7 @@ function isFrustumVisible (model: Model, frustum: Readonly<Frustum>, castShadow:
return !intersect.aabbFrustum(transWorldBounds, frustum);
}

function isIntersectAABB (lAABB: AABB, rAABB: AABB): boolean {
function isAABBCulled (lAABB: AABB, rAABB: AABB): boolean {
return !intersect.aabbWithAABB(lAABB, rAABB);
}

Expand All @@ -184,12 +186,13 @@ function sceneCulling (
camera: Camera,
camOrLightFrustum: Readonly<Frustum>,
castShadow: boolean,
probe: ReflectionProbe | null,
probePass: boolean,
models: Array<Model>,
worldBounds: AABB | null,
): void {
const skybox = pSceneData.skybox;
const skyboxModel = skybox.model;
const visibility = camera.visibility;
const visibility = probePass ? REFLECTION_PROBE_DEFAULT_MASK : camera.visibility;
const camSkyboxFlag = camera.clearFlag & SKYBOX_FLAG;
if (!castShadow && skybox && skybox.enabled && skyboxModel && camSkyboxFlag) {
models.push(skyboxModel);
Expand All @@ -203,21 +206,33 @@ function sceneCulling (
if (scene && scene.isCulledByLod(camera, model)) {
continue;
}
if (!probe || (probe && probe.probeType === ProbeType.CUBE)) {
if (isNodeVisible(model.node, visibility)
|| isModelVisible(model, visibility)) {
const wBounds = model.worldBounds;
// frustum culling
if (wBounds && ((!probe && isFrustumVisible(model, camOrLightFrustum, castShadow))
|| (probe && isIntersectAABB(wBounds, probe.boundingBox!)))) {
if (!isNodeVisible(model.node, visibility) && !isModelVisible(model, visibility)) {
continue;
}
const wBounds = model.worldBounds;
if (!wBounds) {
continue;
}
if (probePass) {
if (!model.bakeToReflectionProbe) {
continue;
}
if (worldBounds) {
if (isAABBCulled(wBounds, worldBounds)) {
continue;
}

models.push(model);
} else if (isFrustumCulled(model, camOrLightFrustum, castShadow)) {
continue;
}
} else {
if (isFrustumCulled(model, camOrLightFrustum, castShadow)) {
continue;
}
if (worldBounds && isAABBCulled(wBounds, worldBounds)) {
continue;
}
} else if (isReflectProbeMask(model)) {
models.push(model);
}
models.push(model);
}
}

Expand Down Expand Up @@ -254,7 +269,7 @@ function addRenderObject (
): void {
const probeQueue = queue.probeQueue;
if (isDrawProbe) {
probeQueue.applyMacro(model, phaseLayoutId);
probeQueue.addToProbeQueue(model, phaseLayoutId);
}
const subModels = model.subModels;
const subModelCount = subModels.length;
Expand Down Expand Up @@ -518,28 +533,24 @@ export class SceneCulling {
const light = sceneData.light.light;
const level = sceneData.light.level;
const castShadow = cullingKey.castShadows;
const probe = sceneData.light.probe;
const camera = probe ? probe.camera : sceneData.camera;
const probePass = !!(sceneData.flags & SceneFlags.REFLECTION_PROBE);
const camera = sceneData.camera;
assert(frustomCulledResultID < this.frustumCullingResults.length);
const models = this.frustumCullingResults[frustomCulledResultID];
if (probe) {
sceneCulling(scene, camera, camera.frustum, castShadow, probe, models);
continue;
}
if (light) {
switch (light.type) {
case LightType.SPOT:
sceneCulling(scene, camera, (light as SpotLight).frustum, castShadow, null, models);
sceneCulling(scene, camera, (light as SpotLight).frustum, castShadow, probePass, models, sceneData.worldBounds);
break;
case LightType.DIRECTIONAL: {
const frustum = this.getBuiltinShadowFrustum(pplSceneData, camera, light as DirectionalLight, level);
sceneCulling(scene, camera, frustum, castShadow, null, models);
sceneCulling(scene, camera, frustum, castShadow, probePass, models, sceneData.worldBounds);
}
break;
default:
}
} else {
sceneCulling(scene, camera, camera.frustum, castShadow, null, models);
sceneCulling(scene, camera, camera.frustum, castShadow, probePass, models, sceneData.worldBounds);
}
}
}
Expand Down
20 changes: 12 additions & 8 deletions cocos/rendering/custom/web-pipeline-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,17 @@ export class ProbeHelperQueue {
this.probeMap.length = 0;
}

applyMacro (): void {
for (const subModel of this.probeMap) {
let patches: IMacroPatch[] = [
{ name: CC_USE_RGBE_OUTPUT, value: true },
];
if (subModel.patches) {
patches = patches.concat(subModel.patches);
}
subModel.onMacroPatchesStateChanged(patches);
}
}
removeMacro (): void {
for (const subModel of this.probeMap) {
if (!subModel.patches) continue;
Expand All @@ -238,7 +249,7 @@ export class ProbeHelperQueue {
}
}
}
applyMacro (model: Model, probeLayoutId: number): void {
addToProbeQueue (model: Model, probeLayoutId: number): void {
const subModels = model.subModels;
for (let j = 0; j < subModels.length; j++) {
const subModel: SubModel = subModels[j];
Expand All @@ -258,13 +269,6 @@ export class ProbeHelperQueue {
}
if (passIdx < 0) { continue; }
if (!bUseReflectPass) {
let patches: IMacroPatch[] = [];
patches = patches.concat(subModel.patches!);
const useRGBEPatchs: IMacroPatch[] = [
{ name: CC_USE_RGBE_OUTPUT, value: true },
];
patches = patches.concat(useRGBEPatchs);
subModel.onMacroPatchesStateChanged(patches);
this.probeMap.push(subModel);
}
}
Expand Down
5 changes: 5 additions & 0 deletions cocos/rendering/custom/web-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import { Director } from '../../game';
import { ReflectionProbeManager } from '../../3d';
import { legacyCC } from '../../core/global-exports';
import { WebSetter, setCameraUBOValues, setShadowUBOLightView, setShadowUBOView, setTextureUBOView } from './web-pipeline-types';
import { AABB } from '../../core/geometry/aabb';

const _uboVec = new Vec4();
const _samplerPointInfo = new SamplerInfo(
Expand Down Expand Up @@ -221,6 +222,10 @@ export class WebSceneBuilder extends WebSetter implements SceneBuilder {
const layoutName = this._renderGraph.getLayout(passId);
setShadowUBOLightView(this, this._scene.camera, light, csmLevel, layoutName);
}
setCullingWorldBounds (aabb: AABB): void {
this._scene.cullingFlags |= CullingFlags.WORLD_BOUNDS;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Use bitwise OR to add WORLD_BOUNDS flag

this._scene.worldBounds = aabb;
}
private _renderGraph: RenderGraph;
private _scene: SceneData;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ export class BuiltinPipelineSettings extends Component {
group: { id: 'Bloom', name: 'Bloom (PostProcessing)', style: 'section' },
type: CCFloat,
min: 0,
step: 0.01,
})
set bloomThreshold(value: number) {
this._settings.bloom.threshold = value;
Expand All @@ -332,6 +333,7 @@ export class BuiltinPipelineSettings extends Component {
group: { id: 'Bloom', name: 'Bloom (PostProcessing)', style: 'section' },
type: CCFloat,
min: 0,
visible: false,
})
set bloomIntensity(value: number) {
this._settings.bloom.intensity = value;
Expand Down
16 changes: 13 additions & 3 deletions editor/assets/default_renderpipeline/builtin-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ class CameraConfigs {
enableFXAA = false;
enableFSR = false;
enableHDR = false;
enablePlanarReflectionProbe = false;
useFullPipeline = false;
singleForwardRadiancePass = false;
radianceFormat = gfx.Format.RGBA8;
Expand Down Expand Up @@ -212,6 +213,8 @@ function setupCameraConfigs(
&& !!camera.scene.mainLight
&& camera.scene.mainLight.shadowEnabled;

cameraConfigs.enablePlanarReflectionProbe = isMainGameWindow || camera.cameraUsage === CameraUsage.SCENE_VIEW;

cameraConfigs.enableProfiler = DEBUG && isMainGameWindow;

cameraConfigs.settings = camera.pipelineSettings
Expand Down Expand Up @@ -1437,7 +1440,8 @@ if (rendering) {
colorName: string,
depthStencilName: string,
mainLight: renderer.scene.DirectionalLight | null,
scene: renderer.RenderScene | null = null,
scene: renderer.RenderScene | null,
probe?: renderer.scene.ReflectionProbe,
): void {
// set viewport
const colorStoreOp = this._cameraConfigs.enableMSAA ? StoreOp.DISCARD : StoreOp.STORE;
Expand Down Expand Up @@ -1479,11 +1483,14 @@ if (rendering) {
// TODO(zhouzhenglong): Separate OPAQUE and MASK queue

// add opaque and mask queue
pass.addQueue(QueueHint.NONE, 'reflect-map') // Currently we put OPAQUE and MASK into one queue, so QueueHint is NONE
const builder = pass.addQueue(QueueHint.NONE, 'reflect-map') // Currently we put OPAQUE and MASK into one queue, so QueueHint is NONE
.addScene(camera,
SceneFlags.OPAQUE | SceneFlags.MASK | SceneFlags.REFLECTION_PROBE,
mainLight || undefined,
scene ? scene : undefined);
if (probe) {
builder.setCullingWorldBounds(probe.boundingBox);
}
}

private _tryAddReflectionProbePasses(ppl: rendering.BasicPipeline, id: number,
Expand All @@ -1506,6 +1513,9 @@ if (rendering) {
const height = Math.max(Math.floor(area.y), 1);

if (probe.probeType === renderer.scene.ProbeType.PLANAR) {
if (!this._cameraConfigs.enablePlanarReflectionProbe) {
continue;
}
const window: renderer.RenderWindow = probe.realtimePlanarTexture!.window!;
const colorName = `PlanarProbeRT${probeID}`;
const depthStencilName = `PlanarProbeDS${probeID}`;
Expand Down Expand Up @@ -1536,7 +1546,7 @@ if (rendering) {
const probePass = ppl.addRenderPass(width, height, 'default');
probePass.name = `CubeProbe${probeID}${faceIdx}`;
this._buildReflectionProbePass(probePass, id, probe.camera,
colorName, depthStencilName, mainLight, scene);
colorName, depthStencilName, mainLight, scene, probe);
}
probe.needRender = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ class NativeSceneBuilder final : public SceneBuilder, public NativeSetter {
}

void useLightFrustum(IntrusivePtr<scene::Light> light, uint32_t csmLevel, const scene::Camera *optCamera) override;
void setCullingWorldBounds(const geometry::AABB &aabb) override;
};

class NativeRenderSubpassBuilderImpl : public NativeSetter {
Expand Down
Loading
Loading