HDR bloom, adaptive exposure, calibrated nightlights - disabled by default, enable with USE_HDR and HDR_COMPRESS. 4 new vertex programs added.

ver1_6_1
Da Woon Jung 2008-03-25 00:23:16 +00:00
parent b950e37ddc
commit e59f4b4b54
21 changed files with 1728 additions and 25 deletions

View File

@ -0,0 +1,54 @@
!!ARBvp1.0
# Compute the surface space light vectors for diffuse bump mapping
ATTRIB iPos = vertex.position;
ATTRIB iNormal = vertex.normal;
ATTRIB iTangent = vertex.attrib[6];
ATTRIB iTex0 = vertex.texcoord[0];
ATTRIB iTex1 = vertex.texcoord[1];
PARAM mvp[4] = { state.matrix.mvp };
PARAM lightDir = program.env[0];
PARAM qtr = 0.25;
PARAM half = 0.5;
PARAM one = 1;
OUTPUT oPos = result.position;
OUTPUT oColor = result.color;
OUTPUT oTex0 = result.texcoord[0];
OUTPUT oTex1 = result.texcoord[1];
TEMP binormal;
TEMP t;
TEMP light_surf;
# Transform the vertex by the modelview matrix
DP4 oPos.x, mvp[0], iPos;
DP4 oPos.y, mvp[1], iPos;
DP4 oPos.z, mvp[2], iPos;
DP4 oPos.w, mvp[3], iPos;
# Compute the binormal--cross product of tangent and normal
MOV t, iTangent;
MUL binormal, iNormal.zxyw, t.yzxw;
MAD binormal, iNormal.yzxw, t.zxyw, -binormal;
# Normalization should not be necessary
#DP3 binormal.w, binormal, binormal;
#RSQ binormal.w, binormal.w;
#MUL binormal.xyz, binormal, binormal.w;
# Transform the light direction from object space into surface space
DP3 light_surf.x, iTangent, lightDir;
DP3 light_surf.y, -binormal, lightDir;
DP3 light_surf.z, iNormal, lightDir;
# Compress the light direction to fit in the primary color and output it
MAD oColor, light_surf, qtr, half;
MOV oColor.w, one.w;
# Output the texture
MOV oTex0, iTex0;
MOV oTex1, iTex1;
END

View File

@ -0,0 +1,81 @@
!!ARBvp1.0
# Compute the surface space light vectors for diffuse bump mapping
# as well as a fog factor for an atmospheric haze effect.
ATTRIB iPos = vertex.position;
ATTRIB iNormal = vertex.normal;
ATTRIB iTangent = vertex.attrib[6];
ATTRIB iTex0 = vertex.texcoord[0];
ATTRIB iTex1 = vertex.texcoord[1];
PARAM mvp[4] = { state.matrix.mvp };
PARAM eyePos = program.env[1];
PARAM lightDir = program.env[0];
PARAM haze = program.env[6];
PARAM qtr = 0.25;
PARAM half = 0.5;
PARAM zero = 0;
PARAM one = 1;
OUTPUT oPos = result.position;
OUTPUT oColor = result.color;
OUTPUT oTex0 = result.texcoord[0];
OUTPUT oTex1 = result.texcoord[1];
OUTPUT oFog = result.fogcoord;
TEMP binormal;
TEMP t;
TEMP light_surf;
TEMP diffuseFactor;
TEMP eyeVec;
# Transform the vertex by the modelview matrix
DP4 oPos.x, mvp[0], iPos;
DP4 oPos.y, mvp[1], iPos;
DP4 oPos.z, mvp[2], iPos;
DP4 oPos.w, mvp[3], iPos;
# Compute the diffuse light component
DP3 diffuseFactor, iNormal, lightDir;
# Clamp the diffuse component to zero
MAX diffuseFactor, diffuseFactor, zero;
# Get the vector from the eye to the vertex
SUB eyeVec, eyePos, iPos;
# Normalize it
DP3 eyeVec.w, eyeVec, eyeVec;
RSQ eyeVec.w, eyeVec.w;
MUL eyeVec, eyeVec, eyeVec.w;
# Output the fog factor
DP3 diffuseFactor.y, iNormal, eyeVec;
SUB diffuseFactor.y, one, diffuseFactor.y;
MUL oFog.x, diffuseFactor.x, diffuseFactor.y;
# Haze is complete; now do the bump mapping setup
# Compute the binormal--cross product of normal and tangent
MOV t, iTangent;
MUL binormal, iNormal.zxyw, t.yzxw;
MAD binormal, iNormal.yzxw, t.zxyw, -binormal;
# Normalization should not be necessary
#DP3 binormal.w, binormal, binormal;
#RSQ binormal.w, binormal.w;
#MUL binormal.xyz, binormal, binormal.w;
# Transform the light direction from object space into surface space
DP3 light_surf.x, iTangent, lightDir;
DP3 light_surf.y, -binormal, lightDir;
DP3 light_surf.z, iNormal, lightDir;
# Compress the light direction to fit in the primary color and output it
MAD oColor, light_surf, qtr, half;
MOV oColor.w, one.w;
# Output the texture
MOV oTex0, iTex0;
MOV oTex1, iTex1;
END

View File

@ -0,0 +1,48 @@
!!ARBvp1.0
# Night texture lighting
ATTRIB iPos = vertex.position;
ATTRIB iNormal = vertex.normal;
ATTRIB iTex0 = vertex.texcoord[0];
PARAM mvp[4] = { state.matrix.mvp };
PARAM lightDir0 = program.env[0];
PARAM diffuse = program.env[2];
PARAM lightDir1 = program.env[18];
PARAM zeroVec = { 0, 0, 0, 0 };
PARAM one = 1;
OUTPUT oPos = result.position;
OUTPUT oColor = result.color;
OUTPUT oTex0 = result.texcoord[0];
TEMP diffuseFactor;
TEMP diffuseSum;
# Transform the vertex by the modelview matrix
DP4 oPos.x, mvp[0], iPos;
DP4 oPos.y, mvp[1], iPos;
DP4 oPos.z, mvp[2], iPos;
DP4 oPos.w, mvp[3], iPos;
# Compute the illumination from the first light source
DP3 diffuseFactor, iNormal, lightDir0;
MAX diffuseFactor, diffuseFactor, zeroVec;
MOV diffuseSum, diffuseFactor;
# Compute the illumination from the second light source
DP3 diffuseFactor, iNormal, lightDir1;
MAX diffuseFactor, diffuseFactor, zeroVec;
ADD diffuseSum, diffuseSum, diffuseFactor;
# Use the fourth power of L dot N to create a sharper division between
# the lit and unlit sides of the planet.
ADD diffuseSum, one, -diffuseSum;
MUL diffuseSum, diffuseSum, diffuseSum;
MUL diffuseSum, diffuseSum, diffuseSum;
# Output the texture
MOV oTex0, iTex0;
# Output the primary color
MUL oColor, diffuse, diffuseSum;
END

View File

@ -0,0 +1,41 @@
!!ARBvp1.0
# Night texture lighting
ATTRIB iPos = vertex.position;
ATTRIB iNormal = vertex.normal;
ATTRIB iTex0 = vertex.texcoord[0];
PARAM mvp[4] = { state.matrix.mvp };
PARAM lightDir = program.env[0];
PARAM diffuse = program.env[2];
PARAM zeroVec = { 0, 0, 0, 0 };
PARAM one = 1;
OUTPUT oPos = result.position;
OUTPUT oColor = result.color;
OUTPUT oTex0 = result.texcoord[0];
TEMP diffuseFactor;
# Transform the vertex by the modelview matrix
DP4 oPos.x, mvp[0], iPos;
DP4 oPos.y, mvp[1], iPos;
DP4 oPos.z, mvp[2], iPos;
DP4 oPos.w, mvp[3], iPos;
# Compute the diffuse light component
DP3 diffuseFactor, iNormal, lightDir;
# Clamp the diffuse component to zero
MAX diffuseFactor, diffuseFactor, zeroVec;
# Use the fourth power of L dot N to create a sharper division between
# the lit and unlit sides of the planet.
ADD diffuseFactor, one, -diffuseFactor;
MUL diffuseFactor, diffuseFactor, diffuseFactor;
MUL diffuseFactor, diffuseFactor, diffuseFactor;
# Output the texture
MOV oTex0, iTex0;
# Output the primary color
MUL oColor, diffuse, diffuseFactor;
END

View File

@ -240,7 +240,11 @@ ArrowReferenceMark::ArrowReferenceMark(const Body& _body) :
body(_body),
size(1.0),
color(1.0f, 1.0f, 1.0f),
#ifdef USE_HDR
opacity(0.0f)
#else
opacity(1.0f)
#endif
{
}
@ -287,7 +291,11 @@ ArrowReferenceMark::render(Renderer* /* renderer */,
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
#ifdef USE_HDR
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
#else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
}
glPushMatrix();
@ -320,7 +328,11 @@ ArrowReferenceMark::render(Renderer* /* renderer */,
AxesReferenceMark::AxesReferenceMark(const Body& _body) :
body(_body),
size(),
opacity(1.0)
#ifdef USE_HDR
opacity(0.0f)
#else
opacity(1.0f)
#endif
{
}
@ -336,6 +348,9 @@ void
AxesReferenceMark::setOpacity(float _opacity)
{
opacity = _opacity;
#ifdef USE_HDR
opacity = 1.0f - opacity;
#endif
}
@ -359,7 +374,11 @@ AxesReferenceMark::render(Renderer* /* renderer */,
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
#ifdef USE_HDR
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
#else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
}
glDisable(GL_TEXTURE_2D);

View File

@ -79,7 +79,13 @@ class RingSystem
MultiResTexture texture;
RingSystem(float inner, float outer) :
innerRadius(inner), outerRadius(outer), color(1.0f, 1.0f, 1.0f), texture()
innerRadius(inner), outerRadius(outer),
#ifdef HDR_COMPRESS
color(0.5f, 0.5f, 0.5f),
#else
color(1.0f, 1.0f, 1.0f),
#endif
texture()
{ };
RingSystem(float inner, float outer, Color _color, int _loTexture = -1, int _texture = -1) :
innerRadius(inner), outerRadius(outer), color(_color), texture(_loTexture, _texture)

View File

@ -83,9 +83,15 @@ static void GalaxyTextureEval(float u, float v, float /*w*/, unsigned char *pixe
r = 0;
int pixVal = (int) (r * 255.99f);
#ifdef HDR_COMPRESS
pixel[0] = 127;
pixel[1] = 127;
pixel[2] = 127;
#else
pixel[0] = 255;//65;
pixel[1] = 255;//64;
pixel[2] = 255;//65;
#endif
pixel[3] = pixVal;
}

View File

@ -244,10 +244,17 @@ FixedFunctionRenderContext::makeCurrent(const Mesh::Material& m)
if (useNormals || !lightingEnabled)
{
#ifdef HDR_COMPRESS
glColor4f(m.diffuse.red() * 0.5f,
m.diffuse.green() * 0.5f,
m.diffuse.blue() * 0.5f,
m.opacity);
#else
glColor4f(m.diffuse.red(),
m.diffuse.green(),
m.diffuse.blue(),
m.opacity);
#endif
if (m.specular == Color::Black)
{
@ -288,10 +295,17 @@ FixedFunctionRenderContext::makeCurrent(const Mesh::Material& m)
glMaterialfv(GL_FRONT, GL_SPECULAR, matBlack);
glMaterialfv(GL_FRONT, GL_SHININESS, &zero);
{
#ifdef HDR_COMPRESS
float matEmissive[4] = { m.emissive.red() + m.diffuse.red() * 0.5f,
m.emissive.green() + m.diffuse.green() * 0.5f,
m.emissive.blue() + m.diffuse.blue() * 0.5f,
m.opacity };
#else
float matEmissive[4] = { m.emissive.red() + m.diffuse.red(),
m.emissive.green() + m.diffuse.green(),
m.emissive.blue() + m.diffuse.blue(),
m.opacity };
#endif
glMaterialfv(GL_FRONT, GL_EMISSION, matEmissive);
}
}
@ -633,7 +647,11 @@ GLSL_RenderContext::makeCurrent(const Mesh::Material& m)
}
// setLightParameters() expects opacity in the alpha channel of the diffuse color
#ifdef HDR_COMPRESS
Color diffuse(m.diffuse.red() * 0.5f, m.diffuse.green() * 0.5f, m.diffuse.blue() * 0.5f, m.opacity);
#else
Color diffuse(m.diffuse.red(), m.diffuse.green(), m.diffuse.blue(), m.opacity);
#endif
prog->setLightParameters(lightingState, diffuse, m.specular, m.emissive);
@ -814,9 +832,15 @@ GLSLUnlit_RenderContext::makeCurrent(const Mesh::Material& m)
textures[i]->bind();
}
#ifdef HDR_COMPRESS
prog->lights[0].diffuse = Vec3f(m.diffuse.red() * 0.5f,
m.diffuse.green() * 0.5f,
m.diffuse.blue() * 0.5f);
#else
prog->lights[0].diffuse = Vec3f(m.diffuse.red(),
m.diffuse.green(),
m.diffuse.blue());
#endif
prog->opacity = m.opacity;
if ((shaderProps.texUsage & ShaderProperties::PointSprite) != 0)

File diff suppressed because it is too large Load Diff

View File

@ -98,7 +98,11 @@ class Renderer
const Universe&,
float faintestVisible,
const Selection& sel);
void draw(const Observer&,
const Universe&,
float faintestVisible,
const Selection& sel);
enum {
NoLabels = 0x000,
StarLabels = 0x001,
@ -191,6 +195,14 @@ class Renderer
void setVertexShaderEnabled(bool);
bool vertexShaderSupported() const;
#ifdef USE_HDR
bool getBloomEnabled();
void setBloomEnabled(bool);
void increaseBrightness();
void decreaseBrightness();
float getBrightness();
#endif
GLContext* getGLContext() { return context; }
void setStarStyle(StarStyle);
@ -534,6 +546,39 @@ class Renderer
float nearDist,
float farDist);
#ifdef USE_HDR
private:
int sceneTexWidth, sceneTexHeight;
GLfloat sceneTexWScale, sceneTexHScale;
GLsizei blurBaseWidth, blurBaseHeight;
GLuint sceneTexture;
Texture **blurTextures;
Texture *blurTempTexture;
GLuint gaussianLists[4];
GLint blurFormat;
bool useBlendSubtract;
bool useLuminanceAlpha;
bool bloomEnabled;
float maxBodyMag;
float exposure, exposurePrev;
float brightPlus;
void genBlurTexture(int blurLevel);
void genBlurTextures();
void genSceneTexture();
void renderToBlurTexture(int blurLevel);
void renderToTexture(const Observer& observer,
const Universe& universe,
float faintestMagNight,
const Selection& sel);
void drawSceneTexture();
void drawBlur();
void drawGaussian3x3(float xdelta, float ydelta, GLsizei width, GLsizei height, float blend);
void drawGaussian5x5(float xdelta, float ydelta, GLsizei width, GLsizei height, float blend);
void drawGaussian9x9(float xdelta, float ydelta, GLsizei width, GLsizei height, float blend);
void drawBlendedVertices(float xdelta, float ydelta, float blend);
#endif
private:
GLContext* context;

View File

@ -212,7 +212,11 @@ void renderSphere_GLSL(const RenderInfo& ri,
prog->use();
#ifdef USE_HDR
prog->setLightParameters(ls, ri.color, ri.specularColor, Color::Black, ri.nightLightScale);
#else
prog->setLightParameters(ls, ri.color, ri.specularColor, Color::Black);
#endif
prog->eyePosition = ls.eyePos_obj;
prog->shininess = ri.specularPower;

View File

@ -24,13 +24,21 @@ struct RenderInfo
Point3f eyePos_obj;
Color sunColor;
Color ambientColor;
#ifdef USE_HDR
float nightLightScale;
#endif
float lunarLambert;
Quatf orientation;
float pixWidth;
float pointScale;
bool useTexEnvCombine;
RenderInfo() : color(1.0f, 1.0f, 1.0f),
RenderInfo() :
#ifdef HDR_COMPRESS
color(0.5f, 0.5f, 0.5f),
#else
color(1.0f, 1.0f, 1.0f),
#endif
baseTex(NULL),
bumpTex(NULL),
nightTex(NULL),
@ -45,6 +53,9 @@ struct RenderInfo
eyePos_obj(0.0f, 0.0f, 0.0f),
sunColor(1.0f, 1.0f, 1.0f),
ambientColor(0.0f, 0.0f, 0.0f),
#ifdef USE_HDR
nightLightScale(1.0f),
#endif
lunarLambert(0.0f),
orientation(1.0f, 0.0f, 0.0f, 0.0f),
pixWidth(1.0f),

View File

@ -1327,9 +1327,15 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
source += "varying vec3 scatterEx;\n";
}
if ((props.texUsage & ShaderProperties::NightTexture) && VSComputesColorSum(props))
if ((props.texUsage & ShaderProperties::NightTexture))
{
source += "varying float totalLight;\n";
#ifdef USE_HDR
source += "uniform float nightLightScale;\n";
#endif
if (VSComputesColorSum(props))
{
source += "varying float totalLight;\n";
}
}
// Declare shadow parameters
@ -1580,7 +1586,11 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
source += NightTextureBlend();
}
#ifdef USE_HDR
source += "gl_FragColor += texture2D(nightTex, " + nightTexCoord + ".st) * totalLight * nightLightScale;\n";
#else
source += "gl_FragColor += texture2D(nightTex, " + nightTexCoord + ".st) * totalLight;\n";
#endif
}
if (props.texUsage & ShaderProperties::EmissiveTexture)
@ -2144,6 +2154,9 @@ CelestiaGLProgram::initParameters()
opacity = floatParam("opacity");
ambientColor = vec3Param("ambientColor");
#ifdef USE_HDR
nightLightScale = floatParam("nightLightScale");
#endif
if (props.texUsage & ShaderProperties::RingShadowTexture)
{
@ -2253,7 +2266,11 @@ void
CelestiaGLProgram::setLightParameters(const LightingState& ls,
Color materialDiffuse,
Color materialSpecular,
Color materialEmissive)
Color materialEmissive
#ifdef USE_HDR
,float _nightLightScale
#endif
)
{
unsigned int nLights = min(MaxShaderLights, ls.nLights);
@ -2309,6 +2326,9 @@ CelestiaGLProgram::setLightParameters(const LightingState& ls,
ls.ambientColor.y * diffuseColor.y + materialEmissive.green(),
ls.ambientColor.z * diffuseColor.z + materialEmissive.blue());
opacity = materialDiffuse.alpha();
#ifdef USE_HDR
nightLightScale = _nightLightScale;
#endif
}

View File

@ -114,7 +114,11 @@ class CelestiaGLProgram
void setLightParameters(const LightingState& ls,
Color materialDiffuse,
Color materialSpecular,
Color materialEmissive);
Color materialEmissive
#ifdef USE_HDR
,float nightLightScale = 1.0f
#endif
);
void setEclipseShadowParameters(const LightingState& ls,
float planetRadius,
const Mat4f& planetMat);
@ -130,6 +134,9 @@ class CelestiaGLProgram
FloatShaderParameter shininess;
Vec3ShaderParameter ambientColor;
FloatShaderParameter opacity;
#ifdef USE_HDR
FloatShaderParameter nightLightScale;
#endif
FloatShaderParameter ringWidth;
FloatShaderParameter ringRadius;

View File

@ -60,6 +60,14 @@ void Simulation::render(Renderer& renderer)
selection);
}
void Simulation::draw(Renderer& renderer)
{
renderer.draw(*activeObserver,
*universe,
faintestVisible,
selection);
}
void Simulation::render(Renderer& renderer, Observer& observer)
{

View File

@ -39,6 +39,7 @@ class Simulation
void update(double dt);
void render(Renderer&);
void draw(Renderer&);
void render(Renderer&, Observer&);
Selection pickObject(Vec3f pickRay, int renderFlags, float tolerance = 0.0f);

View File

@ -150,6 +150,9 @@ static void FillinSurface(Hash* surfaceData,
surfaceData->getNumber("SpecularPower", surface->specularPower);
surfaceData->getNumber("LunarLambert", surface->lunarLambert);
#ifdef USE_HDR
surfaceData->getNumber("NightLightRadiance", surface->nightLightRadiance);
#endif
string baseTexture;
string bumpTexture;

View File

@ -28,6 +28,9 @@ class Surface
nightTexture(),
overlayTexture(),
bumpHeight(0.0f),
#ifdef USE_HDR
nightLightRadiance(1.e-5f*.5f),
#endif
lunarLambert(0.0f)
{};
@ -56,6 +59,9 @@ class Surface
MultiResTexture overlayTexture; // overlay texture, applied last
float bumpHeight; // scale of bump map relief
float lunarLambert; // mix between Lambertian and Lommel-Seeliger (lunar-like) photometric functions
#ifdef USE_HDR
float nightLightRadiance; // W sr^-1 m^-2
#endif
};
#endif // _SURFACE_H_

View File

@ -41,6 +41,12 @@ unsigned int vp::specular_2light = 0;
unsigned int vp::nightLights_2light = 0;
unsigned int vp::ellipticalGalaxy = 0;
unsigned int vp::starDisc = 0;
#ifdef HDR_COMPRESS
unsigned int vp::diffuseBumpHDR = 0;
unsigned int vp::diffuseBumpHazeHDR = 0;
unsigned int vp::nightLightsHDR = 0;
unsigned int vp::nightLights_2lightHDR = 0;
#endif
class VertexProcessorNV : public VertexProcessor
@ -279,6 +285,16 @@ VertexProcessor* vp::initARB()
return NULL;
if (!LoadARBVertexProgram("shaders/star_arb.vp", starDisc))
return NULL;
#ifdef HDR_COMPRESS
if (!LoadARBVertexProgram("shaders/bumpdiffuse_arb_hdr.vp", diffuseBumpHDR))
return NULL;
if (!LoadARBVertexProgram("shaders/bumphaze_arb_hdr.vp", diffuseBumpHazeHDR))
return NULL;
if (!LoadARBVertexProgram("shaders/night_arb_hdr.vp", nightLightsHDR))
return NULL;
if (!LoadARBVertexProgram("shaders/night2_arb_hdr.vp", nightLights_2lightHDR))
return NULL;
#endif
// Load vertex programs that are only required with fragment programs
if (ExtensionSupported("GL_NV_fragment_program") ||

View File

@ -77,6 +77,12 @@ namespace vp
extern unsigned int nightLights_2light;
extern unsigned int ellipticalGalaxy;
extern unsigned int starDisc;
#ifdef HDR_COMPRESS
extern unsigned int diffuseBumpHDR;
extern unsigned int diffuseBumpHazeHDR;
extern unsigned int nightLightsHDR;
extern unsigned int nightLights_2lightHDR;
#endif
};

View File

@ -2133,6 +2133,31 @@ void CelestiaCore::charEntered(const char *c_p, int /*modifiers*/)
// with a Lua script.
editMode = !editMode;
break;
#ifdef USE_HDR
case '|':
renderer->setBloomEnabled(!renderer->getBloomEnabled());
if (renderer->getBloomEnabled())
flash(_("Bloom enabled"));
else
flash(_("Bloom disabled"));
break;
case '<':
{
char buf[64];
renderer->decreaseBrightness();
sprintf(buf, "%s: %+3.2f", _("Exposure"), -renderer->getBrightness());
flash(buf);
}
break;
case '>':
{
char buf[64];
renderer->increaseBrightness();
sprintf(buf, "%s: %+3.2f", _("Exposure"), -renderer->getBrightness());
flash(buf);
}
break;
#endif
}
}