junk planet
This commit is contained in:
parent
cca0d2b3c3
commit
9dbfb40707
5
assets/shaders/atmosphere.fs
Normal file
5
assets/shaders/atmosphere.fs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
|
||||||
|
}
|
12
assets/shaders/atmosphere.vs
Normal file
12
assets/shaders/atmosphere.vs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
attribute vec3 aVertexPosition;
|
||||||
|
attribute vec2 aTexCoords;
|
||||||
|
|
||||||
|
uniform mat4 uModelMatrix;
|
||||||
|
uniform mat4 uViewMatrix;
|
||||||
|
uniform mat4 uProjectionMatrix;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(aVertexPosition,1);
|
||||||
|
}
|
BIN
assets/textures/grass-plain-1024.jpg
Normal file
BIN
assets/textures/grass-plain-1024.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
29
src/engine/components/planet/atmosphere.js
Normal file
29
src/engine/components/planet/atmosphere.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { MeshInstance } from '../'
|
||||||
|
import Sphere from '../../mesh/geometry/sphere'
|
||||||
|
import { vec3 } from 'gl-matrix'
|
||||||
|
import { normalv3 } from '../../utility'
|
||||||
|
|
||||||
|
class Atmosphere extends MeshInstance {
|
||||||
|
constructor (pos, innerRadius, outerRadius, scale, color) {
|
||||||
|
super(Sphere.new(outerRadius, 64, 64), pos)
|
||||||
|
this.outerRadius = outerRadius
|
||||||
|
this.innerRadius = innerRadius
|
||||||
|
this.scale = scale
|
||||||
|
this.color = color
|
||||||
|
}
|
||||||
|
|
||||||
|
draw (gl, shader, camera, sun, sky) {
|
||||||
|
// Set model transform matrix uniform
|
||||||
|
gl.uniformMatrix4fv(shader.getUniformLocation(gl, 'uModelMatrix'), false, this.transform)
|
||||||
|
|
||||||
|
// Draw the mesh
|
||||||
|
gl.disable(gl.CULL_FACE)
|
||||||
|
this.mesh.prepare(gl, shader)
|
||||||
|
this.mesh.draw(gl, shader)
|
||||||
|
this.mesh.postdraw(gl, shader)
|
||||||
|
gl.enable(gl.CULL_FACE)
|
||||||
|
gl.cullFace(gl.BACK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Atmosphere
|
@ -45,11 +45,10 @@ class CubeFace {
|
|||||||
if (this.generated) return
|
if (this.generated) return
|
||||||
|
|
||||||
let VERTICES = this.generator.resolution
|
let VERTICES = this.generator.resolution
|
||||||
let count = VERTICES * VERTICES
|
let vertices = []
|
||||||
let vertices = new Array(count * 3)
|
let normals = []
|
||||||
let normals = new Array(count * 3)
|
let textureCoords = []
|
||||||
let textureCoords = new Array(count * 2)
|
let indices = []
|
||||||
let indices = new Array(6 * (VERTICES - 1) * (VERTICES - 1))
|
|
||||||
|
|
||||||
let radius = this.generator.radius
|
let radius = this.generator.radius
|
||||||
let divisionLevel = Math.pow(2, this.level)
|
let divisionLevel = Math.pow(2, this.level)
|
||||||
@ -69,7 +68,7 @@ class CubeFace {
|
|||||||
|
|
||||||
// Normalize and multiply by radius to create a spherical mesh
|
// Normalize and multiply by radius to create a spherical mesh
|
||||||
let normal = normalv3(vertex)
|
let normal = normalv3(vertex)
|
||||||
let pos = mulv3(normal, (radius))
|
let pos = mulv3(normal, (this.generator.noise.getNoise3D(this.level + 1, normal[0], normal[1], normal[2]) + radius))
|
||||||
|
|
||||||
vertices[vertexPointer * 3] = pos[0]
|
vertices[vertexPointer * 3] = pos[0]
|
||||||
vertices[vertexPointer * 3 + 1] = pos[1]
|
vertices[vertexPointer * 3 + 1] = pos[1]
|
||||||
@ -101,6 +100,41 @@ class CubeFace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate normals
|
||||||
|
for (let i = 0; i < indices.length; i += 3) {
|
||||||
|
// Extract face from vertices
|
||||||
|
// First vertex position
|
||||||
|
let vertexA = [
|
||||||
|
vertices[indices[i] * 3],
|
||||||
|
vertices[indices[i] * 3 + 1],
|
||||||
|
vertices[indices[i] * 3 + 2]
|
||||||
|
]
|
||||||
|
|
||||||
|
// Second vertex position
|
||||||
|
let vertexB = [
|
||||||
|
vertices[indices[i + 1] * 3],
|
||||||
|
vertices[indices[i + 1] * 3 + 1],
|
||||||
|
vertices[indices[i + 1] * 3 + 2]
|
||||||
|
]
|
||||||
|
|
||||||
|
// Third vertex position
|
||||||
|
let vertexC = [
|
||||||
|
vertices[indices[i + 2] * 3],
|
||||||
|
vertices[indices[i + 2] * 3 + 1],
|
||||||
|
vertices[indices[i + 2] * 3 + 2]
|
||||||
|
]
|
||||||
|
|
||||||
|
// Normalize
|
||||||
|
let dir = crossv3(subv3(vertexB, vertexA), subv3(vertexC, vertexA))
|
||||||
|
let normal = normalv3(dir)
|
||||||
|
|
||||||
|
for (let k = 0; k < 3; k++) {
|
||||||
|
normals[indices[i + k] * 3] = normal[0]
|
||||||
|
normals[indices[i + k] * 3 + 1] = normal[1]
|
||||||
|
normals[indices[i + k] * 3 + 2] = normal[2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.mesh = Mesh.construct(Screen.gl, vertices, indices, textureCoords, normals)
|
this.mesh = Mesh.construct(Screen.gl, vertices, indices, textureCoords, normals)
|
||||||
this.generated = true
|
this.generated = true
|
||||||
}
|
}
|
||||||
@ -162,10 +196,10 @@ class CubeFace {
|
|||||||
let divisionLevel = Math.pow(2, this.level)
|
let divisionLevel = Math.pow(2, this.level)
|
||||||
let splitDistance = this.generator.radius / divisionLevel
|
let splitDistance = this.generator.radius / divisionLevel
|
||||||
|
|
||||||
if (camToOrigin < splitDistance * 1.5 && this.children.length === 0) {
|
if (camToOrigin < splitDistance * 2 && this.children.length === 0) {
|
||||||
this.subdivide()
|
this.subdivide()
|
||||||
return
|
return
|
||||||
} else if (camToOrigin > splitDistance * 2 && this.children.length > 0) {
|
} else if (camToOrigin > splitDistance * 2.5 && this.children.length > 0) {
|
||||||
this.merge()
|
this.merge()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -62,10 +62,8 @@ class SimplexHeightMap extends HeightMap {
|
|||||||
// octaves - Number of noise layers
|
// octaves - Number of noise layers
|
||||||
// period - Distance above which we start to see similarities. The higher, the longer "hills" will be on a terrain.
|
// period - Distance above which we start to see similarities. The higher, the longer "hills" will be on a terrain.
|
||||||
// lacunarity - Controls period change across octaves. 2 is usually a good value to address all detail levels.
|
// lacunarity - Controls period change across octaves. 2 is usually a good value to address all detail levels.
|
||||||
constructor (offsetX, offsetY, size, seed, amplitude = 15, persistence = 0.4, octaves = 5, period = 80, lacunarity = 2) {
|
constructor (seed, amplitude = 15, period = 80, persistence = 0.4, lacunarity = 2, octaves = 5) {
|
||||||
super(size)
|
super(0)
|
||||||
this.ix = offsetX
|
|
||||||
this.iy = offsetY
|
|
||||||
this.seed = seed
|
this.seed = seed
|
||||||
|
|
||||||
this.osn = new OpenSimplexNoise(seed)
|
this.osn = new OpenSimplexNoise(seed)
|
||||||
@ -73,32 +71,48 @@ class SimplexHeightMap extends HeightMap {
|
|||||||
this.amplitude = amplitude
|
this.amplitude = amplitude
|
||||||
this.period = period
|
this.period = period
|
||||||
this.lacunarity = lacunarity
|
this.lacunarity = lacunarity
|
||||||
this.octaves = octaves
|
|
||||||
this.persistence = persistence
|
this.persistence = persistence
|
||||||
|
this.octaves = octaves
|
||||||
}
|
}
|
||||||
|
|
||||||
getNoise (zx, zy) {
|
// Fractal/Fractional Brownian Motion (fBm) summation of 3D Perlin Simplex noise
|
||||||
let x = ((this.size * this.ix) + zx) / this.period
|
getNoise2D (o, x, y) {
|
||||||
let y = ((this.size * this.iy) + zy) / this.period
|
let output = 0.0
|
||||||
|
let denom = 0.0
|
||||||
|
let frequency = this.period
|
||||||
|
let amplitude = this.amplitude
|
||||||
|
|
||||||
let amp = 1.0
|
for (let i = 0; i < o; i++) {
|
||||||
let max = 1.0
|
output += (amplitude * this.osn.noise3D(x * frequency, y * frequency))
|
||||||
let sum = this.osn.noise2D(x, y)
|
denom += amplitude
|
||||||
|
|
||||||
let i = 0
|
frequency *= this.lacunarity
|
||||||
while (++i < this.octaves) {
|
amplitude *= this.persistence
|
||||||
x *= this.lacunarity
|
|
||||||
y *= this.lacunarity
|
|
||||||
amp *= this.persistence
|
|
||||||
max += amp
|
|
||||||
sum += this.osn.noise2D(x, y) * amp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sum / max
|
return (output / denom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNoise3D (o, x, y, z) {
|
||||||
|
let output = 0.0
|
||||||
|
let denom = 0.0
|
||||||
|
let frequency = this.period
|
||||||
|
let amplitude = this.amplitude
|
||||||
|
|
||||||
|
for (let i = 0; i < o; i++) {
|
||||||
|
output += (amplitude * this.osn.noise3D(x * frequency, y * frequency, z * frequency))
|
||||||
|
denom += amplitude
|
||||||
|
|
||||||
|
frequency *= this.lacunarity
|
||||||
|
amplitude *= this.persistence
|
||||||
|
}
|
||||||
|
|
||||||
|
return (output / denom)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2D Height Map
|
||||||
getHeight (x, y) {
|
getHeight (x, y) {
|
||||||
return this.getNoise(x, y) * this.amplitude
|
return this.getNoise2D(this.octaves, x, y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ class Environment {
|
|||||||
this.fogEnd = 0
|
this.fogEnd = 0
|
||||||
this.fogColor = [0.8, 0.8, 0.8]
|
this.fogColor = [0.8, 0.8, 0.8]
|
||||||
|
|
||||||
this.sun = new DirectionalLight([0.0, 1000.0, -2000.0], [-1.0, -1.0, 0.0], [1.0, 1.0, 1.0])
|
this.sun = new Light([0.0, 1000.0, -2000.0], [1.0, 1.0, 1.0])
|
||||||
this.lights = [ this.sun ]
|
this.lights = [ this.sun ]
|
||||||
|
|
||||||
this.maxEnvironmentLights = ENV_MAX_LIGHTS
|
this.maxEnvironmentLights = ENV_MAX_LIGHTS
|
||||||
|
50
src/engine/mesh/geometry/sphere.js
Normal file
50
src/engine/mesh/geometry/sphere.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { Mesh } from '..'
|
||||||
|
import Screen from '../../screen'
|
||||||
|
|
||||||
|
class Sphere extends Mesh {
|
||||||
|
static new (radius, rings, sectors) {
|
||||||
|
const R = 1.0 / (rings - 1)
|
||||||
|
const S = 1.0 / (sectors - 1)
|
||||||
|
|
||||||
|
const vertices = []
|
||||||
|
const normals = []
|
||||||
|
const textureCoords = []
|
||||||
|
const indices = []
|
||||||
|
|
||||||
|
for (let r = 0, vertexPointer = 0; r < rings; r++) {
|
||||||
|
for (let s = 0; s < sectors; s++, vertexPointer++) {
|
||||||
|
const y = Math.sin(Math.PI / 2 + Math.PI * r * R)
|
||||||
|
const x = Math.cos(2 * Math.PI * s * S) * Math.sin(Math.PI * r * R)
|
||||||
|
const z = Math.sin(2 * Math.PI * s * S) * Math.sin(Math.PI * r * R)
|
||||||
|
|
||||||
|
vertices[vertexPointer * 3] = x * radius
|
||||||
|
vertices[vertexPointer * 3 + 1] = y * radius
|
||||||
|
vertices[vertexPointer * 3 + 2] = z * radius
|
||||||
|
normals[vertexPointer * 3] = x
|
||||||
|
normals[vertexPointer * 3 + 1] = y
|
||||||
|
normals[vertexPointer * 3 + 2] = z
|
||||||
|
textureCoords[vertexPointer * 2] = s * S
|
||||||
|
textureCoords[vertexPointer * 2 + 1] = r * R
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let r = 0, pointer = 0; r < rings - 1; r++) {
|
||||||
|
for (let s = 0; s < sectors - 1; s++) {
|
||||||
|
const topLeft = r * sectors + s
|
||||||
|
const topRight = topLeft + 1
|
||||||
|
const bottomLeft = (r + 1) * sectors + s
|
||||||
|
const bottomRight = bottomLeft + 1
|
||||||
|
indices[pointer++] = bottomLeft
|
||||||
|
indices[pointer++] = topLeft
|
||||||
|
indices[pointer++] = topRight
|
||||||
|
indices[pointer++] = topRight
|
||||||
|
indices[pointer++] = bottomRight
|
||||||
|
indices[pointer++] = bottomLeft
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Mesh.construct(Screen.gl, vertices, indices, textureCoords, normals)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Sphere
|
22
src/index.js
22
src/index.js
@ -6,6 +6,7 @@ import { randomInt } from './engine/utility'
|
|||||||
|
|
||||||
import { Environment } from './engine/environment'
|
import { Environment } from './engine/environment'
|
||||||
import { LODTerrain } from './engine/components/terrain/lod'
|
import { LODTerrain } from './engine/components/terrain/lod'
|
||||||
|
import { MeshInstance } from './engine/components'
|
||||||
import { Skybox } from './engine/components/skybox'
|
import { Skybox } from './engine/components/skybox'
|
||||||
import { WaterRenderer, WaterTile } from './engine/components/water'
|
import { WaterRenderer, WaterTile } from './engine/components/water'
|
||||||
import { Particle, ParticleTexture, ParticleSystem, ParticleRenderer } from './engine/components/particles'
|
import { Particle, ParticleTexture, ParticleSystem, ParticleRenderer } from './engine/components/particles'
|
||||||
@ -14,6 +15,7 @@ import { Material, Texture } from './engine/mesh/material'
|
|||||||
import { GUIRenderer, GUIImage, Dim4 } from './engine/gui'
|
import { GUIRenderer, GUIImage, Dim4 } from './engine/gui'
|
||||||
import { FontRenderer, GUIText, Font } from './engine/gui/font'
|
import { FontRenderer, GUIText, Font } from './engine/gui/font'
|
||||||
import { VoxelWorld, VoxelGenerator } from './engine/voxel'
|
import { VoxelWorld, VoxelGenerator } from './engine/voxel'
|
||||||
|
import Atmosphere from './engine/components/planet/atmosphere'
|
||||||
|
|
||||||
import { CubePlanet, PlanetGenerator } from './engine/components/planet'
|
import { CubePlanet, PlanetGenerator } from './engine/components/planet'
|
||||||
|
|
||||||
@ -27,6 +29,7 @@ async function pipeline () {
|
|||||||
let entity = await loadMesh(game.gl, 'test')
|
let entity = await loadMesh(game.gl, 'test')
|
||||||
let terrainShader = await game.shaders.createShaderFromFiles(game.gl, 'terrain', false)
|
let terrainShader = await game.shaders.createShaderFromFiles(game.gl, 'terrain', false)
|
||||||
let skyboxShader = await game.shaders.createShaderFromFiles(game.gl, 'skybox', false)
|
let skyboxShader = await game.shaders.createShaderFromFiles(game.gl, 'skybox', false)
|
||||||
|
// let atmosShader = await game.shaders.createShaderFromFiles(game.gl, 'atmosphere', false)
|
||||||
|
|
||||||
entity.setRotation([0.0, 0.0, -90.0])
|
entity.setRotation([0.0, 0.0, -90.0])
|
||||||
|
|
||||||
@ -51,21 +54,21 @@ async function pipeline () {
|
|||||||
let particleTexture = new ParticleTexture(await Texture.fromFile(game.gl, 'particleAtlas.png'), 4)
|
let particleTexture = new ParticleTexture(await Texture.fromFile(game.gl, 'particleAtlas.png'), 4)
|
||||||
|
|
||||||
let itms = [
|
let itms = [
|
||||||
new GUIImage(await Texture.fromFile(game.gl, 'noisy.png', false, game.gl.LINEAR),
|
// new GUIImage(await Texture.fromFile(game.gl, 'noisy.png', false, game.gl.LINEAR),
|
||||||
new Dim4(-0.9, 0.0, 0.9, 0.0), new Dim4(0.1, 0.0, 0.1, 0.0))
|
// new Dim4(-0.9, 0.0, 0.9, 0.0), new Dim4(0.1, 0.0, 0.1, 0.0))
|
||||||
]
|
]
|
||||||
// Nesting test
|
// Nesting test
|
||||||
itms[0].addChild(new GUIText('', arialFont, 0.8, new Dim4(0.2, 0.0, 0.0, 0.0), new Dim4(1.0, 0.0, 0.3, 0.0), false))
|
itms[0] = new GUIText('', arialFont, 0.8, new Dim4(0.0, 0.0, 0.0, 0.0), new Dim4(0.1, 0.0, 0.1, 0.0), false)
|
||||||
itms[0].children[0].color = [0.0, 0.2, 1.0]
|
itms[0].color = [0.0, 0.2, 1.0]
|
||||||
|
|
||||||
// Create a height map based on OpenSimplex noise
|
// Create a height map based on OpenSimplex noise
|
||||||
let hmap = new SimplexHeightMap(1, 1, 256, 50)
|
let hmap = new SimplexHeightMap(50, 20, 128)
|
||||||
|
|
||||||
// Create a terrain instance
|
// Create a terrain instance
|
||||||
// let terrain = new LODTerrain([0.0, 0.0, 0.0], 1024, 1024, 850, 4)
|
// let terrain = new LODTerrain([0.0, 0.0, 0.0], 1024, 1024, 850, 4)
|
||||||
|
|
||||||
// Terrain material
|
// Terrain material
|
||||||
let material = new Material(['grass-1024.jpg'])
|
let material = new Material(['grass-plain-1024.jpg'])
|
||||||
await material.loadTextures(game.gl)
|
await material.loadTextures(game.gl)
|
||||||
|
|
||||||
// test code
|
// test code
|
||||||
@ -93,6 +96,7 @@ async function pipeline () {
|
|||||||
|
|
||||||
// Planet test
|
// Planet test
|
||||||
let planet = new CubePlanet([0.0, 0.0, 0.0], new PlanetGenerator(16, 1000, hmap))
|
let planet = new CubePlanet([0.0, 0.0, 0.0], new PlanetGenerator(16, 1000, hmap))
|
||||||
|
// let atmosphere = new Atmosphere([0.0, 0.0, 0.0], 1000, 1025, 1, [0.0, 0.0, 1.0])
|
||||||
|
|
||||||
// Update function for camera and terrain
|
// Update function for camera and terrain
|
||||||
let fpsTimer = 0
|
let fpsTimer = 0
|
||||||
@ -141,7 +145,7 @@ async function pipeline () {
|
|||||||
// Set text to FPS
|
// Set text to FPS
|
||||||
fpsTimer++
|
fpsTimer++
|
||||||
if (fpsTimer === 10) {
|
if (fpsTimer === 10) {
|
||||||
itms[0].children[0].setText(game.fps + ' fps')
|
itms[0].setText(game.fps + ' fps')
|
||||||
fpsTimer = 0
|
fpsTimer = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +175,10 @@ async function pipeline () {
|
|||||||
|
|
||||||
material.apply(gl, terrainShader)
|
material.apply(gl, terrainShader)
|
||||||
planet.draw(gl, terrainShader)
|
planet.draw(gl, terrainShader)
|
||||||
|
|
||||||
|
// atmosShader.use(gl)
|
||||||
|
// cam.draw(gl, atmosShader)
|
||||||
|
// atmosphere.draw(gl, atmosShader, cam, env.sun, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render function for the triangle
|
// Render function for the triangle
|
||||||
|
Loading…
Reference in New Issue
Block a user