分形/shadertoy
與 Shadertoy 相關的 GLSL ES 部分
Preprocessor: # #define #undef #if #ifdef #ifndef #else #elif #endif #error #pragma #extension #version #line Operators: () + - ! * / % << >> < > <= >= == != && || Comments: // /* */ Types: void bool int float vec2 vec3 vec4 bvec2 bvec3 bvec4 ivec2 ivec3 ivec4 mat2 mat3 mat4 sampler2D Function Parameter Qualifiers: [none], in, out, inout Global Variable Qualifiers: const Vector Components: .xyzw .rgba .stpq Flow Control: if else for return break continue Output: vec4 gl_FragColor Input: vec4 gl_FragCoord
主要有四種類型:[3]
- float
- int
- bool
- sampler
vec2, vec3, vec4 2D, 3D and 4D floating point vector ivec2, ivec3, ivec4 2D, 3D and 4D integer vector bvec2, bvec3, bvec4 2D, 3D and 4D boolean vectors \\ matrix types: mat2, mat3, mat4 2x2, 3x3, 4x4 floating point matrix \\ sampler1D, sampler2D, sampler3D 1D, 2D and 3D texture samplerCube Cube Map texture sampler1Dshadow, sampler2Dshadow 1D and 2D depth-component texture
type radians (type degrees) type degrees (type radians) type sin (type angle) type cos (type angle) type tan (type angle) type asin (type x) type acos (type x) type atan (type y, type x) type atan (type y_over_x) type pow (type x, type y) type exp (type x) type log (type x) type exp2 (type x) type log2 (type x) type sqrt (type x) type inversesqrt (type x) type abs (type x) type sign (type x) type floor (type x) type ceil (type x) type fract (type x) type mod (type x, float y) type mod (type x, type y) type min (type x, type y) type min (type x, float y) type max (type x, type y) type max (type x, float y) type clamp (type x, type minV, type maxV) type clamp (type x, float minV, float maxV) type mix (type x, type y, type a) type mix (type x, type y, float a) type step (type edge, type x) type step (float edge, type x) type smoothstep (type a, type b, type x) type smoothstep (float a, float b, type x) mat matrixCompMult (mat x, mat y) float length (type x) float distance (type p0, type p1) float dot (type x, type y) vec3 cross (vec3 x, vec3 y) type normalize (type x) type faceforward (type N, type I, type Nref) type reflect (type I, type N) type refract (type I, type N,float eta) bvec lessThan(vec x, vec y) bvec lessThan(ivec x, ivec y) bvec lessThanEqual(vec x, vec y) bvec lessThanEqual(ivec x, ivec y) bvec greaterThan(vec x, vec y) bvec greaterThan(ivec x, ivec y) bvec greaterThanEqual(vec x, vec y) bvec greaterThanEqual(ivec x, ivec y) bvec equal(vec x, vec y) bvec equal(ivec x, ivec y) bvec equal(bvec x, bvec y) bvec notEqual(vec x, vec y) bvec notEqual(ivec x, ivec y) bvec notEqual(bvec x, bvec y) bool any(bvec x) bool all(bvec x) bvec not(bvec x) vec4 texture2D(sampler2D sampler, vec2 coord ) vec4 texture2D(sampler2D sampler, vec2 coord, float bias) vec4 textureCube(samplerCube sampler, vec3 coord) vec4 texture2DProj(sampler2D sampler, vec3 coord ) vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias) vec4 texture2DProj(sampler2D sampler, vec4 coord) vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias) type dFdx( type x ), dFdy( type x ) type fwidth( type p )
將 Shadertoy 著色器轉換為
- GLSL Sandbox 程式碼[4]
"著色器是在 GPU 中執行的程式。一個著色器實際上包含兩個程式:頂點著色器和片段(或畫素)著色器。" [5]
著色器是一個“單個程式,作用於單個畫素,但 Shadertoy 和 WebGL 將其(同時)執行在視窗中的每個畫素上……這要歸功於 GPU 加速的強大功能” [6]
Shadertoy 著色器的型別
- 影像著色器
- 聲音著色器
- VR 著色器
影像著色器實現 mainImage() 函式,以便透過計算每個畫素的顏色來生成過程影像。
預期此函式對每個畫素呼叫一次,並且主機應用程式負責提供正確的輸入並從中獲取輸出顏色並將其分配給螢幕畫素。
原型是
void mainImage( out vec4 fragColor, in vec2 fragCoord );
"uniform 用於從著色器外部獲取值,並將其輸入到著色器中……uniform 可以是向量、浮點數、浮點陣列、整數和整數陣列。" [7]
可以使用以下 **uniform 變數**(Shadertoy 特定輸入)為著色器提供不同型別的每幀靜態資訊
| 型別 | 名稱 | 描述 |
|---|---|---|
| uniform vec3 | iResolution | 視窗解析度。iResolution 的寬度/高度分別設定為 x 和 y。z 是畫素縱橫比,通常為 1.0 |
| uniform float | iGlobalTime | 當前時間(以秒為單位) |
| uniform float | iChannelTime[4] | 通道時間(如果為影片或音訊),以秒為單位 |
| uniform vec3 | iChannelResolution0..3 | 每個通道的輸入紋理解析度 |
| uniform vec4 | iMouse | xy = 當前畫素座標(如果 LMB 已按下)。zw = 點選畫素 |
| uniform sampler2D | iChannel{i} | 輸入紋理 i 的取樣器 |
| uniform vec4 | iDate | 年、月、日、時間(以秒為單位),分別儲存在 .xyzw 中 |
| uniform float | iSampleRate | 聲音取樣率(通常為 44100) |
型別
- 畫素
- x 從 0 到寬度
- y 從 0 到高度
- 歸一化:從 0.0 到 1.0
- 世界:任意範圍
mainImage() 函式的輸入變數是 **fragCoord**(= GLSL 中的 gl_FragCoord)
它包含當前畫素位置(座標)(以畫素為單位),著色器需要為此計算顏色。我們可以訪問它的 x 和 y 值
**座標**以畫素單位表示
解析度透過 iResolution uniform 傳遞到著色器(參見上表)。
要**歸一化**座標(歸一化裝置座標 = NDC),請執行以下操作
// Converting (x,y) to range [0,1] float x = gl_FragCoord.x / iResolution.x; // float y = gl_FragCoord.y / iResolution.y;
"現在我們的 x 和 y 在 0..1 範圍內,我們不再關心(螢幕)解析度、寬度或長度。" [8]
**縱橫比**[9]
x *= iResolution.x / iResolution.y;
"對於影像著色器,常規的 gl_FragColor 用作輸出通道。目前不是強制性的,但建議將 alpha 通道保留為 1.0;"
// This shader computes the same color ( red = 1.0,0.0,0.0 ) for every pixel
// static image
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// color = r,g,b,a
// every value is in range [0.0, 1.0]
fragColor = vec4(1.0,0.0,0.0,1.0);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float r = fragCoord.x / iResolution.x;
float g = fragCoord.y / iResolution.y;
float b = fragCoord.x / iResolution.y;
fragColor = vec4(r,g,b,1.0);
}
水平紅色漸變
// based on the code by Omar Shehata
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float x = fragCoord.x; //We obtain our coordinates for the current pixel
x = x / iResolution.x; //We divide the coordinates by the screen size
// Now x is 0 for the leftmost pixel, and 1 for the rightmost pixel
//Set its red component to the normalized x value = red gradient from left to right
fragColor = vec4(x, 0.0, 0.0, 1.0);
}
垂直綠色漸變
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float y = fragCoord.y; //We obtain our coordinates for the current pixel
y = y / iResolution.y; //We divide the coordinates by the screen size
// Now y is 0 for the bottom pixel, and 1 for the up pixel
//Set its red component to the normalized x value
fragColor = vec4( 0.0, y, 0.0, 1.0);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float x = fragCoord.x/iResolution.x; // 0.0 < x < 1.0
float y = fragCoord.y/iResolution.y; //
fragColor = vec4(0.0,1.0,0.0,1.0); // green = background
if( x > 0.5 && y > 0.5) {fragColor = vec4(1.0,0.0,0.0,1.0);} // red = upper right
if( x < 0.5 && y < 0.5) {fragColor = vec4(0.0,0.0,1.0,1.0);} // blue = lower left
}
// https://www.shadertoy.com/view/MssXWn
// bu Lukas Pukenis http://www.letsdive.in/2014/05/11/glsl-basics/
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
float thicknessH = 0.01;
float thicknessV = 0.01;
float y = fragCoord.y / iResolution.y;
float x = fragCoord.x / iResolution.x;
float diffY = abs(0.5 - y);
float diffX = abs(0.5 - x);
if ( diffY < thicknessH || diffX < thicknessV) {
fragColor = vec4(1.0, 0.0, 0.0, 1.0 );
} else {
fragColor = vec4(0.0, 0.0, 0.0, 1.0 );
}
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float x = fragCoord.x/iResolution.x; // 0.0 < x < 1.0
float y = fragCoord.y/iResolution.y; //
vec2 center = vec2(0.5, 0.5); // center of the image
fragColor = vec4(0.0,1.0,0.0,1.0); // green = background
if( abs(center.x - x) < 0.2 && abs(center.y - y) < 0.2) {fragColor = vec4(1.0,0.0,0.0,1.0);} // red rectangle in center of image
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{ float ratio = iResolution.x / iResolution.y; // aspect ratio of the window : https://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson3
float x = ratio*fragCoord.x/iResolution.x; // 0.0 < x < 1.0*ratio
float y = fragCoord.y/iResolution.y; // 0.0 < y < 1.0
vec2 center = vec2(ratio*0.5, 0.5); // center of the image
fragColor = vec4(0.0,1.0,0.0,1.0); // green = background
if( abs(center.x - x) < 0.2 && abs(center.y - y) < 0.2) {fragColor = vec4(1.0,0.0,0.0,1.0);} // red rectangle in center of image
}
使用畫素座標 的圓形
// https://www.shadertoy.com/view/Mdf3Df
// circle using pixel coordinate
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// the center of the texture
vec2 center = vec2(iResolution.x/2.0,iResolution.y/2.0);
// current pixel location
vec2 loc = fragCoord.xy;
// how far we are from the center
float radius=length(loc-center);
if (radius<100.0)
fragColor = vec4(1,0,0,1); // if we are within our circle, paint it red
else
fragColor = vec4(0,0,0,1); // black background
}
vec2 center = vec2(0.0,0.0); // center of the image in world units
float radius = 2.0; // Radius is defined as "the difference in imaginary coordinate between the center and the top of the axis-aligned view rectangle".
vec2 GiveCoordinate(vec2 center, float radius, vec2 fragCoord, vec3 iResolution)
{
// from pixel to world coordinate
// start with pixel coordinate : now point=(0,0) is left bottom and point=(iResolution.x, iResolution.y) is right top
float x = (fragCoord.x - iResolution.x/2.0)/ (iResolution.y/2.0);
float y = (fragCoord.y - iResolution.y/2.0)/ (iResolution.y/2.0);
vec2 c = vec2(center.x + radius*x, center.y + radius*y) ;
return c ; // now coordinate are measured in world units : from 0.0 t 1.0
}
vec3 GiveColor ( vec2 c, vec2 circle_center, float circle_radius)
{
vec3 color = vec3(1.0, 0.0, 035); // background
// draws a circle centered at circle_center
if ( length(circle_center-c)< circle_radius) {color = vec3(0.0, 0.0, 0.0);}
return color;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord)
{
vec2 c = GiveCoordinate(center, radius, fragCoord, iResolution);
vec3 color = GiveColor(c, vec2(0.0, 0.9), 1.5);
fragColor = vec4(color,1.0); //
}
Julia 集
- 整數逃逸時間和用於外部的水平集方法
- 內部的純色(紅色)
// based on the code by gltracy
// https://www.shadertoy.com/view/XsS3Rm
const int i_max = 2055;
vec2 c = vec2( -0.12256, 0.74486);
float er2 = 4.0; // er= er*er escape radius
vec2 complex_square( vec2 v ) {
return vec2(
v.x * v.x - v.y * v.y,
v.x * v.y * 2.0
);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// compute coordinate
vec2 z = fragCoord.xy - iResolution.xy * 0.5;
z *= 2.5 / min( iResolution.x, iResolution.y );
float scale = 0.1;
int count = 0;
// iterations
for ( int i = 0 ; i < i_max; i++ ) {
z = c + complex_square( z );
count = i;
if ( dot(z,z) > er2 ) { break; }
}
// color
if (count == i_max-1) {fragColor = vec4(1.0, 0.0,0.0,1.0);} // filled-in Julia set = red
else fragColor = vec4(1.0- float( count ) * scale ); // exterior
}
軌道陷阱,拋物線棋盤格
// https://www.shadertoy.com/view/4dy3RR
// Orbit trapped julia by maeln
#define MAXITER 128
vec2 cmul(vec2 i1, vec2 i2)
{
return vec2(i1.x*i2.x - i1.y*i2.y, i1.y*i2.x + i1.x*i2.y);
}
vec3 julia(vec2 z, vec2 c)
{
int i = 0;
vec2 zi = z;
float trap1 = 10e5;
float trap2 = 10e5;
for(int n=0; n < MAXITER; ++n)
{
if(dot(zi,zi) > 4.0)
break;
i++;
zi = cmul(zi,zi) + c;
// Orbit trap
trap1 = min(trap1, sqrt(zi.x*zi.y));
trap2 = min(trap2, sqrt(zi.y*zi.y));
}
return vec3(i,trap1,trap2);
}
vec4 gen_color(vec3 iter)
{
float t1 = 1.0+log(iter.y)/8.0;
float t2 = 1.0+log(iter.z)/16.0;
float t3 = t1/t2;
//vec3 comp = vec3(t1,t1,t1);
vec3 red = vec3(0.9,0.2,0.1);
vec3 black = vec3(1.0,1.0,1.0);
vec3 blue = vec3(0.1,0.2,0.9);
vec3 comp = mix(blue,black,vec3(t2));
comp = mix(red,comp,vec3(t1));
return vec4(comp, 1.0);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 z = 2.*(2.*fragCoord.xy - iResolution.xy) / iResolution.x;
// Display the julia fractal for C = (-0.8, [0.0;0.3]).
vec3 iter = julia(z, vec2(cos(iTime/5.0), mix(0.0, 0.3, sin(iTime))));
fragColor = gen_color(iter);
}
二次一維多項式 fc(z)=z²+c 的動力學
// Created by inigo quilez - iq/2013
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
//
//-----------------https://www.shadertoy.com/view/MdX3zN-------------------------------------------
//
// Dynamics for quadratic 1D polynomials fc(z)=z²+c
//
// * Orange: the Fatou set Kc.
// * Black: the Julia set Jc.
// * Checkerboard distortion: the Boettcher map phi(z).
// * Checkerboard shadowing: the gradient of the Green's function, log|phi(z)|
// * Blue: the two fixed points.
// * Green, the period 2 fixed points.
// * White: c
// * Yellow: the Koening coordinates
//
// Some theory:
//
// * c (white) belongs to Kc (orange), for these are all connected Julia sets.
//
// * When both fixed points (blue) are in Jc but not in Kc, or in other words, when both points
// are repeling (derivative of fc(z) is bigger than one), c does not belong to the Mandelbrot
// set's main cardioid, but to bulbs of higher period. In that case Kc (orange) is made of several
// branches (as many as the period of the bul)
//
// * When one of the two fixed points (blue dots) is inside Kc, meanins it is attractive (derivative
// of fc(z) < 1), then c belongs to the main cardiod of the Mandelbrot set, and Kc is a single piece
// shape.
//
// * When the period 2 fixed points are always repelling (belong to Jc, not to Kc) except for the sets
// that have c belonging to the period-2 bulb of the Mandelbrot set. In those cases, the green dots
// become attrative and sit inside the orange area Kc.
//
// * The Koening coordinates can only been seen when c belongs to the main cariod of the Madelbrot set
//
//------------------------------------------------------------
// complex number operations
vec2 cadd( vec2 a, float s ) { return vec2( a.x+s, a.y ); }
vec2 cmul( vec2 a, vec2 b ) { return vec2( a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x ); }
vec2 cdiv( vec2 a, vec2 b ) { float d = dot(b,b); return vec2( dot(a,b), a.y*b.x - a.x*b.y ) / d; }
vec2 csqrt( vec2 z ) { float m = length(z); return sqrt( 0.5*vec2(m+z.x, m-z.x) ) * vec2( 1.0, sign(z.y) ); }
vec2 conj( vec2 z ) { return vec2(z.x,-z.y); }
vec2 cpow( vec2 z, float n ) { float r = length( z ); float a = atan( z.y, z.x ); return pow( r, n )*vec2( cos(a*n), sin(a*n) ); }
//------------------------------------------------------------
float argument( in vec2 p )
{
float f = atan( p.y, p.x );
if( f<0.0 ) f += 6.2831;
f = f/6.2831;
return f;
}
float grid( in vec2 p )
{
vec2 q = 16.0*p;
vec2 r = fract( q );
float fx = smoothstep( 0.05, 0.06, r.x ) - smoothstep( 0.94, 0.95, r.x );
float fy = smoothstep( 0.05, 0.06, r.y ) - smoothstep( 0.94, 0.95, r.y );
return 0.5 + 0.5*mod( floor(q.x)+floor(q.y), 2.0 );
}
float cross( vec2 a, vec2 b )
{
return a.x*b.y - a.y*b.x;
}
bool isInTriangle( in vec2 p, in vec2 a, in vec2 b, in vec2 c )
{
vec3 di = vec3( cross( b - a, p - a ),
cross( c - b, p - b ),
cross( a - c, p - c ) );
return all(greaterThan(di,vec3(0.0)));
}
float distanceToSegment( vec2 a, vec2 b, vec2 p )
{
vec2 pa = p - a;
vec2 ba = b - a;
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
return length( pa - ba*h );
}
vec3 circle( vec3 bcol, vec3 col, in vec2 a, in vec2 b )
{
float rr = 0.04;
vec3 res = mix( bcol, col, 1.0 - smoothstep( rr-0.01, rr, length(a-b) ) );
float f = smoothstep( rr-0.01, rr, length(a-b) ) - smoothstep( rr, rr+0.01, length(a-b) );
return mix( res, vec3(0.0), f );
}
//------------------------------------------------------------
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy/iResolution.xy;
vec2 p = -1.0 + 2.0*uv;
p.x *= iResolution.x/iResolution.y;
float at = mod( (iTime+.5)/5.0, 8.0 );
vec2 c = vec2(-0.800, 0.100);
c = mix( c, vec2( 0.280,-0.490), smoothstep(0.0,0.1,at) );
c = mix( c, vec2(-0.500,-0.500), smoothstep(1.0,1.1,at) );
c = mix( c, vec2(-0.160, 0.657), smoothstep(2.0,2.1,at) );
c = mix( c, vec2(-0.650, 0.100), smoothstep(3.0,3.1,at) );
c = mix( c, vec2(-0.114, 0.650), smoothstep(4.0,4.1,at) );
c = mix( c, vec2(-0.731, 0.166), smoothstep(5.0,5.1,at) );
c = mix( c, vec2(-0.100,-0.660), smoothstep(6.0,6.1,at) );
c = mix( c, vec2(-0.800, 0.100), smoothstep(7.0,7.1,at) );
// get the 2 fixed points
vec2 one = vec2( 1.0, 0.0 );
vec2 fix1_1 = 0.5*( one + csqrt( one - 4.0*c ) );
vec2 fix1_2 = 0.5*( one - csqrt( one - 4.0*c ) );
vec2 fix2_1 = -(csqrt(-4.0*c-3.0*one)+one)/2.0;
vec2 fix2_2 = (csqrt(-4.0*c-3.0*one)-one)/2.0;
vec2 fix2_3 = -(csqrt( one-4.0*c)-one)/2.0;
vec2 fix2_4 = (csqrt( one-4.0*c)+one)/2.0;
vec2 z = p;
vec2 dz = vec2( 1.0, 0.0 );
vec2 ph = z;
vec2 gr = vec2( log(length(z)), atan(z.y,z.x) );
float t = 0.0;
for( int i=0; i<512; i++ )
{
if( dot(z,z)>10000.0 ) continue;
t += 1.0;
// derivative
dz = 2.0*cmul( z, dz );
// point
z = cmul(z,z) + c;
vec2 a = cdiv(z,z-c);
float s = pow( 0.5, t );
// phi
ph = cmul( ph, cpow(a, s) );
// green
gr.x += log(length(a)) * s;
float aa = atan(a.y,a.x);
if( isInTriangle( z, vec2(0.0), fix1_2, c ) )
{
aa -= sign(aa)*2.0*3.14159;
}
gr.y += aa * s;
}
vec3 col = vec3(1.0,0.65,0.10);
if( t<511.0 )
{
float s = pow( 0.5, t );
vec2 phib = cpow( z, s );
float phiR = length( phib );
float greenR = log(length(z)) * s;
float greenI = argument(z*s);
float d = log( length(z) ) * length(z) / length(dz);
vec2 gradG = -conj(cmul( dz, conj(z) ));
float n = t/50.0;
float sn = -log2(abs(greenR))/50.0;
col = vec3( 0.6 + 0.4*dot(normalize(-gradG),vec2(0.707)) );
col *= vec3( grid( ph ) );
col *= vec3(1.0)*clamp(d*50.0,0.0,1.0);
}
else
{
z = p;
float t = 0.0;
for( int i=0; i<200; i++ )
{
if( length(z-fix1_2)>0.001 )
{
z = cmul(z,z) + c;
t += 1.0;
}
}
vec2 fix = fix1_2;
if( length(2.0*fix1_1)<1.0 ) fix=fix1_1;
if( length(2.0*fix)<1.0 )
{
vec2 ph = cdiv( z - fix, cpow(2.0*fix,t) );
float g = log(length(ph));
float l = 1.0 - 0.1*smoothstep( 0.7, 0.71, sin(48.0*g) );
col += 0.1*(abs(g));
ph = 1.0*vec2( length(ph), atan(ph.y,ph.x)/3.14 );
col *= l;
}
}
// color depending of attractive/repulsive fixed point
col = circle( col, vec3(1.0,1.0,1.0), p, c );
vec3 col2 = vec3(0.0,1.0,0.0);
col = circle( col, col2, p, fix2_1 );
col = circle( col, col2, p, fix2_2 );
col = circle( col, col2, p, fix2_3 );
col = circle( col, col2, p, fix2_4 );
vec3 col1 = vec3(0.0,0.7,1.0);
col = circle( col, col1, p, fix1_1 );
col = circle( col, col1, p, fix1_2 );
fragColor = vec4( col, 1.0 );
}
曼德勃羅集
- 布林逃逸時間方法
- 外部的純色 background_color = vec3(1.0, 0.0, 035);
- 內部的純色 mandel_color = vec3(0.0, 0.0, 0.0);
使用 的平面描述
// https://www.shadertoy.com/view/4sVGWz
// Simple_Mandelbrot by Created by r1nat in 2016-Jan-29
//Based on explanation http://www.hiddendimension.com/fractalmath/Divergent_Fractals_Main.html
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 c = fragCoord.xy / iResolution.xy;
//scaling real axis to [-2.5, 1.5] and imaginary axis to [-1.5, 1.5]
c = c * vec2(4,3) - vec2(2.5, 1.5);
vec2 z = vec2(0);
fragColor = vec4(0);
for (int i=0;i<100;i++)
{
if (z.x * z.x + z.y * z.y >= 4.)
{
fragColor = vec4(1);
break;
}
z = vec2(z.x*z.x - z.y*z.y, 2.*z.x*z.y) + c;
}
}
// image parameters in world coordinate
vec2 center = vec2(-0.75,0.0); // center of the image in world units : http://mightymandel.mathr.co.uk/gallery.html
float radius = 1.25; // Radius is defined as "the difference in imaginary coordinate between the center and the top of the axis-aligned view rectangle".
// escape time algorithm
float er2 = 40.0; // square of escape radius : er2 = er*er so er = 2.0
#define imax 1000
// rgb colors
vec3 background_color = vec3(1.0, 0.0, 035);
vec3 mandel_color = vec3(0.0, 0.0, 0.0);
// compute pixel coordinate in world units
vec2 GiveCoordinate(vec2 center, float radius, vec2 fragCoord, vec3 iResolution)
{
// from pixel to world coordinate
// start with pixel coordinate : now point=(0,0) is left bottom and point=(iResolution.x, iResolution.y) is right top
float x = (fragCoord.x - iResolution.x/2.0)/ (iResolution.y/2.0);
float y = (fragCoord.y - iResolution.y/2.0)/ (iResolution.y/2.0);
vec2 c = vec2(center.x + radius*x, center.y + radius*y) ;
return c ; // now coordinate are measured in world units : from 0.0 t 1.0
}
// square of vector ( = complex number)
vec2 complex_square( vec2 v ) {
return vec2(
v.x * v.x - v.y * v.y,
v.x * v.y * 2.0
);
}
bool CheckIfIsInsideMandelbrot(vec2 c)
{
int count=0;
vec2 z = vec2(0.0, 0.0); // initial value is a critical point
// iterations
for ( int i = 0 ; i < imax; i++ ) {
z = c + complex_square( z ); // z = fc(z) = z^2+c
count = i;
if ( dot(z,z) > er2 ) { break; }
}
if (count==imax-1)
{return true;}
else return false;
}
vec3 GiveColor ( vec2 c )
{
bool IsInside = CheckIfIsInsideMandelbrot(c);
if ( IsInside) {return mandel_color; }
else return background_color;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord)
{
vec2 c = GiveCoordinate(center, radius, fragCoord, iResolution);
vec3 color = GiveColor(c);
fragColor = vec4(color,1.0); //
}
曼德勃羅集
- 整數逃逸時間方法 = 水平集方法
- 外部的梯度
- 內部的純色 vec3(0.0, 0.0, 0.0);
使用 的平面描述
// image parameters in world coordinate
//vec2 center = vec2(-0.75,0.0); // center of the image in world units : http://mightymandel.mathr.co.uk/gallery.html
//float radius = 1.25; // Radius is defined as "the difference in imaginary coordinate between the center and the top of the axis-aligned view rectangle".
vec2 center = vec2(-0.771139525,-0.115216065);
float radius = 0.001;
// escape time algorithm
float er2 = 4.0; // square of escape radius : er2 = er*er so er = 2.0
#define imax 500
// compute pixel coordinate in world units
vec2 GiveCoordinate(vec2 center, float radius, vec2 fragCoord, vec3 iResolution)
{
// from pixel to world coordinate
// start with pixel coordinate : now point=(0,0) is left bottom and point=(iResolution.x, iResolution.y) is right top
float x = (fragCoord.x - iResolution.x/2.0)/ (iResolution.y/2.0);
float y = (fragCoord.y - iResolution.y/2.0)/ (iResolution.y/2.0);
vec2 c = vec2(center.x + radius*x, center.y + radius*y) ;
return c ; // now coordinate are measured in world units : from 0.0 t 1.0
}
// based on the code by gltracy https://www.shadertoy.com/view/XsS3Rm
// square of vector ( = complex number)
vec2 complex_square( vec2 v ) {
return vec2(
v.x * v.x - v.y * v.y,
v.x * v.y * 2.0 );
}
// based on the code by gltracy https://www.shadertoy.com/view/XsS3Rm
int GiveLevel(vec2 c)
{
int final_i = 0; // level
vec2 z = vec2(0.0, 0.0); // initial value is a critical point
// iterations
for ( int i = 0 ; i < imax; i++ ) {
z = c + complex_square( z ); // z = fc(z) = z^2+c
final_i = i;
if ( dot(z,z) > er2 ) { break; }
}
return final_i;
}
vec3 GiveColor ( int i)
{
vec3 color;
if ( i < imax )
// level set method = LSM/M
// based on https://www.weheartswift.com/fractals-xcode-6/ by Silviu Pop
{ color.r = sin(float(i) / 3.0); // exterior of Mandelbrot set
color.g = cos(float(i) / 6.0);
color.b = cos(float(i) / 12.0 + 3.14 / 4.0);
}
else color= vec3(0.0, 0.0, 0.0); // interior of mandelbrot set
return color;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord)
{
vec2 c = GiveCoordinate(center, radius, fragCoord, iResolution);
int level = GiveLevel(c );
vec3 color = GiveColor(level);
fragColor = vec4(color,1.0); //
}
// image parameters in world coordinate
vec2 center = vec2(-0.75,0.0); // center of the image in world units : http://mightymandel.mathr.co.uk/gallery.html
float radius = 1.5; // Radius is defined as "the difference in imaginary coordinate between the center and the top of the axis-aligned view rectangle".
// escape time algorithm
float er2 = 100000.0; // square of escape radius : er2 = er*er so er = 1000.0;
#define imax 1000
// rgba colors
vec4 up_color = vec4(1.0, 1.0, 1.0, 1.0);// target set up
vec4 down_color = vec4(0.0, 0.0, 0.0, 1.0); // target set down
vec4 mandel_color = vec4(0.0, 0.0, 0.0, 1.0); // inside
// compute pixel coordinate in world units
vec2 GiveCoordinate(vec2 center, float radius, vec2 fragCoord, vec3 iResolution)
{
// from pixel to world coordinate
// start with pixel coordinate : now point=(0,0) is left bottom and point=(iResolution.x, iResolution.y) is right top
float x = (fragCoord.x - iResolution.x/2.0)/ (iResolution.y/2.0);
float y = (fragCoord.y - iResolution.y/2.0)/ (iResolution.y/2.0);
vec2 c = vec2(center.x + radius*x, center.y + radius*y) ;
return c ; // now coordinate are measured in world units : from 0.0 t 1.0
}
// square of vector ( = complex number)
vec2 complex_square( vec2 v ) {
return vec2(
v.x * v.x - v.y * v.y,
v.x * v.y * 2.0
);
}
int CheckType(vec2 c)
{
int count=0;
vec2 z = vec2(0.0, 0.0); // initial value is a critical point
// iterations
for ( int i = 0 ; i < imax; i++ ) {
z = c + complex_square( z ); // z = fc(z) = z^2+c
count = i;
if ( dot(z,z) > er2 ) { break; }
}
if (count==imax-1)
{return 0;}
else
if (z.x>0.0) return 1;
else return 2;
}
vec4 GiveColor ( vec2 c )
{
int colorType = CheckType(c);
if ( colorType==0) {return mandel_color; }
if (colorType==1) return up_color;
return down_color;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord)
{
vec2 c = GiveCoordinate(center, radius, fragCoord, iResolution);
fragColor = GiveColor(c);
}
//see http://linas.org/art-gallery/escape/escape.html for more info on normalizing the Mandelbrot escape
// Smooth Mandelbrot Created by Justaway in 2015-Jan-2
// https://www.shadertoy.com/view/ltXGDN
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float e=100.0;
vec2 c = vec2(
(fragCoord.x-iResolution.x/2.0)/iResolution.y,
(fragCoord.y-iResolution.y/2.0)/iResolution.y);
c*=2.5;
int ic=0;
vec2 tz;
vec2 z=vec2(0.0);
for(int i=0;i<32;i++){
if(length(z)<e){
tz=z;
z.x=tz.x*tz.x-z.y*tz.y+c.x;
z.y=2.0*tz.x*tz.y+c.y;
ic++;
}
}
float m=float(ic)-(log(log(length(z))))/log(2.0);
fragColor=vec4(abs(sin(m/5.0)));
}
// Mandelbrot set zoom, with smooth coloring (Douady-Hubbard) by iq]
// https://www.shadertoy.com/view/lllGWH
// Created by inigo quilez - iq/2015
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
void mainImage( out vec4 f, in vec2 p )
{
float n = 0.;
vec2 c = vec2(-.745,.186) + 3. * (p.xy/iResolution.y-.5)*pow(.01,1.+cos(.2*iGlobalTime)), z=c*n;
for( int i=0; i<128; i++ )
{
z = vec2( z.x*z.x - z.y*z.y, 2.*z.x*z.y ) + c;
if( dot(z,z)>1e4 ) break;
n++;
}
f = .5 + .5*cos( vec4(3,4,11,0) + .05*(n - log2(log2(dot(z,z)))) );
}
// https://www.shadertoy.com/view/ldfSW4
// The trees are breathing Created by jld in 2014-May-24
#define M_PI 3.14159265358979323846
#define N 53
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 rth = fragCoord.xy / iResolution.xy * 2.0 * M_PI;
rth.y *= iResolution.y / iResolution.x;
rth.x += (iTime / 60.0) * 2.0 * M_PI;
vec2 z0 = (1.0 + rth.y) * vec2(cos(rth.x), sin(rth.x)) / 2.0;
vec2 z1 = vec2(1.0, 0.0) - z0;
vec2 c = vec2(z0.x * z1.x - z0.y * z1.y, z0.x * z1.y + z0.y * z1.x);
vec2 a = c;
float g = 1.0;
float thresh = 10.0 + 6.0 ;
vec3 color = vec3(1.0, 1.0, 1.0);
// color += (1.0 + cos (iTime)) * vec3(0.0, 0.007, 0.01) * clamp(z1.x - z0.x, -2.0, 3.0);
for (int i = 0; i < N; ++i) {
if (dot(a, a) > thresh) {
break;
}
g *= 0.9;
a = vec2(a.x * a.x - a.y * a.y, 2.0 * a.x * a.y) + c;
}
fragColor = vec4(g * color, 1.0);
}
// https://www.shadertoy.com/view/4st3Wn
// Filled Mandelbrot created by Kramin in 2015-Dec-1
#define AA 2
#define maxIteration 300
#define CX -0.75
#define CY 0.0
#define INVZOOM 2.5
#define T 20.0
float getColourValue(float mu, float s, float m, float e)
{
if (mu<s) {
return 0.0;
} else if (mu<m) {
return (mu - s)/(m-s);
} else if (mu<e) {
return 1.0 - (mu - m)/(e-m);
}
return 0.0;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
float modtime = iTime*1.5; //controls the slight pulsating
float sinsq1 = max(0.0,sin(modtime)); sinsq1 = sinsq1*sinsq1;
float sinsq2 = max(0.0,sin(modtime+0.75)); sinsq2 = sinsq2*sinsq2;
float sinsq3 = max(0.0,sin(modtime+1.5)); sinsq3 = sinsq3*sinsq3;
float sinsq4 = max(0.0,sin(modtime+2.25)); sinsq4 = sinsq4*sinsq4;
float izoom = INVZOOM;
vec3 colour = vec3(0.0,0.0,0.0);
#if AA>1
for( int m=0; m<AA; m++ )
for( int n=0; n<AA; n++ )
{
vec2 c = vec2(CX,CY) + (fragCoord+vec2(float(m),float(n))/float(AA)-iResolution.xy/2.0)*izoom/iResolution.y;
float w = float(AA*m+n);
#else
vec2 c = vec2(CX,CY) + (fragCoord-iResolution.xy/2.0)*izoom/iResolution.y;
#endif
vec2 z = c;
float iteration = float(maxIteration);
float zlen = length(z);
float minz = zlen;
int minziter = 0;
for (int i = 0; i<maxIteration; i++) {
if (zlen > 3000.0) {
iteration = float(i);
break;
}
if (zlen < minz){
minziter = i;
minz = zlen;
}
// do z = z^2 + c
z = mat2(z,-z.y,z.x)*z + c;
zlen = length(z);
}
if (iteration < float(maxIteration)){
//smooth colouring
float mu = float(iteration) - log(log(length(vec2(z))))/0.6931471805599453; //log(2.0) = 0.6931471805599453
mu = max(mu,0.0);
//transform to between 0 and 1
//mu/(mu+constant) goes to 1 as mu goes to infinity and to 0 as mu goes to 0.
//This transformation is much better than a simple mu = mu/maxIteration because it
//is independent of maxIteration
mu=mu/(mu+T);
//colour.x += getColourValue(mu,0.5,1.0,1.0) + getColourValue(mu,0.0,0.5,1.0)*0.9 + getColourValue(mu,-1.0,-0.5,0.5)*0.3;
//colour.y += getColourValue(mu,0.5,1.0,1.0) + getColourValue(mu,0.0,0.5,1.0)*0.1 + getColourValue(mu,-1.0,-0.5,0.5)*0.0;
//colour.z += getColourValue(mu,0.5,1.0,1.0) + getColourValue(mu,0.0,0.5,1.0)*0.1 + getColourValue(mu,-1.0,-0.5,0.5)*0.4;
colour += getColourValue(mu,0.5+0.05*(-0.5*sinsq2+0.5),1.0,1.0) + (0.2*sinsq2+0.8)*getColourValue(mu,0.0,0.5,1.0)*vec3(0.867,0.282,0.078) + (0.2*sinsq1+0.8)*getColourValue(mu,-1.0,-0.5,0.5)*vec3(0.302,0.114,0.208);
}
else {
float mu = float(minziter);
mu = (0.5+0.25*(-0.2*sinsq4+0.8))*10.0/(mu+10.0)+0.25*(-0.2*sinsq3+0.8)*sqrt(minz);//sqrt(minz) adds a little gradient to the interior
//colour.x += getColourValue(mu,0.0,0.7,1.0)*0.1 + getColourValue(mu,0.0,0.4,0.7)*0.0 + getColourValue(mu,0.0,0.1,0.5);
//colour.y += getColourValue(mu,0.0,0.7,1.0)*0.0 + getColourValue(mu,0.0,0.4,0.7)*0.6 + getColourValue(mu,0.0,0.1,0.5);
//colour.z += getColourValue(mu,0.0,0.7,1.0)*0.2 + getColourValue(mu,0.0,0.4,0.7)*0.8 + getColourValue(mu,0.0,0.1,0.5);
colour += getColourValue(mu,0.0,0.7,1.0)*vec3(0.302,0.114,0.208) + getColourValue(mu,0.0,0.4,0.7)*vec3(0.867,0.282,0.078) + getColourValue(mu,0.0,0.1,0.5);
}
#if AA>1
}
colour /= float(AA*AA);
#endif
fragColor = vec4( colour.x, colour.y, colour.z, 1.0 );
}