POV-Ray : Newsgroups : povray.binaries.images : Basic SDL raymarcher : Re: Basic SDL raymarcher Server Time
5 Nov 2024 16:41:55 EST (-0500)
  Re: Basic SDL raymarcher  
From: Samuel B 
Date: 10 Aug 2023 19:25:00
Message: <web.64d57159884abba8f8c47d526e741498@news.povray.org>
"Samuel B." <stb### [at] hotmailcom> wrote:
> a generic raymarcher in POV-Ray.

Here's another version. I added a surface color, fog color, and shadows. It's
very slow. No antialiasing. A lot of artifacts typical of naive ray marching.
This image parsed very slowly but rendered quickly, finishing at a total of 3
minutes and 33 seconds, with a resolution of only 354x354.

(Why did I do this?)

This is far as I'll take it, because the whole exercise if kind of pointless,
other than to show how flexible POV-Ray's SDL can be.

Sam

/*

BasicRaymarchingB.pov

2023 Sam Benge

Warning! It takes a long time to parse... minutes, even. For faster parsing,
lower the values for Res (start with <32, 32> Also, lower or RaySteps and
LightSteps if needed.

*/

#version 3.7;
global_settings{assumed_gamma 2.2}
#default{ finish{emission 1} }

// linear interpolation function
#macro Mix(A, B, C) A*(1-C) + B*C #end

camera{
 orthographic
 right x up y
 location -z
 look_at 0
}

// distance estimate for sphere and plane (This is the scene's geometry.
DE=signed distance field/function)
#declare DE =
 function{
  min(
   // sphere
   sqrt(x*x+y*y+z*z)-2,

   // plane
   y+2
  )

  // displacement
  + .07*(cos(7*x)+cos(7*y)+cos(7*z))
 }


//~~~ Raymarching Variables ~~~//

//  x & y resolution (later versions of POV-Ray [or maybe just UberPOV] allow
for more than 256 pigment_map entries)
#declare Res = <354, 354>;

// number of camera raymarching steps
#declare RaySteps = 256;

// adjust camera ray step amount (1 is ideal, but some distance estimates
require lower values)
#declare Adj = 0.5;

// number of light steps
#declare LightSteps = 32;

// camera position
#declare RayBeg = <0, 0, -10>;

// light position
#declare LPos = <1, .5, -.3>;

// raymarching bailout threshold
#declare Threshold = 0.001;

// normal accuracy
#declare NAcc = .001;

// object color
#declare ObjCol = <1, .8, .5>;

// fog color
#declare FogCol = <.2, .4, 1>;

// fog distance
#declare FogDist = 20;


//~~~ Rendering ~~~//

// we are only looking at a plane
plane{
 z, 0

 // image is mapped using x & y gradients
 pigment{

  // image uv y gradient
  function{min(1, max(0, y))}
  pigment_map{
   #for(Y, 0, Res.y-1)
    [1/Res.y*Y

     // image uv x gradient
     function{min(1, max(0, x))}
     pigment_map{
      #for(X, 0, Res.x-1)
       [1/Res.x*X

        // initialize Ray
        #local Ray = RayBeg;

        // ray direction
        #local RayDir = vnormalize(<X/Res.x-.5, Y/Res.y-.5, 1>);

        // did the ray hit something?
        // false = (default) no, it didn't hit anything
        // true  = yeah, it hit something
        #local DidHit = false;

        // march the ray through DE
        #for(I, 0, RaySteps-1)

         // functions require all axes to be reduced to single values
         #local RX = Ray.x;
         #local RY = Ray.y;
         #local RZ = Ray.z;

         // value for DE at Ray position
         #local Dist = Adj*DE(RX, RY, RZ);

         // if DE at Ray position is below threshold
         #if(Dist<Threshold)

          // the ray hit something, so we set DidHit to true
          #local DidHit = true;

          // escape the loop because we don't need to trace anything anymore
          #break
         #end

         // advance the ray
         #local Ray = Ray + Dist * RayDir;

        #end

        // did the ray hit something?
        #if(DidHit) // the ray hit something, so we start shading the objects

         // position where the ray hit
         #local Hit = Ray;
         #local HX = Hit.x;
         #local HY = Hit.y;
         #local HZ = Hit.z;

         // initial color
         #local Col = ObjCol;

         // get the surface normal from DE() at hit position
         #local Norm =
          vnormalize(
           <
            DE(HX+NAcc, HY, HZ)-DE(HX-NAcc, HY, HZ),
            DE(HX, HY+NAcc, HZ)-DE(HX, HY-NAcc, HZ),
            DE(HX, HY, HZ+NAcc)-DE(HX, HY, HZ-NAcc)
           >
          );

         // diffuse value
         #local Diffuse = max(0, pow(vdot(Norm, LPos), .75));

         // set initial color
         #local Col = ObjCol;

         // apply diffuse
         #local Col = Col * Diffuse;

         // calculate shadows
         #if(true)
          // light direction
          #local LDir = vnormalize(LPos);

          // initialize light ray (slightly offset from surface)
          #local LRay = Hit + 2 * Threshold * Norm;

          // Is the light shining here? default = true
          #local IsLit = true;

          // march the light ray through DE
          // (not designed to stop after passing through light source)
          #for(I, 0, LightSteps)

           // light ray position is reduced to single values
           #local LX = LRay.x;
           #local LY = LRay.y;
           #local LZ = LRay.z;

           // value for DE at light ray position
           #local LDist = DE(LX, LY, LZ);

           // if light ray hits an object, then no light is shining on this
pixel
           #if(LDist<Threshold)

            // not lit
            #local IsLit = false;

            // escape the loop because we don't need to trace anything anymore
            #break

           #end

           // advance the ray
           #local LRay = LRay + LDist * LDir;

          #end

          // apply shadow
          #local Col = Col * IsLit;

         #end // ~if shadows

         // apply fog (calculation provided from POV docs)
         #local Col = Mix(FogCol, Col, exp(-vlength(RayBeg-Hit)/FogDist));

         // final object color
         rgb Col

        #else // the ray didn't hit anything, so we use the background color

         // background
         rgb FogCol

        #end
       ]
      #end
     }
    ]
   #end
  }

  // center pattern on screen
  translate -.5*(x+y-1/Res)
 }
}


Post a reply to this message


Attachments:
Download 'basicraymarchingb3m_33s.jpg' (59 KB)

Preview of image 'basicraymarchingb3m_33s.jpg'
basicraymarchingb3m_33s.jpg


 

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