AI GENERATED

東風が厚い氷を解かし始める

by anonymous

PROMPT

東風が厚い氷を解かし始める

DATE
2026/6/17
SOURCE
AI GENERATED
MODEL
gemini-2.5-flash
LIKES
0
VIEW SHADER CODE
float hash21(vec2 p) {
    p = fract(p * vec2(123.34, 345.45));
    p += dot(p, p + 78.23);
    return fract(p.x * p.y);
}

float noise2d(vec2 p) {
    vec2 i = floor(p);
    vec2 f = fract(p);
    f = f * f * (3.0 - 2.0 * f);

    float a = hash21(i);
    float b = hash21(i + vec2(1.0, 0.0));
    float c = hash21(i + vec2(0.0, 1.0));
    float d = hash21(i + vec2(1.0, 1.0));

    return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
}

float fbm2d(vec2 p) {
    float sum = 0.0;
    float amplitude = 0.5;
    float frequency = 1.0;
    for (int i = 0; i < 5; i++) {
        sum += amplitude * noise2d(p * frequency);
        frequency *= 2.0;
        amplitude *= 0.5;
    }
    return sum;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y;

    float time = iTime * 0.2; // Slow animation speed

    // Subtle domain warping to simulate flow and distortion from "east wind"
    vec2 windForce = vec2(
        fbm2d(uv * 1.5 + time * 0.3) * 0.5,
        fbm2d(uv * 1.5 + time * 0.3 + vec2(10.0, 20.0)) * 0.5
    );
    // Add a more direct, wavy horizontal flow component for "east wind"
    windForce.x += cos(uv.y * 7.0 + time * 0.8) * 0.15;
    
    vec2 p_uv = uv + windForce * 0.15; // Apply small warp to UVs

    // Base "water" layer - smoother, lower frequency, represents melted areas
    float waterValue = fbm2d(p_uv * 2.0 - time * 0.1);

    // "Ice" layer - higher frequency, more detailed, animated to break up
    // Self-perturbation with waterValue adds an organic, depth-like interaction
    float iceRaw = fbm2d(p_uv * 7.0 + time * 0.2 + waterValue * 0.5);

    // Animate the "melting" by making the ice recede or break up over time
    // This value cycles, so the ice subtly melts and reforms, creating continuous animation
    float meltProgress = sin(time * 0.3) * 0.5 + 0.5; // Cycles from 0.0 to 1.0 and back

    // Determine ice presence:
    // A higher meltProgress effectively increases the threshold for ice, making less ice visible.
    float iceThreshold = 0.4 + meltProgress * 0.3; // Ice appears "thinner" or more broken up
    float icePresence = smoothstep(iceThreshold - 0.15, iceThreshold + 0.15, iceRaw);

    // Color palette for the melting ice
    vec3 colorA = vec3(0.05, 0.15, 0.3); // Deepest water/shadows
    vec3 colorB = vec3(0.2, 0.4, 0.7);   // Medium blue for meltwater
    vec3 colorC = vec3(0.7, 0.85, 0.95); // Icy blue
    vec3 colorD = vec3(0.95, 0.98, 1.0); // Brightest ice highlights/whitecaps

    // Mix colors based on the water and ice presence
    vec3 finalColor = mix(colorA, colorB, waterValue); // Base color is deep water
    finalColor = mix(finalColor, colorC, icePresence * 0.7); // Add icy blue where ice is present
    finalColor = mix(finalColor, colorD, icePresence * 1.0); // Add bright highlights for strong ice presence

    // Add some subtle color shift/animation based on wind and melt for dynamic feel
    finalColor += vec3(windForce.x * 0.05, windForce.y * 0.03, meltProgress * 0.05);
    finalColor = clamp(finalColor, 0.0, 1.0); // Ensure colors stay within valid range

    // Subtle vignette to focus the viewer's eye
    float vignette = length(uv);
    vignette = smoothstep(0.0, 1.2, vignette); // Controls the falloff from center
    finalColor *= (1.0 - vignette * 0.3); // Darken edges slightly

    fragColor = vec4(finalColor, 1.0);
}

ZIP を展開して .playground を Xcode でダブルクリックし、Live View を表示して ▶ を押すとシェーダーがアニメーションします。Metal ソースは Resources/Shader.metal に独立ファイルとして入っているので、Xcode 上で直接編集できます。