mirror of
https://github.com/FMS-Cat/condition.git
synced 2025-08-20 04:11:41 +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 { 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
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