hashBlur.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import { float, Fn, vec2, uv, sin, rand, degrees, cos, Loop, vec4, premultiplyAlpha, unpremultiplyAlpha, convertToTexture, nodeObject } from 'three/tsl';
  2. /**
  3. * Applies a hash blur effect to the given texture node.
  4. *
  5. * Reference: {@link https://www.shadertoy.com/view/4lXXWn}.
  6. *
  7. * @function
  8. * @param {Node<vec4>} textureNode - The texture node that should be blurred.
  9. * @param {Node<float>} [bluramount=float(0.1)] - This node determines the amount of blur.
  10. * @param {Object} [options={}] - Additional options for the hash blur effect.
  11. * @param {Node<float>} [options.repeats=float(45)] - The number of iterations for the blur effect.
  12. * @param {Node<vec4>} [options.mask=null] - A mask node to control the alpha blending of the blur.
  13. * @param {boolean} [options.premultipliedAlpha=false] - Whether to use premultiplied alpha for the blur effect.
  14. * @return {Node<vec4>} The blurred texture node.
  15. */
  16. export const hashBlur = /*#__PURE__*/ Fn( ( [ textureNode, bluramount = float( 0.1 ), options = {} ] ) => {
  17. textureNode = convertToTexture( textureNode );
  18. bluramount = nodeObject( bluramount );
  19. const repeats = nodeObject( options.size ) || float( 45 );
  20. const mask = options.mask || null;
  21. const premultipliedAlpha = options.premultipliedAlpha || false;
  22. const draw = ( uv ) => {
  23. let sample = textureNode.sample( uv );
  24. if ( mask !== null ) {
  25. const alpha = mask.sample( uv ).x;
  26. sample = vec4( sample.rgb, sample.a.mul( alpha ) );
  27. }
  28. return premultipliedAlpha ? premultiplyAlpha( sample ) : sample;
  29. };
  30. const targetUV = textureNode.uvNode || uv();
  31. const blurred_image = vec4( 0. ).toVar();
  32. Loop( { start: 0., end: repeats, type: 'float' }, ( { i } ) => {
  33. const q = vec2( vec2( cos( degrees( i.div( repeats ).mul( 360. ) ) ), sin( degrees( i.div( repeats ).mul( 360. ) ) ) ).mul( rand( vec2( i, targetUV.x.add( targetUV.y ) ) ).add( bluramount ) ) );
  34. const uv2 = vec2( targetUV.add( q.mul( bluramount ) ) );
  35. blurred_image.addAssign( draw( uv2 ) );
  36. } );
  37. blurred_image.divAssign( repeats );
  38. return premultipliedAlpha ? unpremultiplyAlpha( blurred_image ) : blurred_image;
  39. } );
粤ICP备19079148号