mirror of https://gitee.com/antv-l7/antv-l7
Shihui (#955)
* feat: 优化后处理 bloom 的效果 * feat: 修改交替绘制 bloom 的写法 * style: lint style
This commit is contained in:
parent
556f9c5c75
commit
ef1d867ba7
|
@ -1,5 +1,6 @@
|
|||
import { ILayer } from '../layer/ILayerService';
|
||||
import { IFramebuffer } from './IFramebuffer';
|
||||
import { ITexture2D } from './ITexture2D';
|
||||
|
||||
export enum PassType {
|
||||
Normal = 'normal',
|
||||
|
@ -16,7 +17,7 @@ export interface IPass<InitializationOptions> {
|
|||
getName(): string;
|
||||
getType(): PassType;
|
||||
init(layer: ILayer, config?: Partial<InitializationOptions>): void;
|
||||
render(layer: ILayer): void;
|
||||
render(layer: ILayer, tex?: ITexture2D): void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -76,6 +76,19 @@ export interface ITexture2DInitializationOptions {
|
|||
colorSpace?: gl.NONE | gl.BROWSER_DEFAULT_WEBGL;
|
||||
|
||||
mipmap?: boolean | gl.DONT_CARE | gl.NICEST | gl.FASTEST;
|
||||
|
||||
/* 是否复制当前的 framebuffer */
|
||||
x?: number;
|
||||
y?: number;
|
||||
copy?: boolean;
|
||||
// From the pixels in the current frame buffer
|
||||
// var copyPixels = regl.texture({
|
||||
// x: 5,
|
||||
// y: 1,
|
||||
// width: 10,
|
||||
// height: 10,
|
||||
// copy: true
|
||||
// })
|
||||
}
|
||||
|
||||
export interface ITexture2D {
|
||||
|
|
|
@ -10,6 +10,7 @@ import quad from '../../../shaders/post-processing/quad.glsl';
|
|||
import { TYPES } from '../../../types';
|
||||
import { ILayer } from '../../layer/ILayerService';
|
||||
import { IPostProcessingPass, PassType } from '../IMultiPassRenderer';
|
||||
import { ITexture2D } from '../ITexture2D';
|
||||
import { IUniform } from '../IUniform';
|
||||
|
||||
/**
|
||||
|
@ -106,7 +107,7 @@ export default class BasePostProcessingPass<InitializationOptions = {}>
|
|||
});
|
||||
}
|
||||
|
||||
public render(layer: ILayer) {
|
||||
public render(layer: ILayer, tex?: ITexture2D) {
|
||||
const postProcessor = layer.multiPassRenderer.getPostProcessor();
|
||||
const { useFramebuffer, getViewportSize, clear } = this.rendererService;
|
||||
const { width, height } = getViewportSize();
|
||||
|
@ -119,12 +120,20 @@ export default class BasePostProcessingPass<InitializationOptions = {}>
|
|||
depth: 1,
|
||||
stencil: 0,
|
||||
});
|
||||
|
||||
const uniformOptions: { [key: string]: any } = {
|
||||
u_BloomFinal: 0.0,
|
||||
u_Texture: postProcessor.getReadFBO(),
|
||||
// u_Texture: tex ? tex : postProcessor.getReadFBO(),
|
||||
u_ViewportSize: [width, height],
|
||||
...this.convertOptionsToUniforms(this.optionsToUpdate),
|
||||
};
|
||||
if (tex) {
|
||||
uniformOptions.u_BloomFinal = 1.0;
|
||||
uniformOptions.u_Texture2 = tex;
|
||||
}
|
||||
this.model.draw({
|
||||
uniforms: {
|
||||
u_Texture: postProcessor.getReadFBO(),
|
||||
u_ViewportSize: [width, height],
|
||||
...this.convertOptionsToUniforms(this.optionsToUpdate),
|
||||
},
|
||||
uniforms: uniformOptions,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
|
@ -6,6 +6,7 @@ import { gl } from '../gl';
|
|||
import { IFramebuffer } from '../IFramebuffer';
|
||||
import { IPostProcessingPass, IPostProcessor } from '../IMultiPassRenderer';
|
||||
import { IRendererService } from '../IRendererService';
|
||||
import { ITexture2D } from '../ITexture2D';
|
||||
|
||||
/**
|
||||
* ported from Three.js EffectComposer
|
||||
|
@ -28,24 +29,69 @@ export default class PostProcessor implements IPostProcessor {
|
|||
return this.writeFBO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从当前的 framebuffer 中获取贴图
|
||||
* @returns
|
||||
*/
|
||||
public getCurrentFBOTex() {
|
||||
const { getViewportSize, createTexture2D } = this.rendererService;
|
||||
const { width, height } = getViewportSize();
|
||||
return createTexture2D({
|
||||
x: 0,
|
||||
y: 0,
|
||||
width,
|
||||
height,
|
||||
copy: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 readFBO 中获取贴图
|
||||
* @returns
|
||||
*/
|
||||
public getReadFBOTex() {
|
||||
const { useFramebuffer } = this.rendererService;
|
||||
return new Promise((resolve, reject) => {
|
||||
useFramebuffer(this.readFBO, async () => {
|
||||
resolve(this.getCurrentFBOTex());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async renderBloomPass(
|
||||
layer: ILayer,
|
||||
pass: IPostProcessingPass<unknown>,
|
||||
) {
|
||||
const tex = (await this.getReadFBOTex()) as ITexture2D;
|
||||
// count 定义 bloom 交替绘制的次数
|
||||
let count = 0;
|
||||
while (count < 4) {
|
||||
await pass.render(layer, tex);
|
||||
this.swap();
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
public async render(layer: ILayer) {
|
||||
for (let i = 0; i < this.passes.length; i++) {
|
||||
const pass = this.passes[i];
|
||||
// last pass should render to screen
|
||||
pass.setRenderToScreen(this.isLastEnabledPass(i));
|
||||
|
||||
await pass.render(layer);
|
||||
// pingpong
|
||||
if (i !== this.passes.length - 1) {
|
||||
this.swap();
|
||||
}
|
||||
|
||||
// if (pass.getName() === 'bloom') {
|
||||
// await pass.render(layer);
|
||||
// this.swap();
|
||||
// await pass.render(layer);
|
||||
// await pass.render(layer);
|
||||
// // pingpong
|
||||
// if (i !== this.passes.length - 1) {
|
||||
// this.swap();
|
||||
// }
|
||||
if (pass.getName() === 'bloom') {
|
||||
await this.renderBloomPass(layer, pass);
|
||||
} else {
|
||||
await pass.render(layer);
|
||||
// pingpong
|
||||
if (i !== this.passes.length - 1) {
|
||||
this.swap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@ import { IUniform } from '../../IUniform';
|
|||
import BasePostProcessingPass from '../BasePostProcessingPass';
|
||||
|
||||
export interface IBloomPassConfig {
|
||||
bloomBaseRadio: number;
|
||||
bloomRadius: number;
|
||||
bloomIntensity: number;
|
||||
}
|
||||
|
||||
@injectable()
|
||||
|
@ -47,6 +49,12 @@ export default class BloomPass extends BasePostProcessingPass<
|
|||
if (!isNil(options.bloomRadius)) {
|
||||
uniforms.u_radius = options.bloomRadius;
|
||||
}
|
||||
if (!isNil(options.bloomIntensity)) {
|
||||
uniforms.u_intensity = options.bloomIntensity;
|
||||
}
|
||||
if (!isNil(options.bloomBaseRadio)) {
|
||||
uniforms.u_baseRadio = options.bloomBaseRadio;
|
||||
}
|
||||
|
||||
return uniforms;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
varying vec2 v_UV;
|
||||
|
||||
uniform float u_BloomFinal: 0.0;
|
||||
uniform sampler2D u_Texture;
|
||||
uniform sampler2D u_Texture2;
|
||||
|
||||
uniform vec2 u_ViewportSize: [1.0, 1.0];
|
||||
uniform float u_radius: 5.0;
|
||||
uniform float u_intensity: 0.3;
|
||||
uniform float u_baseRadio: 0.5;
|
||||
|
||||
// https://github.com/Jam3/glsl-fast-gaussian-blur/blob/master/9.glsl
|
||||
vec4 blur9(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) {
|
||||
|
@ -18,51 +22,97 @@ vec4 blur9(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) {
|
|||
return color;
|
||||
}
|
||||
|
||||
float luminance(vec4 color) {
|
||||
return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// vec4 baseColor = texture2D(u_Texture, v_UV);
|
||||
// float lum = luminance(baseColor);
|
||||
// baseColor.a *= lum;
|
||||
|
||||
// gl_FragColor = baseColor;
|
||||
|
||||
// if(u_BloomFinal > 0.0) { //
|
||||
// gl_FragColor = baseColor; //--
|
||||
// }
|
||||
|
||||
float r = sqrt(u_radius);
|
||||
|
||||
vec4 c1 = blur9(u_Texture, v_UV, u_ViewportSize, vec2(u_radius, 0.0));
|
||||
// c1 *= luminance(c1);
|
||||
vec4 c2 = blur9(u_Texture, v_UV, u_ViewportSize, vec2(0.0, u_radius));
|
||||
// c2 *= luminance(c2);
|
||||
vec4 c3 = blur9(u_Texture, v_UV, u_ViewportSize, vec2(r, r));
|
||||
// c3 *= luminance(c3);
|
||||
vec4 c4 = blur9(u_Texture, v_UV, u_ViewportSize, vec2(r, -r));
|
||||
vec4 inbloomColor = c1 * 0.25 + c2 * 0.25 + c3 * 0.25 + c4 * 0.25;
|
||||
// c4 *= luminance(c4);
|
||||
vec4 inbloomColor = (c1 + c2 + c3 + c4) * 0.25;
|
||||
|
||||
// float lum = luminance(inbloomColor);
|
||||
// inbloomColor.rgb *= lum;
|
||||
|
||||
if(u_BloomFinal > 0.0) {
|
||||
vec4 baseColor = texture2D(u_Texture2, v_UV);
|
||||
float baselum = luminance(baseColor);
|
||||
// float lum = luminance(inbloomColor);
|
||||
// vec4 bloom = vec4(lum);
|
||||
// inbloomColor.a *= lum;
|
||||
// gl_FragColor = inbloomColor * u_intensity + texture2D(u_Texture2, v_UV);
|
||||
// gl_FragColor = inbloomColor * 0.5 + texture2D(u_Texture2, v_UV);
|
||||
// gl_FragColor = baseColor;
|
||||
// gl_FragColor = inbloomColor;
|
||||
// vec4 mixColor = mix(baseColor, inbloomColor, max(u_intensity - 0.3, 0.0));
|
||||
// mixColor.a = max(baseColor.a, mixColor.a);
|
||||
gl_FragColor = mix(inbloomColor, baseColor, max(1.0 - u_intensity, u_baseRadio));
|
||||
// gl_FragColor = mixColor;
|
||||
// gl_FragColor = baseColor;
|
||||
|
||||
if(baselum <= 0.0) {
|
||||
// float lum = luminance(inbloomColor);
|
||||
// inbloomColor.rgb *= lum;
|
||||
gl_FragColor += inbloomColor * u_intensity;
|
||||
}
|
||||
// gl_FragColor = inbloomColor * baseColor + baseColor;
|
||||
// gl_FragColor = baseColor + bloom * 0.5;
|
||||
} else {
|
||||
gl_FragColor = inbloomColor;
|
||||
}
|
||||
// gl_FragColor = inbloomColor;
|
||||
|
||||
float h = 0.01;
|
||||
vec4 baseColor = texture2D(u_Texture, v_UV);
|
||||
// float h = 0.01;
|
||||
|
||||
// vec4 color11 = texture2D( u_Texture, vec2( v_UV.x - 1.0 * h, v_UV.y + 1.0 * h) );
|
||||
// vec4 color12 = texture2D( u_Texture, vec2( v_UV.x - 0.0 * h, v_UV.y + 1.0 * h) );
|
||||
// vec4 color13 = texture2D( u_Texture, vec2( v_UV.x + 1.0 * h, v_UV.y + 1.0 * h) );
|
||||
|
||||
vec4 color11 = texture2D( u_Texture, vec2( v_UV.x - 1.0 * h, v_UV.y + 1.0 * h) );
|
||||
vec4 color12 = texture2D( u_Texture, vec2( v_UV.x - 0.0 * h, v_UV.y + 1.0 * h) );
|
||||
vec4 color13 = texture2D( u_Texture, vec2( v_UV.x + 1.0 * h, v_UV.y + 1.0 * h) );
|
||||
// vec4 color21 = texture2D( u_Texture, vec2( v_UV.x - 1.0 * h, v_UV.y) );
|
||||
// vec4 color23 = texture2D( u_Texture, vec2( v_UV.x + 1.0 * h, v_UV.y) );
|
||||
|
||||
vec4 color21 = texture2D( u_Texture, vec2( v_UV.x - 1.0 * h, v_UV.y) );
|
||||
vec4 color23 = texture2D( u_Texture, vec2( v_UV.x + 1.0 * h, v_UV.y) );
|
||||
// vec4 color31 = texture2D( u_Texture, vec2( v_UV.x - 1.0 * h, v_UV.y-1.0*h) );
|
||||
// vec4 color32 = texture2D( u_Texture, vec2( v_UV.x - 0.0 * h, v_UV.y-1.0*h) );
|
||||
// vec4 color33 = texture2D( u_Texture, vec2( v_UV.x + 1.0 * h, v_UV.y-1.0*h) );
|
||||
|
||||
vec4 color31 = texture2D( u_Texture, vec2( v_UV.x - 1.0 * h, v_UV.y-1.0*h) );
|
||||
vec4 color32 = texture2D( u_Texture, vec2( v_UV.x - 0.0 * h, v_UV.y-1.0*h) );
|
||||
vec4 color33 = texture2D( u_Texture, vec2( v_UV.x + 1.0 * h, v_UV.y-1.0*h) );
|
||||
// vec4 bloomColor =
|
||||
// color11 +
|
||||
// color12 +
|
||||
// color13 +
|
||||
// color21 +
|
||||
// color21 +
|
||||
// color23 +
|
||||
// color31 +
|
||||
// color32 +
|
||||
// color33;
|
||||
|
||||
vec4 bloomColor =
|
||||
color11 +
|
||||
color12 +
|
||||
color13 +
|
||||
color21 +
|
||||
color21 +
|
||||
color23 +
|
||||
color31 +
|
||||
color32 +
|
||||
color33;
|
||||
|
||||
if(baseColor.a > 0.0) {
|
||||
// if(baseColor.a > 0.0) {
|
||||
|
||||
gl_FragColor.r = min(bloomColor.r, baseColor.r);
|
||||
gl_FragColor.g = min(bloomColor.g, baseColor.g);
|
||||
gl_FragColor.b = min(bloomColor.b, baseColor.b);
|
||||
gl_FragColor.a = min(bloomColor.a, baseColor.a);
|
||||
// gl_FragColor.r = min(bloomColor.r, baseColor.r);
|
||||
// gl_FragColor.g = min(bloomColor.g, baseColor.g);
|
||||
// gl_FragColor.b = min(bloomColor.b, baseColor.b);
|
||||
// gl_FragColor.a = min(bloomColor.a, baseColor.a);
|
||||
|
||||
gl_FragColor = mix(inbloomColor, gl_FragColor, 0.7);
|
||||
} else {
|
||||
gl_FragColor = bloomColor/9.0;
|
||||
}
|
||||
// gl_FragColor = mix(inbloomColor, gl_FragColor, 0.7);
|
||||
// } else {
|
||||
// gl_FragColor = bloomColor/9.0;
|
||||
// }
|
||||
}
|
|
@ -36,6 +36,9 @@ export default class ReglTexture2D implements ITexture2D {
|
|||
mag = gl.NEAREST,
|
||||
min = gl.NEAREST,
|
||||
colorSpace = gl.BROWSER_DEFAULT_WEBGL,
|
||||
x = 0,
|
||||
y = 0,
|
||||
copy = false,
|
||||
} = options;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
@ -56,6 +59,11 @@ export default class ReglTexture2D implements ITexture2D {
|
|||
colorSpace: colorSpaceMap[colorSpace],
|
||||
premultiplyAlpha,
|
||||
aniso,
|
||||
|
||||
// copy pixels from current bind framebuffer
|
||||
x,
|
||||
y,
|
||||
copy,
|
||||
};
|
||||
|
||||
if (data) {
|
||||
|
|
|
@ -26,14 +26,14 @@ export default class Bloom extends React.Component {
|
|||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
// style: 'mapbox://styles/mapbox/streets-v9',
|
||||
style: 'blank',
|
||||
style: 'mapbox://styles/mapbox/streets-v9',
|
||||
// style: 'blank',
|
||||
center: [110.19382669582967, 50.258134],
|
||||
pitch: 0,
|
||||
zoom: 3,
|
||||
}),
|
||||
});
|
||||
scene.setBgColor('#000');
|
||||
// scene.setBgColor('#000');
|
||||
const layer = new PolygonLayer({
|
||||
zIndex: 0,
|
||||
// enablePicking: true,
|
||||
|
@ -43,7 +43,9 @@ export default class Bloom extends React.Component {
|
|||
[
|
||||
'bloom',
|
||||
{
|
||||
bloomRadius: 8,
|
||||
// bloomBaseRadio: 0.5,
|
||||
bloomRadius: 25,
|
||||
bloomIntensity: 1,
|
||||
},
|
||||
],
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue