I am trying to add Gaussian blur to a scene. I am using this GLSL shader:
uniform sampler2D tDiffuse;
uniform int uKernel;
uniform float uSigma;
uniform vec2 uDirection;
uniform float uStrength;
uniform float uDirectionalResolution;
varying vec2 v_Uv;
float gaussianPdf(in float x,in float sigma){
return(.39894/sigma)*exp(-.5*x*x/(sigma*sigma));
}
float parabola(float x,float k){
return pow(4.*x*(1.-x),k);
}
void main(){
float weightSum=gaussianPdf(0.,uSigma);
vec4 t=texture2D(tDiffuse,v_Uv);
vec3 diffuseSum=t.rgb*weightSum;
float invSize=1./uDirectionalResolution;
float focus=distance(vec2(.5),v_Uv);
focus=smoothstep(0.,.7,focus);
for(int i=1;i<uKernel;i++){
float x=float(i);
float w=gaussianPdf(x,uSigma);
vec2 offset=uDirection*invSize*x*uStrength*focus;
vec4 sample1=texture2D(tDiffuse,v_Uv+offset);
vec4 sample2=texture2D(tDiffuse,v_Uv-offset);
diffuseSum+=(sample1.rgb+sample2.rgb)*w;
weightSum+=2.*w;
}
gl_FragColor=vec4(diffuseSum/weightSum,1.);
}
It works on images when you provide image as the tDiffuse texture but I am trying to add it as a postprocessing effect. I tried to get the renderTarget of the camera and pass that texture as the tDiffuse but that was computationally too expensive :(
Here is the react code:
import vert from "./vertex.glsl"
import frag from "./fragment.glsl"
function BlurShader() {
const { gl, size, scene, camera } = useThree();
const uniforms = useMemo(() => ({
time: { value: 0.0 },
uKernel: { value: 13 },
uSigma: { value: 3 },
tDiffuse: { value: null },
uStrength: { value: 1 },
uDirection: { value: new THREE.Vector2(1, 1) },
uDirectionalResolution: { value: 512 },
}), [])
return (
<>
</>
)
}
export default function Test() {
return (
<div className='h-full w-full absolute'>
<Canvas camera={{ fov: 75, near: 0.01, far: 50, position: [0, 0, 1] }}>
<color attach="background" args={["black"]} />
<OrbitControls />
<Particles />
<BlurShader />
</Canvas>
</div>
)
}
Is there a way of achieving this without doing the camera renderTarget stuff? Or any other more efficient way?
To answer my own question, I created a huge plane in front of the camera :)