three.js examples (threejs.org)
(6条消息) webgl智慧楼宇发光效果算法系列之高斯模糊_netcy的专栏-CSDN博客_webgl 光晕
WebGL学习之HDR与Bloom - Jeff.Zhong - 博客园 (cnblogs.com)
- 高斯模糊的数值,好像很常见
- 先施加垂直方向的高斯模糊算法;
- 在垂直模糊的基础上进行水平方向的高斯模糊算法。
- 分两步(左右N+N)高斯模糊算法和一步(NxN)进行两个方向的高斯模糊算法的结果基本是一致的,但是却可以提高算法的效率。
乒乓帧缓存
- 声明
//2乒乓帧缓存(都只包含1颜色附件)
const hFbo = createFramebuffer(gl,{informat:gl.RGBA16F, type:gl.FLOAT});
const vFbo = createFramebuffer(gl,{informat:gl.RGBA16F, type:gl.FLOAT});
- bindFramebufferInfo
- drawBuffer
/**
* 乒乓帧缓存
*/
gl.useProgram(pProgram.program);
for(let i=0; i < 6; i++){
bindFramebufferInfo(gl, i%2 ? hFbo:vFbo);
setBuffersAndAttributes(gl, pProgram, pVao);
setUniforms(pProgram,{
horizontal: i%2? true:false,
image: i == 0 ? fbo.textures[1]: i%2 ? vFbo.textures[0]: hFbo.textures[0], //第1次两个乒乓帧缓存都为空,因此第一次要将灯光纹理传入
});
drawBufferInfo(gl, pVao);
}
THREEJS高斯模糊
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
#define SIGMA 3
#define KERNEL_RADIUS 3 //循环次数
varying vec2 vUv;
uniform sampler2D colorTexture;
uniform vec2 texSize; //这个是贴图的大小 往往是屏幕空间
uniform vec2 direction;//1, 0 , 是个是水平 0,1是垂直 都是遍历3次
float gaussianPdf(in float x, in float sigma) { //高斯模糊
return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;
}
void main() {
vec2 invSize = 1.0 / texSize;
float fSigma = float(SIGMA);
float weightSum = gaussianPdf(0.0, fSigma); //0.0
vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum; //这个是0.0最初的那个
for( int i = 1; i < KERNEL_RADIUS; i ++ ) { //只有一个方向的
float x = float(i);
float w = gaussianPdf(x, fSigma); //高斯比例
vec2 uvOffset = direction * invSize * x; //vec2 偏移方向
vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb; //
vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb; //
diffuseSum += (sample1 + sample2) * w; //相加
weightSum += 2.0 * w; //weightSum也要相加
}
gl_FragColor = vec4(diffuseSum/weightSum, 1.0);
}
其他网站高斯模糊
#version 300 es
precision highp float;
uniform sampler2D image;
uniform bool horizontal;
in vec2 texcoord;
out vec4 FragColor;
const float weight[5] = float[](0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162); //加起来是一 至于为什么是这些数字 不清楚
void main() {
vec2 tex_offset = vec2(1.0 / float(textureSize(image, 0)));//每个像素的尺寸
vec3 result = texture(image, texcoord).rgb * weight[0];
if (horizontal) {
for (int i = 0; i < 5; ++i) {
result += texture(image, texcoord + vec2(tex_offset.x * float(i), 0.0)).rgb * weight[i];
result += texture(image, texcoord - vec2(tex_offset.x * float(i), 0.0)).rgb * weight[i];
}
} else {
for (int i = 0; i < 5; ++i) {
result += texture(image, texcoord + vec2(0.0, tex_offset.y * float(i))).rgb * weight[i];
result += texture(image, texcoord - vec2(0.0, tex_offset.y * float(i))).rgb * weight[i];
}
}
FragColor = vec4 (result, 1.0);
}