Skip to content
Snippets Groups Projects
Commit 6ed42e95 authored by Alexander Rose's avatar Alexander Rose
Browse files

add mipmap-based blur for skybox backgrounds

parent fb01ba60
No related branches found
No related tags found
No related merge requests found
...@@ -6,6 +6,8 @@ Note that since we don't clearly distinguish between a public and private interf ...@@ -6,6 +6,8 @@ Note that since we don't clearly distinguish between a public and private interf
## [Unreleased] ## [Unreleased]
- Add mipmap-based blur for skybox backgrounds
## [v3.19.0] - 2022-10-01 ## [v3.19.0] - 2022-10-01
- Fix "empty textures" error on empty canvas - Fix "empty textures" error on empty canvas
......
...@@ -72,6 +72,7 @@ export const Backgrounds = PluginBehavior.create<{ }>({ ...@@ -72,6 +72,7 @@ export const Backgrounds = PluginBehavior.create<{ }>({
lightness: 0, lightness: 0,
saturation: 0, saturation: 0,
opacity: 1, opacity: 1,
blur: 0.3,
} }
} }
}, 'Purple Nebula Skybox'], }, 'Purple Nebula Skybox'],
......
...@@ -49,6 +49,7 @@ const SkyboxParams = { ...@@ -49,6 +49,7 @@ const SkyboxParams = {
pz: PD.File({ label: 'Positive Z / Front', accept: 'image/*' }), pz: PD.File({ label: 'Positive Z / Front', accept: 'image/*' }),
}, { isExpanded: true, label: 'Files' }), }, { isExpanded: true, label: 'Files' }),
}), }),
blur: PD.Numeric(0, { min: 0.0, max: 1.0, step: 0.01 }, { description: 'Note, this only works in WebGL2 or when "EXT_shader_texture_lod" is available.' }),
...SharedParams, ...SharedParams,
}; };
type SkyboxProps = PD.Values<typeof SkyboxParams> type SkyboxProps = PD.Values<typeof SkyboxParams>
...@@ -170,6 +171,7 @@ export class BackgroundPass { ...@@ -170,6 +171,7 @@ export class BackgroundPass {
Mat4.invert(m, m); Mat4.invert(m, m);
ValueCell.update(this.renderable.values.uViewDirectionProjectionInverse, m); ValueCell.update(this.renderable.values.uViewDirectionProjectionInverse, m);
ValueCell.updateIfChanged(this.renderable.values.uBlur, props.blur);
ValueCell.updateIfChanged(this.renderable.values.uOpacity, props.opacity); ValueCell.updateIfChanged(this.renderable.values.uOpacity, props.opacity);
ValueCell.updateIfChanged(this.renderable.values.uSaturation, props.saturation); ValueCell.updateIfChanged(this.renderable.values.uSaturation, props.saturation);
ValueCell.updateIfChanged(this.renderable.values.uLightness, props.lightness); ValueCell.updateIfChanged(this.renderable.values.uLightness, props.lightness);
...@@ -367,7 +369,7 @@ function getSkyboxTexture(ctx: WebGLContext, assetManager: AssetManager, faces: ...@@ -367,7 +369,7 @@ function getSkyboxTexture(ctx: WebGLContext, assetManager: AssetManager, faces:
const cubeAssets = getCubeAssets(assetManager, faces); const cubeAssets = getCubeAssets(assetManager, faces);
const cubeFaces = getCubeFaces(assetManager, cubeAssets); const cubeFaces = getCubeFaces(assetManager, cubeAssets);
const assets = [cubeAssets.nx, cubeAssets.ny, cubeAssets.nz, cubeAssets.px, cubeAssets.py, cubeAssets.pz]; const assets = [cubeAssets.nx, cubeAssets.ny, cubeAssets.nz, cubeAssets.px, cubeAssets.py, cubeAssets.pz];
const texture = ctx.resources.cubeTexture(cubeFaces, false, onload); const texture = ctx.resources.cubeTexture(cubeFaces, true, onload);
return { texture, assets }; return { texture, assets };
} }
...@@ -424,12 +426,15 @@ const BackgroundSchema = { ...@@ -424,12 +426,15 @@ const BackgroundSchema = {
uGradientColorA: UniformSpec('v3'), uGradientColorA: UniformSpec('v3'),
uGradientColorB: UniformSpec('v3'), uGradientColorB: UniformSpec('v3'),
uGradientRatio: UniformSpec('f'), uGradientRatio: UniformSpec('f'),
uBlur: UniformSpec('f'),
uOpacity: UniformSpec('f'), uOpacity: UniformSpec('f'),
uSaturation: UniformSpec('f'), uSaturation: UniformSpec('f'),
uLightness: UniformSpec('f'), uLightness: UniformSpec('f'),
dVariant: DefineSpec('string', ['skybox', 'image', 'verticalGradient', 'horizontalGradient', 'radialGradient']), dVariant: DefineSpec('string', ['skybox', 'image', 'verticalGradient', 'horizontalGradient', 'radialGradient']),
}; };
const SkyboxShaderCode = ShaderCode('background', background_vert, background_frag); const SkyboxShaderCode = ShaderCode('background', background_vert, background_frag, {
shaderTextureLod: 'optional'
});
type BackgroundRenderable = ComputeRenderable<Values<typeof BackgroundSchema>> type BackgroundRenderable = ComputeRenderable<Values<typeof BackgroundSchema>>
function getBackgroundRenderable(ctx: WebGLContext, width: number, height: number): BackgroundRenderable { function getBackgroundRenderable(ctx: WebGLContext, width: number, height: number): BackgroundRenderable {
...@@ -448,6 +453,7 @@ function getBackgroundRenderable(ctx: WebGLContext, width: number, height: numbe ...@@ -448,6 +453,7 @@ function getBackgroundRenderable(ctx: WebGLContext, width: number, height: numbe
uGradientColorA: ValueCell.create(Vec3()), uGradientColorA: ValueCell.create(Vec3()),
uGradientColorB: ValueCell.create(Vec3()), uGradientColorB: ValueCell.create(Vec3()),
uGradientRatio: ValueCell.create(0.5), uGradientRatio: ValueCell.create(0.5),
uBlur: ValueCell.create(0),
uOpacity: ValueCell.create(1), uOpacity: ValueCell.create(1),
uSaturation: ValueCell.create(0), uSaturation: ValueCell.create(0),
uLightness: ValueCell.create(0), uLightness: ValueCell.create(0),
......
...@@ -6,6 +6,7 @@ precision mediump sampler2D; ...@@ -6,6 +6,7 @@ precision mediump sampler2D;
#if defined(dVariant_skybox) #if defined(dVariant_skybox)
uniform samplerCube tSkybox; uniform samplerCube tSkybox;
uniform mat4 uViewDirectionProjectionInverse; uniform mat4 uViewDirectionProjectionInverse;
uniform float uBlur;
uniform float uOpacity; uniform float uOpacity;
uniform float uSaturation; uniform float uSaturation;
uniform float uLightness; uniform float uLightness;
...@@ -49,7 +50,11 @@ vec3 lightenColor(vec3 c, float amount) { ...@@ -49,7 +50,11 @@ vec3 lightenColor(vec3 c, float amount) {
void main() { void main() {
#if defined(dVariant_skybox) #if defined(dVariant_skybox)
vec4 t = uViewDirectionProjectionInverse * vPosition; vec4 t = uViewDirectionProjectionInverse * vPosition;
#ifdef enabledShaderTextureLod
gl_FragColor = textureCubeLodEXT(tSkybox, normalize(t.xyz / t.w), uBlur * 8.0);
#else
gl_FragColor = textureCube(tSkybox, normalize(t.xyz / t.w)); gl_FragColor = textureCube(tSkybox, normalize(t.xyz / t.w));
#endif
gl_FragColor.a = uOpacity; gl_FragColor.a = uOpacity;
gl_FragColor.rgb = lightenColor(saturateColor(gl_FragColor.rgb, uSaturation), uLightness); gl_FragColor.rgb = lightenColor(saturateColor(gl_FragColor.rgb, uSaturation), uLightness);
#elif defined(dVariant_image) #elif defined(dVariant_image)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment