|
![](/i/fill.gif) |
Here's a simple scene of grass, using the 'MultiMesh' technique I described
in the General message area.
// Persistence of Vision Ray Tracer Scene Description File
// File: Grass.pov
// Vers: 3.6
// Desc: Grass blades using smoothed mesh
// Date: 14 Aug 2005
// Auth: PM 2Ring
//
// Derived from:
//
// From: Mike Williams
// Subject: Re: Optimizing scenes with nested loops.
// Date: 13 Aug 2005 05:50:19
// Message: <mfea4CA4nY$CFwvC@econym.demon.co.uk>
//
// -f +A0.6 +AM2 +R1
// -f -A0.4 +AM2 +R1
// -d +A0.1 +AM2 +R3
//
#version 3.6;
//Leaf details
#declare Do_Normal = 1;
#declare Do_Tip = 1;
#include "transforms.inc"
global_settings {assumed_gamma 1.0}
//randomizer macros
#declare R2 = seed(137);
#macro RI(A) floor(A*rand(R2)) #end //Random integer between 0 & <A
#macro RU(A) (A*rand(R2)) #end //Random Unsigned number between 0
& A
#macro RS(A) (A*(rand(R2) - .5)) #end //Random Signed number between
-0.5*A & +0.5*A
//-----------------------------------------------------------------------------
//grass blade parameters
#declare bladeSeg = 6; //trapezoidal segments per blade + 1
#declare bladeWidth = .0275 * 1.25; //blade width at base (=maximum
width)
#declare bladeCount = 8; //blades per patch. Must be even!!!
#declare patchCount = 19; //total number of patches
#declare patchM = 9; //Patch array size
#declare sDelta = 1e-3 / bladeSeg; //Parameter step size for spline
tangent calculation
//grass pigment
#macro CGrass(A) rgb<.15 +(1-A)*.075, .2+sqrt(A)*.6, .05+0.05*A>*.9 #end
//#macro CGrass(A) rgb<0, A*.7, 0> #end
#declare FGrass = finish{diffuse .8 specular .5 roughness 1e-2}
//#declare FGrass = finish {diffuse .75}
#declare NGrass = normal{gradient x scale 1.35 scallop_wave bump_size 1.25}
//grass texture
#macro TGrass(A, SC)
pigment{CGrass(A)}
finish{FGrass}
#if(Do_Normal)
normal{NGrass scale SC}
#end
#end
//Find approximate normal vector to spline spl in YZ plane at parameter A
#macro Normal(A)
#local V = spl(A+sDelta) - spl(A-sDelta); //approximate tangent=secant
vnormalize(<0, V.z, -V.y>) //rotate tangent by -90*x to
find normal
#end
/* Grass blade segment structure:
p2L*---:---*p2R
| : |
| : |
| : |
| : |
| : |
| : |
| : |
p1L*---:---*p1R
*/
// Create a single grass blade as a 'sub-mesh'. Transform by Trans,
pointwise.... :(
#macro MakeBlade(Trans)
#local sA = spl(0);
#local bW1 = bladeWidth;
#local p1L = vtransform(sA-bW1*x, Trans);
#local p1R = vtransform(sA+bW1*x, Trans);
#local N1 = vtransform(Normal(0), Trans);
#local T1 = texture{TGrass(0, bW1) transform Trans}
//Make blade segments
#local I = 1;
#while (I < bladeSeg)
#local A = I / bladeSeg;
#local sA = spl(A);
#local bW2 = bladeWidth * sqrt(1-A);
#local p2L = vtransform(sA-bW2*x, Trans);
#local p2R = vtransform(sA+bW2*x, Trans);
#local N2 = vtransform(Normal(A), Trans);
#local T2 = texture{TGrass(A, bW2) transform Trans}
smooth_triangle {
p1L, N1,
p1R, N1,
p2L, N2
texture_list {T1, T1, T2}
}
smooth_triangle {
p2R, N2,
p2L, N2,
p1R, N1
texture_list {T2, T2, T1}
}
#local p1L = p2L;
#local p1R = p2R;
#local bW1 = bW2;
#local N1 = N2;
#local T1 = T2;
#local I = I + 1;
#end
//Make blade tip
#if(Do_Tip)
smooth_triangle {
#local T2 = texture{pigment{rgb<.75, 1, .25>}}
p1L, N1,
vtransform(spl(1), Trans), vtransform(Normal(1), Trans),
p1R, N1
texture_list {T1, T2, T1}
}
#end
#end
//make a patch of blades as a single mesh, in a checkered pattern,
//so they can be overlapped pairwise
#macro MakePatch()
mesh{
#local I=0;
#while(I < bladeCount)
#local J=mod(I, 2);
#while(J < bladeCount)
//Shape of blade's centre line. Must be in YZ plane !!!
#declare spl = spline {
#local M = .3 + RU(.5);
quadratic_spline
0.0, <0, 0, 0>
M, <0, M, 0>
1.0, <0, 1, .1 + RU(.6)>
}
//Create blade transform
#local Trans = transform{
scale 2*6*(1 + <RU(.3), RU(.6), RU(.1)>*0.175) / (1.175*bladeCount)
rotate y*RU(360)
translate (<J, 0, I> + <RS(1), 0, RS(1)> - .5*<1, 0,
1>*(bladeCount-1))/bladeCount
}
MakeBlade(Trans)
#local J = J + 2;
#end
#local I = I + 1;
#end
}
#end
//Create patches
#declare Patch = array[patchM];
#declare I=0;
#while(I < patchM)
#declare Patch[I] = MakePatch()
#declare I = I + 1;
#end
//---Ground-----------------------------------
#declare Sandy = colour rgb <1, .80, 0.45>;
#declare PSand = pigment{
granite scale 2e-3
colour_map{
[0 Sandy*.60]
[0.35 Sandy]
[1 Sandy*1.5]
}
}
#declare GW = 140;
#declare Ground =
cylinder{
0, 1e-3*y , GW
texture {
pigment{PSand}
finish{diffuse 1}
normal{
average
normal_map{
[5 wrinkles scale 2.3 bump_size 1.1]
[1 granite scale 5e-3 bump_size .85]
}
}
}
}
//---Sky-----------------------------------
#declare SkyBlue = rgb<0.035, 0.27, 0.67>; //For water & sky
//Clouds
#declare CM_Clouds2 =
color_map {
[0.0 rgb 1]
[0.15 rgb 0.85]
[0.175 rgb 0.75]
[0.525 SkyBlue]
}
#declare T_Clouds =
texture{
pigment {
bozo
color_map {CM_Clouds2}
warp{
turbulence 0.375
octaves 6
omega 0.7
lambda 2.25
}
}
finish{ambient 0.975 diffuse 0.7}
}
#declare Sky =
plane{<0, 15, 1>, 1E4
inverse
no_shadow
texture{
T_Clouds
scale <1, 1/4, 4>* 3E4
}
}
//---Scene-----------------------------------
//place lots of pairs of patches
#if(1)
union {
#declare I=0;
#while(I < patchCount)
#declare J=0;
#while(J < patchCount)
object {
Patch[RI(patchM)]
scale (1 + <RU(.3), RU(.6), RU(.1)>*0.3)/1.075
rotate y*(180*RI(2))
translate <I, 0, J>
}
object {
Patch[RI(patchM)]
scale (1 + <RU(.3), RU(.6), RU(.1)>*0.3)/1.075
rotate y*(90+180*RI(2))
translate <I, 0, J>
}
#declare J = J + 1;
#end
#declare I = I + 1;
#end
translate -0.5*<1, 0, 1>*(patchCount-1)
scale .5
}
#end
object{Ground}
object {Sky}
background{SkyBlue*.85}
camera {location <0, 8, -50>*.75 look_at 2.3*y angle 20}
//camera {location <0, 10, -30> look_at 5.5*y angle 35 scale .15}
//closeup
//camera {location <0, 18, -16> look_at .33*y angle 17} //overhead
light_source {<80, 280, -150> rgb 1}
//-----------------------------------------------------------------------------
Post a reply to this message
Attachments:
Download 'grassi3s.jpg' (283 KB)
Preview of image 'grassi3s.jpg'
![grassi3s.jpg](/povray.binaries.images/attachment/%3Cweb.431c5db8580ece8ad43d28a00%40news.povray.org%3E/grassi3s.jpg?ttop=441697&toff=5000&preview=1)
|
![](/i/fill.gif) |