Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Animating Shapes with Simple Equations

Animating Shapes with Simple Equations

yakatabune.swift での発表資料です。

shu223

March 21, 2024
Tweet

More Decks by shu223

Other Decks in Programming

Transcript

  1. Disclaimer • No Swift, only MSL (Metal Shader Language) •

    HOWEVER, the concept is universal — GLSL, HLSL, even Swift. • Hope you'll find the concept interesting!
  2. 3D

  3. 2D

  4. Define the shape for each frame? and display the sequence

    of images? animatedImage(with: images, duration: 2.0)
  5. Calculate the shape for each frame? like vector images <?xml

    version="1.0" standalone="no"?> <svg width="200" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg"> <rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/> <rect x="60" y="10" rx="10" ry="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/> <circle cx="25" cy="75" r="20" stroke="red" fill="transparent" stroke-width="5"/> <ellipse cx="75" cy="75" rx="20" ry="5" stroke="red" fill="transparent" stroke-width="5"/> <line x1="10" x2="50" y1="110" y2="150" stroke="orange" stroke-width="5"/> <polyline points="60 110 65 120 70 115 75 130 80 125 85 140 90 135 95 150 100 145" stroke="orange" fill="transparent" stroke-width="5"/> <polygon points="50 160 55 180 70 180 60 190 65 205 50 195 35 205 40 190 30 180 45 180" stroke="green" fill="transparent" stroke-width="5"/> <path d="M20,230 Q40,205 50,230 T90,230" fill="none" stroke="blue" stroke-width="5"/> </svg>
  6. Just use ONE function mix(x, y, a) • x: Shape

    1 • y: Shape 2 • a: 0.0 - 1.0
  7. !

  8. Signed Distance Function (SDF) Function Returning the Distance to a

    Shape • Returns 0 for points on the contour of the shape • Positive values for points outside the shape • Negative values for points inside the shape
  9. Implementing SDF of a Circle ‑ Metal Shader Language (MSL)

    float circleSDF(float2 p, float2 c, float r) { return length(p - c) - r; }
  10. Rendering Circle SDF with MSL float circleSDF(float2 p, float2 c,

    float r){ return length(p - c) - r; } float contour(float v) { return step(abs(v), 0.008); } [[ stitchable ]] half4 circleShader(float2 position, half4 color, float4 boundingRect) { float2 p = (position.xy * 2.0 - boundingRect.zw) / min(boundingRect.z, boundingRect.w); half3 rgb = contour(circleSDF(p, float2(0.0), 0.9)); return half4(rgb, 1); } Sample code: circleShader.metal
  11. Implementing SDF of a Sphere float circleSDF(float2 p, float2 c,

    float r){ return length(p - c) - r; } ‑ float sphereSDF(float3 p, float3 c, float r) { return length(p - c) - r; }
  12. Rendering Sphere SDF with MSL float sphereSDF(float3 p, float3 c,

    float r) { return length(p - c) - r; } Not explain today about 3D graphics... ! (Camera, Lighting, Ray casting / Ray marching) Sample code: mathShader_8_6.metal
  13. Recap on SDF • SDF is a function that returns

    the distance to a shape. • It enables the representing shapes using "distance". • Learned the SDF of a circle and sphere, and their implementations in MSL.
  14. Combining Shapes The union of SDFs can be calculated with

    min(d1, d2) // Circle SDF 1 float d1 = circleSDF(p, float2(0, 0.5), 0.9); // Circle SDF 2 float d2 = circleSDF(p, float2(0, -0.5), 0.5); // The union of SDFs float u = min(d1, d2); → Enable SDF shapes to be combined. Sample code: minCircles.metal
  15. Example of combining shapes using min: float d = 1.0;

    for (float i = 0.0; i < 6.0; i++) { float3 cent = float3(cos(PI * i / 3.0), sin(PI * i / 3.0), 0.0); d = min(d, sphereSDF(p, cent, 0.2)); } → Represents six spheres with a single SDF.
  16. Morphing mix(d1, d2, a) enables Morphing between Shapes. • d1:

    SDF representing one sphere • d2: SDF representing six spheres • a: Cycles from 0.0 to 1.0 over time float a = abs(mod(time, 2.0) - 1.0); Sample code: mathShader_9_2.metal
  17. Smooth Union smin(d1, d2, k) enables a "smooth" union between

    shapes. // A min function that interpolates the junction for a smooth SDF union float smin(float a, float b, float k) { float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0); return mix(b, a, h) - k * h * (1.0 - h); } (The derivation process of this formula is on p129–130) • d1: A smaller sphere • d2: A larger sphere • k: From left, 0.1, 0.3, 0.5 Sample code: mathShader_9_3.metal
  18. Summary • Using SDF allows for representing shapes with "distance."

    • → Enable Shape Animations with Simple Equations and Functions. Sample code on GitHub: shu223/Metal-SDF-Examples