Fixed eclipse shadows on non-spherical planets (especially noticeable on
Saturn.) Fix affects the GLSL/OpenGL 2.0 render path only.sensor-dev
parent
f357f2608b
commit
52b1dccdff
|
@ -549,6 +549,20 @@ GLSL_RenderContext::GLSL_RenderContext(const LightingState& ls, float _objRadius
|
|||
atmosphere(NULL),
|
||||
blendMode(Material::InvalidBlend),
|
||||
objRadius(_objRadius),
|
||||
objScale(Vector3f::Constant(_objRadius)),
|
||||
objOrientation(orientation),
|
||||
lunarLambert(0.0f)
|
||||
{
|
||||
initLightingEnvironment();
|
||||
}
|
||||
|
||||
|
||||
GLSL_RenderContext::GLSL_RenderContext(const LightingState& ls, const Eigen::Vector3f& _objScale, const Quaternionf& orientation) :
|
||||
lightingState(ls),
|
||||
atmosphere(NULL),
|
||||
blendMode(Material::InvalidBlend),
|
||||
objRadius(_objScale.maxCoeff()),
|
||||
objScale(_objScale),
|
||||
objOrientation(orientation),
|
||||
lunarLambert(0.0f)
|
||||
{
|
||||
|
@ -749,7 +763,7 @@ GLSL_RenderContext::makeCurrent(const Material& m)
|
|||
prog->setLightParameters(lightingState, diffuse, specular, emissive);
|
||||
|
||||
if (shaderProps.hasEclipseShadows() != 0)
|
||||
prog->setEclipseShadowParameters(lightingState, objRadius, objOrientation);
|
||||
prog->setEclipseShadowParameters(lightingState, objScale, objOrientation);
|
||||
|
||||
// TODO: handle emissive color
|
||||
prog->shininess = m.specularPower;
|
||||
|
|
|
@ -115,6 +115,7 @@ class GLSL_RenderContext : public RenderContext
|
|||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||
|
||||
GLSL_RenderContext(const LightingState& ls, float _objRadius, const Eigen::Quaternionf& orientation);
|
||||
GLSL_RenderContext(const LightingState& ls, const Eigen::Vector3f& _objScale, const Eigen::Quaternionf& orientation);
|
||||
virtual ~GLSL_RenderContext();
|
||||
|
||||
virtual void makeCurrent(const cmod::Material&);
|
||||
|
@ -134,6 +135,7 @@ class GLSL_RenderContext : public RenderContext
|
|||
const Atmosphere* atmosphere;
|
||||
cmod::Material::BlendMode blendMode;
|
||||
float objRadius;
|
||||
Eigen::Vector3f objScale;
|
||||
Eigen::Quaternionf objOrientation;
|
||||
|
||||
// extended material properties
|
||||
|
|
|
@ -7064,12 +7064,12 @@ void Renderer::renderObject(const Vector3f& pos,
|
|||
switch (context->getRenderPath())
|
||||
{
|
||||
case GLContext::GLPath_GLSL:
|
||||
renderSphere_GLSL(ri, ls,
|
||||
const_cast<Atmosphere*>(obj.atmosphere), cloudTexOffset,
|
||||
obj.radius,
|
||||
textureResolution,
|
||||
renderFlags,
|
||||
obj.orientation, viewFrustum, *context);
|
||||
renderEllipsoid_GLSL(ri, ls,
|
||||
const_cast<Atmosphere*>(obj.atmosphere), cloudTexOffset,
|
||||
scaleFactors,
|
||||
textureResolution,
|
||||
renderFlags,
|
||||
obj.orientation, viewFrustum, *context);
|
||||
break;
|
||||
|
||||
case GLContext::GLPath_NV30:
|
||||
|
@ -7282,7 +7282,7 @@ void Renderer::renderObject(const Vector3f& pos,
|
|||
cloudTex,
|
||||
cloudNormalMap,
|
||||
cloudTexOffset,
|
||||
radius,
|
||||
scaleFactors,
|
||||
textureResolution,
|
||||
renderFlags,
|
||||
obj.orientation,
|
||||
|
|
|
@ -52,17 +52,19 @@ const double AtmosphereExtinctionThreshold = 0.05;
|
|||
|
||||
|
||||
// Render a planet sphere with GLSL shaders
|
||||
void renderSphere_GLSL(const RenderInfo& ri,
|
||||
void renderEllipsoid_GLSL(const RenderInfo& ri,
|
||||
const LightingState& ls,
|
||||
Atmosphere* atmosphere,
|
||||
float cloudTexOffset,
|
||||
float radius,
|
||||
const Vector3f& semiAxes,
|
||||
unsigned int textureRes,
|
||||
int renderFlags,
|
||||
const Quaternionf& planetOrientation,
|
||||
const Frustum& frustum,
|
||||
const GLContext& context)
|
||||
{
|
||||
float radius = semiAxes.maxCoeff();
|
||||
|
||||
Texture* textures[MAX_SPHERE_MESH_TEXTURES] =
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
unsigned int nTextures = 0;
|
||||
|
@ -271,7 +273,7 @@ void renderSphere_GLSL(const RenderInfo& ri,
|
|||
}
|
||||
|
||||
if (shadprop.hasEclipseShadows() != 0)
|
||||
prog->setEclipseShadowParameters(ls, radius, planetOrientation);
|
||||
prog->setEclipseShadowParameters(ls, semiAxes, planetOrientation);
|
||||
|
||||
glColor(ri.color);
|
||||
|
||||
|
@ -391,13 +393,15 @@ void renderClouds_GLSL(const RenderInfo& ri,
|
|||
Texture* cloudTex,
|
||||
Texture* cloudNormalMap,
|
||||
float texOffset,
|
||||
float radius,
|
||||
const Vector3f& semiAxes,
|
||||
unsigned int textureRes,
|
||||
int renderFlags,
|
||||
const Quaternionf& planetOrientation,
|
||||
const Frustum& frustum,
|
||||
const GLContext& context)
|
||||
{
|
||||
float radius = semiAxes.maxCoeff();
|
||||
|
||||
Texture* textures[MAX_SPHERE_MESH_TEXTURES] =
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
unsigned int nTextures = 0;
|
||||
|
@ -500,7 +504,7 @@ void renderClouds_GLSL(const RenderInfo& ri,
|
|||
#endif
|
||||
|
||||
if (shadprop.shadowCounts != 0)
|
||||
prog->setEclipseShadowParameters(ls, cloudRadius, planetOrientation);
|
||||
prog->setEclipseShadowParameters(ls, semiAxes, planetOrientation);
|
||||
|
||||
unsigned int attributes = LODSphereMesh::Normals;
|
||||
if (cloudNormalMap != NULL)
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
#include <Eigen/Geometry>
|
||||
|
||||
|
||||
void renderSphere_GLSL(const RenderInfo& ri,
|
||||
void renderEllipsoid_GLSL(const RenderInfo& ri,
|
||||
const LightingState& ls,
|
||||
Atmosphere* atmosphere,
|
||||
float cloudTexOffset,
|
||||
float radius,
|
||||
const Eigen::Vector3f& semiAxes,
|
||||
unsigned int textureRes,
|
||||
int renderFlags,
|
||||
const Eigen::Quaternionf& planetOrientation,
|
||||
|
@ -44,7 +44,7 @@ void renderClouds_GLSL(const RenderInfo& ri,
|
|||
Texture* cloudTex,
|
||||
Texture* cloudNormalMap,
|
||||
float texOffset,
|
||||
float radius,
|
||||
const Eigen::Vector3f& semiAxes,
|
||||
unsigned int textureRes,
|
||||
int renderFlags,
|
||||
const Eigen::Quaternionf& planetOrientation,
|
||||
|
|
|
@ -3363,14 +3363,19 @@ CelestiaGLProgram::setLightParameters(const LightingState& ls,
|
|||
}
|
||||
|
||||
|
||||
// Set GLSL shader constants for shadows from ellipsoid occluders; shadows from
|
||||
// irregular objects are not handled yet.
|
||||
/** Set GLSL shader constants for shadows from ellipsoid occluders; shadows from
|
||||
* irregular objects are not handled yet.
|
||||
* \param scaleFactors the scale factors of the object being shadowed
|
||||
* \param orientation orientation of the object being shadowed
|
||||
*/
|
||||
void
|
||||
CelestiaGLProgram::setEclipseShadowParameters(const LightingState& ls,
|
||||
float planetRadius,
|
||||
const Eigen::Quaternionf& planetOrientation)
|
||||
const Vector3f& scaleFactors,
|
||||
const Eigen::Quaternionf& orientation)
|
||||
{
|
||||
Matrix3f planetTransform = planetOrientation.toRotationMatrix();
|
||||
// Compute the transformation from model to world coordinates
|
||||
Transform3f rotation(orientation.conjugate());
|
||||
Matrix4f modelToWorld = (rotation * Scaling3f(scaleFactors)).matrix();
|
||||
|
||||
for (unsigned int li = 0;
|
||||
li < min(ls.nLights, MaxShaderLights);
|
||||
|
@ -3380,6 +3385,13 @@ CelestiaGLProgram::setEclipseShadowParameters(const LightingState& ls,
|
|||
{
|
||||
unsigned int nShadows = min((size_t) MaxShaderEclipseShadows, ls.shadows[li]->size());
|
||||
|
||||
// The shadow bias matrix maps from
|
||||
Matrix4f shadowBias;
|
||||
shadowBias << 0.5f, 0.0f, 0.0f, 0.5f,
|
||||
0.0f, 0.5f, 0.0f, 0.5f,
|
||||
0.0f, 0.0f, 0.5f, 0.5f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f;
|
||||
|
||||
for (unsigned int i = 0; i < nShadows; i++)
|
||||
{
|
||||
EclipseShadow& shadow = ls.shadows[li]->at(i);
|
||||
|
@ -3388,30 +3400,30 @@ CelestiaGLProgram::setEclipseShadowParameters(const LightingState& ls,
|
|||
// Compute shadow parameters: max depth of at the center of the shadow
|
||||
// (always 1 if an eclipse is total) and the linear falloff
|
||||
// rate from the center to the outer endge of the penumbra.
|
||||
float u = shadow.umbraRadius / shadow.penumbraRadius;
|
||||
shadowParams.falloff = -shadow.maxDepth / std::max(0.001f, 1.0f - std::fabs(u));
|
||||
float umbra = shadow.umbraRadius / shadow.penumbraRadius;
|
||||
shadowParams.falloff = -shadow.maxDepth / std::max(0.001f, 1.0f - std::fabs(umbra));
|
||||
shadowParams.maxDepth = shadow.maxDepth;
|
||||
|
||||
// Compute the transformation to use for generating texture
|
||||
// coordinates from the object vertices.
|
||||
Vector3f origin = planetTransform * shadow.origin;
|
||||
Vector3f dir = planetTransform * shadow.direction;
|
||||
float scale = planetRadius / shadow.penumbraRadius;
|
||||
|
||||
Quaternionf shadowRotation;
|
||||
shadowRotation.setFromTwoVectors(Vector3f::UnitY(), dir);
|
||||
Matrix3f m = shadowRotation.toRotationMatrix();
|
||||
Vector3f sAxis = m * Vector3f::UnitX() * (0.5f * scale);
|
||||
Vector3f tAxis = m * Vector3f::UnitZ() * (0.5f * scale);
|
||||
// Compute a transformation that will rotate points in world space to shadow space
|
||||
Vector3f u = shadow.direction.unitOrthogonal();
|
||||
Vector3f v = u.cross(shadow.direction);
|
||||
Matrix4f shadowRotation;
|
||||
shadowRotation << u.transpose(), 0.0f,
|
||||
v.transpose(), 0.0f,
|
||||
shadow.direction.transpose(), 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f;
|
||||
|
||||
Vector4f texGenS;
|
||||
Vector4f texGenT;
|
||||
texGenS.start<3>() = sAxis;
|
||||
texGenT.start<3>() = tAxis;
|
||||
texGenS[3] = -origin.dot(sAxis) / planetRadius + 0.5f;
|
||||
texGenT[3] = -origin.dot(tAxis) / planetRadius + 0.5f;
|
||||
shadowParams.texGenS = texGenS;
|
||||
shadowParams.texGenT = texGenT;
|
||||
// Compose the world-to-shadow matrix
|
||||
Matrix4f worldToShadow = shadowRotation *
|
||||
Transform3f(Scaling3f(1.0f / shadow.penumbraRadius)).matrix() *
|
||||
Transform3f(Translation3f(-shadow.origin)).matrix();
|
||||
|
||||
// Finally, multiply all the matrices together to get the mapping from
|
||||
// object space to shadow map space.
|
||||
Matrix4f m = shadowBias * worldToShadow * modelToWorld;
|
||||
|
||||
shadowParams.texGenS = m.row(0);
|
||||
shadowParams.texGenT = m.row(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,8 +159,8 @@ class CelestiaGLProgram
|
|||
#endif
|
||||
);
|
||||
void setEclipseShadowParameters(const LightingState& ls,
|
||||
float planetRadius,
|
||||
const Eigen::Quaternionf& planetOrientation);
|
||||
const Eigen::Vector3f& scale,
|
||||
const Eigen::Quaternionf& orientation);
|
||||
void setAtmosphereParameters(const Atmosphere& atmosphere,
|
||||
float atmPlanetRadius,
|
||||
float objRadius);
|
||||
|
|
Loading…
Reference in New Issue