sky and water domes using shaders

This commit is contained in:
2020-08-29 14:34:21 +02:00
parent e8e679a442
commit 654fd08863
8 changed files with 150 additions and 40 deletions
+6
View File
@@ -0,0 +1,6 @@
varying vec3 vWorldPosition;
void main() {
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
vWorldPosition = worldPosition.xyz;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
+22
View File
@@ -0,0 +1,22 @@
// https://gamedevelopment.tutsplus.com/tutorials/a-beginners-guide-to-coding-graphics-shaders--cms-23313
uniform vec3 topColor;
uniform vec3 horizontColor;
uniform float offset;
uniform float exponent;
varying vec3 vWorldPosition;
void main() {
float h = normalize( vWorldPosition + offset ).y;
gl_FragColor = vec4(
mix(
horizontColor,
topColor,
max(
pow(
max( h , 0.0),
exponent
),
0.0
)
), 1.0
);
}
+26
View File
@@ -0,0 +1,26 @@
// https://gamedevelopment.tutsplus.com/tutorials/a-beginners-guide-to-coding-graphics-shaders--cms-23313
uniform vec3 waterColor;
uniform vec3 bottomColor;
uniform float wateroffset;
uniform float waterexponent;
varying vec3 vWorldPosition;
void main() {
float h = normalize( vWorldPosition * -1.0 + wateroffset ).y;
gl_FragColor = vec4(
// mix(x, y, a) performs a linear interpolation between x and y using a to weight between them.
// The return value is computed as x×(1a)+y×a.
mix(
waterColor,
bottomColor,
max(
pow(
max( h , 0.0),
waterexponent
),
0.0
)
),
1.0
);
}
+6 -1
View File
@@ -4,12 +4,13 @@ const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
const { VueLoaderPlugin } = require('vue-loader')
// const { GlslLoaderPlugin } = require('webpack-glsl-loader')
const utils = require('./utils')
module.exports = {
resolve: {
extensions: ['.js', '.vue', '.json'],
extensions: ['.js', '.vue', '.json', '.glsl'],
alias: {
'assets': utils.resolve('assets'),
'pages': utils.resolve('src/pages'),
@@ -28,6 +29,9 @@ module.exports = {
}, {
test: /\.vue$/,
use: 'vue-loader'
}, {
test: /\.glsl$/,
loader: 'webpack-glsl-loader'
}, {
test: /\.js$/,
use: {
@@ -73,6 +77,7 @@ module.exports = {
}),
new HtmlWebpackHarddiskPlugin(),
new VueLoaderPlugin(),
// new GlslLoaderPlugin(),
new CopyWebpackPlugin([{
from: utils.resolve('static/img'),
to: utils.resolve('dist/static/img'),
+22
View File
@@ -7618,6 +7618,12 @@
"readable-stream": "^2.0.0"
}
},
"fs": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/fs/-/fs-0.0.2.tgz",
"integrity": "sha1-4fJE7zkzwbKmS9R5kTYGDQ9ZFPg=",
"dev": true
},
"fs-write-stream-atomic": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
@@ -11552,6 +11558,12 @@
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
"dev": true
},
"path": {
"version": "0.11.14",
"resolved": "https://registry.npmjs.org/path/-/path-0.11.14.tgz",
"integrity": "sha1-y8dWk1XLPIOv60rOQ+z/lSMeWn0=",
"dev": true
},
"path-browserify": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
@@ -15161,6 +15173,16 @@
}
}
},
"webpack-glsl-loader": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/webpack-glsl-loader/-/webpack-glsl-loader-1.0.1.tgz",
"integrity": "sha1-cqDjAZK9V5R9YNbVBckVvmgNCsw=",
"dev": true,
"requires": {
"fs": "0.0.2",
"path": "^0.11.14"
}
},
"webpack-log": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
+1
View File
@@ -70,6 +70,7 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"webpack-glsl-loader": "^1.0.1",
"webpack-merge": "^4.2.2"
}
}
+65 -37
View File
@@ -14,6 +14,8 @@
<renderer :obj="myRenderer" :size="size">
<scene :obj="myScene" @update:obj="handleScene">
<!-- <SkyBox :size="{x:500,y:500,z:500}" :position="{x:0,y:0,z:0}" :color="0x992222" /> -->
<!-- <orbit-controls ref="cam_controls" :position="init_cam_pos" :rotation="{ x: 0, y: 0, z: 0 }">
<camera />
</orbit-controls> -->
@@ -30,7 +32,7 @@
<cube :size="{x:1,y:1,z:30}" :position="{x:0,y:0,z:15}" :color="0x17d100" />
</template>
<plan :size="{w:5000,h:5000}" :position="{x:0,y:0,z:0}" :color="0x1a1a1a" :rotation="{x:90,y:0,z:0}" />
<ground :size="{w:5000,h:5000}" :position="{x:0,y:0,z:0}" :color="0x000011" :rotation="{x:90,y:0,z:0}" />
<template v-if="projects.length">
<project
@@ -56,12 +58,16 @@ import mixins from 'components/mixins'
import * as THREE from 'three'
import TWEEN from '@tweenjs/tween.js'
import Plan from './components/objects/Plan'
import BgVertex from 'assets/glsl/BgVertex'
import SkyFragment from 'assets/glsl/SkyFragment'
import WaterFragment from 'assets/glsl/WaterFragment'
import Ground from './components/objects/Ground'
import Cube from './components/objects/Cube'
import Project from './components/objects/Project'
// const TWEEN = require('@tweenjs/tween.js')
const _debug = true
const _debug = false
export default {
metaInfo: {
@@ -73,7 +79,7 @@ export default {
components: {
Cube,
Project,
Plan
Ground
},
mixins: [mixins],
data () {
@@ -85,11 +91,41 @@ export default {
// scene obj is well overwrited but background color not visible
let scene = new THREE.Scene()
scene.background = new THREE.Color(0x1a1a1a)
scene.fog = new THREE.Fog(scene.background, 50, 400)
// scene.fog = new THREE.Fog(new THREE.Color(0xffffff), 50, 200)
// console.log('myScene', scene)
// let cameraHelper = new THREE.CameraHelper()
// scene.add(cameraHelper)
// SKYDOME
// https://github.com/mrdoob/three.js/blob/master/examples/webgl_lights_hemisphere.html
// https://gamedevelopment.tutsplus.com/tutorials/a-beginners-guide-to-coding-graphics-shaders--cms-23313
var uniforms = {
'topColor': { value: new THREE.Color(0x0077ff) },
'horizontColor': { value: new THREE.Color(0xffffff) },
'waterColor': { value: new THREE.Color(0x0000aa) },
'bottomColor': { value: new THREE.Color(0x000000) },
'offset': { value: 33 },
'wateroffset': { value: 33 },
'exponent': { value: 0.6 },
'waterexponent': { value: 0.6 }
}
// SphereBufferGeometry(radius : Float, widthSegments : Integer, heightSegments : Integer, phiStart : Float, phiLength : Float, thetaStart : Float, thetaLength : Float)
var bgGeo = new THREE.SphereBufferGeometry(900, 32, 15, 0, 2 * Math.PI, 0, 0.5 * Math.PI)
var skyMat = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: BgVertex,
fragmentShader: SkyFragment,
side: THREE.BackSide
})
var sky = new THREE.Mesh(bgGeo, skyMat)
scene.add(sky)
var waterMat = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: BgVertex,
fragmentShader: WaterFragment,
side: THREE.BackSide
})
var ground = new THREE.Mesh(bgGeo, waterMat)
ground.rotateZ(this.deg2rad(180))
scene.add(ground)
return {
debug: _debug,
@@ -112,7 +148,7 @@ export default {
cam_target: new THREE.Vector3(0, 0, 0)
},
// cam_controls: null,
init_cam_pos: { x: 0, y: 10, z: 150 },
init_cam_pos: { x: 0, y: 10, z: 100 },
raycaster: new THREE.Raycaster(),
interactive_objects: [],
light_opts: {
@@ -195,47 +231,39 @@ export default {
// CONTROLS
this.controls.user_interact = false
// INTERACT
// INTERACTIONS
// TODO: check if draging
// update the picking ray with the camera and mouse position
this.raycaster.setFromCamera(this.mouse, this.camera)
// calculate objects intersecting the picking ray
var intersects = this.raycaster.intersectObjects(this.interactive_objects)
// console.log('intersects', intersects)
// console.log('camera', this.camera)
// console.log('TWEEN', TWEEN)
let object, vnode, topos
let cam = this.camera
// let camControls = this.cam_controls
let camPos = { ...this.camera.position }
// console.log('camPos', camPos)
let object, vnode//, toPos
// let cam = this.camera
// let camPos = { ...this.camera.position }
if (intersects.length) {
for (var i = 0; i < intersects.length; i++) {
// intersects[i].object.material.color.set(0xff0000)
object = intersects[i].object
vnode = object.userData.vnode
vnode.isOpened = true
// this.cam_controls.target = object.position
new TWEEN.Tween(this.controls.cam_target)
.to(object.position, 400)
.start()
// cam.position.set({ x: camPos.x, y: camPos.y, z: camPos.z })
// camControls.update()
topos = { ...object.position }
topos.z += 20
topos.y = 5
new TWEEN.Tween(camPos)
.easing(TWEEN.Easing.Quadratic.InOut)
.to(topos, 3000)
.onUpdate(function () {
// console.log('tween update', this._object)
cam.position.set(this._object.x, this._object.y, this._object.z)
// camControls.update()
})
.start()
// new TWEEN.Tween(this.controls.cam_target)
// .to(object.position, 400)
// .start()
//
// toPos = { ...object.position }
// toPos.z += 20
// toPos.y = 5
// new TWEEN.Tween(camPos)
// .easing(TWEEN.Easing.Quadratic.InOut)
// .to(toPos, 3000)
// .onUpdate(function () {
// // console.log('tween update', this._object)
// cam.position.set(this._object.x, this._object.y, this._object.z)
// // camControls.update()
// })
// .start()
// console.log('tween', tween)
break
@@ -1,6 +1,6 @@
<template>
<mesh
name="Plane"
name="Ground"
:position="position"
:rotation="{
x:deg2rad(rotation.x),
@@ -19,7 +19,7 @@ import mixins from 'components/mixins'
import * as THREE from 'three'
export default {
name: 'Plan',
name: 'Ground',
mixins: [mixins],
props: {
size: Object,