2D Graphics

NPR Final Touches

All the bells and whistles – Ambient Occlusion, Depth fading, Image Adjustment, etc. Highlights can now be dialated or eroded. Support for separate outlines of normals. Presets and clean menus. I think this shader is about done.


NPR Shading Continued

I’m continuing to refine the NonPhotoRealistic (NPR) sketch post-process in Unreal. This is using completely different methods now, I’ve changed the method of convolution edge detection for outlines, and am using world-aligned sketch texturing in the shadow and highlight regions.

The background is also given a custom color and texture. The light source is defined through any number of unreal lights.

There is now support for sketchy highlights and varying line colors, and much better response to light. Ideally the post process would support variation in outline width, although I don’t have a good method for that yet.

There are options to use procedural line, dot and crosshatching for a more comic/newsprint look.

The results are very solid and smooth in motion, with no temporal swimming or distractions. I see this shader being ideal for architectural stylization and general NPR usage. 

To get a more chalk-like effect with ink outlines I take this post process and combine it with an NPR painterly process which applies brushstrokes on the image in world space. Here’s the result:

Niagara Game Effects

I did a little job for a studio in Prague recently which consisted of a series of “spell” effects for a RPG. I can’t show any of those effects of course but along the way I made a number of other interesting little Niagara effects, here are a few:


Dot Product and Edges in Vex

Getting the dot product of two vectors is infinitely useful, and easy in Vex. In this example I get a vector pointing from scattered particles to the camera and then get their dot product with the surface normal at that point. This gives you a very good idea of whether the surface is facing or perpendicular to the camera at any given point.

In this case, I simply cull any point which isn’t close to a value of zero, indicating the surface is perpendicular to the camera. If instead I culled particles that were less than zero I would be removing all back-facing (occluded) particles, which is perhaps more useful but less visually interesting. Since I am left with only particles near the edges of the geometry it’s easy to connect them with lines and get an “edge detection” kind of look.

Here’s the Vex wrangle I used. Note an earlier polyframe node gave me point normals on the scattered points to work with.

float threshold = chf("Threshold");
//User input threshold

vector camPos = point(1, "P", 0); 
//The position of the imported camera

vector toCam = normalize(camPos - @P); 
//A vector from each point to the camera)

//@N = toCam; 
//Use to visualize toCam as normals

f@angle = dot(toCam, @N);
//The dot product of the normal and toCam vectors. 

if (@angle > threshold || @angle < -1*threshold){

I’ve used this edge culling in production a few times, to create anime style speedlines and particle effects like rain strikes and halos. Culling particles behind geometry is of course also handy, though raycast solutions are much cleaner for that kind of thing. Next, we’ll use a simple dot product calculation to cull points and create a gradient effect.



My harddrive barfed up these scraps. What to do with all this? Put ’em on the internet of course.