Skip to content

Commit

Permalink
Refactor - do not create cookies render pass each time but reuse one (#…
Browse files Browse the repository at this point in the history
…5645)

Co-authored-by: Martin Valigursky <mvaligursky@snapchat.com>
  • Loading branch information
mvaligursky and Martin Valigursky authored Sep 18, 2023
1 parent bdf8eac commit 03f3fb0
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 38 deletions.
8 changes: 6 additions & 2 deletions examples/src/examples/graphics/clustered-spot-shadows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ class ClusteredSpotShadowsExample {
controls(data: Observer) {
return <>
<Panel headerText='Atlas'>
<LabelGroup text='Resolution'>
<LabelGroup text='Shadow Res'>
<SliderInput binding={new BindingTwoWay()} link={{ observer: data, path: 'settings.shadowAtlasResolution' }} min={256} max={4096} precision={0}/>
</LabelGroup>
<LabelGroup text='Cookie Res'>
<SliderInput binding={new BindingTwoWay()} link={{ observer: data, path: 'settings.cookieAtlasResolution' }} min={128} max={4096} precision={0}/>
</LabelGroup>
{<LabelGroup text='Split'>
<SelectInput binding={new BindingTwoWay()} link={{ observer: data, path: 'settings.atlasSplit' }} type="number" options={[
{ v: 0, t: 'Automatic' },
Expand Down Expand Up @@ -116,6 +119,7 @@ class ClusteredSpotShadowsExample {

data.set('settings', {
shadowAtlasResolution: 1024, // shadow map resolution storing all shadows
cookieAtlasResolution: 1024, // cookie map resolution storing all cookies
shadowType: pc.SHADOW_PCF3, // shadow filter type
shadowsEnabled: true,
cookiesEnabled: true,
Expand Down Expand Up @@ -153,7 +157,7 @@ class ClusteredSpotShadowsExample {

// resolution of the shadow and cookie atlas
lighting.shadowAtlasResolution = data.get('settings.shadowAtlasResolution');
lighting.cookieAtlasResolution = 1500;
lighting.cookieAtlasResolution = data.get('settings.cookieAtlasResolution');;

const splitOptions = [
null, // automatic - split atlas each frame to give all required lights an equal size
Expand Down
45 changes: 20 additions & 25 deletions src/scene/lighting/light-texture-atlas.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ class LightTextureAtlas {
// This needs to be a pixel more than a shadow filter needs to access.
this.shadowEdgePixels = 3;

this.cookieAtlasResolution = 2048;
this.cookieAtlas = null;
this.cookieRenderTarget = null;
this.cookieAtlasResolution = 4;
this.cookieAtlas = CookieRenderer.createTexture(this.device, this.cookieAtlasResolution);
this.cookieRenderTarget = new RenderTarget({
colorBuffer: this.cookieAtlas,
depth: false,
flipY: true
});

// available slots (of type Slot)
this.slots = [];
Expand Down Expand Up @@ -69,24 +73,20 @@ class LightTextureAtlas {
}

destroyShadowAtlas() {
if (this.shadowAtlas) {
this.shadowAtlas.destroy();
this.shadowAtlas = null;
}
this.shadowAtlas?.destroy();
this.shadowAtlas = null;
}

destroyCookieAtlas() {
if (this.cookieAtlas) {
this.cookieAtlas.destroy();
this.cookieAtlas = null;
}
if (this.cookieRenderTarget) {
this.cookieRenderTarget.destroy();
this.cookieRenderTarget = null;
}
this.cookieAtlas?.destroy();
this.cookieAtlas = null;

this.cookieRenderTarget?.destroy();
this.cookieRenderTarget = null;
}

allocateShadowAtlas(resolution) {

if (!this.shadowAtlas || this.shadowAtlas.texture.width !== resolution) {

// content of atlas is lost, force re-render of static shadows
Expand All @@ -106,19 +106,14 @@ class LightTextureAtlas {
}

allocateCookieAtlas(resolution) {
if (!this.cookieAtlas || this.cookieAtlas.width !== resolution) {

// content of atlas is lost, force re-render of static cookies
this.version++;
// resize atlas
if (this.cookieAtlas.width !== resolution) {

this.destroyCookieAtlas();
this.cookieAtlas = CookieRenderer.createTexture(this.device, resolution);
this.cookieRenderTarget.resize(resolution, resolution);

this.cookieRenderTarget = new RenderTarget({
colorBuffer: this.cookieAtlas,
depth: false,
flipY: true
});
// content of atlas is lost, force re-render of static cookies
this.version++;
}
}

Expand Down
27 changes: 18 additions & 9 deletions src/scene/renderer/cookie-renderer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DebugHelper } from '../../core/debug.js';
import { Debug, DebugHelper } from '../../core/debug.js';
import { Vec4 } from '../../core/math/vec4.js';
import { Mat4 } from '../../core/math/mat4.js';

Expand Down Expand Up @@ -60,6 +60,8 @@ class CookieRenderer {

this.blitTextureId = this.device.scope.resolve('blitTexture');
this.invViewProjId = this.device.scope.resolve('invViewProj');

this.renderPass = this.createRenderPass(lightTextureAtlas.cookieRenderTarget);
}

destroy() {
Expand Down Expand Up @@ -143,12 +145,9 @@ class CookieRenderer {
}
}

render(renderTarget, lights) {
createRenderPass(renderTarget) {

// pick lights we need to update the cookies for
this.filter(lights);
if (_filteredLights.length <= 0)
return;
Debug.assert(renderTarget);

// prepare a single render pass to render all quads to the render target
const device = this.device;
Expand Down Expand Up @@ -208,10 +207,20 @@ class CookieRenderer {
renderPass.colorOps.clear = false;
renderPass.depthStencilOps.clearDepth = false;

// render the pass
renderPass.render();
return renderPass;
}

render(lights) {

_filteredLights.length = 0;
// pick lights we need to update the cookies for
this.filter(lights);
if (_filteredLights.length > 0) {

// render the pass
this.renderPass.render();

_filteredLights.length = 0;
}
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/scene/renderer/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1159,8 +1159,7 @@ class Renderer {
}

renderCookies(lights) {
const cookieRenderTarget = this.lightTextureAtlas.cookieRenderTarget;
this._cookieRenderer.render(cookieRenderTarget, lights);
this._cookieRenderer.render(lights);
}

/**
Expand Down

0 comments on commit 03f3fb0

Please sign in to comment.