59b7958b47eec6168615a6469581f8f48e26cb00.js 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302
  1. System.register(["__unresolved_0", "cc", "cc/env", "__unresolved_1"], function (_export, _context) {
  2. "use strict";
  3. var _reporterNs, _cclegacy, __checkObsolete__, __checkObsoleteInNamespace__, DEBUG, EDITOR, assert, clamp, geometry, gfx, Layers, Material, pipeline, renderer, rendering, sys, Vec2, Vec3, Vec4, cclegacy, PipelineEventType, warn, makePipelineSettings, PipelineConfigs, CameraConfigs, _crd, AABB, Sphere, intersect, ClearFlagBit, Color, Format, FormatFeatureBit, LoadOp, StoreOp, TextureType, Viewport, scene, CameraUsage, CSMLevel, LightType, defaultSettings, QueueHint, SceneFlags, ResourceFlags, ResourceResidency;
  4. function forwardNeedClearColor(camera) {
  5. return !!(camera.clearFlag & (ClearFlagBit.COLOR | ClearFlagBit.STENCIL << 1));
  6. }
  7. function getCsmMainLightViewport(light, w, h, level, vp, screenSpaceSignY) {
  8. if (light.shadowFixedArea || light.csmLevel === CSMLevel.LEVEL_1) {
  9. vp.left = 0;
  10. vp.top = 0;
  11. vp.width = Math.trunc(w);
  12. vp.height = Math.trunc(h);
  13. } else {
  14. vp.left = Math.trunc(level % 2 * 0.5 * w);
  15. if (screenSpaceSignY > 0) {
  16. vp.top = Math.trunc((1 - Math.floor(level / 2)) * 0.5 * h);
  17. } else {
  18. vp.top = Math.trunc(Math.floor(level / 2) * 0.5 * h);
  19. }
  20. vp.width = Math.trunc(0.5 * w);
  21. vp.height = Math.trunc(0.5 * h);
  22. }
  23. vp.left = Math.max(0, vp.left);
  24. vp.top = Math.max(0, vp.top);
  25. vp.width = Math.max(1, vp.width);
  26. vp.height = Math.max(1, vp.height);
  27. }
  28. function setupPipelineConfigs(ppl, configs) {
  29. var sampleFeature = FormatFeatureBit.SAMPLED_TEXTURE | FormatFeatureBit.LINEAR_FILTER;
  30. var device = ppl.device; // Platform
  31. configs.isWeb = !sys.isNative;
  32. configs.isWebGL1 = device.gfxAPI === gfx.API.WEBGL;
  33. configs.isWebGPU = device.gfxAPI === gfx.API.WEBGPU;
  34. configs.isMobile = sys.isMobile; // Rendering
  35. configs.isHDR = ppl.pipelineSceneData.isHDR; // Has tone mapping
  36. configs.useFloatOutput = ppl.getMacroBool('CC_USE_FLOAT_OUTPUT');
  37. configs.toneMappingType = ppl.pipelineSceneData.postSettings.toneMappingType; // Shadow
  38. var shadowInfo = ppl.pipelineSceneData.shadows;
  39. configs.shadowEnabled = shadowInfo.enabled;
  40. configs.shadowMapFormat = pipeline.supportsR32FloatTexture(ppl.device) ? Format.R32F : Format.RGBA8;
  41. configs.shadowMapSize.set(shadowInfo.size);
  42. configs.usePlanarShadow = shadowInfo.enabled && shadowInfo.type === renderer.scene.ShadowType.Planar; // Device
  43. configs.screenSpaceSignY = ppl.device.capabilities.screenSpaceSignY;
  44. configs.supportDepthSample = (ppl.device.getFormatFeatures(Format.DEPTH_STENCIL) & sampleFeature) === sampleFeature; // Constants
  45. var screenSpaceSignY = device.capabilities.screenSpaceSignY;
  46. configs.platform.x = configs.isMobile ? 1.0 : 0.0;
  47. configs.platform.w = screenSpaceSignY * 0.5 + 0.5 << 1 | device.capabilities.clipSpaceSignY * 0.5 + 0.5;
  48. }
  49. function setupPostProcessConfigs(pipelineConfigs, settings, cameraConfigs) {
  50. cameraConfigs.enableDOF = pipelineConfigs.supportDepthSample && settings.depthOfField.enabled && !!settings.depthOfField.material;
  51. cameraConfigs.enableBloom = settings.bloom.enabled && !!settings.bloom.material;
  52. cameraConfigs.enableColorGrading = settings.colorGrading.enabled && !!settings.colorGrading.material && !!settings.colorGrading.colorGradingMap;
  53. cameraConfigs.enableFXAA = settings.fxaa.enabled && !!settings.fxaa.material;
  54. cameraConfigs.enablePostProcess = cameraConfigs.enableDOF || cameraConfigs.enableBloom || cameraConfigs.enableColorGrading || cameraConfigs.enableFXAA;
  55. }
  56. function setupCameraConfigs(camera, pipelineConfigs, cameraConfigs) {
  57. var window = camera.window;
  58. var isMainGameWindow = camera.cameraUsage === CameraUsage.GAME && !!window.swapchain;
  59. var isEditorView = camera.cameraUsage === CameraUsage.SCENE_VIEW || camera.cameraUsage === CameraUsage.PREVIEW;
  60. cameraConfigs.colorName = window.colorName;
  61. cameraConfigs.depthStencilName = window.depthStencilName;
  62. cameraConfigs.useFullPipeline = (camera.visibility & Layers.Enum.DEFAULT) !== 0;
  63. cameraConfigs.enableMainLightShadowMap = pipelineConfigs.shadowEnabled && !pipelineConfigs.usePlanarShadow && !!camera.scene && !!camera.scene.mainLight && camera.scene.mainLight.shadowEnabled;
  64. cameraConfigs.enableMainLightPlanarShadowMap = pipelineConfigs.shadowEnabled && pipelineConfigs.usePlanarShadow && !!camera.scene && !!camera.scene.mainLight && camera.scene.mainLight.shadowEnabled;
  65. cameraConfigs.enablePlanarReflectionProbe = isMainGameWindow || camera.cameraUsage === CameraUsage.SCENE_VIEW;
  66. cameraConfigs.enableProfiler = DEBUG && isMainGameWindow;
  67. cameraConfigs.settings = camera.pipelineSettings ? camera.pipelineSettings : defaultSettings;
  68. setupPostProcessConfigs(pipelineConfigs, cameraConfigs.settings, cameraConfigs);
  69. if (isEditorView) {
  70. var editorSettings = rendering.getEditorPipelineSettings();
  71. if (editorSettings) {
  72. cameraConfigs.settings = editorSettings;
  73. setupPostProcessConfigs(pipelineConfigs, cameraConfigs.settings, cameraConfigs);
  74. }
  75. } // MSAA
  76. cameraConfigs.enableMSAA = cameraConfigs.settings.msaa.enabled && !pipelineConfigs.isWeb // TODO(zhouzhenglong): remove this constraint
  77. && !pipelineConfigs.isWebGL1; // Shading scale
  78. cameraConfigs.shadingScale = cameraConfigs.settings.shadingScale;
  79. cameraConfigs.enableShadingScale = cameraConfigs.settings.enableShadingScale && cameraConfigs.shadingScale !== 1.0; // FSR (Depend on Shading scale)
  80. cameraConfigs.enableFSR = cameraConfigs.settings.fsr.enabled && !!cameraConfigs.settings.fsr.material && cameraConfigs.enableShadingScale && cameraConfigs.shadingScale < 1.0; // Forward rendering (Depend on MSAA and TBR)
  81. cameraConfigs.singleForwardRadiancePass = pipelineConfigs.isMobile || cameraConfigs.enableMSAA;
  82. cameraConfigs.enableHDR = cameraConfigs.useFullPipeline && pipelineConfigs.useFloatOutput;
  83. cameraConfigs.radianceFormat = cameraConfigs.enableHDR ? gfx.Format.RGBA16F : gfx.Format.RGBA8;
  84. }
  85. function _reportPossibleCrUseOfPipelineSettings(extras) {
  86. _reporterNs.report("PipelineSettings", "./builtin-pipeline-types", _context.meta, extras);
  87. }
  88. function _reportPossibleCrUseOfmakePipelineSettings(extras) {
  89. _reporterNs.report("makePipelineSettings", "./builtin-pipeline-types", _context.meta, extras);
  90. }
  91. return {
  92. setters: [function (_unresolved_) {
  93. _reporterNs = _unresolved_;
  94. }, function (_cc) {
  95. _cclegacy = _cc.cclegacy;
  96. __checkObsolete__ = _cc.__checkObsolete__;
  97. __checkObsoleteInNamespace__ = _cc.__checkObsoleteInNamespace__;
  98. assert = _cc.assert;
  99. clamp = _cc.clamp;
  100. geometry = _cc.geometry;
  101. gfx = _cc.gfx;
  102. Layers = _cc.Layers;
  103. Material = _cc.Material;
  104. pipeline = _cc.pipeline;
  105. renderer = _cc.renderer;
  106. rendering = _cc.rendering;
  107. sys = _cc.sys;
  108. Vec2 = _cc.Vec2;
  109. Vec3 = _cc.Vec3;
  110. Vec4 = _cc.Vec4;
  111. cclegacy = _cc.cclegacy;
  112. PipelineEventType = _cc.PipelineEventType;
  113. warn = _cc.warn;
  114. }, function (_ccEnv) {
  115. DEBUG = _ccEnv.DEBUG;
  116. EDITOR = _ccEnv.EDITOR;
  117. }, function (_unresolved_2) {
  118. makePipelineSettings = _unresolved_2.makePipelineSettings;
  119. }],
  120. execute: function () {
  121. _crd = true;
  122. _cclegacy._RF.push({}, "ff9b0GZzgRM/obMbHGfCNbk", "builtin-pipeline", undefined);
  123. /*
  124. Copyright (c) 2021-2024 Xiamen Yaji Software Co., Ltd.
  125. https://www.cocos.com/
  126. Permission is hereby granted, free of charge, to any person obtaining a copy
  127. of this software and associated documentation files (the "Software"), to deal
  128. in the Software without restriction, including without limitation the rights to
  129. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  130. of the Software, and to permit persons to whom the Software is furnished to do so,
  131. subject to the following conditions:
  132. The above copyright notice and this permission notice shall be included in
  133. all copies or substantial portions of the Software.
  134. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  135. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  136. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  137. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  138. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  139. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  140. THE SOFTWARE.
  141. */
  142. __checkObsolete__(['assert', 'clamp', 'geometry', 'gfx', 'Layers', 'Material', 'pipeline', 'renderer', 'rendering', 'sys', 'Vec2', 'Vec3', 'Vec4', 'cclegacy', 'PipelineEventType', 'PipelineEventProcessor', 'ReflectionProbeManager', 'warn']);
  143. ({
  144. AABB,
  145. Sphere,
  146. intersect
  147. } = geometry);
  148. ({
  149. ClearFlagBit,
  150. Color,
  151. Format,
  152. FormatFeatureBit,
  153. LoadOp,
  154. StoreOp,
  155. TextureType,
  156. Viewport
  157. } = gfx);
  158. ({
  159. scene
  160. } = renderer);
  161. ({
  162. CameraUsage,
  163. CSMLevel,
  164. LightType
  165. } = scene);
  166. PipelineConfigs = class PipelineConfigs {
  167. constructor() {
  168. this.isWeb = false;
  169. this.isWebGL1 = false;
  170. this.isWebGPU = false;
  171. this.isMobile = false;
  172. this.isHDR = false;
  173. this.useFloatOutput = false;
  174. this.toneMappingType = 0;
  175. // 0: ACES, 1: None
  176. this.shadowEnabled = false;
  177. this.shadowMapFormat = Format.R32F;
  178. this.shadowMapSize = new Vec2(1, 1);
  179. this.usePlanarShadow = false;
  180. this.screenSpaceSignY = 1;
  181. this.supportDepthSample = false;
  182. this.mobileMaxSpotLightShadowMaps = 1;
  183. this.platform = new Vec4(0, 0, 0, 0);
  184. }
  185. };
  186. defaultSettings = (_crd && makePipelineSettings === void 0 ? (_reportPossibleCrUseOfmakePipelineSettings({
  187. error: Error()
  188. }), makePipelineSettings) : makePipelineSettings)();
  189. CameraConfigs = class CameraConfigs {
  190. constructor() {
  191. this.colorName = '';
  192. this.depthStencilName = '';
  193. this.enableMainLightShadowMap = false;
  194. this.enableMainLightPlanarShadowMap = false;
  195. this.enablePostProcess = false;
  196. this.enableProfiler = false;
  197. this.enableShadingScale = false;
  198. this.enableMSAA = false;
  199. this.enableDOF = false;
  200. this.enableBloom = false;
  201. this.enableColorGrading = false;
  202. this.enableFXAA = false;
  203. this.enableFSR = false;
  204. this.enableHDR = false;
  205. this.enablePlanarReflectionProbe = false;
  206. this.useFullPipeline = false;
  207. this.singleForwardRadiancePass = false;
  208. this.radianceFormat = gfx.Format.RGBA8;
  209. this.shadingScale = 0.5;
  210. this.settings = defaultSettings;
  211. }
  212. };
  213. if (rendering) {
  214. ({
  215. QueueHint,
  216. SceneFlags,
  217. ResourceFlags,
  218. ResourceResidency
  219. } = rendering);
  220. class ForwardLighting {
  221. constructor() {
  222. // Active lights
  223. this.lights = [];
  224. // Active spot lights with shadows (Mutually exclusive with `lights`)
  225. this.shadowEnabledSpotLights = [];
  226. // Internal cached resources
  227. this._sphere = Sphere.create(0, 0, 0, 1);
  228. this._boundingBox = new AABB();
  229. this._rangedDirLightBoundingBox = new AABB(0.0, 0.0, 0.0, 0.5, 0.5, 0.5);
  230. }
  231. // ----------------------------------------------------------------
  232. // Interface
  233. // ----------------------------------------------------------------
  234. cullLights(scene, frustum, cameraPos) {
  235. // TODO(zhouzhenglong): Make light culling native
  236. this.lights.length = 0;
  237. this.shadowEnabledSpotLights.length = 0; // spot lights
  238. for (var light of scene.spotLights) {
  239. if (light.baked) {
  240. continue;
  241. }
  242. Sphere.set(this._sphere, light.position.x, light.position.y, light.position.z, light.range);
  243. if (intersect.sphereFrustum(this._sphere, frustum)) {
  244. if (light.shadowEnabled) {
  245. this.shadowEnabledSpotLights.push(light);
  246. } else {
  247. this.lights.push(light);
  248. }
  249. }
  250. } // sphere lights
  251. for (var _light of scene.sphereLights) {
  252. if (_light.baked) {
  253. continue;
  254. }
  255. Sphere.set(this._sphere, _light.position.x, _light.position.y, _light.position.z, _light.range);
  256. if (intersect.sphereFrustum(this._sphere, frustum)) {
  257. this.lights.push(_light);
  258. }
  259. } // point lights
  260. for (var _light2 of scene.pointLights) {
  261. if (_light2.baked) {
  262. continue;
  263. }
  264. Sphere.set(this._sphere, _light2.position.x, _light2.position.y, _light2.position.z, _light2.range);
  265. if (intersect.sphereFrustum(this._sphere, frustum)) {
  266. this.lights.push(_light2);
  267. }
  268. } // ranged dir lights
  269. for (var _light3 of scene.rangedDirLights) {
  270. AABB.transform(this._boundingBox, this._rangedDirLightBoundingBox, _light3.node.getWorldMatrix());
  271. if (intersect.aabbFrustum(this._boundingBox, frustum)) {
  272. this.lights.push(_light3);
  273. }
  274. }
  275. if (cameraPos) {
  276. this.shadowEnabledSpotLights.sort((lhs, rhs) => Vec3.squaredDistance(cameraPos, lhs.position) - Vec3.squaredDistance(cameraPos, rhs.position));
  277. }
  278. }
  279. _addLightQueues(camera, pass) {
  280. for (var light of this.lights) {
  281. var queue = pass.addQueue(QueueHint.BLEND, 'forward-add');
  282. switch (light.type) {
  283. case LightType.SPHERE:
  284. queue.name = 'sphere-light';
  285. break;
  286. case LightType.SPOT:
  287. queue.name = 'spot-light';
  288. break;
  289. case LightType.POINT:
  290. queue.name = 'point-light';
  291. break;
  292. case LightType.RANGED_DIRECTIONAL:
  293. queue.name = 'ranged-directional-light';
  294. break;
  295. default:
  296. queue.name = 'unknown-light';
  297. }
  298. queue.addScene(camera, SceneFlags.BLEND, light);
  299. }
  300. }
  301. addSpotlightShadowPasses(ppl, camera, maxNumShadowMaps) {
  302. var i = 0;
  303. for (var light of this.shadowEnabledSpotLights) {
  304. var shadowMapSize = ppl.pipelineSceneData.shadows.size;
  305. var shadowPass = ppl.addRenderPass(shadowMapSize.x, shadowMapSize.y, 'default');
  306. shadowPass.name = "SpotLightShadowPass" + i;
  307. shadowPass.addRenderTarget("SpotShadowMap" + i, LoadOp.CLEAR, StoreOp.STORE, new Color(1, 1, 1, 1));
  308. shadowPass.addDepthStencil("SpotShadowDepth" + i, LoadOp.CLEAR, StoreOp.DISCARD);
  309. shadowPass.addQueue(QueueHint.NONE, 'shadow-caster').addScene(camera, SceneFlags.OPAQUE | SceneFlags.MASK | SceneFlags.SHADOW_CASTER).useLightFrustum(light);
  310. ++i;
  311. if (i >= maxNumShadowMaps) {
  312. break;
  313. }
  314. }
  315. }
  316. addLightQueues(pass, camera, maxNumShadowMaps) {
  317. this._addLightQueues(camera, pass);
  318. var i = 0;
  319. for (var light of this.shadowEnabledSpotLights) {
  320. // Add spot-light pass
  321. // Save last RenderPass to the `pass` variable
  322. // TODO(zhouzhenglong): Fix per queue addTexture
  323. pass.addTexture("SpotShadowMap" + i, 'cc_spotShadowMap');
  324. var queue = pass.addQueue(QueueHint.BLEND, 'forward-add');
  325. queue.addScene(camera, SceneFlags.BLEND, light);
  326. ++i;
  327. if (i >= maxNumShadowMaps) {
  328. break;
  329. }
  330. }
  331. } // Notice: ForwardLighting cannot handle a lot of lights.
  332. // If there are too many lights, the performance will be very poor.
  333. // If many lights are needed, please implement a forward+ or deferred rendering pipeline.
  334. addLightPasses(colorName, depthStencilName, depthStencilStoreOp, id, // window id
  335. width, height, camera, viewport, ppl, pass) {
  336. this._addLightQueues(camera, pass);
  337. var count = 0;
  338. var shadowMapSize = ppl.pipelineSceneData.shadows.size;
  339. for (var light of this.shadowEnabledSpotLights) {
  340. var shadowPass = ppl.addRenderPass(shadowMapSize.x, shadowMapSize.y, 'default');
  341. shadowPass.name = 'SpotlightShadowPass'; // Reuse csm shadow map
  342. shadowPass.addRenderTarget("ShadowMap" + id, LoadOp.CLEAR, StoreOp.STORE, new Color(1, 1, 1, 1));
  343. shadowPass.addDepthStencil("ShadowDepth" + id, LoadOp.CLEAR, StoreOp.DISCARD);
  344. shadowPass.addQueue(QueueHint.NONE, 'shadow-caster').addScene(camera, SceneFlags.OPAQUE | SceneFlags.MASK | SceneFlags.SHADOW_CASTER).useLightFrustum(light); // Add spot-light pass
  345. // Save last RenderPass to the `pass` variable
  346. ++count;
  347. var storeOp = count === this.shadowEnabledSpotLights.length ? depthStencilStoreOp : StoreOp.STORE;
  348. pass = ppl.addRenderPass(width, height, 'default');
  349. pass.name = 'SpotlightWithShadowMap';
  350. pass.setViewport(viewport);
  351. pass.addRenderTarget(colorName, LoadOp.LOAD);
  352. pass.addDepthStencil(depthStencilName, LoadOp.LOAD, storeOp);
  353. pass.addTexture("ShadowMap" + id, 'cc_spotShadowMap');
  354. var queue = pass.addQueue(QueueHint.BLEND, 'forward-add');
  355. queue.addScene(camera, SceneFlags.BLEND, light);
  356. }
  357. return pass;
  358. }
  359. isMultipleLightPassesNeeded() {
  360. return this.shadowEnabledSpotLights.length > 0;
  361. }
  362. }
  363. class BuiltinPipelineBuilder {
  364. constructor() {
  365. this._pipelineEvent = cclegacy.director.root.pipelineEvent;
  366. // Internal cached resources
  367. this._clearColor = new Color(0, 0, 0, 1);
  368. this._clearColorTransparentBlack = new Color(0, 0, 0, 0);
  369. this._reflectionProbeClearColor = new Vec3(0, 0, 0);
  370. this._viewport = new Viewport();
  371. this._configs = new PipelineConfigs();
  372. this._cameraConfigs = new CameraConfigs();
  373. // DepthOfField
  374. this._cocParams = new Vec4(0, 0, 0, 0);
  375. this._cocTexSize = new Vec4(0, 0, 0, 0);
  376. // Bloom
  377. this._bloomParams = new Vec4(0, 0, 0, 0);
  378. this._bloomTexSize = new Vec4(0, 0, 0, 0);
  379. this._bloomWidths = [];
  380. this._bloomHeights = [];
  381. this._bloomTexNames = [];
  382. // Color Grading
  383. this._colorGradingTexSize = new Vec2(0, 0);
  384. // FXAA
  385. this._fxaaParams = new Vec4(0, 0, 0, 0);
  386. // FSR
  387. this._fsrParams = new Vec4(0, 0, 0, 0);
  388. this._fsrTexSize = new Vec4(0, 0, 0, 0);
  389. // Materials
  390. this._copyAndTonemapMaterial = new Material();
  391. // Internal States
  392. this._initialized = false;
  393. // TODO(zhouzhenglong): Make default effect asset loading earlier and remove this flag
  394. // Forward lighting
  395. this.forwardLighting = new ForwardLighting();
  396. }
  397. // ----------------------------------------------------------------
  398. // Interface
  399. // ----------------------------------------------------------------
  400. windowResize(ppl, window, camera, nativeWidth, nativeHeight) {
  401. setupPipelineConfigs(ppl, this._configs);
  402. setupCameraConfigs(camera, this._configs, this._cameraConfigs);
  403. var settings = this._cameraConfigs.settings;
  404. var id = window.renderWindowId;
  405. var width = this._cameraConfigs.enableShadingScale ? Math.max(Math.floor(nativeWidth * this._cameraConfigs.shadingScale), 1) : nativeWidth;
  406. var height = this._cameraConfigs.enableShadingScale ? Math.max(Math.floor(nativeHeight * this._cameraConfigs.shadingScale), 1) : nativeHeight; // Render Window (UI)
  407. ppl.addRenderWindow(this._cameraConfigs.colorName, Format.RGBA8, nativeWidth, nativeHeight, window, this._cameraConfigs.depthStencilName);
  408. if (this._cameraConfigs.enableShadingScale) {
  409. ppl.addDepthStencil("ScaledSceneDepth" + id, Format.DEPTH_STENCIL, width, height);
  410. ppl.addRenderTarget("ScaledRadiance" + id, this._cameraConfigs.radianceFormat, width, height);
  411. ppl.addRenderTarget("ScaledLdrColor" + id, Format.RGBA8, width, height);
  412. } else {
  413. ppl.addDepthStencil("SceneDepth" + id, Format.DEPTH_STENCIL, width, height);
  414. ppl.addRenderTarget("Radiance" + id, this._cameraConfigs.radianceFormat, width, height);
  415. ppl.addRenderTarget("LdrColor" + id, Format.RGBA8, width, height);
  416. }
  417. if (this._cameraConfigs.enableFSR) {
  418. ppl.addRenderTarget("FsrColor" + id, Format.RGBA8, nativeWidth, nativeHeight);
  419. } // MsaaRadiance
  420. if (this._cameraConfigs.enableMSAA) {
  421. // Notice: We never store multisample results.
  422. // These samples are always resolved and discarded at the end of the render pass.
  423. // So the ResourceResidency should be MEMORYLESS.
  424. if (this._cameraConfigs.enableHDR) {
  425. ppl.addTexture("MsaaRadiance" + id, TextureType.TEX2D, this._cameraConfigs.radianceFormat, width, height, 1, 1, 1, settings.msaa.sampleCount, ResourceFlags.COLOR_ATTACHMENT, ResourceResidency.MEMORYLESS);
  426. } else {
  427. ppl.addTexture("MsaaRadiance" + id, TextureType.TEX2D, Format.RGBA8, width, height, 1, 1, 1, settings.msaa.sampleCount, ResourceFlags.COLOR_ATTACHMENT, ResourceResidency.MEMORYLESS);
  428. }
  429. ppl.addTexture("MsaaDepthStencil" + id, TextureType.TEX2D, Format.DEPTH_STENCIL, width, height, 1, 1, 1, settings.msaa.sampleCount, ResourceFlags.DEPTH_STENCIL_ATTACHMENT, ResourceResidency.MEMORYLESS);
  430. } // Mainlight ShadowMap
  431. ppl.addRenderTarget("ShadowMap" + id, this._configs.shadowMapFormat, this._configs.shadowMapSize.x, this._configs.shadowMapSize.y);
  432. ppl.addDepthStencil("ShadowDepth" + id, Format.DEPTH_STENCIL, this._configs.shadowMapSize.x, this._configs.shadowMapSize.y); // Spot-light shadow maps
  433. if (this._cameraConfigs.singleForwardRadiancePass) {
  434. var count = this._configs.mobileMaxSpotLightShadowMaps;
  435. for (var i = 0; i !== count; ++i) {
  436. ppl.addRenderTarget("SpotShadowMap" + i, this._configs.shadowMapFormat, this._configs.shadowMapSize.x, this._configs.shadowMapSize.y);
  437. ppl.addDepthStencil("SpotShadowDepth" + i, Format.DEPTH_STENCIL, this._configs.shadowMapSize.x, this._configs.shadowMapSize.y);
  438. }
  439. } // ---------------------------------------------------------
  440. // Post Process
  441. // ---------------------------------------------------------
  442. // DepthOfField
  443. if (this._cameraConfigs.enableDOF) {
  444. var halfWidth = Math.max(Math.floor(width / 2), 1);
  445. var halfHeight = Math.max(Math.floor(height / 2), 1); // `DofCoc${id}` texture will reuse ldrColorName
  446. ppl.addRenderTarget("DofRadiance" + id, this._cameraConfigs.radianceFormat, width, height);
  447. ppl.addRenderTarget("DofPrefilter" + id, this._cameraConfigs.radianceFormat, halfWidth, halfHeight);
  448. ppl.addRenderTarget("DofBokeh" + id, this._cameraConfigs.radianceFormat, halfWidth, halfHeight);
  449. ppl.addRenderTarget("DofFilter" + id, this._cameraConfigs.radianceFormat, halfWidth, halfHeight);
  450. } // Bloom (Kawase Dual Filter)
  451. if (this._cameraConfigs.enableBloom) {
  452. var bloomWidth = width;
  453. var bloomHeight = height;
  454. for (var _i = 0; _i !== settings.bloom.iterations + 1; ++_i) {
  455. bloomWidth = Math.max(Math.floor(bloomWidth / 2), 1);
  456. bloomHeight = Math.max(Math.floor(bloomHeight / 2), 1);
  457. ppl.addRenderTarget("BloomTex" + id + "_" + _i, this._cameraConfigs.radianceFormat, bloomWidth, bloomHeight);
  458. }
  459. } // Color Grading
  460. if (this._cameraConfigs.enableColorGrading && settings.colorGrading.material && settings.colorGrading.colorGradingMap) {
  461. settings.colorGrading.material.setProperty('colorGradingMap', settings.colorGrading.colorGradingMap);
  462. } // FXAA
  463. if (this._cameraConfigs.enableFXAA && this._cameraConfigs.enableShadingScale) {
  464. ppl.addRenderTarget("AaColor" + id, Format.RGBA8, width, height);
  465. }
  466. }
  467. setup(cameras, ppl) {
  468. // TODO(zhouzhenglong): Make default effect asset loading earlier and remove _initMaterials
  469. if (this._initMaterials(ppl)) {
  470. return;
  471. } // Render cameras
  472. // log(`==================== One Frame ====================`);
  473. for (var camera of cameras) {
  474. // Skip invalid camera
  475. if (!camera.scene || !camera.window) {
  476. continue;
  477. } // Setup camera configs
  478. setupCameraConfigs(camera, this._configs, this._cameraConfigs); // log(`Setup camera: ${camera.node!.name}, window: ${camera.window.renderWindowId}, isFull: ${this._cameraConfigs.useFullPipeline}, `
  479. // + `size: ${camera.window.width}x${camera.window.height}`);
  480. this._pipelineEvent.emit(PipelineEventType.RENDER_CAMERA_BEGIN, camera); // Build pipeline
  481. if (this._cameraConfigs.useFullPipeline) {
  482. this._buildForwardPipeline(ppl, camera, camera.scene);
  483. } else {
  484. this._buildSimplePipeline(ppl, camera);
  485. }
  486. this._pipelineEvent.emit(PipelineEventType.RENDER_CAMERA_END, camera);
  487. }
  488. } // ----------------------------------------------------------------
  489. // Pipelines
  490. // ----------------------------------------------------------------
  491. _buildSimplePipeline(ppl, camera) {
  492. var width = Math.max(Math.floor(camera.window.width), 1);
  493. var height = Math.max(Math.floor(camera.window.height), 1);
  494. var colorName = this._cameraConfigs.colorName;
  495. var depthStencilName = this._cameraConfigs.depthStencilName;
  496. var viewport = camera.viewport; // Reduce C++/TS interop
  497. this._viewport.left = Math.round(viewport.x * width);
  498. this._viewport.top = Math.round(viewport.y * height); // Here we must use camera.viewport.width instead of camera.viewport.z, which
  499. // is undefined on native platform. The same as camera.viewport.height.
  500. this._viewport.width = Math.max(Math.round(viewport.width * width), 1);
  501. this._viewport.height = Math.max(Math.round(viewport.height * height), 1);
  502. var clearColor = camera.clearColor; // Reduce C++/TS interop
  503. this._clearColor.x = clearColor.x;
  504. this._clearColor.y = clearColor.y;
  505. this._clearColor.z = clearColor.z;
  506. this._clearColor.w = clearColor.w;
  507. var pass = ppl.addRenderPass(width, height, 'default'); // bind output render target
  508. if (forwardNeedClearColor(camera)) {
  509. pass.addRenderTarget(colorName, LoadOp.CLEAR, StoreOp.STORE, this._clearColor);
  510. } else {
  511. pass.addRenderTarget(colorName, LoadOp.LOAD, StoreOp.STORE);
  512. } // bind depth stencil buffer
  513. if (camera.clearFlag & ClearFlagBit.DEPTH_STENCIL) {
  514. pass.addDepthStencil(depthStencilName, LoadOp.CLEAR, StoreOp.DISCARD, camera.clearDepth, camera.clearStencil, camera.clearFlag & ClearFlagBit.DEPTH_STENCIL);
  515. } else {
  516. pass.addDepthStencil(depthStencilName, LoadOp.LOAD, StoreOp.DISCARD);
  517. }
  518. pass.setViewport(this._viewport); // The opaque queue is used for Reflection probe preview
  519. pass.addQueue(QueueHint.OPAQUE).addScene(camera, SceneFlags.OPAQUE); // The blend queue is used for UI and Gizmos
  520. var flags = SceneFlags.BLEND | SceneFlags.UI;
  521. if (this._cameraConfigs.enableProfiler) {
  522. flags |= SceneFlags.PROFILER;
  523. pass.showStatistics = true;
  524. }
  525. pass.addQueue(QueueHint.BLEND).addScene(camera, flags);
  526. }
  527. _buildForwardPipeline(ppl, camera, scene) {
  528. // Init
  529. var settings = this._cameraConfigs.settings;
  530. var nativeWidth = Math.max(Math.floor(camera.window.width), 1);
  531. var nativeHeight = Math.max(Math.floor(camera.window.height), 1);
  532. var width = this._cameraConfigs.enableShadingScale ? Math.max(Math.floor(nativeWidth * this._cameraConfigs.shadingScale), 1) : nativeWidth;
  533. var height = this._cameraConfigs.enableShadingScale ? Math.max(Math.floor(nativeHeight * this._cameraConfigs.shadingScale), 1) : nativeHeight;
  534. var id = camera.window.renderWindowId;
  535. var colorName = this._cameraConfigs.colorName;
  536. var sceneDepth = this._cameraConfigs.enableShadingScale ? "ScaledSceneDepth" + id : "SceneDepth" + id;
  537. var radianceName = this._cameraConfigs.enableShadingScale ? "ScaledRadiance" + id : "Radiance" + id;
  538. var ldrColorName = this._cameraConfigs.enableShadingScale ? "ScaledLdrColor" + id : "LdrColor" + id;
  539. var mainLight = scene.mainLight; // Forward Lighting (Light Culling)
  540. this.forwardLighting.cullLights(scene, camera.frustum); // Main Directional light CSM Shadow Map
  541. if (this._cameraConfigs.enableMainLightShadowMap) {
  542. assert(!!mainLight);
  543. this._addCascadedShadowMapPass(ppl, id, mainLight, camera);
  544. } // Spot light shadow maps (Mobile or MSAA)
  545. if (this._cameraConfigs.singleForwardRadiancePass) {
  546. // Currently, only support 1 spot light with shadow map on mobile platform.
  547. // TODO(zhouzhenglong): Relex this limitation.
  548. this.forwardLighting.addSpotlightShadowPasses(ppl, camera, this._configs.mobileMaxSpotLightShadowMaps);
  549. }
  550. this._tryAddReflectionProbePasses(ppl, id, mainLight, camera.scene); // Forward Lighting
  551. var lastPass;
  552. if (this._cameraConfigs.enablePostProcess) {
  553. // Post Process
  554. // Radiance and DoF
  555. if (this._cameraConfigs.enableDOF) {
  556. assert(!!settings.depthOfField.material);
  557. var dofRadianceName = "DofRadiance" + id; // Disable MSAA, depth stencil cannot be resolved cross-platformly
  558. this._addForwardRadiancePasses(ppl, id, camera, width, height, mainLight, dofRadianceName, sceneDepth, true, StoreOp.STORE);
  559. this._addDepthOfFieldPasses(ppl, settings, settings.depthOfField.material, id, camera, width, height, dofRadianceName, sceneDepth, radianceName, ldrColorName);
  560. } else {
  561. this._addForwardRadiancePasses(ppl, id, camera, width, height, mainLight, radianceName, sceneDepth);
  562. } // Bloom
  563. if (this._cameraConfigs.enableBloom) {
  564. assert(!!settings.bloom.material);
  565. this._addKawaseDualFilterBloomPasses(ppl, settings, settings.bloom.material, id, width, height, radianceName);
  566. } // Tone Mapping and FXAA
  567. if (this._cameraConfigs.enableFXAA) {
  568. assert(!!settings.fxaa.material);
  569. var copyAndTonemapPassNeeded = this._cameraConfigs.enableHDR || this._cameraConfigs.enableColorGrading;
  570. var ldrColorBufferName = copyAndTonemapPassNeeded ? ldrColorName : radianceName; // FXAA is applied after tone mapping
  571. if (copyAndTonemapPassNeeded) {
  572. this._addCopyAndTonemapPass(ppl, settings, width, height, radianceName, ldrColorBufferName);
  573. } // Apply FXAA
  574. if (this._cameraConfigs.enableShadingScale) {
  575. var aaColorName = "AaColor" + id; // Apply FXAA on scaled image
  576. this._addFxaaPass(ppl, settings.fxaa.material, width, height, ldrColorBufferName, aaColorName); // Copy FXAA result to screen
  577. if (this._cameraConfigs.enableFSR && settings.fsr.material) {
  578. // Apply FSR
  579. lastPass = this._addFsrPass(ppl, settings, settings.fsr.material, id, width, height, aaColorName, nativeWidth, nativeHeight, colorName);
  580. } else {
  581. // Scale FXAA result to screen
  582. lastPass = this._addCopyPass(ppl, nativeWidth, nativeHeight, aaColorName, colorName);
  583. }
  584. } else {
  585. // Image not scaled, output FXAA result to screen directly
  586. lastPass = this._addFxaaPass(ppl, settings.fxaa.material, nativeWidth, nativeHeight, ldrColorBufferName, colorName);
  587. }
  588. } else {
  589. // No FXAA (Size might be scaled)
  590. lastPass = this._addTonemapResizeOrSuperResolutionPasses(ppl, settings, id, width, height, radianceName, ldrColorName, nativeWidth, nativeHeight, colorName);
  591. }
  592. } else if (this._cameraConfigs.enableHDR || this._cameraConfigs.enableShadingScale) {
  593. // HDR or Scaled LDR
  594. this._addForwardRadiancePasses(ppl, id, camera, width, height, mainLight, radianceName, sceneDepth);
  595. lastPass = this._addTonemapResizeOrSuperResolutionPasses(ppl, settings, id, width, height, radianceName, ldrColorName, nativeWidth, nativeHeight, colorName);
  596. } else {
  597. // LDR (Size is not scaled)
  598. lastPass = this._addForwardRadiancePasses(ppl, id, camera, nativeWidth, nativeHeight, mainLight, colorName, this._cameraConfigs.depthStencilName);
  599. } // UI size is not scaled, does not have AA
  600. this._addUIQueue(camera, lastPass);
  601. } // ----------------------------------------------------------------
  602. // Common Passes
  603. // ----------------------------------------------------------------
  604. _addTonemapResizeOrSuperResolutionPasses(ppl, settings, id, width, height, radianceName, ldrColorName, nativeWidth, nativeHeight, colorName) {
  605. var lastPass;
  606. if (this._cameraConfigs.enableFSR && settings.fsr.material) {
  607. // Apply FSR
  608. this._addCopyAndTonemapPass(ppl, settings, width, height, radianceName, ldrColorName);
  609. lastPass = this._addFsrPass(ppl, settings, settings.fsr.material, id, width, height, ldrColorName, nativeWidth, nativeHeight, colorName);
  610. } else {
  611. // Output HDR/LDR result to screen directly (Size might be scaled)
  612. lastPass = this._addCopyAndTonemapPass(ppl, settings, nativeWidth, nativeHeight, radianceName, colorName);
  613. }
  614. return lastPass;
  615. }
  616. _addCascadedShadowMapPass(ppl, id, light, camera) {
  617. // ----------------------------------------------------------------
  618. // Dynamic states
  619. // ----------------------------------------------------------------
  620. var width = ppl.pipelineSceneData.shadows.size.x;
  621. var height = ppl.pipelineSceneData.shadows.size.y;
  622. this._viewport.left = 0;
  623. this._viewport.top = 0;
  624. this._viewport.width = width;
  625. this._viewport.height = height; // ----------------------------------------------------------------
  626. // CSM Shadow Map
  627. // ----------------------------------------------------------------
  628. var pass = ppl.addRenderPass(width, height, 'default');
  629. pass.name = 'CascadedShadowMap';
  630. pass.addRenderTarget("ShadowMap" + id, LoadOp.CLEAR, StoreOp.STORE, new Color(1, 1, 1, 1));
  631. pass.addDepthStencil("ShadowDepth" + id, LoadOp.CLEAR, StoreOp.DISCARD);
  632. var csmLevel = ppl.pipelineSceneData.csmSupported ? light.csmLevel : 1; // Add shadow map viewports
  633. for (var level = 0; level !== csmLevel; ++level) {
  634. getCsmMainLightViewport(light, width, height, level, this._viewport, this._configs.screenSpaceSignY);
  635. var queue = pass.addQueue(QueueHint.NONE, 'shadow-caster');
  636. if (!this._configs.isWebGPU) {
  637. // Temporary workaround for WebGPU
  638. queue.setViewport(this._viewport);
  639. }
  640. queue.addScene(camera, SceneFlags.OPAQUE | SceneFlags.MASK | SceneFlags.SHADOW_CASTER).useLightFrustum(light, level);
  641. }
  642. }
  643. _addCopyPass(ppl, width, height, input, output) {
  644. var pass = ppl.addRenderPass(width, height, 'cc-tone-mapping');
  645. pass.addRenderTarget(output, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  646. pass.addTexture(input, 'inputTexture');
  647. pass.setVec4('g_platform', this._configs.platform);
  648. pass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(this._copyAndTonemapMaterial, 1);
  649. return pass;
  650. }
  651. _addCopyAndTonemapPass(ppl, settings, width, height, radianceName, colorName) {
  652. var pass;
  653. if (this._cameraConfigs.enableColorGrading && settings.colorGrading.material && settings.colorGrading.colorGradingMap) {
  654. var lutTex = settings.colorGrading.colorGradingMap;
  655. this._colorGradingTexSize.x = lutTex.width;
  656. this._colorGradingTexSize.y = lutTex.height;
  657. var isSquareMap = lutTex.width === lutTex.height;
  658. if (isSquareMap) {
  659. pass = ppl.addRenderPass(width, height, 'cc-color-grading-8x8');
  660. } else {
  661. pass = ppl.addRenderPass(width, height, 'cc-color-grading-nx1');
  662. }
  663. pass.addRenderTarget(colorName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  664. pass.addTexture(radianceName, 'sceneColorMap');
  665. pass.setVec4('g_platform', this._configs.platform);
  666. pass.setVec2('lutTextureSize', this._colorGradingTexSize);
  667. pass.setFloat('contribute', settings.colorGrading.contribute);
  668. pass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(settings.colorGrading.material, isSquareMap ? 1 : 0);
  669. } else {
  670. pass = ppl.addRenderPass(width, height, 'cc-tone-mapping');
  671. pass.addRenderTarget(colorName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  672. pass.addTexture(radianceName, 'inputTexture');
  673. pass.setVec4('g_platform', this._configs.platform);
  674. if (settings.toneMapping.material) {
  675. pass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(settings.toneMapping.material, 0);
  676. } else {
  677. pass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(this._copyAndTonemapMaterial, 0);
  678. }
  679. }
  680. return pass;
  681. }
  682. _buildForwardMainLightPass(pass, id, camera, colorName, depthStencilName, depthStencilStoreOp, mainLight, scene) {
  683. if (scene === void 0) {
  684. scene = null;
  685. }
  686. // set viewport
  687. pass.setViewport(this._viewport);
  688. var colorStoreOp = this._cameraConfigs.enableMSAA ? StoreOp.DISCARD : StoreOp.STORE; // bind output render target
  689. if (forwardNeedClearColor(camera)) {
  690. pass.addRenderTarget(colorName, LoadOp.CLEAR, colorStoreOp, this._clearColor);
  691. } else {
  692. pass.addRenderTarget(colorName, LoadOp.LOAD, colorStoreOp);
  693. } // bind depth stencil buffer
  694. if (DEBUG) {
  695. if (colorName === this._cameraConfigs.colorName && depthStencilName !== this._cameraConfigs.depthStencilName) {
  696. warn('Default framebuffer cannot use custom depth stencil buffer');
  697. }
  698. }
  699. if (camera.clearFlag & ClearFlagBit.DEPTH_STENCIL) {
  700. pass.addDepthStencil(depthStencilName, LoadOp.CLEAR, depthStencilStoreOp, camera.clearDepth, camera.clearStencil, camera.clearFlag & ClearFlagBit.DEPTH_STENCIL);
  701. } else {
  702. pass.addDepthStencil(depthStencilName, LoadOp.LOAD, depthStencilStoreOp);
  703. } // Set shadow map if enabled
  704. if (this._cameraConfigs.enableMainLightShadowMap) {
  705. pass.addTexture("ShadowMap" + id, 'cc_shadowMap');
  706. } // TODO(zhouzhenglong): Separate OPAQUE and MASK queue
  707. // add opaque and mask queue
  708. pass.addQueue(QueueHint.NONE) // Currently we put OPAQUE and MASK into one queue, so QueueHint is NONE
  709. .addScene(camera, SceneFlags.OPAQUE | SceneFlags.MASK, mainLight || undefined, scene ? scene : undefined);
  710. }
  711. _addDepthOfFieldPasses(ppl, settings, dofMaterial, id, camera, width, height, dofRadianceName, depthStencil, radianceName, ldrColorName) {
  712. // https://catlikecoding.com/unity/tutorials/advanced-rendering/depth-of-field/
  713. this._cocParams.x = settings.depthOfField.focusDistance;
  714. this._cocParams.y = settings.depthOfField.focusRange;
  715. this._cocParams.z = settings.depthOfField.bokehRadius;
  716. this._cocParams.w = 0.0;
  717. this._cocTexSize.x = 1.0 / width;
  718. this._cocTexSize.y = 1.0 / height;
  719. this._cocTexSize.z = width;
  720. this._cocTexSize.w = height;
  721. var halfWidth = Math.max(Math.floor(width / 2), 1);
  722. var halfHeight = Math.max(Math.floor(height / 2), 1);
  723. var cocName = ldrColorName;
  724. var prefilterName = "DofPrefilter" + id;
  725. var bokehName = "DofBokeh" + id;
  726. var filterName = "DofFilter" + id; // CoC
  727. var cocPass = ppl.addRenderPass(width, height, 'cc-dof-coc');
  728. cocPass.addRenderTarget(cocName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  729. cocPass.addTexture(depthStencil, 'DepthTex');
  730. cocPass.setVec4('g_platform', this._configs.platform);
  731. cocPass.setMat4('proj', camera.matProj);
  732. cocPass.setVec4('cocParams', this._cocParams);
  733. cocPass.addQueue(QueueHint.OPAQUE).addCameraQuad(camera, dofMaterial, 0); // addCameraQuad will set camera related UBOs
  734. // Downsample and Prefilter
  735. var prefilterPass = ppl.addRenderPass(halfWidth, halfHeight, 'cc-dof-prefilter');
  736. prefilterPass.addRenderTarget(prefilterName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  737. prefilterPass.addTexture(dofRadianceName, 'colorTex');
  738. prefilterPass.addTexture(cocName, 'cocTex');
  739. prefilterPass.setVec4('g_platform', this._configs.platform);
  740. prefilterPass.setVec4('mainTexTexelSize', this._cocTexSize);
  741. prefilterPass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(dofMaterial, 1); // Bokeh blur
  742. var bokehPass = ppl.addRenderPass(halfWidth, halfHeight, 'cc-dof-bokeh');
  743. bokehPass.addRenderTarget(bokehName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  744. bokehPass.addTexture(prefilterName, 'prefilterTex');
  745. bokehPass.setVec4('g_platform', this._configs.platform);
  746. bokehPass.setVec4('mainTexTexelSize', this._cocTexSize);
  747. bokehPass.setVec4('cocParams', this._cocParams);
  748. bokehPass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(dofMaterial, 2); // Filtering
  749. var filterPass = ppl.addRenderPass(halfWidth, halfHeight, 'cc-dof-filter');
  750. filterPass.addRenderTarget(filterName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  751. filterPass.addTexture(bokehName, 'bokehTex');
  752. filterPass.setVec4('g_platform', this._configs.platform);
  753. filterPass.setVec4('mainTexTexelSize', this._cocTexSize);
  754. filterPass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(dofMaterial, 3); // Combine
  755. var combinePass = ppl.addRenderPass(width, height, 'cc-dof-combine');
  756. combinePass.addRenderTarget(radianceName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  757. combinePass.addTexture(dofRadianceName, 'colorTex');
  758. combinePass.addTexture(cocName, 'cocTex');
  759. combinePass.addTexture(filterName, 'filterTex');
  760. combinePass.setVec4('g_platform', this._configs.platform);
  761. combinePass.setVec4('cocParams', this._cocParams);
  762. combinePass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(dofMaterial, 4);
  763. }
  764. _addKawaseDualFilterBloomPasses(ppl, settings, bloomMaterial, id, width, height, radianceName) {
  765. // Based on Kawase Dual Filter Blur. Saves bandwidth on mobile devices.
  766. // eslint-disable-next-line max-len
  767. // https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-20-66/siggraph2015_2D00_mmg_2D00_marius_2D00_slides.pdf
  768. // Size: [prefilter(1/2), downsample(1/4), downsample(1/8), downsample(1/16), ...]
  769. var iterations = settings.bloom.iterations;
  770. var sizeCount = iterations + 1;
  771. this._bloomWidths.length = sizeCount;
  772. this._bloomHeights.length = sizeCount;
  773. this._bloomWidths[0] = Math.max(Math.floor(width / 2), 1);
  774. this._bloomHeights[0] = Math.max(Math.floor(height / 2), 1);
  775. for (var i = 1; i !== sizeCount; ++i) {
  776. this._bloomWidths[i] = Math.max(Math.floor(this._bloomWidths[i - 1] / 2), 1);
  777. this._bloomHeights[i] = Math.max(Math.floor(this._bloomHeights[i - 1] / 2), 1);
  778. } // Bloom texture names
  779. this._bloomTexNames.length = sizeCount;
  780. for (var _i2 = 0; _i2 !== sizeCount; ++_i2) {
  781. this._bloomTexNames[_i2] = "BloomTex" + id + "_" + _i2;
  782. } // Setup bloom parameters
  783. this._bloomParams.x = this._configs.useFloatOutput ? 1 : 0;
  784. this._bloomParams.x = 0; // unused
  785. this._bloomParams.z = settings.bloom.threshold;
  786. this._bloomParams.w = settings.bloom.enableAlphaMask ? 1 : 0; // Prefilter pass
  787. var prefilterPass = ppl.addRenderPass(this._bloomWidths[0], this._bloomHeights[0], 'cc-bloom-prefilter');
  788. prefilterPass.addRenderTarget(this._bloomTexNames[0], LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  789. prefilterPass.addTexture(radianceName, 'inputTexture');
  790. prefilterPass.setVec4('g_platform', this._configs.platform);
  791. prefilterPass.setVec4('bloomParams', this._bloomParams);
  792. prefilterPass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(bloomMaterial, 0); // Downsample passes
  793. for (var _i3 = 1; _i3 !== sizeCount; ++_i3) {
  794. var downPass = ppl.addRenderPass(this._bloomWidths[_i3], this._bloomHeights[_i3], 'cc-bloom-downsample');
  795. downPass.addRenderTarget(this._bloomTexNames[_i3], LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  796. downPass.addTexture(this._bloomTexNames[_i3 - 1], 'bloomTexture');
  797. this._bloomTexSize.x = this._bloomWidths[_i3 - 1];
  798. this._bloomTexSize.y = this._bloomHeights[_i3 - 1];
  799. downPass.setVec4('g_platform', this._configs.platform);
  800. downPass.setVec4('bloomTexSize', this._bloomTexSize);
  801. downPass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(bloomMaterial, 1);
  802. } // Upsample passes
  803. for (var _i4 = iterations; _i4-- > 0;) {
  804. var upPass = ppl.addRenderPass(this._bloomWidths[_i4], this._bloomHeights[_i4], 'cc-bloom-upsample');
  805. upPass.addRenderTarget(this._bloomTexNames[_i4], LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  806. upPass.addTexture(this._bloomTexNames[_i4 + 1], 'bloomTexture');
  807. this._bloomTexSize.x = this._bloomWidths[_i4 + 1];
  808. this._bloomTexSize.y = this._bloomHeights[_i4 + 1];
  809. upPass.setVec4('g_platform', this._configs.platform);
  810. upPass.setVec4('bloomTexSize', this._bloomTexSize);
  811. upPass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(bloomMaterial, 2);
  812. } // Combine pass
  813. var combinePass = ppl.addRenderPass(width, height, 'cc-bloom-combine');
  814. combinePass.addRenderTarget(radianceName, LoadOp.LOAD, StoreOp.STORE);
  815. combinePass.addTexture(this._bloomTexNames[0], 'bloomTexture');
  816. combinePass.setVec4('g_platform', this._configs.platform);
  817. combinePass.setVec4('bloomParams', this._bloomParams);
  818. combinePass.addQueue(QueueHint.BLEND).addFullscreenQuad(bloomMaterial, 3);
  819. }
  820. _addFsrPass(ppl, settings, fsrMaterial, id, width, height, ldrColorName, nativeWidth, nativeHeight, colorName) {
  821. this._fsrTexSize.x = width;
  822. this._fsrTexSize.y = height;
  823. this._fsrTexSize.z = nativeWidth;
  824. this._fsrTexSize.w = nativeHeight;
  825. this._fsrParams.x = clamp(1.0 - settings.fsr.sharpness, 0.02, 0.98);
  826. var fsrColorName = "FsrColor" + id;
  827. var easuPass = ppl.addRenderPass(nativeWidth, nativeHeight, 'cc-fsr-easu');
  828. easuPass.addRenderTarget(fsrColorName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  829. easuPass.addTexture(ldrColorName, 'outputResultMap');
  830. easuPass.setVec4('g_platform', this._configs.platform);
  831. easuPass.setVec4('fsrTexSize', this._fsrTexSize);
  832. easuPass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(fsrMaterial, 0);
  833. var rcasPass = ppl.addRenderPass(nativeWidth, nativeHeight, 'cc-fsr-rcas');
  834. rcasPass.addRenderTarget(colorName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  835. rcasPass.addTexture(fsrColorName, 'outputResultMap');
  836. rcasPass.setVec4('g_platform', this._configs.platform);
  837. rcasPass.setVec4('fsrTexSize', this._fsrTexSize);
  838. rcasPass.setVec4('fsrParams', this._fsrParams);
  839. rcasPass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(fsrMaterial, 1);
  840. return rcasPass;
  841. }
  842. _addFxaaPass(ppl, fxaaMaterial, width, height, ldrColorName, colorName) {
  843. this._fxaaParams.x = width;
  844. this._fxaaParams.y = height;
  845. this._fxaaParams.z = 1 / width;
  846. this._fxaaParams.w = 1 / height;
  847. var pass = ppl.addRenderPass(width, height, 'cc-fxaa');
  848. pass.addRenderTarget(colorName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
  849. pass.addTexture(ldrColorName, 'sceneColorMap');
  850. pass.setVec4('g_platform', this._configs.platform);
  851. pass.setVec4('texSize', this._fxaaParams);
  852. pass.addQueue(QueueHint.OPAQUE).addFullscreenQuad(fxaaMaterial, 0);
  853. return pass;
  854. }
  855. _addUIQueue(camera, pass) {
  856. var flags = SceneFlags.UI;
  857. if (this._cameraConfigs.enableProfiler) {
  858. flags |= SceneFlags.PROFILER;
  859. pass.showStatistics = true;
  860. }
  861. pass.addQueue(QueueHint.BLEND, 'default', 'default').addScene(camera, flags);
  862. } // ----------------------------------------------------------------
  863. // Forward
  864. // ----------------------------------------------------------------
  865. _addForwardRadiancePasses(ppl, id, camera, width, height, mainLight, colorName, depthStencilName, disableMSAA, depthStencilStoreOp) {
  866. if (disableMSAA === void 0) {
  867. disableMSAA = false;
  868. }
  869. if (depthStencilStoreOp === void 0) {
  870. depthStencilStoreOp = StoreOp.DISCARD;
  871. }
  872. // ----------------------------------------------------------------
  873. // Dynamic states
  874. // ----------------------------------------------------------------
  875. // Prepare camera clear color
  876. var clearColor = camera.clearColor; // Reduce C++/TS interop
  877. this._clearColor.x = clearColor.x;
  878. this._clearColor.y = clearColor.y;
  879. this._clearColor.z = clearColor.z;
  880. this._clearColor.w = clearColor.w; // Prepare camera viewport
  881. var viewport = camera.viewport; // Reduce C++/TS interop
  882. this._viewport.left = Math.round(viewport.x * width);
  883. this._viewport.top = Math.round(viewport.y * height); // Here we must use camera.viewport.width instead of camera.viewport.z, which
  884. // is undefined on native platform. The same as camera.viewport.height.
  885. this._viewport.width = Math.max(Math.round(viewport.width * width), 1);
  886. this._viewport.height = Math.max(Math.round(viewport.height * height), 1); // MSAA
  887. var enableMSAA = !disableMSAA && this._cameraConfigs.enableMSAA;
  888. assert(!enableMSAA || this._cameraConfigs.singleForwardRadiancePass); // ----------------------------------------------------------------
  889. // Forward Lighting (Main Directional Light)
  890. // ----------------------------------------------------------------
  891. var pass = this._cameraConfigs.singleForwardRadiancePass ? this._addForwardSingleRadiancePass(ppl, id, camera, enableMSAA, width, height, mainLight, colorName, depthStencilName, depthStencilStoreOp) : this._addForwardMultipleRadiancePasses(ppl, id, camera, width, height, mainLight, colorName, depthStencilName, depthStencilStoreOp); // Planar Shadow
  892. if (this._cameraConfigs.enableMainLightPlanarShadowMap) {
  893. this.addPlanarShadowQueue(camera, mainLight, pass);
  894. } // ----------------------------------------------------------------
  895. // Forward Lighting (Blend)
  896. // ----------------------------------------------------------------
  897. // Add transparent queue
  898. var sceneFlags = SceneFlags.BLEND | (camera.geometryRenderer ? SceneFlags.GEOMETRY : SceneFlags.NONE);
  899. pass.addQueue(QueueHint.BLEND).addScene(camera, sceneFlags, mainLight || undefined);
  900. return pass;
  901. }
  902. _addForwardSingleRadiancePass(ppl, id, camera, enableMSAA, width, height, mainLight, colorName, depthStencilName, depthStencilStoreOp) {
  903. assert(this._cameraConfigs.singleForwardRadiancePass); // ----------------------------------------------------------------
  904. // Forward Lighting (Main Directional Light)
  905. // ----------------------------------------------------------------
  906. var pass;
  907. if (enableMSAA) {
  908. var msaaRadianceName = "MsaaRadiance" + id;
  909. var msaaDepthStencilName = "MsaaDepthStencil" + id;
  910. var sampleCount = this._cameraConfigs.settings.msaa.sampleCount;
  911. var msPass = ppl.addMultisampleRenderPass(width, height, sampleCount, 0, 'default');
  912. msPass.name = 'MsaaForwardPass'; // MSAA always discards depth stencil
  913. this._buildForwardMainLightPass(msPass, id, camera, msaaRadianceName, msaaDepthStencilName, StoreOp.DISCARD, mainLight);
  914. msPass.resolveRenderTarget(msaaRadianceName, colorName);
  915. pass = msPass;
  916. } else {
  917. pass = ppl.addRenderPass(width, height, 'default');
  918. pass.name = 'ForwardPass';
  919. this._buildForwardMainLightPass(pass, id, camera, colorName, depthStencilName, depthStencilStoreOp, mainLight);
  920. }
  921. assert(pass !== undefined); // Forward Lighting (Additive Lights)
  922. this.forwardLighting.addLightQueues(pass, camera, this._configs.mobileMaxSpotLightShadowMaps);
  923. return pass;
  924. }
  925. addPlanarShadowQueue(camera, mainLight, pass) {
  926. pass.addQueue(QueueHint.BLEND, 'planar-shadow').addScene(camera, SceneFlags.SHADOW_CASTER | SceneFlags.PLANAR_SHADOW | SceneFlags.BLEND, mainLight || undefined);
  927. }
  928. _addForwardMultipleRadiancePasses(ppl, id, camera, width, height, mainLight, colorName, depthStencilName, depthStencilStoreOp) {
  929. assert(!this._cameraConfigs.singleForwardRadiancePass); // Forward Lighting (Main Directional Light)
  930. var pass = ppl.addRenderPass(width, height, 'default');
  931. pass.name = 'ForwardPass';
  932. var firstStoreOp = this.forwardLighting.isMultipleLightPassesNeeded() ? StoreOp.STORE : depthStencilStoreOp;
  933. this._buildForwardMainLightPass(pass, id, camera, colorName, depthStencilName, firstStoreOp, mainLight); // Forward Lighting (Additive Lights)
  934. pass = this.forwardLighting.addLightPasses(colorName, depthStencilName, depthStencilStoreOp, id, width, height, camera, this._viewport, ppl, pass);
  935. return pass;
  936. }
  937. _buildReflectionProbePass(pass, id, camera, colorName, depthStencilName, mainLight, scene) {
  938. if (scene === void 0) {
  939. scene = null;
  940. }
  941. // set viewport
  942. var colorStoreOp = this._cameraConfigs.enableMSAA ? StoreOp.DISCARD : StoreOp.STORE; // bind output render target
  943. if (forwardNeedClearColor(camera)) {
  944. this._reflectionProbeClearColor.x = camera.clearColor.x;
  945. this._reflectionProbeClearColor.y = camera.clearColor.y;
  946. this._reflectionProbeClearColor.z = camera.clearColor.z;
  947. var clearColor = rendering.packRGBE(this._reflectionProbeClearColor);
  948. this._clearColor.x = clearColor.x;
  949. this._clearColor.y = clearColor.y;
  950. this._clearColor.z = clearColor.z;
  951. this._clearColor.w = clearColor.w;
  952. pass.addRenderTarget(colorName, LoadOp.CLEAR, colorStoreOp, this._clearColor);
  953. } else {
  954. pass.addRenderTarget(colorName, LoadOp.LOAD, colorStoreOp);
  955. } // bind depth stencil buffer
  956. if (camera.clearFlag & ClearFlagBit.DEPTH_STENCIL) {
  957. pass.addDepthStencil(depthStencilName, LoadOp.CLEAR, StoreOp.DISCARD, camera.clearDepth, camera.clearStencil, camera.clearFlag & ClearFlagBit.DEPTH_STENCIL);
  958. } else {
  959. pass.addDepthStencil(depthStencilName, LoadOp.LOAD, StoreOp.DISCARD);
  960. } // Set shadow map if enabled
  961. if (this._cameraConfigs.enableMainLightShadowMap) {
  962. pass.addTexture("ShadowMap" + id, 'cc_shadowMap');
  963. } // TODO(zhouzhenglong): Separate OPAQUE and MASK queue
  964. // add opaque and mask queue
  965. pass.addQueue(QueueHint.NONE, 'reflect-map') // Currently we put OPAQUE and MASK into one queue, so QueueHint is NONE
  966. .addScene(camera, SceneFlags.OPAQUE | SceneFlags.MASK | SceneFlags.REFLECTION_PROBE, mainLight || undefined, scene ? scene : undefined);
  967. }
  968. _tryAddReflectionProbePasses(ppl, id, mainLight, scene) {
  969. var reflectionProbeManager = cclegacy.internal.reflectionProbeManager;
  970. if (!reflectionProbeManager) {
  971. return;
  972. }
  973. var probes = reflectionProbeManager.getProbes();
  974. var maxProbeCount = 4;
  975. var probeID = 0;
  976. for (var probe of probes) {
  977. if (!probe.needRender) {
  978. continue;
  979. }
  980. var area = probe.renderArea();
  981. var width = Math.max(Math.floor(area.x), 1);
  982. var height = Math.max(Math.floor(area.y), 1);
  983. if (probe.probeType === renderer.scene.ProbeType.PLANAR) {
  984. if (!this._cameraConfigs.enablePlanarReflectionProbe) {
  985. continue;
  986. }
  987. var window = probe.realtimePlanarTexture.window;
  988. var colorName = "PlanarProbeRT" + probeID;
  989. var depthStencilName = "PlanarProbeDS" + probeID; // ProbeResource
  990. ppl.addRenderWindow(colorName, this._cameraConfigs.radianceFormat, width, height, window);
  991. ppl.addDepthStencil(depthStencilName, gfx.Format.DEPTH_STENCIL, width, height, ResourceResidency.MEMORYLESS); // Rendering
  992. var probePass = ppl.addRenderPass(width, height, 'default');
  993. probePass.name = "PlanarReflectionProbe" + probeID;
  994. this._buildReflectionProbePass(probePass, id, probe.camera, colorName, depthStencilName, mainLight, scene);
  995. } else if (EDITOR) {
  996. for (var faceIdx = 0; faceIdx < probe.bakedCubeTextures.length; faceIdx++) {
  997. probe.updateCameraDir(faceIdx);
  998. var _window = probe.bakedCubeTextures[faceIdx].window;
  999. var _colorName = "CubeProbeRT" + probeID + faceIdx;
  1000. var _depthStencilName = "CubeProbeDS" + probeID + faceIdx; // ProbeResource
  1001. ppl.addRenderWindow(_colorName, this._cameraConfigs.radianceFormat, width, height, _window);
  1002. ppl.addDepthStencil(_depthStencilName, gfx.Format.DEPTH_STENCIL, width, height, ResourceResidency.MEMORYLESS); // Rendering
  1003. var _probePass = ppl.addRenderPass(width, height, 'default');
  1004. _probePass.name = "CubeProbe" + probeID + faceIdx;
  1005. this._buildReflectionProbePass(_probePass, id, probe.camera, _colorName, _depthStencilName, mainLight, scene);
  1006. }
  1007. probe.needRender = false;
  1008. }
  1009. ++probeID;
  1010. if (probeID === maxProbeCount) {
  1011. break;
  1012. }
  1013. }
  1014. }
  1015. _initMaterials(ppl) {
  1016. if (this._initialized) {
  1017. return 0;
  1018. }
  1019. setupPipelineConfigs(ppl, this._configs); // When add new effect asset, please add its uuid to the dependentAssets in cc.config.json.
  1020. this._copyAndTonemapMaterial._uuid = "builtin-pipeline-tone-mapping-material";
  1021. this._copyAndTonemapMaterial.initialize({
  1022. effectName: 'pipeline/post-process/tone-mapping'
  1023. });
  1024. if (this._copyAndTonemapMaterial.effectAsset) {
  1025. this._initialized = true;
  1026. }
  1027. return this._initialized ? 0 : 1;
  1028. }
  1029. }
  1030. rendering.setCustomPipeline('Builtin', new BuiltinPipelineBuilder());
  1031. } // if (rendering)
  1032. _cclegacy._RF.pop();
  1033. _crd = false;
  1034. }
  1035. };
  1036. });
  1037. //# sourceMappingURL=59b7958b47eec6168615a6469581f8f48e26cb00.js.map