User Tools

Site Tools


Sidebar

irradiance_lys

This is an old revision of the document!


Irradiance

Short paragraph explaining the function of the Irradiance stuff here, along with a nice picture for eye candy.

Irradiance As A Spherical Harmonics Expansion

Lys allows you to export the irradiance as a nine coefficient spherical harmonic expansion per channel.

These may be exported either as text or as a 9×1 floating point texture. The initial pixel represents the first band. The next three pixels represent the second band and the last five pixels represent the third band of the expansion. The orientation of the spherical harmonic expansion is identical to that of the destination cube map and the color space is always linear. An example of how to sample the function is shown below.

float coeffsSH(const int l, const int m, vec3 v);
 
vec3 SampleExpansionSH(sampler2D ShCoeffs_tex, vec3 v)
{
   // fetch all coefficients
   // pre-load these if you intend to sample more than once.
   vec3 coeffL0 = texelFetch(ShCoeffs_tex, ivec2(0,0), 0).xyz;
 
   vec3 coeffL1[3] = vec3[3]( texelFetch(ShCoeffs_tex, ivec2(1,0), 0).xyz,
                  texelFetch(ShCoeffs_tex, ivec2(2,0), 0).xyz,
                  texelFetch(ShCoeffs_tex, ivec2(3,0), 0).xyz );
 
   vec3 coeffL2[5] = vec3[5]( texelFetch(ShCoeffs_tex, ivec2(4,0), 0).xyz,
                  texelFetch(ShCoeffs_tex, ivec2(5,0), 0).xyz,
                  texelFetch(ShCoeffs_tex, ivec2(6,0), 0).xyz,
                  texelFetch(ShCoeffs_tex, ivec2(7,0), 0).xyz,
                  texelFetch(ShCoeffs_tex, ivec2(8,0), 0).xyz );
 
   // sample and sum up all contributions
   vec3 res = coeffsSH(0, 0, v) * coeffL0 + 
         coeffsSH(1, -1, v) * coeffL1[0] + coeffsSH(1, 0, v) * coeffL1[1] + coeffsSH(1, 1, v) * coeffL1[2] +
         coeffsSH(2, -2, v) * coeffL2[0] + coeffsSH(2, -1, v) * coeffL2[1] + coeffsSH(2, 0, v) * coeffL2[2] +
         coeffsSH(2, 1, v) * coeffL2[3] + coeffsSH(2, 2, v) * coeffL2[4];
 
   res = max(res, vec3(0.0));	// don't want negative values
 
   // to view as color divide by pi and convert to gamma space
   // vec3 vGammaColor = pow(res/M_PI, 1/2.2);
 
 
   return res;
}
 
// though this function looks complex most of it is optimized away
// by the shader compiler since l and m are known compile time.
float coeffsSH(const int l, const int m, vec3 v)
{
   float fRes = (1.0/2.0) * sqrt(1.0/M_PI);
   float x = v.x, y = v.y, z = v.z;
 
   switch(l)
   {
      case 1:
      { fRes = (1.0/2.0) * sqrt(3.0f/M_PI) * (m==-1 ? y : (m==0 ? z : x));} break;
      case 2:
      {
         const float fS = (m==0 || m==2 ? 0.25 : 0.5) * sqrt((m==0 ? 5.0 : 15.0) / M_PI);
 
         if(m==-2) fRes = fS * x*y;
         else if(m==-1) fRes = fS * y*z;
         else if(m==0) fRes = fS * (2*z*z - x*x - y*y);
         else if(m==1) fRes = fS * z*x;
         else fRes = fS * (x*x-y*y);
      }
      break;
   }
 
   return fRes;
}

Irradiance vs Spherical Harmonics

Above we have set out renders1) featuring results of irradiance vs spherical harmonics. The results using irradiance are on the left whereas the right shows the results obtained from spherical harmonics.
1) All HDRI photo based source images shown in the above were kindly provided by Marmoset. http://www.marmoset.co
irradiance_lys.1417154178.txt.gz · Last modified: 2017/05/23 03:49 (external edit)