POV-Ray : Newsgroups : povray.binaries.images : Grass using MultiMesh : Grass using MultiMesh Server Time
8 Aug 2024 06:18:38 EDT (-0400)
  Grass using MultiMesh  
From: PM 2Ring
Date: 5 Sep 2005 11:10:01
Message: <web.431c5db8580ece8ad43d28a00@news.povray.org>
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


 

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.