daily pastebin goal
42%
SHARE
TWEET

Sh-Coeff fn

a guest Jan 25th, 2015 417 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.         void sphericalHarmonicsEvaluateDirection(float * result, int order,
  2.                 const Math::Vector3 & dir)
  3.         {
  4.                 result[0] = 0.282095;
  5.                 result[1] = 0.488603 *  dir.y;
  6.                 result[2] = 0.488603 *  dir.z;
  7.                 result[3] = 0.488603 *  dir.x;
  8.                 result[4] = 1.092548 *  dir.x*dir.y;
  9.                 result[5] = 1.092548 *  dir.y*dir.z;
  10.                 result[6] = 0.315392 * (3.f*dir.z*dir.z - 1.f);
  11.                 result[7] = 1.092548 *  dir.x * dir.z;
  12.                 result[8] = 0.546274 * (dir.x*dir.x - dir.y*dir.y);
  13.         }
  14.  
  15.         void sphericalHarmonicsAdd(float * result, int order,
  16.                 const float * inputA, const float * inputB)
  17.         {
  18.                 const int numCoeff = order * order;
  19.                 for (int i = 0; i < numCoeff; i++)
  20.                 {
  21.                         result[i] = inputA[i] + inputB[i];
  22.                 }
  23.         }
  24.  
  25.         void sphericalHarmonicsScale(float * result, int order,
  26.                 const float * input, float scale)
  27.         {
  28.                 const int numCoeff = order * order;
  29.                 for (int i = 0; i < numCoeff; i++)
  30.                 {
  31.                         result[i] = input[i] * scale;
  32.                 }
  33.         }
  34.  
  35.  
  36.  
  37.         void sphericalHarmonicsFromTexture(GLuint cubeTexture,
  38.                 std::vector<Math::Vector3> & output, const uint order)
  39.         {
  40.                 const uint sqOrder = order*order;
  41.  
  42.                 // allocate memory for calculations
  43.                 output.resize(sqOrder);
  44.                 std::vector<float> resultR(sqOrder);
  45.                 std::vector<float> resultG(sqOrder);
  46.                 std::vector<float> resultB(sqOrder);
  47.  
  48.                 // variables that describe current face of cube texture
  49.                 GLubyte* data;
  50.                 GLint width, height;
  51.                 GLint internalFormat;
  52.                 GLint numComponents;
  53.  
  54.                 // initialize values
  55.                 float fWt = 0.0f;
  56.                 for (uint i = 0; i < sqOrder; i++)
  57.                 {
  58.                         output[i].x = 0;
  59.                         output[i].y = 0;
  60.                         output[i].z = 0;
  61.                         resultR[i] = 0;
  62.                         resultG[i] = 0;
  63.                         resultB[i] = 0;
  64.                 }
  65.                 std::vector<float> shBuff(sqOrder);
  66.                 std::vector<float> shBuffB(sqOrder);
  67.                
  68.                
  69.                 const GLenum cubeSides[6] = {
  70.                         GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // Top
  71.                         GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // Left
  72.                         GL_TEXTURE_CUBE_MAP_POSITIVE_Z, // Front
  73.                         GL_TEXTURE_CUBE_MAP_POSITIVE_X, // Right
  74.                         GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, // Back
  75.                         GL_TEXTURE_CUBE_MAP_NEGATIVE_Y // Bottom
  76.                 };
  77.  
  78.                 // bind current texture
  79.                 glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);
  80.  
  81.                 int level = 0;
  82.                 // for each face of cube texture
  83.                 for (int face = 0; face < 6; face++)
  84.                 {
  85.                         // get width and height
  86.                         glGetTexLevelParameteriv(cubeSides[face], level, GL_TEXTURE_WIDTH, &width);
  87.                         glGetTexLevelParameteriv(cubeSides[face], level, GL_TEXTURE_HEIGHT, &height);
  88.  
  89.                         if (width != height)
  90.                         {
  91.                                 return;
  92.                         }
  93.  
  94.                         // get format of data in texture
  95.  
  96.                         glGetTexLevelParameteriv(cubeSides[face], level,
  97.                                 GL_TEXTURE_INTERNAL_FORMAT, &internalFormat);
  98.  
  99.                         // get data from texture
  100.                         if (internalFormat == GL_RGBA)
  101.                         {
  102.                                 numComponents = 4;
  103.                                 data = new GLubyte[numComponents * width * width];
  104.                         }
  105.                         else if (internalFormat == GL_RGB)
  106.                         {
  107.                                 numComponents = 3;
  108.                                 data = new GLubyte[numComponents * width * width];
  109.                         }
  110.                         else
  111.                         {
  112.                                 return;
  113.                         }
  114.                         glGetTexImage(cubeSides[face], level, internalFormat, GL_UNSIGNED_BYTE, data);
  115.  
  116.                         // step between two texels for range [0, 1]
  117.                         float invWidth = 1.0f / float(width);
  118.                         // initial negative bound for range [-1, 1]
  119.                         float negativeBound = -1.0f + invWidth;
  120.                         // step between two texels for range [-1, 1]
  121.                         float invWidthBy2 = 2.0f / float(width);
  122.  
  123.                         for (int y = 0; y < width; y++)
  124.                         {
  125.                                 // texture coordinate V in range [-1 to 1]
  126.                                 const float fV = negativeBound + float(y) * invWidthBy2;
  127.  
  128.                                 for (int x = 0; x < width; x++)
  129.                                 {
  130.                                         // texture coordinate U in range [-1 to 1]
  131.                                         const float fU = negativeBound + float(x) * invWidthBy2;
  132.  
  133.                                         // determine direction from center of cube texture to current texel
  134.                                         Math::Vector3 dir;
  135.                                         switch (cubeSides[face])
  136.                                         {
  137.                                         case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  138.                                                 dir.x = 1.0f;
  139.                                                 dir.y = 1.0f - (invWidthBy2 * float(y) + invWidth);
  140.                                                 dir.z = 1.0f - (invWidthBy2 * float(x) + invWidth);
  141.                                                 //dir = -dir;
  142.                                                 break;
  143.                                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  144.                                                 dir.x = -1.0f;
  145.                                                 dir.y = 1.0f - (invWidthBy2 * float(y) + invWidth);
  146.                                                 dir.z = -1.0f + (invWidthBy2 * float(x) + invWidth);
  147.                                                 //dir = dir;
  148.                                                 break;
  149.                                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  150.                                                 dir.x = -1.0f + (invWidthBy2 * float(x) + invWidth);
  151.                                                 dir.y = 1.0f;
  152.                                                 dir.z = -1.0f + (invWidthBy2 * float(y) + invWidth);
  153.                                                 //dir = dir;
  154.                                                 break;
  155.                                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  156.                                                 dir.x = -1.0f + (invWidthBy2 * float(x) + invWidth);
  157.                                                 dir.y = -1.0f;
  158.                                                 dir.z = 1.0f - (invWidthBy2 * float(y) + invWidth);
  159.                                                 //dir = dir; //!
  160.                                                 break;
  161.                                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  162.                                                 dir.x = -1.0f + (invWidthBy2 * float(x) + invWidth);
  163.                                                 dir.y = 1.0f - (invWidthBy2 * float(y) + invWidth);
  164.                                                 dir.z = 1.0f;
  165.                                                 break;
  166.                                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  167.                                                 dir.x = 1.0f - (invWidthBy2 * float(x) + invWidth);
  168.                                                 dir.y = 1.0f - (invWidthBy2 * float(y) + invWidth);
  169.                                                 dir.z = -1.0f;
  170.                                                 break;
  171.                                         default:
  172.                                                 return;
  173.                                         }
  174.  
  175.                                         // normalize direction
  176.                                         dir = Math::Normalize(dir);
  177.  
  178.  
  179.                                         // scale factor depending on distance from center of the face
  180.                                         const float fDiffSolid = 4.0f / ((1.0f + fU*fU + fV*fV) *
  181.                                                 sqrtf(1.0f + fU*fU + fV*fV));
  182.                                         fWt += fDiffSolid;
  183.  
  184.                                         // calculate coefficients of spherical harmonics for current direction
  185.                                         sphericalHarmonicsEvaluateDirection(shBuff.data(), order, dir);
  186.  
  187.                                         // index of texel in texture
  188.                                         uint pixOffsetIndex = (x + y * width) * numComponents;
  189.                                         // get color from texture and map to range [0, 1]
  190.                                         Math::Vector3 clr(
  191.                                                 float(data[pixOffsetIndex]) / 255,
  192.                                                 float(data[pixOffsetIndex + 1]) / 255,
  193.                                                 float(data[pixOffsetIndex + 2]) / 255
  194.                                                 );
  195.  
  196.                                         //clr.x = pow(clr.x, 1.1f);
  197.                                         //clr.y = pow(clr.y, 1.1f);
  198.                                         //clr.z = pow(clr.z, 1.1f);
  199.  
  200.                                         clr.x = clr.x*0.5f;
  201.                                         clr.y = clr.y*0.5f;
  202.                                         clr.z = clr.z*0.5f;
  203.  
  204.                                         // scale color and add to previously accumulated coefficients
  205.                                         sphericalHarmonicsScale(shBuffB.data(), order,
  206.                                                 shBuff.data(), clr.x * fDiffSolid);
  207.                                         sphericalHarmonicsAdd(resultR.data(), order,
  208.                                                 resultR.data(), shBuffB.data());
  209.  
  210.                                         sphericalHarmonicsScale(shBuffB.data(), order,
  211.                                                 shBuff.data(), clr.y * fDiffSolid);
  212.                                         sphericalHarmonicsAdd(resultG.data(), order,
  213.                                                 resultG.data(), shBuffB.data());
  214.  
  215.                                         sphericalHarmonicsScale(shBuffB.data(), order,
  216.                                                 shBuff.data(), clr.z * fDiffSolid);
  217.                                         sphericalHarmonicsAdd(resultB.data(), order,
  218.                                                 resultB.data(), shBuffB.data());
  219.                                 }
  220.                         }
  221.  
  222.                         delete[] data;
  223.                 }
  224.  
  225.                 // final scale for coefficients
  226.                 const float fNormProj = (4.0f * Math::PI<float>()) / fWt;
  227.                 sphericalHarmonicsScale(resultR.data(), order, resultR.data(), fNormProj);
  228.                 sphericalHarmonicsScale(resultG.data(), order, resultG.data(), fNormProj);
  229.                 sphericalHarmonicsScale(resultB.data(), order, resultB.data(), fNormProj);
  230.  
  231.                 // save result
  232.                 for (uint i = 0; i < sqOrder; i++)
  233.                 {
  234.                         output[i].x = resultR[i];
  235.                         output[i].y = resultG[i];
  236.                         output[i].z = resultB[i];
  237.                 }
  238.  
  239.                 //glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
  240.         }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top