5fn gaussian_linear(image:texture_2d<f32>,uv:vec2f)->vec3f {
6 let size=vec2i(textureDimensions(image));let pos=uv*vec2f(size)-.5;let lo=vec2i(floor(pos));let f=fract(pos);
7 var a=textureLoad(image,clamp(lo,vec2i(0),size-1),0).rgb;
8 var b=textureLoad(image,clamp(lo+vec2i(1,0),vec2i(0),size-1),0).rgb;
9 var c=textureLoad(image,clamp(lo+vec2i(0,1),vec2i(0),size-1),0).rgb;
10 var d=textureLoad(image,clamp(lo+vec2i(1,1),vec2i(0),size-1),0).rgb;
12 a=select(vec3f(0),a,all(lo>=vec2i(0))&&all(lo<size));
13 b=select(vec3f(0),b,all(lo+vec2i(1,0)>=vec2i(0))&&all(lo+vec2i(1,0)<size));
14 c=select(vec3f(0),c,all(lo+vec2i(0,1)>=vec2i(0))&&all(lo+vec2i(0,1)<size));
15 d=select(vec3f(0),d,all(lo+vec2i(1,1)>=vec2i(0))&&all(lo+vec2i(1,1)<size));
17 return mix(mix(a,b,f.x),mix(c,d,f.x),f.y);
19fn gaussian_sample(uv:vec2f,h:vec2f)->vec3f{return gaussian_linear(mainTex,clamp(uv,.5*vec2f(p(0),p(1)),vec2f(1)-h));}
20@fragment fn fs_main(i:FSIn)->@location(0) vec4f {
21 let t=vec2f(p(0),p(1)); var c=vec3f(0);
24 c=gaussian_linear(mainTex,i.uv);
26 c=max(vec3f(0),(gaussian_linear(mainTex,i.uv+t*vec2f(-1,-1))+
27 gaussian_linear(mainTex,i.uv+t*vec2f(1,-1))+
28 gaussian_linear(mainTex,i.uv+t*vec2f(-1,1))+
29 gaussian_linear(mainTex,i.uv+t*vec2f(1,1)))*.25);
34 let brightness=max(c.r,max(c.g,c.b));let knee=p(3)*.5;
35 var soft=clamp(brightness-p(3)+knee,0,2*knee);soft=soft*soft/(4*knee+.0001);
36 c=max(c*(max(brightness-p(3),soft)/max(brightness,.0001)),vec3f(0));
41 let radius=max(p(7),.0001);var sum:f32=0;let count=i32(ceil(radius));
42 let axis=select(vec2f(0,t.y),vec2f(t.x,0),p(2)<6.5);
43 for(var j:i32=-count;j<=count;j++){
44 let dx=f32(j)/radius;let weight=exp(-16.7*dx*dx);
45 c+=gaussian_linear(mainTex,i.uv+axis*f32(j))*weight;sum+=weight;
48 if(p(2)>6.5){c*=p(8);if(p(9)>.5){c+=gaussian_linear(auxTex,i.uv);}}
51 c=min(gaussian_sample(i.uv,t*.5),vec3f(p(4)));
52 let brightness=max(c.r,max(c.g,c.b));let knee=p(3)*.5;
53 var soft=clamp(brightness-p(3)+knee,0,2*knee);soft=soft*soft/(4*knee+.0001);
54 c=max(c*(max(brightness-p(3),soft)/max(brightness,.0001)),vec3f(0));
56 let weights=array<f32,5>(.22702703,.19459459,.12162162,.05405405,.01621622);
57 for(var j:i32=-4;j<=4;j++){c+=gaussian_sample(i.uv+vec2f(f32(j)*2*t.x,0),t)*weights[abs(j)];}
59 c=gaussian_sample(i.uv,t*.5)*.22702703;
60 c+=(gaussian_sample(i.uv+vec2f(0,1.38461538*t.y),t*.5)+gaussian_sample(i.uv-vec2f(0,1.38461538*t.y),t*.5))*.31621622;
61 c+=(gaussian_sample(i.uv+vec2f(0,3.23076923*t.y),t*.5)+gaussian_sample(i.uv-vec2f(0,3.23076923*t.y),t*.5))*.07027027;
63 let h=.5/vec2f(textureDimensions(auxTex));
64 let high=gaussian_sample(i.uv,t*.5);let low=gaussian_linear(auxTex,clamp(i.uv,h,vec2f(1)-h));
65 c=select(high+low*p(6),mix(high,low,p(5)),p(2)<3.5);
67 return vec4f(c*i.color.rgb,1);
constexpr const char * kBloomGaussian
Gaussian-scatter HDR bloom stages. @lifetime Static process storage.