mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-03 00:03:50 +00:00
Refine sun rendering: remove white washout, add subtle atmospheric turbulence
- render sun with alpha blend while keeping moon additive glow - add dedicated always-running sun haze timer (decoupled from moon phase cycling) - constrain sun sprite with radial alpha mask and low-alpha discard to remove square artifact - tune sun tint warmer without over-yellowing - replace noisy/pulsing haze with slower flow-warp turbulence and lower amplitude
This commit is contained in:
parent
19759d506a
commit
566e7138f3
2 changed files with 61 additions and 9 deletions
|
|
@ -129,6 +129,7 @@ private:
|
||||||
float blueChildPhase_ = 0.25f; // 0.0-1.0 (0=new, 0.5=full) - secondary moon
|
float blueChildPhase_ = 0.25f; // 0.0-1.0 (0=new, 0.5=full) - secondary moon
|
||||||
bool moonPhaseCycling = true;
|
bool moonPhaseCycling = true;
|
||||||
float moonPhaseTimer = 0.0f; // Fallback for deltaTime mode (development)
|
float moonPhaseTimer = 0.0f; // Fallback for deltaTime mode (development)
|
||||||
|
float sunHazeTimer_ = 0.0f; // Always-running timer for sun haze animation
|
||||||
bool dualMoonMode_ = true; // Default: render both moons (Azeroth-specific)
|
bool dualMoonMode_ = true; // Default: render both moons (Azeroth-specific)
|
||||||
|
|
||||||
// WoW lunar cycle constants (in game days)
|
// WoW lunar cycle constants (in game days)
|
||||||
|
|
|
||||||
|
|
@ -51,21 +51,56 @@ bool Celestial::initialize() {
|
||||||
uniform vec3 celestialColor;
|
uniform vec3 celestialColor;
|
||||||
uniform float intensity;
|
uniform float intensity;
|
||||||
uniform float moonPhase; // 0.0 = new moon, 0.5 = full moon, 1.0 = new moon
|
uniform float moonPhase; // 0.0 = new moon, 0.5 = full moon, 1.0 = new moon
|
||||||
|
uniform float uAnimTime;
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
float hash(vec2 p) {
|
||||||
|
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
||||||
|
}
|
||||||
|
|
||||||
|
float noise(vec2 p) {
|
||||||
|
vec2 i = floor(p);
|
||||||
|
vec2 f = fract(p);
|
||||||
|
f = f * f * (3.0 - 2.0 * f);
|
||||||
|
float a = hash(i + vec2(0.0, 0.0));
|
||||||
|
float b = hash(i + vec2(1.0, 0.0));
|
||||||
|
float c = hash(i + vec2(0.0, 1.0));
|
||||||
|
float d = hash(i + vec2(1.0, 1.0));
|
||||||
|
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Create circular disc
|
// Create circular disc
|
||||||
vec2 center = vec2(0.5, 0.5);
|
vec2 center = vec2(0.5, 0.5);
|
||||||
float dist = distance(TexCoord, center);
|
float dist = distance(TexCoord, center);
|
||||||
|
|
||||||
// Core disc
|
// Core disc + glow with explicit radial mask to avoid square billboard artifact.
|
||||||
float disc = smoothstep(0.5, 0.4, dist);
|
float disc = smoothstep(0.50, 0.38, dist);
|
||||||
|
float glow = smoothstep(0.64, 0.00, dist) * 0.24;
|
||||||
|
float radialMask = 1.0 - smoothstep(0.58, 0.70, dist);
|
||||||
|
|
||||||
// Glow around disc
|
float alpha = (disc + glow) * radialMask * intensity;
|
||||||
float glow = smoothstep(0.7, 0.0, dist) * 0.3;
|
vec3 outColor = celestialColor;
|
||||||
|
|
||||||
float alpha = (disc + glow) * intensity;
|
// Very faint animated haze over sun disc/glow (no effect for moon).
|
||||||
|
if (intensity > 0.5) {
|
||||||
|
vec2 uv = (TexCoord - vec2(0.5)) * 3.0;
|
||||||
|
// Slow flow field for atmospheric-like turbulence drift.
|
||||||
|
vec2 flow = vec2(
|
||||||
|
noise(uv * 0.9 + vec2(uAnimTime * 0.012, -uAnimTime * 0.009)),
|
||||||
|
noise(uv * 0.9 + vec2(-uAnimTime * 0.010, uAnimTime * 0.011))
|
||||||
|
) - vec2(0.5);
|
||||||
|
vec2 warped = uv + flow * 0.42;
|
||||||
|
float n1 = noise(warped * 1.7 + vec2(uAnimTime * 0.016, -uAnimTime * 0.013));
|
||||||
|
float n2 = noise(warped * 3.0 + vec2(-uAnimTime * 0.021, uAnimTime * 0.017));
|
||||||
|
float haze = mix(n1, n2, 0.35);
|
||||||
|
float hazeMask = clamp(disc * 0.75 + glow * 0.28, 0.0, 1.0);
|
||||||
|
float hazeMix = hazeMask * 0.55;
|
||||||
|
float lumaMod = mix(1.0, 0.93 + haze * 0.10, hazeMix);
|
||||||
|
outColor *= lumaMod;
|
||||||
|
alpha *= mix(1.0, 0.94 + haze * 0.06, hazeMix);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply moon phase shadow (only for moon, indicated by low intensity)
|
// Apply moon phase shadow (only for moon, indicated by low intensity)
|
||||||
if (intensity < 0.5) { // Moon has lower intensity than sun
|
if (intensity < 0.5) { // Moon has lower intensity than sun
|
||||||
|
|
@ -88,7 +123,7 @@ bool Celestial::initialize() {
|
||||||
|
|
||||||
// Apply elliptical terminator for 3D effect
|
// Apply elliptical terminator for 3D effect
|
||||||
float y = (TexCoord.y - 0.5) * 2.0;
|
float y = (TexCoord.y - 0.5) * 2.0;
|
||||||
float ellipse = sqrt(1.0 - y * y);
|
float ellipse = sqrt(max(0.0, 1.0 - y * y));
|
||||||
float terminatorX = phasePos / ellipse;
|
float terminatorX = phasePos / ellipse;
|
||||||
|
|
||||||
if (moonPhase < 0.5) {
|
if (moonPhase < 0.5) {
|
||||||
|
|
@ -101,7 +136,11 @@ bool Celestial::initialize() {
|
||||||
alpha *= mix(0.05, 1.0, shadow);
|
alpha *= mix(0.05, 1.0, shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
FragColor = vec4(celestialColor, alpha);
|
if (alpha < 0.01) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
FragColor = vec4(outColor, alpha);
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
|
@ -144,8 +183,12 @@ void Celestial::render(const Camera& camera, float timeOfDay,
|
||||||
// Disable culling - billboards can face either way
|
// Disable culling - billboards can face either way
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
// Render sun and moons (pass lighting parameters)
|
// Render sun with alpha blending (avoids additive white clipping).
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
renderSun(camera, timeOfDay, sunDir, sunColor);
|
renderSun(camera, timeOfDay, sunDir, sunColor);
|
||||||
|
|
||||||
|
// Render moons additively for glow.
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||||
renderMoon(camera, timeOfDay); // White Lady (primary moon)
|
renderMoon(camera, timeOfDay); // White Lady (primary moon)
|
||||||
|
|
||||||
if (dualMoonMode_) {
|
if (dualMoonMode_) {
|
||||||
|
|
@ -189,11 +232,15 @@ void Celestial::renderSun(const Camera& camera, float timeOfDay,
|
||||||
|
|
||||||
// Sun color and intensity (use lighting color if provided)
|
// Sun color and intensity (use lighting color if provided)
|
||||||
glm::vec3 color = sunColor ? *sunColor : getSunColor(timeOfDay);
|
glm::vec3 color = sunColor ? *sunColor : getSunColor(timeOfDay);
|
||||||
float intensity = getSunIntensity(timeOfDay);
|
// Force strong warm/yellow tint; avoid white blowout.
|
||||||
|
const glm::vec3 warmSun(1.0f, 0.88f, 0.55f);
|
||||||
|
color = glm::mix(color, warmSun, 0.52f);
|
||||||
|
float intensity = getSunIntensity(timeOfDay) * 0.92f;
|
||||||
|
|
||||||
celestialShader->setUniform("celestialColor", color);
|
celestialShader->setUniform("celestialColor", color);
|
||||||
celestialShader->setUniform("intensity", intensity);
|
celestialShader->setUniform("intensity", intensity);
|
||||||
celestialShader->setUniform("moonPhase", 0.5f); // Sun doesn't use this, but shader expects it
|
celestialShader->setUniform("moonPhase", 0.5f); // Sun doesn't use this, but shader expects it
|
||||||
|
celestialShader->setUniform("uAnimTime", sunHazeTimer_);
|
||||||
|
|
||||||
// Render quad
|
// Render quad
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
|
|
@ -242,6 +289,7 @@ void Celestial::renderMoon(const Camera& camera, float timeOfDay) {
|
||||||
celestialShader->setUniform("celestialColor", color);
|
celestialShader->setUniform("celestialColor", color);
|
||||||
celestialShader->setUniform("intensity", intensity);
|
celestialShader->setUniform("intensity", intensity);
|
||||||
celestialShader->setUniform("moonPhase", whiteLadyPhase_);
|
celestialShader->setUniform("moonPhase", whiteLadyPhase_);
|
||||||
|
celestialShader->setUniform("uAnimTime", sunHazeTimer_);
|
||||||
|
|
||||||
// Render quad
|
// Render quad
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
|
|
@ -296,6 +344,7 @@ void Celestial::renderBlueChild(const Camera& camera, float timeOfDay) {
|
||||||
celestialShader->setUniform("celestialColor", color);
|
celestialShader->setUniform("celestialColor", color);
|
||||||
celestialShader->setUniform("intensity", intensity);
|
celestialShader->setUniform("intensity", intensity);
|
||||||
celestialShader->setUniform("moonPhase", blueChildPhase_);
|
celestialShader->setUniform("moonPhase", blueChildPhase_);
|
||||||
|
celestialShader->setUniform("uAnimTime", sunHazeTimer_);
|
||||||
|
|
||||||
// Render quad
|
// Render quad
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
|
|
@ -465,6 +514,8 @@ void Celestial::destroyCelestialQuad() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Celestial::update(float deltaTime) {
|
void Celestial::update(float deltaTime) {
|
||||||
|
sunHazeTimer_ += deltaTime;
|
||||||
|
|
||||||
if (!moonPhaseCycling) {
|
if (!moonPhaseCycling) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue