Examples

Procedural Hatching

I’ve been using Shadershop as a tool to explore useful procedural functions. In this case I needed procedural hatching. A square wave was quick to define:
  In this case, all that we need to do is call a couple of floor functions. Frequency, phase and amplitude are easy enough to adjust after the fact just as you would any other periodic function. (A simpler method to create a square wave is to use a rounding function, but I wanted to see where Shadershop’s approach took me.)
  I then extrapolated this function into a vector2, skewed it with a 2×2 matrix, and voila. Shadershop makes figuring this kind of thing out much easier by using a visual workflow and graphing your function as you go. Very handy!

  You can do something similar with a 1d random function fract(sin(x)*999) to achieve a periodic 2d noise pattern.

  A simple crosshatch shader in unity can be made by adding two of the above square wave functions. In this case I used a min and max function to change the “pulse length” of the square wave. You can get a similar look by using the more common approach of establishing a sine wave which you then clip/threshold. I’m not sure which method would be faster… Here’s the basic shader:
 

Shader "Unlit/Test"
{
    Properties
    {
      _Density ("Density", Range(1,400)) = 150
      _Rotation ("Rotation", Range(0,360)) = 45.0
      _Width ("Width", Range(0,1)) = 0.4
    }
    SubShader
    {
        Pass
        {
          CGPROGRAM
          #pragma vertex vert
          #pragma fragment frag
          #include "UnityCG.cginc"
          struct v2f
          {
              float2 uv : TEXCOORD0;
              float4 vertex : SV_POSITION;
          };
          float _Density;
          float _Rotation;
          float _Width;
          v2f vert (float4 pos : POSITION, float2 uv : TEXCOORD0)
          {
              v2f o;
              o.vertex = UnityObjectToClipPos(pos);
              o.uv = uv * _Density;
              return o;
          }
            
          fixed4 frag (v2f i) : SV_Target
          {
            float sn, cs;
            sincos(radians(_Rotation), sn, cs);
            float2x2 mt = float2x2(cs, -sn, sn, cs); 
            float2 c = i.uv;
            c.xy = mul ( c.xy, mt );
            float hatch = max(abs(floor((c.x/2 - 0.5)/-1) 
                          + floor(c.x/2)+1),
                          abs(floor(((c.x-_Width)/2 - 0.5)/-1) 
                          + floor((c.x-_Width)/2)+1))
                          - min(abs(floor((c.y/2 - 0.5)/-1) 
                          + floor(c.y/2)+1),
                          abs(floor(((c.y-_Width)/2 - 0.5)/-1) 
                          + floor((c.y-_Width)/2)+1));
            return hatch;
          }
          ENDCG
      }
  }
}

  The problem with this kind of approach is that it’s overly complex. All of that min/max/floor stuff can be replaced with a much shorter step function. Same look, much more direct.
 

{
  float sn, cs;
  sincos(radians(_Rotation), sn, cs);
  float2x2 mt = float2x2(cs, -sn, sn, cs); 
  float2 c = i.uv;
  c.xy = mul ( c.xy, mt );
  float hatch = abs(step(1-_Width,sin(c.x)))
              + abs(step(1-_Width,sin(c.y)));
  return hatch;
}

  I added some lighting to the shader and here’s the result. Procedural and written entirely in notepad!

Misc Shots

I haven’t edited an “official” demo reel in a very long time. People know who I am, and hire me for projects based on peer testimonial and having seen past work directly. A reel just hasn’t been needed, since I’m fortunate enough to be a freelancer who gets approached regularly. So when I started teaching students who knew nothing about me I had the challenge of presenting myself to an entirely new audience who were eager to see some work I’ve done in films. I really haven’t had time to edit much, so instead I spent an evening grabbing various shots from films and the like. Stuff I’ve either worked on directly, supervised, or had some hand in.

I have only grabbed a portion of the films I’ve worked on, plus some TV and game stuff, pretty much in the order they were stacked on my desk. The choices are fairly miscellaneous – at the moment I just don’t have time to go through film after film and say “oh yeah, I did that,” then tighten it all down into an edit with music and polish. I know, this breaks all the rules where I’m supposed to present only the very very best, nothing less. But the policy that seems to work best for me is to just be open, good or bad just get it out there and get back to making the next thing. I will never be a charismatic showman or clever self-promoter. I’m a creative geek and frankly I like showing failures, too. It’s part of the process, and that’s what really motivates me.

So all of that said, here’s about 6 minutes of footage and, well, stuff. I basically play it in the background when I introduce myself to students, so it is what it is. Enjoy!

Popcorn FX fractalFlame

Popcorn FX is capable of some pretty sophisticated particle effects. With a little effort one can get past the “usual” turbularized effects and push the limits a bit. Here’s a “fractal flame” look made by spawning, coloring and moving particles with layered noise fields. Given the number of particles used to give the soft look it’s not really something you could include in a game or application but was a fun way to explore some techniques which could be used for more efficient effects. You can get a similar look with much better performance using a vertex shader to distort a mesh and a fragment shader with an additive fresnel transparency, but again the point of the exercise was more an exploration of PopcornFX. That said, this does run in realtime with about 24 fps in the editor, pretty nice.

Vex setpointgroup snippet

Since I was making circuit looking stuff I tried a different approach above, and in doing so had to explore setting random points into a group via Vex. Enter the setpointgroup function, very handy indeed. This snippet creates a group of random points based on a threshold, and is useful enough to take note of:

if ( rand(@ptnum+chi("seed")) < ch('threshold') ) 
{
setpointgroup(0, chs("Group"), @ptnum, 1, "set");
}

Circuit POP

This was fun and quick to do by restricting the direction particles could move to 45 degree increments and keeping them flat on the ground plane. Eventually I’ll be posting .hip files with these posts, once I get this blog’s back end a bit more up to date.

Circuit Pops

Example – Display Spotlight Data

This scene shows how ICE can be used to display custom information about aspects of a scene. In this case, the cone of a spotlight is displayed, with an option to display a projection of the spotlight on the surface of geometry. A second example shows how the same setup can be used for a near and far attenuation display.

One great thing about ICE is how easy it is to re-use and re-task your “code.” In this example, it is simple to save the null containing the ICE operator as a model. Any time you need this display, import the model and give it your spotlight’s name, and you’re done. Or better, write a script which does this for you so all you have to do is pick the light. – AM

Here’s the file (softimage 2013, 276kb): ICEspotlightDisplay

Update

Petr Zloty sent me a useful tip… when you place the ICE operator on an empty pointcloud rather than a null, the results display properly in any viewport. This is an important realization which is really good to know. In fact, the problem with ICE display attributes on nulls only appearing with wireframes is an annoyance which I’ve bumped against more than once. Thanks Petr!

Thanks Petr for the tip and the screenshot!
Thanks Petr for the tip and the screenshot!

Example – Ridge Turbulence and Whirlpool Fun

Rob Chapman posted a cool whirlpool deformer to the “Resource Dump” on SI-Community here. Since I had been doing a lot with logarithmic spirals recently I decided to make one from scratch and compare the two. Here’s the result.

Instead of using Rob’s wave deformer, since it’s fun to share it out there’s a “ridged turbulence” compound in there. Here’s what it looks like when used as a deformer:

 And here’s the file (softimage 2013 ~160kb): alt_whirlpool

Example – Taper Deform

Unlike most of the examples, I built this specifically to show how a deformer can be constructed with simple visual guides. So the good news is that it’s all nicely commented. This example shows the structure of a deformation, some tricks for making viewport guides, and the taper function itself (originally published by Alan Barr, it’s quite simple).

The down side is that I didn’t want to get into matrix transforms for the example, so this implementation is only on the object’s local Y axis. This limits it’s production value (not that there’s a great need for another taper deformer.) It’s an example, not a tool – adding in the transforms to make the taper axis arbitrary isn’t too difficult, but as I was making this I realized it was going to make the entire thing unreadable and that I was out of time – I have paying work I need to get to. ^_^ So here it is, as-is. Cheers – AM

File (softimage 2013 ~270kb): Example_TaperDeform

Update

Had a little time and I hated leaving this in a state that wasn’t that useful, so I added in the additional kinds of control I usually have in production compounds (in this case, mainly the optional ability to deform on an arbitrary axis as supplied by a control object like a null, and minor cosmetics.)

A taper deformer isn’t high-tech feeling and exciting, but it’s useful in everyday practice, and more to the point this is a structure that can be used for many useful kinds of deformations. For instance, once I had the taper structure it was pretty simple to replace the internal “taper” formula with one to do a twist:

I’ll share out the twist version eventually, in the meantime here’s the full taper compound (if you look inside you’ll see what I was getting at by the arbitrary axis adding a lot of seeming complexity, but it’s really not complex, ICE just tends to look that way when there are a lot of different things all connected.)

File (softimage 2013, 379kb): example_TaperDeform2