Add Skybox class for rendering sky and update shaders for sky rendering

This commit is contained in:
2026-01-31 23:00:40 +01:00
parent 109eafa90a
commit b576d6a8cf
4 changed files with 168 additions and 14 deletions

View File

@@ -1,6 +1,7 @@
import { vec3, mat4 } from 'gl-matrix';
import { Camera } from './Camera';
import { OceanLOD } from './OceanLOD';
import { Skybox } from './Skybox';
import { createProgram } from './Shader';
import * as Config from './constants';
@@ -89,10 +90,12 @@ function initGeometry() {
var perlinNoiseProgram: WebGLProgram | null;
var defaultProgram: WebGLProgram | null;
var textureProgram: WebGLProgram | null;
var skyProgram: WebGLProgram | null;
function initShaders() {
perlinNoiseProgram = createProgram(gl, "ndc-vs", "noise-fs", "Perlin Noise");
defaultProgram = createProgram(gl, "default-vs", "default-fs", "Default");
textureProgram = createProgram(gl, "texture-vs", "texture-fs", "Texture");
skyProgram = createProgram(gl, "sky-vs", "sky-fs", "Sky");
}
/** Init an FBO used for the first render pass / perlin noise */
@@ -142,6 +145,7 @@ var keysPressed: Set<string> = new Set();
/** Objects and states*/
var camera: Camera;
var oceanLOD: OceanLOD;
var skybox: Skybox;
var curRotX = Config.CAMERA_DEFAULT_ROT_X;
var curRotY = Config.CAMERA_DEFAULT_ROT_Y;
var wireframeMode = false;
@@ -172,17 +176,18 @@ function drawScene() {
console.log(`LOD Stats - High:${stats[0]} Med:${stats[1]} Low:${stats[2]} VeryLow:${stats[3]}`);
}
lastTime = now.getTime();
// Single render pass with Gerstner waves computed in vertex shader
// Sun direction (matches the one in ocean shader)
const sunDirection = vec3.fromValues(0.3, 0.5, 0.8);
vec3.normalize(sunDirection, sunDirection);
//--- Render pass -> Ocean with Gerstner wave displacement ---
//--- Render pass -> Skybox first (no depth write) ---
{
gl.bindFramebuffer(gl.FRAMEBUFFER, null); //Bind default framebuffer
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, viewportWidth, viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
var projection = mat4.create();
mat4.identity(projection);
mat4.perspective(projection, Config.FOV, viewportWidth / viewportHeight, Config.NEAR_PLANE, Config.FAR_PLANE);
camera.setOffset(Config.CAMERA_DEFAULT_OFFSET + keyboardZoom);
@@ -190,6 +195,22 @@ function drawScene() {
camera.setRotationY((curRotY += mouseXVel * Config.MOUSE_SENSITIVITY + keyboardRotationY));
var view = camera.getViewMatrix();
// Draw skybox first with depth test disabled (always behind everything)
gl.depthMask(false);
gl.disable(gl.DEPTH_TEST);
gl.useProgram(skyProgram);
let sky_view_loc = gl.getUniformLocation(<WebGLProgram>skyProgram, "view");
gl.uniformMatrix4fv(sky_view_loc, false, view);
let sky_projection_loc = gl.getUniformLocation(<WebGLProgram>skyProgram, "projection");
gl.uniformMatrix4fv(sky_projection_loc, false, projection);
let sky_sun_loc = gl.getUniformLocation(<WebGLProgram>skyProgram, "uSunDirection");
gl.uniform3fv(sky_sun_loc, sunDirection);
skybox.draw(gl);
gl.enable(gl.DEPTH_TEST);
gl.depthMask(true);
// Update LOD based on camera position and view direction
oceanLOD.updateLOD(gl, camera.pos, camera.target);
@@ -346,6 +367,10 @@ function main() {
oceanLOD = new OceanLOD();
oceanLOD.initVAO(gl);
console.log(`Ocean LOD initialized with ${oceanLOD.getGridCount()} patches`);
skybox = new Skybox();
skybox.initVAO(gl);
console.log('Skybox initialized');
camera = new Camera();
//Check if any errors apeared during init.