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

Animating Shapes with Simple Equations

shu223
March 21, 2024

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