1
0

yay procedural sky!

This commit is contained in:
Sky Johnson 2025-09-09 14:29:46 -05:00
parent 9d60dddcc2
commit 6ff828a167
5 changed files with 193 additions and 53 deletions

View File

@ -133,7 +133,7 @@ class Game {
public:
Game() {
InitWindow(1280, 720, "Multiplayer Terrain Game");
InitWindow(1280, 720, "Game");
SetTargetFPS(60);
// Initialize sky after window is created

65
client/shaders/sky.fs Normal file
View File

@ -0,0 +1,65 @@
#version 330
// Input vertex attributes (from vertex shader)
in vec3 fragPosition;
in vec2 fragTexCoord;
in vec4 fragColor;
in vec3 fragNormal;
in vec3 worldPos;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
// Custom uniforms for sky
uniform vec3 horizonColor;
uniform vec3 zenithColor;
uniform vec3 sunDirection;
uniform vec3 sunColor;
uniform float sunIntensity;
// Output fragment color
out vec4 finalColor;
void main()
{
// Normalize the world position to get direction from center
vec3 direction = normalize(worldPos);
// Calculate gradient based on Y component (height)
float gradientFactor = smoothstep(-0.5, 1.0, direction.y);
// Interpolate between horizon and zenith colors
vec3 skyColor = mix(horizonColor, zenithColor, gradientFactor);
// Calculate sun contribution
vec3 sunDir = normalize(sunDirection);
float sunDot = dot(direction, sunDir);
// Sun rendering
vec3 color = skyColor;
// Only render sun if it's above horizon and has intensity
if (sunDir.y > 0.0 && sunIntensity > 0.1) {
// Sun disc with soft edges
float sunSize = 0.99; // Smaller value = larger sun
float sunEdge = 0.98;
if (sunDot > sunSize) {
// Bright sun core
color = mix(sunColor, vec3(1.0, 1.0, 0.95), 0.8);
} else if (sunDot > sunEdge) {
// Soft edge
float edge = smoothstep(sunEdge, sunSize, sunDot);
color = mix(skyColor, sunColor, edge);
}
// Sun glow
if (sunDot > 0.85) {
float glow = pow(max(0.0, (sunDot - 0.85) / 0.15), 2.0) * sunIntensity;
color = mix(color, sunColor, glow * 0.5);
}
}
finalColor = vec4(color, 1.0);
}

34
client/shaders/sky.vs Normal file
View File

@ -0,0 +1,34 @@
#version 330
// Input vertex attributes
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec3 vertexNormal;
in vec4 vertexColor;
// Input uniform values
uniform mat4 mvp;
uniform mat4 matModel;
uniform mat4 matNormal;
// Output vertex attributes (to fragment shader)
out vec3 fragPosition;
out vec2 fragTexCoord;
out vec4 fragColor;
out vec3 fragNormal;
out vec3 worldPos;
void main()
{
// Send vertex attributes to fragment shader
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 0.0)));
// Store world position for sky calculations
worldPos = vertexPosition;
// Calculate final vertex position
gl_Position = mvp * vec4(vertexPosition, 1.0);
}

View File

@ -2,6 +2,7 @@
#include <rlgl.h>
#include <cmath>
#include <algorithm>
#include <iostream>
Sky::Sky()
: fogDensity(0.01f)
@ -14,8 +15,28 @@ Sky::Sky()
createSkyDome();
updateColors();
// Try to load a custom shader if available
// For now we'll use basic rendering
// Try to load the sky shader
const char* vsPath = "shaders/sky.vs";
const char* fsPath = "shaders/sky.fs";
if (FileExists(vsPath) && FileExists(fsPath)) {
skyShader = LoadShader(vsPath, fsPath);
// Get shader uniform locations
horizonColorLoc = GetShaderLocation(skyShader, "horizonColor");
zenithColorLoc = GetShaderLocation(skyShader, "zenithColor");
sunDirectionLoc = GetShaderLocation(skyShader, "sunDirection");
sunColorLoc = GetShaderLocation(skyShader, "sunColor");
sunIntensityLoc = GetShaderLocation(skyShader, "sunIntensity");
// Assign shader to sky model
skyModel.materials[0].shader = skyShader;
shaderLoaded = true;
std::cout << "Sky shader loaded successfully\n";
} else {
std::cout << "Sky shader files not found, using fallback rendering\n";
}
}
Sky::~Sky() {
@ -26,17 +47,11 @@ Sky::~Sky() {
}
void Sky::createSkyDome() {
// Create a large inverted sphere for the sky dome
// The sphere is inverted so we see the inside surface
skyDome = GenMeshSphere(1000.0f, 32, 32);
// Create a large sphere for the sky dome
skyDome = GenMeshSphere(500.0f, 16, 16);
// Invert the mesh normals to render the inside
for (int i = 0; i < skyDome.vertexCount * 3; i++) {
skyDome.normals[i] *= -1.0f;
}
// Update mesh in GPU
UploadMesh(&skyDome, false);
// Don't invert normals - let's use backface culling instead
// Just upload the mesh as-is
skyModel = LoadModelFromMesh(skyDome);
}
@ -162,38 +177,58 @@ void Sky::renderSkybox(const Camera3D& camera) {
// Disable depth write but keep depth test for proper rendering order
rlDisableDepthMask();
// Disable backface culling so we can see the inside of the sphere
rlDisableBackfaceCulling();
// Position skybox at camera position so it moves with the camera
// This ensures the skybox is always centered on the viewer
rlTranslatef(camera.position.x, camera.position.y, camera.position.z);
// Draw the sky dome with gradient color
// We'll use vertex colors or a simple colored material
Color topColor = zenithColor;
Color bottomColor = horizonColor;
if (shaderLoaded) {
// First make sure sun position is updated
sun.updatePosition(timeOfDay);
// For now, draw with a blended color
Color skyColor = interpolateColor(bottomColor, topColor, 0.5f);
DrawModel(skyModel, {0, 0, 0}, 1.0f, skyColor);
// Update shader uniforms
Vector3 horizonColorVec = {
horizonColor.r / 255.0f,
horizonColor.g / 255.0f,
horizonColor.b / 255.0f
};
Vector3 zenithColorVec = {
zenithColor.r / 255.0f,
zenithColor.g / 255.0f,
zenithColor.b / 255.0f
};
Vector3 sunColorVec = {
sun.color.r / 255.0f,
sun.color.g / 255.0f,
sun.color.b / 255.0f
};
// Draw sun as a sphere on the skybox
if (sun.intensity > 0.2f && sun.position.y > 0) {
// Calculate sun direction from camera
Vector3 sunDir = Vector3Normalize(sun.position);
Vector3 sunPosOnSphere = Vector3Scale(sunDir, 900.0f); // Just inside the skybox
// Normalize sun direction (make sure it's valid)
Vector3 sunDir = {0, 1, 0}; // Default up if sun position is invalid
if (Vector3Length(sun.position) > 0.001f) {
sunDir = Vector3Normalize(sun.position);
}
// Draw sun as a sphere
DrawSphere(sunPosOnSphere, 50.0f, sun.color);
// Draw sun glow layers
Color glowColor = sun.color;
glowColor.a = 80;
DrawSphere(sunPosOnSphere, 70.0f, glowColor);
// Set shader uniforms
SetShaderValue(skyShader, horizonColorLoc, &horizonColorVec, SHADER_UNIFORM_VEC3);
SetShaderValue(skyShader, zenithColorLoc, &zenithColorVec, SHADER_UNIFORM_VEC3);
SetShaderValue(skyShader, sunDirectionLoc, &sunDir, SHADER_UNIFORM_VEC3);
SetShaderValue(skyShader, sunColorLoc, &sunColorVec, SHADER_UNIFORM_VEC3);
SetShaderValue(skyShader, sunIntensityLoc, &sun.intensity, SHADER_UNIFORM_FLOAT);
glowColor.a = 40;
DrawSphere(sunPosOnSphere, 90.0f, glowColor);
// Draw the sky dome with shader
DrawModel(skyModel, {0, 0, 0}, 1.0f, WHITE);
} else {
// Fallback: Draw without shader
Color skyColor = interpolateColor(horizonColor, zenithColor, 0.5f);
DrawModel(skyModel, {0, 0, 0}, 1.0f, skyColor);
}
// Restore depth state
rlEnableBackfaceCulling();
rlEnableDepthMask();
rlPopMatrix();
}

View File

@ -2,7 +2,6 @@
#include <raylib.h>
#include <raymath.h>
#include <vector>
class Sky {
private:
@ -29,6 +28,13 @@ private:
Model skyModel;
bool shaderLoaded;
// Shader locations
int horizonColorLoc;
int zenithColorLoc;
int sunDirectionLoc;
int sunColorLoc;
int sunIntensityLoc;
public:
Sky();
~Sky();