|
|
What ho
Here is a slightly more complex example of the brick mesh, with two combined
pigment functions. If anybody wants a go at it, here's the code (no
smoothing):
/* --------- begin SDL --------- */
#include "shapes.inc"
#include "colors.inc"
global_settings {
assumed_gamma 1 }
camera {
location <18, 10, -10>
up <0, 1, 0>
right <4/3, 0, 0>
direction <0, 0, FoV_45>
look_at <0, 0, 0> }
light_source { <300, 500, -100> color White }
// calculate curvature displacement:
// result1 = inward displacement vector due to curvature
// result2 = outward unit vector for pigment displacement
#macro Curv(posx, posy, rad, sx, sy, vx, vy, nml, result1, result2)
#local vecx = vnormalize(vx);
#local vecy = vnormalize(vy);
#local t1 = 0;
#local t2 = 0;
#if (vlength(posx) < rad)
#local t1 = -(rad-vlength(posx));
#end
#if (vlength(posy) < rad)
#local t2 = -(rad-vlength(posy));
#end
#if (vlength(posx) > sx-rad)
#local t1 = rad-(sx-vlength(posx));
#end
#if (vlength(posy) > sy-rad)
#local t2 = rad-(sy-vlength(posy));
#end
#local nn = vnormalize(nml);
#local vecr = t1*vecx + t2*vecy + nn*rad;
#local result1 = -(vlength(vecr)-rad)*vnormalize(vecr);
#local result2 = vnormalize(vecr);
#end
// calculate pigment displacement
#macro Displace(posi, vect, scal, ampl)
( (ampl-ampl/2) * vect * fn_brick_surface(posi.x/scal, posi.y/scal,
posi.z/scal).x )
#end
// single facet macro
#macro Face(posit, sx,sy, nx,ny, vx,vy,norm, rad, sc, amp)
#local dpx = vx*sx/(nx-1);
#local dpy = vy*sy/(ny-1);
#local ox = -vx*sx/2;
#local oy = -vy*sy/2;
#local px = <0,0,0>;
#local py = <0,0,0>;
#local n = 0;
#local result1 = <0,0,0>;
#local result2 = <0,0,0>;
#while (n < (nx-1)*(ny-1))
#local pos1 = posit + ox + oy + px + py;
#local pos2 = posit + ox + oy + px+dpx + py;
#local pos3 = posit + ox + oy + px + py+dpy;
Curv(px, py, rad, sx, sy, vx, vy, norm, result1, result2)
#local pos1 = pos1 + result1 + Displace(pos1, result2, sc, amp);
Curv(px+dpx, py, rad, sx, sy, vx, vy, norm, result1, result2)
#local pos2 = pos2 + result1 + Displace(pos2, result2, sc, amp);
Curv(px, py+dpy, rad, sx, sy, vx, vy, norm, result1, result2)
#local pos3 = pos3 + result1 + Displace(pos3, result2, sc, amp);
triangle { pos1, pos2, pos3 }
#local pos1 = posit + ox + oy + px + py+dpy;
#local pos2 = posit + ox + oy + px+dpx + py;
#local pos3 = posit + ox + oy + px+dpx + py+dpy;
Curv(px, py+dpy, rad, sx, sy, vx, vy, norm, result1, result2);
#local pos1 = pos1 + result1 + Displace(pos1, result2, sc, amp);
Curv(px+dpx, py, rad, sx, sy, vx, vy, norm, result1, result2);
#local pos2 = pos2 + result1 + Displace(pos2, result2, sc, amp);
Curv(px+dpx, py+dpy, rad, sx, sy, vx, vy, norm, result1, result2);
#local pos3 = pos3 + result1 + Displace(pos3, result2, sc, amp);
triangle { pos1, pos2, pos3 }
#local px = px + dpx;
#if (vlength(px) >= sx)
#local px = 0;
#local py = py + dpy;
#end
#local n = n + 1;
#end
#end
// top-level brick macro
// <xs,ys,zs> = size (actually box 'radii')
// rad = radius of curvature at corner
// res = resolution setting: scale factor * res
// sc = pigment function scale factor
// amp = amplitude of surface roughness:
// NB this will be added to surface, so extent of
// surface is e.g. xs + amp in +ve x-direction
#macro RealBrick(xs, ys, zs, rad, res, sc, amp)
mesh {
Face(<0,ys,0>, xs*2,zs*2, int(xs*res),int(zs*res), <1,0,0>, <0,0,1>,
<0,1,0>, rad, sc, amp)
Face(<0,-ys,0>, xs*2,zs*2, int(xs*res),int(zs*res), <-1,0,0>, <0,0,1>,
<0,-1,0>, rad, sc, amp)
Face(<xs,0,0>, ys*2,zs*2, int(ys*res),int(zs*res), <0,-1,0>, <0,0,1>,
<1,0,0>, rad, sc, amp)
Face(<-xs,0,0>, ys*2,zs*2, int(ys*res),int(zs*res), <0,1,0>, <0,0,1>,
<-1,0,0>, rad, sc, amp)
Face(<0,0,-zs>, xs*2,ys*2, int(xs*res),int(ys*res), <1,0,0>, <0,1,0>,
<0,0,-1>, rad, sc, amp)
Face(<0,0,zs>, xs*2,ys*2, int(xs*res),int(ys*res), <1,0,0>, <0,-1,0>,
<0,0,1>, rad, sc, amp)
}
#end
#declare gran1 = function {
pigment {
granite
color_map {
[0 color 1]
[0.5 color 1]
[1 color 0] } } }
#declare gran2 = function {
pigment {
granite
color_map {
[0 color 0]
[1 color 1] } } }
#declare fn_brick_surface = function {
gran1(x,y,z).x + 0.1*gran2(x/0.2,y/0.2,z/0.2).x }
object {
RealBrick(2,1.5,4, 0.5, 50, 10,0.5)
pigment { color White }
finish { ambient 0 } }
/* --------- end SDL --------- */
All the parameters required can be passed to the macro, except the pigment
function (I couldn't get it to work for some reason). The macro therefore
assumes a pre-declared function called fn_brick_surface.
It should be noted there is a severe limitation to this technique. Using too
large a pigment amplitude with too small a curvature radius (rad) can cause
the surface displacement to diverge too much at the edges, resulting in a
loss of resolution. This effect is also slightly dependent on the
resolution setting. Have a play and I'm sure you'll see what I mean...
Bill
Post a reply to this message
Attachments:
Download 'isomesh1.jpg' (45 KB)
Preview of image 'isomesh1.jpg'
|
|