1/*! © 2011â2026 Georg Luif · georgluif.at · All rights reserved. */ 2import*as a from"./three.module.min.js";export const MAX_RADIUS=35,POST_VERT="varying vec2 vUv; void main(){ vUv = uv; gl_Position = vec4(position, 1.0); }",KUWAHARA_GAUSSIAN_FRAG=["precision highp float;","#define SECTOR_COUNT 8","uniform float radius;","uniform sampler2D inputBuffer;","uniform vec4 resolution;","varying vec2 vUv;","#ifdef GRADE","uniform float uGrade;","uniform vec3 uShadowTint;","uniform vec3 uLightTint;","uniform float uSat;","uniform float uVignette;","vec3 goldenGrade(vec3 c) {"," float l = dot(c, vec3(0.299, 0.587, 0.114));"," vec3 g = c * mix(uShadowTint, uLightTint, smoothstep(0.05, 0.85, l));"," g = mix(vec3(dot(g, vec3(0.299, 0.587, 0.114))), g, uSat);"," vec2 q = (vUv - 0.5) * vec2(1.15, 1.0);"," g *= 1.0 - uVignette * smoothstep(0.35, 0.85, length(q));"," return mix(c, clamp(g, 0.0, 1.0), uGrade);","}","#endif","vec4 fromLinear(vec4 linearRGB) {"," bvec3 cutoff = lessThan(linearRGB.rgb, vec3(0.0031308));"," vec3 higher = vec3(1.055) * pow(linearRGB.rgb, vec3(1.0 / 2.4)) - vec3(0.055);"," vec3 lower = linearRGB.rgb * vec3(12.92);"," return vec4(mix(higher, lower, cutoff), linearRGB.a);","}","vec3 sampleColor(vec2 offset) {"," vec2 coord = (gl_FragCoord.xy + offset) / resolution.xy;"," return texture2D(inputBuffer, coord).rgb;","}","float gaussianWeight(float dist, float sigma) {"," return exp(-(dist * dist) / (2.0 * sigma * sigma));","}","void getSectorVarianceAndAverageColor(float angle, float radiusVal, out vec3 avgColor, out float variance) {"," vec3 weightedColorSum = vec3(0.0);"," vec3 weightedSquaredColorSum = vec3(0.0);"," float totalWeight = 0.0;"," float sigma = radiusVal / 3.0;"," for (float r = 1.0; r <= 35.0; r += 1.0) {"," if (r > radiusVal) break;"," for (float a = -0.392699; a <= 0.392699; a += 0.196349) {"," vec2 sampleOffset = r * vec2(cos(angle + a), sin(angle + a));"," vec3 color = sampleColor(sampleOffset);"," float weight = gaussianWeight(length(sampleOffset), sigma);"," weightedColorSum += color * weight;"," weightedSquaredColorSum += color * color * weight;"," totalWeight += weight;"," }"," }"," avgColor = weightedColorSum / totalWeight;"," vec3 varianceRes = (weightedSquaredColorSum / totalWeight) - (avgColor * avgColor);"," variance = dot(varianceRes, vec3(0.299, 0.587, 0.114));","}","void main() {"," vec3 sectorAvgColors[SECTOR_COUNT];"," float sectorVariances[SECTOR_COUNT];"," for (int i = 0; i < SECTOR_COUNT; i++) {"," float angle = float(i) * 6.28318 / float(SECTOR_COUNT);"," getSectorVarianceAndAverageColor(angle, radius, sectorAvgColors[i], sectorVariances[i]);"," }"," float minVariance = sectorVariances[0];"," vec3 finalColor = sectorAvgColors[0];"," for (int i = 1; i < SECTOR_COUNT; i++) {"," if (sectorVariances[i] < minVariance) {"," minVariance = sectorVariances[i];"," finalColor = sectorAvgColors[i];"," }"," }","#ifdef PRESERVE_ALPHA"," float outAlpha = texture2D(inputBuffer, gl_FragCoord.xy / resolution.xy).a;","#else"," float outAlpha = 1.0;","#endif","#ifdef LINEAR_OUTPUT"," gl_FragColor = vec4(finalColor, outAlpha);","#else"," gl_FragColor = fromLinear(vec4(finalColor, outAlpha));","#ifdef GRADE"," gl_FragColor.rgb = goldenGrade(gl_FragColor.rgb);","#endif","#endif","}"].join(` 3`);function S(t){return Math.max(1,Math.min(MAX_RADIUS,t||1))}export function createPainterlyPass(t){t=t||{};let u=S(t.radius==null?15:t.radius),g=t.resolutionScale||1,c=2,f=2;const n=new a.WebGLRenderTarget(2,2,{minFilter:a.LinearFilter,magFilter:a.LinearFilter,format:a.RGBAFormat}),l=new a.Mesh(new a.PlaneGeometry(2,2)),d=new a.Scene;d.add(l);const m=new a.OrthographicCamera(-1,1,1,-1,0,1),o=t.grade||null,v={};
3t.preserveAlpha&&(v.PRESERVE_ALPHA=""),o&&(v.GRADE="");const r={radius:{value:u},inputBuffer:{value:null},resolution:{value:new a.Vector4}};o&&(r.uGrade={value:0},r.uShadowTint={value:new a.Vector3().fromArray(o.shadow||[1,1,1])},r.uLightTint={value:new a.Vector3().fromArray(o.light||[1,1,1])},r.uSat={value:o.sat!=null?o.sat:1},r.uVignette={value:o.vignette||0});const i=new a.ShaderMaterial({defines:v,uniforms:r,vertexShader:POST_VERT,fragmentShader:KUWAHARA_GAUSSIAN_FRAG,depthTest:!1,depthWrite:!1}),h=new a.MeshBasicMaterial({map:n.texture,depthTest:!1,depthWrite:!1});function p(){n.setSize(Math.max(1,Math.round(c*g)),Math.max(1,Math.round(f*g)))}const C={enabled:!0,setSize:function(e,s){c=Math.max(1,e|0),f=Math.max(1,s|0),p()},setRadius:function(e){u=S(e),i.uniforms.radius.value=u},getRadius:function(){return u},setGrade:function(e){r.uGrade&&(r.uGrade.value=Math.max(0,Math.min(1,e||0)))},setResolutionScale:function(e){g=Math.max(.1,Math.min(1,e||1)),p()},render:function(e,s,R){const T=e.getRenderTarget();e.setRenderTarget(n),e.render(s,R),C.enabled?(i.uniforms.inputBuffer.value=n.texture,i.uniforms.resolution.value.set(c,f,1/c,1/f),l.material=i):l.material=h,e.setRenderTarget(T),e.render(d,m)},precompile:function(e,s){return l.material=i,s(e,d,m)},dispose:function(){i.dispose(),h.dispose(),n.dispose(),l.geometry.dispose()}};return C}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.