AI GENERATED

綺麗な海

by anonymous

PROMPT

綺麗な海

DATE
2026/10/8
SOURCE
AI GENERATED
MODEL
gemini-3.6-flash
LIKES
1
VIEW SHADER CODE
// "綺麗な海" (Beautiful Ocean) - Generative Art Fragment Shader

vec3 seaPalette(float t) {
    // Custom turquoise to deep ocean palette
    vec3 a = vec3(0.02, 0.28, 0.42);
    vec3 b = vec3(0.15, 0.45, 0.48);
    vec3 c = vec3(0.80, 0.90, 0.85);
    vec3 d = vec3(0.10, 0.40, 0.55);
    return a + b * cos(6.28318 * (c * t + d));
}

float seaHash(vec2 p) {
    p = fract(p * vec2(123.34, 456.21));
    p += dot(p, p + 34.345);
    return fract(p.x * p.y);
}

float seaNoise(vec2 p) {
    vec2 i = floor(p);
    vec2 f = fract(p);
    f = f * f * (3.0 - 2.0 * f);
    float a = seaHash(i);
    float b = seaHash(i + vec2(1.0, 0.0));
    float c = seaHash(i + vec2(0.0, 1.0));
    float d = seaHash(i + vec2(1.0, 1.0));
    return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
}

float seaHeight(vec2 p, float time, float detailDist) {
    float h = 0.0;
    float amp = 0.55;
    float freq = 0.32;
    mat2 rot = mat2(0.8, 0.6, -0.6, 0.8);
    vec2 dir = vec2(0.9, 0.6);

    // Dynamic wave octaves
    for(int i = 0; i < 5; i++) {
        vec2 q = p * freq + dir * (time * 0.75);
        float w = sin(q.x + sin(q.y * 0.7));
        w += cos(q.y * 1.2 - cos(q.x * 0.8));
        
        // Add sharp chop to wave crests
        float chop = 1.0 - abs(sin(q.x * 0.9 + q.y * 0.5));
        w += chop * 0.35;

        h += w * amp;

        p = rot * p * 1.62;
        amp *= 0.42;
        freq *= 1.58;
        dir = vec2(dir.y, -dir.x) * 1.08;
    }

    // Micro ripple noise for close surface glitter
    if (detailDist < 25.0) {
        float micro = seaNoise(p * 4.0 + vec2(time * 1.5, -time * 1.2));
        h += (micro - 0.5) * 0.08 * (1.0 - detailDist / 25.0);
    }

    return h;
}

vec3 seaNormal(vec2 p, float time, float dist) {
    float eps = 0.005 + dist * 0.001;
    float h = seaHeight(p, time, dist);
    float hx = seaHeight(p + vec2(eps, 0.0), time, dist) - h;
    float hz = seaHeight(p + vec2(0.0, eps), time, dist) - h;
    return normalize(vec3(-hx, eps, -hz));
}

vec3 oceanSky(vec3 rd, vec3 sunDir) {
    float sunDot = max(dot(rd, sunDir), 0.0);
    
    // Sky gradient from bright horizon to deep zenith
    vec3 skyTop = vec3(0.08, 0.35, 0.68);
    vec3 skyHorizon = vec3(0.55, 0.82, 0.92);
    vec3 skyColor = mix(skyHorizon, skyTop, pow(max(rd.y, 0.0), 0.5));
    
    // Soft sun glow
    vec3 sunColor = vec3(1.0, 0.92, 0.75);
    skyColor += sunColor * pow(sunDot, 12.0) * 0.4;
    skyColor += sunColor * pow(sunDot, 250.0) * 1.2;
    
    return skyColor;
}

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

    // Gentle camera motion over water
    float camBob = sin(time * 0.5) * 0.15;
    vec3 ro = vec3(0.0, 1.8 + camBob, time * 2.2);
    
    // Slight roll and pitch
    float roll = sin(time * 0.3) * 0.03;
    vec3 lookAt = vec3(sin(time * 0.2) * 0.5, 1.2, ro.z + 10.0);
    
    vec3 forward = normalize(lookAt - ro);
    vec3 right = normalize(cross(forward, vec3(sin(roll), 1.0, 0.0)));
    vec3 up = cross(right, forward);
    vec3 rd = normalize(uv.x * right + uv.y * up + forward * 1.6);

    vec3 sunDir = normalize(vec3(0.4, 0.32, 0.86));
    vec3 finalColor = vec3(0.0);

    // Raymarch sea surface heightmap
    float t = 0.0;
    float tMax = 80.0;
    bool hit = false;
    vec3 p = ro;

    for(int i = 0; i < 60; i++) {
        p = ro + rd * t;
        float h = p.y - seaHeight(p.xz, time, t);
        if (h < 0.002 * t) {
            hit = true;
            break;
        }
        t += h * 0.45; // Conservative step
        if (t > tMax) break;
    }

    if (hit) {
        vec3 norm = seaNormal(p.xz, time, t);
        
        // Underwater refraction depth tint
        float depth = clamp((seaHeight(p.xz, time, t) - p.y + 0.5) * 1.2, 0.0, 1.0);
        vec3 shallowColor = vec3(0.05, 0.72, 0.75);
        vec3 deepColor = vec3(0.01, 0.12, 0.28);
        vec3 waterBody = mix(shallowColor, deepColor, exp(-depth * 2.0));

        // Subsurface scattering on crests
        float crest = max(0.0, seaHeight(p.xz, time, t) - 0.2);
        vec3 sss = vec3(0.1, 0.85, 0.65) * pow(crest, 2.0) * max(0.0, dot(rd, -sunDir));

        // Sky reflection with Fresnel calculation
        vec3 refDir = reflect(rd, norm);
        vec3 skyRef = oceanSky(refDir, sunDir);
        float fresnel = 0.04 + 0.96 * pow(1.0 - max(0.0, dot(-rd, norm)), 5.0);

        // Sun specular highlights & ocean glitter
        float specDot = max(0.0, dot(refDir, sunDir));
        float specular = pow(specDot, 128.0) * 2.5;
        float glitter = pow(specDot, 512.0) * 6.0 * seaNoise(p.xz * 15.0 + time);

        // Foam tips on high waves
        float foamVal = smoothstep(0.45, 0.75, seaHeight(p.xz, time, t));
        vec3 foamColor = vec3(0.92, 0.97, 1.0) * foamVal * 0.6;

        // Combine lighting components
        finalColor = mix(waterBody + sss, skyRef, fresnel);
        finalColor += (specular + glitter) * vec3(1.0, 0.95, 0.85);
        finalColor += foamColor;

        // Fog fade near horizon
        vec3 fogColor = oceanSky(rd, sunDir);
        float fogFactor = 1.0 - exp(-t * 0.025);
        finalColor = mix(finalColor, fogColor, fogFactor);
    } else {
        // Sky background above horizon
        finalColor = oceanSky(rd, sunDir);
    }

    // Color grading & warmth boost
    finalColor = pow(finalColor, vec3(0.9)); // Slight gamma adjustment
    finalColor = mix(finalColor, seaPalette(length(uv) * 0.2 + time * 0.05), 0.06);

    // Subtle vignette
    vec2 q = fragCoord / iResolution.xy;
    float vignette = q.x * q.y * (1.0 - q.x) * (1.0 - q.y);
    finalColor *= pow(16.0 * vignette, 0.25);

    fragColor = vec4(finalColor, 1.0);
}

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