POV-Ray : Newsgroups : povray.general : Post something Server Time
2 Apr 2026 19:55:46 EDT (-0400)
  Post something (Message 7 to 16 of 26)  
<<< Previous 6 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Bald Eagle
Subject: Re: Post something
Date: 21 Mar 2026 10:40:00
Message: <web.69beacde4fed62631f9dae3025979125@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:

> "I tried to get Z to work, but never finished it."

Way back when - when I had lots more time to spend several (mostly)
uninterrupted hours working things out, I coded up an animation of the entire
solar system, which mostly astronomically correct.   Plus the asteroid belt.

Everything started out at clock=0, and all the objects were in syzygy.

For all those other folks playing around with such things like orreries, the
important part is adjusting everything for it's specific Mean Anomaly.


January 1, 2000, at 12:00 Terrestrial Time (TT) or Julian Date 2451545.0

Mean anomaly formulation:
M(t) = M0 + 360 * (t - t0)/P
Where:
- M0 : mean anomaly at J2000
- t : POV-Ray clock (years)
- t0 : epoch (0 = J2000)
- P : orbital period (years)

#declare Epoch_J2000 = 0.0;

#declare Mercury_M0 = 174.79253;
#declare Venus_M0   =  50.37663;
#declare Earth_M0   = 357.51716;
#declare Mars_M0    =  19.39020;
#declare Jupiter_M0 =  19.66796;
#declare Saturn_M0  = 317.02070;
#declare Uranus_M0  = 142.28383;
#declare Neptune_M0 = 260.24710;
#declare Pluto_M0   =  14.53;

Moons don't orbit around the sun, and so they need to be adjusted for their
local barycentric framing.


#declare Luna_M0 = 115.3654;

#declare Io_M0       = 171.0168;
#declare Europa_M0   =  67.9876;
#declare Ganymede_M0 =  44.0648;
#declare Callisto_M0 = 259.7088;

#declare Titan_M0     = 186.5855;
#declare Rhea_M0      = 191.9137;
#declare Iapetus_M0   =  79.6900;
#declare Dione_M0     = 131.5349;
#declare Tethys_M0    = 215.1191;
#declare Enceladus_M0 = 268.0502;

#declare Miranda_M0 = 311.33;
#declare Ariel_M0   =  98.35;
#declare Umbriel_M0 = 355.67;
#declare Titania_M0 =  77.82;
#declare Oberon_M0  = 250.96;

#declare Triton_M0 = 328.92;


Post a reply to this message

From: Bald Eagle
Subject: Re: Post something
Date: 21 Mar 2026 14:05:00
Message: <web.69bedd644fed62631f9dae3025979125@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:

> A little coding or math trick.

Writing functions for a pigment {function {}} pattern with a scalar-only
function parser / VM can be painful.

For every vector, I need to evaluate 3 separate functions for each component,
and then when I need to daisy-chain functions together, that multiplies at every
step.

So one of the things I have come up with that makes this a little easier is to
extract the component that I need from the vector, and use select () to choose
which equation I need to evaluate based on a nice little operation.

select is a nice little function that gives me a way to use different equations
given the sign of some variable.
The easy way to remember this is to write select (N, -1, 0, 1).
Depending on the sign of N, I get the sign as the result.
You can put whatever you want in place of the sign when actually using this
mnemonic in practice.

To choose what equation you want would require you to remember that the pattern
is x=-1, y=0, and z=+1
But that's one more thing to forget, so we can make use of the dot product to
generate those values for us from the cardinal axis values themselves.

In POV-Ray, during the parse phase,
            ======================
x = <1, 0, 0>
y = <0, 1, 0>
z = <0, 0, 1>

The dot product takes the respective components of each vector, multiplies them
together, and then adds all the quotients to give a scalar value.

V1.x * V2.x +
V1.y * V2.y +
V1.z * V2.z
-------------
= dot product (V1, V2)

With POV-Ray's x, y, and z vectors, we are only ever multiplying anything by 0
or 1.

So what we do is take vector <-1, 0, 1> and calculate the dot product of that
with x, y, or z.

with x, you get 1 * -1, and the rest are zeros. Sum = -1
with Y, you get 1 *  0, and the rest are zeros. Sum =  0
with z, you get 1 *  1, and the rest are zeros. Sum =  1

This makes it easy to write macros that can take a vector argument and return a
function from a macro or the scalar result of a function from select ().

That's handy when you need to write a bunch of functions for x AND y AND z.
Because you can write a macro to assemble the function based upon which vector
you need.

MyMacro (x)

So you can either use an array of x, y, and z, or manually specify in your code
which one you want, and your intent is unambiguous.

This seems trivial.
It also requires a little bit of work up front to create the functionality, but
it makes handling functions along 3 different axes a lot more easily managed,
especially when you have A LOT of them.

In the macro below, I can assemble functions for each axis by using select() to
grab that vector component from an array using dot notation.  This is
interesting because we're operating in the parser, not the function VM, so we
can use both arrays and dot notation to _construct_ a function.

Those values will remain static - which is fine because those are the vector
components of the control points for the Bezier surface, and don't need to
dynamically change during render phase.

#macro MakeVFn_BezierPatch (_Array, _Component)
// Assembles formula for ONE VECTOR COMPONENT of a Bezier patch
//             (need to run THREE TIMES: once each for x, y, and z)
 #local Degree = dimension_size (_Array, 1)-1;
 function (_U, _V) {
 #for (j, 0, Degree)
  #for (i, 0, Degree)
  #local _P =
                select (_Component, _Array [i][j].x, _Array [i][j].y, _Array
[i][j].z);

  Bernstein(Degree, i, _V) * Bernstein(Degree, j, _U) * _P +
  #end
 #end
 0}  // terminates equation for sum of all Bernstein polynomials in the patch
#end

That's a little snippet from a mammoth .pov file, so below is a self-contained
script that you can read and play with.  A different function is graphed along
each axis without having to specify each axis operation by hand.

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


// Scene file for demonstrating the use of the dot product for
// extracting the relevant vector component of a macro argument
// by converting it to an index value for direct use in select ()
// Bill "Bald Eagle" Walker  2026/03/21

// There are other ways to do this, but this highlights one of the
// MANY uses of the vector dot product.

#version version;
global_settings {assumed_gamma 1.0}


camera {
 location  <1/4, 1, -1/2>*15
 right  x*image_width/image_height
 up   y
 look_at  <0, 0, 0>
}

light_source {<40, 30, -50> rgb 1 shadowless}

sky_sphere {pigment {rgb 1}}

plane {y, 0 pigment {checker rgb 0.1 rgb 0.2} scale 2}

#declare E = 0.000001;
#declare Line = 0.05;
#declare Extent = 10;
#declare Step = 0.1;


#declare Vdot = function (Vx, Vy, Vz, Cx, Cy, Cz) {Vx*Cx + Vy*Cy + Vz*Cz}
#macro DotProduct (V1, V2)
 #local V1x = V1.x;
 #local V1y = V1.y;
 #local V1z = V1.z;
 #local V2x = V2.x;
 #local V2y = V2.y;
 #local V2z = V2.z;
 Vdot (V1x, V1y, V1z, V2x, V2y, V2z)
#end
#declare even = function(x) {select(mod(x, 2), 0, 1, 0)}
#declare odd  = function(x) {select(mod(x, 2), 1, 0, 1)}

#declare Cardinal = array {x, y, z}
#declare Selector = <-1, 0, 1>;
#local ZeroVector = <0, 0, 0>;

#declare FunctionX = function (N) {sqrt(N)}
#declare FunctionY = function (N) {abs(-odd(floor(N))+mod(N, 1))}
#declare FunctionZ = function (N) {sin (N)}
#declare V3 = function (N) {mod (N, 3)}

#declare AxisFunction = function (Switch, N) {
 select (
  Switch,
  FunctionX (N),
  FunctionY (N),
  FunctionZ (N)
 )
}

#for (Axis, 0, 2)
 #local Vector = Cardinal [Axis];
 //===============================================
 #local Component = DotProduct (Vector, Selector);
 //===============================================
 #local Abscissa = Vector;
 #local Ordinate = Cardinal [V3(Axis+1)];

 union {
  #for (i, 0, Extent, Step)
   #local Value = AxisFunction (Component, i);
   #local A = Abscissa * i;
   #local O = Ordinate * Value;
   #local Current = A + O + ZeroVector;
   sphere {Current, Line}
   #if (i > 0)
    cylinder {Last, Current+E Line}
   #end
   #local Last = Current;
  #end
  pigment {rgb Vector}
 }
#end


Post a reply to this message


Attachments:
Download 'axisselection.png' (55 KB)

Preview of image 'axisselection.png'
axisselection.png


 

From: jr
Subject: Re: Post something
Date: 22 Mar 2026 13:45:00
Message: <web.69c029db4fed626348bf72fa6cde94f1@news.povray.org>
hi,

"Bald Eagle" <cre### [at] netscapenet> wrote:
> OK "POV-Ray community,"
>
> Let's make a concerted effort to get some of those things out of your heads and
> off of your hard drives and onto the forum during the next week.
>
> Post something.  It doesn't matter what it is.
> Really.   Just post it.  Here.

good "initiative", thanks.  so, in the spirit :-), attached a "beta" version of
a POV-Ray documentation tool I'm playing with.  it requires version 3.7.0.8
documentation (the HTML files) installed, and a GNU/Linux "box"; Tcl, SQLite3,
BASH.  while I have a 3.8 version too, the code will need revising first to
allow choice of version (at runtime).


enjoy, jr.


Post a reply to this message


Attachments:
Download 'prdq37b.tar.gz' (923 KB)

From: Bald Eagle
Subject: Re: Post something
Date: 22 Mar 2026 17:15:00
Message: <web.69c05ae24fed62631f9dae3025979125@news.povray.org>
I have a small library of periodic waveforms.
Note that it's a practical library, sometimes with different ways of
implementing the same general shape.
Some could be trimmed down.
Some could be expanded by adding named parameters that control the shape.
Having differentiable curves would be useful for people who have need for, and
know what they're doing with that sort of thing.

I know that there are a lot of "smoothing functions" out there for use in
animations,

There are some nice polar equations out there.

These should all be standard tools that we can easily implement in scenes.

// Waveform Equations
// Bill "Bald Eagle" Walker 2026/3/22

#version version;
global_settings {assumed_gamma 1.0}


#declare Zoom = 20;
camera {
 orthographic
 location <10, 19, -50>
 right    x*image_width/Zoom
 up       y*image_height/Zoom
 look_at  <10, 19, 0>
}

light_source {<40, 30, -50> rgb 1 shadowless}

sky_sphere {pigment {rgb 1}}

plane {z, 0.01 pigment {checker rgb 0.9 rgb 0.8}}

#declare Axes =
 union {
  #declare Line = 0.05;
  #declare Base = Line*2;
  #declare Length = 10;
  #declare Ext = 0.25;
  cylinder {<0, 0, 0>, <Length, 0, 0>, Line pigment {rgb x}}
   cone {<Length, 0, 0>, Base, <Length+Ext, 0, 0>, 0 pigment {rgb x} }

  cylinder {<0, 0, 0>, <0, Length, 0>, Line pigment {rgb y}}
   cone {<0, Length, 0>, Base, <0, Length+Ext, 0>, 0 pigment {rgb y}}

  cylinder {<0, 0, 0>, <0, 0, Length>, Line pigment {rgb z}}
   cone {<0, 0, Length>, Base, <0, 0, Length+Ext>, 0 pigment {rgb z}}
 }

//object {Axes}

#declare E = 1e-9;
#declare Inf = 1e10;
#declare Line = 0.08;
#declare Extent = 20;
#declare Step = 0.01;

#declare even = function(N) {select(mod(N, 2), 0, 1, 0)}
#declare odd  = function(N) {select(mod(N, 2), 1, 0, 1)}
#declare sgn  = function(N) {select(N, -1, 0, 1)}
#declare cot = function (N) {1/tan(N)}
#declare sec = function (N) {1/cos(N)}
#declare csc = function (N) {select (sin(N), 1/sin(N), Inf, 1/sin(N))}

#declare Amplitude = 1;
#declare Period = 1;
#declare a = 1;
#declare b = 1;
#declare c = 0;
#declare f = 1;
#declare m = 1;
#declare l = 1;
#declare p = 1;
#declare T = 0.3; // how long pulse wave stays at 1
// capacitor charge-discharge
//
https://www.syncad.com/waveform_block_equations_for_timing_diagram_editors.htm
#declare pns = 0.2;
#declare pps = pns * 10;
#declare rcns = 0.01;
#declare rcps = 10 * rcns;

#declare Sample = function (N) {mod(N, pps/2)}
#declare Charge = function (N) {select (mod(floor(N/(pps/2)),2), 1, 0, 1)}

#declare Waveforms = array {
 function (N) {abs(-odd(floor(N))+mod(N, 1))},
 function (N) {1-(cos(N*pi)*0.5+0.5)},
 function (N) {sqrt(abs(-odd(floor(N))+mod(N, 1)) )},
 function (N) {pow(abs(-odd(floor(N))+mod(N, 1)), 2)},
 function (N) {select (mod(N, 2)-1, 0, 1)},
 function (N) {mod (N, 1)},
 function (N) {(-3*pow(sin(N*3), 2)*sin(N*6))*0.5},
 function (N) {-pow(sin(N*3), 2)*(a*cos(N*6) + b*sin(N*6))},
 //function (N) {-cos(N*3)*(cos(N*6)+sin(N*6))},
 function (N) {sgn (sin (2*pi*f*N))/2+0.5},
 function (N) {-(2*floor(f*N)-floor(2*f*N))},
 function (N) {pow (-1, floor(2*f*N))/2},
 function (N) {(2/pi) * atan (tan (pi*f*N/2)) + (2/pi) * atan (cot (pi*f*N/2))},
 function (N) {(4/p)*(N-(p/2)*floor(2*N/p+0.5))*pow(-1,floor(2*N/p+0.5))},
 function (N) {2*(N/p-floor(0.5+N/p))},
 function (N) {sgn (cos(2*pi*N/p)-cos(pi*T/p)) * 0.5},
 function (N) {select (Charge(N), 0, a*(1-exp(-Sample(N)/rcps)),
a*exp(-Sample(N)/rcps) )},
 function (N) {(a/pi) * (asin(sin((pi/m)*N+l)) + acos(cos((pi/m)*N+l))) - (a/2)
+ c},
 function (N) {pow(-1, floor(N/2))*sqrt (1-pow((mod(N,2)-1),2))}
};

#declare NF = dimension_size (Waveforms, 1)-1;

#declare Abscissa = x;
#declare Ordinate = y;
// Applicate: The z-coordinate (the last of the three terms by which a point is
referred to,
// in a system of Cartesian coordinates for a three-dimensional space)
#local ZeroVector = <0, 0, 0>;

#for (F, 0, NF)
 #ifdef(Function) #undef Function #end
 #local Function = Waveforms [F];
 //#debug concat ("F = ", str(F, 0, 0), "\n")
 #local Shift_Y = y*F*2;
 cylinder {<0, F*2, 0>, <Extent, F*2, 0> Line*0.75 pigment {checker rgb x rgbf 1
scale 0.25}}
 union {
  #for (i, 0, Extent, Step)
   #local Value = Function (i);
   #local A = Abscissa * i;
   #local O = Ordinate * Value + Shift_Y;
   #local Current = A + O + ZeroVector;
   sphere {Current, Line}
   #if (i > 0)
    cylinder {Last, Current+E Line}
   #end
   #local Last = Current;
  #end
  pigment {rgb 0}
 }
#end

text { ttf "arial.ttf", "Waveform Equations     Bald Eagle 2026/3/22", 0.02, 0.0
pigment {rgb z*0.4} translate y*(F)*2}


Post a reply to this message


Attachments:
Download 'waveforms.png' (145 KB)

Preview of image 'waveforms.png'
waveforms.png


 

From: Josh English
Subject: Re: Post something
Date: 22 Mar 2026 19:29:06
Message: <69c07b42@news.povray.org>
On 3/20/2026 4:21 PM, Bald Eagle wrote:
> OK "POV-Ray community,"
> 
> Let's make a concerted effort to get some of those things out of your heads and
> off of your hard drives and onto the forum during the next week.
> 
> Post something.  It doesn't matter what it is.
> Really.   Just post it.  Here.
> 

I've been on-and-off playing with creating cities on the irregular grids 
I was playing with last year.

Buildings align to the "roads" defined by the grid.


Post a reply to this message


Attachments:
Download 'fillrect.png' (66 KB)

Preview of image 'fillrect.png'
fillrect.png


 

From: laser
Subject: Re: Post something
Date: 23 Mar 2026 11:15:00
Message: <web.69c157d44fed6263b5e70e3d617a575b@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:

> Post something.  It doesn't matter what it is.
> Really.   Just post it.  Here.
>

I'm modifying a compiler I wrote that was for an assignment in my compilers
college course many years ago.  I've expanded the grammar to be a fully usable
language rather than a "toy" language.  So, of course, I just had to create a
raytracer for it.  Here's the source code written in my language:

{
/* Integer loop + shading vars */
i_x = 0; i_y = 0;
i_shade = 0;
i_check = 0;
i_mod2 = 0;

/* Camera origin */
f_sx = 0.0; f_sy = 0.1; f_sz = 5.5;

/* Light direction (will normalize) */
#f_lx = -2.0; f_ly = 3.0; f_lz = -1.0;
f_lx = -2.0; f_ly = 3.0; f_lz = 2.0;

/* Ray direction */
f_dx = 0.0; f_dy = 0.0; f_dz = 0.0;

/* 2nd Sphere position */
f_sp_x = 1.75; f_sp_y = 0.0; f_sp_z = -2.0;

/* Sphere radiuses */
f_sp1_r = 1.2; f_sp2_r = 0.6;

/* Sphere intersection */
f_b = 0.0; f_c = 0.0; f_disc = 0.0; f_t = 0.0;

/* plane height */
f_ply = -1.6;

/* Normals and points */
f_nx = 0.0; f_ny = 0.0; f_nz = 0.0;
f_px = 0.0; f_py = 0.0; f_pz = 0.0;

/* Helpers */
f_len = 0.0; f_dot = 0.0; f_spec = 0.0; f_tmp = 0.0;
f_fx = 0.0; f_fz = 0.0;

/* Shadow ray vars */
f_sdx = 0.0; f_sdy = 0.0; f_sdz = 0.0;
f_tb = 0.0; f_tc = 0.0; f_tdisc = 0.0; f_tshadow = 0.0;

/* Normalize light direction once */
f_len = sqrt(f_lx*f_lx + f_ly*f_ly + f_lz*f_lz);
f_lx = f_lx / f_len; f_ly = f_ly / f_len; f_lz = f_lz / f_len;

f_aspect = 1.0;

print "P6\n640 480\n255\n";
/* Image loop */
for i_y = -240 to 239 do
 {
 for i_x = -320 to 319 do
  {
  /* Ray direction from camera through pixel */
  f_dx = float(i_x) / 490.0;
  f_dy = -float(i_y) * f_aspect / 490.0;
  f_dz = -1.0;

  /* Normalize ray direction */
  f_len = sqrt(f_dx*f_dx + f_dy*f_dy + f_dz*f_dz);
  f_dx = f_dx / f_len;
  f_dy = f_dy / f_len;
  f_dz = f_dz / f_len;

  /* Sphere intersection: center at (0,0,0), radius 1.2 */
  f_tx = f_sx;
  f_ty = f_sy;
  f_tz = f_sz;
  f_b = 2.0 * (f_dx*f_tx + f_dy*f_ty + f_dz*f_tz);
  f_c = f_tx*f_tx + f_ty*f_ty + f_tz*f_tz - f_sp1_r;

  f_disc = f_b*f_b - 4.0*f_c;

  if f_disc >= 0.0 then
   {
   /* Hit sphere: nearest t */
   f_t = (-f_b - sqrt(f_disc)) / 2.0;
   if f_t <= 0.0 then
    {
    /* Behind camera: treat as no sphere hit, fall through */
    f_disc = -1.0;
    }
   else
    {
    f_obj_red = 0.9;
    f_obj_green = 0.9;
    f_obj_blue = 0.0;
    }
   }

  /* Sphere intersection: center at (f_sp_x,f_sp_y,f_sp_z), radius .6 */
  f_tx2 = f_sx - f_sp_x;
  f_ty2 = f_sy - f_sp_y;
  f_tz2 = f_sz - f_sp_z;
  f_b = 2.0 * (f_dx*f_tx2 + f_dy*f_ty2 + f_dz*f_tz2);
  f_c = f_tx2*f_tx2 + f_ty2*f_ty2 + f_tz2*f_tz2 - f_sp2_r;

  f_disc2 = f_b*f_b - 4.0*f_c;

  if f_disc2 >= 0.0 then
   {
   /* Hit sphere: nearest t */
   f_t2 = (-f_b - sqrt(f_disc2)) / 2.0;
   if f_t2 > 0.0 then
    {
    b_sp1=(f_disc<0.0); #(f_t<0.0); /* boolean */
    b_sp2=(f_t2<f_t); /* boolean */
    if b_sp1+b_sp2 then /* boolean + = or */
     {
     f_obj_red = 0.0;
     f_obj_green = 0.9;
     f_obj_blue = 0.0;
     f_disc = f_disc2;
     f_t = f_t2;
     f_tx = f_tx2;
     f_ty = f_ty2;
     f_tz = f_tz2;
     }
    }
   }

  if f_disc < 0.0 then
   {
   /* No sphere hit: try ground plane y = -1.6 */

   if f_dy == 0.0 then
    {
    /* Ray parallel to plane: background */
    printc 0;
    printc 90;
    printc 130;
    }
   else
    {
    f_t = (f_ply - f_sy) / f_dy;
    if f_t <= 0.0 then
     {
     /* Plane behind camera */
     printc 0;
     printc 90;
     printc 130;
     }
    else
     {
     /* Hit point on plane */
     f_px = f_sx + f_dx*f_t;
     f_py = f_ply;
     f_pz = f_sz + f_dz*f_t;

     /* Checkerboard: floor(px), floor(pz) using int */
     f_fx = float(int(f_px));
     if f_px < 0.0 then f_fx = f_fx - 1.0;

     f_fz = float(int(f_pz));
     if f_pz < 0.0 then f_fz = f_fz - 1.0;

     i_check = (int(f_fx + f_fz)) % 2;
     if (i_check == 0) then { f_red=0.75; f_green=0.0; f_blue=0.0; }
     else { f_red=0.75; f_green=0.75; f_blue=0.75; }

     /* Shadow from sphere onto plane:
     cast ray from plane point toward light,
     check if it hits sphere before light. */

     f_sdx = f_lx;
     f_sdy = f_ly;
     f_sdz = f_lz;

     /* Sphere intersection from plane point:
     ray: P + t*L, sphere at origin, radius 1 */

     f_tb = 2.0 * (f_sdx*f_px + f_sdy*f_py + f_sdz*f_pz);
     f_tc = f_px*f_px + f_py*f_py + f_pz*f_pz - f_sp1_r;
     f_tdisc = f_tb*f_tb - 4.0*f_tc;

     if f_tdisc > 0.0 then
      {
      f_tshadow = (-f_tb - sqrt(f_tdisc)) / 2.0;
      if f_tshadow > 0.0 then
       {
       /* In shadow: darken */
       f_red = f_red * 0.5;
       f_green = f_green * 0.5;
       f_blue = f_blue * 0.5;
       }
      }

     f_tx = f_px - f_sp_x;
     f_ty = f_py - f_sp_y;
     f_tz = f_pz - f_sp_z;

     f_tb = 2.0 * (f_sdx*f_tx + f_sdy*f_ty + f_sdz*f_tz);
     f_tc = f_tx*f_tx + f_ty*f_ty + f_tz*f_tz - f_sp2_r;
     f_tdisc = f_tb*f_tb - 4.0*f_tc;

     if f_tdisc > 0.0 then
      {
      f_tshadow = (-f_tb - sqrt(f_tdisc)) / 2.0;
      if f_tshadow > 0.0 then
       {
       /* In shadow: darken */
       f_red = f_red * 0.5;
       f_green = f_green * 0.5;
       f_blue = f_blue * 0.5;
       }
      }

     i_red=int(f_red * 255.0);
     i_green=int(f_green * 255.0);
     i_blue=int(f_blue * 255.0);

     if i_red < 0 then i_red = 0;
     if i_red > 255 then i_red = 255;
     if i_green < 0 then i_green = 0;
     if i_green > 255 then i_green = 255;
     if i_blue < 0 then i_blue = 0;
     if i_blue > 255 then i_blue = 255;

     printc i_red;
     printc i_green;
     printc i_blue;
     }
    }
   }
  else
   {
   /* Sphere shading */

   /* Hit point */
   f_px = f_tx + f_dx*f_t;
   f_py = f_ty + f_dy*f_t;
   f_pz = f_tz + f_dz*f_t;

   /* Normal at sphere */
   f_nx = f_px;
   f_ny = f_py;
   f_nz = f_pz;

   f_len = sqrt(f_nx*f_nx + f_ny*f_ny + f_nz*f_nz);
   f_nx = f_nx / f_len;
   f_ny = f_ny / f_len;
   f_nz = f_nz / f_len;

   /* Diffuse term */
   f_dot = f_nx*f_lx + f_ny*f_ly + f_nz*f_lz;
   if f_dot < 0.0 then f_dot = 0.0;

   /* Specular: reflection of light around normal, dotted with view dir (-ray)
*/
   f_tmp = 2.0 * f_dot;
   f_fx = f_tmp*f_nx - f_lx;
   f_fz = f_tmp*f_nz - f_lz;
   f_len = f_tmp*f_ny - f_ly;  /* reuse f_len as ry */

   /* view dir is -ray: (-dx, -dy, -dz) */
   f_spec = f_fx*(-f_dx) + f_len*(-f_dy) + f_fz*(-f_dz);
   if f_spec < 0.0 then f_spec = 0.0;
   f_spec = f_spec * f_spec;

   /* Combine diffuse + specular + small ambient */
   f_dot = 0.12 + .6*f_dot + 0.3*f_spec;

   if f_dot < 0.0 then f_dot = 0.0;
   if f_dot > 1.0 then f_dot = 1.0;

   i_red = int(f_obj_red * f_dot * 255.0);
   i_green = int(f_obj_green * f_dot * 255.0);
   i_blue = int(f_obj_blue * f_dot * 255.0);

   if i_red < 0 then i_red = 0;
   if i_red > 255 then i_red = 255;
   if i_green < 0 then i_green = 0;
   if i_green > 255 then i_green = 255;
   if i_blue < 0 then i_blue = 0;
   if i_blue > 255 then i_blue = 255;

   printc i_red;
   printc i_green;
   printc i_blue;
   }
  }
 }
}

There are no specific variable type declarations.  The type is based on the
first letter of the variable (i for integer, f for floating point, s for string,
and b for boolean).
# are line comments and /* */ are comment blocks.  The resulting compiled
x86/x64 program (either Windows or Linux) outputs a PPM (netpbm) image file.
The code is not that great because I haven't fully implemented functions (so no
recursion), and there's no pointers, no structs, and no arrays.  Here's the
resulting image:


Post a reply to this message


Attachments:
Download 'rayout.png' (18 KB)

Preview of image 'rayout.png'
rayout.png


 

From: Bald Eagle
Subject: Re: Post something
Date: 23 Mar 2026 13:45:00
Message: <web.69c17b454fed62636750f02625979125@news.povray.org>
"laser" <nomail@nomail> wrote:

> I'm modifying a compiler I wrote that was for an assignment in my compilers
> college course many years ago.  I've expanded the grammar to be a fully usable
> language rather than a "toy" language.  So, of course, I just had to create a
> raytracer for it.

Excellent.
Curious what you do professionally?

Have you seen the raytracer that you can write in SDL?
I've done about 3 different versions of that so far.

- BE


Post a reply to this message

From: jr
Subject: Re: Post something
Date: 23 Mar 2026 16:30:00
Message: <web.69c1a2084fed626348bf72fa6cde94f1@news.povray.org>
"jr" <cre### [at] gmailcom> wrote:
> ...
> a POV-Ray documentation tool I'm playing with.  it requires version 3.7.0.8
> documentation (the HTML files) installed, ...

link to an archive with a copy of my 'povray-3.7.0.8' docs, in case :-)

<drive.google.com/file/d/1ZN8ZHOi5x6GWfSATUtcgrMtsO2ochFRw/view?usp=sharing>


regards, jr.


Post a reply to this message

From: laser
Subject: Re: Post something
Date: 24 Mar 2026 12:05:00
Message: <web.69c2b50a4fed6263b5e70e3d617a575b@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:
> "laser" <nomail@nomail> wrote:
>
> > I'm modifying a compiler I wrote that was for an assignment in my compilers
> > college course many years ago.  I've expanded the grammar to be a fully usable
> > language rather than a "toy" language.  So, of course, I just had to create a
> > raytracer for it.
>
> Excellent.
> Curious what you do professionally?
>
> Have you seen the raytracer that you can write in SDL?
> I've done about 3 different versions of that so far.
>
> - BE

Thanks.  I'm a programmer, but compiler writing is definitely outside of the
range of my normal coding,  Though configuration script (and similar) writing
(and therefore designing the script language) isn't (but that's interpreted not
compiled).

I probably have seen the raytracer you mention, but I can't quite remember what
it was like right now.  I mostly go right to the "Image Digest" and don't always
read the posts (but I do see your name a lot :-) )

If you're interested in seeing some of my work, etc. you can see examples on my
youtube channel (lot's of tutorials now, and also my earlier videos are
raytracings.  I only have 42 videos so it's not hard to look through the whole
channel):  http://www.youtube.com/MrMcSoftware/videos

An x86 assembly raytracer (different than the one I posted an image of) I coded
is covered in my assembly language videos and a little bit in my "My Projects:
Pathtracing, Raytracer (x86 Assembly, Amiga, Linux & Windows), Tesla Coil Use &
More" video,  This raytracer was based on my assembly raytracer for a CPU I
designed - it first appeared in my "My Logisim CPU / Computer - Now With
Floating Point (FPU) (Fractals, Raytracer, Etc.)" video.  And a GLSL version of
this raytracer is at my shadertoy page:
https://www.shadertoy.com/user/mrmcsoftware (I think that link will provide a
link to it).  Sorry to do so much promoting, but it's all along the same lines
of coding a raytracer in an unorthodox way.


Post a reply to this message

From: laser
Subject: Re: Post something
Date: 24 Mar 2026 18:35:00
Message: <web.69c311074fed6263b5e70e3d617a575b@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:
> "laser" <nomail@nomail> wrote:
>
> > I'm modifying a compiler I wrote that was for an assignment in my compilers
> > college course many years ago.  I've expanded the grammar to be a fully usable
> > language rather than a "toy" language.  So, of course, I just had to create a
> > raytracer for it.
>
> Excellent.
> Curious what you do professionally?
>
> Have you seen the raytracer that you can write in SDL?
> I've done about 3 different versions of that so far.
>
> - BE

I'm a programmer.  A compiler is outside of my normal range of coding, though I
have written various configuration (and similar) scripting languages (but that's
interpreted not compiled).

I probably have seen the raytracer you mention, but I can't quite remember what
it was like right now.  I mostly go right to "Image Digest" and don't always
read the posts (but I have seen your name often :-) )

If you want to see some of the stuff I've done, you can see some examples on my
youtube channel (mostly tutorials lately, and my earlier videos contain many
raytracings) (my channel only has 42 videos, so it wouldn't take long to look
through): <www.youtube.com/MrMcSoftware/videos>

An x86 assembly raytracer I wrote (not the one I first posted about) is covered
in my assembly language videos and a little bit in my "My Projects: Pathtracing,
Raytracer (x86 Assembly, Amiga, Linux & Windows), Tesla Coil Use & More" video -
it was based on my assembly raytracer I wrote for a CPU I designed and first
appeared in my video "My Logisim CPU / Computer - Now With Floating Point (FPU)
(Fractals, Raytracer, Etc.)".  And a GLSL version can be viewed on my shadertoy
page: <www.shadertoy.com/user/mrmcsoftware>
Sorry about all the self-promoting, but they all are along the same lines we're
talking about - unorthodox ways of doing raytracing.


Post a reply to this message

<<< Previous 6 Messages Goto Latest 10 Messages Next 10 Messages >>>

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