Archive for July, 2009

Stairwell

Sunday, July 19th, 2009

I modeled the stairwell based on a photo I found on the net. All the textures were painted in either Gimp or Photoshop using various concrete and wood reference photos.

Here are the various passes I rendered out

This is the final comp done using Houdini's compositor. Click the image to view high resolution.

Compiling Shaders with VIM

Friday, July 17th, 2009

1 function! MakeSlo()
2 set makeprg=shader\ -o\ /home/alan/rsl/rel/%:t:r.slo\ %\
3 make
4 set makeprg=make
5 endfunction
6

You'll also need to add this to your .vimrc to bind the above function to a hotkey

1 map eig :call MakeSlo()
2 map ,e eig<C-M>

Now compiling is as simple as pressing ,e (comma + e)

If the fonts used in the code above don't appear legibly then set your browser's monospace font. In Firefox it's under Tools > options > content > Fonts & Colors > advanced. I use the same font I program with, which I highly recommend if you also dislike anti-aliased fonts. Dina Programming Font

RSL – Glass

Thursday, July 16th, 2009

This shader is based off the VEX Glass shader found on od[force].net's shading forums. Credit goes to Mario Marengo for the original VEX shader that I based this shader from. He was nice enough to provide multiple resources and quite a bit of information on creating a glass shader from scratch. You can check out that thread here

This shader is pretty simple, but handles about 90% of my glass needs so I stopped adding features to it. It also takes a very long time to render complicated objects so be forewarned. You should also take particular care that your normals are facing the appropriate direction as this shader depends heavily on them. Specular Depth is also of importance. In Houdini the default is set to 2 bounces, so you may need to increase this depending on how complicated the objects you're trying to refract are. This is one knob that will definitely increase your render times so take care with it. It may even be advisable to write a shader that stores ray levels 1 into the R channel, ray levels 2 into G, 3 into B, etc. This can give you good feedback on the depth necessary in your scene.

Features:

  • Basic stuff. Reflection + Refraction
  • Absorption
  • Glossy reflections
  • Frost (think frosted glass)
  • Transmission shadows pickup the absorption color

Here's a standard render with absorption. Using prman 14.3. Shading quality 0.5, 5×5 samples and 6 specular depth (ouch).

This is a good example of how rays are attenuated by the distance they travel. It may cause a little longer rendering times because I'm using gather to shoot a ray into the surface from the incident direction. Then I take the length of that vector from the ray origin to the ray hit point. However, just like VEX Glass I'm only taking this measurment for secondary rays that are leaving the surface.


1  gather("", P, I, 0, 1, "surface:P", hitP)
2  {
3     tracedlen = length(hitP – P);
4  }
5
6  float d = (absorption – tracedlen) / absorption;
7  d = smoothstep(0,1,d);
8  d = pow(d, fadeexp);

This is a frosty version using a solid glass ball so I didn't have to jack up the specular depth. It still took a long time though.

The frost is high frequency brownian noise used to perturb the normals being fed into both specular and fresnel shadeops. It's really no different then you would handle a regular bump map.


 1   PP = transform("shader", P);
 2   Brownian(frequency, octaves, lacunarity, gain, scale, seed, PP, dQu,
 3               dQv, bumps);
 4   
 5   /* handle the normals */
 6   if(frost != 0) {
 7   Nn = calculatenormal(P + normalize(N) * (frost * bumps));
 8   } else {
 9      Nn = normalize(N);
10   }
11   normal Norig = faceforward(normalize(Ng), I);
12   normal Nbump = faceforward(normalize(Nn), I);
13   normal Nspec = 0;
14   if(frost != 0) {
15   Nspec = normalize(mix(Norig, Nbump, clamp(frost,0.0,1.0)));
16   } else {
17      Nspec = faceforward(normalize(N), I);
18   }
19   
20   
21   fresnel(In, Nspec, eta, kr, kt, R, T);
22   kt = (1 - kr);
23

You can get the shader here. Download Source

VEX uber shader

Thursday, July 16th, 2009

This shader is my current work in progress. I'll keep adding features to it as I need them.

Current supported features

  • Oren Nayar Diffuse
  • Ashikhmin, Ward and Glossy Specular
  • Per-Light Exports
  • Texture map inputs for Specular, Diffuse and Reflection
  • Bump Map
  • Absorption
  • Reflection
  • Environment Map
  • sRGB decoding to make 8bit textures linear

Here's an example of the various per-light exports.

This is the final output from this render. I also added in an SSS pass using the AXIS SSS shader found on the Houdini Exchange.

You can download the shader here.

Click to View Source

  1 /* written by Alan Warren
  2  * alan-warren@gmail.com
  3  *
  4  * description: shader with 3 specular models
  5  * and per light export capability
  6  *
  7  * todo: lots of stuff..
  8  */
  9
 10 #define CAST_FLOAT(x)   ((float)(x))
 11 #define M_PI   3.1415926
 12 #define LIGHT_SPECULAR  0×04
 13 #define mod(x,y)     ((x) % (y))
 14
 15 //logic
 16 #pragma hint surfcol color
 17 #pragma hint attencolor color
 18 #pragma hint amb color
 19 #pragma hint refl color
 20 #pragma hint speccolor color
 21 #pragma hint exp_diff hidden
 22 #pragma hint exp_refl hidden
 23 #pragma hint exp_spec hidden
 24 #pragma hint exp_rim hidden
 25 #pragma hint exp_tex hidden
 26 #pragma hint uv hidden
 27 #pragma hint envmap image
 28 #pragma hint transparency toggle
 29 #pragma hint makedifflin toggle
 30 #pragma hint makebumplin toggle
 31 #pragma hint makespeclin toggle
 32 #pragma hint makerefllin toggle
 33 #pragma hint texmap image
 34 #pragma hint texbump image
 35 #pragma hint reflmap image
 36 #pragma hint specmap image
 37 #pragma disable rough mode 1
 38 #pragma disable rough mode 2
 39 #pragma disable urough mode 0
 40 #pragma disable vrough mode 0
 41 #pragma disable sharp mode 1
 42 #pragma disable sharp mode 2
 43 #pragma choice mode 0 "Glossy"
 44 #pragma choice mode 1 "Ward"
 45 #pragma choice mode 2 "Ashikhmin"
 46 #pragma choice filter "Box" "box"
 47 #pragma choice filter "Gaussian" "gauss"
 48 #pragma choice filter "Bartlett/Triangular" "bartlett"
 49 #pragma choice filter "Sinc Sharpening" "sinc"
 50 #pragma choice filter "Hanning" "hanning"
 51 #pragma choice filter "Blackman" "blackman"
 52 #pragma choice filter "Catmull-Rom" "catrom"
 53 #pragma choice filter "Mitchell" "mitchell"
 54 #pragma choice filter "Point (no filter)" "point"
 55 #pragma choice wrap "Repeat" "repeat"
 56 #pragma choice wrap "Streak" "streak"
 57 #pragma choice wrap "Decal" "decal"
 58 //descriptions
 59 #pragma label Kd "Diffuse Intensity"
 60 #pragma label amb "Ambient"
 61 #pragma label speccolor "Specular Color"
 62 #pragma label surfcol "Surface Color"
 63 #pragma label diffuserough "Diffuse Roughness"
 64 #pragma label Ks "Specular Intensity"
 65 #pragma label rough "Glossy Roughness"
 66 #pragma label sharp "Glossy Sharpness"
 67 #pragma label urough "Anisotropic Urough"
 68 #pragma label vrough "Anisotropic Vrough"
 69 #pragma label mode "Specular Type"
 70 #pragma label refl "Reflection"
 71 #pragma label bias "Bias"
 72 #pragma label transparency "Transparency"
 73 #pragma label ior_in "IOR – In"
 74 #pragma label ior_out "IOR – Out"
 75 #pragma label dmax "Max Distance"
 76 #pragma label samples "Raytrace Samples"
 77 #pragma label angle "Cone Angle"
 78 #pragma label envmap "Environment Map"
 79 #pragma label transform_space "Transform Space"
 80 #pragma label attencolor "Absorption Color"
 81 #pragma label atten_exp "Exponent"
 82 #pragma label atten_amplitude "Amplitude"
 83 #pragma label texmap "Texture Map"
 84 #pragma label filter "Filter"
 85 #pragma label wrap "Wrap"
 86 #pragma label width "Width"
 87 #pragma label interp "Interpolate MIP"
 88 #pragma label blurpxls "Pixel Blur"
 89 #pragma label specmap "Specular Map"
 90 #pragma label srep "U Repeat"
 91 #pragma label trep "V Repeat"
 92 #pragma label Kb "Bump Strength"
 93 #pragma label texbump "Bumpmap"
 94 #pragma label makedifflin "Convert sRGB to Linear"
 95 #pragma label makebumplin "Convert sRGB to Linear"
 96 #pragma label makespeclin "Convert sRGB to Linear"
 97 #pragma label makerefllin "Convert sRGB to Linear"
 98 #pragma label reflmap "Reflection Map"
 99 //grouping
100 #pragma group Diffuse Kd amb surfcol diffuserough makedifflin texmap filter srep trep wrap width interp blurpxls border srep trep makebumplin texbump Kb
101 #pragma group Specular mode Ks speccolor makespeclin specmap sharp rough urough vrough
102 #pragma group Raytrace refl bias ior_in ior_out dmax samples angle makerefllin envmap transform_space transparency Absorption attencolor atten_exp atten_amplitude reflmap
103
104
105 #include <aw_util.h>
106
107
108 surface aw_exports( /* diffuse */
109                     float Kd = 0.95;
110                     vector amb = {1,1,1};
111                     vector surfcol = {1,1,1};
112                     float diffuserough = 0.1;
113                     int makedifflin = 1;
114                     string texmap = "";
115                     string filter = "Box";
116                     string wrap = "Repeat";
117                     float width = 1;
118                     float srep = 1;
119                     float trep = 1;
120                     int interp = 1;
121                     float blurpxls = 0;
122                     /* bump map */
123                     int makebumplin = 1;
124                     string texbump = "";
125                     float Kb = 0.5;
126                     /* specular */
127                     int mode = 0;
128                     float Ks = 0.75;
129                     vector speccolor = {1,1,1};
130                     int makespeclin = 1;
131                     string specmap = "";
132                     float sharp = 0.1;
133                     float rough = 0.2;
134                     float urough = 0.2;
135                     float vrough = 0.2;
136                     /* reflection */
137                     vector refl = {0,0,0};
138                     int makerefllin = 1;
139                     string reflmap = "";
140                     float bias = 0.005;
141                     float ior_in = 1;
142                     float ior_out = 1.5;
143                     float dmax = -1;
144                     int samples = 1;
145                     float angle = 0;
146                     string envmap = "";
147                     string transform_space = "space:world";
148                     /* transmission */
149                     int transparency = 0;
150                     float Absorption = 0.02;
151                     vector attencolor = {0.5,0.5,0.5};
152                     float atten_exp = 1;
153                     float atten_amplitude=1;
154                     vector uv = {0,0,0};
155                     /* exports */
156                     export vector exp_diff = {0,0,0};
157                     export vector exp_refl = {0,0,0};
158                     export vector exp_spec = {0,0,0};
159                     export vector exp_rim = {0,0,0};
160                     export vector exp_tex = {0,0,0};
161                    )
162
163 {
164    // LOCAL VARS **************************************
165    float kr, kt;
166    vector In = normalize(I);
167    vector Nf = frontface(normalize(N), In);
168    vector Refl = 0;
169    vector Trans = 0;
170    vector Crefl = 0, Crim = 0, OutColor = 0;
171    vector V = -In;
172    vector raydir = 0;
173    vector PP = P;
174    vector mycol = {1,1,1};
175    vector k = 1, cc = 1;
176    float maxcont = 1;
177    vector cf,of; float af;
178    float ior = ior_out;
179    float Ndot = dot(In, normalize(N));
180    if(Ndot<0)
181    {
182       ior = ior_in;
183    }
184
185    // TEXTURE MAP *************************************
186    vector texcol = {1,1,1};
187
188    float ss = mod((uv.x) * (srep), 1.0);
189    float tt = mod((uv.y) * (trep), 1.0);
190
191    if(texmap != "")
192    {
193
194    texcol = texture(texmap, ss, tt, "wrap", wrap,
195             "filter", filter, "width", width,
196             "border", {0,0,0,1}, "lerp", interp,
197             "pixelblur", blurpxls);
198        if(makedifflin != 0)
199        {
200           texcol = sRGB_decode(texcol);
201        }
202
203    exp_tex = texcol;
204    }
205
206    // BUMP MAP ****************************************
207    float lum = 0;
208    vector bump = {1,1,1};
209    vector Nn = {0,0,0};
210
211    if(texbump != "")
212    {
213       bump = texture(texbump, ss, tt, "wrap", wrap,
214             "filter", filter, "width", width,
215             "border", {0,0,0,1}, "lerp", interp,
216             "pixalblur", blurpxls);
217       if(makebumplin != 0)
218       {
219          bump = sRGB_decode(bump);
220       }
221
222       lum = bump.r*0.3 + bump.g*0.6 + bump.b*0.1;
223       lum *= Kb;
224       Nn = computenormal(P + normalize(N) * lum * Kb);
225    } else {
226        Nn = normalize(N);
227    }
228    // SPECULAR BUMP ***********************************
229    vector Norig = frontface(normalize(Ng), I);
230    vector Nbump = frontface(normalize(Nn), I);
231    vector Nspec = normalize(lerp((vector)Norig, (vector)Nbump, clamp(Kb, 0.0, 1.0)));
232
233    // RAYTRACING **************************************
234    fresnel(In, normalize(N), ior, kr, kt, Refl, Trans);
235    // Attenuation
236    vector tinthsv = rgbtohsv(attencolor);
237    vector absolute = hsvtorgb(set(tinthsv.x,tinthsv.y,1));
238
239  if(getraylevel() > 0)
240    {
241       float d = pow(length(P-Eye), atten_exp);
242       cc = exp((absolute-max(absolute)-min(absolute))*2.0*atten_amplitude*d);
243    } else {
244       cc = 1;
245    }
246    if(kt > 0.0 && transparency != 0)
247    {
248       k = lerp((vector)kt,kt*cc, clamp(Absorption,0,1));
249       maxcont = max(k);
250       if(maxcont >0.0) {
251           Crim = k*refractlight(cf,of,af,P,Trans,bias,kt);
252       }
253       exp_rim = Crim;
254
255    }
256   
257    // Reflection – with environment
258    Crefl = refl*reflectlight(bias, max(refl),
259                        "samples", samples,
260                        "angle", angle,
261                        "environment", envmap,
262                        "envobject", transform_space);
263    // Reflection Map
264    vector Rmap = 0;
265    if(reflmap != "")
266    {
267
268    Rmap = texture(reflmap, ss, tt, "wrap", wrap,
269             "filter", filter, "width", width,
270             "border", {0,0,0,1}, "lerp", interp,
271             "pixelblur", blurpxls);
272        if(makerefllin != 0)
273        {
274           Rmap = sRGB_decode(Rmap);
275        }
276    }
277    Crefl *= Rmap;
278
279    exp_refl = Crefl;
280    OutColor = Crefl + Crim;
281
282    vector CD = 0;
283    vector Ccol = 0;
284
285    // SPECULAR ****************************************
286    float w = sharp / 2.0;
287    float spec;
288    float NdotI = dot(Nn, V);
289    vector illum = 0;
290    vector Cspec;
291    vector uvv = 0;
292    vector H;
293    vector tanU, tanV;
294    float rz, cos_i;
295    float nml_term;
296    float uval, vval, nval;
297    float exponent;
298    //todo: provide this control
299    int tstyle = 0;
300
301    // lighting calcs
302
303    if(NdotI > 0.0 && w < 0.5)
304    {
305       computeTangents(tanU, tanV, Nn, uvv, tstyle);
306      // both diffuse and specular are defined inside this loop
307       illuminance(PP, normalize(N), M_PI/2, LIGHT_SPECULAR)
308       {
309            vector Nl = normalize(L);
310            cos_i = dot(Nn, Nl);
311
312            if(cos_i > 0.0)
313            {
314               //setup vars
315               H = normalize(V + Nl);
316               uval = dot(tanU, H);
317               vval = dot(tanV, H);
318               nval = dot(Nn, H);
319               rz = 0;
320               shadow(Cl);
321
322               if(mode == 0) // glossy model
323               {
324                  spec = specularBRDF(Nl, Nspec, V, rough);
325                  if(w <= 0) Cspec = Cl * spec;
326                  else  Cspec = Cl * smooth(w, 1-w, spec);
327                  illum += Cspec;
328               }
329               else if(mode == 1) { // ward model
330
331                  if(nval > 0)
332                  {
333                     nml_term = 4.0 * M_PI * urough * vrough;
334                     uval /= urough;
335                     vval /= vrough;
336                     rz = cos_i*exp(-2.0*(uval*uval + vval*vval) /
337                           (1.0 + nval));
338                     rz /= nml_term * sqrt(cos_i*NdotI);
339
340                  }
341                  Cspec = rz * Cl;
342                  illum += Cspec;
343                 
344               }
345               else if (mode == 2) { // ashikhmin model
346                  if(nval > 0)
347                  {
348                     exponent = uval * uval/urough + vval*vval/vrough;
349                     exponent /= 1.0 - nval*nval;
350                     rz = pow(nval, exponent) / (4.0 * dot(V, H));
351                  }
352                  Cspec = rz * Cl;
353                  illum += Cspec;
354               }
355            }
356            else {
357               Cspec = 0;
358            }
359
360          // DIFFUSE ***********************************
361          Ccol = Cl * diffuseBRDF(Nl, Nbump, V, diffuserough);
362          CD += Ccol;
363          //diffuse export
364          exp_diff = Ccol;
365          // assign specular export
366          exp_spec = Cspec;
367       }
368    }
369
370    // SPECULAR MAP *************************************
371    vector specmapcol = {1,1,1};
372
373    if(specmap != "")
374    {
375
376    specmapcol = texture(specmap, ss, tt, "wrap", wrap,
377             "filter", filter, "width", width,
378             "border", {0,0,0,1}, "lerp", interp,
379             "pixelblur", blurpxls);
380        if(makespeclin != 0)
381        {
382           specmapcol = sRGB_decode(specmapcol);
383        }
384    }
385
386   // diffuse calc's
387    mycol = Kd*((CD * texcol) * surfcol);
388
389    // assign glossy specular to final color
390    OutColor += (Ks*(illum*specmapcol))*speccolor;
391
392   Of = 1;
393   Cf = mycol + OutColor;
394 }
395
396