IBL: Implement IBL
This commit is contained in:
parent
02fa3ceed0
commit
391053e368
49
data/shaders/diffuseenvmap.frag
Normal file
49
data/shaders/diffuseenvmap.frag
Normal file
@ -0,0 +1,49 @@
|
||||
uniform float blueLmn[9];
|
||||
uniform float greenLmn[9];
|
||||
uniform float redLmn[9];
|
||||
uniform sampler2D ntex;
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
out vec4 Diff;
|
||||
out vec4 Spec;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define Diff gl_FragData[0]
|
||||
#define Spec gl_FragData[1]
|
||||
#endif
|
||||
|
||||
vec3 DecodeNormal(vec2 n)
|
||||
{
|
||||
float z = dot(n, n) * 2. - 1.;
|
||||
vec2 xy = normalize(n) * sqrt(1. - z * z);
|
||||
return vec3(xy,z);
|
||||
}
|
||||
|
||||
mat4 getMatrix(float L[9])
|
||||
{
|
||||
float c1 = 0.429043, c2 = 0.511664, c3 = 0.743125, c4 = 0.886227, c5 = 0.247708;
|
||||
|
||||
return mat4(
|
||||
c1 * L[8] /*L22*/, c1 * L[4] /*L2-2*/, c1 * L[7] /*L21*/, c2 * L[3] /*L11*/,
|
||||
c1 * L[4], - c1 * L[8], c1 * L[5] /*L2-1*/, c2 * L[1] /*L1-1*/,
|
||||
c1 * L[7], c1 * L[5], c3 * L[6] /*L20*/, c2 * L[2] /*L10*/,
|
||||
c2 * L[3], c2 * L[1], c2 * L[2], c4 * L[0] /*L00*/ - c5 * L[6]
|
||||
);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec3 normal = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
|
||||
vec4 extendednormal = vec4(normal, 1.);
|
||||
mat4 rmat = getMatrix(redLmn);
|
||||
mat4 gmat = getMatrix(greenLmn);
|
||||
mat4 bmat = getMatrix(blueLmn);
|
||||
|
||||
float r = dot(extendednormal, rmat * extendednormal);
|
||||
float g = dot(extendednormal, gmat * extendednormal);
|
||||
float b = dot(extendednormal, bmat * extendednormal);
|
||||
|
||||
Diff = 0.25 * vec4(r, g, b, .1);
|
||||
Spec = vec4(0.);
|
||||
}
|
@ -1173,6 +1173,7 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector<video::ITexture*>
|
||||
assert(texture.size() == 6);
|
||||
SkyboxTextures = texture;
|
||||
SkyboxCubeMap = 0;
|
||||
ConvolutedSkyboxCubeMap = 0;
|
||||
return m_scene_manager->addSkyBoxSceneNode(texture[0], texture[1],
|
||||
texture[2], texture[3],
|
||||
texture[4], texture[5]);
|
||||
@ -1182,7 +1183,9 @@ void IrrDriver::suppressSkyBox()
|
||||
{
|
||||
SkyboxTextures.clear();
|
||||
glDeleteTextures(1, &SkyboxCubeMap);
|
||||
glDeleteTextures(1, &ConvolutedSkyboxCubeMap);
|
||||
SkyboxCubeMap = 0;
|
||||
ConvolutedSkyboxCubeMap = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -115,7 +115,10 @@ private:
|
||||
core::matrix4 m_ViewMatrix, m_InvViewMatrix, m_ProjMatrix, m_InvProjMatrix, m_ProjViewMatrix, m_InvProjViewMatrix;
|
||||
|
||||
std::vector<video::ITexture *> SkyboxTextures;
|
||||
GLuint SkyboxCubeMap;
|
||||
GLuint SkyboxCubeMap, ConvolutedSkyboxCubeMap;
|
||||
float blueSHCoeff[9];
|
||||
float greenSHCoeff[9];
|
||||
float redSHCoeff[9];
|
||||
|
||||
|
||||
/** Flag to indicate if a resolution change is pending (which will be
|
||||
|
@ -302,6 +302,27 @@ void PostProcessing::renderPointlight(const std::vector<float> &positions, const
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff)
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
|
||||
glUseProgram(FullScreenShader::DiffuseEnvMapShader::Program);
|
||||
glBindVertexArray(FullScreenShader::DiffuseEnvMapShader::vao);
|
||||
|
||||
setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::DiffuseEnvMapShader::setUniforms(bSHCoeff, gSHCoeff, rSHCoeff, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void PostProcessing::renderSunlight()
|
||||
{
|
||||
SunLightProvider * const cb = (SunLightProvider *) irr_driver->getCallback(ES_SUNLIGHT);
|
||||
|
@ -79,6 +79,7 @@ public:
|
||||
|
||||
void renderFog(const core::matrix4 &ipvmat);
|
||||
void renderSSAO(const core::matrix4 &invprojm, const core::matrix4 &projm);
|
||||
void renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff);
|
||||
|
||||
/** Blur the in texture */
|
||||
void renderGaussian3Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height);
|
||||
|
@ -741,6 +741,8 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
|
||||
video::SOverrideMaterial &overridemat,
|
||||
int cam, float dt)
|
||||
{
|
||||
if (SkyboxCubeMap)
|
||||
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
|
||||
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
|
||||
sun_ortho_matrix[i] *= getInvViewMatrix();
|
||||
core::array<video::IRenderTarget> rtts;
|
||||
@ -831,6 +833,8 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
|
||||
accumulatedLightEnergy.push_back(0.);
|
||||
}
|
||||
m_post_processing->renderPointlight(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy);
|
||||
if (SkyboxCubeMap)
|
||||
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
// Handle SSAO
|
||||
m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), true, false,
|
||||
SColor(255, 255, 255, 255));
|
||||
@ -916,13 +920,351 @@ static void createcubevao()
|
||||
}
|
||||
|
||||
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
|
||||
|
||||
static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)
|
||||
{
|
||||
switch (face)
|
||||
{
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
x = 1.;
|
||||
y = -i;
|
||||
z = -j;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
x = -1.;
|
||||
y = -i;
|
||||
z = j;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
x = j;
|
||||
y = 1.;
|
||||
z = i;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
x = j;
|
||||
y = -1;
|
||||
z = -i;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
x = j;
|
||||
y = -i;
|
||||
z = 1;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
x = -j;
|
||||
y = -i;
|
||||
z = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
float norm = sqrt(x * x + y * y + z * z);
|
||||
x /= norm, y /= norm, z /= norm;
|
||||
return;
|
||||
}
|
||||
|
||||
static void getYml(GLenum face, size_t width, size_t height,
|
||||
float *Y00,
|
||||
float *Y1minus1, float *Y10, float *Y11,
|
||||
float *Y2minus2, float *Y2minus1, float *Y20, float *Y21, float *Y22)
|
||||
{
|
||||
for (unsigned i = 0; i < width; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < height; j++)
|
||||
{
|
||||
float x, y, z;
|
||||
float fi = i, fj = j;
|
||||
fi /= width, fj /= height;
|
||||
fi = 2 * fi - 1, fj = 2 * fj - 1;
|
||||
getXYZ(face, fi, fj, x, y, z);
|
||||
|
||||
// constant part of Ylm
|
||||
float c00 = 0.282095;
|
||||
float c1minus1 = 0.488603;
|
||||
float c10 = 0.488603;
|
||||
float c11 = 0.488603;
|
||||
float c2minus2 = 1.092548;
|
||||
float c2minus1 = 1.092548;
|
||||
float c21 = 1.092548;
|
||||
float c20 = 0.315392;
|
||||
float c22 = 0.546274;
|
||||
|
||||
size_t idx = i * height + j;
|
||||
|
||||
Y00[idx] = c00;
|
||||
Y1minus1[idx] = c1minus1 * y;
|
||||
Y10[idx] = c10 * z;
|
||||
Y11[idx] = c11 * x;
|
||||
Y2minus2[idx] = c2minus2 * x * y;
|
||||
Y2minus1[idx] = c2minus1 * y * z;
|
||||
Y21[idx] = c21 * x * z;
|
||||
Y20[idx] = c20 * (3 * z * z - 1);
|
||||
Y22[idx] = c22 * (x * x - y * y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static float getTexelValue(unsigned i, unsigned j, size_t width, size_t height, float *Coeff, float *Y00, float *Y1minus1, float *Y10, float *Y11,
|
||||
float *Y2minus2, float * Y2minus1, float * Y20, float *Y21, float *Y22)
|
||||
{
|
||||
float d = sqrt(i * i + j * j + 1);
|
||||
float solidangle = 1.;
|
||||
size_t idx = i * height + j;
|
||||
float reconstructedVal = Y00[idx] * Coeff[0];
|
||||
reconstructedVal += Y1minus1[i * height + j] * Coeff[1] + Y10[i * height + j] * Coeff[2] + Y11[i * height + j] * Coeff[3];
|
||||
reconstructedVal += Y2minus2[idx] * Coeff[4] + Y2minus1[idx] * Coeff[5] + Y20[idx] * Coeff[6] + Y21[idx] * Coeff[7] + Y22[idx] * Coeff[8];
|
||||
reconstructedVal /= solidangle;
|
||||
return MAX2(255 * reconstructedVal, 0.);
|
||||
}
|
||||
|
||||
static void unprojectSH(float *output[], size_t width, size_t height,
|
||||
float *Y00[],
|
||||
float *Y1minus1[], float *Y10[], float *Y11[],
|
||||
float *Y2minus2[], float *Y2minus1[], float * Y20[],float *Y21[], float *Y22[],
|
||||
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff)
|
||||
{
|
||||
for (unsigned face = 0; face < 6; face++)
|
||||
{
|
||||
for (unsigned i = 0; i < width; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < height; j++)
|
||||
{
|
||||
float fi = i, fj = j;
|
||||
fi /= width, fj /= height;
|
||||
fi = 2 * fi - 1, fj = 2 * fj - 1;
|
||||
|
||||
output[face][4 * height * i + 4 * j + 2] = getTexelValue(i, j, width, height,
|
||||
redSHCoeff,
|
||||
Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
|
||||
output[face][4 * height * i + 4 * j + 1] = getTexelValue(i, j, width, height,
|
||||
greenSHCoeff,
|
||||
Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
|
||||
output[face][4 * height * i + 4 * j] = getTexelValue(i, j, width, height,
|
||||
blueSHCoeff,
|
||||
Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void projectSH(float *color[], size_t width, size_t height,
|
||||
float *Y00[],
|
||||
float *Y1minus1[], float *Y10[], float *Y11[],
|
||||
float *Y2minus2[], float *Y2minus1[], float * Y20[], float *Y21[], float *Y22[],
|
||||
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff
|
||||
)
|
||||
{
|
||||
for (unsigned i = 0; i < 9; i++)
|
||||
{
|
||||
blueSHCoeff[i] = 0;
|
||||
greenSHCoeff[i] = 0;
|
||||
redSHCoeff[i] = 0;
|
||||
}
|
||||
float wh = width * height;
|
||||
for (unsigned face = 0; face < 6; face++)
|
||||
{
|
||||
for (unsigned i = 0; i < width; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < height; j++)
|
||||
{
|
||||
size_t idx = i * height + j;
|
||||
float fi = i, fj = j;
|
||||
fi /= width, fj /= height;
|
||||
fi = 2 * fi - 1, fj = 2 * fj - 1;
|
||||
|
||||
|
||||
float d = sqrt(fi * fi + fj * fj + 1);
|
||||
|
||||
// Constant obtained by projecting unprojected ref values
|
||||
float solidangle = 2.75 / (wh * pow(d, 1.5));
|
||||
float b = color[face][4 * height * i + 4 * j] / 255.;
|
||||
float g = color[face][4 * height * i + 4 * j + 1] / 255.;
|
||||
float r = color[face][4 * height * i + 4 * j + 2] / 255.;
|
||||
|
||||
assert(b >= 0.);
|
||||
|
||||
blueSHCoeff[0] += b * Y00[face][idx] * solidangle;
|
||||
blueSHCoeff[1] += b * Y1minus1[face][idx] * solidangle;
|
||||
blueSHCoeff[2] += b * Y10[face][idx] * solidangle;
|
||||
blueSHCoeff[3] += b * Y11[face][idx] * solidangle;
|
||||
blueSHCoeff[4] += b * Y2minus2[face][idx] * solidangle;
|
||||
blueSHCoeff[5] += b * Y2minus1[face][idx] * solidangle;
|
||||
blueSHCoeff[6] += b * Y20[face][idx] * solidangle;
|
||||
blueSHCoeff[7] += b * Y21[face][idx] * solidangle;
|
||||
blueSHCoeff[8] += b * Y22[face][idx] * solidangle;
|
||||
|
||||
greenSHCoeff[0] += g * Y00[face][idx] * solidangle;
|
||||
greenSHCoeff[1] += g * Y1minus1[face][idx] * solidangle;
|
||||
greenSHCoeff[2] += g * Y10[face][idx] * solidangle;
|
||||
greenSHCoeff[3] += g * Y11[face][idx] * solidangle;
|
||||
greenSHCoeff[4] += g * Y2minus2[face][idx] * solidangle;
|
||||
greenSHCoeff[5] += g * Y2minus1[face][idx] * solidangle;
|
||||
greenSHCoeff[6] += g * Y20[face][idx] * solidangle;
|
||||
greenSHCoeff[7] += g * Y21[face][idx] * solidangle;
|
||||
greenSHCoeff[8] += g * Y22[face][idx] * solidangle;
|
||||
|
||||
|
||||
redSHCoeff[0] += r * Y00[face][idx] * solidangle;
|
||||
redSHCoeff[1] += r * Y1minus1[face][idx] * solidangle;
|
||||
redSHCoeff[2] += r * Y10[face][idx] * solidangle;
|
||||
redSHCoeff[3] += r * Y11[face][idx] * solidangle;
|
||||
redSHCoeff[4] += r * Y2minus2[face][idx] * solidangle;
|
||||
redSHCoeff[5] += r * Y2minus1[face][idx] * solidangle;
|
||||
redSHCoeff[6] += r * Y20[face][idx] * solidangle;
|
||||
redSHCoeff[7] += r * Y21[face][idx] * solidangle;
|
||||
redSHCoeff[8] += r * Y22[face][idx] * solidangle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void displayCoeff(float *SHCoeff)
|
||||
{
|
||||
printf("L00:%f\n", SHCoeff[0]);
|
||||
printf("L1-1:%f, L10:%f, L11:%f\n", SHCoeff[1], SHCoeff[2], SHCoeff[3]);
|
||||
printf("L2-2:%f, L2-1:%f, L20:%f, L21:%f, L22:%f\n", SHCoeff[4], SHCoeff[5], SHCoeff[6], SHCoeff[7], SHCoeff[8]);
|
||||
}
|
||||
|
||||
// Only for 9 coefficients
|
||||
static void testSH(char *color[6], size_t width, size_t height,
|
||||
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff)
|
||||
{
|
||||
float *Y00[6];
|
||||
float *Y1minus1[6];
|
||||
float *Y10[6];
|
||||
float *Y11[6];
|
||||
float *Y2minus2[6];
|
||||
float *Y2minus1[6];
|
||||
float *Y20[6];
|
||||
float *Y21[6];
|
||||
float *Y22[6];
|
||||
|
||||
float *testoutput[6];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
testoutput[i] = new float[width * height * 4];
|
||||
for (unsigned j = 0; j < width * height; j++)
|
||||
{
|
||||
testoutput[i][4 * j] = 0xFF & color[i][4 * j];
|
||||
testoutput[i][4 * j + 1] = 0xFF & color[i][4 * j + 1];
|
||||
testoutput[i][4 * j + 2] = 0xFF & color[i][4 * j + 2];
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned face = 0; face < 6; face++)
|
||||
{
|
||||
Y00[face] = new float[width * height];
|
||||
Y1minus1[face] = new float[width * height];
|
||||
Y10[face] = new float[width * height];
|
||||
Y11[face] = new float[width * height];
|
||||
Y2minus2[face] = new float[width * height];
|
||||
Y2minus1[face] = new float[width * height];
|
||||
Y20[face] = new float[width * height];
|
||||
Y21[face] = new float[width * height];
|
||||
Y22[face] = new float[width * height];
|
||||
|
||||
getYml(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, width, height, Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
|
||||
}
|
||||
|
||||
/* blueSHCoeff[0] = 0.54,
|
||||
blueSHCoeff[1] = .6, blueSHCoeff[2] = -.27, blueSHCoeff[3] = .01,
|
||||
blueSHCoeff[4] = -.12, blueSHCoeff[5] = -.47, blueSHCoeff[6] = -.15, blueSHCoeff[7] = .14, blueSHCoeff[8] = -.3;
|
||||
greenSHCoeff[0] = .44,
|
||||
greenSHCoeff[1] = .35, greenSHCoeff[2] = -.18, greenSHCoeff[3] = -.06,
|
||||
greenSHCoeff[4] = -.05, greenSHCoeff[5] = -.22, greenSHCoeff[6] = -.09, greenSHCoeff[7] = .21, greenSHCoeff[8] = -.05;
|
||||
redSHCoeff[0] = .79,
|
||||
redSHCoeff[1] = .39, redSHCoeff[2] = -.34, redSHCoeff[3] = -.29,
|
||||
redSHCoeff[4] = -.11, redSHCoeff[5] = -.26, redSHCoeff[6] = -.16, redSHCoeff[7] = .56, redSHCoeff[8] = .21;
|
||||
|
||||
printf("Blue:\n");
|
||||
displayCoeff(blueSHCoeff);
|
||||
printf("Green:\n");
|
||||
displayCoeff(greenSHCoeff);
|
||||
printf("Red:\n");
|
||||
displayCoeff(redSHCoeff);*/
|
||||
|
||||
projectSH(testoutput, width, height,
|
||||
Y00,
|
||||
Y1minus1, Y10, Y11,
|
||||
Y2minus2, Y2minus1, Y20, Y21, Y22,
|
||||
blueSHCoeff, greenSHCoeff, redSHCoeff
|
||||
);
|
||||
|
||||
printf("Blue:\n");
|
||||
displayCoeff(blueSHCoeff);
|
||||
printf("Green:\n");
|
||||
displayCoeff(greenSHCoeff);
|
||||
printf("Red:\n");
|
||||
displayCoeff(redSHCoeff);
|
||||
|
||||
|
||||
|
||||
// Convolute in frequency space
|
||||
/* float A0 = 3.141593;
|
||||
float A1 = 2.094395;
|
||||
float A2 = 0.785398;
|
||||
blueSHCoeff[0] *= A0;
|
||||
greenSHCoeff[0] *= A0;
|
||||
redSHCoeff[0] *= A0;
|
||||
for (unsigned i = 0; i < 3; i++)
|
||||
{
|
||||
blueSHCoeff[1 + i] *= A1;
|
||||
greenSHCoeff[1 + i] *= A1;
|
||||
redSHCoeff[1 + i] *= A1;
|
||||
}
|
||||
for (unsigned i = 0; i < 5; i++)
|
||||
{
|
||||
blueSHCoeff[4 + i] *= A2;
|
||||
greenSHCoeff[4 + i] *= A2;
|
||||
redSHCoeff[4 + i] *= A2;
|
||||
}
|
||||
|
||||
|
||||
unprojectSH(testoutput, width, height,
|
||||
Y00,
|
||||
Y1minus1, Y10, Y11,
|
||||
Y2minus2, Y2minus1, Y20, Y21, Y22,
|
||||
blueSHCoeff, greenSHCoeff, redSHCoeff
|
||||
);*/
|
||||
|
||||
|
||||
/* printf("Blue:\n");
|
||||
displayCoeff(blueSHCoeff);
|
||||
printf("Green:\n");
|
||||
displayCoeff(greenSHCoeff);
|
||||
printf("Red:\n");
|
||||
displayCoeff(redSHCoeff);
|
||||
|
||||
printf("\nAfter projection\n\n");*/
|
||||
|
||||
|
||||
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < width * height; j++)
|
||||
{
|
||||
color[i][4 * j] = MIN2(testoutput[i][4 * j], 255);
|
||||
color[i][4 * j + 1] = MIN2(testoutput[i][4 * j + 1], 255);
|
||||
color[i][4 * j + 2] = MIN2(testoutput[i][4 * j + 2], 255);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned face = 0; face < 6; face++)
|
||||
{
|
||||
delete[] testoutput[face];
|
||||
delete[] Y00[face];
|
||||
delete[] Y1minus1[face];
|
||||
delete[] Y10[face];
|
||||
delete[] Y11[face];
|
||||
}
|
||||
}
|
||||
|
||||
void IrrDriver::generateSkyboxCubemap()
|
||||
{
|
||||
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
|
||||
glGenTextures(1, &SkyboxCubeMap);
|
||||
glGenTextures(1, &ConvolutedSkyboxCubeMap);
|
||||
|
||||
GLint w = 0, h = 0;
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
@ -932,7 +1274,9 @@ void IrrDriver::generateSkyboxCubemap()
|
||||
}
|
||||
|
||||
const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 };
|
||||
char *rgba = new char[w * h * 4];
|
||||
char *rgba[6];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
rgba[i] = new char[w * h * 4];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
unsigned idx = texture_permutation[i];
|
||||
@ -945,13 +1289,22 @@ void IrrDriver::generateSkyboxCubemap()
|
||||
);
|
||||
SkyboxTextures[idx]->unlock();
|
||||
|
||||
image->copyToScaling(rgba, w, h);
|
||||
image->copyToScaling(rgba[i], w, h);
|
||||
image->drop();
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, SkyboxCubeMap);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba);
|
||||
image->drop();
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
|
||||
}
|
||||
delete[] rgba;
|
||||
|
||||
testSH(rgba, w, h, blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, ConvolutedSkyboxCubeMap);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
|
||||
}
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
delete[] rgba[i];
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
}
|
||||
|
||||
@ -981,7 +1334,7 @@ void IrrDriver::renderSkybox()
|
||||
transform.getInverse(invtransform);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, SkyboxCubeMap);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, ConvolutedSkyboxCubeMap);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glUseProgram(MeshShader::SkyboxShader::Program);
|
||||
|
@ -230,6 +230,7 @@ void Shaders::loadShaders()
|
||||
FullScreenShader::PointLightShader::init();
|
||||
FullScreenShader::SSAOShader::init();
|
||||
FullScreenShader::SunLightShader::init();
|
||||
FullScreenShader::DiffuseEnvMapShader::init();
|
||||
FullScreenShader::ShadowedSunLightShader::init();
|
||||
FullScreenShader::MotionBlurShader::init();
|
||||
FullScreenShader::GodFadeShader::init();
|
||||
@ -1400,6 +1401,31 @@ namespace FullScreenShader
|
||||
glUniform1i(uniform_dtex, TU_dtex);
|
||||
}
|
||||
|
||||
GLuint DiffuseEnvMapShader::Program;
|
||||
GLuint DiffuseEnvMapShader::uniform_ntex;
|
||||
GLuint DiffuseEnvMapShader::uniform_blueLmn;
|
||||
GLuint DiffuseEnvMapShader::uniform_greenLmn;
|
||||
GLuint DiffuseEnvMapShader::uniform_redLmn;
|
||||
GLuint DiffuseEnvMapShader::vao;
|
||||
|
||||
void DiffuseEnvMapShader::init()
|
||||
{
|
||||
Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/diffuseenvmap.frag").c_str());
|
||||
uniform_ntex = glGetUniformLocation(Program, "ntex");
|
||||
uniform_blueLmn = glGetUniformLocation(Program, "blueLmn[0]");
|
||||
uniform_greenLmn = glGetUniformLocation(Program, "greenLmn[0]");
|
||||
uniform_redLmn = glGetUniformLocation(Program, "redLmn[0]");
|
||||
vao = createVAO(Program);
|
||||
}
|
||||
|
||||
void DiffuseEnvMapShader::setUniforms(const float *blueSHCoeff, const float *greenSHCoeff, const float *redSHCoeff, unsigned TU_ntex)
|
||||
{
|
||||
glUniform1i(uniform_ntex, TU_ntex);
|
||||
glUniform1fv(uniform_blueLmn, 9, blueSHCoeff);
|
||||
glUniform1fv(uniform_greenLmn, 9, greenSHCoeff);
|
||||
glUniform1fv(uniform_redLmn, 9, redSHCoeff);
|
||||
}
|
||||
|
||||
GLuint ShadowedSunLightShader::Program;
|
||||
GLuint ShadowedSunLightShader::uniform_ntex;
|
||||
GLuint ShadowedSunLightShader::uniform_dtex;
|
||||
|
@ -408,6 +408,17 @@ public:
|
||||
static void setUniforms(const core::vector3df &direction, const core::matrix4 &InvProjMatrix, float r, float g, float b, unsigned TU_ntex, unsigned TU_dtex);
|
||||
};
|
||||
|
||||
class DiffuseEnvMapShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_ntex, uniform_blueLmn, uniform_greenLmn, uniform_redLmn;
|
||||
static GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const float *blueSHCoeff, const float *greenSHCoeff, const float *redSHCoeff, unsigned TU_ntex);
|
||||
};
|
||||
|
||||
class ShadowedSunLightShader
|
||||
{
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user