POV-Ray : Newsgroups : povray.advanced-users : Isosurface Rocks, using a single iso; could use a bit of help Server Time
16 Apr 2024 06:41:47 EDT (-0400)
  Isosurface Rocks, using a single iso; could use a bit of help (Message 1 to 10 of 10)  
From: [GDS|Entropy]
Subject: Isosurface Rocks, using a single iso; could use a bit of help
Date: 8 Dec 2016 05:10:01
Message: <web.584930896adf4b231c3f31c90@news.povray.org>
Hello,

I have a macro adapted from a nice rock Tek posted, and wish to merge this
technique with one by PM 2 Ring that uses a single Isosurface but grants
multiple objects. The problem is that I have tried, and I don't know what I am
doing, so I lose 99% of the detail from the nice function.

There are a few things which will determine the utility of what I am doing, one
being that I wish to include an automatic trace function which will be used to
position the things. That is easy and I already have macros for it, but I am not
sure that it can be done with the single Isosurface method without passing in
the Isosurface to be used for the terrain and combining its function with the
rock function somehow and I have no earthly idea how to do it.

The other thing is the whole loss of detail. I am intentionally reducing the
octaves/detail of my rocks based on distance from camera, and I am not sure that
can be done with the single method, but then again, it is so dang fast that
might make up for it. My attempts to merge the two methods result in basically
no detail beyond that of the original rocks by PM 2 Ring, likely because I have
no idea what I am doing.

The last thing is that I am planning to use a function select method with this
to allow each rock to use a different function or combination thereof, I have
this already working with a stone floor macro I made, which will be released
with this one. If I convert both of these to use the single Isosurface method,
that isn't going to work, will it? I also use variable sized containers for the
isosurfaces to modify brick shape...which will not work with the single method.

Those points above are just to give you some context, and maybe you can tell me
I am being dumb in many ways and guide me properly for it. ;-)

I expect the rotation/scaling and translation perturbations will suffer or
become immensely complex as well...

So, I defer to those more experienced than I for advice and such.

The end result of this is to be a set of rock, terrain, volumetric sky,
volumetric fog and stone block macros for the community, which I have made a
whole ton of progress on. These are intended to augment my corrosion,
snow/ice/icicle and moss macros which I am also updating, as part of a kind of
"natural elements" macro pack for folks to use...though I am as yet unaware of
any of my previous macros ever having been used by anyone lol! :p

Note:
The rocks in RockTest are fairly repetitive in shape, and I am working on this.
If you look at the bit where you see "crackle form" there are a number of lines
commented out, I am playing with variations here but so far the best results
come from <9.0, 0, 0> in conjunction with max gradient 70, just FYI.

I will post an image in PBI which corresponds with the RockTest.pov file, for
reference, when it is done rendering.

Here are the scenes:

---------------------------------------------------------------
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

--------------------------------------------------------------------

The RockTest.pov file:

#include "RandomTools.mcr"

#local RsA = seed(112080);

global_settings
{
    assumed_gamma 1.0
}

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

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 for the generation of Isosurface rocks utilizing a pattern based on
work by Tek and Mike Williams.
//    While a value of 1 for Octaves is perfectly valid, there is little
differentiation
//    between the various patterns.
#macro IsoRock(Position, Octaves)

    //    This setting is internal due to
    //    its effect being interesting but
    //    distinctly very un rock-like in
    //    nature. It makes a 3d fractal.
    #local UsePavement = !true;

    //    Disallow 0 as a value for octaves.
    #local Octaves = max(1, Octaves);

    #local P =
    function
    {
        pigment
        {
            //    Small values make it look porous.
            #local Curve = 2 / 8;
            #local Omega = 0.5;
            #local Lambda = 2.5;
            #local Octaves = Octaves;

            pigment_pattern
            {

                //    Octaves:    [1-3]    Foamy, smooth rock with cavities of
varying scale.
                //    Octaves:    [4-8]    Foamy, smooth rock with cavities of
varying scale.
                average

                //    Octaves:    [1-3]    Angular boulder like faces are
produced, which may be good targets for combination with other functions
                //    Octaves:    [4-8]    Very accurate representation of open
cell foam, completely fills container object.
                //granite

                pigment_map
                {
                    #local octave = 0;
                    #while (octave < Octaves)

                        [pow(Omega, octave)
                            pigment_pattern
                            {

                                #if (UsePavement)
                                    pavement form 1
                                #else
                                    //    X:    [0.1 - 0.9]    Smooth ridges ->
Very cratered ridges
                                    //    Y:    [0.1 - 0.9]    Smooth wrinkles
-> Very wrinkly with voids
                                    //    Z:    [0.1 - 0.7]    Very smooth ->
Very jagged
                                    //    The values above are valid only alone;
their range is decreased when used in concert.
                                    //crackle form <RRand(RsA, 0.1, 0.9),
RRand(RsA, 0.1, 0.9), RRand(RsA, 0.1, 0.7)> * 0.125

                                    crackle form <RRand(RsA, 0.3, 0.9),
RRand(RsA, 0.3, 0.9), RRand(RsA, 0.3, 0.7)> * 0.5

                                    //    Default; creates a foamy looking rock.
                                    //crackle form <0.9, 0.0, 0.0>

                                    //crackle form <0.1, 0.1, 0.1>

                                    //crackle form <0.0, 0.1, 0.5>    //
Smooth crinkly wrinkles.
                                #end

                                scale pow(Lambda, -octave)

                                color_map
                                {
                                    [0 rgb 1]
                                    [1 rgb 0]
                                }
                            }

                            poly_wave 1 / Curve
                        ]

                    #local octave = octave + 1;
                    #end
                }
            }

            poly_wave Curve

            color_map
            {
                [0 rgb 1]
                [1 rgb 0]
            }
        }
    }

    #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 3
        max_gradient 34    //    Somewhat rough, but acceptable and has
interesting branching lace-like features.
        //max_gradient 70   //    Generally smooth and highly porous, similar to
Tufa rock or Pumice.

        //    Useful for the construction of a large number of rocks from within
a loop.
        //max_gradient RRand(RsA, 2, 70)

        //    This needs to be a randomly perturbed mesh primitive.
        //    The rock generation algorithm from River 2017 might be a good
candidate if we can figure it out.
        contained_by
        {
            sphere
            {
                0,
                1.5 * 2.5 //   Perhaps basing scale on the parameters which fill
the container utterly will prevent that issue?
            }
        }

        pigment
        {
            rgb 1
        }

        //scale 3
        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)>
    }

    object
    {
        Iso_Rock

        scale 1
        translate <Position.x, Position.y, Position.z>
    }

#end

//    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);

                //    This is a guess, and should be improved to be a smooth
curve.
                #if (camDist > 50)
                    #local camDist = camDist * 0.01;
                #else
                    #local camDist = camDist * 0.1;
                #end

                //#debug concat("Distance from Camera: ", str(camDist, 0, 1), "
Adjusted Octaves: ", str(8 / camDist, 0, 2))
                //#debug "\n\n"

                //    Reduce octaves/detail with distance from camera.
                IsoRock(rockLocation, 8 / camDist)

            #local J = J + 1;
            #end
        #local I = I + 1;
        #end
    }

    object
    {
        Floor
        translate <Extent * 0.5, 0, Extent * 0.5>
    }
#end

//    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_snoise3d(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)
    }

    //    This doesn't really work, as such:
    /*
    function
    {
        (f_Stone(x, y, z) * (P(x, z, y).grey * 2.5)) - Radius * f_Rad(x, y, z)
    }
    */

    //    Many orbs.
    /*
    function
    {
        f_r(cmod(x, Width), y / Height, cmod(z, Width)) - Radius
    }
    */

    contained_by
    {
        box
        {
            <-1, -Width * Height, -1>,
            <1, Width * Height, 1>
        }
    }

    max_gradient 30
    accuracy 5e-3

    //texture{MultiStone scale 2*Width}

    scale 5.7             //Fill view with stones
    rotate -3*y
    translate <0, 0.35 * Radius * Height - 1, 1>
}


Post a reply to this message

From: Bald Eagle
Subject: Re: Isosurface Rocks, using a single iso; could use a bit of help
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

From: INVALID ADDRESS
Subject: Re: Isosurface Rocks, using a single iso; could use a bit of help
Date: 9 Dec 2016 00:35:22
Message: <1789407256.502954273.966147.gdsHYPHENentropyAThotmaolDOTcom@news.povray.org>
Bald Eagle <cre### [at] netscapenet> wrote:
> 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 wanted to make sure folks would have a file that would do its thing with
little work. :)

> 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)

Do you have any idea how to unite the single iso method with the multiple
one I have? Thats what has me stuck, nit sure how to do that at all.

I suppose it isn't too big of a deal if I cannot combine them, but it would
be nice from a speed perspective and so people can use many of the rocks vs
only a few.

Thanks for the tips too btw.

Ian


Post a reply to this message

From: Bald Eagle
Subject: Re: Isosurface Rocks, using a single iso; could use a bit of help
Date: 9 Dec 2016 07:55:01
Message: <web.584aa95d916cc6b4c437ac910@news.povray.org>
[GDS|Entropy] <gdsHYPHENentropyAThotmaolDOTcom> wrote:

> Do you have any idea how to unite the single iso method with the multiple
> one I have? Thats what has me stuck, nit sure how to do that at all.

I guess you mean this:

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

?

That's a single invocation of the macro.
The DistributeRocks macro just does a nested loop 'Extent' times, to make the
grid of single rocks.

Just comment out the #while J and its #end, and pop a #declare J=0; in there
instead.   Then you'll get a horizontal line at z=0;
Change 'Extent' to a lower number to get fewer rocks.

I'd say this would benefit from TOK's isosurface estimator macros, or maybe
reworking it into a parametric-style set of equations that would generate a
union of smooth triangles or an actual mesh{} object from the resulting points.
 THAT ought to be lightning fast in comparison - especially if you intend on
making a LOT of rocks, like a gravel driveway or something   :)

I will think on it a bit.


Post a reply to this message

From: [GDS|Entropy]
Subject: Re: Isosurface Rocks, using a single iso; could use a bit of help
Date: 9 Dec 2016 08:15:01
Message: <web.584aadff916cc6b41c3f31c90@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:
> I guess you mean this:
>
> // Single Rock.
> // #local RockPosition = <0, 0, 0>;
> // IsoRock(RockPosition, 4)

No, I wrote all of that...I guess I wasn't clear. The only part I didn't write
is the base Isosurface math, everything else I coded.

The part I didn't write is the following, and it uses a single Isosurface which
produces many rocks, whereas my rock maker uses one Isosurface for *every* rock.

Here is the code which uses the single iso but gives many rocks, what I am
trying to do is combine the Isosurface function from my bit that I adapted from
Tek with the single iso method below so I can use a single iso and get many
rocks but using my algorithm.

//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_snoise3d(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)
    }

    //    This doesn't really work, as such:
    /*
    function
    {
        (f_Stone(x, y, z) * (P(x, z, y).grey * 2.5)) - Radius * f_Rad(x, y, z)
    }
    */

    //    Many orbs.
    /*
    function
    {
        f_r(cmod(x, Width), y / Height, cmod(z, Width)) - Radius
    }
    */

    contained_by
    {
        box
        {
            <-1, -Width * Height, -1>,
            <1, Width * Height, 1>
        }
    }

    max_gradient 30
    accuracy 5e-3

    //texture{MultiStone scale 2*Width}

    scale 5.7             //Fill view with stones
    rotate -3*y
    translate <0, 0.35 * Radius * Height - 1, 1>
}


Post a reply to this message

From: Bald Eagle
Subject: Re: Isosurface Rocks, using a single iso; could use a bit of help
Date: 9 Dec 2016 10:20:00
Message: <web.584aca92916cc6b4c437ac910@news.povray.org>
"[GDS|Entropy]" <nomail@nomail> wrote:

> Here is the code which uses the single iso but gives many rocks, what I am
> trying to do is combine the Isosurface function from my bit that I adapted from
> Tek with the single iso method below so I can use a single iso and get many
> rocks but using my algorithm.

I think I understand.

Follow that code like this -
the moduli (AFAIK) produce intermittent values, for lack of a better way to
describe it - just the remainders.  Bread crumbs on the number line.

> //    2D cells: returns a random value for each unit square
for every square generate a random number,

> //    Noisy modulus. Makes a random centre for each stone
.... and then a random location,

> //    Randomized radius for tumbled stone shape
... with a random size

> //Displaced, vertically squashed spheres

and then make spheres.


>     function
>     {
>         f_Stone(x, y, z) - Radius * f_Rad(x, y, z)
>     }

so you take that first function, and subtract a varying value of f_rad from it
to get the overall value where the isosurface function equals zero.

To give a sort of 2D analogy, imagine making a heightfield and intersecting it's
isolated peaks with a plane at y=0.   You'd get irregular shaped 'disks'
scattered throughout the plane.

This just does sort of the same thing but it's in 3D, where the function of x,
y, and z equals zero, and the irregular shapes are in space, not a plane.

I will have to think a bit about how to take your pigment pattern method and
make it work as a single isosurface.
I think you will have to add or subtract something like leopard or spotted, or
just part of that original code function to get _your_ shape scattered
throughout a single isosurface like the example code.

Does that make sense?


Post a reply to this message

From: [GDS|Entropy]
Subject: Re: Isosurface Rocks, using a single iso; could use a bit of help
Date: 9 Dec 2016 12:10:01
Message: <web.584ae3f3916cc6b41c3f31c90@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:
> "[GDS|Entropy]" <nomail@nomail> wrote:
>
> > Here is the code which uses the single iso but gives many rocks, what I am
> > trying to do is combine the Isosurface function from my bit that I adapted from
> > Tek with the single iso method below so I can use a single iso and get many
> > rocks but using my algorithm.
>
> I think I understand.
>
> Follow that code like this -
> the moduli (AFAIK) produce intermittent values, for lack of a better way to
> describe it - just the remainders.  Bread crumbs on the number line.
>
> > //    2D cells: returns a random value for each unit square
> for every square generate a random number,
>
> > //    Noisy modulus. Makes a random centre for each stone
> .... and then a random location,
>
> > //    Randomized radius for tumbled stone shape
> ... with a random size
>
> > //Displaced, vertically squashed spheres
>
> and then make spheres.
>
>
> >     function
> >     {
> >         f_Stone(x, y, z) - Radius * f_Rad(x, y, z)
> >     }
>
> so you take that first function, and subtract a varying value of f_rad from it
> to get the overall value where the isosurface function equals zero.
>
> To give a sort of 2D analogy, imagine making a heightfield and intersecting it's
> isolated peaks with a plane at y=0.   You'd get irregular shaped 'disks'
> scattered throughout the plane.
>
> This just does sort of the same thing but it's in 3D, where the function of x,
> y, and z equals zero, and the irregular shapes are in space, not a plane.
>
> I will have to think a bit about how to take your pigment pattern method and
> make it work as a single isosurface.
> I think you will have to add or subtract something like leopard or spotted, or
> just part of that original code function to get _your_ shape scattered
> throughout a single isosurface like the example code.
>
> Does that make sense?

I think I get it, the spotted or leopard makes sense for a method to produce
unique instances of another thing, using them as a sort of mask, if I have your
meaning.

Before the rabbit hole is too deeply traversed, will it be possible to have
variance in the function governing each rock? I want to maintain the rocks
having many functions.

Of course a workaround would be to simply call the resultant macro, passing in
whichever function is desired for volume governance, a number of times equal to
the number of rock function variants desired.

Of course I will need to run some sort of collision detection to prevent
overlaps.

Is it possible to use an array of blobs in a single blob object [elements not
necessarily touching] as the container shape for the iso?

This would simplify the whole collision thing since the iso would only appear
within those elements and I can run an algo to track the positions, and allocate
location vector subsets to each rock function through an external array passed
to each call to the macro for each function variant desired.

I guess IO am getting a little ahead of myself though; first the single iso will
need to be done, then assuming what I am thinking of with the blob container is
actually possible, the rest will be pretty simple for me to knock out.

Thanks for your time!
Ian


Post a reply to this message

From: Bald Eagle
Subject: Re: Isosurface Rocks, using a single iso; could use a bit of help
Date: 9 Dec 2016 12:45:00
Message: <web.584aed57916cc6b4c437ac910@news.povray.org>
"[GDS|Entropy]" <nomail@nomail> wrote:

> I think I get it, the spotted or leopard makes sense for a method to produce
> unique instances of another thing, using them as a sort of mask, if I have your
> meaning.

Right, if you're going to do it the pigment pattern way.

> Before the rabbit hole is too deeply traversed, will it be possible to have
> variance in the function governing each rock? I want to maintain the rocks
> having many functions.

Stop thinking rocks, and think pigment, since that's the function that you're
passing on to the isosurface.  I'm not that great with the many pigment
functions - maybe there's something with turbulence, octaves, warp, etc.


> Of course I will need to run some sort of collision detection to prevent
> overlaps.

I think that the spotted type patterns have that built in, as does the method of
creating separate visible rocks as part of one isosurface.   In other words - no
you don't, since it's already done.

> Is it possible to use an array of blobs in a single blob object [elements not
> necessarily touching] as the container shape for the iso?

I dunno.   I thought that only spheres and boxes could be used - but give it a
try and see what happens.
Though I think all that will do is "clip" out areas of the isosurface and not
give you the real _surface_, which is the whole point.

Also, See Mike Horvath's current "disappearing isosurface" thread - I think
evaluate would be an excellent feature to incorporate into all this.

Also, check out:
http://news.povray.org/povray.binaries.images/thread/%3Cweb.578a5fb98b356715e7df57c0@news.povray.org%3E/
and Tor's links to his scene which use his space-division method.
mod and select can be pretty cool when combined together like he does!


Post a reply to this message

From: Thomas de Groot
Subject: Re: Isosurface Rocks, using a single iso; could use a bit of help
Date: 10 Dec 2016 03:10:48
Message: <584bb888@news.povray.org>
Many years ago (around 2005) when I was pretty knowledgeable about 
isosurfaces, I wrote a macro for generating isosurface landscapes. I 
introduced so many variables however, that the macro was/is almost 
impractical ;-) and so it went forgotten by the world at large.

Maybe you could glean bits and pieces from it for your rock macro? 
Essentially, my isosurface is a single iso.


-- 
Thomas


Post a reply to this message


Attachments:
Download 'geomorph22.pdf' (436 KB) Download 'utf-8' (38 KB)

From: INVALID ADDRESS
Subject: Re: Isosurface Rocks, using a single iso; could use a bit of help
Date: 10 Dec 2016 06:48:06
Message: <1320438699.503062758.332340.gdsHYPHENentropyAThotmaolDOTcom@news.povray.org>
Thomas de Groot <tho### [at] degrootorg> wrote:
> Many years ago (around 2005) when I was pretty knowledgeable about 
> isosurfaces, I wrote a macro for generating isosurface landscapes. I 
> introduced so many variables however, that the macro was/is almost 
> impractical ;-) and so it went forgotten by the world at large.
> 
> Maybe you could glean bits and pieces from it for your rock macro? 
> Essentially, my isosurface is a single iso.
> 
> 

Thank you sir, I humbly accept your offer. :)

You make a good point and UX case with regard to not necessarily exposing
parameters for everything.

I will endeavor to produce some targeted presets geared toward certain
purposes, and expose perhaps a single scalar parameter for "feature size"
(though by doing so I sort of put the lie to that choice of names) and an
integer to select the function, which would be presented as a macro which
wraps the more complex call of the "real" version, so both options are
there if folks decide thy want more control.

Ian


Post a reply to this message

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