IBL: Spheremap now reflects skybox

This commit is contained in:
Vincent Lejeune 2014-03-03 00:47:13 +01:00
parent 391053e368
commit 8600d3bc61
5 changed files with 38 additions and 19 deletions

View File

@ -1,4 +1,6 @@
uniform sampler2D tex;
uniform samplerCube tex;
uniform mat4 invproj;
uniform vec2 screen;
#if __VERSION__ >= 130
in vec3 nor;
@ -10,18 +12,12 @@ varying vec3 nor;
void main() {
// Calculate the spherical UV
const vec3 forward = vec3(0.0, 0.0, 1.0);
vec3 fpos = gl_FragCoord.xyz / vec3(screen, 1.);
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
vec3 normal_x = normalize(vec3(nor.x, 0.0, nor.z));
float sin_theta_x = length(cross( forward, normal_x )) * nor.x / abs(nor.x);
xpos.xyz /= xpos.w;
vec4 detail0 = texture(tex, reflect(xpos.xyz, nor));
// 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.);
}

View File

@ -115,7 +115,7 @@ private:
core::matrix4 m_ViewMatrix, m_InvViewMatrix, m_ProjMatrix, m_InvProjMatrix, m_ProjViewMatrix, m_InvProjViewMatrix;
std::vector<video::ITexture *> SkyboxTextures;
GLuint SkyboxCubeMap, ConvolutedSkyboxCubeMap;
float blueSHCoeff[9];
float greenSHCoeff[9];
float redSHCoeff[9];
@ -130,6 +130,7 @@ private:
RES_CHANGE_CANCEL} m_resolution_changing;
public:
GLuint SkyboxCubeMap, ConvolutedSkyboxCubeMap;
/** A simple class to store video resolutions. */
class VideoMode
{

View File

@ -678,6 +678,8 @@ namespace MeshShader
GLuint SphereMapShader::uniform_MVP;
GLuint SphereMapShader::uniform_TIMV;
GLuint SphereMapShader::uniform_tex;
GLuint SphereMapShader::uniform_invproj;
GLuint SphereMapShader::uniform_screen;
void SphereMapShader::init()
{
@ -687,12 +689,16 @@ namespace MeshShader
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView");
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_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);
}

View File

@ -152,10 +152,10 @@ class SphereMapShader
public:
static GLuint Program;
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 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

View File

@ -226,13 +226,29 @@ void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM
GLenum itype = mesh.IndexType;
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);
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);
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)