Jump to content

Occlusion Question


SpencerL

Recommended Posts

I have a basic Vop Surface Shader where I am using an Occlusion VOP and Ive set the backgroun color to white (1,1,1). It seems that the areas that are not occluded are only reciving a value of (0.5,0.5,0.5) when I would expect the unoccluded areas to recieve a value of (1,1,1). Why is the max value only 0.5?

Thanks!

post-675-1201110096_thumb.jpg

Link to comment
Share on other sites

ok, still dont understand completely. Isnt it calculated based on ray length so that the longer the ray, the less occluded it is. If that is the case then why would it matter if the max is 0.5, 1 or 100. (but based on that assumption, I have a feeling Im wrong in how it is calculated).

Edited by SpencerL
Link to comment
Share on other sites

I don't get it.. If I have grid with light of intensity 1 coming all around it, then each sample would add 1 / NumberOfSamples so the resulting color would be white, right? I tried it with texture too, and the resulting color is 0.5 * texture. Why? I can't think of anything other than cosmetic reasons :blink:

Link to comment
Share on other sites

First off, I haven't tried Houdini's occlusion shader yet, but many other occlusion shaders just calculate the _ratio_ of rays hitting something (usually within a defined limit). Personally I like to take the distance into account too.

As for the scaling factor, I think it kinda makes sense. If you're sampling different parts of your scene with different sampling angles, eg. some spiky things with a full sphere, then the intensities would match better. A point on a plane is half occluded in a sense :)

eetu.

Link to comment
Share on other sites

Sorry in my earlier post i should have said because they don't sum over the hemisphere they sum over the entire sphere.

Generally occlusion works like this.

For each point being rendering fire off a heap of rays in random directions. Those directions are somewhere within 180 degress of the normal for the point being rendered. This creates a hemisphere of rays. Anything between 180 degrees and 360 is bound to be occluded because the point is sitting on a surface.

So for the example of a grid with no occlusion all the rays from 0 to 180 degrees have no occlusion and all the rays from 180 to 360 have total occlusion. This means that when you add them together you can never get more than half the rays not hitting something hence the 0.5 top value.

However you would have thought it was safe to only concider the values from 0 to 180 and not care about the 180 to 360 bit and therefore get a top value of 1. Go figure....

Link to comment
Share on other sites

Sorry in my earlier post i should have said because they don't sum over the hemisphere they sum over the entire sphere.

Hmm ... according to the docs (wow there are quite a number of broken links in the 9.1 docs), it's just the hemisphere. Full-sphere sampling would explain it though (in which case I'd hope transparent objects would be able to achieve >0.5)

Link to comment
Share on other sites

Hmm ... according to the docs (wow there are quite a number of broken links in the 9.1 docs), it's just the hemisphere. Full-sphere sampling would explain it though (in which case I'd hope transparent objects would be able to achieve >0.5)

Houdini occlusion when I last looked at it doesn't deal with transparency, I wish it did, but it would be a hell of a lot slower.

They may well only use the hemisphere to send the rays, it would be pointless to check for rays that are always occluded. But their final calculation has to be assuming the use of the full sphere.

Maybe its just an almighty big bug, but I'm sure I asked them about this exact same thing and the answer was because they concider the entire sphere not just the hemisphere.

Link to comment
Share on other sites

Hmm ... according to the docs (wow there are quite a number of broken links in the 9.1 docs), it's just the hemisphere. Full-sphere sampling would explain it though (in which case I'd hope transparent objects would be able to achieve >0.5)

This is further enforced by a test with a very significant ray bias. If you render a grid of size 1 with a ray bias of 0.5, full-sphere sampling should give you a noticeable value of >0.5 near the edge of the grid ... but it doesn't.

Link to comment
Share on other sites

They may well only use the hemisphere to send the rays, it would be pointless to check for rays that are always occluded. But their final calculation has to be assuming the use of the full sphere.

That definitely does seem to be what's happening. Although I'm curious if anyone would use the result for anything other than the input to a "x2" operator.

Link to comment
Share on other sites

Yep, that may be the case. But.. sampling spiky things with full sphere.. Wouldn't that mean that the surface is transparent for it to take into account what's on the other side?

Am I right that light can land on the non-transparent surface only from the hemisphere above normal? If so, then that scaling doesn't make sense to me.. Nah, if you need occlusion in 0 - 1 range just multiply it by 2 :)

Link to comment
Share on other sites

That definitely does seem to be what's happening. Although I'm curious if anyone would use the result for anything other than the input to a "x2" operator.

For what it's worth, SESI's ambient occlusion demo (launched from the docs) has the tint multiplier set to 2.

Personally I really don't like this ... especially since you are given the option of setting a cone angle which then seems to be used to define two cones (one above and one below the surface, the second of which is then ignored other than to pull down the result value to a 0-0.5 range)

Link to comment
Share on other sites

For each point being rendering fire off a heap of rays in random directions. Those directions are somewhere within 180 degress of the normal for the point being rendered. This creates a hemisphere of rays. Anything between 180 degrees and 360 is bound to be occluded because the point is sitting on a surface.

This makes a lot more sense now, thanks. You could also use a fit VOP to bring the value to fall between 0 and 1.

Link to comment
Share on other sites

occlusion() in VEX has two forms, vector occlusion() and float occlusion(). Vector type should be multiplied by 2 but float type occlusion gives "good" values by default. Both functions have a bit different sense.

1. vector occlusion(vector P, vector N)
	  Computes ambient occlusion at the point P with the normal N. Just as in the irradiance function, the hemisphere is sampled. However, unlike irradiance, surfaces intersected during the hemisphere sampling are not shaded. For this function to work properly, either a constant background color or an environment map must be specified in the optional scope parameters.
2. void occlusion(float coverage&, vector missed_direction&, vector P, vector N)
	  Instead of computing color information from ambient occlusion, this form computes the coverage (the percentage of occlusion) and the average direction of empty space. The average direction can be used to look up the color in a pre-blurred environment map.

Link to comment
Share on other sites

occlusion() in VEX has two forms, vector occlusion() and float occlusion().

Yup, as Hoknamahn mentions, there are two versions: #1 is occluded irradiance, and I believe one could argue that it is correct as it is (i.e: a diffuse albedo of 0.5). And #2 is the one that *everyone* always expects to see (which I've gotten used to calling "visibility" instead of "occlusion") and which represents "percent exposure" to the environment. This second form has the added advantage of calculating the now famous "bent normal" for you. This bent normal can be used to look up a pre-blurred environment map to do quick'n'dirty (and pretty good looking actually) ambient illumination.

To put it a different way: Our libraries here never, ever, not once, make a call to version #1. All the occlusion wrappers forward to version #2: "visibility".

The bad news is that there is no VOP available for the second form of the function (except for the InLine VOP) -- and this is still true in H9.1.133 AFAICT -- so people will typically plunk down an Occlusion VOP (which computes occluded irradiance, not visibility), render an image and then go wtf?!?!?... then start a thread about it :)

BTW: this issue (which I consider a flaw with VOPs, not VEX) has been brought up countless times (since VOPs first appeared on the scene, in fact). They *must* have multiple RFE's logged for it by now. But by all means continue to flood them with requests for a VOP representation of the visibility form of the function!

Cheers.

Link to comment
Share on other sites

BTW: this issue (which I consider a flaw with VOPs, not VEX) has been brought up countless times (since VOPs first appeared on the scene, in fact). They *must* have multiple RFE's logged for it by now. But by all means continue to flood them with requests for a VOP representation of the visibility form of the function!

Thanks for the explanation, its really good information to know. Now that its been explained, it makes complete sense, but I think its more important now than ever that SESI incorporates a VOP that represents the "visibility" form since they are really trying to make Houdini a more intuitive, user-friendly package.

Link to comment
Share on other sites

3 questions:

Is it true to say though that neither 1 nor 2 take into account transparency?

If all you want is the percentage coverage, converting 1 to a float by luminance (assuming a white background) and multiplying by 2 will give you the coverage value from 2?

Finally is version 2 more efficient than 1, since neither call the shaders?

Edited by sibarrick
Link to comment
Share on other sites

3 questions:

Is it true to say though that neither 1 nor 2 take into account transparency?

If all you want is the percentage coverage, converting 1 to a float by luminance (assuming a white background) and multiplying by 2 will give you the coverage value from 2?

Finally is version 2 more efficient than 1, since neither call the shaders?

1. According to:

Monday, January 21, 2008

Houdini 9.1.130: Added support for opacity for occlusion() and irradiance(). For occlusion(), it is necessary to turn on opacity-based filtering by passing the "samplefilter" parameter to the occlusion() function with a value of "opacity". Eg:

Cf = occlusion(pp, nn, "samplefilter", "opacity");

Updated the gilight shader to support a transparent occlusion option.

So I guess that opacity is now supported, though I haven't tested it myself yet.

2. Assuming a white bg, then I suppose it should come close to being the same... needs to be tested (as I said, I hardly ever -- read never -- call version 1, so I don't know).

3. Ditto: probably similar in efficiency, but needs to be tested. The biggest difference (certainly for my typical use), would be that version 1 doesn't compute the bent normal (which is internally trivial to compute so shouldn't be slowing it down much at all, I would think). This feature alone makes version 2 much more attractive than version 1 in my books.

Link to comment
Share on other sites

Probably the speed should be the same coz they both do a simple trace (except the case with magic "opacity" filter).

One of good reasons to use pure VEX is it's cleanness - you always know what are you doing. But you never know what is under the hood of VOP until you check a VEX code in that VOP. And if something is not accessible you have to implement that in VEX. In this context VOPs are not as simple as many people thought.

Edited by hoknamahn
Link to comment
Share on other sites

But by all means continue to flood them with requests for a VOP representation of the visibility form of the function!

Note that not everyone reads the forums. The right way to request is send them through support for RFEs or to submit bugs via the sidefx.com web form.

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...