A fingerprint OSL shader for Blender Cycles

Scanning your own fingerprints for use in your renderings might not be such a good idea with new methods of identity theft being invented everyday so here I present a shader that generates random fingerprint patterns. Finally you can identify the suspect that emptied your whiskey glass!

In the example image we duplicated and separated a small square from the glass mesh and scaled it a minuscule bit outward, effectively turning it into a decal or sticker. This object was uv-mapped and the fingerprint material applied to it. (The decal is still a bit darker than the glass because I didn't use enough transparent bounces. I might update this image in the future.)

An elliptic mask shader

Besides the regular nodes this Cycles shader consist of two separate OSL shaders. The first is a generic one to generate elliptic masks, not unlike the one available in the compositor:
#include "stdosl.h"

shader ellipse(
 point Pos = P,
 point Center = 0.5,
 float Radius = 0.5,
 float E = 1,
 float Rotation = 0,
 float Blur = 0,
 output float Fac = 0
 point p = rotate(Pos,radians(Rotation),Center,Center+vector(0,0,1));
 vector d = p - Center;
 d[0] *= E;
 float r2 = d[0]*d[0]+d[1]*d[1];
 if (r2 <= Radius*Radius) {
  Fac = 1-Blur*sqrt(r2/(Radius*Radius));

Generating a flow field

The second one is a flow shader. It works by generating a number of points that are considered the centers of vortices (rotating vector fields) with different strengths. At the point being shaded all the vectors are summed and the magnitude of the resulting vector is calculated. This output is used in the example noodle at the end of this article as input to a sinus node to create the banding pattern. Of course this pattern only superficially resembles human fingerprints (for example, it will not produce whorls, just concentric circles) but it does resemble it and is in fact related to the way fingerprint patterns are produced in the developing embryo. Anyway, as always, shaders are not about science but about art. For more information check Wikipedia, this pdf or this research. The animation on that last site actually inspired me although I have no idea my simplistic implementation in any way resembles their approach apart from using a vector field to act as a base for generating the ridge patterns.
Apart from fingerprints I think it should be possible to generate all sorts of patterns that in real life might be produced by processes that resemble cellular automata or reaction-diffusion systems that are far too expensive to simulate insode a shader. Zebra stripes might be a prime example.
I think my approach is at generating these patterns for graphical purposes is quite new, but if you have pointers to similar solutions you saw elsewhere, please mention this is a comment.
#include "stdosl.h"
#include "node_texture.h"

shader flow(
 point Pos = P,
 float Scale = 1,
 int Np = 5,
 int Seed = 42,
 output float Fac = 0
 float da;
 point pa;
 float d;
 vector up   = vector(0,0,1);
 vector tdir = 0;
 int pi;
 for(pi=0; pi< Np; pi++){
  pa = Scale * point(
  da = pa[2];
  vector v = pa - Pos;
  float d = length(v);
  v = normalize(v);
  tdir += cross(v,up)*da*d;
 Fac = sqrt(dot(tdir,tdir));

If we use some lighting that shows of the details you can see that it resembles a fingerprint but is actually nowhere near a real one.

Example node setup

The are quite a few nodes in the example shown below, so it is good the understand the general flow. The flow shader is used drive a sinus node via a multiplication node that lets us control the spacing of the bands. The output of this sinus is only propagated if it is positive (that is what the greater than and multiply nodes do, akin to an electrical 'rectifier' circuit) [The red box]]. This is mutiplied (i.e. masked) by the output of the ellipse shader and again by some noise [both in the green box] before being fed into mixture of closures (shaders) that will turn complete transparent when black and whitish-with-a-slight-gloss if not black [the yellow highlight]. The sinusoidal ridges also drive the displacement, adding a little extra realism [the blue highlight].

No comments:

Post a Comment