POV-Ray : Newsgroups : povray.advanced-users : Isosurface Rocks, using a single iso; could use a bit of help : Re: Isosurface Rocks, using a single iso; could use a bit of help Server Time
20 Apr 2024 05:15:03 EDT (-0400)
  Re: Isosurface Rocks, using a single iso; could use a bit of help  
From: Bald Eagle
Date: 8 Dec 2016 15:20:00
Message: <web.5849bfbd916cc6b4c437ac910@news.povray.org>
I find it easier to follow along if the code is tightened up a bit, so I deleted
a bunch of stuff, and left the macro in the main file.

I'd make a single line of rocks varying octave horizontally and with an
orthographic camera, so that you can really see what sort of difference in
texture you get, and it will be faster than rendering 100 isosurfaces (it took
53 min on my i7 work laptop)

I needed to include functions.inc to get it to work.

I increased max gradient near the end of the file (see comment)

Maybe change the scaling of the octave - you may need a more extreme change to
see a difference (see comment)

looks like you define a noise function, and then modify a sphere to make it
bumpy.   Then it gets scaled to make it less spherical and more irregular.

IIRC, search for "spherical [Perlin] noise" and you may find some helpful
scenes.

{... back to lifting heavy things...}

//#####################################################################


//RandomTools.mcr:
//    Randomization macros.

#macro SRand(RS)
    (rand(RS) * 2 - 1)
#end

#macro RRand(RS, Min, Max)
    (rand(RS) * (Max - Min) + Min)
#end

#macro Clamp(V, Min, Max)
    (min(Max, max(Min, V)))
#end

#macro Range(V, Rmn, Rmx)
    (V * (Rmx - Rmn) + Rmn)
#end

#macro RClamp(V, Rmn, Rmx, Min, Max)
    (Clamp(Range(V, Rmn, Rmx), Min, Max))
#end

#macro Displace_Line(pos, p0, p1, len, rad, scatter)
    #local w = pos - p0;
    #local ul = vnormalize(p1-p0);
    #local dist = vlength(vcross(ul, w));
    #local uv = vnormalize(VPerp_To_Vector(ul));
    #local vv = vnormalize(VPerp_To_Plane(ul, uv));
    #local trans = ul*len*exp(-(len/rad)*dist);
    #local rang = vlength(trans);
    #local u_ad = uv*rang*tan(radians(scatter));
    #local v_ad = vv*rang*tan(radians(scatter));
    #local trans = trans + rand(r1)*u_ad-u_ad/2 + rand(r1)*v_ad-v_ad/2;

    (trans)
#end

#local RsA = seed(112080);

global_settings {assumed_gamma 1.0}

#include "functions.inc"

camera { location <0, 10, -10>
  look_at <0, 0, 0>}

background {rgb <0.8, 0.8, 1>}

light_source {<-30, 100, -30> color rgb 0.5}

light_source {<0, 10, -30> color rgb 0.5}

#macro IsoRock(Position, Octaves)

    #local UsePavement = !true;
    #local Octaves = max (1, Octaves);

    #local P = function {
  pigment {
   #local Curve = 2/8;
   #local Omega = 0.5;
   #local Lambda = 2.5;
   #local Octaves = Octaves;    //  *** is this line really needed? ***
   pigment_pattern {
    average
    pigment_map {
                     #local octave = 0;
                     #while (octave < Octaves)
      [pow(Omega, octave)   // opening square bracket
      pigment_pattern {
       #if (UsePavement)
        pavement form 1
       #else
        crackle form <RRand(RsA, 0.3, 0.9), RRand(RsA, 0.3, 0.9), RRand(RsA,
0.3, 0.7)> * 0.5
       #end
       scale pow(Lambda, -octave)
       color_map {
        [0 rgb 1]
        [1 rgb 0]
       } // end color map
      } // end pigment pattern
      poly_wave 1/Curve
      ]      // closing square bracket
                      #local octave = octave + 1;
     #end // end while octave
     } // end pigment map
   } // end pigment pattern
   poly_wave Curve
   color_map {
    [0 rgb 1]
    [1 rgb 0]
   } // end color map
  } // end pigment
 } // end function


 #local S = function {x * x + y * y +  z *z - 1}

 #declare Iso_Rock = isosurface {
  function {S(x, y, z) - P(x, z, y).grey * 2}
  max_gradient 34    //    Somewhat rough, but acceptable and has interesting
branching lace-like features.
  contained_by {sphere {0, 1.5*2.5}}
  pigment {rgb 1}
  scale <RRand(RsA, 0.3, 0.9), RRand(RsA, 0.3, 0.9), RRand(RsA, 0.3, 0.9)>
  rotate <RRand(RsA, 0, 360), RRand(RsA, 0, 360), RRand(RsA, 0, 360)>
 } // end isosurface

 object {Iso_Rock
  scale 1
  translate <Position.x, Position.y, Position.z>
 }
#end // end macro isorock

// Single Rock.
// #local RockPosition = <0, 0, 0>;
// IsoRock(RockPosition, 4)

//    Build tracing into this, along with pigment pattern placement.
#macro DistributeRocks(Extent, CameraLocation)
 #local RsA = seed(112080);
 #local Types = array[4];
 #local Types[0] = !true;    //    Fairly normal.
 #local Types[1] = true;    //    Vein mounds.
 #local Types[2] = true;    //    Sparse.
 #local Types[3] = !true;    //    Stones.
 #local Floor = union {
  #local I = -Extent;
  #while(I < Extent)
   #local J = -Extent;
   #while(J < Extent)
    #local rockLocation = <I, 0, J> * 3;
    #local camDist = vlength(CameraLocation - rockLocation);
    #if (camDist > 50)
                     #local camDist = camDist * 0.01;
    #else
                     #local camDist = camDist * 0.1;
    #end
    IsoRock(rockLocation, 8/camDist)    // Maybe add a scaling factor for
camDist - it may need to be larger to see a difference
    #local J = J + 1;
   #end // end while J
  #local I = I + 1;
  #end // end while I
 } // end union
 object {Floor translate <Extent*0.5, 0, Extent*0.5>}
#end // end macro DistributeRocks


//    Many Rocks.
#local Extent = 5;
DistributeRocks(Extent, <0, 10, -10>)

//Chunk of the scene by PM 2 Ring that uses the single iso technique:
//Stone parameters
#declare GridSize = 4;    // Total number of stones =
#local GridSize = GridSize * GridSize;
#declare Width = 1 / GridSize;  // Cell width.
#declare Radius = Width * 0.70;  // Stone radius
#declare DRate = 0.875 / Radius;  // Radius deformation rate
#declare Height = 0.55;    // Stone height

//---Functions------------------------------------------------

// Positive modulus: never returns negative values
#declare smod = function (A, B) {mod(B + mod(A, B), B)}

// Centered modulus
#declare cmod = function (A, B) {smod(A, 2 * B) - B}

// 2D cells: returns a random value for each unit square
#declare f_cell2D = function (x, z) {f_snoise3d (floor(x), 0, floor(z))}

// Noisy modulus. Makes a random centre for each stone
#declare f_modnoise = function (x,z) {cmod(x, Width) + (Width - Radius) *
f_cell2D (x*0.5/Width, z*0.5/Width)}

// Randomized radius for tumbled stone shape
#declare f_Rad = function {1 + 0.45*f_noise3d (x*DRate, y*DRate, z*DRate)}

//Displaced, vertically squashed spheres
#declare f_Stone = function {f_r (f_modnoise (x, z), y/Height, f_modnoise(-z,
x))}

// The stones. Scaled so that textures appears the same, no matter how many
stones are done.
isosurface {
 function {f_Stone (x, y, z) - Radius * f_Rad(x, y, z)}
 contained_by {
  box {<-1, -Width*Height, -1>, <1, Width * Height, 1>}
 }
 max_gradient 50       // <==== I changed this to 50, [msg - 46.596]
 accuracy 5e-3
 scale 5.7             //Fill view with stones
 rotate -3*y
 translate <0, 0.35*Radius*Height-1, 1>
}


Post a reply to this message

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