![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
I have three functions that return values between 0 and 1 (inclusive).
What is the proper threshold to use with them? Here is an example of one
such function.
isosurface
{
function
{
convertLCH2RGBb2(y*100,sqrt(x*x+z*z)*100,atan2d(x,z))
}
contained_by
{
box {<-1,0,-1>,<+1,+1,+1>}
}
threshold 1
accuracy 0.01
// max_gradient 1.1
// [evaluate P0, P1, P2]
// open
// [max_trace INTEGER] | [all_intersections]
pigment {srgb 1}
}
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 23.11.2016 22:50, Mike Horvath wrote:
> I have three functions that return values between 0 and 1 (inclusive).
> What is the proper threshold to use with them? Here is an example of one
> such function.
No threshold will give the desired result using the color
conversion function directly, as clipka explained you need
a define a "distance" function for this purpose.
Alternatively you could try to render the clipped function
(set to 0 outside the gamut) as strongly scattering media but
it may be fiddly and you don't get the look of a "surface"
regarding finish and lighting etc.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 11/23/2016 7:22 PM, Christian Froeschlin wrote:
> No threshold will give the desired result using the color
> conversion function directly, as clipka explained you need
> a define a "distance" function for this purpose.
>
> Alternatively you could try to render the clipped function
> (set to 0 outside the gamut) as strongly scattering media but
> it may be fiddly and you don't get the look of a "surface"
> regarding finish and lighting etc.
>
What is a "distance" function?
The "convertLCH2RGBb2(y*100,sqrt(x*x+z*z)*100,atan2d(x,z))" bit is what
clipka showed me.
Mike
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Am 24.11.2016 um 01:27 schrieb Mike Horvath:
> On 11/23/2016 7:22 PM, Christian Froeschlin wrote:
>> No threshold will give the desired result using the color
>> conversion function directly, as clipka explained you need
>> a define a "distance" function for this purpose.
>>
>> Alternatively you could try to render the clipped function
>> (set to 0 outside the gamut) as strongly scattering media but
>> it may be fiddly and you don't get the look of a "surface"
>> regarding finish and lighting etc.
>>
>
> What is a "distance" function?
>
> The "convertLCH2RGBb2(y*100,sqrt(x*x+z*z)*100,atan2d(x,z))" bit is what
> clipka showed me.
You may need to deconstruct the problem into easy-to-handle building
blocks, and tackle each of them separately.
One building block you need is a function that maps a single RGB colour
component to a distance-ish scalar telling you how "far away" the colour
component is from the valid range (this time, just for giggles, I'm
contructing the function in such a way that <0 is inside, >0 is outside):
#declare fD = function(C) { abs(C-0.5)-0.5 }
Another building block you need is a function that combines three such
distance-ish scalars, such that you get a positive value if one or more
parameters is positive, or a negative value if all are negative, in a
manner that avoid steps:
#declare fDist = function(Dr,Dg,Db) { max(Dr,Dg,Db) }
That's kind of all you need to know about the "distance" functions;
however, those functions alone don't get you anywhere.
Another necessary building block is a set of functions that map Lch to RGB:
#declare fR = function(L,c,h) { ... }
#declare fG = function(L,c,h) { ... }
#declare fB = function(L,c,h) { ... }
And the final building block is a set of functions that map 3D cartesian
space to Lch:
#declare fL = function(x,y,z) { y*100 }
#declare fc = function(x,y,z) { sqrt(x*x+z*z)*100 }
#declare fh = function(x,y,z) { atan2d(x,z) }
Once you have all these building blocks, all that's left is to plug them
all together.
The final result to be compared to the threshold by the isosurface is
the result of the `fDist` function, so that's where you start:
isosurface {
threshold 0
function { fDist (Dr,Dg,Db) }
}
The isosurface doesn't know what `Dr`, `Dg` and `Db` are, but we know
they are supposed to be results of the `fD` function, using the three
colour channels as input:
isosurface {
threshold 0
function { fDist (
fD (R),
fD (G),
fD (B)
) }
}
Again the isosurface doesn't know `R`, `G` and `B`:
isosurface {
threshold 0
function { fDist (
fD ( fR (L,c,h) ),
fD ( fG (L,c,h) ),
fD ( fB (L,c,h) )
) }
}
Still not done yet, as the isosurface doesn't know `L`, `c` and `h` either:
isosurface {
threshold 0
function { fDist (
fD ( fR (fL(x,y,z),fc(x,y,z),fh(x,y,z)) ),
fD ( fG (fL(x,y,z),fc(x,y,z),fh(x,y,z)) ),
fD ( fB (fL(x,y,z),fc(x,y,z),fh(x,y,z)) )
) }
}
Now we have only `x`, `y` and `z` left as parameters, which is what the
isosurface can handle.
For bonus points, you could eliminate the multiple invocation of
`fL(x,y,z)`, `fc(x,y,z)` and `fh(x,y,z)`. To this end, you need to
provide a function that does not compute these values itself, but rather
takes them as parameters:
#declare fFinal = function(L,c,h) { fDist (
fD ( fR (L,c,h) ),
fD ( fG (L,c,h) ),
fD ( fB (L,c,h) )
) }
isosurface {
threshold 0
function { fFinal (fL(x,y,z),fc(x,y,z),fh(x,y,z)) }
}
And of course you'll want to use different names; I chose the above for
brevity.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
This produces similar results as before, except it looks like someone
has been chewing on it. Compare the two images I attached.
Also, I don't really know what I am doing, but taking the abs of each
component separately seems wrong. Rather, a color should be considered
"bad" if any of R, G or B are outside 0..1 range. Clamping R, G and B
should also not be done.
(This is very frustrating for me.)
:(
Mike
Post a reply to this message
Attachments:
Download 'cielch_color_solid_cylinder_isosurface.png' (12 KB)
Download 'cielch_color_solid_cylinder_isosurface_backup.png' (45 KB)
Preview of image 'cielch_color_solid_cylinder_isosurface.png'
![cielch_color_solid_cylinder_isosurface.png](/povray.advanced-users/attachment/%3C58372618%241%40news.povray.org%3E/cielch_color_solid_cylinder_isosurface.png?ttop=443814&toff=200&preview=1)
Preview of image 'cielch_color_solid_cylinder_isosurface_backup.png'
![cielch_color_solid_cylinder_isosurface_backup.png](/povray.advanced-users/attachment/%3C58372618%241%40news.povray.org%3E/cielch_color_solid_cylinder_isosurface_backup.png?ttop=443814&toff=200&preview=1)
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 11/24/2016 12:40 PM, Mike Horvath wrote:
> This produces similar results as before, except it looks like someone
> has been chewing on it. Compare the two images I attached.
>
> Also, I don't really know what I am doing, but taking the abs of each
> component separately seems wrong. Rather, a color should be considered
> "bad" if any of R, G or B are outside 0..1 range. Clamping R, G and B
> should also not be done.
>
> (This is very frustrating for me.)
>
> :(
>
> Mike
>
I guess I should explain this better. If I take the LCH coordinate <50,
50, 180> and convert it to RGB, the result is <-0.84558, 0.54573,
0.46120>. Since one of the components is outside the range 0..1, the
coordinate is out of gamut. This should not be clamped to <0.00000,
0.54573, 0.46120>.
Mike
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Am 24.11.2016 um 18:40 schrieb Mike Horvath:
> This produces similar results as before, except it looks like someone
> has been chewing on it. Compare the two images I attached.
My guess would be a max_gradient issue.
> Also, I don't really know what I am doing, but taking the abs of each
> component separately seems wrong. Rather, a color should be considered
> "bad" if any of R, G or B are outside 0..1 range. Clamping R, G and B
> should also not be done.
Designing isosurface functions requires a certain way of thinking, which
may occasionally go against common intuition.
Don't let a mere feeling of "this seems wrong" stop you from examining
the approach closer and trying to understand why it may work nonetheless
(unless of course you have internalized the "isosurface way" of thinking
to such a degree that it is reflected by your gut feeling, but I don't
have the impression that this is the case ;)).
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Am 24.11.2016 um 19:02 schrieb Mike Horvath:
> On 11/24/2016 12:40 PM, Mike Horvath wrote:
>> This produces similar results as before, except it looks like someone
>> has been chewing on it. Compare the two images I attached.
>>
>> Also, I don't really know what I am doing, but taking the abs of each
>> component separately seems wrong. Rather, a color should be considered
>> "bad" if any of R, G or B are outside 0..1 range. Clamping R, G and B
>> should also not be done.
>>
>> (This is very frustrating for me.)
>>
>> :(
>>
>> Mike
>>
>
> I guess I should explain this better. If I take the LCH coordinate <50,
> 50, 180> and convert it to RGB, the result is <-0.84558, 0.54573,
> 0.46120>. Since one of the components is outside the range 0..1, the
> coordinate is out of gamut. This should not be clamped to <0.00000,
> 0.54573, 0.46120>.
I'm not sure where you get the idea that my approach would do any
clamping. Maybe I misunderstood what "convertLCH2RGBb2" (which I
mentioned earlier in this context) is supposed to do; try to ignore
that, and only refer to my later explanations.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> Also, I don't really know what I am doing, but taking the abs of each
> component separately seems wrong. Rather, a color should be considered
> "bad" if any of R, G or B are outside 0..1 range.
That is what is happening.
Look at this function, if C is outside the range 0...1 then the result
will be positive, or "bad". Negative is a "good" output.
#declare fD = function(C) { abs(C-0.5)-0.5 }
Now consider this function, feeding into it three results (some could be
"bad", some could be "good"):
#declare fDist = function(Dr,Dg,Db) { max(Dr,Dg,Db) }
Here "max" is working like a boolean "or" function. It will return "bad"
(ie positive) if any of the three parameters are "bad".
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 11/24/2016 1:20 PM, clipka wrote:
> Am 24.11.2016 um 18:40 schrieb Mike Horvath:
>> This produces similar results as before, except it looks like someone
>> has been chewing on it. Compare the two images I attached.
>
> My guess would be a max_gradient issue.
>
You are correct. That was the exact problem.
>> Also, I don't really know what I am doing, but taking the abs of each
>> component separately seems wrong. Rather, a color should be considered
>> "bad" if any of R, G or B are outside 0..1 range. Clamping R, G and B
>> should also not be done.
>
> Designing isosurface functions requires a certain way of thinking, which
> may occasionally go against common intuition.
>
> Don't let a mere feeling of "this seems wrong" stop you from examining
> the approach closer and trying to understand why it may work nonetheless
> (unless of course you have internalized the "isosurface way" of thinking
> to such a degree that it is reflected by your gut feeling, but I don't
> have the impression that this is the case ;)).
>
I give up! I will never understand isosurfaces, and will just take your
word for it.
Mike
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |