From 9fc62b41af073328f99c0af694e039056290d8b2 Mon Sep 17 00:00:00 2001 From: GengineJS <476393671@qq.com> Date: Fri, 15 Sep 2023 14:52:48 +0800 Subject: [PATCH] [Added] new pipeline setter's light interface --- cocos/rendering/custom/web-pipeline.ts | 216 +++++++++++++++--- .../renderer/pipeline/custom/NativeSetter.cpp | 88 +++++++ 2 files changed, 274 insertions(+), 30 deletions(-) diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index f1fe7cb129c..def592d42a2 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -146,7 +146,7 @@ export class WebSetter implements Setter { const block: string = this._currBlock; const nodeId = this._lg.locateChild(0xFFFFFFFF, this._currStage); const ppl = this._lg.getLayout(nodeId); - const layout = ppl.descriptorSets.get(UpdateFrequency.PER_PASS)!.descriptorSetLayoutData; + const layout = ppl.descriptorSets.get(this._currFrequency)!.descriptorSetLayoutData; const nameID: number = this._lg.attributeIndex.get(block)!; return layout.uniformBlocks.get(nameID); } @@ -154,7 +154,7 @@ export class WebSetter implements Setter { protected _getCurrDescSetLayoutData (): DescriptorSetLayoutData { const nodeId = this._lg.locateChild(0xFFFFFFFF, this._currStage); const ppl = this._lg.getLayout(nodeId); - const layout = ppl.descriptorSets.get(UpdateFrequency.PER_PASS)!.descriptorSetLayoutData; + const layout = ppl.descriptorSets.get(this._currFrequency)!.descriptorSetLayoutData; return layout; } @@ -171,9 +171,10 @@ export class WebSetter implements Setter { return -1; } - setCurrConstant (block: string, stage = 'default'): boolean { + setCurrConstant (block: string, stage = 'default', frequency: UpdateFrequency = UpdateFrequency.PER_PASS): boolean { this._currBlock = block; this._currStage = stage; + this._currFrequency = frequency; const nameID: number = this._lg.attributeIndex.get(block)!; this._currCount = 0; const currBlock = this._getCurrUniformBlock(); @@ -189,9 +190,10 @@ export class WebSetter implements Setter { return this._currConstant; } - public addConstant (block: string, stage = 'default'): boolean { + public addConstant (block: string, stage = 'default', frequency: UpdateFrequency = UpdateFrequency.PER_PASS): boolean { this._currBlock = block; this._currStage = stage; + this._currFrequency = frequency; const num = this._lg.attributeIndex.get(block)!; this._currCount = 0; const currBlock = this._getCurrUniformBlock(); @@ -269,32 +271,195 @@ export class WebSetter implements Setter { const num = this._lg.attributeIndex.get(name)!; this._data.samplers.set(num, sampler); } + + public getParentLayout (): string { + const director = cclegacy.director; + const root = director.root; + const pipeline = root.pipeline as WebPipeline; + const parId = pipeline.renderGraph!.getParent(this._vertID); + const layoutName = pipeline.renderGraph!.getLayout(parId); + return layoutName; + } + + public getCurrentLayout (): string { + const director = cclegacy.director; + const root = director.root; + const pipeline = root.pipeline as WebPipeline; + const layoutName = pipeline.renderGraph!.getLayout(this._vertID); + return layoutName; + } + public setBuiltinCameraConstants (camera: Camera): void { - // TODO + const director = cclegacy.director; + const root = director.root; + const pipeline = root.pipeline as WebPipeline; + const layoutName = this.getParentLayout(); + setCameraUBOValues(this, camera, pipeline.pipelineSceneData, camera.scene, layoutName); } public setBuiltinShadowMapConstants (light: Light, numLevels?: number): void { - // TODO + setShadowUBOView(this, null, this.getParentLayout()); } public setBuiltinDirectionalLightFrustumConstants (camera: Camera, light: DirectionalLight, csmLevel = 0): void { setShadowUBOLightView(this, camera, light, csmLevel); } public setBuiltinSpotLightFrustumConstants (light: SpotLight): void { - // TODO + setShadowUBOLightView(this, null, light, 0); } public setBuiltinDirectionalLightConstants (light: DirectionalLight, camera: Camera): void { // TODO } public setBuiltinSphereLightConstants (light: SphereLight, camera: Camera): void { - // TODO + const director = cclegacy.director; + const pipeline = (director.root as Root).pipeline; + const sceneData = pipeline.pipelineSceneData; + if (!this.addConstant('CCForwardLight', this.getParentLayout(), UpdateFrequency.PER_BATCH)) return; + uniformOffset = this.getUniformOffset('cc_lightPos', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.position.x, light.position.y, light.position.z, LightType.SPHERE); + this.offsetVec4(_uboVec, uniformOffset); + } + uniformOffset = this.getUniformOffset('cc_lightSizeRangeAngle', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.size, light.range, 0.0, 0.0); + this.offsetVec4(_uboVec, uniformOffset); + } + const isHDR = sceneData.isHDR; + const lightMeterScale = 10000.0; + uniformOffset = this.getUniformOffset('cc_lightColor', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.color.x, light.color.y, light.color.z, 0); + if (light.useColorTemperature) { + const finalColor = light.finalColor; + _uboVec.x = finalColor.x; + _uboVec.y = finalColor.y; + _uboVec.z = finalColor.z; + } + if (isHDR) { + _uboVec.w = (light).luminance * camera.exposure * lightMeterScale; + } else { + _uboVec.w = (light).luminance; + } + this.offsetVec4(_uboVec, uniformOffset); + } } public setBuiltinSpotLightConstants (light: SpotLight, camera: Camera): void { - // TODO + const director = cclegacy.director; + const pipeline = (director.root as Root).pipeline; + const sceneData = pipeline.pipelineSceneData; + + const shadowInfo = sceneData.shadows; + if (!this.addConstant('CCForwardLight', this.getParentLayout(), UpdateFrequency.PER_BATCH)) return; + uniformOffset = this.getUniformOffset('cc_lightPos', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.position.x, light.position.y, light.position.z, LightType.SPOT); + this.offsetVec4(_uboVec, uniformOffset); + } + uniformOffset = this.getUniformOffset('cc_lightSizeRangeAngle', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.size, light.range, light.spotAngle, (shadowInfo.enabled && light.shadowEnabled && shadowInfo.type === ShadowType.ShadowMap) ? 1 : 0); + this.offsetVec4(_uboVec, uniformOffset); + } + uniformOffset = this.getUniformOffset('cc_lightDir', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.direction.x, light.direction.y, light.direction.z, 0); + this.offsetVec4(_uboVec, uniformOffset); + } + const isHDR = sceneData.isHDR; + const lightMeterScale = 10000.0; + uniformOffset = this.getUniformOffset('cc_lightColor', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.color.x, light.color.y, light.color.z, 0); + if (light.useColorTemperature) { + const finalColor = light.finalColor; + _uboVec.x = finalColor.x; + _uboVec.y = finalColor.y; + _uboVec.z = finalColor.z; + } + if (isHDR) { + _uboVec.w = (light).luminance * camera.exposure * lightMeterScale; + } else { + _uboVec.w = (light).luminance; + } + this.offsetVec4(_uboVec, uniformOffset); + } } public setBuiltinPointLightConstants (light: PointLight, camera: Camera): void { - // TODO + const director = cclegacy.director; + const pipeline = (director.root as Root).pipeline; + const sceneData = pipeline.pipelineSceneData; + if (!this.addConstant('CCForwardLight', this.getParentLayout(), UpdateFrequency.PER_BATCH)) return; + uniformOffset = this.getUniformOffset('cc_lightPos', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.position.x, light.position.y, light.position.z, LightType.POINT); + this.offsetVec4(_uboVec, uniformOffset); + } + uniformOffset = this.getUniformOffset('cc_lightSizeRangeAngle', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(0.0, light.range, 0.0, 0.0); + this.offsetVec4(_uboVec, uniformOffset); + } + const isHDR = sceneData.isHDR; + const lightMeterScale = 10000.0; + uniformOffset = this.getUniformOffset('cc_lightColor', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.color.x, light.color.y, light.color.z, 0); + if (light.useColorTemperature) { + const finalColor = light.finalColor; + _uboVec.x = finalColor.x; + _uboVec.y = finalColor.y; + _uboVec.z = finalColor.z; + } + if (isHDR) { + _uboVec.w = (light).luminance * camera.exposure * lightMeterScale; + } else { + _uboVec.w = (light).luminance; + } + this.offsetVec4(_uboVec, uniformOffset); + } } public setBuiltinRangedDirectionalLightConstants (light: RangedDirectionalLight, camera: Camera): void { - // TODO + const director = cclegacy.director; + const pipeline = (director.root as Root).pipeline; + const sceneData = pipeline.pipelineSceneData; + if (!this.addConstant('CCForwardLight', this.getParentLayout(), UpdateFrequency.PER_BATCH)) return; + uniformOffset = this.getUniformOffset('cc_lightPos', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.position.x, light.position.y, light.position.z, LightType.RANGED_DIRECTIONAL); + this.offsetVec4(_uboVec, uniformOffset); + } + uniformOffset = this.getUniformOffset('cc_lightSizeRangeAngle', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.right.x, light.right.y, light.right.z, 0.0); + this.offsetVec4(_uboVec, uniformOffset); + } + uniformOffset = this.getUniformOffset('cc_lightDir', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.direction.x, light.direction.y, light.direction.z, 0); + this.offsetVec4(_uboVec, uniformOffset); + } + uniformOffset = this.getUniformOffset('cc_lightBoundingSizeVS', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + const scale = light.scale; + _uboVec.set(scale.x * 0.5, scale.y * 0.5, scale.z * 0.5, 0); + this.offsetVec4(_uboVec, uniformOffset); + } + const isHDR = sceneData.isHDR; + uniformOffset = this.getUniformOffset('cc_lightColor', Type.FLOAT4); + if (this.hasUniform(uniformOffset)) { + _uboVec.set(light.color.x, light.color.y, light.color.z, 0); + if (light.useColorTemperature) { + const finalColor = light.finalColor; + _uboVec.x = finalColor.x; + _uboVec.y = finalColor.y; + _uboVec.z = finalColor.z; + } + if (isHDR) { + _uboVec.w = light.illuminance * camera.exposure; + } else { + _uboVec.w = light.illuminance; + } + this.offsetVec4(_uboVec, uniformOffset); + } } public hasSampler (name: string): boolean { const id = this._lg.attributeIndex.get(name); @@ -317,15 +482,17 @@ export class WebSetter implements Setter { // protected protected _data: RenderData; protected _lg: LayoutGraphData; + protected _vertID: number = -1; protected _currBlock; protected _currStage: string = ''; + protected _currFrequency: UpdateFrequency = UpdateFrequency.PER_PASS; protected _currCount; protected _currConstant: number[] = []; } function setShadowUBOLightView ( setter: WebSetter, - camera: Camera, + camera: Camera | null, light: Light, csmLevel: number, layout = 'default', @@ -348,8 +515,8 @@ function setShadowUBOLightView ( if (shadowInfo.enabled) { if (shadowInfo.type === ShadowType.ShadowMap) { // update CSM layers - if (light && light.node) { - csmLayers.update(sceneData, camera); + if (light && light.node && light.type === LightType.DIRECTIONAL) { + csmLayers.update(sceneData, camera!); } } } @@ -905,7 +1072,7 @@ export class WebSceneBuilder extends WebSetter implements SceneBuilder { const queueId = this._renderGraph.getParent(this._sceneId); const passId = this._renderGraph.getParent(queueId); const layoutName = this._renderGraph.getLayout(passId); - setShadowUBOLightView(this, this._scene.camera!, light, csmLevel, layoutName); + setShadowUBOLightView(this, this._scene.camera, light, csmLevel, layoutName); } private readonly _renderGraph: RenderGraph; private readonly _scene: SceneData; @@ -930,16 +1097,10 @@ export class WebRenderQueueBuilder extends WebSetter implements RenderQueueBuild this._renderGraph.setName(this._vertID, name); } - getLayoutName (): string { - const parId = this._renderGraph.getParent(this._vertID); - const layoutName = this._renderGraph.getLayout(parId); - return layoutName; - } - addSceneOfCamera (camera: Camera, light: LightInfo, sceneFlags = SceneFlags.NONE, name = 'Camera'): void { const sceneData = new SceneData(camera.scene, camera, sceneFlags, light); this._renderGraph.addVertex(RenderGraphValue.Scene, sceneData, name, '', new RenderData(), false, this._vertID); - const layoutName = this.getLayoutName(); + const layoutName = this.getParentLayout(); const scene: Scene = cclegacy.director.getScene(); setCameraUBOValues( this, @@ -964,7 +1125,7 @@ export class WebRenderQueueBuilder extends WebSetter implements RenderQueueBuild const renderData = new RenderData(); const sceneId = this._renderGraph.addVertex(RenderGraphValue.Scene, sceneData, 'Scene', '', renderData, false, this._vertID); if (!(sceneFlags & SceneFlags.NON_BUILTIN)) { - const layoutName = this.getLayoutName(); + const layoutName = this.getParentLayout(); setCameraUBOValues( this, camera, @@ -988,7 +1149,7 @@ export class WebRenderQueueBuilder extends WebSetter implements RenderQueueBuild false, this._vertID, ); - const layoutName = this.getLayoutName(); + const layoutName = this.getParentLayout(); const scene: Scene | null = cclegacy.director.getScene(); setCameraUBOValues( this, @@ -1015,7 +1176,7 @@ export class WebRenderQueueBuilder extends WebSetter implements RenderQueueBuild false, this._vertID, ); - const layoutName = this.getLayoutName(); + const layoutName = this.getParentLayout(); const scene: Scene = cclegacy.director.getScene(); setCameraUBOValues( this, @@ -1050,7 +1211,6 @@ export class WebRenderQueueBuilder extends WebSetter implements RenderQueueBuild throw new Error('Method not implemented.'); } private _renderGraph: RenderGraph; - private _vertID: number; private _queue: RenderQueue; private _pipeline: PipelineSceneData; } @@ -1124,7 +1284,6 @@ export class WebRenderSubpassBuilder extends WebSetter implements RenderSubpassB } private readonly _renderGraph: RenderGraph; - private readonly _vertID: number; private readonly _layoutID: number; private readonly _subpass: RasterSubpass; private readonly _pipeline: PipelineSceneData; @@ -1311,7 +1470,6 @@ export class WebRenderPassBuilder extends WebSetter implements BasicMultisampleR this._pass.showStatistics = enable; } private readonly _renderGraph: RenderGraph; - private readonly _vertID: number; private readonly _layoutID: number; private readonly _pass: RasterPass; private readonly _pipeline: PipelineSceneData; @@ -1359,7 +1517,6 @@ export class WebComputeQueueBuilder extends WebSetter implements ComputeQueueBui ); } private readonly _renderGraph: RenderGraph; - private readonly _vertID: number; private readonly _queue: RenderQueue; private readonly _pipeline: PipelineSceneData; } @@ -1433,7 +1590,6 @@ export class WebComputePassBuilder extends WebSetter implements ComputePassBuild private readonly _renderGraph: RenderGraph; private readonly _layoutGraph: LayoutGraphData; private readonly _resourceGraph: ResourceGraph; - private readonly _vertID: number; private readonly _layoutID: number; private readonly _pass: ComputePass; private readonly _pipeline: PipelineSceneData; diff --git a/native/cocos/renderer/pipeline/custom/NativeSetter.cpp b/native/cocos/renderer/pipeline/custom/NativeSetter.cpp index b06cfbbc52b..4c5fc26c4a5 100644 --- a/native/cocos/renderer/pipeline/custom/NativeSetter.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeSetter.cpp @@ -165,6 +165,35 @@ void NativeSetter::setBuiltinDirectionalLightConstants(const scene::DirectionalL } void NativeSetter::setBuiltinSphereLightConstants(const scene::SphereLight *light, const scene::Camera *camera) { + const auto &sceneData = *this->pipelineRuntime->getPipelineSceneData(); + const auto &shadowInfo = *sceneData.getShadows(); + + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setVec4Impl( + data, *layoutGraph, "cc_lightPos", + toVec4(light->getPosition(), static_cast(scene::LightType::SPHERE))); + auto color = toVec4(light->getColor()); + if (light->isUseColorTemperature()) { + const auto &rgb = light->getColorTemperatureRGB(); + color.x *= rgb.x; + color.y *= rgb.y; + color.z *= rgb.z; + } + if (sceneData.isHDR()) { + color.w = light->getLuminance() * camera->getExposure() * LIGHT_METER_SCALE; + } else { + color.w = light->getLuminance(); + } + + setVec4Impl( + data, *layoutGraph, "cc_lightColor", color); + setVec4Impl( + data, *layoutGraph, "cc_lightSizeRangeAngle", + Vec4( + light->getSize(), + light->getRange(), + 0.f, + 0.f)); } void NativeSetter::setBuiltinSpotLightConstants(const scene::SpotLight *light, const scene::Camera *camera) { @@ -211,9 +240,68 @@ void NativeSetter::setBuiltinSpotLightConstants(const scene::SpotLight *light, c } void NativeSetter::setBuiltinPointLightConstants(const scene::PointLight *light, const scene::Camera *camera) { + const auto &sceneData = *this->pipelineRuntime->getPipelineSceneData(); + const auto &shadowInfo = *sceneData.getShadows(); + + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setVec4Impl( + data, *layoutGraph, "cc_lightPos", + toVec4(light->getPosition(), static_cast(scene::LightType::POINT))); + auto color = toVec4(light->getColor()); + if (light->isUseColorTemperature()) { + const auto &rgb = light->getColorTemperatureRGB(); + color.x *= rgb.x; + color.y *= rgb.y; + color.z *= rgb.z; + } + if (sceneData.isHDR()) { + color.w = light->getLuminance() * camera->getExposure() * LIGHT_METER_SCALE; + } else { + color.w = light->getLuminance(); + } + + setVec4Impl( + data, *layoutGraph, "cc_lightColor", color); + setVec4Impl( + data, *layoutGraph, "cc_lightSizeRangeAngle", + Vec4( + 0.f, + light->getRange(), + 0.f, + 0.f)); } void NativeSetter::setBuiltinRangedDirectionalLightConstants(const scene::RangedDirectionalLight *light, const scene::Camera *camera) { + const auto &sceneData = *this->pipelineRuntime->getPipelineSceneData(); + const auto &shadowInfo = *sceneData.getShadows(); + + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setVec4Impl( + data, *layoutGraph, "cc_lightPos", + toVec4(light->getPosition(), static_cast(scene::LightType::RANGED_DIRECTIONAL))); + auto color = toVec4(light->getColor()); + if (light->isUseColorTemperature()) { + const auto &rgb = light->getColorTemperatureRGB(); + color.x *= rgb.x; + color.y *= rgb.y; + color.z *= rgb.z; + } + if (sceneData.isHDR()) { + color.w = light->getIlluminance() * camera->getExposure(); + } else { + color.w = light->getIlluminance(); + } + + setVec4Impl( + data, *layoutGraph, "cc_lightColor", color); + setVec4Impl( + data, *layoutGraph, "cc_lightSizeRangeAngle", + Vec4( + light->getRight().x, + light->getRight().y, + light->getRight().z, + 0.f)); + } } // namespace render