Add motion blur and better interpolation when OES_texture_float_linear is not available
This commit is contained in:
parent
2889fd54db
commit
7803bbeaee
7 changed files with 50 additions and 8 deletions
|
|
@ -18,8 +18,8 @@ export class DistanceTexture extends Texture {
|
||||||
|
|
||||||
const bufferFloatExtension = tryEnableExtension(gl, 'EXT_color_buffer_float');
|
const bufferFloatExtension = tryEnableExtension(gl, 'EXT_color_buffer_float');
|
||||||
const floatLinearExtension = tryEnableExtension(gl, 'OES_texture_float_linear');
|
const floatLinearExtension = tryEnableExtension(gl, 'OES_texture_float_linear');
|
||||||
this.floatLinearEnabled = !!bufferFloatExtension && !!floatLinearExtension;
|
|
||||||
|
|
||||||
|
this.floatLinearEnabled = !!bufferFloatExtension && !!floatLinearExtension;
|
||||||
gl.insights.floatInterpolationEnabled = this.floatLinearEnabled;
|
gl.insights.floatInterpolationEnabled = this.floatLinearEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,18 @@ export const getUniversalRenderingContext = (
|
||||||
canvas: HTMLCanvasElement,
|
canvas: HTMLCanvasElement,
|
||||||
ignoreWebGL2 = false
|
ignoreWebGL2 = false
|
||||||
): UniversalRenderingContext => {
|
): UniversalRenderingContext => {
|
||||||
|
const contextAttributes: WebGLContextAttributes = {
|
||||||
|
alpha: true,
|
||||||
|
antialias: false,
|
||||||
|
depth: false,
|
||||||
|
desynchronized: true,
|
||||||
|
preserveDrawingBuffer: true,
|
||||||
|
powerPreference: 'high-performance',
|
||||||
|
};
|
||||||
|
|
||||||
const context: WebGL2RenderingContext | WebGLRenderingContext | null = ignoreWebGL2
|
const context: WebGL2RenderingContext | WebGLRenderingContext | null = ignoreWebGL2
|
||||||
? null
|
? null
|
||||||
: canvas.getContext('webgl2');
|
: canvas.getContext('webgl2', contextAttributes);
|
||||||
|
|
||||||
let result = context as UniversalRenderingContext;
|
let result = context as UniversalRenderingContext;
|
||||||
|
|
||||||
|
|
@ -23,10 +32,13 @@ export const getUniversalRenderingContext = (
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = (canvas.getContext('webgl') ||
|
result = (canvas.getContext('webgl') ||
|
||||||
canvas.getContext('experimental-webgl')) as UniversalRenderingContext;
|
canvas.getContext('experimental-webgl', {
|
||||||
|
...contextAttributes,
|
||||||
|
alpha: false,
|
||||||
|
})) as UniversalRenderingContext;
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw new Error('Neither WebGL or WebGL2 is supported');
|
throw new Error('Neither WebGL nor WebGL2 is supported');
|
||||||
}
|
}
|
||||||
|
|
||||||
result.isWebGL2 = false;
|
result.isWebGL2 = false;
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,8 @@ export class RendererImplementation implements Renderer {
|
||||||
private stopwatch?: WebGlStopwatch;
|
private stopwatch?: WebGlStopwatch;
|
||||||
private textures: Array<Texture> = [];
|
private textures: Array<Texture> = [];
|
||||||
private palette!: PaletteTexture;
|
private palette!: PaletteTexture;
|
||||||
private _canvasSize = vec2.fromValues(1, 1);
|
private _canvasSize: vec2;
|
||||||
|
private blendFactor!: number;
|
||||||
private canvasResizeObserver!: ResizeObserver;
|
private canvasResizeObserver!: ResizeObserver;
|
||||||
|
|
||||||
private applyRuntimeSettings: {
|
private applyRuntimeSettings: {
|
||||||
|
|
@ -63,6 +64,7 @@ export class RendererImplementation implements Renderer {
|
||||||
this.distanceFieldFrameBuffer.renderScale = v;
|
this.distanceFieldFrameBuffer.renderScale = v;
|
||||||
this.gl.insights.renderPasses.distance.renderScale = v;
|
this.gl.insights.renderPasses.distance.renderScale = v;
|
||||||
},
|
},
|
||||||
|
motionBlur: (v) => (this.blendFactor = 1 - v),
|
||||||
lightsRenderScale: (v) => {
|
lightsRenderScale: (v) => {
|
||||||
this.lightingFrameBuffer.renderScale = v;
|
this.lightingFrameBuffer.renderScale = v;
|
||||||
this.gl.insights.renderPasses.lights.renderScale = v;
|
this.gl.insights.renderPasses.lights.renderScale = v;
|
||||||
|
|
@ -89,7 +91,10 @@ export class RendererImplementation implements Renderer {
|
||||||
ignoreWebGL2 !== undefined ? ignoreWebGL2 : defaultStartupSettings.ignoreWebGL2
|
ignoreWebGL2 !== undefined ? ignoreWebGL2 : defaultStartupSettings.ignoreWebGL2
|
||||||
);
|
);
|
||||||
|
|
||||||
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE);
|
this.gl.blendFunc(this.gl.CONSTANT_COLOR, this.gl.ONE_MINUS_CONSTANT_COLOR);
|
||||||
|
|
||||||
|
const { width, height } = canvas.getBoundingClientRect();
|
||||||
|
this._canvasSize = vec2.fromValues(width, height);
|
||||||
|
|
||||||
this.applyCanvasResizeObserver();
|
this.applyCanvasResizeObserver();
|
||||||
|
|
||||||
|
|
@ -144,6 +149,7 @@ export class RendererImplementation implements Renderer {
|
||||||
compiler,
|
compiler,
|
||||||
{
|
{
|
||||||
paletteSize: settings.paletteSize,
|
paletteSize: settings.paletteSize,
|
||||||
|
floatLinearEnabled: this.gl.insights.floatInterpolationEnabled ? '1' : '0',
|
||||||
backgroundColor: colorToString(settings.backgroundColor),
|
backgroundColor: colorToString(settings.backgroundColor),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -158,6 +164,7 @@ export class RendererImplementation implements Renderer {
|
||||||
{
|
{
|
||||||
shadowTraceCount: settings.shadowTraceCount.toString(),
|
shadowTraceCount: settings.shadowTraceCount.toString(),
|
||||||
intensityInsideRatio: settings.lightPenetrationRatio,
|
intensityInsideRatio: settings.lightPenetrationRatio,
|
||||||
|
floatLinearEnabled: this.gl.insights.floatInterpolationEnabled ? '1' : '0',
|
||||||
backgroundColor: colorToString(settings.backgroundColor),
|
backgroundColor: colorToString(settings.backgroundColor),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -225,7 +232,7 @@ export class RendererImplementation implements Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.distanceFieldFrameBuffer.setSize(this.canvasSize);
|
this.distanceFieldFrameBuffer.setSize(this.canvasSize);
|
||||||
this.lightingFrameBuffer.setSize(this.canvasSize);
|
const sizeChanged = this.lightingFrameBuffer.setSize(this.canvasSize);
|
||||||
|
|
||||||
const common = {
|
const common = {
|
||||||
// texture units
|
// texture units
|
||||||
|
|
@ -243,6 +250,8 @@ export class RendererImplementation implements Renderer {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.gl.enable(this.gl.BLEND);
|
this.gl.enable(this.gl.BLEND);
|
||||||
|
const q = sizeChanged ? 1 : this.blendFactor;
|
||||||
|
this.gl.blendColor(q, q, q, 1);
|
||||||
this.lightsPass.render(
|
this.lightsPass.render(
|
||||||
this.uniformsProvider.getUniforms(common),
|
this.uniformsProvider.getUniforms(common),
|
||||||
this.distanceFieldFrameBuffer.textures
|
this.distanceFieldFrameBuffer.textures
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ export const defaultRuntimeSettings: RuntimeSettings = {
|
||||||
distanceRenderScale: 0.5,
|
distanceRenderScale: 0.5,
|
||||||
lightsRenderScale: 1,
|
lightsRenderScale: 1,
|
||||||
colorPalette: [],
|
colorPalette: [],
|
||||||
|
motionBlur: 0.3,
|
||||||
ambientLight: vec3.fromValues(0.25, 0.15, 0.25),
|
ambientLight: vec3.fromValues(0.25, 0.15, 0.25),
|
||||||
textures: {},
|
textures: {},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,14 @@ export interface RuntimeSettings {
|
||||||
*/
|
*/
|
||||||
lightsRenderScale: number;
|
lightsRenderScale: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the extent of the motion blur.
|
||||||
|
*
|
||||||
|
* The values must be between 0 and 1. Where 0 means no motion blur,
|
||||||
|
* and values just below 1 mean an extreme amount of motion blur.
|
||||||
|
*/
|
||||||
|
motionBlur: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is possible to use your own textures in your SDF definitions.
|
* It is possible to use your own textures in your SDF definitions.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
precision lowp float;
|
precision lowp float;
|
||||||
|
|
||||||
|
#define FLOAT_LINEAR_ENABLED {floatLinearEnabled}
|
||||||
|
|
||||||
uniform float maxMinDistance;
|
uniform float maxMinDistance;
|
||||||
uniform float distanceNdcPixelSize;
|
uniform float distanceNdcPixelSize;
|
||||||
in vec2 position;
|
in vec2 position;
|
||||||
|
|
@ -28,6 +30,11 @@ void main() {
|
||||||
|
|
||||||
{functionCalls}
|
{functionCalls}
|
||||||
|
|
||||||
|
#if FLOAT_LINEAR_ENABLED
|
||||||
distanceValue = minDistance;
|
distanceValue = minDistance;
|
||||||
|
#else
|
||||||
|
distanceValue = minDistance * 8.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
fragmentColor = color;
|
fragmentColor = color;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ precision lowp float;
|
||||||
|
|
||||||
#define INTENSITY_INSIDE_RATIO {intensityInsideRatio}
|
#define INTENSITY_INSIDE_RATIO {intensityInsideRatio}
|
||||||
#define SHADOW_TRACE_COUNT {shadowTraceCount}
|
#define SHADOW_TRACE_COUNT {shadowTraceCount}
|
||||||
|
#define FLOAT_LINEAR_ENABLED {floatLinearEnabled}
|
||||||
|
|
||||||
{macroDefinitions}
|
{macroDefinitions}
|
||||||
|
|
||||||
|
|
@ -23,7 +24,11 @@ vec4 getColor(vec2 target) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float getDistance(vec2 target) {
|
float getDistance(vec2 target) {
|
||||||
|
#if FLOAT_LINEAR_ENABLED
|
||||||
return texture(distanceTexture, target)[0];
|
return texture(distanceTexture, target)[0];
|
||||||
|
#else
|
||||||
|
return texture(distanceTexture, target)[0] / 8.0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
float shadowTransparency(float startingDistance, float lightCenterDistance, vec2 direction) {
|
float shadowTransparency(float startingDistance, float lightCenterDistance, vec2 direction) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue