# Downsampled SphericalHarmonics Creation

**URL:** <https://forum.babylonjs.com/t/downsampled-sphericalharmonics-creation/62858>\
**Category:** Completed Features\
**Tags:** ibl, environment, performance, hdr, cubetexture\
**Created:** [March 20, 2026, 8:18am UTC](https://forum.babylonjs.com/t/downsampled-sphericalharmonics-creation/62858 "2026-03-20T08:18:38Z")\
**Posts on this page:** 1\
**Showing post:** 6

<div class="post-metadata">

**Author:** ![kzhsw](https://avatars.discourse-cdn.com/v4/letter/k/848f3c/32.png) [@kzhsw](https://forum.babylonjs.com/u/kzhsw)\
**Post date:** [March 25, 2026, 7:39am UTC](https://forum.babylonjs.com/t/downsampled-sphericalharmonics-creation/62858/6 "2026-03-25T07:39:20Z")

</div>

Ok, here are estimated files to change:

1. baseTexture.polynomial.ts

- Added \_sphericalPolynomialTargetSize: number via module augmentation on BaseTexture
- Initialized to 0 on prototype (default = full resolution, no behavior change)

1. cubeTexture.ts

- Added sphericalPolynomialTargetSize?: number to ICubeTextureCreationOptions
- Wired through constructor options handling

1. envCubeTexture.ts

- Added sphericalPolynomialTargetSize = 0 constructor parameter
- Stores on instance; passes to ConvertCubeMapToSphericalPolynomial in the eager (HDR/EXR) path

1. hdrCubeTexture.ts

- Added sphericalPolynomialTargetSize = 0 constructor parameter, passes through to EnvCubeTexture

1. equiRectangularCubeTexture.ts

- Added sphericalPolynomialTargetSize = 0 constructor parameter, stores on instance
- Added side-effect import of baseTexture.polynomial

1. cubemapToSphericalPolynomial.ts (main logic)

- GPU path (ConvertCubeMapTextureToSphericalPolynomial): reads texture.\_sphericalPolynomialTargetSize, if mipmaps available reads from computed mip level, otherwise falls back to CPU box-filter downsample after readback
- CPU path (ConvertCubeMapToSphericalPolynomial): accepts optional targetSize parameter, downsamples each face before integration
- \_DownsampleFace: box-filter averaging helper, handles both Float32Array and Uint8Array
- \_NearestPow2Floor: clamps non-pow-2 target sizes to nearest power-of-two (rounding down) — so passing e.g. 100 silently becomes 64

And here is a playground, open devtools console to compare performance:

> **[Babylon.js Playground](https://playground.babylonjs.com/#2FDQT5%233075)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL and WebGPU 3D scenes

 ![playground](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/3/4/346f261c0ba4ede9292cb0d237adf019d94068f8.png)  
This is less precise, but even faster than the [GPU accelerated impl](https://forum.babylonjs.com/t/gpu-sphericalharmonics-creation/62341/10)

---

_[View the full topic](https://forum.babylonjs.com/t/downsampled-sphericalharmonics-creation/62858)._
