sky and water domes using shaders
This commit is contained in:
@@ -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 );
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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×(1−a)+y×a.
|
||||||
|
mix(
|
||||||
|
waterColor,
|
||||||
|
bottomColor,
|
||||||
|
max(
|
||||||
|
pow(
|
||||||
|
max( h , 0.0),
|
||||||
|
waterexponent
|
||||||
|
),
|
||||||
|
0.0
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1.0
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -4,12 +4,13 @@ const HtmlWebpackPlugin = require('html-webpack-plugin')
|
|||||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||||
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
|
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
|
||||||
const { VueLoaderPlugin } = require('vue-loader')
|
const { VueLoaderPlugin } = require('vue-loader')
|
||||||
|
// const { GlslLoaderPlugin } = require('webpack-glsl-loader')
|
||||||
|
|
||||||
const utils = require('./utils')
|
const utils = require('./utils')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.js', '.vue', '.json'],
|
extensions: ['.js', '.vue', '.json', '.glsl'],
|
||||||
alias: {
|
alias: {
|
||||||
'assets': utils.resolve('assets'),
|
'assets': utils.resolve('assets'),
|
||||||
'pages': utils.resolve('src/pages'),
|
'pages': utils.resolve('src/pages'),
|
||||||
@@ -28,6 +29,9 @@ module.exports = {
|
|||||||
}, {
|
}, {
|
||||||
test: /\.vue$/,
|
test: /\.vue$/,
|
||||||
use: 'vue-loader'
|
use: 'vue-loader'
|
||||||
|
}, {
|
||||||
|
test: /\.glsl$/,
|
||||||
|
loader: 'webpack-glsl-loader'
|
||||||
}, {
|
}, {
|
||||||
test: /\.js$/,
|
test: /\.js$/,
|
||||||
use: {
|
use: {
|
||||||
@@ -73,6 +77,7 @@ module.exports = {
|
|||||||
}),
|
}),
|
||||||
new HtmlWebpackHarddiskPlugin(),
|
new HtmlWebpackHarddiskPlugin(),
|
||||||
new VueLoaderPlugin(),
|
new VueLoaderPlugin(),
|
||||||
|
// new GlslLoaderPlugin(),
|
||||||
new CopyWebpackPlugin([{
|
new CopyWebpackPlugin([{
|
||||||
from: utils.resolve('static/img'),
|
from: utils.resolve('static/img'),
|
||||||
to: utils.resolve('dist/static/img'),
|
to: utils.resolve('dist/static/img'),
|
||||||
|
|||||||
Generated
+22
@@ -7618,6 +7618,12 @@
|
|||||||
"readable-stream": "^2.0.0"
|
"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": {
|
"fs-write-stream-atomic": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
|
"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=",
|
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
|
||||||
"dev": true
|
"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": {
|
"path-browserify": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
|
"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": {
|
"webpack-log": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
"webpack": "^4.43.0",
|
"webpack": "^4.43.0",
|
||||||
"webpack-cli": "^3.3.12",
|
"webpack-cli": "^3.3.12",
|
||||||
"webpack-dev-server": "^3.11.0",
|
"webpack-dev-server": "^3.11.0",
|
||||||
|
"webpack-glsl-loader": "^1.0.1",
|
||||||
"webpack-merge": "^4.2.2"
|
"webpack-merge": "^4.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+65
-37
@@ -14,6 +14,8 @@
|
|||||||
<renderer :obj="myRenderer" :size="size">
|
<renderer :obj="myRenderer" :size="size">
|
||||||
<scene :obj="myScene" @update:obj="handleScene">
|
<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 }">
|
<!-- <orbit-controls ref="cam_controls" :position="init_cam_pos" :rotation="{ x: 0, y: 0, z: 0 }">
|
||||||
<camera />
|
<camera />
|
||||||
</orbit-controls> -->
|
</orbit-controls> -->
|
||||||
@@ -30,7 +32,7 @@
|
|||||||
<cube :size="{x:1,y:1,z:30}" :position="{x:0,y:0,z:15}" :color="0x17d100" />
|
<cube :size="{x:1,y:1,z:30}" :position="{x:0,y:0,z:15}" :color="0x17d100" />
|
||||||
</template>
|
</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">
|
<template v-if="projects.length">
|
||||||
<project
|
<project
|
||||||
@@ -56,12 +58,16 @@ import mixins from 'components/mixins'
|
|||||||
import * as THREE from 'three'
|
import * as THREE from 'three'
|
||||||
import TWEEN from '@tweenjs/tween.js'
|
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 Cube from './components/objects/Cube'
|
||||||
import Project from './components/objects/Project'
|
import Project from './components/objects/Project'
|
||||||
|
|
||||||
// const TWEEN = require('@tweenjs/tween.js')
|
// const TWEEN = require('@tweenjs/tween.js')
|
||||||
const _debug = true
|
const _debug = false
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
metaInfo: {
|
metaInfo: {
|
||||||
@@ -73,7 +79,7 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
Cube,
|
Cube,
|
||||||
Project,
|
Project,
|
||||||
Plan
|
Ground
|
||||||
},
|
},
|
||||||
mixins: [mixins],
|
mixins: [mixins],
|
||||||
data () {
|
data () {
|
||||||
@@ -85,11 +91,41 @@ export default {
|
|||||||
// scene obj is well overwrited but background color not visible
|
// scene obj is well overwrited but background color not visible
|
||||||
let scene = new THREE.Scene()
|
let scene = new THREE.Scene()
|
||||||
scene.background = new THREE.Color(0x1a1a1a)
|
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)
|
// console.log('myScene', scene)
|
||||||
|
|
||||||
// let cameraHelper = new THREE.CameraHelper()
|
// SKYDOME
|
||||||
// scene.add(cameraHelper)
|
// 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 {
|
return {
|
||||||
debug: _debug,
|
debug: _debug,
|
||||||
@@ -112,7 +148,7 @@ export default {
|
|||||||
cam_target: new THREE.Vector3(0, 0, 0)
|
cam_target: new THREE.Vector3(0, 0, 0)
|
||||||
},
|
},
|
||||||
// cam_controls: null,
|
// 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(),
|
raycaster: new THREE.Raycaster(),
|
||||||
interactive_objects: [],
|
interactive_objects: [],
|
||||||
light_opts: {
|
light_opts: {
|
||||||
@@ -195,47 +231,39 @@ export default {
|
|||||||
// CONTROLS
|
// CONTROLS
|
||||||
this.controls.user_interact = false
|
this.controls.user_interact = false
|
||||||
|
|
||||||
// INTERACT
|
// INTERACTIONS
|
||||||
// TODO: check if draging
|
// TODO: check if draging
|
||||||
// update the picking ray with the camera and mouse position
|
// update the picking ray with the camera and mouse position
|
||||||
this.raycaster.setFromCamera(this.mouse, this.camera)
|
this.raycaster.setFromCamera(this.mouse, this.camera)
|
||||||
// calculate objects intersecting the picking ray
|
// calculate objects intersecting the picking ray
|
||||||
var intersects = this.raycaster.intersectObjects(this.interactive_objects)
|
var intersects = this.raycaster.intersectObjects(this.interactive_objects)
|
||||||
|
|
||||||
// console.log('intersects', intersects)
|
// console.log('intersects', intersects)
|
||||||
// console.log('camera', this.camera)
|
|
||||||
// console.log('TWEEN', TWEEN)
|
let object, vnode//, toPos
|
||||||
let object, vnode, topos
|
// let cam = this.camera
|
||||||
let cam = this.camera
|
// let camPos = { ...this.camera.position }
|
||||||
// let camControls = this.cam_controls
|
|
||||||
let camPos = { ...this.camera.position }
|
|
||||||
// console.log('camPos', camPos)
|
|
||||||
if (intersects.length) {
|
if (intersects.length) {
|
||||||
for (var i = 0; i < intersects.length; i++) {
|
for (var i = 0; i < intersects.length; i++) {
|
||||||
// intersects[i].object.material.color.set(0xff0000)
|
|
||||||
object = intersects[i].object
|
object = intersects[i].object
|
||||||
vnode = object.userData.vnode
|
vnode = object.userData.vnode
|
||||||
vnode.isOpened = true
|
vnode.isOpened = true
|
||||||
// this.cam_controls.target = object.position
|
|
||||||
|
|
||||||
new TWEEN.Tween(this.controls.cam_target)
|
// new TWEEN.Tween(this.controls.cam_target)
|
||||||
.to(object.position, 400)
|
// .to(object.position, 400)
|
||||||
.start()
|
// .start()
|
||||||
|
//
|
||||||
// cam.position.set({ x: camPos.x, y: camPos.y, z: camPos.z })
|
// toPos = { ...object.position }
|
||||||
// camControls.update()
|
// toPos.z += 20
|
||||||
topos = { ...object.position }
|
// toPos.y = 5
|
||||||
topos.z += 20
|
// new TWEEN.Tween(camPos)
|
||||||
topos.y = 5
|
// .easing(TWEEN.Easing.Quadratic.InOut)
|
||||||
new TWEEN.Tween(camPos)
|
// .to(toPos, 3000)
|
||||||
.easing(TWEEN.Easing.Quadratic.InOut)
|
// .onUpdate(function () {
|
||||||
.to(topos, 3000)
|
// // console.log('tween update', this._object)
|
||||||
.onUpdate(function () {
|
// cam.position.set(this._object.x, this._object.y, this._object.z)
|
||||||
// console.log('tween update', this._object)
|
// // camControls.update()
|
||||||
cam.position.set(this._object.x, this._object.y, this._object.z)
|
// })
|
||||||
// camControls.update()
|
// .start()
|
||||||
})
|
|
||||||
.start()
|
|
||||||
|
|
||||||
// console.log('tween', tween)
|
// console.log('tween', tween)
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<mesh
|
<mesh
|
||||||
name="Plane"
|
name="Ground"
|
||||||
:position="position"
|
:position="position"
|
||||||
:rotation="{
|
:rotation="{
|
||||||
x:deg2rad(rotation.x),
|
x:deg2rad(rotation.x),
|
||||||
@@ -19,7 +19,7 @@ import mixins from 'components/mixins'
|
|||||||
import * as THREE from 'three'
|
import * as THREE from 'three'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Plan',
|
name: 'Ground',
|
||||||
mixins: [mixins],
|
mixins: [mixins],
|
||||||
props: {
|
props: {
|
||||||
size: Object,
|
size: Object,
|
||||||
Reference in New Issue
Block a user