created stage atlas+meshes, simplifying models and materials

This commit is contained in:
Diego F. Goberna
2018-11-30 20:33:05 +01:00
committed by Diego Marcos
parent 30c3abd2da
commit 8c98df87e2
18 changed files with 2627 additions and 40 deletions

View File

@@ -13,9 +13,20 @@
<a-asset-item id="mineBrokenObj" src="assets/models/minebroken.obj"></a-asset-item>
<a-asset-item id="mineParticlesJSON" src="assets/models/mineparticles.json"></a-asset-item>
<a-asset-item id="saberParticlesJSON" src="assets/models/sabercut.json"></a-asset-item>
<!--
<a-asset-item id="stageNeonObj" src="assets/models/neons.obj"></a-asset-item>
<a-asset-item id="tunnelObj" src="assets/models/tunnel.obj"></a-asset-item>
<a-asset-item id="tunnelNeonObj" src="assets/models/tunnelneon.obj"></a-asset-item>
-->
<a-asset-item id="stageObj" src="assets/models/stage.obj"></a-asset-item>
<a-asset-item id="stageAdditiveObj" src="assets/models/stageadditive.obj"></a-asset-item>
<a-asset-item id="stepbackObj" src="assets/models/stepback.obj"></a-asset-item>
<a-asset-item id="missObj" src="assets/models/miss.obj"></a-asset-item>
<a-asset-item id="wrongObj" src="assets/models/wrong.obj"></a-asset-item>
<a-asset-item id="smokeObj" src="assets/models/smoke.obj"></a-asset-item>
<a-asset-item id="audiocolumnObj" src="assets/models/audiocolumn.obj"></a-asset-item>
<a-asset-item id="tutorial1Obj" src="assets/models/tutorial1.obj"></a-asset-item>
<a-asset-item id="tutorial2Obj" src="assets/models/tutorial2.obj"></a-asset-item>
<a-asset-item id="tutorial3Obj" src="assets/models/tutorial3.obj"></a-asset-item>
@@ -33,31 +44,29 @@
<audio id="hitSound{{ i }}right" src="assets/sounds/hit{{ i }}right.ogg"></audio>
{% endfor %}
<img id="skyTexture" src="assets/img/sky.jpg">
<img id="backglowTexture" src="assets/img/backglow.png">
<img id="cursorMeshImg" src="assets/models/laser/laser.png">
<img id="downIconImg" src="assets/img/downIcon.png">
<img id="envmapTexture" src="assets/img/envMap.png">
<img id="envmapWallTexture" src="assets/img/envmapwall.jpg">
<img id="floorImg" src="assets/img/floor.png">
<img id="neonImg" src="assets/img/neon.png">
<img id="gridImg" src="assets/img/grid.png">
<img id="playImg" src="assets/img/play.png">
<img id="skyTexture" src="assets/img/sky.jpg">
<img id="sliceImg" src="assets/img/slice.png">
<img id="slicebtnImg" src="assets/img/slicebtn.png">
<img id="smokeTexture" src="assets/img/smoke.png">
<img id="beamImg" src="assets/img/beam.png">
<img id="wrongImg" src="assets/img/wrong.png">
<img id="missImg" src="assets/img/miss.png">
<img id="noiseTexture" src="assets/img/noise.png">
<img id="neonImg" src="assets/img/neon.png">
<img id="sparkImg" src="assets/img/spark.png">
<img id="spark2Img" src="assets/img/spark2.png">
<img id="stepbackImg" src="assets/img/stepback.png">
<img id="soundboxingImg" src="assets/img/soundboxing.png">
<img id="genresImg" src="assets/img/genres.png">
<img id="tutorialImg" src="assets/img/tutorial.png">
<img id="floorEnvImg" src="assets/img/floorenv.jpg">
<img id="floorNormalsImg" src="assets/img/floornormals.png">
<img id="atlasImg" src="assets/img/atlas.png">
<a-mixin id="slice" slice9="color: #050505; transparent: true; opacity: 0.7; src: #sliceImg; left: 50; right: 52; top: 50; bottom: 52; padding: 0.18"></a-mixin>
<a-mixin id="font" text="font: assets/fonts/Teko-Bold.json; shader: msdf; letterSpacing: 1"></a-mixin>
@@ -119,15 +128,15 @@
<a-mixin
id="beatWrong"
geometry="primitive: plane; height: 0.3; width: 0.3"
material="shader: flat; transparent: true; src: #wrongImg"
obj-model="obj: #wrongObj"
material="shader: flat; transparent: true; src: #atlasImg"
visible="false"
animation__posz="property: object3D.position.z; to: -8; startEvents: beatwrong; easing: easeOutQuart; dur: 4000"
animation__alpha="property: components.material.material.opacity; from: 1; to: 0; startEvents: beatwrong; easing: easeOutQuart; dur: 4000"></a-mixin>
<a-mixin id="beatMiss"
geometry="primitive: plane; height: 0.25; width: 0.5"
material="shader: flat; transparent: true; src: #missImg"
obj-model="obj: #missObj"
material="shader: flat; transparent: true; src: #atlasImg"
visible="false"
animation__posz="property: object3D.position.z; to: -8; startEvents: beatmiss; easing: easeOutQuart; dur: 4000"
animation__alpha="property: components.material.material.opacity; from: 1; to: 0; startEvents: beatmiss; easing: easeOutQuart; dur: 4000"></a-mixin>

View File

@@ -1,9 +1,5 @@
/**
* 72 values per box.
* Divided by 3 (x, y, z) is 24 vertices.
* 6 vertices per side of the cube (2 faces per side).
*/
const NUM_VALUES_PER_BOX = 72;
const NUM_VALUES_PER_BOX = 90;
/**
* Column bars moving in sync to the audio via audio analyser.
@@ -19,6 +15,10 @@ AFRAME.registerComponent('audio-columns', {
},
init: function () {
var objData = document.getElementById('audiocolumnObj').data;
var loader = new THREE.OBJLoader();
var columnGeometry = loader.parse(objData).children[0].geometry;
this.analyser = this.data.analyser.components.audioanalyser;
// Number of levels is half the FFT size.
@@ -29,7 +29,7 @@ AFRAME.registerComponent('audio-columns', {
let zPosition = 0;
for (let i = 0; i < this.frequencyBinCount; i++) {
for (let side = 0; side < 2; side++) {
const box = new THREE.BoxBufferGeometry();
const box = columnGeometry.clone();
this.initBox(box, side === 0 ? 1 : -1, zPosition);
geometries.push(box);
// Move Z back.
@@ -38,7 +38,7 @@ AFRAME.registerComponent('audio-columns', {
}
this.geometry = THREE.BufferGeometryUtils.mergeBufferGeometries(geometries);
const mesh = new THREE.Mesh(this.geometry, this.el.sceneEl.systems.materials.black);
const mesh = new THREE.Mesh(this.geometry, this.el.sceneEl.systems.materials.stageNormal);
this.el.setObject3D('mesh', mesh);
},
@@ -63,8 +63,8 @@ AFRAME.registerComponent('audio-columns', {
// Set position and scale of box via vertices.
for (let v = 0; v < box.attributes.position.array.length; v += 3) {
// Apply thickness to X and Z.
box.attributes.position.array[v] *= data.thickness;
box.attributes.position.array[v + 2] *= data.thickness;
//box.attributes.position.array[v] *= data.thickness;
//box.attributes.position.array[v + 2] *= data.thickness;
// Apply zPosition.
box.attributes.position.array[v + 2] += zPosition;

View File

@@ -1,6 +1,6 @@
AFRAME.registerShader('floorShader', {
schema: {
src: {type: 'map', is: 'uniform'},
color: {type: 'vec3', is: 'uniform', default: {x: 0, y: 0, z: 0}},
normalMap: {type: 'map', is: 'uniform'},
envMap: {type: 'map', is: 'uniform'},
hitRight: {type: 'vec3', is: 'uniform', default: {x: 0, y: 1, z: 0}},
@@ -21,7 +21,7 @@ AFRAME.registerShader('floorShader', {
fragmentShader: `
varying vec2 uvs;
varying vec3 worldPos;
uniform sampler2D src;
uniform vec3 color;
uniform sampler2D normalMap;
uniform sampler2D envMap;
uniform vec3 hitRight;
@@ -33,9 +33,12 @@ AFRAME.registerShader('floorShader', {
void main() {
vec2 p = uvs.xy - 0.5;
float border = smoothstep(0.49, 0.495, abs(p.x)) + smoothstep(0.49, 0.495, abs(p.y));
p*= 4.0;
vec3 col = texture2D(src, uvs).xyz;
vec3 col = color;
vec3 col2 = color;
vec4 outColor;
col += drawCircle(worldPos, hitRight, 0.04, 0.05, vec3(1.0, 0.4, 0.4));
col += drawCircle(worldPos, hitRight, 0.02, 0.005, vec3(1.0, 1.0, 1.0));
@@ -48,7 +51,11 @@ AFRAME.registerShader('floorShader', {
vec3 reflectVec = normalize(reflect(normalize(worldPos - cameraPosition), normal));
//vec3 reflectView = normalize((viewMatrix * vec4(reflectVec, 0.0)).xyz + vec3(0.0, 0.0, 1.0));
gl_FragColor = vec4(texture2D(envMap, reflectVec.xy * vec2(0.3, 1.0) + vec2(0.75, -cameraPosition.z * 0.05)).xyz * 0.08 + col, 0.9 + col.x);
col2 = texture2D(envMap, reflectVec.xy * vec2(0.3, 1.0) + vec2(0.75, -cameraPosition.z * 0.05)).xyz * 0.08 + col;
outColor = smoothstep(vec4(col2, 0.9 + col.x), vec4(1.0), vec4(border));
gl_FragColor = outColor;
}
`
});

View File

@@ -1,20 +1,57 @@
const stageShaders = require('../../assets/shaders/stage.js')
AFRAME.registerSystem('materials', {
init: function () {
this.black = new THREE.MeshLambertMaterial({color: 0x000000, flatShading: true});
this.default = new THREE.MeshLambertMaterial({color: 0xff0000, flatShading: true});
this.neon = new THREE.MeshBasicMaterial({color: 0x9999ff, fog: false});
this.stageNormal = new THREE.ShaderMaterial({
uniforms: {
color: {value: new THREE.Vector3(0, 0, 0) },
fogColor: {value: new THREE.Vector3(0, 0.48, 0.72) },
src: {value: new THREE.TextureLoader().load(document.getElementById('atlasImg').src)},
},
vertexShader: stageShaders.vertexShader,
fragmentShader: stageShaders.fragmentShader,
fog: false,
transparent: true
});
}
});
AFRAME.registerComponent('materials', {
schema: {
default: 'black',
oneOf: ['black', 'default', 'neon']
name: { default: ''},
recursive: { default: true}
},
update: function () {
this.el.object3D.traverse(o => {
o.material = this.system[this.data]
});
var mesh;
var material = this.system[this.data.name];
if (!material) {
console.warn(`undefined material "${this.system[this.data.name]}"`);
return;
}
mesh = this.el.getObject3D('mesh');
if (!mesh) {
console.log('not loaded yet');
this.el.addEventListener('model-loaded', this.applyMaterial.bind(this));
} else {
this.applyMaterial(mesh);
}
},
applyMaterial: function (obj, material) {
var material = this.system[this.data.name];
if (this.data.recursive) {
obj.detail.model.traverse(o => {
if (o.type === 'Mesh') {
o.material = material;
}
});
} else {
obj.material = material;
}
}
});

View File

@@ -0,0 +1,35 @@
AFRAME.registerShader('stageShader', {
schema: {
color: {type: 'vec3', is: 'uniform', default: {x: 0, y: 0, z: 0}},
fogColor: {type: 'vec3', is: 'uniform', default: {x: 0, y: 0.48, z: 0.72}},
src: {type: 'map', is: 'uniform'},
},
vertexShader: `
varying vec2 uvs;
varying vec3 worldPos;
void main() {
uvs.xy = uv.xy;
vec4 p = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
worldPos = (modelMatrix * vec4( position, 1.0 )).xyz;
gl_Position = p;
}
`,
fragmentShader: `
#define FOG_RADIUS 50.0
#define FOG_FALLOFF 45.0
varying vec2 uvs;
varying vec3 worldPos;
uniform vec3 color;
uniform vec3 fogColor;
uniform sampler2D src;
void main() {
vec4 col = texture2D(src, uvs);
col.xyz = mix(fogColor, col.xyz, clamp(distance(worldPos, vec3(0., 0., -FOG_RADIUS)) / FOG_FALLOFF, 0., 1.));
gl_FragColor = col;
}
`
});

View File

@@ -17,6 +17,7 @@
<audio id="introSong" src="assets/sounds/introSong.ogg" loop></audio>
<a-scene
stats
mixin="gameoverAnimation fogAnimation"
bind__beat-loader="challengeId: challenge.id; difficulty: menuSelectedChallenge.difficulty; isPlaying: isPlaying; menuSelectedChallengeId: menuSelectedChallenge.id"
bind__gameover="isGameOver: isGameOver"
@@ -224,9 +225,9 @@
<a-entity
id="stepback"
class="overlay"
geometry="primitive: plane; width: 0.5; height: 0.25;"
obj-model="obj: #stepbackObj"
position="0 1.6 -1.55"
material="shader: flat; src: #stepbackImg; transparent: true; opacity: 0"></a-entity>
material="shader: flat; src: #atlasImg; transparent: true; opacity: 0"></a-entity>
{% if not IS_PRODUCTION %}
<a-entity

View File

@@ -64,7 +64,7 @@ AFRAME.registerState({
leaderboardQualified: false,
leaderboardNames: '',
leaderboardScores: '',
menuActive: true, // Main menu active.
menuActive: false, // Main menu active.
menuDifficulties: [], // List of strings of available difficulties for selected.
menuSelectedChallenge: { // Currently selected challenge in the main menu.
author: '',

View File

@@ -25,6 +25,7 @@
<a-sky
id="sky"
visible="false"
mixin="gameoverAnimation bgAnimation"
animation__gameover="property: components.material.material.color; type: color; to: #301000; startEvents: gameover"
geometry="segmentsHeight: 16; segmentsWidth: 32"
@@ -37,12 +38,14 @@
proxy-event="event: audioanalyserbeat; to: #logolight"></a-entity>
<a-entity id="stage">
<a-entity id="backglow"
visible="false"
mixin="gameoverAnimation bgAnimation"
animation__gameover="property: components.material.material.opacity; to: 0.2; startEvents: gameover"
obj-model="obj: #backglowObj"
material="transparent: true; color: #f00; src: #backglowTexture; opacity: 0.7"
position="0 0 -50"
position="0 0 -60"
scale="20 20 20"></a-entity>
<a-entity id="twister" position="0 0 -35" rotation="90 0 0" bind__twister="enabled: isPlaying"></a-entity>
@@ -52,15 +55,14 @@
audio-columns="analyser: #audioAnalyser; height: 28; mirror: 18; scale: 9; thickness: 0.6; separation: 0.55"
position="0 -19 5"></a-entity>
<!--
<a-mixin id="corridor" geometry="skipCache: true" vertex-colors-buffer="baseColor: #010101" visible="false"></a-mixin>
<a-entity id="stageCorridor" buffer-geometry-merger material="shader: flat; flatShading: true; vertexColors: vertex">
<!-- Corridor. -->
<a-entity mixin="corridor" geometry="height: 0.3; depth: 50; width: 4.1" position="0 0 -31.85"></a-entity>
<a-entity mixin="corridor" geometry="height: 20; depth: 0.3; width: 0.3" position="1.9 -9.97 -7"></a-entity>
<a-entity mixin="corridor" geometry="height: 20; depth: 0.3; width: 0.3" position="-1.9 -9.97 -7"></a-entity>
<a-entity mixin="corridor" geometry="height: 0.3; depth: 50; width: 0.3" position="1.9 -1 -31.85"></a-entity>
<a-entity mixin="corridor" geometry="height: 0.3; depth: 50; width: 0.3" position="-1.9 -1 -31.85"></a-entity>
<!-- Corridor handrail. -->
<a-entity mixin="corridor" geometry="height: 21.5; depth: 0.2; width: 0.2" position="3.5 -10 -7"></a-entity>
<a-entity mixin="corridor" geometry="height: 21.5; depth: 0.2; width: 0.2" position="-3.5 -10 -7"></a-entity>
</a-entity>
@@ -80,6 +82,16 @@
id="stageNeon"
mixin="neonAnimation"
obj-model="obj: #stageNeonObj"></a-entity>
-->
<a-entity
id="stageobj"
obj-model="obj: #stageObj"
materials="name: stageNormal"></a-entity>
<a-entity
id="stageadditiveobj"
obj-model="obj: #stageAdditiveObj"
material="shader: flat; color: #f00; src: #atlasImg; transparent: true; blending: additive; depthWrite: false; fog: false"></a-entity>
<!-- Lasers left. -->
<a-entity id="leftStageLasers" bind__stage-lasers="enabled: isPlaying">
@@ -100,13 +112,12 @@
<a-mixin
id="smoke"
mixin="gameoverAnimation"
additive
animation__gameover="property: components.material.material.opacity; to: 0; startEvents: gameover"
animation__rotate="property: rotation; to: 0 360 0; easing: linear; loop: true"
geometry="primitive: cylinder; height: 30"
material="src: #smokeTexture; repeat: 2 1; side: double; fog: true; shader: flat; transparent: true; color: #111"></a-mixin>
<a-entity id="smoke1" mixin="smoke" geometry="radius: 10" position="0 1.4 0" animation__rotate="dur: 200000"></a-entity>
<a-entity id="smoke2" mixin="smoke" geometry="radius: 20" position="0 1.8 0" animation__rotate="dur: 243000"></a-entity>
obj-model="obj:#smokeObj"
material="src: #atlasImg; fog: false; shader: flat; transparent: true"></a-mixin>
<a-entity id="smoke1" mixin="smoke" position="0 1.4 0" animation__rotate="dur: 200000"></a-entity>
<a-entity id="smoke2" mixin="smoke" position="0 1.8 0" scale="1.25 0.8 1.25" animation__rotate="dur: 243000"></a-entity>
<a-entity light="type: directional; intensity: 3" position="0 10 10"></a-entity>
@@ -124,13 +135,15 @@
<a-entity id="logoFrontU" obj-model="obj: #logofrontUObj" material="color: #e81e23" logoflicker="delay: 1200" bind__logoflicker="active: menuActive || isVictory"></a-entity>
</a-entity>
<!-- material="color: #030303" -->
<a-entity
id="floor"
data-saber-particles
geometry="primitive: plane; width: 3; height: 3"
material="shader: floorShader; src: #floorImg; normalMap: #floorNormalsImg; envMap: #floorEnvImg; hitRight: -999 0 0; hitLeft: -999 0 0"
rotation="-90 0 0"
raycastable-game
rotation="-90 0 0"
material="shader: floorShader; color: #f33; normalMap: #floorNormalsImg; envMap: #floorEnvImg"
stepback></a-entity>
<a-entity