Moved SpecularIBLGenerator-shader into IBL.cpp, and ColoredLine

shader into Shaders. Fixed codying style of IBL somewhat.
This commit is contained in:
hiker 2015-05-11 08:09:09 +10:00
parent 93f24f2a74
commit 400f9c612b
7 changed files with 197 additions and 150 deletions

View File

@ -22,6 +22,26 @@
#include <set>
#include "central_settings.hpp"
class SpecularIBLGenerator : public Shader<SpecularIBLGenerator, core::matrix4,
float >,
public TextureReadNew<ST_TRILINEAR_CUBEMAP>
{
public:
GLuint m_tu_samples;
SpecularIBLGenerator()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert",
GL_FRAGMENT_SHADER, "importance_sampling_specular.frag");
assignUniforms("PermutationMatrix", "ViewportSize");
m_tu_samples = 1;
assignSamplerNames(m_program, 0, "tex", ST_TRILINEAR_CUBEMAP);
assignTextureUnit(m_tu_samples, "samples");
}
}; // SpecularIBLGenerator
// ============================================================================
static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)
{
switch (face)
@ -61,9 +81,10 @@ static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)
float norm = sqrt(x * x + y * y + z * z);
x /= norm, y /= norm, z /= norm;
return;
}
} // getXYZ
// ----------------------------------------------------------------------------
static void getYml(GLenum face, size_t edge_size,
float *Y00,
float *Y1minus1, float *Y10, float *Y11,
@ -107,18 +128,18 @@ static void getYml(GLenum face, size_t edge_size,
}
static void projectSH(Color *CubemapFace[6], size_t edge_size,
float *Y00[],
float *Y1minus1[], float *Y10[], float *Y11[],
float *Y2minus2[], float *Y2minus1[], float * Y20[], float *Y21[], float *Y22[],
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff
)
// ----------------------------------------------------------------------------
static void projectSH(Color *cubemap_face[6], size_t edge_size, float *Y00[],
float *Y1minus1[], float *Y10[], float *Y11[],
float *Y2minus2[], float *Y2minus1[], float * Y20[],
float *Y21[], float *Y22[], float *blue_sh_coeff,
float *green_sh_coeff, float *red_sh_coeff)
{
for (unsigned i = 0; i < 9; i++)
{
blueSHCoeff[i] = 0;
greenSHCoeff[i] = 0;
redSHCoeff[i] = 0;
blue_sh_coeff[i] = 0;
green_sh_coeff[i] = 0;
red_sh_coeff[i] = 0;
}
float wh = float(edge_size * edge_size);
@ -127,7 +148,9 @@ static void projectSH(Color *CubemapFace[6], size_t edge_size,
float g0 = 0., g1 = 0., g2 = 0., g3 = 0., g4 = 0., g5 = 0., g6 = 0., g7 = 0., g8 = 0.;
for (unsigned face = 0; face < 6; face++)
{
#pragma omp parallel for reduction(+ : b0, b1, b2, b3, b4, b5, b6, b7, b8, r0, r1, r2, r3, r4, r5, r6, r7, r8, g0, g1, g2, g3, g4, g5, g6, g7, g8)
#pragma omp parallel for reduction(+ : b0, b1, b2, b3, b4, b5, b6, b7, b8, \
r0, r1, r2, r3, r4, r5, r6, r7, r8, \
g0, g1, g2, g3, g4, g5, g6, g7, g8)
for (int i = 0; i < int(edge_size); i++)
{
for (unsigned j = 0; j < edge_size; j++)
@ -143,9 +166,9 @@ static void projectSH(Color *CubemapFace[6], size_t edge_size,
// Constant obtained by projecting unprojected ref values
float solidangle = 2.75f / (wh * pow(d, 1.5f));
// pow(., 2.2) to convert from srgb
float b = CubemapFace[face][edge_size * i + j].Blue;
float g = CubemapFace[face][edge_size * i + j].Green;
float r = CubemapFace[face][edge_size * i + j].Red;
float b = cubemap_face[face][edge_size * i + j].Blue;
float g = cubemap_face[face][edge_size * i + j].Green;
float r = cubemap_face[face][edge_size * i + j].Red;
b0 += b * Y00[face][idx] * solidangle;
b1 += b * Y1minus1[face][idx] * solidangle;
@ -181,38 +204,46 @@ static void projectSH(Color *CubemapFace[6], size_t edge_size,
}
}
blueSHCoeff[0] = b0;
blueSHCoeff[1] = b1;
blueSHCoeff[2] = b2;
blueSHCoeff[3] = b3;
blueSHCoeff[4] = b4;
blueSHCoeff[5] = b5;
blueSHCoeff[6] = b6;
blueSHCoeff[7] = b7;
blueSHCoeff[8] = b8;
blue_sh_coeff[0] = b0;
blue_sh_coeff[1] = b1;
blue_sh_coeff[2] = b2;
blue_sh_coeff[3] = b3;
blue_sh_coeff[4] = b4;
blue_sh_coeff[5] = b5;
blue_sh_coeff[6] = b6;
blue_sh_coeff[7] = b7;
blue_sh_coeff[8] = b8;
redSHCoeff[0] = r0;
redSHCoeff[1] = r1;
redSHCoeff[2] = r2;
redSHCoeff[3] = r3;
redSHCoeff[4] = r4;
redSHCoeff[5] = r5;
redSHCoeff[6] = r6;
redSHCoeff[7] = r7;
redSHCoeff[8] = r8;
red_sh_coeff[0] = r0;
red_sh_coeff[1] = r1;
red_sh_coeff[2] = r2;
red_sh_coeff[3] = r3;
red_sh_coeff[4] = r4;
red_sh_coeff[5] = r5;
red_sh_coeff[6] = r6;
red_sh_coeff[7] = r7;
red_sh_coeff[8] = r8;
greenSHCoeff[0] = g0;
greenSHCoeff[1] = g1;
greenSHCoeff[2] = g2;
greenSHCoeff[3] = g3;
greenSHCoeff[4] = g4;
greenSHCoeff[5] = g5;
greenSHCoeff[6] = g6;
greenSHCoeff[7] = g7;
greenSHCoeff[8] = g8;
}
green_sh_coeff[0] = g0;
green_sh_coeff[1] = g1;
green_sh_coeff[2] = g2;
green_sh_coeff[3] = g3;
green_sh_coeff[4] = g4;
green_sh_coeff[5] = g5;
green_sh_coeff[6] = g6;
green_sh_coeff[7] = g7;
green_sh_coeff[8] = g8;
} // projectSH
void SphericalHarmonics(Color *CubemapFace[6], size_t edge_size, float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff)
// ----------------------------------------------------------------------------
/** Generate the 9 first SH coefficients for each color channel
* using the cubemap provided by CubemapFace.
* \param textures sequence of 6 square textures.
* \param row/columns count of textures.
*/
void generateSphericalHarmonics(Color *cubemap_face[6], size_t edge_size,
float *blue_sh_coeff, float *green_sh_coeff,
float *red_sh_coeff)
{
float *Y00[6];
float *Y1minus1[6];
@ -236,15 +267,14 @@ void SphericalHarmonics(Color *CubemapFace[6], size_t edge_size, float *blueSHCo
Y21[face] = new float[edge_size * edge_size];
Y22[face] = new float[edge_size * edge_size];
getYml(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, edge_size, Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
getYml(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, edge_size, Y00[face],
Y1minus1[face], Y10[face], Y11[face], Y2minus2[face],
Y2minus1[face], Y20[face], Y21[face], Y22[face]);
}
projectSH(CubemapFace, edge_size,
Y00,
Y1minus1, Y10, Y11,
Y2minus2, Y2minus1, Y20, Y21, Y22,
blueSHCoeff, greenSHCoeff, redSHCoeff
);
projectSH(cubemap_face, edge_size, Y00, Y1minus1, Y10, Y11, Y2minus2,
Y2minus1, Y20, Y21, Y22, blue_sh_coeff, green_sh_coeff,
red_sh_coeff);
for (unsigned face = 0; face < 6; face++)
{
@ -258,38 +288,49 @@ void SphericalHarmonics(Color *CubemapFace[6], size_t edge_size, float *blueSHCo
delete[] Y21[face];
delete[] Y22[face];
}
}
} // generateSphericalHarmonics
// ----------------------------------------------------------------------------
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html
/** Returns the index-th pair from Hammersley set of pseudo random set.
Hammersley set is a uniform distribution between 0 and 1 for 2 components.
We use the natural indexation on the set to avoid storing the whole set.
\param index of the pair
\param size of the set. */
std::pair<float, float> HammersleySequence(int index, int samples)
std::pair<float, float> getHammersleySequence(int index, int samples)
{
float InvertedBinaryRepresentation = 0.;
for (size_t i = 0; i < 32; i++)
{
InvertedBinaryRepresentation += ((index >> i) & 0x1) * powf(.5, (float) (i + 1.));
InvertedBinaryRepresentation += ((index >> i) & 0x1)
* powf(.5, (float) (i + 1.));
}
return std::make_pair(float(index) / float(samples), InvertedBinaryRepresentation);
}
return std::make_pair(float(index) / float(samples),
InvertedBinaryRepresentation);
} // HammersleySequence
/** Returns a pseudo random (theta, phi) generated from a probability density function modeled after Phong function.
\param a pseudo random float pair from a uniform density function between 0 and 1.
\param exponent from the Phong formula. */
std::pair<float, float> ImportanceSamplingPhong(std::pair<float, float> Seeds, float exponent)
// ----------------------------------------------------------------------------
/** Returns a pseudo random (theta, phi) generated from a probability density
* function modeled after Phong function.
* \param a pseudo random float pair from a uniform density function between
* 0 and 1.
* \param exponent from the Phong formula.
*/
std::pair<float, float> getImportanceSamplingPhong(std::pair<float, float> Seeds,
float exponent)
{
return std::make_pair(acosf(powf(Seeds.first, 1.f / (exponent + 1.f))), 2.f * 3.14f * Seeds.second);
}
return std::make_pair(acosf(powf(Seeds.first, 1.f / (exponent + 1.f))),
2.f * 3.14f * Seeds.second);
} // getImportanceSamplingPhong
static
core::matrix4 getPermutationMatrix(size_t indexX, float valX, size_t indexY, float valY, size_t indexZ, float valZ)
// ----------------------------------------------------------------------------
static core::matrix4 getPermutationMatrix(size_t indexX, float valX,
size_t indexY, float valY,
size_t indexZ, float valZ)
{
core::matrix4 resultMat;
float *M = resultMat.pointer();
core::matrix4 result_mat;
float *M = result_mat.pointer();
memset(M, 0, 16 * sizeof(float));
assert(indexX < 4);
assert(indexY < 4);
@ -297,9 +338,10 @@ core::matrix4 getPermutationMatrix(size_t indexX, float valX, size_t indexY, flo
M[indexX] = valX;
M[4 + indexY] = valY;
M[8 + indexZ] = valZ;
return resultMat;
}
return result_mat;
} // getPermutationMatrix
// ----------------------------------------------------------------------------
GLuint generateSpecularCubemap(GLuint probe)
{
GLuint cubemap_texture;
@ -308,7 +350,10 @@ GLuint generateSpecularCubemap(GLuint probe)
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap_texture);
size_t cubemap_size = 256;
for (int i = 0; i < 6; i++)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA16F, cubemap_size, cubemap_size, 0, GL_BGRA, GL_FLOAT, 0);
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA16F,
cubemap_size, cubemap_size, 0, GL_BGRA, GL_FLOAT, 0);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
if (!CVS->isDefferedEnabled())
@ -320,7 +365,7 @@ GLuint generateSpecularCubemap(GLuint probe)
glViewport(0, 0, cubemap_size, cubemap_size);
GLenum bufs[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, bufs);
UtilShader::SpecularIBLGenerator::getInstance()->use();
SpecularIBLGenerator::getInstance()->use();
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
@ -337,7 +382,8 @@ GLuint generateSpecularCubemap(GLuint probe)
for (unsigned level = 0; level < 8; level++)
{
// Blinn Phong can be approximated by Phong with 4x the specular coefficient
// Blinn Phong can be approximated by Phong with 4x the specular
// coefficient
// See http://seblagarde.wordpress.com/2012/03/29/relationship-between-phong-and-blinn-lighting-model/
// NOTE : Removed because it makes too sharp reflexion
float roughness = (8 - level) * pow(2.f, 10.f) / 8.f;
@ -346,17 +392,21 @@ GLuint generateSpecularCubemap(GLuint probe)
float *tmp = new float[2048];
for (unsigned i = 0; i < 1024; i++)
{
std::pair<float, float> sample = ImportanceSamplingPhong(HammersleySequence(i, 1024), roughness);
std::pair<float, float> sample =
getImportanceSamplingPhong(getHammersleySequence(i, 1024),
roughness);
tmp[2 * i] = sample.first;
tmp[2 * i + 1] = sample.second;
}
glBindVertexArray(0);
glActiveTexture(GL_TEXTURE0 + UtilShader::SpecularIBLGenerator::getInstance()->TU_Samples);
glActiveTexture(GL_TEXTURE0 +
SpecularIBLGenerator::getInstance()->m_tu_samples);
GLuint sampleTex, sampleBuffer;
glGenBuffers(1, &sampleBuffer);
glBindBuffer(GL_TEXTURE_BUFFER, sampleBuffer);
glBufferData(GL_TEXTURE_BUFFER, 2048 * sizeof(float), tmp, GL_STATIC_DRAW);
glBufferData(GL_TEXTURE_BUFFER, 2048 * sizeof(float), tmp,
GL_STATIC_DRAW);
glGenTextures(1, &sampleTex);
glBindTexture(GL_TEXTURE_BUFFER, sampleTex);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, sampleBuffer);
@ -365,16 +415,20 @@ GLuint generateSpecularCubemap(GLuint probe)
for (unsigned face = 0; face < 6; face++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubemap_texture, level);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
cubemap_texture, level);
GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(status == GL_FRAMEBUFFER_COMPLETE);
UtilShader::SpecularIBLGenerator::getInstance()->setTextureUnits(probe);
UtilShader::SpecularIBLGenerator::getInstance()->setUniforms(M[face], viewportSize);
SpecularIBLGenerator::getInstance()->setTextureUnits(probe);
SpecularIBLGenerator::getInstance()->setUniforms(M[face],
viewportSize);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
glActiveTexture(GL_TEXTURE0 + UtilShader::SpecularIBLGenerator::getInstance()->TU_Samples);
glActiveTexture( GL_TEXTURE0
+ SpecularIBLGenerator::getInstance()->m_tu_samples);
glBindBuffer(GL_TEXTURE_BUFFER, 0);
glBindTexture(GL_TEXTURE_BUFFER, 0);
@ -385,4 +439,4 @@ GLuint generateSpecularCubemap(GLuint probe)
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbo);
return cubemap_texture;
}
} // generateSpecularCubemap

View File

@ -27,12 +27,9 @@ struct Color
float Blue;
};
/** Generate the 9 first SH coefficients for each color channel
using the cubemap provided by CubemapFace.
* \param textures sequence of 6 square textures.
* \param row/columns count of textures.
*/
void SphericalHarmonics(Color *CubemapFace[6], size_t edge_size, float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff);
void generateSphericalHarmonics(Color *CubemapFace[6], size_t edge_size,
float *blue_sh_coeff, float *green_sh_coeff,
float *red_sh_coeff);
GLuint generateSpecularCubemap(GLuint probe);
#endif

View File

@ -295,12 +295,13 @@ void draw3DLine(const core::vector3df& start,
end.X, end.Y, end.Z
};
glBindVertexArray(UtilShader::ColoredLine::getInstance()->vao);
glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::getInstance()->vbo);
Shaders::ColoredLine *line = Shaders::ColoredLine::getInstance();
line->bindVertexArray();
line->bindBuffer();
glBufferSubData(GL_ARRAY_BUFFER, 0, 6 * sizeof(float), vertex);
UtilShader::ColoredLine::getInstance()->use();
UtilShader::ColoredLine::getInstance()->setUniforms(color);
line->use();
line->setUniforms(color);
glDrawArrays(GL_LINES, 0, 2);
glGetError();

View File

@ -192,10 +192,11 @@ void IrrDriver::renderGLSL(float dt)
// Render bounding boxes
if (irr_driver->getBoundingBoxesViz())
{
UtilShader::ColoredLine::getInstance()->use();
glBindVertexArray(UtilShader::ColoredLine::getInstance()->vao);
glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::getInstance()->vbo);
UtilShader::ColoredLine::getInstance()->setUniforms(SColor(255, 255, 0, 0));
Shaders::ColoredLine *line = Shaders::ColoredLine::getInstance();
line->use();
line->bindVertexArray();
line->bindBuffer();
line->setUniforms(SColor(255, 255, 0, 0));
const float *tmp = BoundingBoxes.data();
for (unsigned int i = 0; i < BoundingBoxes.size(); i += 1024 * 6)
{
@ -221,12 +222,13 @@ void IrrDriver::renderGLSL(float dt)
const std::map<video::SColor, std::vector<float> >& lines = debug_drawer->getLines();
std::map<video::SColor, std::vector<float> >::const_iterator it;
UtilShader::ColoredLine::getInstance()->use();
glBindVertexArray(UtilShader::ColoredLine::getInstance()->vao);
glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::getInstance()->vbo);
Shaders::ColoredLine *line = Shaders::ColoredLine::getInstance();
line->use();
line->bindVertexArray();
line->bindBuffer();
for (it = lines.begin(); it != lines.end(); it++)
{
UtilShader::ColoredLine::getInstance()->setUniforms(it->first);
line->setUniforms(it->first);
const std::vector<float> &vertex = it->second;
const float *tmp = vertex.data();
for (unsigned int i = 0; i < vertex.size(); i += 1024 * 6)

View File

@ -373,7 +373,7 @@ void IrrDriver::generateDiffuseCoefficients()
}
}
SphericalHarmonics(FloatTexCube, sh_w, blueSHCoeff, greenSHCoeff, redSHCoeff);
generateSphericalHarmonics(FloatTexCube, sh_w, blueSHCoeff, greenSHCoeff, redSHCoeff);
for (unsigned i = 0; i < 6; i++)
{

View File

@ -225,6 +225,26 @@ GLuint LoadShader(const char * file, unsigned type)
Shaders::ColoredLine::ColoredLine()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "object_pass.vert",
GL_FRAGMENT_SHADER, "coloredquad.frag");
assignUniforms("color");
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, 6 * 1024 * sizeof(float), 0, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
} // Shaders::ColoredLine
GLuint quad_vbo, tri_vbo;
GLuint SharedObject::FullScreenQuadVAO = 0;
@ -508,24 +528,6 @@ void bypassUBO(GLuint Program)
namespace UtilShader
{
ColoredLine::ColoredLine()
{
loadProgram(OBJECT,
GL_VERTEX_SHADER, "object_pass.vert",
GL_FRAGMENT_SHADER, "coloredquad.frag");
assignUniforms("color");
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 6 * 1024 * sizeof(float), 0, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
@ -539,20 +541,6 @@ unsigned getGLSLVersion()
return CVS->getGLSLVersion();
}
namespace UtilShader
{
SpecularIBLGenerator::SpecularIBLGenerator()
{
loadProgram(OBJECT,
GL_VERTEX_SHADER, "screenquad.vert",
GL_FRAGMENT_SHADER, "importance_sampling_specular.frag");
assignUniforms("PermutationMatrix", "ViewportSize");
TU_Samples = 1;
assignSamplerNames(m_program, 0, "tex", ST_TRILINEAR_CUBEMAP);
assignTextureUnit(TU_Samples, "samples");
}
}
namespace MeshShader
{
// Solid Normal and depth pass shaders

View File

@ -40,25 +40,6 @@ public:
static GLuint UIVAO;
};
namespace UtilShader
{
class ColoredLine : public Shader<ColoredLine, video::SColor>
{
public:
GLuint vao, vbo;
ColoredLine();
};
class SpecularIBLGenerator : public Shader<SpecularIBLGenerator, core::matrix4, float >,
public TextureReadNew<ST_TRILINEAR_CUBEMAP>
{
public:
GLuint TU_Samples;
SpecularIBLGenerator();
};
}
namespace MeshShader
{
@ -861,8 +842,32 @@ public:
void killShaders();
private:
};
// ========================================================================
/** Shader to draw a colored line.
*/
class ColoredLine : public Shader<ColoredLine, video::SColor>
{
private:
GLuint m_vao, m_vbo;
public:
ColoredLine();
// --------------------------------------------------------------------
/** Bind the vertex array of this shader. */
void bindVertexArray()
{
glBindVertexArray(m_vao);
} // bindVertexArray
// --------------------------------------------------------------------
/** Binds the vbo of this shader. */
void bindBuffer()
{
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
} // bindBuffer
}; // class ColoredLine
}; // class Shaders
#undef ENUM
#undef STR