3. Funkcja odległości (Distance estimators)
Funkcja odległości jest to matematyczny opis obiektu dla danej pozycji (f) gdzie wynikiem tej funkcji jest dystans który pozwala stwierdzić czy punkt jest na powierzchni, przed obiektem lub wewnątrz obiektu:
- f(p)>0 – punkt (p) jest na zewnątrz obiektu
- f(p)=0 – punkt (p) jest na powierzchni obiektu
- f(p)<0 – punkt (p) jest wewnątrz obiektu
4. Funkcja odległości płaszczyzny (Distance Fields)
Jest to połączenie generowania sceny na podstawie jednego lub więcej obiektów, gdzie wykorzystuje się operatory min(), max(), mod(), rotateX(), itd. do wykonywania operacji łączenia obiektów, odejmowania od siebie obiektów, zwielokrotnienia, itd.
5. Przykładowe funkcje obiektów
Poniżej przedstawiam funkcje używane do otrzymywania różnych obiektów:
- Box:
vec3 d = abs(p-pos) – size; float distance=min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
- Sphere:
float distance=length(p - pos) – radius;
- Plane:
float distance=dot(p - pos, normal);
gdzie normal – jest wektorem normalnym danej płaszczyzny
- RoundBox:
float distance=length(max(abs(p – pos) - size,0.0)) – radius;
- Torus:
p=p – pos; vec2 q = vec2(length(p.xy) – t.x, p.z); float distance=length(q)-t.y;
- HexPrism:
vec3 q = abs(p – pos); float distance=max(q.z - h.y, max(q.x + q.y * 0.57735, q.y * 1.1547) – h.x);
- Capsule:
vec3 pa = p – a; vec3 ba = b – a; float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); float distance=length( pa - ba*h ) - r;
- TriPrism:
vec3 q = abs(p – pos); float distance=max(q.z - h.y, max(q.x * 0.866025 + p.y * 0.5, -p.y) - h.x * 0.5);
6. Funkcje modyfikujące
Funkcje modyfikujące scene/obiekty możemy podzielić na 3 główne grupy:
- Łączenia obiektów
- Union
vec2 join(vec2 a, vec2 b) { if (a.x > b.x){ return b; } return a; } vec2 join(vec2 a, vec2 b, vec2 c) { if (a.x > b.x){ if (b.x > c.x){ return c; } return b; } if (a.x > c.x){ return c; } return a; }
- Substraction
vec2 diff(vec2 a, vec2 b) { b.x=-b.x; if (b.x > a.x){ return b; } return a; } vec2 diff(vec2 a, vec2 b, vec2 c) { b.x=-b.x; if (b.x > a.x){ c.x=-c.x; if (c.x > c.x){ return c; } return b; } if (b.x > c.x){ a.x=-a.x; if (a.x > c.x){ return a; } return c; } c.x=-c.x; if (c.x > a.x){ return c; } return a; }
- Intersection
vec2 intersect(vec2 a, vec2 b) { if (a.x > b.x){ return a; } return b; } vec2 intersect(vec2 a, vec2 b, vec2 c) { if (a.x > b.x){ if (c.x > a.x){ return c; } return a; } if (c.x > b.x){ return c; } return b; }
- Smoth Union
vec2 smothJoin(vec2 a, vec2 b, float k ) { float h=clamp(0.5 + 0.5 * (b.x - a.x) / k, 0.0, 1.0); float distance=mix(b.x, a.x, h) - k * h * (1.0 - h); if (distance > b.x){ b.x=distance; return b; } a.x=distance; return a; }
- Union
- Operacji na pozycji
- Repetition
vec3 repetition(vec3 pos, vec3 c) { return mod(pos, c) - 0.5 * c; }
- Rotation
vec3 rotateX(vec3 p, float angle) { float c=cos(angle); float s=sin(angle); return vec3(p.x, c * p.y - s * p.z, s * p.y + c * p.z); } vec3 rotateY(vec3 p, float angle) { float c=cos(angle); float s=sin(angle); return vec3(c * p.x - s * p.z, p.y, s * p.x + c * p.z); } vec3 rotateZ(vec3 p, float angle) { float c=cos(angle); float s=sin(angle); return vec3(c * p.x - s * p.y, s * p.x + c * p.y, p.z); }
- Scale
vec3 scale(vec3 p, float s) { return primitive(p/s)*s; }
- Repetition
- Deformacji obiektów
- Displacement
vec2 sinDisplace(vec3 p, vec2 primitive, float steps, float scale) { primitive.x+=(sin(steps * p.x) * sin(steps * p.y) * sin(steps * p.z)) * scale; return primitive; } vec2 sinDisplace(vec3 p, vec2 primitive, float steps, float scale, float tim) { primitive.x+=(sin(steps * p.x + tim) * sin(steps * p.y + tim) * sin(steps * p.z + tim)) * scale; return primitive; }
- Twist
vec3 twist(vec3 p, float tc, float ts) { float c=-1. * cos(tc * p.y + ts); float s=1. * sin(tc * p.y + ts); mat2 m=mat2(c, -s, s, c); return vec3(m * p.xz, p.y); }
- Cheap bend
vec3 bend(vec3 p, float tc, float ts) { float c=-1. * cos(tc * p.y + ts); float s=1. * sin(tc * p.y + ts); mat2 m=mat2(c, -s, s, c); return vec3(m * p.xy, p.z); }
- Displacement
Możliwość komentowania jest wyłączona.