POV-Ray : Newsgroups : povray.binaries.images : Normal documentation images. Quilted. : Re: Normal documentation images. Quilted. Server Time
2 May 2024 08:25:36 EDT (-0400)
  Re: Normal documentation images. Quilted.  
From: Bald Eagle
Date: 14 Oct 2020 16:10:06
Message: <web.5f875a8dcc1d58b61f9dae300@news.povray.org>
William F Pokorny <ano### [at] anonymousorg> wrote:

> I'd guess there isn't much use in translating the non-working normal.cpp
> quilted code so

Translating the non-working code would help reproduce the nonworkability.
Then we could see where and why it doesn't work.

> below is an my initial attempt at a fix for surfaces
> perpendicular to the x, y and z axis.

But what did you fix?

> This updated code passes most of
> my test cases but of course has varying results with respect to curved
> surfaces - as does the original.  Whether this is what we want for a
> best quilted fix - I don't know! I don't think we really know what the
> original coders expected or perhaps even got to one degree or another in
> older versions of code

I'm not sure what you mean about curved surfaces - no examples have been
provided.

> One puzzle for me is I looked at no_bump_scale in the upper right render
> (C).  I expected it to have some effect on all three surfaces, but it's
> only changing the -x one! Not dug into code. Anyone have an idea what's
> going on? This touches on me not being a big user of normals. Not sure
> I've ever used no_bump_scale myself.

You haven't supplied any of your scene code, so I can't tell if you have any
scaling or offsets.  The wiki says that no_bump_scale just cancels out any
scaling of the normal depth when the texture or normal itself is scaled.

> DBL just means double - an sdl float. The normal is the incoming normal.
>   fabs is abs in sdl. The () ? ... : ... stuff is select. floor and ceil
> are floor and ceil. The quilt_cubic you, Bill, understand better than me
> at this point.

I'll address that and the code supplied below right here.
What I was looking for was as close to a 1:1 translation from the original
source code written in c++ to how it would be done with functions in SDL if it
were written that way from scratch.

Not sure where you are pulling the code below from, but what I had found was:


const DBL INV_SQRT_3_4 = 1.154700538;


DBL quilt_cubic(DBL t, DBL p1, DBL p2)
{
 DBL it=(1-t);
 DBL itsqrd=it*it;
 // DBL itcubed=it*itsqrd;
 DBL tsqrd=t*t;
 DBL tcubed=t*tsqrd;
 DBL val;
 // Originally coded as...
 // val= (DBL)(itcubed*n1+(tcubed)*n2+3*t*(itsqrd)*p1+3*(tsqrd)*(it)*p2);
 //re-written by CEY to optimise because n1=0 n2=1 always.
 val = (tcubed + 3.0*t*itsqrd*p1 + 3.0*tsqrd*it*p2) * INV_SQRT_3_4;
 return(val);
}


And so my first attempt at translating that was:

#declare INV_SQRT_3_4 = 1.154700538;
#declare Floor = function (T) {select (T, floor (1-T), floor (T))}
#declare IT = function (T) {1-T}
#declare ITsqr = function (T) {pow(IT (T), 2)}
#declare Tsqr = function (T) {pow(T, 2)}
#declare Tcub = function (T) {pow(T, 3)}
#declare Val0 = function (T, _P1, _P2) {
(
pow(T, 3) +
(3 * T * pow(1-T, 2) * _P1) +
(3 * pow(T,2) * (T - pow(T, 2)) * _P2)
)
* INV_SQRT_3_4

}

So:
I would say that if we could get that working as a pigment {function{}}
statement and as a normal{function{}}, then we should be able to then graph it
out the way I did mine to emulate the graphs in the documentation.
They _should_ match (aside from any misleading typos in the docs)

As for the underlying problems with the raytraced result of the pattern, I can
only speculate:
1. it's a function gradient problem since the function may be discontinuous,
have cusps, or whatever else resulting from the use of floor(), etc - since it's
a function designed to be constrained to a unit cube.
I'll have to look at what the isosurface looks like, etc.

2.  There's some interface problem between the output of the function and the
rest of what happens to that information after it gets evaluated and sent down
the ray / surface rendering pipeline.

As for the normal-specific function, I'd just need a very basic and specific
explanation of exactly how a given surface normal gets perturbed, in general (by
any user-written scalar function{}), and specifically by this function.
Just so it's crystal clear to me -  because what direction does a +y normal get
tilted to? It has 360 degrees of directions to get perturbed in.

I'd also need the following three statements in c++ syntax decrypted, so I could
try translating those into SDL.

    const QuiltedPattern *pattern =
dynamic_cast<QuiltedPattern*>(Tnormal->pattern.get());

    POV_PATTERN_ASSERT(pattern);

and

    normal += (DBL)Tnormal->Amount * value;




> This the sort of thing you're looking for?
>
> ----------
> DBL nx = normal.x(), ny = normal.y(), nz = normal.z();
> DBL ax = fabs(nx),   ay = fabs(ny),   az = fabs(nz);
>
> DBL x = EPoint.x(), y = EPoint.y(), z = EPoint.z();
> DBL flx = floor(x), fly = floor(y), flz = floor(z);
> DBL sx = (x-flx < 0.5) ? -1 : 1,
>      sy = (y-fly < 0.5) ? -1 : 1,
>      sz = (z-flz < 0.5) ? -1 : 1;
> DBL xm = flx+(ceil(flx+4.4e-8)-flx)/2.0;
> DBL ym = fly+(ceil(fly+4.4e-8)-fly)/2.0;
> DBL zm = flz+(ceil(flz+4.4e-8)-flz)/2.0;
>
> DBL c0 = pattern->Control0, c1 = pattern->Control1;
> DBL na = Tnormal->Amount;
>
> if ((ax >= ay) && (ax >= az))
> {
>      DBL vy = quilt_cubic(fabs(y-ym),c0,c1)*sy;
>      DBL vz = quilt_cubic(fabs(z-zm),c0,c1)*sz;
>      nz = (nz < 0.0) ? -1 : 1;
>      ny = ny + (na * vy);
>      nz = nz + (na * vz);
> }
> else if ((ay >= ax) && (ay >= az))
> {
>      DBL vx = quilt_cubic(fabs(x-xm),c0,c1)*sx;
>      DBL vz = quilt_cubic(fabs(z-zm),c0,c1)*sz;
>      nx = nx + (na * vx);
>      ny = (ny < 0.0) ? -1 : 1;
>      nz = nz + (na * vz);
> }
> else
> {
>      DBL vx = quilt_cubic(fabs(x-xm),c0,c1)*sx;
>      DBL vy = quilt_cubic(fabs(y-ym),c0,c1)*sy;
>      nx = nx + (na * vx);
>      ny = ny + (na * vy);
>      nz = (nz < 0.0) ? -1 : 1;
> }
> normal = Vector3d(nx,ny,nz);
> normal.normalize();  // <-- this normal vector what gets updated.


> C) normal {quilted 0.5 control0 +1.0 control1 +1.0
> no_bump_scale scale 0.5}

So, as I currently understand it, if the default bump_size is 1.0, then
no_bump_scale decouples the bump_size from the scale 0.5 statement, so that the
area of the normal gets scaled, but the bump_size stays the same at 1.0 instead
of getting shrunk to 0.5 .


Post a reply to this message

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