Shadow: reenable shadows

It's just plain basic shadowmaps, a lot of tweak is still necessary but
it gives a way to see how light values are affected in some places.
(cave in chocolate for instance)
This commit is contained in:
Vincent Lejeune 2014-02-09 17:47:11 +01:00
parent ab05cb45b8
commit f0ef8e9913
12 changed files with 273 additions and 93 deletions

View File

@ -1,95 +1,107 @@
#version 130
uniform sampler2D ntex;
uniform sampler2D dtex;
uniform sampler2D cloudtex;
uniform sampler2D shadowtex;
uniform sampler2D warpx;
uniform sampler2D warpy;
//uniform sampler2D warpx;
///uniform sampler2D warpy;
uniform vec3 center;
uniform vec3 direction;
uniform vec3 col;
uniform vec2 screen;
uniform mat4 invprojview;
uniform mat4 invproj;
uniform mat4 shadowmat;
uniform int hasclouds;
uniform vec2 wind;
uniform float shadowoffset;
//uniform int hasclouds;
//uniform vec2 wind;
//uniform float shadowoffset;
out vec4 FragColor;
out vec4 OtherOutput;
in vec2 uv;
out vec4 Diff;
out vec4 Spec;
out vec4 SpecularMap;
float decdepth(vec4 rgba) {
return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
const float tolerance_z = 0.001;
vec3 DecodeNormal(vec2 n)
{
float z = dot(n, n) * 2. - 1.;
vec2 xy = normalize(n) * sqrt(1. - z * z);
return vec3(xy,z);
}
void main() {
vec2 texc = gl_FragCoord.xy / screen;
vec4 depthread = texture(dtex, texc);
float z = decdepth(vec4(depthread.xyz, 0.0));
float z = texture(dtex, uv).x;
vec4 xpos = 2.0 * vec4(uv, z, 1.0) - 1.0;
xpos = invproj * xpos;
xpos.xyz /= xpos.w;
if (z < 0.03)
{
// Skyboxes are fully lit
FragColor = vec4(1.0);
OtherOutput = vec4(0.0);
Diff = vec4(1.0);
Spec = vec4(1.0);
return;
}
vec3 norm = texture(ntex, texc).xyz;
norm = (norm - 0.5) * 2.0;
vec3 norm = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
// Normalized on the cpu
vec3 L = center;
vec3 L = direction;
float NdotL = max(0.0, dot(norm, L));
if (NdotL < 0.01) discard;
vec3 R = reflect(L, norm);
float RdotE = max(0.0, dot(R, normalize(xpos.xyz)));
float Specular = pow(RdotE, 200);
vec3 outcol = NdotL * col;
// World-space position
vec3 tmp = vec3(texc, z);
tmp = tmp * 2.0 - 1.0;
// if (hasclouds == 1)
// {
// vec2 cloudcoord = (xpos.xz * 0.00833333) + wind;
// float cloud = texture(cloudtex, cloudcoord).x;
// //float cloud = step(0.5, cloudcoord.x) * step(0.5, cloudcoord.y);
vec4 xpos = vec4(tmp, 1.0);
xpos = invprojview * xpos;
xpos.xyz /= xpos.w;
if (hasclouds == 1)
{
vec2 cloudcoord = (xpos.xz * 0.00833333) + wind;
float cloud = texture(cloudtex, cloudcoord).x;
//float cloud = step(0.5, cloudcoord.x) * step(0.5, cloudcoord.y);
outcol *= cloud;
}
// outcol *= cloud;
// }
// Shadows
vec3 shadowcoord = (shadowmat * vec4(xpos.xyz, 1.0)).xyz;
shadowcoord = (shadowcoord * 0.5) + vec3(0.5);
vec4 shadowcoord = (shadowmat * vec4(xpos.xyz, 1.0));
shadowcoord /= shadowcoord.w;
vec2 shadowtexcoord = shadowcoord.xy * 0.5 + 0.5;
// shadowcoord = (shadowcoord * 0.5) + vec3(0.5);
float movex = decdepth(texture(warpx, shadowcoord.xy));
float movey = decdepth(texture(warpy, shadowcoord.xy));
float dx = movex * 2.0 - 1.0;
float dy = movey * 2.0 - 1.0;
shadowcoord.xy += vec2(dx, dy);
// float movex = decdepth(texture(warpx, shadowcoord.xy));
// float movey = decdepth(texture(warpy, shadowcoord.xy));
// float dx = movex * 2.0 - 1.0;
// float dy = movey * 2.0 - 1.0;
// shadowcoord.xy += vec2(dx, dy);*/
vec4 shadowread = texture(shadowtex, shadowcoord.xy);
float shadowmapz = decdepth(vec4(shadowread.xyz, 0.0));
float shadowmapz = 2. * texture(shadowtex, shadowtexcoord).x - 1.;
float moved = (abs(dx) + abs(dy)) * 0.5;
if (shadowmapz > shadowcoord.z - tolerance_z)
{
Diff = vec4(NdotL * col, 1.);
Spec = vec4(Specular * col, 1.);
}
else
{
Diff = vec4(0., 0., 0., 1.);
Spec = vec4(0., 0., 0., 1.);
}
SpecularMap = vec4(1.0);
return;
// float moved = (abs(dx) + abs(dy)) * 0.5;
/*
float bias = 0.002 * tan(acos(NdotL)); // According to the slope
bias += smoothstep(0.001, 0.1, moved) * 0.014; // According to the warping
bias = clamp(bias, 0.001, 0.014);
*/
/*
float avi = 0.002;
float abi = 0.0025; */
float avi = 0.0018;
// float bias = 0.002 * tan(acos(NdotL)); // According to the slope
// bias += smoothstep(0.001, 0.1, moved) * 0.014; // According to the warping
// bias = clamp(bias, 0.001, 0.014);
// float avi = 0.002;
// float abi = 0.0025;
/* float avi = 0.0018;
float abi = 0.002;
float bias = avi * tan(acos(NdotL)); // According to the slope
@ -113,11 +125,11 @@ void main() {
float shadowed = step(shadowmapz + bias, shadowcoord.z);
float dist = (shadowcoord.z / shadowmapz) - 1.0;
float penumbra = dist * softness / gl_FragCoord.z;
penumbra *= shadowed;
penumbra *= shadowed;*/
/* outcol.r = (shadowcoord.z - shadowmapz) * 50.0;
outcol.g = moved;*/
FragColor = vec4(outcol, 0.05);
OtherOutput = vec4(shadowed, penumbra, shadowed, shadowed);
// FragColor = vec4(outcol, 0.05);
// OtherOutput = vec4(shadowed, penumbra, shadowed, shadowed);
}

View File

@ -102,6 +102,7 @@ private:
RTT *m_rtts;
/** Shadow importance. */
ShadowImportance *m_shadow_importance;
core::matrix4 sun_ortho_matrix;
/** Additional details to be shown in case that a texture is not found.
* This is used to specify details like: "while loading kart '...'" */
@ -111,7 +112,7 @@ private:
core::array<video::IRenderTarget> m_mrt;
/** Matrixes used in several places stored here to avoid recomputation. */
core::matrix4 m_ViewMatrix, 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;
@ -203,9 +204,9 @@ private:
void renderFixed(float dt);
void renderGLSL(float dt);
void renderShadows(ShadowImportanceProvider * const sicb,
void renderShadows(//ShadowImportanceProvider * const sicb,
scene::ICameraSceneNode * const camnode,
video::SOverrideMaterial &overridemat,
//video::SOverrideMaterial &overridemat,
Camera * const camera);
void renderGlow(video::SOverrideMaterial &overridemat,
std::vector<GlowData>& glows,
@ -492,8 +493,9 @@ public:
// ------------------------------------------------------------------------
scene::IMeshSceneNode *getSunInterposer() { return m_sun_interposer; }
// ------------------------------------------------------------------------
void setViewMatrix(core::matrix4 matrix) { m_ViewMatrix = matrix; }
void setViewMatrix(core::matrix4 matrix) { m_ViewMatrix = matrix; matrix.getInverse(m_InvViewMatrix); }
const core::matrix4 &getViewMatrix() const { return m_ViewMatrix; }
const core::matrix4 &getInvViewMatrix() const { return m_InvViewMatrix; }
void setProjMatrix(core::matrix4 matrix) { m_ProjMatrix = matrix; matrix.getInverse(m_InvProjMatrix); }
const core::matrix4 &getProjMatrix() const { return m_ProjMatrix; }
const core::matrix4 &getInvProjMatrix() const { return m_InvProjMatrix; }

View File

@ -346,6 +346,25 @@ void PostProcessing::renderSunlight()
glBindVertexArray(0);
}
void PostProcessing::renderShadowedSunlight(const core::matrix4 &sun_ortho_matrix)
{
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
glUseProgram(FullScreenShader::ShadowedSunLightShader::Program);
glBindVertexArray(FullScreenShader::ShadowedSunLightShader::vao);
setTexture(0, static_cast<irr::video::COpenGLTexture*>(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST);
setTexture(1, static_cast<irr::video::COpenGLFBOTexture*>(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))->DepthBufferTexture, GL_NEAREST, GL_NEAREST);
setTexture(2, static_cast<irr::video::COpenGLFBOTexture*>(irr_driver->getRTT(RTT_SHADOW))->DepthBufferTexture, GL_NEAREST, GL_NEAREST);
FullScreenShader::ShadowedSunLightShader::setUniforms(sun_ortho_matrix, cb->getPosition(), irr_driver->getInvProjMatrix(), cb->getRed(), cb->getGreen(), cb->getBlue(), 0, 1, 2);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
}
void PostProcessing::renderGaussian3Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height)
{
@ -448,6 +467,27 @@ void PostProcessing::renderPassThrough(ITexture *tex)
glDisable(GL_BLEND);
}
void PostProcessing::renderPassThrough(GLuint tex)
{
glDisable(GL_DEPTH_TEST);
glUseProgram(FullScreenShader::PassThroughShader::Program);
glBindVertexArray(FullScreenShader::PassThroughShader::vao);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glUniform1i(FullScreenShader::PassThroughShader::uniform_texture, 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::renderGlow(ITexture *tex)
{
glDisable(GL_DEPTH_TEST);
@ -807,7 +847,7 @@ void PostProcessing::render()
else if (irr_driver->getSSAOViz())
renderPassThrough(irr_driver->getRTT(RTT_SSAO));
else if (irr_driver->getShadowViz())
renderPassThrough(irr_driver->getRTT(RTT_SHADOW));
renderPassThrough(static_cast<irr::video::COpenGLFBOTexture*>(irr_driver->getRTT(RTT_SHADOW))->DepthBufferTexture);
else
renderColorLevel(in);
}

View File

@ -75,6 +75,7 @@ public:
/** Generate diffuse and specular map */
void renderPointlight(const std::vector<float> &positions, const std::vector<float> &colors, const std::vector<float> &energy);
void renderSunlight();
void renderShadowedSunlight(const core::matrix4 &sun_ortho_matrix);
void renderFog(const core::matrix4 &ipvmat);
void renderSSAO(const core::matrix4 &invprojm, const core::matrix4 &projm);
@ -85,6 +86,7 @@ public:
/** Render tex. Used for blit/texture resize */
void renderPassThrough(video::ITexture *tex);
void renderPassThrough(unsigned tex);
void renderGlow(video::ITexture *tex);

View File

@ -215,10 +215,10 @@ void IrrDriver::renderGLSL(float dt)
const core::aabbox3df cambox = camnode->getViewFrustum()->getBoundingBox();
// Shadows
if (!m_mipviz && !m_wireframe && UserConfigParams::m_shadows &&
World::getWorld()->getTrack()->hasShadows())
if (!m_mipviz && !m_wireframe && UserConfigParams::m_shadows)
//&& World::getWorld()->getTrack()->hasShadows())
{
//renderShadows(sicb, camnode, overridemat, camera);
renderShadows(camnode, camera);
}
@ -464,9 +464,9 @@ void IrrDriver::renderFixed(float dt)
// ----------------------------------------------------------------------------
void IrrDriver::renderShadows(ShadowImportanceProvider * const sicb,
void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb,
scene::ICameraSceneNode * const camnode,
video::SOverrideMaterial &overridemat,
//video::SOverrideMaterial &overridemat,
Camera * const camera)
{
m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID);
@ -486,7 +486,6 @@ void IrrDriver::renderShadows(ShadowImportanceProvider * const sicb,
camnode->render();
// Set up a nice ortho projection that contains our camera frustum
core::matrix4 ortho;
core::aabbox3df box = smallcambox;
box = box.intersect(trackbox);
@ -518,16 +517,16 @@ void IrrDriver::renderShadows(ShadowImportanceProvider * const sicb,
if (up == down) down += 0.1f;
if (z == 30) z += 0.1f;
ortho.buildProjectionMatrixOrthoLH(left, right,
sun_ortho_matrix.buildProjectionMatrixOrthoLH(left, right,
up, down,
30, z);
m_suncam->setProjectionMatrix(ortho, true);
m_suncam->setProjectionMatrix(sun_ortho_matrix, true);
m_scene_manager->setActiveCamera(m_suncam);
m_suncam->render();
ortho *= m_suncam->getViewMatrix();
((SunLightProvider *) m_shaders->m_callbacks[ES_SUNLIGHT])->setShadowMatrix(ortho);
//sun_ortho_matrix *= m_suncam->getViewMatrix();
/* ((SunLightProvider *) m_shaders->m_callbacks[ES_SUNLIGHT])->setShadowMatrix(ortho);
sicb->setShadowMatrix(ortho);
overridemat.Enabled = 0;
@ -563,7 +562,7 @@ void IrrDriver::renderShadows(ShadowImportanceProvider * const sicb,
m_rtts->getRTT(RTT_WARPV)->getSize().Height,
m_rtts->getRTT(RTT_WARPV)->getSize().Height);
/* sq.setMaterialType(m_shaders->getShader(ES_GAUSSIAN6H));
sq.setMaterialType(m_shaders->getShader(ES_GAUSSIAN6H));
sq.setTexture(m_rtts->getRTT(RTT_WARPH));
sq.render(m_rtts->getRTT(curh));
@ -577,7 +576,7 @@ void IrrDriver::renderShadows(ShadowImportanceProvider * const sicb,
// calculating the min, max, and total, it's several hundred us
// faster to do that than to do it once in a separate shader
// (shader switch overhead, measured).
colcb->setResolution(m_rtts->getRTT(RTT_WARPV)->getSize().Height,
/*colcb->setResolution(m_rtts->getRTT(RTT_WARPV)->getSize().Height,
m_rtts->getRTT(RTT_WARPV)->getSize().Height);
sq.setMaterialType(m_shaders->getShader(ES_SHADOW_WARPH));
@ -586,11 +585,12 @@ void IrrDriver::renderShadows(ShadowImportanceProvider * const sicb,
sq.setMaterialType(m_shaders->getShader(ES_SHADOW_WARPV));
sq.setTexture(m_rtts->getRTT(curv));
sq.render(m_rtts->getRTT(RTT_WARPV));
sq.render(m_rtts->getRTT(RTT_WARPV));*/
// Actual shadow map
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_SHADOW), true, true);
overridemat.Material.MaterialType = m_shaders->getShader(ES_SHADOWPASS);
/* overridemat.Material.MaterialType = m_shaders->getShader(ES_SHADOWPASS);
overridemat.EnableFlags = video::EMF_MATERIAL_TYPE | video::EMF_TEXTURE1 |
video::EMF_TEXTURE2;
overridemat.EnablePasses = scene::ESNRP_SOLID;
@ -607,18 +607,20 @@ void IrrDriver::renderShadows(ShadowImportanceProvider * const sicb,
overridemat.Material.TextureLayer[1].AnisotropicFilter =
overridemat.Material.TextureLayer[2].AnisotropicFilter = 0;
overridemat.Material.Wireframe = 1;
overridemat.Enabled = true;
overridemat.Enabled = true;*/
sun_ortho_matrix = getVideoDriver()->getTransform(video::ETS_PROJECTION);
sun_ortho_matrix *= getVideoDriver()->getTransform(video::ETS_VIEW);
irr_driver->setPhase(SHADOW_PASS);
glDisable(GL_BLEND);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_SHADOW), true, true);
glDrawBuffer(GL_NONE);
m_scene_manager->drawAll(scene::ESNRP_SOLID);
glCullFace(GL_BACK);
if (m_shadowviz)
{
overridemat.EnableFlags |= video::EMF_WIREFRAME;
m_scene_manager->drawAll(scene::ESNRP_SOLID);
}
overridemat.EnablePasses = 0;
overridemat.Enabled = false;
// overridemat.EnablePasses = 0;
// overridemat.Enabled = false;
camera->activate();
tick++;
@ -728,6 +730,7 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
video::SOverrideMaterial &overridemat,
int cam, float dt)
{
sun_ortho_matrix *= getInvViewMatrix();
core::array<video::IRenderTarget> rtts;
// Diffuse
rtts.push_back(m_rtts->getRTT(RTT_TMP1));
@ -749,7 +752,10 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
if (!m_lights[i]->isPointLight())
{
m_lights[i]->render();
m_post_processing->renderSunlight();
if (UserConfigParams::m_shadows)
m_post_processing->renderShadowedSunlight(sun_ortho_matrix);
else
m_post_processing->renderSunlight();
continue;
}
const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos);

View File

@ -36,7 +36,7 @@ RTT::RTT()
const dimension2du ssaosize = UserConfigParams::m_ssao == 2 ? res : quarter;
const u16 shadowside = UserConfigParams::m_shadows == 2 ? 2048 : 512;
const u16 shadowside = 8192;
const dimension2du shadowsize(shadowside, shadowside);
const dimension2du warpvsize(1, 512);
const dimension2du warphsize(512, 1);

View File

@ -154,7 +154,7 @@ void Shaders::loadShaders()
m_shaders[ES_OBJECTPASS_RIMLIT] = glsl_noinput(dir + "objectpass_rimlit.vert", dir + "objectpass_rimlit.frag");
m_shaders[ES_SUNLIGHT] = glsl_noinput(std::string(""), dir + "sunlight.frag");
m_shaders[ES_SUNLIGHT_SHADOW] = glsl_noinput(dir + "pass.vert", dir + "sunlightshadow.frag");
m_shaders[ES_SUNLIGHT_SHADOW] = glsl_noinput(dir + "pass.vert", dir + "pass.frag");
m_shaders[ES_MLAA_COLOR1] = glsl(dir + "mlaa_offset.vert", dir + "mlaa_color1.frag",
m_callbacks[ES_MLAA_COLOR1]);
@ -238,6 +238,7 @@ void Shaders::loadShaders()
FullScreenShader::PPDisplaceShader::init();
FullScreenShader::SSAOShader::init();
FullScreenShader::SunLightShader::init();
FullScreenShader::ShadowedSunLightShader::init();
MeshShader::ColorizeShader::init();
MeshShader::NormalMapShader::init();
MeshShader::ObjectPass1Shader::init();
@ -257,6 +258,7 @@ void Shaders::loadShaders()
MeshShader::TransparentFogShader::init();
MeshShader::BillboardShader::init();
MeshShader::DisplaceShader::init();
MeshShader::ShadowShader::init();
ParticleShader::FlipParticleRender::init();
ParticleShader::HeightmapSimulationShader::init();
ParticleShader::SimpleParticleRender::init();
@ -873,6 +875,22 @@ namespace MeshShader
glUniform3f(uniform_col, r, g, b);
}
GLuint ShadowShader::Program;
GLuint ShadowShader::attrib_position;
GLuint ShadowShader::uniform_MVP;
void ShadowShader::init()
{
Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/white.frag").c_str());
attrib_position = glGetAttribLocation(Program, "Position");
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
}
void ShadowShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix)
{
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
}
GLuint DisplaceShader::Program;
GLuint DisplaceShader::attrib_position;
GLuint DisplaceShader::attrib_texcoord;
@ -1219,6 +1237,40 @@ namespace FullScreenShader
glUniform1i(uniform_dtex, TU_dtex);
}
GLuint ShadowedSunLightShader::Program;
GLuint ShadowedSunLightShader::uniform_ntex;
GLuint ShadowedSunLightShader::uniform_dtex;
GLuint ShadowedSunLightShader::uniform_shadowtex;
GLuint ShadowedSunLightShader::uniform_shadowmat;
GLuint ShadowedSunLightShader::uniform_direction;
GLuint ShadowedSunLightShader::uniform_col;
GLuint ShadowedSunLightShader::uniform_invproj;
GLuint ShadowedSunLightShader::vao;
void ShadowedSunLightShader::init()
{
Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/sunlightshadow.frag").c_str());
uniform_ntex = glGetUniformLocation(Program, "ntex");
uniform_dtex = glGetUniformLocation(Program, "dtex");
uniform_shadowtex = glGetUniformLocation(Program, "shadowtex");
uniform_shadowmat = glGetUniformLocation(Program, "shadowmat"),
uniform_direction = glGetUniformLocation(Program, "direction");
uniform_col = glGetUniformLocation(Program, "col");
uniform_invproj = glGetUniformLocation(Program, "invproj");
vao = createVAO(Program);
}
void ShadowedSunLightShader::setUniforms(const core::matrix4 &shadowmat, const core::vector3df &direction, const core::matrix4 &InvProjMatrix, float r, float g, float b, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_shadowtex)
{
glUniformMatrix4fv(uniform_shadowmat, 1, GL_FALSE, shadowmat.pointer());
glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, InvProjMatrix.pointer());
glUniform3f(uniform_direction, direction.X, direction.Y, direction.Z);
glUniform3f(uniform_col, r, g, b);
glUniform1i(uniform_ntex, TU_ntex);
glUniform1i(uniform_dtex, TU_dtex);
glUniform1i(uniform_shadowtex, TU_shadowtex);
}
GLuint Gaussian6HBlurShader::Program;
GLuint Gaussian6HBlurShader::uniform_tex;
GLuint Gaussian6HBlurShader::uniform_pixel;

View File

@ -225,6 +225,17 @@ public:
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, float r, float g, float b);
};
class ShadowShader
{
public:
static GLuint Program;
static GLuint attrib_position;
static GLuint uniform_MVP;
static void init();
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix);
};
class DisplaceShader
{
public:
@ -352,6 +363,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 ShadowedSunLightShader
{
public:
static GLuint Program;
static GLuint uniform_ntex, uniform_dtex, uniform_shadowtex, uniform_shadowmat, uniform_direction, uniform_col, uniform_invproj;
static GLuint vao;
static void init();
static void setUniforms(const core::matrix4 &shadowmat, const core::vector3df &direction, const core::matrix4 &InvProjMatrix, float r, float g, float b, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_shadowtex);
};
class Gaussian6HBlurShader
{
public:

View File

@ -94,6 +94,20 @@ isObjectPass(video::E_MATERIAL_TYPE type)
return false;
}
void STKAnimatedMesh::drawShadow(const GLMesh &mesh)
{
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
assert(irr_driver->getPhase() == SHADOW_PASS);
core::matrix4 ShadowMVP;
computeMVP(ShadowMVP);
glUseProgram(MeshShader::ShadowShader::Program);
MeshShader::ShadowShader::setUniforms(ShadowMVP);
glBindVertexArray(mesh.vao_shadow_pass);
glDrawElements(ptype, count, itype, 0);
}
void STKAnimatedMesh::render()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
@ -151,7 +165,9 @@ void STKAnimatedMesh::render()
glBindBuffer(GL_ARRAY_BUFFER, GLmeshes[i].vertex_buffer);
glBufferSubData(GL_ARRAY_BUFFER, 0, mb->getVertexCount() * GLmeshes[i].Stride, mb->getVertices());
}
if (isTransparentPass)
if (irr_driver->getPhase() == SHADOW_PASS)
drawShadow(GLmeshes[i]);
else if (isTransparentPass)
drawTransparent(GLmeshes[i], material.MaterialType);
else
drawSolid(GLmeshes[i], material.MaterialType);

View File

@ -15,6 +15,7 @@ protected:
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
void drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
void drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
void drawShadow(const GLMesh &mesh);
public:
STKAnimatedMesh(irr::scene::IAnimatedMesh* mesh, irr::scene::ISceneNode* parent,
irr::scene::ISceneManager* mgr, irr::s32 id,

View File

@ -723,6 +723,21 @@ void STKMesh::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
return;
}
void STKMesh::drawShadow(const GLMesh &mesh)
{
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
assert(irr_driver->getPhase() == SHADOW_PASS);
core::matrix4 ShadowMVP;
computeMVP(ShadowMVP);
glUseProgram(MeshShader::ShadowShader::Program);
MeshShader::ShadowShader::setUniforms(ShadowMVP);
glBindVertexArray(mesh.vao_shadow_pass);
glDrawElements(ptype, count, itype, 0);
}
void STKMesh::drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
{
switch (irr_driver->getPhase())
@ -910,6 +925,11 @@ void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type)
return;
mesh.vao_displace_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position, MeshShader::DisplaceShader::attrib_texcoord, MeshShader::DisplaceShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride);
return;
case SHADOW_PASS:
if (mesh.vao_shadow_pass)
return;
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
return;
}
}
@ -961,6 +981,11 @@ void STKMesh::render()
initvaostate(GLmeshes[i], material.MaterialType);
drawGlow(GLmeshes[i]);
}
else if (irr_driver->getPhase() == SHADOW_PASS)
{
initvaostate(GLmeshes[i], material.MaterialType);
drawShadow(GLmeshes[i]);
}
else
{
irr_driver->IncreaseObjectCount();

View File

@ -13,6 +13,7 @@ struct GLMesh {
GLuint vao_second_pass;
GLuint vao_glow_pass;
GLuint vao_displace_pass;
GLuint vao_shadow_pass;
GLuint vertex_buffer;
GLuint index_buffer;
GLuint textures[6];
@ -62,6 +63,7 @@ protected:
// Misc passes shaders (glow, displace...)
void drawGlow(const GLMesh &mesh);
void drawDisplace(const GLMesh &mesh);
void drawShadow(const GLMesh &mesh);
void createGLMeshes();
void cleanGLMeshes();
public: