feature: add a cube

This commit is contained in:
FMS-Cat
2021-03-15 01:39:25 +09:00
parent 0630b728f1
commit 350f84acb3
5 changed files with 249 additions and 6 deletions

85
src/entities/Cube.ts Normal file
View File

@@ -0,0 +1,85 @@
import { Quaternion, Vector3 } from '@fms-cat/experimental';
import { Mesh } from '../heck/components/Mesh';
import { Entity } from '../heck/Entity';
import { Geometry } from '../heck/Geometry';
import { Material } from '../heck/Material';
import cubeVert from '../shaders/cube.vert';
import cubeFrag from '../shaders/cube.frag';
import { genCube } from '../geometries/genCube';
import { Lambda } from '../heck/components/Lambda';
export class Cube {
public mesh: Mesh;
public geometry: Geometry;
public material: Material;
public entity: Entity;
public constructor() {
this.entity = new Entity();
this.entity.transform.rotation = Quaternion.fromAxisAngle(
new Vector3( [ 1.0, 0.0, 0.0 ] ),
0.4,
).multiply( Quaternion.fromAxisAngle(
new Vector3( [ 0.0, 0.0, 1.0 ] ),
0.4,
) );
this.entity.transform.scale = this.entity.transform.scale.scale( 0.8 );
this.geometry = this.__createGeometry();
this.material = this.__createMaterial();
this.mesh = new Mesh( {
geometry: this.geometry,
material: this.material,
name: process.env.DEV && 'Cube/mesh',
} );
this.entity.components.push( this.mesh );
this.entity.components.push( new Lambda( {
onUpdate: ( { deltaTime } ) => {
this.entity.transform.rotation = this.entity.transform.rotation.multiply(
Quaternion.fromAxisAngle( new Vector3( [ 0.0, 1.0, 0.0 ] ), deltaTime )
);
},
visible: false,
} ) );
}
private __createGeometry(): Geometry {
const cube = genCube();
const geometry = new Geometry();
geometry.addAttribute( 'position', cube.position );
geometry.addAttribute( 'normal', cube.normal );
geometry.setIndex( cube.index );
geometry.count = cube.count;
geometry.mode = cube.mode;
return geometry;
}
private __createMaterial(): Material {
const material = new Material( cubeVert, cubeFrag );
material.addUniform( 'inflate', '1f', 0.01 );
if ( process.env.DEV ) {
if ( module.hot ) {
module.hot.accept(
[
'../shaders/cube.vert',
'../shaders/cube.frag',
],
() => {
material.replaceShader( cubeVert, cubeFrag );
},
);
}
}
return material;
}
}

81
src/geometries/genCube.ts Normal file
View File

@@ -0,0 +1,81 @@
import { gl, glCat } from '../heck/canvas';
import { GeometryAttribute, GeometryIndex } from '../heck/Geometry';
interface ResultGenCube {
position: GeometryAttribute;
normal: GeometryAttribute;
index: GeometryIndex;
count: number;
mode: GLenum;
}
export function genCube(): ResultGenCube {
const pos: number[] = [];
const nor: number[] = [];
const ind: number[] = [];
const p = [
[ -1, -1, 1 ],
[ 1, -1, 1 ],
[ -1, 1, 1 ],
[ 1, 1, 1 ],
];
const n = [
[ 0, 0, 1 ],
[ 0, 0, 1 ],
[ 0, 0, 1 ],
[ 0, 0, 1 ],
];
for ( let i = 0; i < 6; i ++ ) {
let func = ( v: number[] ) => {
const vt: number[] = [];
if ( i < 4 ) {
const t = i * Math.PI / 2.0;
vt[ 0 ] = Math.cos( t ) * v[ 0 ] - Math.sin( t ) * v[ 2 ];
vt[ 1 ] = v[ 1 ];
vt[ 2 ] = Math.sin( t ) * v[ 0 ] + Math.cos( t ) * v[ 2 ];
} else {
const t = ( i - 0.5 ) * Math.PI;
vt[ 0 ] = v[ 0 ];
vt[ 1 ] = Math.cos( t ) * v[ 1 ] - Math.sin( t ) * v[ 2 ];
vt[ 2 ] = Math.sin( t ) * v[ 1 ] + Math.cos( t ) * v[ 2 ];
}
return vt;
};
pos.push( ...p.map( func ).flat() );
nor.push( ...n.map( func ).flat() );
ind.push( ...[ 0, 1, 3, 0, 3, 2 ].map( ( v ) => v + 4 * i ) );
}
const position: GeometryAttribute = {
buffer: glCat.createBuffer(),
type: gl.FLOAT,
size: 3
};
position.buffer.setVertexbuffer( new Float32Array( pos ) );
const normal: GeometryAttribute = {
buffer: glCat.createBuffer(),
type: gl.FLOAT,
size: 3
};
normal.buffer.setVertexbuffer( new Float32Array( nor ) );
const index: GeometryIndex = {
buffer: glCat.createBuffer(),
type: gl.UNSIGNED_SHORT
};
index.buffer.setIndexbuffer( new Uint16Array( ind ) );
return {
position,
normal,
index,
count: ind.length,
mode: gl.TRIANGLES
};
}

View File

@@ -26,6 +26,7 @@ import { FlickyParticles } from './entities/FlickyParticles';
import { PixelSorter } from './entities/PixelSorter';
import { IBLLUT } from './entities/IBLLUT';
import { EnvironmentMap } from './entities/EnvironmentMap';
import { Cube } from './entities/Cube';
// == music ========================================================================================
const audio = new AudioContext();
@@ -203,12 +204,12 @@ const environmentMap = new EnvironmentMap();
dog.root.children.push( environmentMap.entity );
// -- "objects" ------------------------------------------------------------------------------------
const sphereParticles = new SphereParticles( {
particlesSqrt: 256,
textureRandom: randomTexture.texture,
textureRandomStatic: randomTextureStatic.texture
} );
dog.root.children.push( sphereParticles.entity );
// const sphereParticles = new SphereParticles( {
// particlesSqrt: 256,
// textureRandom: randomTexture.texture,
// textureRandomStatic: randomTextureStatic.texture
// } );
// dog.root.children.push( sphereParticles.entity );
// const trails = new Trails( {
// trails: 4096,
@@ -221,6 +222,9 @@ dog.root.children.push( sphereParticles.entity );
const rings = new Rings();
dog.root.children.push( rings.entity );
const cube = new Cube();
dog.root.children.push( cube.entity );
const flickyParticles = new FlickyParticles( {
particlesSqrt: 8,
textureRandom: randomTexture.texture,

41
src/shaders/cube.frag Normal file
View File

@@ -0,0 +1,41 @@
#version 300 es
precision highp float;
const int MTL_PBR = 2;
in float vLife;
in vec3 vNormal;
in vec4 vPosition;
in vec4 vPositionWithoutModel;
layout (location = 0) out vec4 fragPosition;
layout (location = 1) out vec4 fragNormal;
layout (location = 2) out vec4 fragColor;
layout (location = 3) out vec4 fragWTF;
#pragma glslify: noise = require( ./-simplex4d );
uniform float time;
float fbm( vec4 p ) {
float v = 0.5 * noise( 1.0 * p );
v += 0.25 * noise( 2.0 * p );
v += 0.125 * noise( 4.0 * p );
v += 0.0625 * noise( 8.0 * p );
return v;
}
void main() {
float rough = smoothstep( -0.6, 0.6, fbm( vPositionWithoutModel ) );
// vec3 ndisp = rough * 0.2 * vec3(
// fbm( 1.577 + 4.0 * vPosition ),
// fbm( 12.577 + 4.0 * vPosition ),
// fbm( 27.577 + 4.0 * vPosition )
// );
fragPosition = vPosition;
fragNormal = vec4( normalize( vNormal ), 1.0 );
fragColor = vec4( vec3( 0.5 - 0.3 * rough ), 1.0 );
fragWTF = vec4( vec3( 0.3 + 0.2 * rough, 0.9, 0.0 ), MTL_PBR );
}

32
src/shaders/cube.vert Normal file
View File

@@ -0,0 +1,32 @@
#version 300 es
in vec3 position;
in vec3 normal;
in vec2 uv;
out vec4 vPositionWithoutModel;
out vec4 vPosition;
out vec3 vNormal;
out vec2 vUv;
uniform vec2 resolution;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 normalMatrix;
// ------
void main() {
vNormal = normalize( ( normalMatrix * vec4( normal, 1.0 ) ).xyz );
vPositionWithoutModel = vec4( position, 1.0 );
vPosition = modelMatrix * vPositionWithoutModel;
vec4 outPos = projectionMatrix * viewMatrix * vPosition;
outPos.x *= resolution.y / resolution.x;
gl_Position = outPos;
vPosition.w = outPos.z / outPos.w;
vUv = uv;
}