- Implemented cloud textures
- Changed eclipse shadow shaders to use just a single interpolant for all shadows rather than one interpolant per shadow. This will prevent Celestia from generating uncompilable shaders when there are many eclipse shadowsver1_5_1
parent
8283e04e95
commit
063ec093d3
|
@ -4012,7 +4012,10 @@ static void renderSphere_FP_VP(const RenderInfo& ri,
|
|||
static void renderSphere_GLSL(const RenderInfo& ri,
|
||||
const LightingState& ls,
|
||||
RingSystem* rings,
|
||||
Atmosphere* atmosphere,
|
||||
float cloudTexOffset,
|
||||
float radius,
|
||||
unsigned int textureRes,
|
||||
const Mat4f& planetMat,
|
||||
const Frustum& frustum,
|
||||
const GLContext& context)
|
||||
|
@ -4069,7 +4072,7 @@ static void renderSphere_GLSL(const RenderInfo& ri,
|
|||
(renderFlags & ShowRingShadows) != 0)
|
||||
#endif
|
||||
{
|
||||
Texture* ringsTex = rings->texture.find(medres);
|
||||
Texture* ringsTex = rings->texture.find(textureRes);
|
||||
if (ringsTex != NULL)
|
||||
{
|
||||
glx::glActiveTextureARB(GL_TEXTURE0_ARB + nTextures);
|
||||
|
@ -4087,6 +4090,23 @@ static void renderSphere_GLSL(const RenderInfo& ri,
|
|||
shadprop.texUsage |= ShaderProperties::RingShadowTexture;
|
||||
}
|
||||
}
|
||||
|
||||
if (atmosphere != NULL)
|
||||
{
|
||||
Texture* cloudTex = NULL;
|
||||
if (atmosphere->cloudTexture.tex[textureRes] != InvalidResource)
|
||||
cloudTex = atmosphere->cloudTexture.find(textureRes);
|
||||
if (cloudTex != NULL)
|
||||
{
|
||||
shadprop.texUsage |= ShaderProperties::CloudShadowTexture;
|
||||
textures[nTextures++] = cloudTex;
|
||||
#if 1
|
||||
glx::glActiveTextureARB(GL_TEXTURE0_ARB + nTextures);
|
||||
cloudTex->bind();
|
||||
glx::glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Set the shadow information.
|
||||
// Track the total number of shadows; if there are too many, we'll have
|
||||
|
@ -4126,6 +4146,12 @@ static void renderSphere_GLSL(const RenderInfo& ri,
|
|||
prog->ringRadius = rings->innerRadius / radius;
|
||||
prog->ringWidth = radius / ringWidth;
|
||||
}
|
||||
|
||||
if (shadprop.texUsage & ShaderProperties::CloudShadowTexture)
|
||||
{
|
||||
prog->shadowTextureOffset = cloudTexOffset;
|
||||
prog->cloudHeight = 1.0f + atmosphere->cloudHeight / radius;
|
||||
}
|
||||
|
||||
if (shadprop.shadowCounts != 0)
|
||||
setEclipseShadowShaderConstants(ls, radius, planetMat, *prog);
|
||||
|
@ -4178,6 +4204,7 @@ static void renderClouds_GLSL(const RenderInfo& ri,
|
|||
float texOffset,
|
||||
RingSystem* rings,
|
||||
float radius,
|
||||
unsigned int textureRes,
|
||||
const Mat4f& planetMat,
|
||||
const Frustum& frustum,
|
||||
const GLContext& context)
|
||||
|
@ -4199,7 +4226,7 @@ static void renderClouds_GLSL(const RenderInfo& ri,
|
|||
if (rings != NULL)
|
||||
//(renderFlags & ShowRingShadows) != 0)
|
||||
{
|
||||
Texture* ringsTex = rings->texture.find(medres);
|
||||
Texture* ringsTex = rings->texture.find(textureRes);
|
||||
if (ringsTex != NULL)
|
||||
{
|
||||
glx::glActiveTextureARB(GL_TEXTURE0_ARB + nTextures);
|
||||
|
@ -5418,12 +5445,28 @@ void Renderer::renderObject(Point3f pos,
|
|||
nearPlaneDistance, farPlaneDistance);
|
||||
viewFrustum.transform(invMV);
|
||||
|
||||
// Temporary hack until we fix culling for ringed planets
|
||||
// Temporary hack until we fix culling for ringed planets; prevents
|
||||
// over-tesselation of ringed planet surfaces. The amount of tesselation
|
||||
// should be based on the screen width of the planet sphere, not including
|
||||
// the rings.
|
||||
if (obj.rings != NULL)
|
||||
{
|
||||
if (ri.pixWidth > 5000)
|
||||
ri.pixWidth = 5000;
|
||||
}
|
||||
|
||||
// Get cloud layer parameters
|
||||
Texture* cloudTex = NULL;
|
||||
float cloudTexOffset = 0.0f;
|
||||
if (obj.atmosphere != NULL)
|
||||
{
|
||||
Atmosphere* atmosphere = const_cast<Atmosphere*>(obj.atmosphere); // Ugly cast required because MultiResTexture::find() is non-const
|
||||
if ((renderFlags & ShowCloudMaps) != 0 &&
|
||||
atmosphere->cloudTexture.tex[textureResolution] != InvalidResource)
|
||||
cloudTex = atmosphere->cloudTexture.find(textureResolution);
|
||||
if (atmosphere->cloudSpeed != 0.0f)
|
||||
cloudTexOffset = (float) (-pfmod(now * atmosphere->cloudSpeed / (2 * PI), 1.0));
|
||||
}
|
||||
|
||||
Model* model = NULL;
|
||||
if (obj.model == InvalidResource)
|
||||
|
@ -5434,7 +5477,10 @@ void Renderer::renderObject(Point3f pos,
|
|||
switch (context->getRenderPath())
|
||||
{
|
||||
case GLContext::GLPath_GLSL:
|
||||
renderSphere_GLSL(ri, ls, obj.rings, obj.radius,
|
||||
renderSphere_GLSL(ri, ls, obj.rings,
|
||||
const_cast<Atmosphere*>(obj.atmosphere), cloudTexOffset,
|
||||
obj.radius,
|
||||
textureResolution,
|
||||
planetMat, viewFrustum, *context);
|
||||
break;
|
||||
|
||||
|
@ -5573,11 +5619,6 @@ void Renderer::renderObject(Point3f pos,
|
|||
}
|
||||
|
||||
// If there's a cloud layer, we'll render it now.
|
||||
Texture* cloudTex = NULL;
|
||||
if ((renderFlags & ShowCloudMaps) != 0 &&
|
||||
atmosphere->cloudTexture.tex[textureResolution] != InvalidResource)
|
||||
cloudTex = atmosphere->cloudTexture.find(textureResolution);
|
||||
|
||||
if (cloudTex != NULL)
|
||||
{
|
||||
glPushMatrix();
|
||||
|
@ -5590,7 +5631,6 @@ void Renderer::renderObject(Point3f pos,
|
|||
if (distance - radius < atmosphere->cloudHeight)
|
||||
glFrontFace(GL_CW);
|
||||
|
||||
float texOffset = (float) (-pfmod(now * atmosphere->cloudSpeed / (2 * PI), 1.0));
|
||||
if (atmosphere->cloudSpeed != 0.0f)
|
||||
{
|
||||
// Make the clouds appear to rotate above the surface of
|
||||
|
@ -5599,7 +5639,7 @@ void Renderer::renderObject(Point3f pos,
|
|||
// texture matrix doesn't require us to compute a second
|
||||
// set of model space rendering parameters.
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glTranslatef(texOffset, 0.0f, 0.0f);
|
||||
glTranslatef(cloudTexOffset, 0.0f, 0.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
|
@ -5616,9 +5656,10 @@ void Renderer::renderObject(Point3f pos,
|
|||
{
|
||||
renderClouds_GLSL(ri, ls,
|
||||
cloudTex,
|
||||
texOffset,
|
||||
cloudTexOffset,
|
||||
obj.rings,
|
||||
radius * cloudScale,
|
||||
textureResolution,
|
||||
planetMat,
|
||||
viewFrustum,
|
||||
*context);
|
||||
|
@ -5631,7 +5672,7 @@ void Renderer::renderObject(Point3f pos,
|
|||
vproc->enable();
|
||||
vproc->parameter(vp::AmbientColor, ri.ambientColor * ri.color);
|
||||
vproc->parameter(vp::TextureTranslation,
|
||||
texOffset, 0.0f, 0.0f, 0.0f);
|
||||
cloudTexOffset, 0.0f, 0.0f, 0.0f);
|
||||
if (ls.nLights > 1)
|
||||
vproc->use(vp::diffuseTexOffset_2light);
|
||||
else
|
||||
|
|
|
@ -53,10 +53,9 @@ ShaderProperties::ShaderProperties() :
|
|||
bool
|
||||
ShaderProperties::usesShadows() const
|
||||
{
|
||||
if ((texUsage & RingShadowTexture) != 0 || shadowCounts != 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return (texUsage & RingShadowTexture) != 0 ||
|
||||
(texUsage & CloudShadowTexture) != 0 ||
|
||||
shadowCounts != 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,8 +93,8 @@ bool
|
|||
ShaderProperties::hasShadowsForLight(unsigned int light) const
|
||||
{
|
||||
assert(light < MaxShaderLights);
|
||||
return ((getShadowCountForLight(light) != 0) ||
|
||||
(texUsage & RingShadowTexture));
|
||||
return getShadowCountForLight(light) != 0 ||
|
||||
(texUsage & (RingShadowTexture | CloudShadowTexture)) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -287,6 +286,15 @@ RingShadowTexCoord(unsigned int index)
|
|||
}
|
||||
|
||||
|
||||
static string
|
||||
CloudShadowTexCoord(unsigned int index)
|
||||
{
|
||||
char buf[64];
|
||||
sprintf(buf, "cloudShadowTexCoord%d", index);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CelestiaGLProgram::initParameters(const ShaderProperties& props)
|
||||
{
|
||||
|
@ -333,6 +341,12 @@ CelestiaGLProgram::initParameters(const ShaderProperties& props)
|
|||
|
||||
textureOffset = floatParam("textureOffset");
|
||||
|
||||
if (props.texUsage & ShaderProperties::CloudShadowTexture)
|
||||
{
|
||||
cloudHeight = floatParam("cloudHeight");
|
||||
shadowTextureOffset = floatParam("cloudShadowTexOffset");
|
||||
}
|
||||
|
||||
if ((props.texUsage & ShaderProperties::NightTexture) != 0)
|
||||
{
|
||||
nightTexMin = floatParam("nightTexMin");
|
||||
|
@ -387,6 +401,13 @@ CelestiaGLProgram::initSamplers(const ShaderProperties& props)
|
|||
if (slot != -1)
|
||||
glx::glUniform1iARB(slot, nSamplers++);
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::CloudShadowTexture)
|
||||
{
|
||||
int slot = glx::glGetUniformLocationARB(program->getID(), "cloudShadowTex");
|
||||
if (slot != -1)
|
||||
glx::glUniform1iARB(slot, nSamplers++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -475,6 +496,16 @@ SeparateSpecular(unsigned int i)
|
|||
}
|
||||
|
||||
|
||||
// Used by rings shader
|
||||
static string
|
||||
ShadowDepth(unsigned int i)
|
||||
{
|
||||
char buf[32];
|
||||
sprintf(buf, "shadowDepths.%c", "xyzw"[i & 3]);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
|
||||
static string
|
||||
TexCoord2D(unsigned int i)
|
||||
{
|
||||
|
@ -595,6 +626,12 @@ BeginLightSourceShadows(const ShaderProperties& props, unsigned int light)
|
|||
source += "shadow *= (1.0 - texture2D(ringTex, vec2(" +
|
||||
RingShadowTexCoord(light) + ", 0.0)).a);\n";
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::CloudShadowTexture)
|
||||
{
|
||||
source += "shadow *= (1.0 - texture2D(cloudShadowTex, " +
|
||||
CloudShadowTexCoord(light) + ").a * 0.75);\n";
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
|
@ -605,9 +642,10 @@ Shadow(unsigned int light, unsigned int shadow)
|
|||
{
|
||||
string source;
|
||||
|
||||
source += "shadowCenter = " +
|
||||
IndexedParameter("shadowTexCoord", light, shadow) +
|
||||
".st - vec2(0.5, 0.5);\n";
|
||||
source += "shadowCenter.s = dot(vec4(position_obj, 1.0), " +
|
||||
IndexedParameter("shadowTexGenS", light, shadow) + ") - 0.5;\n";
|
||||
source += "shadowCenter.t = dot(vec4(position_obj, 1.0), " +
|
||||
IndexedParameter("shadowTexGenT", light, shadow) + ") - 0.5;\n";
|
||||
source += "shadowR = clamp(dot(shadowCenter, shadowCenter) * " +
|
||||
IndexedParameter("shadowScale", light, shadow) + " + " +
|
||||
IndexedParameter("shadowBias", light, shadow) + ", 0.0, 1.0);\n";
|
||||
|
@ -659,7 +697,7 @@ TextureSamplerDeclarations(const ShaderProperties& props)
|
|||
{
|
||||
source += "uniform sampler2D overlayTex;\n";
|
||||
}
|
||||
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
|
@ -768,18 +806,7 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
|
|||
// Shadow parameters
|
||||
if (props.shadowCounts != 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < props.getShadowCountForLight(i); j++)
|
||||
{
|
||||
source += "varying vec2 " +
|
||||
IndexedParameter("shadowTexCoord", i, j) + ";\n";
|
||||
source += "uniform vec4 " +
|
||||
IndexedParameter("shadowTexGenS", i, j) + ";\n";
|
||||
source += "uniform vec4 " +
|
||||
IndexedParameter("shadowTexGenT", i, j) + ";\n";
|
||||
}
|
||||
}
|
||||
source += "varying vec3 position_obj;\n";
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::RingShadowTexture)
|
||||
|
@ -789,6 +816,13 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
|
|||
source += "varying vec4 ringShadowTexCoord;\n";
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::CloudShadowTexture)
|
||||
{
|
||||
source += "uniform float cloudShadowTexOffset;\n";
|
||||
source += "uniform float cloudHeight;\n";
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
source += "varying vec2 " + CloudShadowTexCoord(i) + ";\n";
|
||||
}
|
||||
|
||||
// Begin main() function
|
||||
source += "\nvoid main(void)\n{\n";
|
||||
|
@ -881,6 +915,33 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
|
|||
" = (length(ringShadowProj) - ringRadius) * ringWidth;\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::CloudShadowTexture)
|
||||
{
|
||||
for (unsigned int j = 0; j < props.nLights; j++)
|
||||
{
|
||||
source += "{\n";
|
||||
|
||||
// A cheap way to calculate cloud shadow texture coordinates that doesn't correctly account
|
||||
// for sun angle.
|
||||
//source += " " + CloudShadowTexCoord(j) + " = vec2(diffTexCoord.x + cloudShadowTexOffset, diffTexCoord.y);\n";
|
||||
|
||||
// Compute the intersection of the sun direction and the cloud layer (currently assumed to be a sphere)
|
||||
source += " float s = 1.0 / (cloudHeight * cloudHeight);\n";
|
||||
source += " float invPi = 1.0f / 3.1415927;\n";
|
||||
source += " vec3 coeff;\n";
|
||||
source += " coeff.x = dot(" + LightProperty(j, "direction") + ", " + LightProperty(j, "direction") + ") * s;\n";
|
||||
source += " coeff.y = dot(" + LightProperty(j, "direction") + ", gl_Vertex.xyz) * s;\n";
|
||||
source += " coeff.z = dot(gl_Vertex.xyz, gl_Vertex.xyz) * s - 1.0;\n";
|
||||
source += " float disc = sqrt(coeff.y * coeff.y - coeff.x * coeff.z);\n";
|
||||
source += " vec3 cloudSpherePos = normalize(gl_Vertex.xyz + ((-coeff.y + disc) / coeff.x) * " + LightProperty(j, "direction") + ");\n";
|
||||
|
||||
// Find the texture coordinates at this point on the sphere by converting from rectangular to spherical; this is an
|
||||
// expensive calculation to perform per vertex.
|
||||
source += " " + CloudShadowTexCoord(j) + " = vec2(cloudShadowTexOffset + fract(atan(cloudSpherePos.x, cloudSpherePos.z) * (invPi * 0.5) + 0.75), 0.5 - asin(cloudSpherePos.y) * invPi);\n";
|
||||
source += "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::OverlayTexture)
|
||||
{
|
||||
|
@ -890,18 +951,7 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
|
|||
|
||||
if (props.shadowCounts != 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < props.getShadowCountForLight(i); j++)
|
||||
{
|
||||
source += IndexedParameter("shadowTexCoord", i, j) +
|
||||
".s = dot(gl_Vertex, " +
|
||||
IndexedParameter("shadowTexGenS", i, j) + ");\n";
|
||||
source += IndexedParameter("shadowTexCoord", i, j) +
|
||||
".t = dot(gl_Vertex, " +
|
||||
IndexedParameter("shadowTexGenT", i, j) + ");\n";
|
||||
}
|
||||
}
|
||||
source += "position_obj = gl_Vertex.xyz;\n";
|
||||
}
|
||||
|
||||
source += "gl_Position = ftransform();\n";
|
||||
|
@ -1019,12 +1069,15 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
|
|||
// Declare shadow parameters
|
||||
if (props.shadowCounts != 0)
|
||||
{
|
||||
source += "varying vec3 position_obj;\n";
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < props.getShadowCountForLight(i); j++)
|
||||
{
|
||||
source += "varying vec2 " +
|
||||
IndexedParameter("shadowTexCoord", i, j) + ";\n";
|
||||
source += "uniform vec4 " +
|
||||
IndexedParameter("shadowTexGenS", i, j) + ";\n";
|
||||
source += "uniform vec4 " +
|
||||
IndexedParameter("shadowTexGenT", i, j) + ";\n";
|
||||
source += "uniform float " +
|
||||
IndexedParameter("shadowScale", i, j) + ";\n";
|
||||
source += "uniform float " +
|
||||
|
@ -1038,7 +1091,14 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
|
|||
source += "uniform sampler2D ringTex;\n";
|
||||
source += "varying vec4 ringShadowTexCoord;\n";
|
||||
}
|
||||
|
||||
|
||||
if (props.texUsage & ShaderProperties::CloudShadowTexture)
|
||||
{
|
||||
source += "uniform sampler2D cloudShadowTex;\n";
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
source += "varying vec2 " + CloudShadowTexCoord(i) + ";\n";
|
||||
}
|
||||
|
||||
source += "\nvoid main(void)\n{\n";
|
||||
source += "vec4 color;\n";
|
||||
|
||||
|
@ -1053,7 +1113,6 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Sum the illumination from each light source, computing a total diffuse and specular
|
||||
// contributions from all sources.
|
||||
if (props.usesTangentSpaceLighting())
|
||||
|
@ -1065,6 +1124,7 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
|
|||
// an option for this.
|
||||
if (props.texUsage & ShaderProperties::NormalTexture)
|
||||
{
|
||||
//source += "vec3 n = normalize(texture2D(normTex, " + normTexCoord + ".st).xyz * 2.0 - vec3(1.0, 1.0, 1.0));\n";
|
||||
source += "vec3 n = texture2D(normTex, " + normTexCoord + ".st).xyz * 2.0 - vec3(1.0, 1.0, 1.0);\n";
|
||||
}
|
||||
else
|
||||
|
@ -1221,15 +1281,8 @@ ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
|
|||
|
||||
if (props.shadowCounts != 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
{
|
||||
source += "uniform vec4 " +
|
||||
IndexedParameter("shadowTexGenS", i, 0) + ";\n";
|
||||
source += "uniform vec4 " +
|
||||
IndexedParameter("shadowTexGenT", i, 0) + ";\n";
|
||||
source += "varying vec3 " +
|
||||
IndexedParameter("shadowTexCoord", i, 0) + ";\n";
|
||||
}
|
||||
source += "varying vec3 position_obj;\n";
|
||||
source += "varying vec4 shadowDepths;\n";
|
||||
}
|
||||
|
||||
source += "\nvoid main(void)\n{\n";
|
||||
|
@ -1249,17 +1302,11 @@ ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
|
|||
|
||||
if (props.shadowCounts != 0)
|
||||
{
|
||||
source += "position_obj = gl_Vertex.xyz;\n";
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
{
|
||||
source += IndexedParameter("shadowTexCoord", i, 0) +
|
||||
".x = dot(gl_Vertex, " +
|
||||
IndexedParameter("shadowTexGenS", i, 0) + ");\n";
|
||||
source += IndexedParameter("shadowTexCoord", i, 0) +
|
||||
".y = dot(gl_Vertex, " +
|
||||
IndexedParameter("shadowTexGenT", i, 0) + ");\n";
|
||||
source += IndexedParameter("shadowTexCoord", i, 0) +
|
||||
".z = dot(gl_Vertex.xyz, " +
|
||||
LightProperty(i, "direction") + ");\n";
|
||||
source += ShadowDepth(i) + " = dot(gl_Vertex.xyz, " +
|
||||
LightProperty(i, "direction") + ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1300,16 +1347,25 @@ ShaderManager::buildRingsFragmentShader(const ShaderProperties& props)
|
|||
source += "uniform sampler2D diffTex;\n";
|
||||
}
|
||||
|
||||
|
||||
if (props.shadowCounts != 0)
|
||||
{
|
||||
source += "varying vec3 position_obj;\n";
|
||||
source += "varying vec4 shadowDepths;\n";
|
||||
|
||||
for (unsigned int i = 0; i < props.nLights; i++)
|
||||
{
|
||||
source += "varying vec3 " +
|
||||
IndexedParameter("shadowTexCoord", i, 0) + ";\n";
|
||||
source += "uniform float " +
|
||||
IndexedParameter("shadowScale", i, 0) + ";\n";
|
||||
source += "uniform float " +
|
||||
IndexedParameter("shadowBias", i, 0) + ";\n";
|
||||
for (unsigned int j = 0; j < props.getShadowCountForLight(i); j++)
|
||||
{
|
||||
source += "uniform vec4 " +
|
||||
IndexedParameter("shadowTexGenS", i, j) + ";\n";
|
||||
source += "uniform vec4 " +
|
||||
IndexedParameter("shadowTexGenT", i, j) + ";\n";
|
||||
source += "uniform float " +
|
||||
IndexedParameter("shadowScale", i, j) + ";\n";
|
||||
source += "uniform float " +
|
||||
IndexedParameter("shadowBias", i, j) + ";\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1331,8 +1387,7 @@ ShaderManager::buildRingsFragmentShader(const ShaderProperties& props)
|
|||
{
|
||||
source += "shadow = 1.0;\n";
|
||||
source += Shadow(i, 0);
|
||||
source += "shadow = min(1.0, shadow + step(0.0, " +
|
||||
IndexedParameter("shadowTexCoord", i, 0) + ".z));\n";
|
||||
source += "shadow = min(1.0, shadow + step(0.0, " + ShadowDepth(i) + "));\n";
|
||||
source += "diff.rgb += (shadow * " + SeparateDiffuse(i) + ") * " +
|
||||
FragLightProperty(i, "color") + ";\n";
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ class ShaderProperties
|
|||
SpecularInDiffuseAlpha = 0x10,
|
||||
RingShadowTexture = 0x20,
|
||||
OverlayTexture = 0x40,
|
||||
CloudShadowTexture = 0x80,
|
||||
SharedTextureCoords = 0x8000,
|
||||
};
|
||||
|
||||
|
@ -97,6 +98,11 @@ class CelestiaGLProgram
|
|||
|
||||
// Diffuse texture coordinate offset
|
||||
FloatShaderParameter textureOffset;
|
||||
|
||||
// Cloud shadow parameters
|
||||
// Height of cloud layer above planet, in units of object radius
|
||||
FloatShaderParameter cloudHeight;
|
||||
FloatShaderParameter shadowTextureOffset;
|
||||
|
||||
// Control the night texture effect--set to 1 for a purely additive effect,
|
||||
// and 0 to show the night texture only in otherwise unilluminated regions.
|
||||
|
|
Loading…
Reference in New Issue