celestia/shaders/globular_vert.glsl

57 lines
1.9 KiB
GLSL

attribute vec3 in_Position;
attribute vec4 in_Color;
attribute float starSize;
attribute float eta;
uniform mat3 m;
uniform vec3 offset;
uniform float brightness;
uniform float pixelWeight;
uniform float RRatio;
uniform float scale;
const float RRatio_min = pow(10.0, 1.7);
const float clipDistance = 100.0; // observer distance [ly] from globular, where we
// start "morphing" the star-sprite sizes towards
// their physical values
varying vec4 color;
float relStarDensity(void)
{
/*! As alpha blending weight (relStarDensity) I take the theoretical
* number of globular stars in 2d projection at a distance
* rho = r / r_c = eta * r_t from the center (cf. King_1962's Eq.(18)),
* divided by the area = PI * rho * rho . This number density of stars
* I normalized to 1 at rho=0.
* The resulting blending weight increases strongly -> 1 if the
* 2d number density of stars rises, i.e for rho -> 0.
*/
float rRatio = max(RRatio_min, RRatio);
float Xi = 1.0 / sqrt(1.0 + rRatio * rRatio);
float XI2 = Xi * Xi;
float rho2 = 1.0001 + eta * eta * rRatio * rRatio; //add 1e-4 as regulator near rho=0
return ((log(rho2) + 4.0 * (1.0 - sqrt(rho2)) * Xi) / (rho2 - 1.0) + XI2) / (1.0 - 2.0 * Xi + XI2);
}
void main(void)
{
vec3 p = m * in_Position.xyz;
float br = 2.0 * brightness;
vec4 mod = ModelViewMatrix * vec4(in_Position, 1.0);
float s = 2000.0 / -mod.z * br * starSize * scale;
float obsDistanceToStarRatio = length(p + offset) / clipDistance;
// "Morph" the star-sprite sizes at close observer distance such that
// the overdense globular core is dissolved upon closing in.
gl_PointSize = s * min(obsDistanceToStarRatio, 1.0);
color = vec4(in_Color.rgb, min(1.0, br * (1.0 - pixelWeight * relStarDensity())));
set_vp(vec4(p, 1.0));
}