add bloom;some treaks

This commit is contained in:
2026-03-17 16:20:22 +08:00
parent 28d9a7dfb6
commit f1de5df4de
19 changed files with 678 additions and 421 deletions

View File

@ -21,59 +21,64 @@ layout(location = 0) out vec4 o_Color;
in vec2 v_TexCoord;
uniform sampler2D u_Texture;
uniform bool u_Horizontal;
uniform bool u_Horizontal; // 未使用,可保留或移除
uniform bool u_FirstPass; // 是否进行阈值处理
uniform float u_Threshold; // 亮度阈值
void main()
{
#if 1
// From learnopengl.com
float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
float Pi = 6.28318530718; // 2*PI
vec2 tex_offset = 1.0 / textureSize(u_Texture, 0); // gets size of single texel
vec3 result = texture(u_Texture, v_TexCoord).rgb * weight[0]; // current fragment's contribution
if (u_Horizontal)
float Directions = 32.0; // 模糊方向数
float Quality = 6.0; // 每个方向上的采样质量(采样次数)
float Size = 16.0; // 模糊半径
vec2 Radius = Size / textureSize(u_Texture, 0);
// 中心像素采样
vec3 centerColor = texture(u_Texture, v_TexCoord).rgb;
float centerLum = dot(centerColor, vec3(0.2126, 0.7152, 0.0722));
// 如果启用第一次处理且中心像素亮度低于阈值,则直接输出黑色(不进行模糊)
if (u_FirstPass && centerLum <= u_Threshold)
{
for(int i = 1; i < 5; ++i)
o_Color = vec4(0.0, 0.0, 0.0, 1.0);
return;
}
vec3 result = centerColor; // 先累加中心像素
float totalSamples = 1.0; // 有效采样计数(中心像素已计入)
// 周围像素采样
for (float d = 0.0; d < Pi; d += Pi / Directions)
{
for (float i = 1.0 / Quality; i <= 1.0; i += 1.0 / Quality)
{
result += texture(u_Texture, v_TexCoord + vec2(tex_offset.x * i, 0.0)).rgb * weight[i];
result += texture(u_Texture, v_TexCoord - vec2(tex_offset.x * i, 0.0)).rgb * weight[i];
}
}
else
{
for(int i = 1; i < 5; ++i)
{
result += texture(u_Texture, v_TexCoord + vec2(0.0, tex_offset.y * i)).rgb * weight[i];
result += texture(u_Texture, v_TexCoord - vec2(0.0, tex_offset.y * i)).rgb * weight[i];
vec2 offset = vec2(cos(d), sin(d)) * Radius * i;
vec3 sampleColor = texture(u_Texture, v_TexCoord + offset).rgb;
if (u_FirstPass)
{
float lum = dot(sampleColor, vec3(0.2126, 0.7152, 0.0722));
if (lum <= u_Threshold)
{
// 低于阈值则贡献黑色,但采样点仍计入分母?这里选择不计入有效采样数
// 若希望保持模糊能量,可以 continue 跳过累加,但需调整分母
// 为简单起见,此处设为黑色并计入计数(分母不变),也可选择跳过
sampleColor = vec3(0.0);
// 如果希望忽略该采样点,可以 continue 并减少 totalSamples
// 但为了效果平滑,这里保留为黑色并计入计数
}
}
result += sampleColor;
totalSamples += 1.0;
}
}
// 归一化:除以总采样数(包括中心像素)
// 若之前选择忽略低于阈值的采样点continue则需相应调整 totalSamples
result /= totalSamples;
o_Color = vec4(result, 1.0);
#else
// From https://www.shadertoy.com/view/Xltfzj
float Pi = 6.28318530718; // Pi*2
// GAUSSIAN BLUR SETTINGS {{{
float Directions =32.0; // BLUR DIRECTIONS (Default 16.0 - More is better but slower)
float Quality = 6.0; // BLUR QUALITY (Default 4.0 - More is better but slower)
float Size = 16.0; // BLUR SIZE (Radius)
// GAUSSIAN BLUR SETTINGS }}}
vec2 Radius = Size/textureSize(u_Texture, 0);
vec3 result = texture(u_Texture, v_TexCoord).rgb;
vec2 uv = v_TexCoord;
// Blur calculations
for( float d=0.0; d<Pi; d+=Pi/Directions)
{
for(float i=1.0/Quality; i<=1.0; i+=1.0/Quality)
{
result += texture( u_Texture, uv+vec2(cos(d),sin(d))*Radius*i).rgb;
}
}
// Output to screen
result /= Quality * Directions - 15.0;
o_Color = vec4(result, 1.0);
#endif
}

View File

@ -7,6 +7,8 @@ layout(binding = 0, rgba32f) restrict writeonly uniform imageCube o_CubeMap;
uniform vec3 u_TurbidityAzimuthInclination;
#define PI 3.14159265359
vec3 GetCubeMapTexCoord()
{
vec2 st = gl_GlobalInvocationID.xy / vec2(imageSize(o_CubeMap));
@ -22,11 +24,10 @@ vec3 GetCubeMapTexCoord()
return normalize(ret);
}
#define PI 3.14159265359
float saturatedDot( in vec3 a, in vec3 b )
{
return max( dot( a, b ), 0.0 );
return clamp(dot(a, b), 0.0, 1.0);
}
vec3 YxyToXYZ( in vec3 Yxy )
@ -96,6 +97,7 @@ vec3 calculateZenithLuminanceYxy( in float t, in float thetaS )
vec3 calculatePerezLuminanceYxy( in float theta, in float gamma, in vec3 A, in vec3 B, in vec3 C, in vec3 D, in vec3 E )
{
float cosTheta = max(cos(theta), 1e-6);
return ( 1.0 + A * exp( B / cos( theta ) ) ) * ( 1.0 + C * exp( D * gamma ) + E * cos( gamma ) * cos( gamma ) );
}
@ -104,8 +106,8 @@ vec3 calculateSkyLuminanceRGB( in vec3 s, in vec3 e, in float t )
vec3 A, B, C, D, E;
calculatePerezDistribution( t, A, B, C, D, E );
float thetaS = acos( saturatedDot( s, vec3(0,1,0) ) );
float thetaE = acos( saturatedDot( e, vec3(0,1,0) ) );
float thetaS = acos(clamp(dot(s, vec3(0,1,0)), 0.0, 1.0));
float thetaE = acos(clamp(dot(e, vec3(0,1,0)), 0.0, 1.0));
float gammaE = acos( saturatedDot( s, e ) );
vec3 Yz = calculateZenithLuminanceYxy( t, thetaS );
@ -128,8 +130,30 @@ void main()
float inclination = u_TurbidityAzimuthInclination.z;
vec3 sunDir = normalize( vec3( sin(inclination) * cos(azimuth), cos(inclination), sin(inclination) * sin(azimuth) ) );
vec3 viewDir = cubeTC;
vec3 skyLuminance = calculateSkyLuminanceRGB( sunDir, viewDir, turbidity );
const float SUN_ANGULAR_RADIUS = 0.03465;
const float SUN_INTENSITY = 100.0;
vec3 skyLuminance;
if (viewDir.y < 0.0) {
skyLuminance = vec3(0.02);
} else {
skyLuminance = calculateSkyLuminanceRGB(sunDir, viewDir, turbidity);
}
float cosAngle = dot(viewDir, sunDir);
float angle = acos(cosAngle);
if (angle < SUN_ANGULAR_RADIUS) {
skyLuminance = vec3(SUN_INTENSITY);
} else {
float haloWidth = 0.1;
if (angle < SUN_ANGULAR_RADIUS + haloWidth) {
float t = (angle - SUN_ANGULAR_RADIUS) / haloWidth;
float haloFactor = 1.0 - smoothstep(0.0, 1.0, t);
skyLuminance += vec3(SUN_INTENSITY * 0.1 * haloFactor);
}
}
vec4 color = vec4(skyLuminance * 0.05, 1.0);
imageStore(o_CubeMap, ivec3(gl_GlobalInvocationID), color);
}
}

View File

@ -22,6 +22,7 @@ layout(location = 1) out vec4 o_BloomTexture;
in vec2 v_TexCoord;
uniform sampler2DMS u_Texture;
uniform sampler2D u_BloomTexture;
uniform bool u_EnableAutoExposure;
@ -55,6 +56,17 @@ vec4 MultiSampleTexture(sampler2DMS tex, vec2 tc)
return result;
}
float MultiSampleDepth(sampler2DMS tex, vec2 tc)
{
ivec2 texSize = textureSize(tex);
ivec2 texCoord = ivec2(tc * texSize);
float result = 0.0;
for (int i = 0; i < u_TextureSamples; i++)
result += texelFetch(tex, texCoord, i).r;
result /= float(u_TextureSamples);
return result;
}
void main()
{
const float gamma = 2.2;
@ -62,12 +74,11 @@ void main()
// Tonemapping
vec4 msColor = MultiSampleTexture(u_Texture, v_TexCoord);
vec3 color = msColor.rgb;
if (u_EnableBloom)
{
vec3 bloomColor = MultiSampleTexture(u_Texture, v_TexCoord).rgb;
vec3 bloomColor = texture(u_BloomTexture, v_TexCoord).rgb;
color += bloomColor;
}