Restore sun halo

pull/863/head
Levin Li 2020-10-09 13:29:16 +08:00
parent aca0243488
commit b1d7797e54
5 changed files with 105 additions and 6 deletions

View File

@ -0,0 +1,9 @@
uniform sampler2D starTex;
uniform vec4 color;
varying vec2 texCoord;
void main(void)
{
gl_FragColor = texture2D(starTex, texCoord) * color;
}

View File

@ -0,0 +1,10 @@
attribute vec3 in_Position;
attribute vec2 in_TexCoord0;
varying vec2 texCoord;
void main(void)
{
texCoord = in_TexCoord0.st;
gl_Position = MVPMatrix * vec4(in_Position, 1.0);
}

View File

@ -14,6 +14,7 @@ bool EXT_framebuffer_object = false;
bool ARB_shader_texture_lod = false;
bool EXT_texture_compression_s3tc = false;
bool EXT_texture_filter_anisotropic = false;
GLint maxPointSize = 0;
namespace
{
@ -35,6 +36,14 @@ bool init() noexcept
EXT_texture_compression_s3tc = has_extension("GL_EXT_texture_compression_s3tc");
EXT_texture_filter_anisotropic = has_extension("GL_EXT_texture_filter_anisotropic");
GLint pointSizeRange[2];
#ifdef GL_ES
glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);
#else
glGetIntegerv(GL_SMOOTH_POINT_SIZE_RANGE, pointSizeRange);
#endif
maxPointSize = pointSizeRange[1];
return true;
}

View File

@ -42,6 +42,7 @@ extern bool OES_vertex_array_object;
extern bool ARB_vertex_array_object;
extern bool EXT_framebuffer_object;
#endif
extern GLint maxPointSize;
bool init() noexcept;
bool checkVersion(int) noexcept;

View File

@ -1827,6 +1827,54 @@ void renderPoint(const Renderer &renderer,
#endif
}
void renderLargePoint(const Renderer &renderer,
const Vector3f &position,
const Color &color,
float size,
float pixelSize,
const Matrix3f &cameraOrientation,
const Matrices &mvp)
{
auto *prog = renderer.getShaderManager().getShader("largestar");
if (prog == nullptr)
return;
prog->use();
prog->samplerParam("starTex") = 0;
prog->setMVPMatrices(*mvp.projection, *mvp.modelview);
prog->vec4Param("color") = color.toVector4();
float distanceAdjust = pixelSize * position.norm() * 0.5f;
size *= distanceAdjust;
auto m = renderer.getCameraOrientation().conjugate().toRotationMatrix();
Vector3f v0 = position + (cameraOrientation * Vector3f(-1, -1, 0) * size);
Vector3f v1 = position + (cameraOrientation * Vector3f( 1, -1, 0) * size);
Vector3f v2 = position + (cameraOrientation * Vector3f( 1, 1, 0) * size);
Vector3f v3 = position + (cameraOrientation * Vector3f(-1, 1, 0) * size);
float quadVertices[] = {
// positions // texCoords
v0.x(), v0.y(), v0.z(), 0.0f, 0.0f,
v1.x(), v1.y(), v1.z(), 1.0f, 0.0f,
v2.x(), v2.y(), v2.z(), 1.0f, 1.0f,
v3.x(), v3.y(), v3.z(), 0.0f, 1.0f
};
static GLubyte indices[] = { 0, 1, 2, 0, 2, 3 };
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), quadVertices);
glVertexAttribPointer(CelestiaGLProgram::TextureCoord0AttributeIndex,
2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), quadVertices + 3);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
}
// If the an object occupies a pixel or less of screen space, we don't
// render its mesh at all and just display a starlike point instead.
// Switching between the particle and mesh renderings of an object is
@ -1834,14 +1882,14 @@ void renderPoint(const Renderer &renderer,
// object to smooth things out, making it dimmer as the disc size exceeds the
// max disc size.
void Renderer::renderObjectAsPoint(const Vector3f& position,
float /*radius*/,
float radius,
float appMag,
float _faintestMag,
float discSizeInPixels,
const Color &color,
bool useHalos,
bool emissive,
const Matrices &m)
const Matrices &mvp)
{
const float maxSize = MaxScaledDiscStarSize;
float maxDiscSize = (starStyle == ScaledDiscStars) ? maxSize : 1.0f;
@ -1900,22 +1948,35 @@ void Renderer::renderObjectAsPoint(const Vector3f& position,
glareAlpha = min(GlareOpacity, (discScale - 2.0f) / 4.0f);
glareSize = pointSize * discScale * 2.0f ;
if (emissive)
glareSize = max(glareSize, pointSize * discSizeInPixels * 3.0f);
glareSize = max(glareSize, pointSize * discSizeInPixels / (screenDpi / 96.0f) * 3.0f);
}
}
alpha *= fade;
if (!emissive)
{
glareSize = max(glareSize, pointSize * discSizeInPixels * 3.0f);
glareSize = max(glareSize, pointSize * discSizeInPixels / (screenDpi / 96.0f) * 3.0f);
glareAlpha *= fade;
}
Matrix3f m = m_cameraOrientation.conjugate().toRotationMatrix();
Vector3f center = position;
// Offset the glare sprite so that it lies in front of the object
Vector3f direction = center.normalized();
// Position the sprite on the the line between the viewer and the
// object, and on a plane normal to the view direction.
center = center + direction * (radius / (m * Vector3f::UnitZ()).dot(direction));
enableDepthTest();
bool useSprites = starStyle != PointStars;
if (useSprites)
gaussianDiscTex->bind();
renderPoint(*this, position, {color, alpha}, pointSize, useSprites, m);
if (pointSize > gl::maxPointSize)
renderLargePoint(*this, center, {color, alpha}, pointSize, pixelSize, m, mvp);
else
renderPoint(*this, center, {color, alpha}, pointSize, useSprites, mvp);
// If the object is brighter than magnitude 1, add a halo around it to
// make it appear more brilliant. This is a hack to compensate for the
@ -1926,7 +1987,10 @@ void Renderer::renderObjectAsPoint(const Vector3f& position,
if (useHalos && glareAlpha > 0.0f)
{
gaussianGlareTex->bind();
renderPoint(*this, position, {color, glareAlpha}, glareSize, true, m);
if (glareSize > gl::maxPointSize)
renderLargePoint(*this, center, {color, glareAlpha}, glareSize, pixelSize, m, mvp);
else
renderPoint(*this, center, {color, glareAlpha}, glareSize, true, mvp);
}
}
}
@ -5443,12 +5507,18 @@ bool Renderer::getInfo(map<string, string>& info) const
GLint maxTextureUnits = 1;
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTextureUnits);
info["MaxTextureUnits"] = to_string(maxTextureUnits);
#endif
GLint pointSizeRange[2];
#ifdef GL_ES
glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);
#else
glGetIntegerv(GL_SMOOTH_POINT_SIZE_RANGE, pointSizeRange);
#endif
info["PointSizeMin"] = to_string(pointSizeRange[0]);
info["PointSizeMax"] = to_string(pointSizeRange[1]);
#ifndef GL_ES
GLfloat pointSizeGran = 0;
glGetFloatv(GL_SMOOTH_POINT_SIZE_GRANULARITY, &pointSizeGran);
info["PointSizeGran"] = fmt::sprintf("%.2f", pointSizeGran);