Add GI support
This commit is contained in:
parent
5caf028a71
commit
af16682a9e
101
data/shaders/gi.frag
Normal file
101
data/shaders/gi.frag
Normal file
@ -0,0 +1,101 @@
|
||||
// From http://graphics.cs.aueb.gr/graphics/research_illumination.html
|
||||
// "Real-Time Diffuse Global Illumination Using Radiance Hints"
|
||||
// paper and shader code
|
||||
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D dtex;
|
||||
|
||||
uniform sampler3D SHR;
|
||||
uniform sampler3D SHG;
|
||||
uniform sampler3D SHB;
|
||||
|
||||
uniform float R_wcs = 10.;
|
||||
uniform vec3 extents;
|
||||
uniform mat4 RHMatrix;
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
vec4 SHBasis (const in vec3 dir)
|
||||
{
|
||||
float L00 = 0.282095;
|
||||
float L1_1 = 0.488603 * dir.y;
|
||||
float L10 = 0.488603 * dir.z;
|
||||
float L11 = 0.488603 * dir.x;
|
||||
return vec4 (L11, L1_1, L10, L00);
|
||||
}
|
||||
|
||||
vec3 SH2RGB (in vec4 sh_r, in vec4 sh_g, in vec4 sh_b, in vec3 dir)
|
||||
{
|
||||
vec4 Y = vec4(1.023326*dir.x, 1.023326*dir.y, 1.023326*dir.z, 0.886226);
|
||||
return vec3 (dot(Y,sh_r), dot(Y,sh_g), dot(Y,sh_b));
|
||||
}
|
||||
|
||||
in vec2 uv;
|
||||
layout (location = 0) out vec4 Diffuse;
|
||||
layout (location = 1) out vec4 Specular;
|
||||
|
||||
vec3 DecodeNormal(vec2 n);
|
||||
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
|
||||
|
||||
vec3 resolution = vec3(32, 16, 32);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 GI = vec3(0.);
|
||||
|
||||
float depth = texture2D(dtex, uv).x;
|
||||
// Discard background fragments
|
||||
if (depth==1.0) discard;
|
||||
|
||||
vec4 pos_screen_space = getPosFromUVDepth(vec3(uv, depth), InverseProjectionMatrix);
|
||||
vec4 tmp = (inverse(RHMatrix) * InverseViewMatrix * pos_screen_space);
|
||||
vec3 pos = tmp.xyz / tmp.w;
|
||||
vec3 normal_screen_space = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
|
||||
vec3 normal = (transpose(ViewMatrix) * vec4(normal_screen_space, 0.)).xyz;
|
||||
|
||||
// Convert to grid coordinates
|
||||
vec3 uvw = .5 + 0.5 * pos / extents;
|
||||
if (uvw.x < 0. || uvw.x > 1. || uvw.y < 0. || uvw.y > 1. || uvw.z < 0. || uvw.z > 1.) discard;
|
||||
|
||||
// Sample the RH volume at 4 locations, one directly above the shaded point,
|
||||
// three on a ring 80degs away from the normal direction.
|
||||
vec3 rnd = vec3(0,0,0);
|
||||
|
||||
// Generate the sample locations
|
||||
vec3 v_rand = vec3(0.5);
|
||||
vec3 tangent = normalize(cross(normal, v_rand));
|
||||
vec3 bitangent = cross(normal, tangent);
|
||||
vec3 D[4];
|
||||
D[0] = vec3(1.0,0.0,0.0);
|
||||
int i;
|
||||
for (i=1; i<4; i++)
|
||||
{
|
||||
D[i] = vec3(0.1, 0.8*cos((rnd.x*1.5+i)*6.2832/3.0), 0.8*sin((rnd.x*1.5+i)*6.2832/3.0));
|
||||
D[i] = normalize(D[i]);
|
||||
}
|
||||
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
vec3 SampleDir = normal * D[i].x + tangent * D[i].y + bitangent *D[i].z;
|
||||
vec3 SampleOffset = (0.5 * normal + SampleDir) / resolution;
|
||||
vec3 uvw_new = uvw + SampleOffset;
|
||||
|
||||
vec4 IncidentSHR = texture(SHR, uvw_new);
|
||||
vec4 IncidentSHG = texture(SHG, uvw_new);
|
||||
vec4 IncidentSHB = texture(SHB, uvw_new);
|
||||
|
||||
GI += SH2RGB(IncidentSHR, IncidentSHG, IncidentSHB, -normal);
|
||||
}
|
||||
GI /= 4;
|
||||
|
||||
Diffuse = max(16. * vec4(GI, 1.), vec4(0.));
|
||||
Specular = vec4(0.);
|
||||
}
|
@ -261,6 +261,35 @@ void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSH
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void PostProcessing::renderGI(const core::matrix4 &RHMatrix, const core::vector3df &rh_extend, GLuint shr, GLuint shg, GLuint shb)
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glUseProgram(FullScreenShader::GlobalIlluminationReconstructionShader::Program);
|
||||
glBindVertexArray(FullScreenShader::GlobalIlluminationReconstructionShader::vao);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_3D, shr);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_3D, shg);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_3D, shb);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
setTexture(3, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(4, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::GlobalIlluminationReconstructionShader::setUniforms(RHMatrix, rh_extend, 3, 4, 0, 1, 2);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void PostProcessing::renderSunlight()
|
||||
{
|
||||
SunLightProvider * const cb = (SunLightProvider *) irr_driver->getCallback(ES_SUNLIGHT);
|
||||
|
@ -81,6 +81,7 @@ public:
|
||||
void renderFog();
|
||||
void renderSSAO();
|
||||
void renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff);
|
||||
void renderGI(const core::matrix4 &RHMatrix, const core::vector3df &rh_extend, unsigned shr, unsigned shg, unsigned shb);
|
||||
|
||||
/** Blur the in texture */
|
||||
void renderGaussian3Blur(FrameBuffer &in_fbo, FrameBuffer &auxiliary);
|
||||
|
@ -323,6 +323,28 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector
|
||||
renderSkybox(camnode);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
if (getRH())
|
||||
{
|
||||
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||
m_rtts->getFBO(FBO_COLORS).Bind();
|
||||
glUseProgram(FullScreenShader::RHDebug::Program);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_3D, m_rtts->getRH().getRTT()[0]);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_3D, m_rtts->getRH().getRTT()[1]);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_3D, m_rtts->getRH().getRTT()[2]);
|
||||
FullScreenShader::RHDebug::setUniforms(rh_extend, 0, 1, 2);
|
||||
glDrawArrays(GL_POINTS, 0, 128 * 128 * 128);
|
||||
glDisable(GL_PROGRAM_POINT_SIZE);
|
||||
}
|
||||
|
||||
if (getGI())
|
||||
{
|
||||
m_rtts->getFBO(FBO_COLORS).Bind();
|
||||
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
|
||||
}
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00);
|
||||
// Render anything glowing.
|
||||
if (!m_mipviz && !m_wireframe && UserConfigParams::m_glow)
|
||||
@ -895,10 +917,9 @@ void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
|
||||
glClearColor(.5, .5, .5, .5);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
{
|
||||
//gl_driver->extGlDrawBuffers(1, bufs);
|
||||
return;
|
||||
}
|
||||
|
||||
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
|
||||
|
||||
if (SkyboxCubeMap)
|
||||
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
|
||||
@ -974,7 +995,6 @@ void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
|
||||
renderPointLights(MIN2(lightnum, MAXLIGHT));
|
||||
if (SkyboxCubeMap)
|
||||
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
// gl_driver->extGlDrawBuffers(1, bufs);
|
||||
}
|
||||
|
||||
void IrrDriver::renderSSAO()
|
||||
|
@ -282,6 +282,7 @@ void Shaders::loadShaders()
|
||||
FullScreenShader::ShadowedSunLightShader::init();
|
||||
FullScreenShader::ShadowedSunLightDebugShader::init();
|
||||
FullScreenShader::RadianceHintsConstructionShader::init();
|
||||
FullScreenShader::GlobalIlluminationReconstructionShader::init();
|
||||
FullScreenShader::MotionBlurShader::init();
|
||||
FullScreenShader::GodFadeShader::init();
|
||||
FullScreenShader::GodRayShader::init();
|
||||
@ -2351,6 +2352,46 @@ namespace FullScreenShader
|
||||
glUniform3f(uniform_extents, extents.X, extents.Y, extents.Z);
|
||||
}
|
||||
|
||||
GLuint GlobalIlluminationReconstructionShader::Program;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_ntex;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_dtex;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_SHR;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_SHG;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_SHB;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_extents;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_RHMatrix;
|
||||
GLuint GlobalIlluminationReconstructionShader::vao;
|
||||
|
||||
void GlobalIlluminationReconstructionShader::init()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gi.frag").c_str());
|
||||
uniform_ntex = glGetUniformLocation(Program, "ntex");
|
||||
uniform_dtex = glGetUniformLocation(Program, "dtex");
|
||||
uniform_SHR = glGetUniformLocation(Program, "SHR");
|
||||
uniform_SHG = glGetUniformLocation(Program, "SHG");
|
||||
uniform_SHB = glGetUniformLocation(Program, "SHB");
|
||||
uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix");
|
||||
uniform_extents = glGetUniformLocation(Program, "extents");
|
||||
vao = createVAO(Program);
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void GlobalIlluminationReconstructionShader::setUniforms(const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_RHMatrix, 1, GL_FALSE, RHMatrix.pointer());
|
||||
glUniform1i(uniform_ntex, TU_ntex);
|
||||
glUniform1i(uniform_dtex, TU_dtex);
|
||||
glUniform1i(uniform_SHR, TU_SHR);
|
||||
glUniform1i(uniform_SHG, TU_SHG);
|
||||
glUniform1i(uniform_SHB, TU_SHB);
|
||||
glUniform3f(uniform_extents, extents.X, extents.Y, extents.Z);
|
||||
}
|
||||
|
||||
GLuint Gaussian17TapHShader::Program;
|
||||
GLuint Gaussian17TapHShader::uniform_tex;
|
||||
GLuint Gaussian17TapHShader::uniform_pixel;
|
||||
|
@ -620,6 +620,17 @@ public:
|
||||
static void setUniforms(const core::matrix4 &RSMMatrix, const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_ctex, unsigned TU_ntex, unsigned TU_dtex);
|
||||
};
|
||||
|
||||
class GlobalIlluminationReconstructionShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_ntex, uniform_dtex, uniform_extents, uniform_SHR, uniform_SHG, uniform_SHB, uniform_RHMatrix;
|
||||
static GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB);
|
||||
};
|
||||
|
||||
class Gaussian17TapHShader
|
||||
{
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user