- Added support for emissive color to OpenGL 2.0 render path
- Eliminated code for Lommel-Seeliger photometric model, since it's just a special case of the more general Lunar-Lambert model. - Cleaned up GLSL_RenderContext so it uses the light and shadow functions in the shader managerver1_5_1
parent
b5a18b1710
commit
54d5de0563
|
@ -402,125 +402,6 @@ GLSL_RenderContext::initLightingEnvironment()
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// TODO: eliminate this and use CelestiaGLProgram::setLightingParameters instead
|
||||
void
|
||||
GLSL_RenderContext::setLightingParameters(CelestiaGLProgram& prog, Color materialDiffuse, Color materialSpecular)
|
||||
{
|
||||
unsigned int nLights = min(MaxShaderLights, lightingState.nLights);
|
||||
|
||||
Vec3f diffuseColor(materialDiffuse.red(),
|
||||
materialDiffuse.green(),
|
||||
materialDiffuse.blue());
|
||||
Vec3f specularColor(materialSpecular.red(),
|
||||
materialSpecular.green(),
|
||||
materialSpecular.blue());
|
||||
|
||||
for (unsigned int i = 0; i < nLights; i++)
|
||||
{
|
||||
const DirectionalLight& light = lightingState.lights[i];
|
||||
|
||||
Vec3f lightColor = Vec3f(light.color.red(),
|
||||
light.color.green(),
|
||||
light.color.blue()) * light.irradiance;
|
||||
prog.lights[i].direction = light.direction_obj;
|
||||
|
||||
if (shaderProps.usesShadows() ||
|
||||
shaderProps.usesFragmentLighting() ||
|
||||
shaderProps.lightModel == ShaderProperties::RingIllumModel)
|
||||
{
|
||||
prog.fragLightColor[i] = Vec3f(lightColor.x * diffuseColor.x,
|
||||
lightColor.y * diffuseColor.y,
|
||||
lightColor.z * diffuseColor.z);
|
||||
if (shaderProps.hasSpecular())
|
||||
{
|
||||
prog.fragLightSpecColor[i] = Vec3f(lightColor.x * specularColor.x,
|
||||
lightColor.y * specularColor.y,
|
||||
lightColor.z * specularColor.z);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prog.lights[i].diffuse = Vec3f(lightColor.x * diffuseColor.x,
|
||||
lightColor.y * diffuseColor.y,
|
||||
lightColor.z * diffuseColor.z);
|
||||
}
|
||||
|
||||
prog.lights[i].specular = Vec3f(lightColor.x * specularColor.x,
|
||||
lightColor.y * specularColor.y,
|
||||
lightColor.z * specularColor.z);
|
||||
|
||||
Vec3f halfAngle_obj = lightingState.eyeDir_obj + light.direction_obj;
|
||||
if (halfAngle_obj.length() != 0.0f)
|
||||
halfAngle_obj.normalize();
|
||||
prog.lights[i].halfVector = halfAngle_obj;
|
||||
}
|
||||
|
||||
prog.eyePosition = lightingState.eyePos_obj;
|
||||
prog.ambientColor = Vec3f(lightingState.ambientColor.x * diffuseColor.x,
|
||||
lightingState.ambientColor.y * diffuseColor.y,
|
||||
lightingState.ambientColor.z * diffuseColor.z);
|
||||
prog.opacity = materialDiffuse.alpha();
|
||||
}
|
||||
|
||||
|
||||
// TODO: eliminate this and use CelestiaGLProgram::setShadowParameters instead
|
||||
void
|
||||
GLSL_RenderContext::setShadowParameters(CelestiaGLProgram& prog)
|
||||
{
|
||||
// TODO: this code is largely a copy of some code in render.cpp; we should
|
||||
// have just a single instance of the code.
|
||||
for (unsigned int li = 0;
|
||||
li < min(lightingState.nLights, MaxShaderLights);
|
||||
li++)
|
||||
{
|
||||
vector<EclipseShadow>* shadows = lightingState.shadows[li];
|
||||
|
||||
if (shadows != NULL)
|
||||
{
|
||||
unsigned int nShadows = min((size_t) MaxShaderShadows,
|
||||
shadows->size());
|
||||
|
||||
for (unsigned int i = 0; i < nShadows; i++)
|
||||
{
|
||||
EclipseShadow& shadow = shadows->at(i);
|
||||
CelestiaGLProgramShadow& shadowParams = prog.shadows[li][i];
|
||||
|
||||
float R2 = 0.25f;
|
||||
float umbra = shadow.umbraRadius / shadow.penumbraRadius;
|
||||
umbra = umbra * umbra;
|
||||
if (umbra < 0.0001f)
|
||||
umbra = 0.0001f;
|
||||
else if (umbra > 0.99f)
|
||||
umbra = 0.99f;
|
||||
|
||||
float umbraRadius = R2 * umbra;
|
||||
float penumbraRadius = R2;
|
||||
float shadowBias = 1.0f / (1.0f - penumbraRadius / umbraRadius);
|
||||
shadowParams.bias = shadowBias;
|
||||
shadowParams.scale = -shadowBias / umbraRadius;
|
||||
|
||||
// Compute the transformation to use for generating texture
|
||||
// coordinates from the object vertices.
|
||||
Point3f origin = shadow.origin * xform;
|
||||
Vec3f dir = shadow.direction * xform;
|
||||
float scale = objRadius / shadow.penumbraRadius;
|
||||
Vec3f axis = Vec3f(0, 1, 0) ^ dir;
|
||||
float angle = (float) acos(Vec3f(0, 1, 0) * dir);
|
||||
axis.normalize();
|
||||
Mat4f mat = Mat4f::rotation(axis, -angle);
|
||||
Vec3f sAxis = Vec3f(0.5f * scale, 0, 0) * mat;
|
||||
Vec3f tAxis = Vec3f(0, 0, 0.5f * scale) * mat;
|
||||
|
||||
float sw = (Point3f(0, 0, 0) - origin) * sAxis / objRadius + 0.5f;
|
||||
float tw = (Point3f(0, 0, 0) - origin) * tAxis / objRadius + 0.5f;
|
||||
shadowParams.texGenS = Vec4f(sAxis.x, sAxis.y, sAxis.z, sw);
|
||||
shadowParams.texGenT = Vec4f(tAxis.x, tAxis.y, tAxis.z, tw);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
|
@ -609,9 +490,9 @@ GLSL_RenderContext::makeCurrent(const Mesh::Material& m)
|
|||
textures[i]->bind();
|
||||
}
|
||||
|
||||
setLightingParameters(*prog, m.diffuse, m.specular);
|
||||
prog->setLightParameters(lightingState, m.diffuse, m.specular, m.emissive);
|
||||
if (shaderProps.shadowCounts != 0)
|
||||
setShadowParameters(*prog);
|
||||
prog->setEclipseShadowParameters(lightingState, objRadius, xform);
|
||||
|
||||
// TODO: handle emissive color
|
||||
prog->shininess = m.specularPower;
|
||||
|
|
|
@ -185,7 +185,7 @@ void renderSphere_GLSL(const RenderInfo& ri,
|
|||
|
||||
prog->use();
|
||||
|
||||
prog->setLightParameters(ls, ri.color, ri.specularColor);
|
||||
prog->setLightParameters(ls, ri.color, ri.specularColor, Color::Black);
|
||||
|
||||
prog->eyePosition = ls.eyePos_obj;
|
||||
prog->shininess = ri.specularPower;
|
||||
|
@ -363,7 +363,7 @@ void renderClouds_GLSL(const RenderInfo& ri,
|
|||
|
||||
prog->use();
|
||||
|
||||
prog->setLightParameters(ls, ri.color, ri.specularColor);
|
||||
prog->setLightParameters(ls, ri.color, ri.specularColor, Color::Black);
|
||||
prog->eyePosition = ls.eyePos_obj;
|
||||
prog->ambientColor = Vec3f(ri.ambientColor.red(), ri.ambientColor.green(),
|
||||
ri.ambientColor.blue());
|
||||
|
@ -427,7 +427,7 @@ renderAtmosphere_GLSL(const RenderInfo& ri,
|
|||
|
||||
prog->use();
|
||||
|
||||
prog->setLightParameters(ls, ri.color, ri.specularColor);
|
||||
prog->setLightParameters(ls, ri.color, ri.specularColor, Color::Black);
|
||||
prog->ambientColor = Vec3f(0.0f, 0.0f, 0.0f);
|
||||
|
||||
float atmosphereRadius = radius + -atmosphere->mieScaleHeight * (float) log(AtmosphereExtinctionThreshold);
|
||||
|
@ -534,7 +534,7 @@ void renderRings_GLSL(RingSystem& rings,
|
|||
prog->eyePosition = ls.eyePos_obj;
|
||||
prog->ambientColor = Vec3f(ri.ambientColor.red(), ri.ambientColor.green(),
|
||||
ri.ambientColor.blue());
|
||||
prog->setLightParameters(ls, ri.color, ri.specularColor);
|
||||
prog->setLightParameters(ls, ri.color, ri.specularColor, Color::Black);
|
||||
|
||||
for (unsigned int li = 0; li < ls.nLights; li++)
|
||||
{
|
||||
|
|
|
@ -46,7 +46,8 @@ ShaderProperties::ShaderProperties() :
|
|||
nLights(0),
|
||||
texUsage(0),
|
||||
lightModel(DiffuseModel),
|
||||
shadowCounts(0)
|
||||
shadowCounts(0),
|
||||
effects(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -165,6 +166,11 @@ bool operator<(const ShaderProperties& p0, const ShaderProperties& p1)
|
|||
return true;
|
||||
else if (p1.shadowCounts < p0.shadowCounts)
|
||||
return false;
|
||||
|
||||
if (p0.effects < p1.effects)
|
||||
return true;
|
||||
else if (p1.effects < p0.effects)
|
||||
return false;
|
||||
|
||||
return (p0.lightModel < p1.lightModel);
|
||||
}
|
||||
|
@ -497,10 +503,6 @@ AddDirectionalLightContrib(unsigned int i, const ShaderProperties& props)
|
|||
source += "diff.rgb += " + LightProperty(i, "diffuse") + " * d;\n";
|
||||
}
|
||||
}
|
||||
else if (props.lightModel == ShaderProperties::LommelSeeligerModel)
|
||||
{
|
||||
source += AssignDiffuse(i, props) + " NL / (max(NV, 0.001) + NL);\n";
|
||||
}
|
||||
else if (props.lightModel == ShaderProperties::LunarLambertModel)
|
||||
{
|
||||
source += AssignDiffuse(i, props) + " mix(NL, NL / (max(NV, 0.001) + NL), lunarLambert);\n";
|
||||
|
@ -922,7 +924,7 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
|
|||
}
|
||||
else
|
||||
{
|
||||
source += "uniform vec3 ambientColor;\n";
|
||||
source += "uniform vec3 ambientColor;\n";
|
||||
source += "uniform float opacity;\n";
|
||||
source += "varying vec4 diff;\n";
|
||||
if (props.lightModel == ShaderProperties::SpecularModel)
|
||||
|
@ -1349,8 +1351,7 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
|
|||
source += "vec3 H;\n";
|
||||
source += "float NH;\n";
|
||||
}
|
||||
else if (props.lightModel == ShaderProperties::LommelSeeligerModel ||
|
||||
props.lightModel == ShaderProperties::LunarLambertModel)
|
||||
else if (props.lightModel == ShaderProperties::LunarLambertModel)
|
||||
{
|
||||
source += "float NV = dot(n, V);\n";
|
||||
}
|
||||
|
@ -1365,12 +1366,7 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
|
|||
// geometry like planet spheres.)
|
||||
// source += LightDir_tan(i) + " = normalize(" + LightDir(i)_tan + ");\n";
|
||||
source += "NL = dot(" + LightDir_tan(i) + ", n);\n";
|
||||
if (props.lightModel == ShaderProperties::LommelSeeligerModel)
|
||||
{
|
||||
source += "NL = max(0.0, NL);\n";
|
||||
source += "l = (NL / (max(NV, 0.001) + NL)) * clamp(" + LightDir_tan(i) + ".z * 8.0, 0.0, 1.0);\n";
|
||||
}
|
||||
else if (props.lightModel == ShaderProperties::LunarLambertModel)
|
||||
if (props.lightModel == ShaderProperties::LunarLambertModel)
|
||||
{
|
||||
source += "NL = max(0.0, NL);\n";
|
||||
source += "l = mix(NL, (NL / (max(NV, 0.001) + NL)), lunarLambert) * clamp(" + LightDir_tan(i) + ".z * 8.0, 0.0, 1.0);\n";
|
||||
|
@ -2010,7 +2006,8 @@ CelestiaGLProgram::initSamplers()
|
|||
void
|
||||
CelestiaGLProgram::setLightParameters(const LightingState& ls,
|
||||
Color materialDiffuse,
|
||||
Color materialSpecular)
|
||||
Color materialSpecular,
|
||||
Color materialEmissive)
|
||||
{
|
||||
unsigned int nLights = min(MaxShaderLights, ls.nLights);
|
||||
|
||||
|
@ -2062,9 +2059,9 @@ CelestiaGLProgram::setLightParameters(const LightingState& ls,
|
|||
}
|
||||
|
||||
eyePosition = ls.eyePos_obj;
|
||||
ambientColor = Vec3f(ls.ambientColor.x * diffuseColor.x,
|
||||
ls.ambientColor.y * diffuseColor.y,
|
||||
ls.ambientColor.z * diffuseColor.z);
|
||||
ambientColor = Vec3f(ls.ambientColor.x * diffuseColor.x + materialEmissive.red(),
|
||||
ls.ambientColor.y * diffuseColor.y + materialEmissive.green(),
|
||||
ls.ambientColor.z * diffuseColor.z + materialEmissive.blue());
|
||||
opacity = materialDiffuse.alpha();
|
||||
}
|
||||
|
||||
|
|
|
@ -53,18 +53,27 @@ class ShaderProperties
|
|||
RingIllumModel = 2,
|
||||
PerPixelSpecularModel = 3,
|
||||
OrenNayarModel = 4,
|
||||
LommelSeeligerModel = 5,
|
||||
AtmosphereModel = 6,
|
||||
LunarLambertModel = 7,
|
||||
AtmosphereModel = 5,
|
||||
LunarLambertModel = 6,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
VolumetricScatteringEffect = 0x0001,
|
||||
VolumetricAbsorptionEffect = 0x0002,
|
||||
VolumetricEmissionEffect = 0x0004,
|
||||
};
|
||||
|
||||
public:
|
||||
unsigned short nLights;
|
||||
unsigned short texUsage;
|
||||
unsigned short texUsage;
|
||||
unsigned short lightModel;
|
||||
|
||||
// Two bits per light, up to eight lights + three shadows per light
|
||||
unsigned short shadowCounts;
|
||||
|
||||
// Effects that may be applied with any light model
|
||||
unsigned short effects;
|
||||
};
|
||||
|
||||
|
||||
|
@ -96,7 +105,8 @@ class CelestiaGLProgram
|
|||
|
||||
void setLightParameters(const LightingState& ls,
|
||||
Color materialDiffuse,
|
||||
Color materialSpecular);
|
||||
Color materialSpecular,
|
||||
Color materialEmissive);
|
||||
void setEclipseShadowParameters(const LightingState& ls,
|
||||
float planetRadius,
|
||||
const Mat4f& planetMat);
|
||||
|
|
Loading…
Reference in New Issue