added 3d game of life
This commit is contained in:
parent
0225da6050
commit
42c04603b0
|
@ -0,0 +1,9 @@
|
||||||
|
# John Conway's Game of Life: 3D
|
||||||
|
Multipass GPU implementation of the famous Game of Life. But in 3D!
|
||||||
|
The rules of this 3D version are as follows:
|
||||||
|
A cell lives if:
|
||||||
|
- it is alive and either 5 or 6 neighboors are alive
|
||||||
|
- or it has 4 alive neighboors
|
||||||
|
otherwise the cell dies.
|
||||||
|
|
||||||
|
![overview.png](https://git.teridax.de/teridax/Shadertoy-Shaders/raw/branch/main/John-Conway's-Game-of-Life:2D/overview.png)
|
Binary file not shown.
|
@ -0,0 +1,41 @@
|
||||||
|
void mainImage(out vec4 fragColor, in vec2 fragCoord)
|
||||||
|
{
|
||||||
|
ivec3 xyz = to3d(ivec2(fragCoord));
|
||||||
|
|
||||||
|
if (xyz.x >= int(Size) || xyz.y >= int(Size) || xyz.z >= int(Size))
|
||||||
|
{
|
||||||
|
fragColor = vec4(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iFrame == 0)
|
||||||
|
{
|
||||||
|
fragColor = vec4( step(0.99, sin(fragCoord.x * 4.0 * fragCoord.y)) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iFrame % 32 != 0)
|
||||||
|
{
|
||||||
|
fragColor = texture(iChannel0, fragCoord/iResolution.xy);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int c = 0;
|
||||||
|
for (int x = -1; x < 2; x++)
|
||||||
|
for (int y = -1; y < 2; y++)
|
||||||
|
for (int z = -1; z < 2; z++)
|
||||||
|
{
|
||||||
|
if (x == 0 && y == 0 && z == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
c += int(texelFetch(iChannel0, to2d(to3d(ivec2(fragCoord)) + ivec3(x,y,z)), 0).r);
|
||||||
|
}
|
||||||
|
|
||||||
|
int m = int(texelFetch(iChannel0, to2d(to3d(ivec2(fragCoord))), 0).r);
|
||||||
|
|
||||||
|
vec3 live = vec3(0);
|
||||||
|
if (m == 1 && (c == 5 || c == 6) || c == 4)
|
||||||
|
live = vec3(1);
|
||||||
|
|
||||||
|
fragColor = vec4(live, 1);
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
const float Size = 16.;
|
||||||
|
|
||||||
|
vec2 pixelize(in vec2 xy)
|
||||||
|
{
|
||||||
|
return floor(xy*Size)/Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ivec3 to3d(in ivec2 xy)
|
||||||
|
{
|
||||||
|
return ivec3(xy.x, xy.y/int(Size), xy.y % int(Size)) + ivec3(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
ivec2 to2d(in ivec3 xyz)
|
||||||
|
{
|
||||||
|
ivec3 stw = xyz - ivec3(4);
|
||||||
|
return ivec2(stw.x, stw.y*int(Size) + stw.z);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
|
||||||
|
|
||||||
|
#define AA 2.
|
||||||
|
|
||||||
|
vec2 boxIntersection(in vec3 ro, in vec3 rd, in vec3 size)
|
||||||
|
{
|
||||||
|
vec3 m = 1.0/rd;
|
||||||
|
vec3 n = m*ro;
|
||||||
|
vec3 k = abs(m)*size;
|
||||||
|
vec3 t1 = -n - k;
|
||||||
|
vec3 t2 = -n + k;
|
||||||
|
float tN = max( max( t1.x, t1.y ), t1.z );
|
||||||
|
float tF = min( min( t2.x, t2.y ), t2.z );
|
||||||
|
if(tN > tF)
|
||||||
|
return vec2(-1.0);
|
||||||
|
return vec2( tN, tF );
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 rot(in float t)
|
||||||
|
{
|
||||||
|
float c = cos(t);
|
||||||
|
float s = sin(t);
|
||||||
|
return mat2(c, -s, s, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 wavelengthToRGB(float wavelength) {
|
||||||
|
vec3 rgb;
|
||||||
|
if (wavelength < 380.0) {
|
||||||
|
rgb = vec3(0.0, 0.0, 0.0);
|
||||||
|
} else if (wavelength < 440.0) {
|
||||||
|
rgb = vec3(0.0, 0.0, 0.4 + 0.6 * (wavelength - 380.0) / (440.0 - 380.0));
|
||||||
|
} else if (wavelength < 490.0) {
|
||||||
|
rgb = vec3(0.0, (wavelength - 440.0) / (490.0 - 440.0), 1.0);
|
||||||
|
} else if (wavelength < 510.0) {
|
||||||
|
rgb = vec3((wavelength - 490.0) / (510.0 - 490.0), 1.0, 1.0 - (wavelength - 490.0) / (510.0 - 490.0));
|
||||||
|
} else if (wavelength < 580.0) {
|
||||||
|
rgb = vec3(1.0, 1.0 - (wavelength - 510.0) / (580.0 - 510.0), 0.0);
|
||||||
|
} else if (wavelength < 645.0) {
|
||||||
|
rgb = vec3(1.0 - (wavelength - 580.0) / (645.0 - 580.0), 0.0, (wavelength - 580.0) / (645.0 - 580.0));
|
||||||
|
} else if (wavelength < 781.0) {
|
||||||
|
rgb = vec3(0.0, 0.0, 0.4 + 0.6 * (780.0 - wavelength) / (780.0 - 645.0));
|
||||||
|
} else {
|
||||||
|
rgb = vec3(0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainImage(out vec4 fragColor, in vec2 fragCoord)
|
||||||
|
{
|
||||||
|
vec3 sum = vec3(0);
|
||||||
|
for (float x = 0.; x < AA; x++)
|
||||||
|
for (float y = 0.; y < AA; y++)
|
||||||
|
{
|
||||||
|
vec2 uv = (fragCoord+vec2(x,y)/AA-.5*iResolution.xy)/iResolution.y;
|
||||||
|
|
||||||
|
vec3 ro = vec3(0,0,-5);
|
||||||
|
vec3 rd = normalize(vec3(uv, 1));
|
||||||
|
|
||||||
|
mat2 r0 = rot( iTime *.1 );
|
||||||
|
mat2 r1 = rot(0.4);
|
||||||
|
|
||||||
|
ro.yz *= r1;
|
||||||
|
rd.yz *= r1;
|
||||||
|
ro.xz *= r0;
|
||||||
|
rd.xz *= r0;
|
||||||
|
|
||||||
|
vec2 dist = boxIntersection(ro, rd, vec3(1)) + vec2(1e-4,-1e-4);
|
||||||
|
|
||||||
|
vec3 col = vec3(0);
|
||||||
|
|
||||||
|
vec3 p = ro + rd * dist.x;
|
||||||
|
float S = 128.;
|
||||||
|
float d = (dist.y-dist.x)/S;
|
||||||
|
|
||||||
|
for (float i = 0.; dist.x > 0. && i < S; i++)
|
||||||
|
{
|
||||||
|
vec3 k = floor(p*Size)/Size;
|
||||||
|
ivec3 v = ivec3((k*.5+.5)*Size);
|
||||||
|
if (texelFetch(iChannel0, to2d(v), 0).r > 0.5)
|
||||||
|
{
|
||||||
|
float c = 0.;
|
||||||
|
for (int x = -1; x < 2; x++)
|
||||||
|
for (int y = -1; y < 2; y++)
|
||||||
|
for (int z = -1; z < 2; z++)
|
||||||
|
c += texelFetch(iChannel0, to2d(v + ivec3(x,y,z)), 0).r;
|
||||||
|
|
||||||
|
float b = 1.;
|
||||||
|
for (int y = 1; y < 9; y++)
|
||||||
|
b += texelFetch(iChannel0, to2d(v + ivec3(0,y,0)), 0).r;
|
||||||
|
|
||||||
|
col = wavelengthToRGB( c / 27.0 * (780.-440.) + 440. ) / b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
p += rd * d;
|
||||||
|
}
|
||||||
|
|
||||||
|
sum += col;
|
||||||
|
}
|
||||||
|
|
||||||
|
sum /= AA * AA;
|
||||||
|
|
||||||
|
fragColor = vec4(sum, 1.0);
|
||||||
|
}
|
Loading…
Reference in New Issue