Question about BRDF
#1 Members - Reputation: 371
Posted 01 September 2012 - 04:15 AM
As wikipedia says, brdf takes incoming direction, outgoing direction, and returns the ratio of reflected radiance exiting along outgoing direction, to irradiance incident from incoming direction.
So basically, I take reflected radiance, and divide it by incoming irradiance?
Ok, that's pretty easy, but how do I calculate reflected radiance?
Outgoing direction dot surface normal?
Another question. If all of my surfaces are perfectly diffuse, can I replace brdf with a constant 1.0?
If I sound like an idiot, don't hate on me, I'm 13 ._.
#2 Moderators - Reputation: 14296
Posted 01 September 2012 - 04:31 AM
Yes, the "lambert" (perfectly diffuse) BRDF is just a constant number -- traditionally the numbers stored in your "diffuse texture".If all of my surfaces are perfectly diffuse, can I replace brdf with a constant 1.0?
As above, for a diffuse surface it's just input radiance * constant (which is >=0 and <= 1).Ok, that's pretty easy, but how do I calculate reflected radiance?
Outgoing direction dot surface normal?
Outside of the BRDF, the rendering equation multiplies the result (which in your case is just the constant diffuse colour) by incoming direction dot surface normal.
e.g.
float3 brdf = tex2d( diffuse, uv ) * irradiance; float3 radiance = brdf * dot(L,N);
Edited by Hodgman, 01 September 2012 - 04:33 AM.
#3 Members - Reputation: 371
Posted 01 September 2012 - 05:01 AM
I have another question about single-bounce global illumination..

(mspaint.exe drawing skillzzzz)
1. Is the picture right?
2. To compute single bounce indirect lighting on the white wall, I have to sum incoming radiance from random directions on hemisphere, then average it?
@edit:
I wrote pseudo code:
double solid_angle = 2 * pi / NUM_SAMPLES; // not sure about 2 * pi, if it's hemisphere maybe it should be just pi?
Vector3 irradiance = 0.0 0.0 0.0;
for(int i = 0; i < NUM_SAMPLES; i++)
{
Ray r = new Ray();
r.Origin = point_on_surface;
r.Direction = RandomDirectionInHemisphereOf(surface.normal);
Surface hit_surface = Trace(r);
Vector3 radianceComing = dot(r.Direction, hit_surface.normal)
* calculateDirectLight(hit_surface)
* hit_surface.color
* solid_angle;
irradiance += radianceComing;
}
finalColor = calculateDirectLight(surface) + irradiance;
Would it work? Are there errors?
@edit2:
Having const solid angle is just the same as averaging the value, I think.
Edited by MrOMGWTF, 01 September 2012 - 07:26 AM.
#4 Moderators - Reputation: 5643
Posted 01 September 2012 - 12:20 PM
To calculate outgoing radiance, you need to integrate BRDF * differential incident irradiance for all directions on the hemisphere surrounding the surface normal. Note that this is not "averaging", it's integrating. From your code it looks like you're attempting to estimate the integral with monte carlo, which is a common way of doing things in graphics. This means you must sum all of your samples, and scale the result by the probability density function (PDF) of your sampling scheme. If you're uniformly sampling about the hemisphere the PDF is 1 / 2 * Pi, since 4 * Pi is the surface area of a sphere with radius of 1. Since this factor is constant can pull it out of your loop if you wish, and apply it at the end. You can also do the same for a Lambertian BRDF, since it's constant for each sample. No matter how you do it you need to be careful about numerical precision, although it probably won't be much of a problem if you're using doubles.
#5 Members - Reputation: 371
Posted 01 September 2012 - 01:25 PM
Normalized lambertian is actually DiffuseAlbedo / Pi. Without the 1 / Pi factor you won't conserve energy.
To calculate outgoing radiance, you need to integrate BRDF * differential incident irradiance for all directions on the hemisphere surrounding the surface normal. Note that this is not "averaging", it's integrating. From your code it looks like you're attempting to estimate the integral with monte carlo, which is a common way of doing things in graphics. This means you must sum all of your samples, and scale the result by the probability density function (PDF) of your sampling scheme. If you're uniformly sampling about the hemisphere the PDF is 1 / 2 * Pi, since 4 * Pi is the surface area of a sphere with radius of 1. Since this factor is constant can pull it out of your loop if you wish, and apply it at the end. You can also do the same for a Lambertian BRDF, since it's constant for each sample. No matter how you do it you need to be careful about numerical precision, although it probably won't be much of a problem if you're using doubles.
Do I have to use solid angles when using your method? And is my calculation of solid angles proper?
double solid_angle = 2 * pi / NUM_SAMPLES;






