POV-Ray : Newsgroups : povray.newusers : Pigment colour from RGB functions Server Time
14 May 2024 04:34:46 EDT (-0400)
  Pigment colour from RGB functions (Message 1 to 10 of 10)  
From: scott
Subject: Pigment colour from RGB functions
Date: 20 May 2013 12:32:38
Message: <519a5026$1@news.povray.org>
I've been digging about in the docs for a while and can't come up with 
an obvious way to achieve this, although I'm sure it must be fairly 
straightforward.

Suppose I have a mathematical formula to calculate the R, G and B values 
of a pigment based on the coordinates (x,y,z), how to write that in POV?

I started by writing 3 functions to calculate the R G and B components, 
but then I got stuck trying to combine them in the pigment part of an 
object. What's the best way to do this?

I want to write this:

pigment{color rgb <functionR,functionG,functionB>}


Post a reply to this message

From: waggy
Subject: Re: Pigment colour from RGB functions
Date: 20 May 2013 14:15:01
Message: <web.519a67c283779f7f21be1230@news.povray.org>
scott wrote:
> I started by writing 3 functions to calculate the R G and B components,
> but then I got stuck trying to combine them in the pigment part of an
> object. What's the best way to do this?
>
> I want to write this:
>
> pigment{color rgb <functionR,functionG,functionB>}

I don't know if this is the best way, but this is what I do.

#local P_R=pigment{
  function{functionR(x,y,z)}
  color_map{[0,rgb<0,0,0>][1,rgb<5,0,0>]}
};
#local P_R=pigment{
  function{functionG(x,y,z)}
  color_map{[0,rgb<0,0,0>][1,rgb<0,5,0>]}
};
#local P_R=pigment{
  function{functionB(x,y,z)}
  color_map{[0,rgb<0,0,0>][1,rgb<0,0,5>]}
};
#local P_F=pigment{
  function{functionF(x,y,z)}
  color_map{[0,rgbf<0,0,0,0>][1,rgbf<0,0,0,5>]}
};
#local P_T=pigment{
  function{functionT(x,y,z)}
  color_map{[0,rgbt<0,0,0,0>][1,rgbt<0,0,0,5>]}
};
pigment{
  average
  pigment_map{[1,P_R][1,P_G][1,P_B][1,P_F][1,P_T]}
}

If you eliminate both the filter and transmit parts, change the 5s to 3s.

I hope this helps.


Post a reply to this message

From: scott
Subject: Re: Pigment colour from RGB functions
Date: 21 May 2013 11:51:10
Message: <519b97ee$1@news.povray.org>
>> I started by writing 3 functions to calculate the R G and B components,
>> but then I got stuck trying to combine them in the pigment part of an
>> object. What's the best way to do this?
>>
>> I want to write this:
>>
>> pigment{color rgb <functionR,functionG,functionB>}
>
> I don't know if this is the best way, but this is what I do.
>
> #local P_R=pigment{
>    function{functionR(x,y,z)}
>    color_map{[0,rgb<0,0,0>][1,rgb<5,0,0>]}
> };
> #local P_R=pigment{
>    function{functionG(x,y,z)}
>    color_map{[0,rgb<0,0,0>][1,rgb<0,5,0>]}
> };
> #local P_R=pigment{
>    function{functionB(x,y,z)}
>    color_map{[0,rgb<0,0,0>][1,rgb<0,0,5>]}
> };
> #local P_F=pigment{
>    function{functionF(x,y,z)}
>    color_map{[0,rgbf<0,0,0,0>][1,rgbf<0,0,0,5>]}
> };
> #local P_T=pigment{
>    function{functionT(x,y,z)}
>    color_map{[0,rgbt<0,0,0,0>][1,rgbt<0,0,0,5>]}
> };
> pigment{
>    average
>    pigment_map{[1,P_R][1,P_G][1,P_B][1,P_F][1,P_T]}
> }
>
> If you eliminate both the filter and transmit parts, change the 5s to 3s.
>
> I hope this helps.

I had thought of doing such a thing but I don't know in my code how 
large the return values of the function will be (certainly not limited 
to 1). If there is no better alternative then I'll end up with something 
like this:

  #local K = 1e8;
  #local P_R=pigment{
     function{ functionR(x,y,z)/K }
     color_map{ [0,rgb <0,0,0>] [1,rgb <3*K,0,0>] }
  };

But obviously I have to choose K large enough for all possible return 
values (maybe I can determine the upper limit with some maths).


Post a reply to this message

From: Samuel Benge
Subject: Re: Pigment colour from RGB functions
Date: 21 May 2013 12:50:01
Message: <web.519ba54783779f7f826ce7c10@news.povray.org>
Scott,

Not sure how much it helps, but here's the method I use:

#declare PFunc = function{pigment{bozo}}

#macro RGBFunc(Channel)
 PFunc(x, y, z)
 #switch(Channel)#case(0).x#break #case(1).y#break #case(2).z#break #end
#end

sphere{
 0, 1
 pigment{
  average
  pigment_map{
   [1 function{RGBFunc(0)} color_map{[0 rgb 0][1 rgb x*3]}]
   [1 function{RGBFunc(1)} color_map{[0 rgb 0][1 rgb y*3]}]
   [1 function{RGBFunc(2)} color_map{[0 rgb 0][1 rgb z*3]}]
  }
 }
}

That's just the bare-bones setup; there's still a lot of room for adjustment.

scott <sco### [at] scottcom> wrote:
> I had thought of doing such a thing but I don't know in my code how
> large the return values of the function will be (certainly not limited
> to 1). If there is no better alternative then I'll end up with something
> like this:
>
>   #local K = 1e8;
>   #local P_R=pigment{
>      function{ functionR(x,y,z)/K }
>      color_map{ [0,rgb <0,0,0>] [1,rgb <3*K,0,0>] }
>   };
>
> But obviously I have to choose K large enough for all possible return
> values (maybe I can determine the upper limit with some maths).

I've had to do it that way, too. In my case I wanted to cover the entire color
range of an hdr image... but I think I just used 256 in the end. Might account
for some color banding I've seen since then ;)

Sam


Post a reply to this message

From: Christian Froeschlin
Subject: Re: Pigment colour from RGB functions
Date: 21 May 2013 20:40:27
Message: <519c13fb$1@news.povray.org>
scott wrote:

> I had thought of doing such a thing but I don't know in my code how 
> large the return values of the function will be (certainly not limited 
> to 1). 

I think there is no elegant way to solve this except for your scaling.
But defining functions without known limit for use as RGB pigment would
seem to be a problematic approach to begin with ... even without the
technicality of turning a function into a pigment you need to decide
on a scaling if the function is not 0 to 1 (or worse, unbounded).


Post a reply to this message

From: Christian Froeschlin
Subject: Re: Pigment colour from RGB functions
Date: 21 May 2013 20:43:15
Message: <519c14a3$1@news.povray.org>
Christian Froeschlin wrote:

> even without the technicality of turning a function into a pigment
> you need to decide on a scaling if the function is not 0 to 1

unless of course you intentionally want to have parts of the
pigment potentially return more light than is incoming.


Post a reply to this message

From: scott
Subject: Re: Pigment colour from RGB functions
Date: 22 May 2013 03:09:53
Message: <519c6f41$1@news.povray.org>
>> even without the technicality of turning a function into a pigment
>> you need to decide on a scaling if the function is not 0 to 1
>
> unless of course you intentionally want to have parts of the
> pigment potentially return more light than is incoming.

It's for a sky_sphere, so will be used as an emission (to simulate a 
realistic sky colour).

I'm looking at the formulas now to see if there is any easy way to pluck 
out a kind of global brightness constant that I can then apply 
afterwards instead, which would guarantee a certain range of return 
values from the functions.


Post a reply to this message

From: kurtz le pirate
Subject: Re: Pigment colour from RGB functions
Date: 22 May 2013 11:39:51
Message: <kurtzlepirate-785486.17395022052013@news.povray.org>
In article <519a5026$1@news.povray.org>, scott <sco### [at] scottcom> wrote:

> I've been digging about in the docs for a while and can't come up with 
> an obvious way to achieve this, although I'm sure it must be fairly 
> straightforward.
> 
> Suppose I have a mathematical formula to calculate the R, G and B values 
> of a pigment based on the coordinates (x,y,z), how to write that in POV?
> 
> I started by writing 3 functions to calculate the R G and B components, 
> but then I got stuck trying to combine them in the pigment part of an 
> object. What's the best way to do this?
> 
> I want to write this:
> 
> pigment{color rgb <functionR,functionG,functionB>}


#macro fnR(x,y,z)
  2*x+y+z
#end

#macro fnG(x,y,z)
  x+2*y+z 
#end

#macro fnG(x,y,z)
  x+y+2*z 
#end


#macro fnColor(thisPoint)
  rgb <fnR(thisPoint.x),fnR(thisPoint.z),fnR(thisPoint.z)>
#end



pigment{color fnColor(<a,b,c>) }


-- 
klp


Post a reply to this message

From: scott
Subject: Re: Pigment colour from RGB functions
Date: 22 May 2013 11:47:57
Message: <519ce8ad$1@news.povray.org>
>> Suppose I have a mathematical formula to calculate the R, G and B values
>> of a pigment based on the coordinates (x,y,z), how to write that in POV?
...
 >
> #macro fnColor(thisPoint)
>    rgb <fnR(thisPoint.x),fnR(thisPoint.z),fnR(thisPoint.z)>
> #end
>
> pigment{color fnColor(<a,b,c>) }

That won't work for me, as the RGB values depend on the coordinates of 
the object the pigment is applied to (so it's not a constant colour). 
I'm using the method waggy suggested, but modified to cope with large 
values. I just wondered if there was a neater way to specify this, 
that's all.


Post a reply to this message

From: waggy
Subject: Re: Pigment colour from RGB functions
Date: 22 May 2013 12:05:01
Message: <web.519cec9783779f7f21be1230@news.povray.org>
scott wrote:
> I had thought of doing such a thing but I don't know in my code how
> large the return values of the function will be (certainly not limited
> to 1).

One function I've used to guarantee all finite values get mapped within [0,1) is
this.

1-1/(1+abs(functionR))

However, emission pigments having values greater than unity is not unusual. A
global brightness parameter seems like the way to go.


Post a reply to this message

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