Add skybox
This commit is contained in:
80
src/Skybox.ts
Normal file
80
src/Skybox.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
/** Skybox cube for rendering the sky */
|
||||
export class Skybox {
|
||||
private vao: WebGLVertexArrayObject | null = null;
|
||||
private vbo: WebGLBuffer | null = null;
|
||||
private indexCount: number = 0;
|
||||
|
||||
constructor() {}
|
||||
|
||||
initVAO(gl: WebGL2RenderingContext): void {
|
||||
// Cube vertices - positions only
|
||||
const vertices = new Float32Array([
|
||||
// Front face
|
||||
-1, -1, 1,
|
||||
1, -1, 1,
|
||||
1, 1, 1,
|
||||
-1, 1, 1,
|
||||
// Back face
|
||||
-1, -1, -1,
|
||||
-1, 1, -1,
|
||||
1, 1, -1,
|
||||
1, -1, -1,
|
||||
// Top face
|
||||
-1, 1, -1,
|
||||
-1, 1, 1,
|
||||
1, 1, 1,
|
||||
1, 1, -1,
|
||||
// Bottom face
|
||||
-1, -1, -1,
|
||||
1, -1, -1,
|
||||
1, -1, 1,
|
||||
-1, -1, 1,
|
||||
// Right face
|
||||
1, -1, -1,
|
||||
1, 1, -1,
|
||||
1, 1, 1,
|
||||
1, -1, 1,
|
||||
// Left face
|
||||
-1, -1, -1,
|
||||
-1, -1, 1,
|
||||
-1, 1, 1,
|
||||
-1, 1, -1,
|
||||
]);
|
||||
|
||||
const indices = new Uint16Array([
|
||||
0, 2, 1, 0, 3, 2, // front
|
||||
4, 6, 5, 4, 7, 6, // back
|
||||
8, 10, 9, 8, 11, 10, // top
|
||||
12, 14, 13, 12, 15, 14, // bottom
|
||||
16, 18, 17, 16, 19, 18, // right
|
||||
20, 22, 21, 20, 23, 22, // left
|
||||
]);
|
||||
|
||||
this.indexCount = indices.length;
|
||||
|
||||
this.vao = gl.createVertexArray();
|
||||
gl.bindVertexArray(this.vao);
|
||||
|
||||
this.vbo = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
||||
|
||||
const ibo = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
||||
|
||||
// Position attribute
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.bindVertexArray(null);
|
||||
}
|
||||
|
||||
draw(gl: WebGL2RenderingContext): void {
|
||||
if (!this.vao) return;
|
||||
|
||||
gl.bindVertexArray(this.vao);
|
||||
gl.drawElements(gl.TRIANGLES, this.indexCount, gl.UNSIGNED_SHORT, 0);
|
||||
gl.bindVertexArray(null);
|
||||
}
|
||||
}
|
||||
33
src/main.ts
33
src/main.ts
@@ -1,6 +1,7 @@
|
||||
import { vec3, mat4 } from 'gl-matrix';
|
||||
import { Camera } from './Camera';
|
||||
import { Grid } from './Grid';
|
||||
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 */
|
||||
@@ -141,6 +144,7 @@ var keysPressed: Set<string> = new Set();
|
||||
/** Objects and states*/
|
||||
var camera: Camera;
|
||||
var oceanGrid: Grid;
|
||||
var skybox: Skybox;
|
||||
var curRotX = Config.CAMERA_DEFAULT_ROT_X;
|
||||
var curRotY = Config.CAMERA_DEFAULT_ROT_Y;
|
||||
function drawScene() {
|
||||
@@ -168,6 +172,9 @@ function drawScene() {
|
||||
//Clear buffer content
|
||||
gl.clearColor(1.0, 1.0, 1.0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT); //No depth buffer
|
||||
|
||||
// Disable face culling for fullscreen quad
|
||||
gl.disable(gl.CULL_FACE);
|
||||
|
||||
//draw a fullscreen quad
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, VBO);
|
||||
@@ -205,6 +212,29 @@ function drawScene() {
|
||||
camera.setRotationX((curRotX += mouseYVel * Config.MOUSE_SENSITIVITY + keyboardRotationX));
|
||||
camera.setRotationY((curRotY += mouseXVel * Config.MOUSE_SENSITIVITY + keyboardRotationY));
|
||||
var view = camera.getViewMatrix();
|
||||
|
||||
// Sun direction (matches the one in ocean shader)
|
||||
const sunDirection = vec3.fromValues(0.3, 0.5, 0.8);
|
||||
vec3.normalize(sunDirection, sunDirection);
|
||||
|
||||
// Draw skybox first with depth test disabled (always behind everything)
|
||||
gl.depthMask(false);
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
gl.disable(gl.CULL_FACE); // Disable face culling for skybox (we're inside)
|
||||
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);
|
||||
gl.enable(gl.CULL_FACE); // Re-enable face culling for ocean
|
||||
gl.cullFace(gl.BACK); // Cull back faces for ocean
|
||||
|
||||
var model = mat4.create();
|
||||
mat4.identity(model);
|
||||
@@ -324,6 +354,9 @@ function main() {
|
||||
|
||||
oceanGrid = new Grid(Config.GRID_SIZE);
|
||||
oceanGrid.initVAO(gl);
|
||||
|
||||
skybox = new Skybox();
|
||||
skybox.initVAO(gl);
|
||||
|
||||
camera = new Camera();
|
||||
//Check if any errors apeared during init.
|
||||
|
||||
Reference in New Issue
Block a user