significant work on procedural sky
This commit is contained in:
parent
6ff828a167
commit
bc2d9eefab
@ -17,10 +17,20 @@ uniform vec3 zenithColor;
|
|||||||
uniform vec3 sunDirection;
|
uniform vec3 sunDirection;
|
||||||
uniform vec3 sunColor;
|
uniform vec3 sunColor;
|
||||||
uniform float sunIntensity;
|
uniform float sunIntensity;
|
||||||
|
uniform vec3 moonDirection;
|
||||||
|
uniform vec3 moonColor;
|
||||||
|
uniform float moonIntensity;
|
||||||
|
uniform float moonPhase;
|
||||||
|
uniform float starsIntensity;
|
||||||
|
|
||||||
// Output fragment color
|
// Output fragment color
|
||||||
out vec4 finalColor;
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
// Simple hash function for stars
|
||||||
|
float hash(vec2 p) {
|
||||||
|
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Normalize the world position to get direction from center
|
// Normalize the world position to get direction from center
|
||||||
@ -32,18 +42,46 @@ void main()
|
|||||||
// Interpolate between horizon and zenith colors
|
// Interpolate between horizon and zenith colors
|
||||||
vec3 skyColor = mix(horizonColor, zenithColor, gradientFactor);
|
vec3 skyColor = mix(horizonColor, zenithColor, gradientFactor);
|
||||||
|
|
||||||
|
// Add stars (only visible at night)
|
||||||
|
if (starsIntensity > 0.01 && direction.y > -0.1) { // Don't render stars below horizon
|
||||||
|
// Create a simple star field using noise
|
||||||
|
vec2 starCoord = direction.xz * 30.0; // Less dense grid
|
||||||
|
|
||||||
|
// Two layers of stars for depth (reduced from 3)
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
vec2 gridPos = floor(starCoord * (1.0 + float(i) * 0.3));
|
||||||
|
vec2 gridFract = fract(starCoord * (1.0 + float(i) * 0.3));
|
||||||
|
|
||||||
|
float starRandom = hash(gridPos + vec2(float(i) * 13.0, float(i) * 17.0));
|
||||||
|
|
||||||
|
// Much fewer stars (higher threshold)
|
||||||
|
if (starRandom > 0.985 + float(i) * 0.005) {
|
||||||
|
float starBrightness = hash(gridPos + vec2(37.0, 73.0));
|
||||||
|
|
||||||
|
// Circular star points
|
||||||
|
vec2 starCenter = vec2(0.5);
|
||||||
|
float dist = length(gridFract - starCenter);
|
||||||
|
|
||||||
|
if (dist < 0.05) { // Slightly larger star points
|
||||||
|
float starAlpha = pow(1.0 - dist / 0.05, 1.5) * starsIntensity;
|
||||||
|
starAlpha *= (0.4 + starBrightness * 0.6); // Vary brightness
|
||||||
|
skyColor = mix(skyColor, vec3(0.95, 0.95, 1.0), starAlpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 color = skyColor;
|
||||||
|
|
||||||
// Calculate sun contribution
|
// Calculate sun contribution
|
||||||
vec3 sunDir = normalize(sunDirection);
|
vec3 sunDir = normalize(sunDirection);
|
||||||
float sunDot = dot(direction, sunDir);
|
float sunDot = dot(direction, sunDir);
|
||||||
|
|
||||||
// Sun rendering
|
|
||||||
vec3 color = skyColor;
|
|
||||||
|
|
||||||
// Only render sun if it's above horizon and has intensity
|
// Only render sun if it's above horizon and has intensity
|
||||||
if (sunDir.y > 0.0 && sunIntensity > 0.1) {
|
if (sunDir.y > 0.0 && sunIntensity > 0.1) {
|
||||||
// Sun disc with soft edges
|
// Sun disc with soft edges - much smaller
|
||||||
float sunSize = 0.99; // Smaller value = larger sun
|
float sunSize = 0.9985; // Much smaller sun (closer to 1.0 = smaller)
|
||||||
float sunEdge = 0.98;
|
float sunEdge = 0.997;
|
||||||
|
|
||||||
if (sunDot > sunSize) {
|
if (sunDot > sunSize) {
|
||||||
// Bright sun core
|
// Bright sun core
|
||||||
@ -51,13 +89,39 @@ void main()
|
|||||||
} else if (sunDot > sunEdge) {
|
} else if (sunDot > sunEdge) {
|
||||||
// Soft edge
|
// Soft edge
|
||||||
float edge = smoothstep(sunEdge, sunSize, sunDot);
|
float edge = smoothstep(sunEdge, sunSize, sunDot);
|
||||||
color = mix(skyColor, sunColor, edge);
|
color = mix(color, sunColor, edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sun glow
|
// Sun glow - tighter radius
|
||||||
if (sunDot > 0.85) {
|
if (sunDot > 0.94) {
|
||||||
float glow = pow(max(0.0, (sunDot - 0.85) / 0.15), 2.0) * sunIntensity;
|
float glow = pow(max(0.0, (sunDot - 0.94) / 0.06), 2.0) * sunIntensity;
|
||||||
color = mix(color, sunColor, glow * 0.5);
|
color = mix(color, sunColor, glow * 0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate moon contribution
|
||||||
|
vec3 moonDir = normalize(moonDirection);
|
||||||
|
float moonDot = dot(direction, moonDir);
|
||||||
|
|
||||||
|
// Only render moon if it's above horizon
|
||||||
|
if (moonDir.y > 0.0 && moonIntensity > 0.1) {
|
||||||
|
// Moon disc - 15% smaller than before
|
||||||
|
float moonSize = 0.9992; // Much smaller than sun (sun is 0.9985)
|
||||||
|
float moonEdge = 0.999;
|
||||||
|
|
||||||
|
if (moonDot > moonSize) {
|
||||||
|
// Simple moon disc (simplified for smaller size)
|
||||||
|
color = mix(color, moonColor, moonIntensity);
|
||||||
|
} else if (moonDot > moonEdge) {
|
||||||
|
// Soft moon edge
|
||||||
|
float edge = smoothstep(moonEdge, moonSize, moonDot);
|
||||||
|
color = mix(color, moonColor * 0.8, edge * moonIntensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtle moon glow - even tighter for smaller moon
|
||||||
|
if (moonDot > 0.98) {
|
||||||
|
float glow = pow(max(0.0, (moonDot - 0.98) / 0.02), 2.0) * moonIntensity;
|
||||||
|
color = mix(color, moonColor, glow * 0.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,10 @@ Sky::Sky()
|
|||||||
sun.intensity = 1.0f;
|
sun.intensity = 1.0f;
|
||||||
sun.angle = 0.0f;
|
sun.angle = 0.0f;
|
||||||
|
|
||||||
|
moon.intensity = 1.0f;
|
||||||
|
moon.phase = 0.5f; // Start with full moon
|
||||||
|
moon.color = {230, 230, 255, 255}; // Pale blue-white
|
||||||
|
|
||||||
createSkyDome();
|
createSkyDome();
|
||||||
updateColors();
|
updateColors();
|
||||||
|
|
||||||
@ -28,6 +32,11 @@ Sky::Sky()
|
|||||||
sunDirectionLoc = GetShaderLocation(skyShader, "sunDirection");
|
sunDirectionLoc = GetShaderLocation(skyShader, "sunDirection");
|
||||||
sunColorLoc = GetShaderLocation(skyShader, "sunColor");
|
sunColorLoc = GetShaderLocation(skyShader, "sunColor");
|
||||||
sunIntensityLoc = GetShaderLocation(skyShader, "sunIntensity");
|
sunIntensityLoc = GetShaderLocation(skyShader, "sunIntensity");
|
||||||
|
moonDirectionLoc = GetShaderLocation(skyShader, "moonDirection");
|
||||||
|
moonColorLoc = GetShaderLocation(skyShader, "moonColor");
|
||||||
|
moonIntensityLoc = GetShaderLocation(skyShader, "moonIntensity");
|
||||||
|
moonPhaseLoc = GetShaderLocation(skyShader, "moonPhase");
|
||||||
|
starsIntensityLoc = GetShaderLocation(skyShader, "starsIntensity");
|
||||||
|
|
||||||
// Assign shader to sky model
|
// Assign shader to sky model
|
||||||
skyModel.materials[0].shader = skyShader;
|
skyModel.materials[0].shader = skyShader;
|
||||||
@ -62,6 +71,7 @@ void Sky::update(float) {
|
|||||||
|
|
||||||
updateColors();
|
updateColors();
|
||||||
sun.updatePosition(timeOfDay);
|
sun.updatePosition(timeOfDay);
|
||||||
|
moon.updatePosition(timeOfDay);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sky::Sun::updatePosition(float timeOfDay) {
|
void Sky::Sun::updatePosition(float timeOfDay) {
|
||||||
@ -90,6 +100,40 @@ void Sky::Sun::updatePosition(float timeOfDay) {
|
|||||||
direction = Vector3Normalize(Vector3Scale(position, -1.0f));
|
direction = Vector3Normalize(Vector3Scale(position, -1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sky::Moon::updatePosition(float timeOfDay) {
|
||||||
|
// Moon follows opposite schedule to sun
|
||||||
|
// Visible from 6 PM (0.75) to 6 AM (0.25)
|
||||||
|
// At midnight (0.0), moon is overhead
|
||||||
|
|
||||||
|
float adjustedTime = timeOfDay + 0.25f; // Shift so moon is overhead at midnight
|
||||||
|
if (adjustedTime > 1.0f) adjustedTime -= 1.0f;
|
||||||
|
|
||||||
|
// Only show moon during nighttime (6pm to 6am)
|
||||||
|
if (timeOfDay < 0.25f || timeOfDay > 0.75f) {
|
||||||
|
float nightProgress;
|
||||||
|
if (timeOfDay > 0.75f) {
|
||||||
|
nightProgress = (timeOfDay - 0.75f) / 0.5f; // 0 to 0.5 for evening
|
||||||
|
} else {
|
||||||
|
nightProgress = (timeOfDay + 0.25f) / 0.5f; // 0.5 to 1 for morning
|
||||||
|
}
|
||||||
|
|
||||||
|
float angle = nightProgress * PI; // 0 to PI (moonrise to moonset)
|
||||||
|
|
||||||
|
// Calculate moon position in an arc (same as sun but at night)
|
||||||
|
float moonX = cosf(angle) * 150.0f; // East to West
|
||||||
|
float moonY = sinf(angle) * 100.0f + 20.0f; // Height arc, minimum 20 units up
|
||||||
|
float moonZ = 0.0f;
|
||||||
|
|
||||||
|
position = {moonX, moonY, moonZ};
|
||||||
|
} else {
|
||||||
|
// Moon is below horizon during day
|
||||||
|
position = {0.0f, -100.0f, 0.0f};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Direction is from moon to origin
|
||||||
|
direction = Vector3Normalize(Vector3Scale(position, -1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
void Sky::updateColors() {
|
void Sky::updateColors() {
|
||||||
float t = timeOfDay;
|
float t = timeOfDay;
|
||||||
|
|
||||||
@ -185,8 +229,9 @@ void Sky::renderSkybox(const Camera3D& camera) {
|
|||||||
rlTranslatef(camera.position.x, camera.position.y, camera.position.z);
|
rlTranslatef(camera.position.x, camera.position.y, camera.position.z);
|
||||||
|
|
||||||
if (shaderLoaded) {
|
if (shaderLoaded) {
|
||||||
// First make sure sun position is updated
|
// First make sure sun and moon positions are updated
|
||||||
sun.updatePosition(timeOfDay);
|
sun.updatePosition(timeOfDay);
|
||||||
|
moon.updatePosition(timeOfDay);
|
||||||
|
|
||||||
// Update shader uniforms
|
// Update shader uniforms
|
||||||
Vector3 horizonColorVec = {
|
Vector3 horizonColorVec = {
|
||||||
@ -204,6 +249,11 @@ void Sky::renderSkybox(const Camera3D& camera) {
|
|||||||
sun.color.g / 255.0f,
|
sun.color.g / 255.0f,
|
||||||
sun.color.b / 255.0f
|
sun.color.b / 255.0f
|
||||||
};
|
};
|
||||||
|
Vector3 moonColorVec = {
|
||||||
|
moon.color.r / 255.0f,
|
||||||
|
moon.color.g / 255.0f,
|
||||||
|
moon.color.b / 255.0f
|
||||||
|
};
|
||||||
|
|
||||||
// Normalize sun direction (make sure it's valid)
|
// Normalize sun direction (make sure it's valid)
|
||||||
Vector3 sunDir = {0, 1, 0}; // Default up if sun position is invalid
|
Vector3 sunDir = {0, 1, 0}; // Default up if sun position is invalid
|
||||||
@ -211,6 +261,22 @@ void Sky::renderSkybox(const Camera3D& camera) {
|
|||||||
sunDir = Vector3Normalize(sun.position);
|
sunDir = Vector3Normalize(sun.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Normalize moon direction
|
||||||
|
Vector3 moonDir = {0, -1, 0}; // Default down if moon position is invalid
|
||||||
|
if (Vector3Length(moon.position) > 0.001f) {
|
||||||
|
moonDir = Vector3Normalize(moon.position);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate stars intensity based on time of day (visible at night)
|
||||||
|
float starsIntensity = 0.0f;
|
||||||
|
if (timeOfDay < 0.2f || timeOfDay > 0.8f) {
|
||||||
|
// Full intensity at midnight
|
||||||
|
if (timeOfDay > 0.5f) {
|
||||||
|
starsIntensity = (timeOfDay - 0.8f) / 0.2f;
|
||||||
|
} else {
|
||||||
|
starsIntensity = 1.0f - (timeOfDay / 0.2f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set shader uniforms
|
// Set shader uniforms
|
||||||
SetShaderValue(skyShader, horizonColorLoc, &horizonColorVec, SHADER_UNIFORM_VEC3);
|
SetShaderValue(skyShader, horizonColorLoc, &horizonColorVec, SHADER_UNIFORM_VEC3);
|
||||||
@ -218,6 +284,11 @@ void Sky::renderSkybox(const Camera3D& camera) {
|
|||||||
SetShaderValue(skyShader, sunDirectionLoc, &sunDir, SHADER_UNIFORM_VEC3);
|
SetShaderValue(skyShader, sunDirectionLoc, &sunDir, SHADER_UNIFORM_VEC3);
|
||||||
SetShaderValue(skyShader, sunColorLoc, &sunColorVec, SHADER_UNIFORM_VEC3);
|
SetShaderValue(skyShader, sunColorLoc, &sunColorVec, SHADER_UNIFORM_VEC3);
|
||||||
SetShaderValue(skyShader, sunIntensityLoc, &sun.intensity, SHADER_UNIFORM_FLOAT);
|
SetShaderValue(skyShader, sunIntensityLoc, &sun.intensity, SHADER_UNIFORM_FLOAT);
|
||||||
|
SetShaderValue(skyShader, moonDirectionLoc, &moonDir, SHADER_UNIFORM_VEC3);
|
||||||
|
SetShaderValue(skyShader, moonColorLoc, &moonColorVec, SHADER_UNIFORM_VEC3);
|
||||||
|
SetShaderValue(skyShader, moonIntensityLoc, &moon.intensity, SHADER_UNIFORM_FLOAT);
|
||||||
|
SetShaderValue(skyShader, moonPhaseLoc, &moon.phase, SHADER_UNIFORM_FLOAT);
|
||||||
|
SetShaderValue(skyShader, starsIntensityLoc, &starsIntensity, SHADER_UNIFORM_FLOAT);
|
||||||
|
|
||||||
// Draw the sky dome with shader
|
// Draw the sky dome with shader
|
||||||
DrawModel(skyModel, {0, 0, 0}, 1.0f, WHITE);
|
DrawModel(skyModel, {0, 0, 0}, 1.0f, WHITE);
|
||||||
|
|||||||
@ -16,7 +16,18 @@ private:
|
|||||||
Vector3 getLightDirection() const { return direction; }
|
Vector3 getLightDirection() const { return direction; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Moon {
|
||||||
|
Vector3 position;
|
||||||
|
Vector3 direction;
|
||||||
|
Color color;
|
||||||
|
float intensity;
|
||||||
|
float phase; // 0 = new moon, 0.5 = full moon, 1 = new moon
|
||||||
|
|
||||||
|
void updatePosition(float timeOfDay);
|
||||||
|
};
|
||||||
|
|
||||||
Sun sun;
|
Sun sun;
|
||||||
|
Moon moon;
|
||||||
Color horizonColor;
|
Color horizonColor;
|
||||||
Color zenithColor;
|
Color zenithColor;
|
||||||
Color fogColor;
|
Color fogColor;
|
||||||
@ -34,6 +45,11 @@ private:
|
|||||||
int sunDirectionLoc;
|
int sunDirectionLoc;
|
||||||
int sunColorLoc;
|
int sunColorLoc;
|
||||||
int sunIntensityLoc;
|
int sunIntensityLoc;
|
||||||
|
int moonDirectionLoc;
|
||||||
|
int moonColorLoc;
|
||||||
|
int moonIntensityLoc;
|
||||||
|
int moonPhaseLoc;
|
||||||
|
int starsIntensityLoc;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Sky();
|
Sky();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user