POV-Ray : Newsgroups : povray.general : What to do with the pixel in the middle Server Time
21 Dec 2024 21:22:52 EST (-0500)
  What to do with the pixel in the middle (Message 1 to 10 of 13)  
Goto Latest 10 Messages Next 3 Messages >>>
From: ingo
Subject: What to do with the pixel in the middle
Date: 1 Feb 2019 16:34:36
Message: <XnsA9E9E5AA556F3seed7@news.povray.org>
Tinkering with various user defined cameras I often seem to run into the 
following; using select in a function you either select bigger smaller or 
bigger and equal or smaller:

from a stereo cam:
#local D2_X_Fn = function(u,v){
  select(
    (u<=0),   //u<0????
    -1,
    D1R_X_Fn((u/AspectU*image_width)-0.25,v),
    D1L_X_Fn((u/AspectU*image_width)+0.25,v)
  )
};

the alternative is select only smaller or bigger resulting in a pixel wide 
black line.

So, what to do with the pixel in the middle? Another select with u=0?

ingo


Post a reply to this message

From: Bald Eagle
Subject: Re: What to do with the pixel in the middle
Date: 1 Feb 2019 17:05:01
Message: <web.5c54c166738ba468765e06870@news.povray.org>
ingo <ing### [at] tagpovrayorg> wrote:

> from a stereo cam:
> #local D2_X_Fn = function(u,v){
>   select(
>     (u<=0),   //u<0????
>     -1,
>     D1R_X_Fn((u/AspectU*image_width)-0.25,v),
>     D1L_X_Fn((u/AspectU*image_width)+0.25,v)
>   )
> };
>
> the alternative is select only smaller or bigger resulting in a pixel wide
> black line.
>
> So, what to do with the pixel in the middle? Another select with u=0?




Well, that's a pretty interestingly constructed select() function.

I would have done away with the Boolean operator and the semicolon.
I don't think the one you're using ever results in a <0 value for select() to
operate on, since the boolean operator only returns 0 or 1.
So just to keep myself sane during debugging, I'd write it like:

#local D2_X_Fn = function(u,v){
     select (u,
          D1L_X_Fn ((u/AspectU*image_width)+0.25,v))  // u <  0
          D1R_X_Fn ((u/AspectU*image_width)-0.25,v))  // u >= 0
     )
}

I guess if you wanted that one-pixel wide strip at the center to use the other
function, then you'd use the 4-argument version and repeat the first function
for the u = 0 case.



Hopefully at some point you can share some of your understanding of the
user-defined camera with a few simple explanatory examples / tutorials.


Post a reply to this message

From: ingo
Subject: Re: What to do with the pixel in the middle
Date: 1 Feb 2019 18:15:37
Message: <XnsA9EA2A6B5B0Dseed7@news.povray.org>
in news:web.5c54c166738ba468765e06870@news.povray.org Bald Eagle wrote:

> I guess if you wanted that one-pixel wide strip at the center to use
> the other function, then you'd use the 4-argument version and repeat
> the first function for the u = 0 case.
> 

Bill, 
on an almost "aside way" you explain me that things can be done simpler 
and then ask:

> Hopefully at some point you can share some of your understanding of
> the user-defined camera with a few simple explanatory examples /
> tutorials. 

in the land of 'nikked' eagles one feather ain't king ;)

but seriously, I almost exclusivly use the 4 term select as:
select(query, ignore(=-1), true, false)

Regarding the pixel in the middle, where does it belong ??? In case of a 
stereo cam, the left or right side of the image, there is no in between?

User defined cameras are great, just starting to explore them, but ...

they are indeed rather under documented. It's hard to understand what 
exactly happens, but once I get it I'm willing to do a write up (to be 
corrected by the ones that realy understand). An other thing is that they 
seem to be "verbose". When I try to reimplement an existing 10 line of c++ 
code cam it seems I need at least 5 times more space. It requires a lot of 
trials and mostley errors as I have a hard time wrapping my brain around 
some things and my brain isn't very structured, more intuitive.

User defined cameras are great, just starting to explore them, but ...

Ray tracing is about rays, objects an cameras and I realy think POV-Ray 
deserves a whealthy choise of ready made cameras. Paul Bourke has defined 
a very nice set of stereo cameras a decade ago that I.M.H.O would be very 
welcome in an official distribution. Le Forgeron, as I discovered today, 
has made a set of _/incredible and bewildering/_ set of 'planet mapping' 
camera's. The https://www.cartographersguild.com would love them (/him for 
that), they do not seem to have discovered them yet. Let's not forget 
Fabrizio's (Clodi) OSD camera.

ingo


Post a reply to this message

From: ingo
Subject: Re: What to do with the pixel in the middle
Date: 1 Feb 2019 18:33:31
Message: <XnsA9EA5AF9A331seed7@news.povray.org>
in news:XnsA9EA2A6B5B0Dseed7@news.povray.org ingo wrote:

> they seem to be "verbose"

A dense stereo cam file for example. Sanity check before serious use,

ingo

---%<------%<------%<---
#version 3.8;
global_settings{ assumed_gamma 1.0 }

#include "math.inc"
#include "transforms.inc"
//#include "udCameras.inc"

#macro udcLookAtTransform(
    D0_X_Fn, D0_Y_Fn, D0_Z_Fn,
    pLocation, pLookAt, Angle,
    optional Roll, optional vDirection,
    optional vRight, optional vUp
  )
  /*==
  Transforms the direction function of a user defined camera to look into 
the
  pLookAt direction from the camera location.
  
  Code base by: Tor Olav Kristensen, http://subcube.com
  This macro is intended to be used in user defined cameras. 
  For example use, see udcPerspective().
  
  D0_X_Fn, D0_Y_Fn, D0_Z_Fn (function): the original camera direction 
functions.
  pLocation  (vec) : the location of the camera
  pLookAt    (vec) : the point to look at
  Angle    (float) : horizontal field of view o view angle
  Roll     (float) : optional, defaults to 0. 
                     Roll, a.k.a. banking, rotates the camera around the 
view 
                     direction vector.
  vDirection (vec) : optional, defaults to +z.
  vRigth     (vec) : optional, defaults to 
<image_width/image_height,0,0>.
  vUp        (vec) : optional, defaults to +y.
  */
  #ifndef(local.Roll)
    #local Roll = 0;
  #end
  #ifndef(local.vDirection)
    #local vDirection = +1*z;
  #end
  #ifndef(local.vRight)
      #local vRight = +image_width/image_height*x;
  #end
  #ifndef(local.vUp)
    #local vUp = +1*y;
  #end
  #local vLookAt = pLookAt - pLocation;
  #local LookAtTransform = transform{
    Reorient_Trans(z, vLookAt)
    Axis_Rotate_Trans(vLookAt, Roll)
  }
  #local vDirection_1 = vtransform(vDirection, LookAtTransform);
  #local vRight_1 = vtransform(vRight, LookAtTransform);
  #local vUp_1 = vtransform(vUp, LookAtTransform);
  #local <X1_X, X1_Y, X1_Z> = vtransform(x, LookAtTransform);
  #local <Y1_X, Y1_Y, Y1_Z> = vtransform(y, LookAtTransform);
  #local <Z1_X, Z1_Y, Z1_Z> = vtransform(z, LookAtTransform);
  #local D1_X_Fn = function(u,v){
    0
    + X1_X*D0_X_Fn(u,v)
    + Y1_X*D0_Y_Fn(u,v)
    + Z1_X*D0_Z_Fn(u,v)
  };
  #local D1_Y_Fn = function(u,v){
    0
    + X1_Y*D0_X_Fn(u, v)
    + Y1_Y*D0_Y_Fn(u, v)
    + Z1_Y*D0_Z_Fn(u, v)
  };
  #local D1_Z_Fn = function(u,v){
    0
    + X1_Z*D0_X_Fn(u, v)
    + Y1_Z*D0_Y_Fn(u, v)
    + Z1_Z*D0_Z_Fn(u, v)
  };
  (D1_X_Fn, D1_Y_Fn, D1_Z_Fn)
#end

#macro udcStereo(pLocation,pLookAt,Angle,FocalDist)
  //http://paulbourke.net/stereographics/stereorender/
  #local EyeSep = FocalDist/30;
  #local Delta  = (image_width*EyeSep)/(2*FocalDist*tand(Angle/2));
  #local Angle1 = 2*atand((image_width+Delta)*tand(Angle/2)/image_width);
  #local AspectU = image_width+Delta+Delta;
  #local AspectV = image_height;
  #local vMovement  = EyeSep/2*vnormalize(vcross(pLookAt-pLocation,
<0,1,0>));
  #local pLocationL = pLocation+vMovement;
  #local pLocationR = pLocation-vMovement;
  #local <LocationXL, LocationYL, LocationZL> = pLocationL;
  #local <LocationXR, LocationYR, LocationZR> = pLocationR;
  #local LocationX = function(u){select((u<=0),-1, LocationXR, 
LocationXL)};
  #local LocationY = function(u){select((u<=0),-1, LocationYR, 
LocationYL)};
  #local LocationZ = function(u){select((u<=0),-1, LocationZR, 
LocationZL)};
  #local D0_X_Fn = function(u,v){u*AspectU};
  #local D0_Y_Fn = function(u,v){v*AspectV};
  #local D0_Z_Fn = function(u,v){AspectU/2/tand(Angle/2)};
  #local pLookAtL = pLookAt+vMovement;
  #local pLookAtR = pLookAt-vMovement;
  #local(D1L_X_Fn, D1L_Y_Fn, D1L_Z_Fn) = udcLookAtTransform(
    D0_X_Fn, D0_Y_Fn, D0_Z_Fn, pLocationL, pLookAtL, Angle1,,,,
  );
  #local(D1R_X_Fn, D1R_Y_Fn, D1R_Z_Fn) = udcLookAtTransform(
    D0_X_Fn, D0_Y_Fn, D0_Z_Fn, pLocationR, pLookAtR, Angle1,,,,
  );
  #local D2_X_Fn = function(u,v){select(
    (u<=0),
    -1, 
    D1R_X_Fn((u/AspectU*image_width)-0.25,v), 
    D1L_X_Fn((u/AspectU*image_width)+0.25,v)
  )};
  #local D2_Y_Fn = function(u,v){select((u<=0),-1, D1R_Y_Fn(u-0.25,v), 
D1L_Y_Fn(u+0.25,v))};
  #local D2_Z_Fn = function(u,v){select((u<=0),-1, D1R_Z_Fn(u-0.25,v), 
D1L_Z_Fn(u+0.25,v))};
  camera {
    user_defined
    location {
      function {LocationX(u)}
      function {LocationY(u)}
      function {LocationZ(u)}
    }
    direction {
      function {D2_X_Fn(u,v)}
      function {D2_Y_Fn(u,v)}
      function {D2_Z_Fn(u,v)}
    }
  }
#end

#declare ZeroParallax = 3;
udcStereo(<0,0,-ZeroParallax>,<0,0,0>,55,ZeroParallax)
light_source{< 1000,1000,-1000>, rgb 1}
light_source{<-1000,1000,-1000>, rgb .3}
difference{
  box{-0.5,0.5 pigment{rgb 1}}
  box{-0.5,0.5 scale <0.97,0.97,1.20>}
  box{-0.5,0.5 scale <0.97,1.20,0.97>}
  box{-0.5,0.5 scale <1.20,0.97,0.97>}
}
sphere{<0,-0.2,-1>,0.035 pigment{rgb z}}
sphere{<0,0.2,10>,0.03 pigment{rgb 1}}
plane{y,-1.5 pigment{checker}}
plane{z,20 pigment{function{abs(y)} scale 12 translate<0,-1.5,0>}}
sphere{<0, 0.0, 0>,0.03 pigment{rgb y}}


Post a reply to this message

From: Bald Eagle
Subject: Re: What to do with the pixel in the middle
Date: 1 Feb 2019 20:40:01
Message: <web.5c54f447738ba468765e06870@news.povray.org>
ingo <ing### [at] tagpovrayorg> wrote:
> in news:web.5c54c166738ba468765e06870@news.povray.org Bald Eagle wrote:
>
> > I guess if you wanted that one-pixel wide strip at the center to use
> > the other function, then you'd use the 4-argument version and repeat
> > the first function for the u = 0 case.
> >
>
> Bill,
> on an almost "aside way" you explain me that things can be done simpler

Well, it's not "simpler" - it's just more straightforward for the easily
confused such as me.   :P


> but seriously, I almost exclusivly use the 4 term select as:
> select(query, ignore(=-1), true, false)

Well, whatever works for you, if you use it consistently without problems - go
for it.

> Regarding the pixel in the middle, where does it belong ??? In case of a
> stereo cam, the left or right side of the image, there is no in between?

Nope.  I suppose you could do the calculations and find out where to shift the
camera so that it's "1 pixel" over one way or the other, and then adjust for
that...
Can you check and see if abs (u) > epsilon so that you can filter out a lot of
"0" results...?


> they are indeed rather under documented. It's hard to understand what
> exactly happens, but once I get it I'm willing to do a write up (to be
> corrected by the ones that realy understand).

Sure, I think the idea is to just post some reasonably well commented code, that
we can look at when we want to implement a similar camera structure, and if
necessary, supplement with some renders, drawings, etc.

> An other thing is that they
> seem to be "verbose". When I try to reimplement an existing 10 line of c++
> code cam it seems I need at least 5 times more space. It requires a lot of
> trials and mostley errors as I have a hard time wrapping my brain around
> some things and my brain isn't very structured, more intuitive.

I seem to be able to teach myself what I need to know faster when I try to
explain the problem I'm having, or when I try to condense it down into a macro
or a formula.


> Ray tracing is about rays, objects an cameras and I realy think POV-Ray
> deserves a whealthy choise of ready made cameras. Paul Bourke has defined
> a very nice set of stereo cameras a decade ago that I.M.H.O would be very
> welcome in an official distribution.

I think there's a LOT of Bourke's work that ought to be readily available and
used a lot more, and even implemented under the hood in C++ so that it's not
stuck in super-slow SDL.

> Le Forgeron, as I discovered today,
> has made a set of _/incredible and bewildering/_ set of 'planet mapping'
> camera's.

Jerome is a really intelligent, inventive, and hard-working guy, and I wish I
had more time to sit down and play with all of the goodies he has coded up over
the years.

> The https://www.cartographersguild.com would love them (/him for
> that), they do not seem to have discovered them yet.

Yet another forum to advertise the wonders of POV-Ray in   :)

> Let's not forget
> Fabrizio's (Clodi) OSD camera.

I have not (yet) heard of that.
Aha -
http://news.povray.org/povray.general/thread/%3Cweb.56d38071f91c97bb4e8811590%40news.povray.org%3E/?mtop=406634

(Clodo)


Post a reply to this message

From: clipka
Subject: Re: What to do with the pixel in the middle
Date: 1 Feb 2019 21:21:14
Message: <5c54fe9a$1@news.povray.org>
Am 02.02.2019 um 00:15 schrieb ingo:

> Regarding the pixel in the middle, where does it belong ??? In case of a
> stereo cam, the left or right side of the image, there is no in between?

That is a fundamental problem - but if you think about it, it's not 
specific to user-defined stereo cameras, but to stereo images with an 
odd number of pixels.

An even-numbered pixel image does not have any pixel at the center - it 
has a _pixel border_ at the center.


Post a reply to this message

From: ingo
Subject: Re: What to do with the pixel in the middle
Date: 2 Feb 2019 03:08:57
Message: <XnsA9EA5D1365E05seed7@news.povray.org>
in news:5c54fe9a$1@news.povray.org clipka wrote:

> think about it

The back pixel in the middle makes sense,

thanks,

ingo


Post a reply to this message

From: ingo
Subject: Re: What to do with the pixel in the middle
Date: 2 Feb 2019 03:15:34
Message: <XnsA9EA5E327FBDEseed7@news.povray.org>
in news:web.5c54f447738ba468765e06870@news.povray.org Bald Eagle wrote:

> I seem to be able to teach myself what I need to know faster when I
> try to explain the problem I'm having, or when I try to condense it
> down into a macro or a formula.
> 

"literate programming" (http://www.literateprogramming.com/)

On most stuff I do I just start with writing down the story, then add 
snippets of code and slowly condense the story into code.

ingo


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: What to do with the pixel in the middle
Date: 2 Feb 2019 13:35:00
Message: <web.5c55e1be738ba468c143b2b0@news.povray.org>
ingo <ing### [at] tagpovrayorg> wrote:
> in news:5c54fe9a$1@news.povray.org clipka wrote:
>
> > think about it
>
> The back pixel in the middle makes sense,

To achieve this you can make the camera look another way when u equals zero,
e.g. like this:

direction {
    function {
        select(
            u,
            D1L_X_Fn(u*image_width/AspectU + 0.25, v),
            0,
            D1R_X_Fn(u*image_width/AspectU - 0.25, v)
       )
    }
    function {
        select(
            u,
            D1L_Y_Fn(u + 0.25, v),
            1,
            D1R_Y_Fn(u - 0.25, v)
        )
    }
    function {
        select(
            u,
            D1L_Z_Fn(u + 0.25, v),
            0,
            D1R_Z_Fn(u - 0.25, v)
        )
    }
}

- and then place something small with a black pigment, no_shadow and
no_reflection close to the camera in that direction (e.g. right above the
camera).

--
Tor Olav
http://subcube.com


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: What to do with the pixel in the middle
Date: 2 Feb 2019 14:45:00
Message: <web.5c55f204738ba468c143b2b0@news.povray.org>
ingo <ing### [at] tagpovrayorg> wrote:
> in news:XnsA9EA2A6B5B0Dseed7@news.povray.org ingo wrote:
>...
> #macro udcLookAtTransform(
>     D0_X_Fn, D0_Y_Fn, D0_Z_Fn,
>     pLocation, pLookAt, Angle,
>     optional Roll, optional vDirection,
>     optional vRight, optional vUp
>   )
>   /*==
>   Transforms the direction function of a user defined camera to look into
> the
>   pLookAt direction from the camera location.
>
>   Code base by: Tor Olav Kristensen, http://subcube.com
>   This macro is intended to be used in user defined cameras.
>   For example use, see udcPerspective().
>
>   D0_X_Fn, D0_Y_Fn, D0_Z_Fn (function): the original camera direction
> functions.
>   pLocation  (vec) : the location of the camera
>   pLookAt    (vec) : the point to look at
>   Angle    (float) : horizontal field of view o view angle
>   Roll     (float) : optional, defaults to 0.
>                      Roll, a.k.a. banking, rotates the camera around the
> view
>                      direction vector.
>   vDirection (vec) : optional, defaults to +z.
>   vRigth     (vec) : optional, defaults to
> <image_width/image_height,0,0>.
>   vUp        (vec) : optional, defaults to +y.
>   */
>   #ifndef(local.Roll)
>     #local Roll = 0;
>   #end
>   #ifndef(local.vDirection)
>     #local vDirection = +1*z;
>   #end
>   #ifndef(local.vRight)
>       #local vRight = +image_width/image_height*x;
>   #end
>   #ifndef(local.vUp)
>     #local vUp = +1*y;
>   #end
>   #local vLookAt = pLookAt - pLocation;
>   #local LookAtTransform = transform{
>     Reorient_Trans(z, vLookAt)
>     Axis_Rotate_Trans(vLookAt, Roll)
>   }
>   #local vDirection_1 = vtransform(vDirection, LookAtTransform);
>   #local vRight_1 = vtransform(vRight, LookAtTransform);
>   #local vUp_1 = vtransform(vUp, LookAtTransform);
>   #local <X1_X, X1_Y, X1_Z> = vtransform(x, LookAtTransform);
>   #local <Y1_X, Y1_Y, Y1_Z> = vtransform(y, LookAtTransform);
>   #local <Z1_X, Z1_Y, Z1_Z> = vtransform(z, LookAtTransform);
>   #local D1_X_Fn = function(u,v){
>     0
>     + X1_X*D0_X_Fn(u,v)
>     + Y1_X*D0_Y_Fn(u,v)
>     + Z1_X*D0_Z_Fn(u,v)
>   };
>   #local D1_Y_Fn = function(u,v){
>     0
>     + X1_Y*D0_X_Fn(u, v)
>     + Y1_Y*D0_Y_Fn(u, v)
>     + Z1_Y*D0_Z_Fn(u, v)
>   };
>   #local D1_Z_Fn = function(u,v){
>     0
>     + X1_Z*D0_X_Fn(u, v)
>     + Y1_Z*D0_Y_Fn(u, v)
>     + Z1_Z*D0_Z_Fn(u, v)
>   };
>   (D1_X_Fn, D1_Y_Fn, D1_Z_Fn)
> #end
>
> #macro udcStereo(pLocation,pLookAt,Angle,FocalDist)
>   //http://paulbourke.net/stereographics/stereorender/
>   #local EyeSep = FocalDist/30;
>   #local Delta  = (image_width*EyeSep)/(2*FocalDist*tand(Angle/2));
>   #local Angle1 = 2*atand((image_width+Delta)*tand(Angle/2)/image_width);
>   #local AspectU = image_width+Delta+Delta;
>   #local AspectV = image_height;
>   #local vMovement  = EyeSep/2*vnormalize(vcross(pLookAt-pLocation,
> <0,1,0>));
>   #local pLocationL = pLocation+vMovement;
>   #local pLocationR = pLocation-vMovement;
>   #local <LocationXL, LocationYL, LocationZL> = pLocationL;
>   #local <LocationXR, LocationYR, LocationZR> = pLocationR;
>   #local LocationX = function(u){select((u<=0),-1, LocationXR,
> LocationXL)};
>   #local LocationY = function(u){select((u<=0),-1, LocationYR,
> LocationYL)};
>   #local LocationZ = function(u){select((u<=0),-1, LocationZR,
> LocationZL)};
>   #local D0_X_Fn = function(u,v){u*AspectU};
>   #local D0_Y_Fn = function(u,v){v*AspectV};
>   #local D0_Z_Fn = function(u,v){AspectU/2/tand(Angle/2)};
>   #local pLookAtL = pLookAt+vMovement;
>   #local pLookAtR = pLookAt-vMovement;
>   #local(D1L_X_Fn, D1L_Y_Fn, D1L_Z_Fn) = udcLookAtTransform(
>     D0_X_Fn, D0_Y_Fn, D0_Z_Fn, pLocationL, pLookAtL, Angle1,,,,
>   );
>   #local(D1R_X_Fn, D1R_Y_Fn, D1R_Z_Fn) = udcLookAtTransform(
>     D0_X_Fn, D0_Y_Fn, D0_Z_Fn, pLocationR, pLookAtR, Angle1,,,,
>   );
>   #local D2_X_Fn = function(u,v){select(
>     (u<=0),
>     -1,
>     D1R_X_Fn((u/AspectU*image_width)-0.25,v),
>     D1L_X_Fn((u/AspectU*image_width)+0.25,v)
>   )};
>   #local D2_Y_Fn = function(u,v){select((u<=0),-1, D1R_Y_Fn(u-0.25,v),
> D1L_Y_Fn(u+0.25,v))};
>   #local D2_Z_Fn = function(u,v){select((u<=0),-1, D1R_Z_Fn(u-0.25,v),
> D1L_Z_Fn(u+0.25,v))};
>   camera {
>     user_defined
>     location {
>       function {LocationX(u)}
>       function {LocationY(u)}
>       function {LocationZ(u)}
>     }
>     direction {
>       function {D2_X_Fn(u,v)}
>       function {D2_Y_Fn(u,v)}
>       function {D2_Z_Fn(u,v)}
>     }
>   }
> #end

Note that vDirection_1, vRight_1 and vUp_1 are calculated in your
udcLookAtTransform macro, but not used for anything. So I suggest that you
remove them, and also vDirection, vRight and vUp, as you you will not be able to
change the default direction vectors for the user defined camera.

Further, I assume that you are implementing "Off-axis" stereo camera pairs. If
so then the corresponding direction vectors for both cameras will all be
parallel. (But their position and field of view will be different.) Therefore
you do not need to create two different direction function sets for them. You
can create a common set based on the initial pLocation and pLookAt positions.

--
Tor Olav
http://subcube.com


Post a reply to this message

Goto Latest 10 Messages Next 3 Messages >>>

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