POV-Ray : Newsgroups : povray.binaries.images : Mesh vs mesh2 : Mesh vs mesh2 Server Time
16 Apr 2024 13:53:12 EDT (-0400)
  Mesh vs mesh2  
From: Bill Pragnell
Date: 25 May 2006 08:00:01
Message: <web.44759ba38c28dbe6731f01d10@news.povray.org>
Following a problem I had with slow mesh parsing (see povray.general), here
is my solution, with an example pic, using an optimized mesh2 object.

My goal was to create a fairly good mountain landscape for use in
backgrounds, etc, without resorting to fiddling with image heightfields or
waiting for isosurfaces. So this is a heightfield generated using only SDL,
using an 'envelope' function to control the height of mountains generated
from pigment functions. I've included the complete scene, with some brief
comments - hopefully someone will find it useful! I'm using 1 pov-unit = 1
metre, approximately, so by all means have a play with the numbers.

Bill

/* code starts */
#include "colors.inc"
#include "shapes.inc"

global_settings {
  assumed_gamma 1
  max_trace_level 10 }

camera {
  location <0, 100, 0>
  right <4/3, 0, 0>
  up <0, 1, 0>
  direction <0, 0, FoV_90>
  look_at <100, 100, 150> }

light_source { <10000, 100000, -50000> color White }

// define basic pigment functions for mountains
// agate for large-scale features, wrinkles for
// fine detail
#declare land1 = function {
  pigment {
    agate
    color_map {
      [0 color rgb 1]
      [1 color rgb 0] } } }
#declare land2 = function {
  pigment {
    wrinkles
    color_map {
      [0 color rgb 1]
      [1 color rgb 0] } } }

// global scaling parameters for pigment functions
#declare sc1 = 20;
#declare sc2 = 5;
#declare hilloff = 12;

// macro function to return a sinusoidal edge, so
// that mountains can rise smoothly from a plain without
// cut-off edges
#macro SineEdge(xp,yp,zp)
  #if (xp >= 0)
    #local Result = 1;
  #end
  #if (xp < 0 & xp >= -pi)
    #local Result = 0.5*cos(xp)+0.5;
  #end
  #if (xp < -pi)
    #local Result = 0;
  #end
  (Result)
#end

// height macro function to return a mountain height value
// given a point in the x-y plane. vary the hilloff parameter defined
// above to move the pigment function around without changing the envelope.
#macro LandHeight(xp, yp)
  #local Result = SineEdge(xp+6,0,yp)
   *(0.5*land1((xp+hilloff)/sc1, 0, yp/sc1).x +
     0.5*land2((xp+hilloff)/sc2, 0, yp/sc2).x);
  (Result)
#end

// texture definitions
#declare p1 = pigment { color Clear }
#declare p2 = pigment {
  slope { <0, 1, 0> }
  color_map {
    [0 color Clear]
    [0.75 color Clear]
    [0.77 color White]
    [1 color White] } }
#declare t1 = texture {
  pigment {
    slope { <0, 1, 0> }
    color_map {
      [0 color Gray70]
      [0.7 color Gray70]
      [0.75 color Tan]
      [0.85 color LightWood]
      [0.94 color rgb <0.3, 0.6, 0.3>]
      [1 color rgb <0.3, 0.6, 0.3>] } }
  finish { ambient 0 } }
#declare t2 = texture {
  pigment {
    gradient y
    pigment_map {
      [0 p1]
      [0.6 p1]
      [0.605 p2]
      [1 p2] } }
  finish { ambient 0.35 } }

// mountain macro to build the mesh2 heightfield
// xs, ys are extent of field in each direction
// (i.e. width = 2*xs etc)
// maxh is maximum altitude of mountains
// dx is grid spacing of heightfield (must divide into
// xs and ys exactly)
#macro Region(xs, ys, maxh, dx)
  #local nx = 2*xs/dx + 1;
  #local ny = 2*ys/dx + 1;
  #local Vertices = nx*ny;
  #local Faces = (nx-1)*(ny-1)*2;
  mesh2 {
  vertex_vectors {
    Vertices,
    #local xp = -xs;
    #local yp = -ys;
    #local n = 0;
    #while (n < Vertices-1)
      <xp, maxh*LandHeight(xp,yp), yp>,
      #local n = n + 1;
      #local xp = xp + dx;
      #if (xp = xs+dx)
        #local xp = -xs;
        #local yp = yp + dx;
      #end
    #end
    <xp, maxh*LandHeight(xp,yp), yp> }
  face_indices {
    Faces,
    #local n = 0;
    #while (n < Vertices-nx-2)
      <n, n+1, n+nx>,
      <n+1, n+nx+1, n+nx>,
      #local n = n + 1;
      #if (mod(n-(nx-1), nx) = 0)
        #local n = n + 1;
      #end
    #end
    <n, n+1, n+nx>,
    <n+1, n+nx+1, n+nx> }
  texture { t1 scale maxh }
  texture { t2 scale maxh } }
#end

// make mountains.
// they were originally created small during testing and
// then scaled up later using transformations. alter the last
// parameter to change the heightfield resolution.
object {
  Region(12, 30, 5, 0.05)
  translate <12, 0, 30>
  scale 500
  translate <1000, 0, 0> }

// ground plane
plane {
  <0, 1, 0>, 0.2
  pigment { color rgb <0.3, 0.6, 0.3> }
  finish { ambient 0 } }

// background & some ground mist
fog {
  color rgb <0.9, 0.975, 1>
  distance 10000
  fog_type 2
  fog_offset 0
  fog_alt 300 }
background { color NavyBlue }

/* code ends */


Post a reply to this message


Attachments:
Download 'hills.jpg' (36 KB)

Preview of image 'hills.jpg'
hills.jpg


 

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