refraction attenuation in surface model

   6205   10   1
User Avatar
Member
3 posts
Joined: Sept. 2006
Offline
so maybe i'm not understanding what this is designed for, but it seems like it's not working.

on the refraction tab of the surface model, there's an option to enable attenuation with a density and a color to describe the effect. sounds perfect for my needs – refracted rays get tinted by some amount of attenuation.

but the subnetwork describes something completely different if i'm following the code. it tints either the refraction ray or the reflection ray (depending on the dot prod of the surface normal) but it uses I in the the attenuation calculation. this I is the global I of the current shading sample. this is NOT the ray length of the ray that was traced from the refraction/reflection calculation… it doesn't seem to make sense to tint the refracted/reflected rays of the surface based on the distance of the trace that got you to this point.

really, i don't see that a shader can get me where i want to go (at r&h we had to hack the pbr tracer or add a fog shader for non-pbr to get this effect). but i've been surprised by pbr in the past, so maybe i'm wrong here.
User Avatar
Member
246 posts
Joined: July 2005
Offline
Still the case as far as I know, although H14 must be imminent at this point and might address some of these limitations…
User Avatar
Member
8555 posts
Joined: July 2007
Offline
fathomgames

but the subnetwork describes something completely different if i'm following the code. it tints either the refraction ray or the reflection ray (depending on the dot prod of the surface normal) but it uses I in the the attenuation calculation. this I is the global I of the current shading sample. this is NOT the ray length of the ray that was traced from the refraction/reflection calculation… it doesn't seem to make sense to tint the refracted/reflected rays of the surface based on the distance of the trace that got you to this point…..

I was using attenuation many times and it's working for me
I believe “I” variable is direction and length of the current ray, whether it comes from the camera to the first shading point or if the shader is invoked from refraction ray then “I” represents that refraction ray
“I” always representing vector from camera to first shading point or current shading point would be useless, so I'm pretty positive it's the direction vector of ray that is currently calling the shader
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
3 posts
Joined: Sept. 2006
Offline
yeah, I is the current ray being traced. the point is that the tinting of the ray uses I to calculate the tint which will only ever work accurately if you're tinting the current shading sample.

if you have a simple closed shape with attenuation on it, then it will work fine. there's logic in the shader to do different things based on the dot prod of the normal and the I vector. so the first intersection gets no tint and the second gets tinted based on I (from the first intersection to the second intersection). but if you throw in a second object with a different material, it will fail to tint the second material.
User Avatar
Member
8555 posts
Joined: July 2007
Offline
you're right, it works only for closed surfaces and even that purely if something stands inbetween. After this being a huge missing feature for ages, one would think that it was done right.
It's indeed painful to be fixing it manually on pbr shader level or hacking by sending more rays that correctly measure traveled distance.
Submit a bug please
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
285 posts
Joined:
Offline
I tested a workaround for this by using the vm_volumesurface and and vm_volumeuniform render properties.

vm_volumesurface:
When rendering a uniform volume (vm_uniformvolume is enabled), this setting controls whether the surface is also rendered. If you enable this setting, the surface shader should handle both volume and surface samples by checking the value of the dPdz global - when it is 0 the shader should render a surface, otherwise a volume.

The enclosed volume should automatically attenuate the internal rays, if you set the shader color to black. Of course this is also limited to closed surfaces but I would think it should work behind other objects.
User Avatar
Member
8555 posts
Joined: July 2007
Offline
Uniform volume for “attenuating” light rays is good for murky water or any media that scatters light, however it's very different from pure glass absorption where rays don't scatter, just attenuate within the distance.
And of course volume is slower since it computes isotropic lighting and shadowing
and since volume is being shadowed by glass geo it's getting unrealistically dark unless you use All Paths or turn off glass shadows or opacity in shadow rays, but with that I've experienced non-physical energy accumulation within the refractions in the past

In theory it's really easy to compute absorbtion, however it needs to be implemented in PBR and not on shader level as the PBR Specular needs to measure distance of the sent ray and compute attenuation of the sample, which is not happening at the moment. For raytrace and micropoly there is always Trace VOP which can compute absorbtion, or Gather VOP to do it manually. For PBR it's possible to use gather to send ray and get distance, compute absorbtion and multiply refraction BSDF, but that would mean sending more rays to thesame places they've already been sent

I really hope SESI will find some time to properly fix this in the future and hopefully expand by using spectral model, dispersion, iridescence, …
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
285 posts
Joined:
Offline
Self-shadwoing issue aside, Isn't it the same thing if the volumetric bsdf is just multiplied by zero? With no light scattering, the shader effectively becomes an absorption model. In the VEX code both models seem to implement a form of Beer's law (e^-x).

I agree though that it would be far better to have the ray attenuated within the bsdf.
User Avatar
Member
8555 posts
Joined: July 2007
Offline
jparker
… Isn't it the same thing if the volumetric bsdf is just multiplied by zero? ….

not sure what you mean by that, if you multiply bsdf by zero you'll obviously get black, so attenuation to black

on top of that even if you can have constant BSDF that doesn't waste samples by sampling lights, uniform volume would simply be occluding the ray, not absorbing certain colors (wavelengths) so in other words it would act like a fog instead of as a color filter
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
285 posts
Joined:
Offline
Right, I suggested multiplying the bsdf to black because I don't think there is a constant bsdf (there used to be before mantra used Ce so maybe it's still hiding somewhere).

The solution to not fading to black is to use a color as input to opacity / density. If your final opacity is {0, 1, 1}, you get a color “tint” that is pure red. I would recommend setting the color as an input to the volume model and not as a multiplier afterwards to correctly calculate the extinction. This is a very rough way of doing per-wavelength absorption… rough because we are only using three “wavelengths”, which of course are not correct spectral lines anyways.

Next time I'm at my workstation I will try to post an example.

Cheers,
Jon
User Avatar
Member
285 posts
Joined:
Offline
I just gave this another try to set up… unfortunately it doesn't actually seem to work correctly as the conditional needed in the shader throws out the back facing surface the refraction ray needs.

Good idea in theory…
  • Quick Links