A Barbwire OSL shader for Blender Cycles

The simple concept used to create a chain link fence is easily extended to a somewhat more elaborate shader that creates barbwire. Finally we can keep the farm animals out of our rendered gardens (but as a goat owner myself I do not really think you should use barbwire to keep animals out except for humans :-)

I won't claim that the composite is very good, but the barbwire material itself holds up quite well even fairly close up.
In the example image I used the sIBL HDRI set 'Topanga Forest B' from Blochi as found on the sIBL archive and for the wooden posts some textures from CGTextures.
The code for the shader is pretty tangled, mainly because the spikey bit of the barbwire is pretty hard to code. The Xscale input is provided in order to make it possible to reduce the number of spikes per length of wire. By default we generate one spike per two turns. If you want to reduce this, you increase the number of turns, scale your input position in the x-direction and divide the Xscale input by the same amount (otherwise the turns on the spike would scale along and look way to thick).
#include "stdosl.h"

float arc(float r){ return sqrt(0.25-(r-0.5)*(r-0.5)); }

shader barbwire(
 float Width = 0.05,
 int Turns = 2,
 int Spiketurns = 2,
 float Xscale = 1,
 point Pos = P,
 output float Fac = 0,
 output float Displ = 0
){
 float x = mod(Pos[0],1);
 float y = mod(Pos[1],1);
 
 if ( x > 0.5 ) {
  x = 1 - x;
  y = 1 - y;
 }
 
 float w = Width/2;
 float t = M_2PI*x*Turns;
 
 float c = cos(t);
 float h = c*w+w;
 float l = c*w-w;
 
 y -= 0.5;
 // the barb part
 float BWidth = Width*Xscale;
 float Lw = BWidth*(Spiketurns-1);
 float Hw = BWidth*Spiketurns;
 if ( x > Lw && x < Hw && y > 1.5*Width && y<4 br="" idth="" part="" spikey="" the="">  if( y<3 br="" idth="" x-width="" y-3="">   Fac = 1;
   Displ = arc(mod(x,BWidth)/BWidth);
  }
 } else if ( x < Hw && abs(y) < 2*Width ){
  if ( abs(y) > 1.5*Width) { // the rounded top and bottom parts
   if ( abs(y) - 1.5*Width < w*arc(mod(x,BWidth)/BWidth) ){
    Fac = 1;
    Displ = arc(mod(x,BWidth)/BWidth);
   }
  } else { // the main part
   Fac = 1;
   Displ = arc(mod(x,BWidth)/BWidth);
  }
 }
 // the wire part 
 else {
  // alternating top/bottom checks to get correct crossings
  if ( (int)(t/M_PI) % 2 == 1 ){
  
   if ( y > l && y < h ) {
    Fac = 1;
    Displ = arc((y-l)/Width);
   } else if ( -y > l && -y < h ) {
    Fac = 1;
    Displ = arc((-y-l)/Width);
   }
   
  } else {
  
   if ( -y > l && -y < h ) {
    Fac = 1;
    Displ = arc((-y-l)/Width);
   } else if ( y > l && y < h ) {
    Fac = 1;
    Displ = arc((y-l)/Width);
   }
  }
 }
}

Example node setup

In the example image at the start of this article the lengths of barbwire were modelled by creating a single square, uv-unwrapping it and then adding an array modifier and a curve modifier to this square. This way we could edit the curve anyway we liked while the square repeats itself as many times as necessary (I set the length of the array modifier to the the length of the same curve that was used in the curve modifier). The noodle that applies the barbwire segment to the square looks like this (it is basically the same as the one for the chain link fence shader):

No comments:

Post a comment