Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #bind layer src
- #bind layer !&dst
- #bind parm pixelSize float val=16.0
- #bind parm radiusScale float val=0.8
- #bind parm gooeyness float val=0.5
- #bind parm dotAspect float val=1.0
- #bind parm cStrength float val=1.0
- #bind parm mStrength float val=1.0
- #bind parm yStrength float val=1.0
- #bind parm kStrength float val=1.0
- // Helper: RGB to CMYK
- float4 RGBtoCMYK(float3 rgb) {
- float k = 1.0f - max(rgb.r, max(rgb.g, rgb.b));
- float invK = 1.0f - k;
- float3 cmy = (float3)(0.0f);
- if (invK != 0.0f) {
- cmy.x = (1.0f - rgb.r - k) / invK;
- cmy.y = (1.0f - rgb.g - k) / invK;
- cmy.z = (1.0f - rgb.b - k) / invK;
- }
- return (float4)(cmy, k);
- }
- // Helper: 2D Rotation
- float2 rotate_vec(float2 p, float angle) {
- float s = sin(angle);
- float c = cos(angle);
- return (float2)(p.x * c - p.y * s, p.x * s + p.y * c);
- }
- // Helper: Smooth Min (Gooeyness)
- float smin_func(float a, float b, float k) {
- float h = clamp(0.5f + 0.5f * (b - a) / k, 0.0f, 1.0f);
- return mix(b, a, h) - k * h * (1.0f - h);
- }
- @KERNEL
- {
- float2 res = (float2)(@xres, @yres);
- float screen_aspect = res.x / res.y;
- // Normalized UVs
- float2 uv = @P;
- // Scale for grid (how many dots fit vertically)
- float gridScale = res.y / @pixelSize;
- float rScale = @radiusScale;
- float gooey = @gooeyness / gridScale;
- float angles[4] = {0.2618f, 1.3090f, 0.0000f, 0.7854f}; // C, M, Y, K
- float dots[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- for(int c=0; c<4; c++) {
- float angle = angles[c];
- // Use a simple coordinate space where Y is 0..1 and X is 0..ScreenAspect
- float2 p_space = (float2)(uv.x * screen_aspect, uv.y);
- float2 center_space = (float2)(0.5f * screen_aspect, 0.5f);
- // Rotate around center
- float2 rotatedP = rotate_vec(p_space - center_space, angle) + center_space;
- float2 gridCoord = rotatedP * gridScale;
- float2 baseCellIndex = floor(gridCoord);
- float min_dist = 1000.0f;
- for (int dx = -1; dx <= 1; dx++) {
- for (int dy = -1; dy <= 1; dy++) {
- float2 cellIndex = baseCellIndex + (float2)(dx, dy);
- float2 cellCenterGrid = cellIndex + 0.5f;
- float2 cellCenterSpace = cellCenterGrid / gridScale;
- // Inverse rotate to find where to sample luma in UV space
- float2 rel_center = cellCenterSpace - center_space;
- float2 sampleP = rotate_vec(rel_center, -angle) + center_space;
- float2 sampleUv = (float2)(sampleP.x / screen_aspect, sampleP.y);
- // Sample luma at center
- float4 sampleClr = @src.imageSample(sampleUv);
- float4 cmyk = RGBtoCMYK(sampleClr.xyz);
- float coverage = (c == 0) ? cmyk.x : (c == 1) ? cmyk.y : (c == 2) ? cmyk.z : cmyk.w;
- // Radius
- float r = (0.5f * rScale * sqrt(clamp(coverage, 0.0f, 1.0f))) / gridScale;
- // Distance with Aspect Control
- float2 diff = rotatedP - cellCenterSpace;
- diff.x *= @dotAspect; // Manual squash/stretch
- float d = length(diff);
- float dist = d - r;
- if(gooey > 0.00001f)
- min_dist = smin_func(min_dist, dist, gooey);
- else
- min_dist = min(min_dist, dist);
- }
- }
- float pixel_w = 1.0f / res.y;
- dots[c] = 1.0f - smoothstep(-pixel_w, pixel_w, min_dist);
- }
- float3 outColor = (float3)(1.0f);
- outColor.r *= (1.0f - @cStrength * dots[0]);
- outColor.g *= (1.0f - @mStrength * dots[1]);
- outColor.b *= (1.0f - @yStrength * dots[2]);
- outColor *= (1.0f - @kStrength * dots[3]);
- @dst.set((float4)(outColor, 1.0f));
- }
Advertisement
Add Comment
Please, Sign In to add comment