Merge branch 'master' of github.com:supertuxkart/stk-code
This commit is contained in:
commit
6450c569ac
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.);
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
uniform sampler2D tex;
|
uniform samplerCube tex;
|
||||||
|
uniform mat4 invproj;
|
||||||
|
uniform vec2 screen;
|
||||||
|
|
||||||
#if __VERSION__ >= 130
|
#if __VERSION__ >= 130
|
||||||
in vec3 nor;
|
in vec3 nor;
|
||||||
@ -10,18 +12,12 @@ varying vec3 nor;
|
|||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Calculate the spherical UV
|
vec3 fpos = gl_FragCoord.xyz / vec3(screen, 1.);
|
||||||
const vec3 forward = vec3(0.0, 0.0, 1.0);
|
vec4 xpos = 2.0 * vec4(fpos, 1.0) - 1.0;
|
||||||
|
xpos = invproj * xpos;
|
||||||
|
|
||||||
// get the angle between the forward vector and the horizontal portion of the normal
|
xpos.xyz /= xpos.w;
|
||||||
vec3 normal_x = normalize(vec3(nor.x, 0.0, nor.z));
|
vec4 detail0 = texture(tex, reflect(xpos.xyz, nor));
|
||||||
float sin_theta_x = length(cross( forward, normal_x )) * nor.x / abs(nor.x);
|
|
||||||
|
|
||||||
// get the angle between the forward vector and the vertical portion of the normal
|
|
||||||
vec3 normal_y = normalize(vec3(0.0, nor.y, nor.z));
|
|
||||||
float sin_theta_y = length(cross( forward, normal_y )) * nor.y / abs(nor.y);
|
|
||||||
|
|
||||||
vec4 detail0 = texture(tex, 0.5 * vec2(sin_theta_x, sin_theta_y) + 0.5);
|
|
||||||
|
|
||||||
FragColor = vec4(detail0.xyz, 1.);
|
FragColor = vec4(detail0.xyz, 1.);
|
||||||
}
|
}
|
||||||
|
@ -1173,6 +1173,7 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector<video::ITexture*>
|
|||||||
assert(texture.size() == 6);
|
assert(texture.size() == 6);
|
||||||
SkyboxTextures = texture;
|
SkyboxTextures = texture;
|
||||||
SkyboxCubeMap = 0;
|
SkyboxCubeMap = 0;
|
||||||
|
ConvolutedSkyboxCubeMap = 0;
|
||||||
return m_scene_manager->addSkyBoxSceneNode(texture[0], texture[1],
|
return m_scene_manager->addSkyBoxSceneNode(texture[0], texture[1],
|
||||||
texture[2], texture[3],
|
texture[2], texture[3],
|
||||||
texture[4], texture[5]);
|
texture[4], texture[5]);
|
||||||
@ -1182,7 +1183,9 @@ void IrrDriver::suppressSkyBox()
|
|||||||
{
|
{
|
||||||
SkyboxTextures.clear();
|
SkyboxTextures.clear();
|
||||||
glDeleteTextures(1, &SkyboxCubeMap);
|
glDeleteTextures(1, &SkyboxCubeMap);
|
||||||
|
glDeleteTextures(1, &ConvolutedSkyboxCubeMap);
|
||||||
SkyboxCubeMap = 0;
|
SkyboxCubeMap = 0;
|
||||||
|
ConvolutedSkyboxCubeMap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -115,7 +115,10 @@ private:
|
|||||||
core::matrix4 m_ViewMatrix, m_InvViewMatrix, m_ProjMatrix, m_InvProjMatrix, m_ProjViewMatrix, m_InvProjViewMatrix;
|
core::matrix4 m_ViewMatrix, m_InvViewMatrix, m_ProjMatrix, m_InvProjMatrix, m_ProjViewMatrix, m_InvProjViewMatrix;
|
||||||
|
|
||||||
std::vector<video::ITexture *> SkyboxTextures;
|
std::vector<video::ITexture *> SkyboxTextures;
|
||||||
GLuint SkyboxCubeMap;
|
|
||||||
|
float blueSHCoeff[9];
|
||||||
|
float greenSHCoeff[9];
|
||||||
|
float redSHCoeff[9];
|
||||||
|
|
||||||
|
|
||||||
/** Flag to indicate if a resolution change is pending (which will be
|
/** Flag to indicate if a resolution change is pending (which will be
|
||||||
@ -127,6 +130,7 @@ private:
|
|||||||
RES_CHANGE_CANCEL} m_resolution_changing;
|
RES_CHANGE_CANCEL} m_resolution_changing;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
GLuint SkyboxCubeMap, ConvolutedSkyboxCubeMap;
|
||||||
/** A simple class to store video resolutions. */
|
/** A simple class to store video resolutions. */
|
||||||
class VideoMode
|
class VideoMode
|
||||||
{
|
{
|
||||||
|
@ -302,6 +302,27 @@ void PostProcessing::renderPointlight(const std::vector<float> &positions, const
|
|||||||
glDisable(GL_BLEND);
|
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()
|
void PostProcessing::renderSunlight()
|
||||||
{
|
{
|
||||||
SunLightProvider * const cb = (SunLightProvider *) irr_driver->getCallback(ES_SUNLIGHT);
|
SunLightProvider * const cb = (SunLightProvider *) irr_driver->getCallback(ES_SUNLIGHT);
|
||||||
|
@ -79,6 +79,7 @@ public:
|
|||||||
|
|
||||||
void renderFog(const core::matrix4 &ipvmat);
|
void renderFog(const core::matrix4 &ipvmat);
|
||||||
void renderSSAO(const core::matrix4 &invprojm, const core::matrix4 &projm);
|
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 */
|
/** Blur the in texture */
|
||||||
void renderGaussian3Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height);
|
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,
|
video::SOverrideMaterial &overridemat,
|
||||||
int cam, float dt)
|
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++)
|
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
|
||||||
sun_ortho_matrix[i] *= getInvViewMatrix();
|
sun_ortho_matrix[i] *= getInvViewMatrix();
|
||||||
core::array<video::IRenderTarget> rtts;
|
core::array<video::IRenderTarget> rtts;
|
||||||
@ -831,6 +833,8 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
|
|||||||
accumulatedLightEnergy.push_back(0.);
|
accumulatedLightEnergy.push_back(0.);
|
||||||
}
|
}
|
||||||
m_post_processing->renderPointlight(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy);
|
m_post_processing->renderPointlight(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy);
|
||||||
|
if (SkyboxCubeMap)
|
||||||
|
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||||
// Handle SSAO
|
// Handle SSAO
|
||||||
m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), true, false,
|
m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), true, false,
|
||||||
SColor(255, 255, 255, 255));
|
SColor(255, 255, 255, 255));
|
||||||
@ -916,13 +920,351 @@ static void createcubevao()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
|
#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()
|
void IrrDriver::generateSkyboxCubemap()
|
||||||
{
|
{
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||||
|
|
||||||
glGenTextures(1, &SkyboxCubeMap);
|
glGenTextures(1, &SkyboxCubeMap);
|
||||||
|
glGenTextures(1, &ConvolutedSkyboxCubeMap);
|
||||||
|
|
||||||
GLint w = 0, h = 0;
|
GLint w = 0, h = 0;
|
||||||
for (unsigned i = 0; i < 6; i++)
|
for (unsigned i = 0; i < 6; i++)
|
||||||
@ -932,7 +1274,9 @@ void IrrDriver::generateSkyboxCubemap()
|
|||||||
}
|
}
|
||||||
|
|
||||||
const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 };
|
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++)
|
for (unsigned i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
unsigned idx = texture_permutation[i];
|
unsigned idx = texture_permutation[i];
|
||||||
@ -945,13 +1289,22 @@ void IrrDriver::generateSkyboxCubemap()
|
|||||||
);
|
);
|
||||||
SkyboxTextures[idx]->unlock();
|
SkyboxTextures[idx]->unlock();
|
||||||
|
|
||||||
image->copyToScaling(rgba, w, h);
|
image->copyToScaling(rgba[i], w, h);
|
||||||
|
image->drop();
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, SkyboxCubeMap);
|
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);
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
|
||||||
image->drop();
|
|
||||||
}
|
}
|
||||||
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);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -981,7 +1334,7 @@ void IrrDriver::renderSkybox()
|
|||||||
transform.getInverse(invtransform);
|
transform.getInverse(invtransform);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
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_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glUseProgram(MeshShader::SkyboxShader::Program);
|
glUseProgram(MeshShader::SkyboxShader::Program);
|
||||||
|
@ -230,6 +230,7 @@ void Shaders::loadShaders()
|
|||||||
FullScreenShader::PointLightShader::init();
|
FullScreenShader::PointLightShader::init();
|
||||||
FullScreenShader::SSAOShader::init();
|
FullScreenShader::SSAOShader::init();
|
||||||
FullScreenShader::SunLightShader::init();
|
FullScreenShader::SunLightShader::init();
|
||||||
|
FullScreenShader::DiffuseEnvMapShader::init();
|
||||||
FullScreenShader::ShadowedSunLightShader::init();
|
FullScreenShader::ShadowedSunLightShader::init();
|
||||||
FullScreenShader::MotionBlurShader::init();
|
FullScreenShader::MotionBlurShader::init();
|
||||||
FullScreenShader::GodFadeShader::init();
|
FullScreenShader::GodFadeShader::init();
|
||||||
@ -677,6 +678,8 @@ namespace MeshShader
|
|||||||
GLuint SphereMapShader::uniform_MVP;
|
GLuint SphereMapShader::uniform_MVP;
|
||||||
GLuint SphereMapShader::uniform_TIMV;
|
GLuint SphereMapShader::uniform_TIMV;
|
||||||
GLuint SphereMapShader::uniform_tex;
|
GLuint SphereMapShader::uniform_tex;
|
||||||
|
GLuint SphereMapShader::uniform_invproj;
|
||||||
|
GLuint SphereMapShader::uniform_screen;
|
||||||
|
|
||||||
void SphereMapShader::init()
|
void SphereMapShader::init()
|
||||||
{
|
{
|
||||||
@ -686,12 +689,16 @@ namespace MeshShader
|
|||||||
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
|
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
|
||||||
uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView");
|
uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView");
|
||||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||||
|
uniform_invproj = glGetUniformLocation(Program, "invproj");
|
||||||
|
uniform_screen = glGetUniformLocation(Program, "screen");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphereMapShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_tex)
|
void SphereMapShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &InvProj, const core::vector2df& screen, unsigned TU_tex)
|
||||||
{
|
{
|
||||||
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
||||||
glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer());
|
glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer());
|
||||||
|
glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, InvProj.pointer());
|
||||||
|
glUniform2f(uniform_screen, screen.X, screen.Y);
|
||||||
glUniform1i(uniform_tex, TU_tex);
|
glUniform1i(uniform_tex, TU_tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1400,6 +1407,31 @@ namespace FullScreenShader
|
|||||||
glUniform1i(uniform_dtex, TU_dtex);
|
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::Program;
|
||||||
GLuint ShadowedSunLightShader::uniform_ntex;
|
GLuint ShadowedSunLightShader::uniform_ntex;
|
||||||
GLuint ShadowedSunLightShader::uniform_dtex;
|
GLuint ShadowedSunLightShader::uniform_dtex;
|
||||||
|
@ -152,10 +152,10 @@ class SphereMapShader
|
|||||||
public:
|
public:
|
||||||
static GLuint Program;
|
static GLuint Program;
|
||||||
static GLuint attrib_position, attrib_normal;
|
static GLuint attrib_position, attrib_normal;
|
||||||
static GLuint uniform_MVP, uniform_TIMV, uniform_tex;
|
static GLuint uniform_MVP, uniform_TIMV, uniform_tex, uniform_invproj, uniform_screen;
|
||||||
|
|
||||||
static void init();
|
static void init();
|
||||||
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_tex);
|
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &InvProj, const core::vector2df& screen, unsigned TU_tex);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SplattingShader
|
class SplattingShader
|
||||||
@ -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);
|
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
|
class ShadowedSunLightShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -226,13 +226,29 @@ void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM
|
|||||||
GLenum itype = mesh.IndexType;
|
GLenum itype = mesh.IndexType;
|
||||||
size_t count = mesh.IndexCount;
|
size_t count = mesh.IndexCount;
|
||||||
|
|
||||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
if (!irr_driver->SkyboxCubeMap)
|
||||||
|
{
|
||||||
|
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE };
|
||||||
|
glTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_TEXTURE_CUBE_MAP, irr_driver->SkyboxCubeMap);
|
||||||
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
}
|
||||||
|
|
||||||
glUseProgram(MeshShader::SphereMapShader::Program);
|
glUseProgram(MeshShader::SphereMapShader::Program);
|
||||||
MeshShader::SphereMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0);
|
MeshShader::SphereMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, irr_driver->getInvProjMatrix(), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0);
|
||||||
|
|
||||||
glBindVertexArray(mesh.vao_second_pass);
|
glBindVertexArray(mesh.vao_second_pass);
|
||||||
glDrawElements(ptype, count, itype, 0);
|
glDrawElements(ptype, count, itype, 0);
|
||||||
|
if (!irr_driver->SkyboxCubeMap)
|
||||||
|
{
|
||||||
|
GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
|
||||||
|
glTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix)
|
void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix)
|
||||||
|
Loading…
Reference in New Issue
Block a user