   Shaders and Photon Mapping
  For a path tracer, it would seem that a shader, knowing all the basic properties of a surface point, simply has to compute the amount of light reflected at that point in a given direction (what's the GI term for this?). The direction being the incoming direction of the ray.However, for photon mapping, where photons need to be traced from a light, it would seem that surfaces will need a second shader subroutine. One responsible for actually determining where photons will be traced to.Is there any way around this, and make the shader definition simpler? Perhaps a shader function that does things probabilistically all the time (russian roulette?). Given an incoming photon, it decides of the new photon direction based on russian roulette. But then, this seems like it would be inefficient as it would not compute direct illumination for surfaces all the time.   
  Have you checked gpgpu.org?   ;  Well, there's the problem, isn't it? Photon mapping, as a forward ray-tracing method, is at heart a scatter operation. A multiple scatter operation, to be exact. This is difficult for current GPUs.It is possible to transform a scatter operation into a gather operation. That requires a significant amount of computation, though, computation which--wait for it--requires a scatter operation.Photon mapping will probably not be feasible for dynamic scenes for quite some time. It runs into the same problems as other ray-tracing methods do WRT bad cache coherence and the need for specialized data structures.Current research focuses primarily on exploiting rigid and semirigid scene structure, so that this stuff can be precomputed to some extent. Sloan had an interesting paper about the semirigid case in this year's SIGGRAPH proceedings. If you want to learn about a new approach, come to the 2006 I3D conference and I'll tell you. [grin]   ;  I'm not talking about graphics hardware. I'm talking about implementing a photon mapping renderer with shaders *in software*. Like RenderMan.   ;  I have been thinking about this for some time too (Renderer in software with photon mapping)My current thinking is to have the renderer be a ray trace based renderer which can have plug-ins that can perform arbitrary operations.The shader system would query the plug-ins for information.i.e. My scene definition would look something like the following:Pass 0PhotonMapPluginPass 1RayTraceThe shaders for my scene would be something like:my_diffuse_shader(ray, surface_point){    diffuse= PhotonMapPlugin.ComputeDiffuse(ray, surface_point);    // do something nice in the shader}This way I can also create plugins for other things like Radiance caching as a plugin.Pbrt is extensible in this way as well, even though I have never used it, it is explained on the book.   ;  Back to the original post, I've given this some thought recently as well.PBRT handles this by forcing shaders to provide two functions: one to evaluate the brdf given an input and output direction, and one to generate a sample direction and a pdf given two random numbers.In my renderer, I want to have the shading api be as simple as possible, but still provide the sort of physical accuracy that pbrt has. So my base shader class would have something likeclass Shader{public:    virtual Vec3 sampleDirection( const float32 u1, const float32 u2, float32& pdf )    {   return generateSchlickSampleDirection( specularity_, isotropy_, u1, u2, pdf );    }};generateSchlickSampleDirection would compute a direction according to the schlick shading model using the member variable parameters, which by default would be completely diffuse so it would just generate a uniform direction in the hemisphere.User shaders deriving from Shader then have two levels of control. They can either modify the schlick paremeters to roughly match the brdf (useful if it's not really physically correct, or is some arbitrary combination of others), or they can override sampleDirection completely and implement it properly if they know how.By default it'll still be correct (unless it's a perfectly specular surface, which I'll have to treat differently), just subject to high variance.   ;Quote:Original post by Max_PayneFor a path tracer, it would seem that a shader, knowing all the basic properties of a surface point, simply has to compute the amount of light reflected at that point in a given direction (what's the GI term for this?). The direction being the incoming direction of the ray.However, for photon mapping, where photons need to be traced from a light, it would seem that surfaces will need a second shader subroutine. One responsible for actually determining where photons will be traced to.Is there any way around this, and make the shader definition simpler? Perhaps a shader function that does things probabilistically all the time (russian roulette?). Given an incoming photon, it decides of the new photon direction based on russian roulette. But then, this seems like it would be inefficient as it would not compute direct illumination for surfaces all the time.The are several ways to do this, but I think the most usable way ( and common) is for all you shaders to take an incident and exident direction and then the photon mapper does the appropriate monte-carlo sampling. OTherwise, its fairly difficult to convert shaders from a parameterized BRDF model to their statistical equivalant.   ;Quote:OTherwise, its fairly difficult to convert shaders from a parameterized BRDF model to their statistical equivalant.why? most of the good reflection models can be importance sampled to some extent, the technique is to do a function inversion on the cdf.  if this can't be done, you can usually do it on a simpler function that has a similar shape.  if all else fails you can do rejction sampling, or a uniform sampling.   ;Quote:Original post by timwQuote:OTherwise, its fairly difficult to convert shaders from a parameterized BRDF model to their statistical equivalant.why? most of the good reflection models can be importance sampled to some extent, the technique is to do a function inversion on the cdf.  if this can't be done, you can usually do it on a simpler function that has a similar shape.  if all else fails you can do rejction sampling, or a uniform sampling.Well, if this sounds simple to you then you are obvoisly very good at it. In my expeirence fitting even simple BRDFs is time consuming - making sure everything is exactly right, making sure your limit conditions are checked (really important), etc. Maple is your friend here. Now, for many of the models you can just look up their other forms (if they exist in the right parameterized way, which is dependent on how the BRDF was made). However, I beleive many of them don't have closed form solutions - (and I would imagine most shaders don't have closed form solutions).   ;  I'm guessing I will have to settle with shaders having a Shade function (to perform shading) and a Trace function (to perform correct photon tracing).The shade function will probably look like this, in the case of a simplified phong shader:Color3f Shade(Vector3f P, Vector3f N, Vector3f L, ... other constands (ie: phong constants)){    Color3f DiffuseColor;    Color3f SpecularColor;    if (Kd > 0)    {   DiffuseColor = DiffuseIrradiance(P, N);    }    if (Ks > 0)    {   Vector3f R = ReflectedVector(N, L);   SpecularColor = Radiance(R);   SpecularColor *= Pow(Dot(L, R), n);    }    return Kd * DiffuseColor + Ks * SpecularColor;}This simple shader would not account for refraction, but for now that's a detail. The main point is that when performing normal shading, irradiance samples could come from the irradiance cache (in the case of diffuse irradiance). However, the same shader could be performed to trace markov chain. Except that now the shader virtual machine would trace a single bounce and a single light-biased ray for the diffuse irradiance.   