Skip to content

WebGPU-Art/lagopus

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lagopus in Calcit

tiny tool for drawing 3D shapes with WebGPU, wraps on Lagopus.ts.

Dandelions, made previously with Triadica

APIs

:lagopus.alias :refer $ object

object $ {}
  :shader demo-wgsl
  :topology :triangle-list
  :attrs-list $ []
    :: :float32x3 :position
    :: :float32x3 :color
  :data $ []
    :: :vertex (v3 0 0 0) (v3 1 0 0)
    :: :vertex (v3 100 0 0) (v3 0 1 0)
    :: :vertex (v3 0 100 0) (v3 0 0 1)
  • :shader custom shader file string
  • :topology topology symbol, :triangle-list or :line-strip
  • :attrs-list list of attributes, first value providing type, second value is a name(history reason...)
  • :data list of data, each data is a map with keys matching :attrs-list, nested list is supported
  • optional :indices list of indices, each index is a number. nested list is supported
  • :get-params, to add custom params with uniform buffer, for example fn () (js-array 1 1 1 1), notice the values should obey memory alignments

Alternatively, there's also object-writer which provides a writer API, which replaces :data:

  :writer $ fn (write!)
    write! $ []
      :: :vertex (v3 1 1 1)

Shader

Shader file expects 3 parts:

  • params(could be empty)
  • vertex_main, here you call transform_perspective to display point in 3d
  • fragment_main
// to include `lagopus-perpective.wgsl` , provide function `transform_perspective`
#import lagopus::perspective

struct Params {
  _t: f32,
}

@group(0) @binding(0) var<uniform> params: Params;

// structure passing from Vertex to Fragment
struct VertexOut {
  @builtin(position) position: vec4f,
};

@vertex
fn vertex_main(
  @location(0) position: vec3f,
  // data added from attributes put here
) -> VertexOut {
  var output: VertexOut;
  let p = transform_perspective(position.xyz).point_position;
  let scale: f32 = 0.002;

  output.position = vec4(p.xyz * scale, 1.0);
  return output;
}

@fragment
fn fragment_main(vtx_out: VertexOut) -> @location(0) vec4f {
  return vec4f(0.0, 0.0, 0.0, 1.0);
}
Builtin functions

#import lagopus::perspective

  • fn transform_perspective(p: vec3f) -> PointResult

#import lagopus::colors

  • fn hsl2rgb(hsl: vec3f) -> vec3f
  • fn hsl(h: f32, s: f32, l: f32) -> vec3f

#import lagopus::rand

  • fn rand(n: f32) -> f32
  • fn rand_balanced(n: f32) -> f32
  • fn noise(p: f32) -> f32
  • fn rand2(n: vec2<f32>) -> f32
  • fn noise2(n: vec2<f32>) -> f32

#import lagopus::simplex

  • fn simplexNoise2(v: vec2<f32>) -> f32

#import lagopus::hsluv

  • fn hsluvToRgb(tuple: vec3f) -> vec3f based on 360 and 100

Components

Curves
lagopus.comp.curves :refer $ comp-curves comp-polylines break-mark

comp-curves $ {} (; :topology :line-strip)
  :curves $ []
    -> (range 400)
      map $ fn (idx)
        let
            angle $ * 0.1 idx
            r 40
          {}
            :position $ []
              * r $ cos angle
              * 0.6 idx
              * r $ sin angle
            :width 2

Another way of defining lines is comp-polylines that seperate segments with :: :breaks. It does not require "flatterned" list so is supposed to be a little performant.

note that : vertex p is a short form for :: :vertex p since Calcit 0.7.2 .

comp-polylines $ {} (; :topology :line-strip)
  :writer $ fn $ (write!)
    write! $ []
      : vertex ([] 0 0 0) width
      : vertex ([] 100 100 0) width
      , break-mark
      : vertex ([] 0 0 10) width
      : vertex ([] 200 0 10) width
      : vertex ([] 200 20 0) width
      : vertex ([] 100 40 0) width
      : vertex ([] 100 20 200) width
      , break-mark

also if you want an extra mark for controlling colors:

comp-polylines-marked $ {} (; :topology :line-strip)
  :writer $ fn (write!)
    write! $ []
      : vertex ([] 0 0 0) width 0
      : vertex ([] 100 100 0) width 0
      , break-mark
      : vertex ([] 0 0 10) width 2
      : vertex ([] 200 0 10) width 2
      : vertex ([] 200 20 0) width 2
      : vertex ([] 100 40 0) width 2
      : vertex ([] 100 20 200) width 2
      , break-mark
Spots
lagopus.comp.spots :refer $ comp-spots comp-bubbles

comp-spots $ {} (; :topology :line-strip)
  :radius 6
  :vertex-count 8
  :shift 12
  :points $ -> (range 80)
    map $ fn (idx)
      let
          r $ * idx 4
        [] r
          * r $ cos (* 0.1129 idx)
          * r $ sin (* 0.123 idx)

comp-bubbles $ {}
  :bubbles $ -> (range 600)
    map $ fn (idx)
      [] (rand-shift 0 area) (rand-shift 0 area) (rand-shift 0 area) (+ 6 $ rand 120)
Axis
laopus.comp.curves :refer $ comp-axis

comp-axis $ {} (:n 20)
  :unit 20
Cube
lagopus.comp.cube :refer $ comp-cube

comp-cube $ {}
  :position $ [] 40 0 0
  :radius 40
Sphere
lagopus.comp.sphere :refer $ comp-sphere

comp-sphere $ {} (; :topology :line-strip)
  :iteration 4
  :radius 160
Plate
lagopus.comp.plate :refer $ comp-plate

comp-plate $ {} (; :topology :line-strip)
  :iteration 20
  :radius 160
  :color $ [] 0.04 0.8 0.6
  :transformer $ fn (i)
    v+ i $ [] 0 0 -10
  ; :x-direction $ [] 1 0 0
  ; :y-direction $ [] 0 1 0
  :chromatism 0.14
Controls
lagopus.comp.button :refer $ comp-button comp-slider comp-drag-point

comp-button
  {}
    :position $ [] 240 260 0
    :color $ [] 0.2 0.9 0.6 1
    :size 20
  fn (e d!)
    d! :tab :sphere

comp-slider
  {} $ :position ([] 0 0 0)
  fn (change on-slide)
    js/console.log "\"Slide" change

comp-drag-point
  {}
    :position $ :pos state
    :color $ [] 0.6 0.6 1.0 1.0
  fn (move d!)
    d! cursor $ assoc state :pos move
Stitch
lagopus.comp.stitch :refer $ comp-stitch

comp-stitch $ {}
  :chars $ [] 0xf2dfea34 0xc3c4a59d 0x88737645
  :position $ [] 0 0 0

Cursor

lagopus.cursor :refer $ update-states >>

Math functions in lagopus.math

  • fibo-grid-range total create a list of points constructing Fibonacci Sphere
  • rotate-3d origin axis-0 angle p rotate point p around axis-0
  • rotate-3d origin axis-0 angle create a function to rotate point p

Resources

Shader functions from https://gist.github.com/munrocket/236ed5ba7e409b8bdf1ff6eca5dcdc39

License

MIT