Skip to content

Commit 2721e91

Browse files
committed
Sierpinski Octahedron
got bored, made a fractal
1 parent 246afab commit 2721e91

9 files changed

+2484
-0
lines changed

Fractals Project/Assets/Scenes/OctahedronFlake.unity

+2,247
Large diffs are not rendered by default.

Fractals Project/Assets/Scenes/OctahedronFlake.unity.meta

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Fractals Project/Assets/Scripts/OctahedronFlake.meta

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#pragma kernel CSMain
2+
3+
// textures
4+
RWTexture2D<float4> Texture;
5+
Texture2D<float4> Source;
6+
7+
// matrixes
8+
float4x4 CamToWorld;
9+
float4x4 CamInverseProjection;
10+
11+
// variables
12+
int Iterations;
13+
float Size;
14+
float3 Offset;
15+
float SizeDec;
16+
17+
// constants
18+
static const int steps = 100;
19+
static const float epsilon = 0.00001;
20+
/*static const float PI = 3.14159265f;
21+
22+
// rotate functions https://en.wikipedia.org/wiki/Rotation_matrix
23+
float DegToRad(float a) { return a * PI / 180; }
24+
float4x4 rotateX(float a) {
25+
a = DegToRad(a);
26+
float c = cos(a); float s = sin(a);
27+
return float4x4(float4(1, 0, 0, 0), float4(0, c, -s, 0), float4(0, s, c, 0), float4(0, 0, 0, 1));
28+
}
29+
float4x4 rotateY(float a) {
30+
a = DegToRad(a);
31+
float c = cos(a); float s = sin(a);
32+
return float4x4(float4(c, 0, s, 0), float4(0, 1, 0, 0), float4(-s, 0, c, 0), float4(0, 0, 0, 1));
33+
}
34+
float4x4 rotateZ(float a) {
35+
a = DegToRad(a);
36+
float c = cos(a); float s = sin(a);
37+
return float4x4(float4(c, -s, 0, 0), float4(s, c, 0, 0), float4(0, 0, 1, 0), float4(0, 0, 0, 1));
38+
}
39+
float3 transform(float3 p, float4x4 m) {
40+
return mul(m, float4(p, 1.0)).xyz;
41+
}
42+
43+
// box distance estimator from https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
44+
float DEBox(float3 p, float s) {
45+
float3 q = abs(p) - float3(s, s, s);
46+
return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0);
47+
}
48+
49+
// 2D box distance estimator from https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
50+
float DEBox2D(float2 p, float s) {
51+
float2 d = abs(p) - s;
52+
return length(max(d, 0.0)) + min(max(d.x, d.y), 0);
53+
}
54+
55+
// cross distance estimator from https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
56+
float DECross(float3 p, float s) {
57+
s = s / 3;
58+
float d = DEBox2D(p.xy, s);
59+
d = min(d, DEBox2D(p.xz, s));
60+
return min(d, DEBox2D(p.yz, s));
61+
}
62+
63+
float DETest(float3 p, float s) {
64+
return max(DEBox(p, s), -DECross(p, s*3));
65+
}*/
66+
67+
// octahedron distance estimator from https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
68+
float DEOctahedron(float3 p, float s) {
69+
p = abs(p);
70+
float m = p.x + p.y + p.z - s;
71+
float3 q;
72+
if (3.0 * p.x < m) q = p.xyz;
73+
else if (3.0 * p.y < m) q = p.yzx;
74+
else if (3.0 * p.z < m) q = p.zxy;
75+
else return m * 0.57735027;
76+
77+
float k = clamp(0.5 * (q.z - q.y + s), 0.0, s);
78+
return length(float3(q.x, q.y - s + k, q.z - k));
79+
}
80+
81+
// fold space from http://blog.hvidtfeldts.net/index.php/2011/08/distance-estimated-3d-fractals-iii-folding-space
82+
float3 Fold(float3 p, float3 n) {
83+
return p - 2.0 * min(0.0, dot(p, n)) * n;
84+
}
85+
86+
// distance to scene
87+
float DE(float3 p) {
88+
int i = 0;
89+
while (i < Iterations) {
90+
p *= SizeDec;
91+
p = Fold(p, normalize(float3(0, 1, 1)));
92+
p = Fold(p, normalize(float3(0, 1, -1)));
93+
p = Fold(p, normalize(float3(1, 1, 0)));
94+
p = Fold(p, normalize(float3(-1, 1, 0)));
95+
p -= Offset * Size;
96+
i++;
97+
}
98+
return DEOctahedron(p, Size) / pow(SizeDec, i);
99+
}
100+
101+
// ray
102+
struct Ray {
103+
float3 origin;
104+
float3 direction;
105+
};
106+
107+
// from http://blog.three-eyed-games.com/2018/05/03/gpu-ray-tracing-in-unity-part-1/
108+
Ray CreateRay(float3 origin, float3 direction) {
109+
Ray ray;
110+
ray.origin = origin;
111+
ray.direction = direction;
112+
return ray;
113+
}
114+
115+
// from http://blog.three-eyed-games.com/2018/05/03/gpu-ray-tracing-in-unity-part-1/
116+
Ray CreateCameraRay(float2 uv) {
117+
float3 origin = mul(CamToWorld, float4(0, 0, 0, 1)).xyz;
118+
float3 direction = mul(CamInverseProjection, float4(uv, 0, 1)).xyz;
119+
direction = mul(CamToWorld, float4(direction, 0)).xyz;
120+
direction = normalize(direction);
121+
return CreateRay(origin, direction);
122+
}
123+
124+
// cast a ray and return the result
125+
float March(Ray ray) {
126+
float d = 0;
127+
float3 eye = ray.origin;
128+
129+
int s = 0;
130+
while (s < steps) {
131+
d = DE(ray.origin); // calculate distance
132+
if (length(eye - ray.origin) > 200) s = steps; // to far away
133+
if (d < epsilon) break; // hit
134+
ray.origin += ray.direction * d; // march
135+
s++; // next iteration
136+
}
137+
138+
return 1 - float(s / float(steps));
139+
}
140+
141+
[numthreads(8,8,1)]
142+
void CSMain (uint3 id : SV_DispatchThreadID) {
143+
144+
// convert into range [-1, 1]
145+
float w, h; Texture.GetDimensions(w, h);
146+
float2 uv = id.xy / float2(w, h) * 2 - 1;
147+
148+
// create ray
149+
Ray ray = CreateCameraRay(uv);
150+
151+
float res = March(ray);
152+
//float4 ao = res * float4(0.1, 0.74, 0.61, 0);
153+
float4 ao = res * float4(0.6, 0.6, 0.6, 0);
154+
Texture[id.xy] = Source[id.xy] + ao;
155+
}

Fractals Project/Assets/Scripts/OctahedronFlake/OctahedronFlake.compute.meta

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using UnityEngine;
2+
3+
public class OctahedronFlake : App {
4+
5+
private int iterations = 0;
6+
private float size = 1;
7+
private Vector3 offset = new Vector3(0, 1, 0);
8+
private float sizeDec = 2;
9+
10+
private void Start() {
11+
cameraType = CameraType.Orbit;
12+
}
13+
14+
protected override void Render(RenderTexture s) {
15+
16+
// shader
17+
shader.SetTexture(0, "Texture", tex);
18+
shader.SetTexture(0, "Source", s);
19+
shader.SetMatrix("CamToWorld", cam.cameraToWorldMatrix);
20+
shader.SetMatrix("CamInverseProjection", cam.projectionMatrix.inverse);
21+
shader.SetInt("Iterations", iterations);
22+
shader.SetFloat("Size", size);
23+
shader.SetVector("Offset", offset);
24+
shader.SetFloat("SizeDec", sizeDec);
25+
26+
shader.Dispatch(0, Mathf.CeilToInt(w / 8), Mathf.CeilToInt(h / 8), 1);
27+
}
28+
29+
public float O_Iterations {
30+
get => iterations;
31+
set => iterations = Mathf.RoundToInt(value);
32+
}
33+
34+
public float O_Size {
35+
get => size;
36+
set => size = value;
37+
}
38+
39+
public Vector3 O_Offset {
40+
get => offset;
41+
set => offset = value;
42+
}
43+
44+
public float O_SizeDec {
45+
get => sizeDec;
46+
set => sizeDec = value;
47+
}
48+
}

Fractals Project/Assets/Scripts/OctahedronFlake/OctahedronFlake.cs.meta

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Fractals Project/Assets/Scripts/Utils/AppManager.cs

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ public void Start() {
5858
"Press R to open the options menu in which you can modify certain variables."));
5959
apps.Add(new App("Menger Sponge", true, 0, "03 MAR", 7,
6060
"Press R to open the options menu in which you can modify certain variables."));
61+
apps.Add(new App("Octahedron Flake", true, 0, "05 MAR", 8,
62+
"Press R to open the options menu in which you can modify certain variables."));
6163

6264
for (int i = 0; i < apps.Count; i++) {
6365
CreateElement(i);

Fractals Project/ProjectSettings/EditorBuildSettings.asset

+3
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,7 @@ EditorBuildSettings:
2929
- enabled: 1
3030
path: Assets/Scenes/MengerSponge.unity
3131
guid: c4a3be4271829e14fa075f54d785c185
32+
- enabled: 1
33+
path: Assets/Scenes/OctahedronFlake.unity
34+
guid: ab8cc282b4f3dfe4db2fb17f4e5ad301
3235
m_configObjects: {}

0 commit comments

Comments
 (0)