Increased quality of dynamic shadows
parent
fd182e5515
commit
e747443312
|
@ -118,6 +118,7 @@ CEngine::CEngine(CApplication *app)
|
||||||
m_textureAnisotropy = 1;
|
m_textureAnisotropy = 1;
|
||||||
m_shadowMapping = false;
|
m_shadowMapping = false;
|
||||||
m_offscreenShadowRendering = false;
|
m_offscreenShadowRendering = false;
|
||||||
|
m_qualityShadows = false;
|
||||||
m_totoMode = true;
|
m_totoMode = true;
|
||||||
m_lensMode = true;
|
m_lensMode = true;
|
||||||
m_waterMode = true;
|
m_waterMode = true;
|
||||||
|
@ -187,6 +188,7 @@ CEngine::CEngine(CApplication *app)
|
||||||
{
|
{
|
||||||
m_shadowMapping = (value > 0);
|
m_shadowMapping = (value > 0);
|
||||||
m_offscreenShadowRendering = (value > 1);
|
m_offscreenShadowRendering = (value > 1);
|
||||||
|
m_qualityShadows = (value > 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_defaultTexParams.format = TEX_IMG_AUTO;
|
m_defaultTexParams.format = TEX_IMG_AUTO;
|
||||||
|
@ -3238,33 +3240,119 @@ void CEngine::Draw3DScene()
|
||||||
// Enable shadow mapping
|
// Enable shadow mapping
|
||||||
if (m_shadowMapping)
|
if (m_shadowMapping)
|
||||||
{
|
{
|
||||||
m_device->SetTextureEnabled(2, true);
|
if (m_qualityShadows)
|
||||||
m_device->SetTexture(2, m_shadowMap);
|
|
||||||
m_device->SetTextureMatrix(2, m_shadowTextureMat);
|
|
||||||
|
|
||||||
Math::Matrix identity;
|
|
||||||
identity.LoadIdentity();
|
|
||||||
m_device->SetTransform(TRANSFORM_WORLD, identity);
|
|
||||||
|
|
||||||
TextureStageParams params;
|
|
||||||
params.colorOperation = TEX_MIX_OPER_MODULATE;
|
|
||||||
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
|
|
||||||
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
|
|
||||||
m_device->SetTextureStageParams(2, params);
|
|
||||||
|
|
||||||
TextureGenerationParams genParams;
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
{
|
||||||
genParams.coords[i].mode = TEX_GEN_EYE_LINEAR;
|
// Texture Unit 2
|
||||||
|
m_device->SetTextureEnabled(2, true);
|
||||||
|
m_device->SetTexture(2, m_shadowMap);
|
||||||
|
m_device->SetTextureMatrix(2, m_shadowTextureMat);
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++)
|
Math::Matrix identity;
|
||||||
|
identity.LoadIdentity();
|
||||||
|
m_device->SetTransform(TRANSFORM_WORLD, identity);
|
||||||
|
|
||||||
|
float shadowBias = 0.6f;
|
||||||
|
float shadowUnbias = 1.0f - shadowBias;
|
||||||
|
|
||||||
|
TextureStageParams params;
|
||||||
|
params.colorOperation = TEX_MIX_OPER_MODULATE;
|
||||||
|
params.colorArg1 = TEX_MIX_ARG_TEXTURE;
|
||||||
|
params.colorArg2 = TEX_MIX_ARG_FACTOR;
|
||||||
|
params.colorOperation = TEX_MIX_OPER_DEFAULT;
|
||||||
|
params.factor = Color(shadowBias, shadowBias, shadowBias, 1.0f);
|
||||||
|
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
|
||||||
|
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
|
||||||
|
|
||||||
|
m_device->SetTextureStageParams(2, params);
|
||||||
|
|
||||||
|
TextureGenerationParams genParams;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
genParams.coords[i].plane[j] = (i == j ? 1.0f : 0.0f);
|
genParams.coords[i].mode = TEX_GEN_EYE_LINEAR;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_device->SetTextureCoordGeneration(2, genParams);
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
genParams.coords[i].plane[j] = (i == j ? 1.0f : 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_device->SetTextureCoordGeneration(2, genParams);
|
||||||
|
|
||||||
|
// Texture Unit 3
|
||||||
|
m_device->SetTextureEnabled(3, true);
|
||||||
|
m_device->SetTexture(3, m_shadowMap);
|
||||||
|
|
||||||
|
params.LoadDefault();
|
||||||
|
params.colorOperation = TEX_MIX_OPER_ADD;
|
||||||
|
params.colorArg1 = TEX_MIX_ARG_COMPUTED_COLOR;
|
||||||
|
params.colorArg2 = TEX_MIX_ARG_FACTOR;
|
||||||
|
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
|
||||||
|
params.factor = Color(shadowUnbias, shadowUnbias, shadowUnbias, 0.0f);
|
||||||
|
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
|
||||||
|
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
|
||||||
|
|
||||||
|
m_device->SetTextureStageParams(3, params);
|
||||||
|
|
||||||
|
// Texture Unit 4
|
||||||
|
m_device->SetTextureEnabled(4, true);
|
||||||
|
m_device->SetTexture(4, m_shadowMap);
|
||||||
|
|
||||||
|
params.LoadDefault();
|
||||||
|
params.colorOperation = TEX_MIX_OPER_MODULATE;
|
||||||
|
params.colorArg1 = TEX_MIX_ARG_COMPUTED_COLOR;
|
||||||
|
params.colorArg2 = TEX_MIX_ARG_SRC_COLOR;
|
||||||
|
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
|
||||||
|
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
|
||||||
|
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
|
||||||
|
|
||||||
|
m_device->SetTextureStageParams(4, params);
|
||||||
|
|
||||||
|
// Texture Unit 5
|
||||||
|
m_device->SetTextureEnabled(5, true);
|
||||||
|
m_device->SetTexture(5, m_shadowMap);
|
||||||
|
|
||||||
|
params.LoadDefault();
|
||||||
|
params.colorOperation = TEX_MIX_OPER_MODULATE;
|
||||||
|
params.colorArg1 = TEX_MIX_ARG_COMPUTED_COLOR;
|
||||||
|
params.colorArg2 = TEX_MIX_ARG_TEXTURE_0;
|
||||||
|
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
|
||||||
|
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
|
||||||
|
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
|
||||||
|
|
||||||
|
m_device->SetTextureStageParams(5, params);
|
||||||
|
}
|
||||||
|
else // Simpler shadows
|
||||||
|
{
|
||||||
|
// Texture Unit 2
|
||||||
|
m_device->SetTextureEnabled(2, true);
|
||||||
|
m_device->SetTexture(2, m_shadowMap);
|
||||||
|
m_device->SetTextureMatrix(2, m_shadowTextureMat);
|
||||||
|
|
||||||
|
Math::Matrix identity;
|
||||||
|
identity.LoadIdentity();
|
||||||
|
m_device->SetTransform(TRANSFORM_WORLD, identity);
|
||||||
|
|
||||||
|
TextureStageParams params;
|
||||||
|
params.colorOperation = TEX_MIX_OPER_MODULATE;
|
||||||
|
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
|
||||||
|
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
|
||||||
|
m_device->SetTextureStageParams(2, params);
|
||||||
|
|
||||||
|
TextureGenerationParams genParams;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
genParams.coords[i].mode = TEX_GEN_EYE_LINEAR;
|
||||||
|
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
genParams.coords[i].plane[j] = (i == j ? 1.0f : 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_device->SetTextureCoordGeneration(2, genParams);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int objRank = 0; objRank < static_cast<int>(m_objects.size()); objRank++)
|
for (int objRank = 0; objRank < static_cast<int>(m_objects.size()); objRank++)
|
||||||
|
@ -3339,6 +3427,12 @@ void CEngine::Draw3DScene()
|
||||||
|
|
||||||
m_device->SetTexture(3, 0);
|
m_device->SetTexture(3, 0);
|
||||||
m_device->SetTextureEnabled(3, false);
|
m_device->SetTextureEnabled(3, false);
|
||||||
|
|
||||||
|
m_device->SetTexture(4, 0);
|
||||||
|
m_device->SetTextureEnabled(4, false);
|
||||||
|
|
||||||
|
m_device->SetTexture(5, 0);
|
||||||
|
m_device->SetTextureEnabled(5, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draws the shadows , if shadows enabled
|
// Draws the shadows , if shadows enabled
|
||||||
|
@ -3582,16 +3676,15 @@ void CEngine::RenderShadowMap()
|
||||||
// recompute matrices
|
// recompute matrices
|
||||||
Math::Vector worldUp(1.0f, 0.0f, 0.0f);
|
Math::Vector worldUp(1.0f, 0.0f, 0.0f);
|
||||||
Math::Vector dir = m_lookatPt - m_eyePt;
|
Math::Vector dir = m_lookatPt - m_eyePt;
|
||||||
float change = Math::Max(0.5f, (5.0f + dir.Length()) / 25.0f);
|
|
||||||
dir.Normalize();
|
dir.Normalize();
|
||||||
Math::Vector pos = m_lookatPt + 40.0f * dir;
|
Math::Vector pos = m_lookatPt + 40.0f * dir;
|
||||||
|
|
||||||
Math::Vector lightPos = pos + Math::Vector(3.0f, 30.0f, 3.0f);
|
Math::Vector lightPos = pos + Math::Vector(3.0f, 30.0f, 3.0f);
|
||||||
Math::Vector lookAt = pos + Math::Vector(0.0, 100.0f, 0.0f);
|
Math::Vector lookAt = pos + Math::Vector(0.0, 100.0f, 0.0f);
|
||||||
|
|
||||||
float dist = 75.0f * change;
|
float dist = 75.0f;
|
||||||
|
|
||||||
if (m_offscreenShadowRendering) dist = 400.0f * change;
|
if (m_offscreenShadowRendering) dist = 400.0f;
|
||||||
|
|
||||||
Math::LoadOrthoProjectionMatrix(m_shadowProjMat, -dist, dist, -dist, dist, -200.0f, 200.0f);
|
Math::LoadOrthoProjectionMatrix(m_shadowProjMat, -dist, dist, -dist, dist, -200.0f, 200.0f);
|
||||||
Math::LoadViewMatrix(m_shadowViewMat, lightPos, lookAt, worldUp);
|
Math::LoadViewMatrix(m_shadowViewMat, lightPos, lookAt, worldUp);
|
||||||
|
@ -3624,8 +3717,8 @@ void CEngine::RenderShadowMap()
|
||||||
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
||||||
|
|
||||||
// TODO: check proper object filtering
|
// TODO: check proper object filtering
|
||||||
if (!IsVisible(objRank))
|
//if (!IsVisible(objRank))
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
int baseObjRank = m_objects[objRank].baseObjRank;
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
||||||
if (baseObjRank == -1)
|
if (baseObjRank == -1)
|
||||||
|
@ -3666,6 +3759,7 @@ void CEngine::RenderShadowMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
//m_device->SetRenderState(RENDER_STATE_DEPTH_BIAS, false);
|
//m_device->SetRenderState(RENDER_STATE_DEPTH_BIAS, false);
|
||||||
|
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, false);
|
||||||
|
|
||||||
// copy depth buffer to shadow map
|
// copy depth buffer to shadow map
|
||||||
m_device->CopyFramebufferToTexture(m_shadowMap, 0, 0, 0, 0, m_shadowMap.size.x, m_shadowMap.size.y);
|
m_device->CopyFramebufferToTexture(m_shadowMap, 0, 0, 0, 0, m_shadowMap.size.x, m_shadowMap.size.y);
|
||||||
|
|
|
@ -1459,6 +1459,8 @@ protected:
|
||||||
bool m_shadowMapping;
|
bool m_shadowMapping;
|
||||||
//! true enables offscreen shadow rendering
|
//! true enables offscreen shadow rendering
|
||||||
bool m_offscreenShadowRendering;
|
bool m_offscreenShadowRendering;
|
||||||
|
//! true enables higher quality shadows
|
||||||
|
bool m_qualityShadows;
|
||||||
|
|
||||||
//! Map of loaded textures (by name)
|
//! Map of loaded textures (by name)
|
||||||
std::map<std::string, Texture> m_texNameMap;
|
std::map<std::string, Texture> m_texNameMap;
|
||||||
|
|
Loading…
Reference in New Issue