particle-view.frag 1.1 KB
// Fragment shader for particles, which simulates depth of field using
// a combination of procedural texturing, alpha testing and alpha blending.

#version 300 es

precision lowp float;
uniform float uAlphaTestRefValue;
uniform vec2 uFadeRange; // near, far
in vec2 vUvUnit;
flat in float vDepth;
flat in float vFocalDistance;
flat in float vOpacity;
flat in vec3 vColor;
out vec4 oFragColor;

const float REF_VALUE_THRESHOLD = 1. / 64.;

void main()
{
  // Softened disc pattern from normalized UVs
  float value = 1.f - dot(vUvUnit, vUvUnit);

  // Decrease area of particles 'in-focus'.
  float refValue = (1.f - vFocalDistance) * .5f;
  float threshold = REF_VALUE_THRESHOLD * (1.f + vDepth);
  float alpha = pow(value, vFocalDistance) * smoothstep(refValue - threshold, refValue + threshold, value);
  if (alpha < uAlphaTestRefValue)
  {
    discard;
  }

  // Apply opacity
  alpha *= vOpacity;
  alpha *= alpha;

  // Fade particles out as they get close to the near and far clipping planes
  alpha *= smoothstep(.0f, uFadeRange.x, vDepth) * smoothstep(1.f, uFadeRange.y, vDepth);

  oFragColor = vec4(vColor, alpha);
}