Gallery

cubic with draw circle

Live parameters

Motion
1.00
Geometry
1.00
Look
0.040
Color
GLSL source
// --- NOISE FUNCTIONS / ФУНКЦИИ ШУМА / ノイズ関数 ---
float noise(vec2 p) {
    return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
}

float smoothNoise(vec2 p) {
    vec2 i = floor(p);
    vec2 f = fract(p);
    f = f * f * (3.0 - 2.0 * f);
    return mix(mix(noise(i), noise(i + vec2(1.0, 0.0)), f.x),
               mix(noise(i + vec2(0.0, 1.0)), noise(i + vec2(1.0, 1.0)), f.x), f.y);
}

// --- WATERCOLOR DOT FUNCTION / ФУНКЦИЯ АКВАРЕЛЬНОГО ПЯТНА ---
vec3 drawCircle(vec2 uv, vec2 pos, float radius, vec3 color, vec3 canvas) {
    float n = smoothNoise(uv * 8.0 + pos);
    float dist = length(uv - pos + n * 0.04);
    float mask = smoothstep(radius, radius - 0.05, dist);
    float border = smoothstep(radius - 0.06, radius - 0.03, dist) * mask;
    float density = mask * (0.4 + 0.6 * smoothNoise(uv * 4.0 + pos));
    vec3 circleLayer = mix(vec3(1.0), color * (1.0 - border * 0.4), density);
    return canvas * circleLayer; 
}

// --- GEOMETRY / ГЕОМЕТРИЯ ---
float sdBox(vec3 p, vec3 b) {
    vec3 q = abs(p) - b;
    return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);
}

mat2 rot(float a) {
    float s=sin(a), c=cos(a);
    return mat2(c,s,-s,c);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
    
    // Raymarching setup
    vec3 ro = vec3(0, 0, -5.5); // Camera position
    vec3 rd = normalize(vec3(uv, 1.-dot(uv,uv)*5.));
    
    float d, t = 0.0;
    bool hit = false;
    vec3 p;
    
    // Raymarching loop
    for(int i = 0; i < 64; i++) {
        p = ro + rd * t;
        // Rotate the cube / Вращаем куб
        p.xz *= rot(iTime * 0.5 * TIME_SCALE);
        p.xy *= rot(iTime * 0.3 * TIME_SCALE);
        d = sdBox(p, vec3(1.0));
        if(d < 0.001) { hit = true; break; }
        if(t > 10.0) break;
        t += d;
    }

    // Default background (Paper texture) / Фон по умолчанию (Текстура бумаги)
    vec3 paperCol = PAPER_COL;
    vec3 finalCol = paperCol;

    if(hit) {
        // Calculate UVs based on the cube's hit face
        // Вычисляем UV координаты грани куба
        vec3 n = abs(p);
        vec2 faceUV = (n.x > n.y && n.x > n.z) ? p.yz : (n.y > n.z ? p.xz : p.xy);
        
        // Start with clean watercolor paper on the cube
        vec3 cubeSurface = vec3(0.98, 0.97, 0.95);
        
        // Draw circles on the face / Рисуем кружки на грани
        for(float i = 0.0; i < 50.0; i++) {
            float seed = i * 45.123;
            vec2 pos = vec2(sin(seed + iTime * 0.5), cos(seed * 0.8 + iTime * 0.4)) * 0.7;
            float radius = (0.15 + 0.1 * noise(vec2(i, 2.0))) * RADIUS_SCALE;
            vec3 circleCol = 0.6 + 0.4 * cos(vec3(0,2,4) + i * 1.5);
            cubeSurface = drawCircle(faceUV, pos, radius, circleCol, cubeSurface);
        }
        
        // Darken the color a bit based on depth to add volume
        // Немного затеняем для объема
        finalCol = cubeSurface * (1.0 - t * 0.05); 
    } else {
        // Background logic: subtle vignetting
        // Логика фона: мягкое виньетирование
        finalCol -= length(uv) * 0.1;
    }
    
    // Global paper grain / Общая зернистость
    finalCol *= (1.0 - GRAIN) + GRAIN * noise(fragCoord);

    fragColor = vec4(finalCol, 1.0);
}