G'MIC Tutorial Fragments

tvfritz.gmic

===

#@cli warpseq : _complexity(1-7),_warpmag(>0),\
# _colorshift(>0),0<=_eccentricity<1,-180<=_eangle<=180,\
# _autoanim_w(>0),_autoanim_h(>0)_autoanim_frames(>0)
#@cli : Distort selected (or create a demo) animation
#@cli : which reflects the warping of a time-varying
#@cli : displacement field.
#@cli : $ warpseq 1,200,1,0,0,600,600,1024 \
#  split z o warpswirl.mp4,30,h264
warpseq: -check ${1=3}>0"      && "\
                ${1}<=7"       && "\
                ${2=1}>0"      && "\
                ${3=2}>0"      && "\
                ${4=0}>=0"     && "\
                ${4}<1"        && "\
                ${5=0}>=-180"  && "\
                ${5}<=180"     && "\
                ${6=512}>0"    && "\
                ${7=$4}>0"     && "\
                ${8=$4}>0
   sz,warpmag,cshift,ecent,ang=${1-5}
   pw={2*$sz+1}
   -local
      nm={0,n}
      -name. anim
      aw,ah,ad:=[w#$anim,h#$anim,d#$anim]
      missing=0
   -onfail
      nm="AutoAnimation"
      aw,ah,ad=${6-8}
      missing=1
   -done

   # Make spectral noiseball around specspace origin
   $pw,$pw,$pw,2,u(-1,1)
   -name. noiseball
   -resize[noiseball] {$aw},{$ah},{$ad},{s},0

   # Make spectral noiseball multiplier ellipse
   -input {w#$noiseball},{h#$noiseball},{d#$noiseball},1
   -name. gaussball
   _mkclip[gaussball] $pw,$ecent,$ang 
   -shift[noiseball] {-$pw/2},{-$pw/2},{-$pw/2},0,2,0
   -shift[gaussball] {-w/2},{-h/2},{-d/2},0,2,0
   -set[gaussball] 0,0,0,0,0
   -normalize[gaussball] 0,1
   -mul[noiseball,gaussball]

   # Take spectral noise to spatial space
   -split[noiseball] c
   -ifft[-2,-1]
   -append[-2,-1] c
   -orientation[noiseball] # Unscaled warping image...

   # Missing anim? Provide default imagery
   if $missing
      -local[noiseball]
         +structuretensors. 1
         -eigen.
         -abs..
         -add.. 1.0e-06
         -log..
         -abs..
         -split. c,2
         -remove.
         -fill.. rot(I(#-1,x,y,z),atan2(i(#$noiseball,x,y,z,1),i(#$noiseball,x,y,z,0)))*I
         -remove.
         -normalize. 0,255
         -name. anim
      -done
   fi
   #Make a separate, per-channel micro-warper
   -mul[noiseball] {$warpmag}
   -input[0] 3,3,1,2,u(-1,1)
   -name[0] microwarper
   -blur[microwarper] 1,1
   -resize[microwarper] {w#$anim},{h#$anim},1,2,5
   -normalize[microwarper] -$cshift,$cshift

   # Micro-warper is responsible for per-channel
   # shifting. Methinks this can be simplified,
   # perturbing noiseball instead and eliminating
   # this per-channel song-and-dance.
   
   ccnt={s#$anim-1}
   -split[anim] c
   foreach[^noiseball,microwarper] {
      nm2={0,n}
      -name. anim
      -pass[noiseball] 1
      -pass[microwarper] 0
      -warp[anim] [noiseball],1,2,3
      -if $><$ccnt
         -repeat {d#$anim}
            -shared[noiseball] {$>},{$>},0
            -warp[-1] [microwarper],1,2,3
            -remove[-1]
            -shared[noiseball] {$>},{$>},1
            -warp[-1] [microwarper],1,2,3
            -remove[-1]
         -done
      -fi
      -keep[anim]
      -name[anim] $nm2
   }
   -remove[microwarper,noiseball]
   -append c
   -crop[anim] 0,0,1,{w-1},{h-1},{d-2}
   -name. $nm

_mkclip:
   nm={n}
   -name. blurball
   span:=_round($1,1,0)
   ecent,ang=${2-3}
   minax:=sqrt(1-$ecent^2)
   -set[blurball] 1,{(w/2)-1},{(h/2)-1},{(d/2)-1},0
   -blur[blurball] $span,1
   -normalize[blurball] 0,1
   -input {w#0},{h#0},1,1
   -gaussian. {$span*[1,$minax]},-$ang
   -name. gaussian
   -repeat d#$blurball
      -shared[blurball] {$>},{$>},0         
      -mul. [gaussian]
      -remove.                           
   -done
   -remove[gaussian]
   -name[blurball] $nm

===

Last spring, @SlavaCat118 observed in Documentation and examples for writing scripts that there seemed to be no cohesive tutorial (or set of tutorials) to bring one up the curve from writing simple to complex scripts — instead there are tutorial “lamp posts”, here and there, illuminating a landscape that is otherwise pitch black.

The gist of the discussion ran along the lines that newcomers do not have G’MIC vocabularies to connect visual goals with some pipeline of G’MIC commands. There needs to be an orderly presentation that starts with Chopsticks and ends with Ragtime, perhaps. Running with this musical analogy, I have been thinking in terms of finger exercises that, as a series, develops a script from a Chopsticks form to a Ragtime form.

tvfritz.gmic may be way too much even for a Ragtime end-state, but I found the resulting animations pretty. Perhaps a Ragtime-to-Chopsticks reduction will be in the mix of finger exercise for upcoming tutorials, these to address SlavaCat’s concerns — perhaps not. Likely not. Even the Ragtime end-state probably needs to be simpler than TV-On-The-Fritz. But it was a fun Sunday-Morning-Before_Breakfast exercise. Enjoy spelunking the code.

3 Likes