Jump to content

Ambient light shader


rob

Recommended Posts

Well Mario , Its taken some time to digest the information you gave . I have even added a few more features to the second example of the occlusion set up you showed. So its helped me learn a lot. !

Great! Glad it was useful.

I already have questions on "how I can define the environment colours " ie assign one colour for the +Y hemisphere and one colour for the - Y hemisphere and then to be able to blend between the two. So I can have a sky and ground colour ! .

To linearize Y (and use it as a blending function between "below" and "above"), try:

vector n = normalize(ntransform("space:world",N));
float weight = 1.0 - acos(n.y)/M_PI;

Here, "weight" ranges between 0 (when Y points directly down), and 1 (when Y points directly "up"), and leaves the horizon at weight=0.5.

Armed with this, you can construct a transition between a "ground color" and a "sky color" based on the value of "weight". See if you can come up with something (hint: check out the smooth() function).

... though blending between just two constant colors may not be very useful in the end. So I'd suggest that once you get this one licked, you may want to try your hand at a more complex analytical sky model, like the one that Wolfwood posted here.

Cheers!

Link to comment
Share on other sites

  • Replies 43
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images

Hey Mario ,

I have not forgotten about my task , currently getting hammered at work right now.

On a side note I have also added some functions to the shaders to make them more user friendly for all. I should be able to upload them in the next couple of days as I quite fancy adding some help to the shaders using Jeff's vex tutorial so they are easy to use.

Regards Rob

Link to comment
Share on other sites

Update

I'm off work now so I can learn to my hearts content , find attached a Void occlusion shader using the 2nd type of occlusion listed in the help. Special thanks of course to that shader "Brain " Mario without him I would still have a half sort of working shader.

I do want to add export parms. So if anyone wants to give a lesson on it and how to add a parm to anywhere in a shader with just code let me know as no matter what I do after copying a vop net I still cannot get it to work . Also how on earth can the occlusion data be stored on a frame by frame basis ......

just changing the icons and a fault

rs_void_oclusion.otl

Edited by rob
Link to comment
Share on other sites

Hi Mario this is my attempt at creating a sky / ground colour part of an ambient light shader.

light rs_ambient_v02(
					 vector skycolor = {1,0,0};
					 vector grndcolor = {0,0,1};
					 float intensity = 1;
					 string env_map = "Mandril.rat";
					 string env_space = "space:world";

					 )
	   {
		vector n = normalize(ntransform("space:world",N));
		float weight = 1.0 - acos(n.y)/3.1415926;   // declared the value of PI
		vector Cenv = 1;
		vector lightcolor = lerp(grndcolor, skycolor, weight);  // using lerp to blend the colours


		if(env_map!="") {
		string space = env_space=="" ? "space:world" : env_space;
		Cenv = environment(env_map,n,"envobject",space);
		}

Cl = lightcolor*intensity*Cenv;
L = n;
}

I tried using the smooth function and just got so bogged down in errors . I had a chat to another shader guru and he pointed me to lerp as mentioned by Jeff early in this thread. I also found that using N_PI , when I tried to compile the shader no value for PI got picked up. So I had to enter a value for it.

post-1566-1213099639_thumb.jpg

Edited by rob
Link to comment
Share on other sites

I also found that using N_PI , when I tried to compile the shader no value for PI got picked up.

Hi rob!

you can add a

#include "math.h"

before your shader funtion.

This include file defines some useful variables like:

M_PI

the file is located at $HH/vex/include

N_PI might be from another include file ...

Georg

Link to comment
Share on other sites

I tried using the smooth function and just got so bogged down in errors . I had a chat to another shader guru and he pointed me to lerp as mentioned by Jeff early in this thread. I also found that using N_PI , when I tried to compile the shader no value for PI got picked up. So I had to enter a value for it.

Let me try to describe what's going on graphically:

The variable "weight" is 0 when the normal "n" points directly down (that is, when dot(n,y)=-1), and 1 when "n" points up (dot(n,y)=1), and varies linearly between the two:

post-148-1213127199_thumb.jpg

Your lerp expression uses weight directly and so you end up with a continuous "blend" between ground and sky -- i.e: instead of a "horizon", you have a linear (vertical) ramp:

post-148-1213127207_thumb.jpg

The smooth function, when parameterized over the whole range of weight [0,1], would look similar, except smoother (no abrupt changes at the ends -- no "discontinuities"):

post-148-1213127223_thumb.jpg

If you wanted a very hard horizon you'd end up with a step function -- one that changes between ground and sky abruptly when dot(n,y)>0. For this, you'd use filterstep, parameterized by "weight", like this:

post-148-1213127214_thumb.jpg

For a smoother transition across the horizon (without discontinuities), you can use the smooth function, but this time, instead of feeding it the entire range of "weight", you restrict it to a small neighbourhood about the horizon (i.e: just above and below the horizon, where weight=0.5):

post-148-1213127229_thumb.jpg

Makes sense?

Link to comment
Share on other sites

Hi Mario,

I understand all of that its just the fact I could not get it to work using the smooth function.The problem is I am finding with the whole learning vex. Is the sheer lack of decent documentation with examples.The old story about reading books on Prman so you can learn vex just does not add up they are like chalk and cheese.

You can take a small step and then you just hit a brick wall , with no resources except for " You " , support ( 24 hr turn around) and the sidefx forum which is so limiting.

light rs_ambient_v02(
					 vector skycolor = {1,0,0};
					 vector grndcolor = {0,0,1};
					 float intensity = 1;
					 string env_map = "Mandril.rat";
					 string env_space = "space:world";

					 )
	   {
		vector n = normalize(ntransform( "space:world",N));
		float weight = 0.5 - acos(n.y)/3.1415926;
		vector Cenv = 1;
		vector lightcolor = smooth(grndcolor, skycolor, weight, 0.5);


		if(env_map!="") {
		string space = env_space=="" ? "space:world" : env_space;
		Cenv = environment(env_map,n,"envobject",space);
		}

Cl = lightcolor*intensity*Cenv;
L = n;
}

float smooth(float value1, float value2, float amount)

I get 2 errors with the shader ( see below ) which I presume are becuase smooth is a float value and lightcolor is a vector and infact I have just had that confirmed that is a problem. Help here I come

post-1566-1213146609_thumb.jpg

Edited by rob
Link to comment
Share on other sites

Heh... a little frustration setting in I see..

Yup, besides the typo that Ed pointed out, I also noticed you changed the equation for "weight", from what I gave you:

float weight = 1.0 - acos(n.y)/M_PI;

to this:

float weight = 0.5 - acos(n.y)/3.1415926;

I understand the confusion with the include file, and that's fine (do what rdg suggested), but I'm talking about that 0.5. Using 0.5 will change the mapping to [-0.5,0.5] -- note that half the range is negative now -- instead of the original [0,1]... Not the same thing.. so yeah, go ahead and change it by all means, so long as you understand the effects of that change.

OK. Here's a revised version using all the curves I showed you above. Note the #include <math.h> line which bring in a few constants (including M_PI... not N_PI ;)). And I sprinkled some #pragma directives just in case you haven't seen them yet. Anyway... lots of comments... hopefully self explanatory.

//This line includes a file with some math constants, like 'M_PI'
// The file's location in actually in your Houdini installation,
// specifically, in $HH/vex/include, but this is one of the 
// default include paths that vcc will look in, so you don't need
// to type the whole path explicitly. Have a look at it when you
// get a chance, as well as some of the other header (.h) files in
// that directory
#include &lt;math.h&gt;

// These UI-related pragmas are for the choice menu
// ... might be instructional if you haven't played with pragmas yet.
// They give vcc some hints for how to draw the UI for the parameters
// "htype" and "hsoft".
#pragma label  htype "Horizon Type"
#pragma choice htype "lramp" "Linear Ramp"
#pragma choice htype "sramp" "Smooth Ramp"
#pragma choice htype "hard"  "Hard"
#pragma choice htype "soft"  "Soft"
#pragma label  hsoft "Horizon Softness"
#pragma range  hsoft 1e-4! 1! 
#pragma disable hsoft htype "lramp"
#pragma disable hsoft htype "sramp"
#pragma disable hsoft htype "hard"

light rs_ambient_v02 (
         vector skycolor   = {1,0,0};
         vector grndcolor  = {0,0,1};
         string htype      = "soft";
         float  hsoft      = 0.2;
         float intensity   = 1;
         string env_map    = "Mandril.rat";
         string env_space  = "space:world";

   )
{
   vector n = normalize(ntransform( "space:world",N));
   vector Cenv = 1;

   // I changed the 0.5 to a 1.0 -- I don't know where you got the 0.5 from.
   // With 0.5 you'd end up with negative values at the bottom...
   // Also notice I reverted back to "M_PI", which is defined in that
   // header file "math.h" included in the first line of this file.
   float weight = 1.0 - acos(n.y)/M_PI;

   // Here hw is the ground/sky color bias, and it's a function of
   // the "weight" variable. Its default value is identical to weight,
   // meaning that if anything goes wrong, this will default to a linear
   // ramp, just like you had before.
   float hw = weight;

   // Now we play with the variations in my post, acording to the 
   // user's choice
          if(htype   == "sramp") {     // Smooth ramp
      hw = smooth(0,1,weight);
   } else if(htype   == "hard") {      // Hard edge
      hw = filterstep(0.5,weight);
   } else if(htype   == "soft") {      // Soft edge
      // Instead of hard-wiring two values that straddle 0.5 for the 
      // softness interval and writing something like this:
      // smooth(0.4,0.6,weight)
      // We let the user enter a value between 0 and 1 (hsoft) which
      // we use to open up that interval from almost completely closed
      // at hsoft=0.0001 (which is the limit enforced by the UI as per
      // our pragma directive above) and fully open at hsoft=1.
      float halfinterval= clamp(hsoft*0.5,1e-4,0.5);
      hw = smooth(0.5-halfinterval,0.5+halfinterval,weight);
   }

   // Now we call lerp as before, except we replace the third argument (which
   // used to be just "weight", with the new "hw" defined above
   vector lightcolor = lerp(grndcolor,skycolor,hw);


   if(env_map!="") {
      string space = env_space=="" ? "space:world" : env_space;
      Cenv = environment(env_map,n,"envobject",space);
   }

   Cl = lightcolor*intensity*Cenv;
   L = n;
}

And here the results of the various curves, as given in my previous post (and rendered with the above shader:

post-148-1213159340_thumb.jpg

Link to comment
Share on other sites

Thanks Mario,

Talk about confusion , I was using the weight value incorrectly at least I was on the right track using lerp to some extent so it was not all doom and gloom.

I have used the #pragma choice before and in the A0 shader page 2 . I built in some functionality using " choice" and " file ". That has not been anywhere near as painfull :) .Its a good job you can help as I think Alvin is getting sick of me pestering him at work :)

R

Link to comment
Share on other sites

Is the sheer lack of decent documentation with examples.

I am somewhat currently somewhat slow and lazy, but I try to compile a compendium about shader writing.

With a strong bias towards non-photo-real useless shaders though :D

It's very likely you are production ready while this compendium ever gets published.

As I see it:

The "lack of documentation" is not existent. It's just the fact that vex - like rsl - is a programming language.

And therefore the basic rules of programming apply.

You can grab any book about programming, be it actionscript php python what soever, and start learning.

Translating a concept between languages might be a brick wall, but a very low one.

Link to comment
Share on other sites

I don't want to change the direction of this thread Georg but I would disagree with you its fine having all the ingredients but your not going to be able to bake a cake unless you have some pans and a cookbook on baking cakes. Check out the Prman docs then compare them to Houdini's.

Just as a suggestion we could pool the info we gain from our shader creation threads and get it on the wikki ?

Edited by rob
Link to comment
Share on other sites

Hey Mario ,

Using your code posted above I get some really different results every time I create a new otl in 9.5. just trying to figure if its something going wrong with the otl files in 9.5 .....

post-1566-1213660038_thumb.jpg

post-1566-1213665587_thumb.jpg

Edited by rob
Link to comment
Share on other sites

Using your code posted above I get some really different results every time I create a new otl in 9.5. just trying to figure if its something going wrong with the otl files in 9.5 .....

Hmm... Oh, wait...

I left the end of the shader as it was in yours, but now I see that, earlier in the code, I changed the definition of 'n' so I could use it in the horizon calculation (by transforming it to world space), so now the original assignment at the end: "L=n;" doesn't make sense anymore -- it is now assigning a world-space N, when it should just assign the normalized current-space N as before.

So change the last line to:

L = normalize(N);

Well... try it anyway. Your images suggest a space-related problem and I suspect that last assignment might be it.

Sorry about that.

Link to comment
Share on other sites

Funny you should say that , I went back to square one using the ambient occlusion guide you kindley created.I did struggle to get the above code to work following those rules.

I did try L = N; with success

will keep you posted

Edited by rob
Link to comment
Share on other sites

Mario,

what is a VEX equivalent for RSL solar() statement? Isn't it a crucial thing for translating Super Ambient shader (from Cortes' PRMan book) into VEX? Sorry, I don't have a time to try this shader myself now. This doubt came from a conversation with my friend who uses PRMan and I didn't know that to say... :(

sy.

Edited by SYmek
Link to comment
Share on other sites

Mario,

what is a VEX equivalent for RSL solor() statement? Isn't it a crucial thing for translating Super Ambient shader (from Cortes' PRMan book) into VEX? Sorry, I don't have a time to try this shader myself now. This doubt came from a conversation with my friend who uses PRMan and I didn't know that to say... :(

The difference between illuminate() and solar() is just that solar() doesn't take into account the light's position -- i.e: it's purely directional.

So, assuming the direction of the light is taken from the transformations and not from "to" and "from" parameters (as you might see in some older prman light shaders), then the conversion would go something like this:

1. Solar without parameters :

This is every point at infinity -- i.e: an illumination map.

RSL:

solar() { /*...*/ }

VEX:

L = normalize(N);

2. Solar with direction but zero angle:

Distant light -- i.e: purely directional, with zero cone angle and direction 'D' matching the light's +Z direction.

RSL:

solar(vector "shader" (0,0,1), 0) { /*...*/ }

VEX:

L = Lz*dot(L,Lz);

3. Solar with direction and non-zero angle:

Distant light over some cone. Presumably, this would use some function 'f' of the angle 'theta' between the light's direction and the the direction to the surface to modulate intensity.

RSL:

vector D = vector "shader" (0,0,1);
solar(D, M_PI/2) { 
   Cl = intensity * color * f(D.L/length(L));
}

VEX:

vector D =  Lz*dot(L,Lz);
Cl = intensity * color * f(dot(D,L)/length(L));

DISCLAIMER: I haven't tried any of the above... just thinking out loud here.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...