mirror of
https://github.com/FMS-Cat/condition.git
synced 2025-08-21 20:55:58 +02:00
feature: add a cube
This commit is contained in:
85
src/entities/Cube.ts
Normal file
85
src/entities/Cube.ts
Normal 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
81
src/geometries/genCube.ts
Normal 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
|
||||||
|
};
|
||||||
|
}
|
16
src/main.ts
16
src/main.ts
@@ -26,6 +26,7 @@ import { FlickyParticles } from './entities/FlickyParticles';
|
|||||||
import { PixelSorter } from './entities/PixelSorter';
|
import { PixelSorter } from './entities/PixelSorter';
|
||||||
import { IBLLUT } from './entities/IBLLUT';
|
import { IBLLUT } from './entities/IBLLUT';
|
||||||
import { EnvironmentMap } from './entities/EnvironmentMap';
|
import { EnvironmentMap } from './entities/EnvironmentMap';
|
||||||
|
import { Cube } from './entities/Cube';
|
||||||
|
|
||||||
// == music ========================================================================================
|
// == music ========================================================================================
|
||||||
const audio = new AudioContext();
|
const audio = new AudioContext();
|
||||||
@@ -203,12 +204,12 @@ const environmentMap = new EnvironmentMap();
|
|||||||
dog.root.children.push( environmentMap.entity );
|
dog.root.children.push( environmentMap.entity );
|
||||||
|
|
||||||
// -- "objects" ------------------------------------------------------------------------------------
|
// -- "objects" ------------------------------------------------------------------------------------
|
||||||
const sphereParticles = new SphereParticles( {
|
// const sphereParticles = new SphereParticles( {
|
||||||
particlesSqrt: 256,
|
// particlesSqrt: 256,
|
||||||
textureRandom: randomTexture.texture,
|
// textureRandom: randomTexture.texture,
|
||||||
textureRandomStatic: randomTextureStatic.texture
|
// textureRandomStatic: randomTextureStatic.texture
|
||||||
} );
|
// } );
|
||||||
dog.root.children.push( sphereParticles.entity );
|
// dog.root.children.push( sphereParticles.entity );
|
||||||
|
|
||||||
// const trails = new Trails( {
|
// const trails = new Trails( {
|
||||||
// trails: 4096,
|
// trails: 4096,
|
||||||
@@ -221,6 +222,9 @@ dog.root.children.push( sphereParticles.entity );
|
|||||||
const rings = new Rings();
|
const rings = new Rings();
|
||||||
dog.root.children.push( rings.entity );
|
dog.root.children.push( rings.entity );
|
||||||
|
|
||||||
|
const cube = new Cube();
|
||||||
|
dog.root.children.push( cube.entity );
|
||||||
|
|
||||||
const flickyParticles = new FlickyParticles( {
|
const flickyParticles = new FlickyParticles( {
|
||||||
particlesSqrt: 8,
|
particlesSqrt: 8,
|
||||||
textureRandom: randomTexture.texture,
|
textureRandom: randomTexture.texture,
|
||||||
|
41
src/shaders/cube.frag
Normal file
41
src/shaders/cube.frag
Normal 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
32
src/shaders/cube.vert
Normal 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;
|
||||||
|
}
|
Reference in New Issue
Block a user