AI GENERATED
スカイミラーボール
by touyou
PROMPT
明るい空の中煌めく星々
- DATE
- 2026/6/13
- SOURCE
- AI GENERATED
- MODEL
- gemini-2.5-flash
- LIKES
- 0
VIEW SHADER CODE
#define PI 3.14159265359
// Hash functions from iq (slightly modified versions)
float hash11(float p) {
p = fract(p * .1031);
p *= p + 33.33;
p *= p + p;
return fract(p);
}
// Fixed hash21 to correctly handle vector types and assignments
vec2 hash21(float p_in) {
// p_in is a float. We need to derive a vec2 from it.
vec2 p = fract(p_in * vec3(.1031, .1030, .0973)).xy;
// The original `p += dot(p, p + 33.33);` had type issues:
// 1. `p + 33.33` needs `vec2(33.33)` for scalar-vector addition.
// 2. `dot(vec2, vec2)` returns a float.
// 3. `vec2 += float` is not allowed in GLSL ES 3.00.
// We explicitly calculate the dot product and then add it as a vec2.
float dot_result = dot(p, p + vec2(33.33));
p = p + vec2(dot_result); // Apply the scalar result to both components of p.
return fract((p.x + p.y) * p);
}
// Cosine palette function
vec3 palette(float t, vec3 a, vec3 b, vec3 c, vec3 d) {
return a + b * cos(2.0 * PI * (c * t + d));
}
// 2D Value Noise (similar to snoise but simpler to implement inline)
float snoise(vec2 p) {
vec2 ip = floor(p);
vec2 fp = fract(p);
fp = fp * fp * (3.0 - 2.0 * fp); // Smoothstep interpolation curve
float a = hash11(ip.x + ip.y * 57.0);
float b = hash11(ip.x + 1.0 + ip.y * 57.0);
float c = hash11(ip.x + (ip.y + 1.0) * 57.0);
float d = hash11(ip.x + 1.0 + (ip.y + 1.0) * 57.0);
return mix(mix(a, b, fp.x), mix(c, d, fp.x), fp.y);
}
// Fractional Brownian Motion (FBM) for sky texture
float fbm_sky(vec2 p, float time) {
float f = 0.0;
f += 0.5000 * snoise(p * 1.0 + time * 0.05);
f += 0.2500 * snoise(p * 2.0 + time * 0.08);
f += 0.1250 * snoise(p * 4.0 + time * 0.12);
f += 0.0625 * snoise(p * 8.0 + time * 0.15);
return f;
}
// Generates sparkling stars using a grid-based approach
float starField(vec2 uv, float time) {
vec2 grid_uv = uv * 40.0; // Scale UV to create a grid of potential star cells
vec2 i_uv = floor(grid_uv); // Integer part of grid UV (cell ID)
vec2 f_uv = fract(grid_uv); // Fractional part within cell
float star_brightness = 0.0;
// Iterate over a 3x3 neighborhood of cells around the current pixel
for (int y = -1; y <= 1; y++) {
for (int x = -1; x <= 1; x++) {
vec2 neighbor_cell = i_uv + vec2(float(x), float(y));
// Generate a random seed for this cell based on its ID
float seed = hash11(dot(neighbor_cell, vec2(12.9898, 78.233)));
// Only create a star if the random seed is above a threshold (sparse distribution)
if (seed < 0.9) continue; // Adjust threshold for star density (higher value = fewer stars)
// Generate a random position within the cell, with subtle animation
vec2 star_pos_offset = hash21(seed); // Base offset [0,1)
// Add a subtle wiggle to star positions over time
star_pos_offset += 0.05 * sin(time * (0.5 + seed) + seed * PI * 2.0) * vec2(1.0, 1.0);
// Calculate distance from the current pixel's fractional part to this star's offset
float d = length(f_uv - star_pos_offset);
// Twinkling effect: modulate brightness over time
float twinkle_phase_seed = hash11(seed + time * 0.5); // Use time to animate twinkle phase
float twinkle = sin(time * (1.0 + twinkle_phase_seed * 2.0) + seed * 10.0) * 0.5 + 0.5;
twinkle = pow(twinkle, 2.0 + twinkle_phase_seed * 2.0); // Sharpen the twinkle effect
// Glow profile: inverse smoothstep for falloff from center
float glow_base = smoothstep(0.1, 0.0, d); // Core glow
glow_base += smoothstep(0.2, 0.1, d) * 0.3; // Fainter halo
// Accumulate brightness for all nearby stars
star_brightness += glow_base * twinkle * (0.5 + seed * 0.5) * 1.5; // Vary intensity and apply twinkle
}
}
return star_brightness;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
// Normalize coordinates [-aspect, aspect] or [-1, 1]
vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y;
// --- Sky Background ---
// Generate subtle noise for the sky, animated over time
float background_noise = fbm_sky(uv * 2.0 + iTime * 0.05, iTime);
background_noise = background_noise * 0.5 + 0.5; // Remap noise to [0,1]
// Define a bright sky color palette: light blues, purples, pinks
vec3 sky_color = palette(background_noise * 0.5 + uv.y * 0.3 + iTime * 0.02,
vec3(0.7, 0.8, 1.0), // Base color: light blue
vec3(0.3, 0.2, 0.1), // Amplitude for color variation
vec3(0.5, 0.4, 0.6), // Frequency for color cycling (pink/purple range)
vec3(0.0, 0.1, 0.2)); // Phase offset
// --- Stars ---
float stars = starField(uv, iTime);
// Define a slightly warm white color for the stars
vec3 star_base_color = vec3(1.0, 0.95, 0.9);
vec3 star_color = star_base_color * stars;
// --- Combine Sky and Stars ---
vec3 final_color = sky_color + star_color * 1.5; // Add stars to sky, boosting their brightness
// --- Subtle Vignette ---
// Darken the edges for better composition
float vignette = smoothstep(1.0, 0.7, length(uv));
final_color *= vignette * 0.8 + 0.2;
// --- Exposure/Gamma correction ---
// Slightly adjust overall brightness and contrast
final_color = pow(final_color, vec3(0.8));
fragColor = vec4(final_color, 1.0);
}ZIP を展開して .playground を Xcode でダブルクリックし、Live View を表示して ▶ を押すとシェーダーがアニメーションします。Metal ソースは Resources/Shader.metal に独立ファイルとして入っているので、Xcode 上で直接編集できます。