mirror of
https://github.com/FMS-Cat/condition.git
synced 2025-08-27 07:14:47 +02:00
feature: add chaos torus
This commit is contained in:
84
src/automaton-fxs/ChaosTorus.ts
Normal file
84
src/automaton-fxs/ChaosTorus.ts
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
import { Entity } from '../heck/Entity';
|
||||||
|
import { Geometry } from '../heck/Geometry';
|
||||||
|
import { Material } from '../heck/Material';
|
||||||
|
import { Mesh, MeshCull } from '../heck/components/Mesh';
|
||||||
|
import { dummyRenderTarget } from '../globals/dummyRenderTarget';
|
||||||
|
import { genTorus } from '../geometries/genTorus';
|
||||||
|
import chaosTorusFrag from '../shaders/chaos-torus.frag';
|
||||||
|
import chaosTorusVert from '../shaders/chaos-torus.vert';
|
||||||
|
import depthFrag from '../shaders/depth.frag';
|
||||||
|
|
||||||
|
export class ChaosTorus extends Entity {
|
||||||
|
public constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// -- geometry ---------------------------------------------------------------------------------
|
||||||
|
const torus = genTorus( { segmentsRadial: 64, segmentsTubular: 8 } );
|
||||||
|
|
||||||
|
const geometry = new Geometry();
|
||||||
|
|
||||||
|
geometry.vao.bindVertexbuffer( torus.position, 0, 3 );
|
||||||
|
geometry.vao.bindVertexbuffer( torus.normal, 1, 3 );
|
||||||
|
geometry.vao.bindIndexbuffer( torus.index );
|
||||||
|
|
||||||
|
geometry.count = torus.count;
|
||||||
|
geometry.mode = torus.mode;
|
||||||
|
geometry.indexType = torus.indexType;
|
||||||
|
|
||||||
|
// -- materials --------------------------------------------------------------------------------
|
||||||
|
const cubemap = new Material(
|
||||||
|
chaosTorusVert,
|
||||||
|
chaosTorusFrag,
|
||||||
|
{
|
||||||
|
defines: [ 'FORWARD 1' ],
|
||||||
|
initOptions: { geometry, target: dummyRenderTarget },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const deferred = new Material(
|
||||||
|
chaosTorusVert,
|
||||||
|
chaosTorusFrag,
|
||||||
|
{
|
||||||
|
defines: [ 'DEFERRED 1' ],
|
||||||
|
initOptions: { geometry, target: dummyRenderTarget },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const depth = new Material(
|
||||||
|
chaosTorusVert,
|
||||||
|
depthFrag,
|
||||||
|
{ initOptions: { geometry, target: dummyRenderTarget } },
|
||||||
|
);
|
||||||
|
|
||||||
|
const materials = {
|
||||||
|
cubemap,
|
||||||
|
deferred,
|
||||||
|
depth,
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( process.env.DEV ) {
|
||||||
|
if ( module.hot ) {
|
||||||
|
module.hot.accept(
|
||||||
|
[
|
||||||
|
'../shaders/chaos-torus.vert',
|
||||||
|
'../shaders/chaos-torus.frag',
|
||||||
|
],
|
||||||
|
() => {
|
||||||
|
cubemap.replaceShader( chaosTorusVert, chaosTorusFrag );
|
||||||
|
deferred.replaceShader( chaosTorusVert, chaosTorusFrag );
|
||||||
|
depth.replaceShader( chaosTorusVert, depthFrag );
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- mesh -------------------------------------------------------------------------------------
|
||||||
|
const mesh = new Mesh( {
|
||||||
|
geometry,
|
||||||
|
materials,
|
||||||
|
name: process.env.DEV && 'ChaosTorus/mesh',
|
||||||
|
} );
|
||||||
|
mesh.cull = MeshCull.None;
|
||||||
|
this.components.push( mesh );
|
||||||
|
}
|
||||||
|
}
|
@@ -1,13 +1,16 @@
|
|||||||
|
import { ChaosTorus } from '../automaton-fxs/ChaosTorus';
|
||||||
import { Crystal } from './Crystal';
|
import { Crystal } from './Crystal';
|
||||||
import { Entity } from '../heck/Entity';
|
import { Entity } from '../heck/Entity';
|
||||||
import { Lambda } from '../heck/components/Lambda';
|
import { Lambda } from '../heck/components/Lambda';
|
||||||
import { Quaternion, Vector3 } from '@fms-cat/experimental';
|
import { Quaternion, Vector3, Xorshift } from '@fms-cat/experimental';
|
||||||
import { Rings } from './Rings';
|
import { Rings } from './Rings';
|
||||||
|
import { auto } from '../globals/automaton';
|
||||||
|
|
||||||
export class SceneCrystals extends Entity {
|
export class SceneCrystals extends Entity {
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
// -- crystals ---------------------------------------------------------------------------------
|
||||||
const crystal = new Crystal( { width: 0.4, height: 1.5, noiseOffset: 7.0 } );
|
const crystal = new Crystal( { width: 0.4, height: 1.5, noiseOffset: 7.0 } );
|
||||||
this.children.push( crystal );
|
this.children.push( crystal );
|
||||||
|
|
||||||
@@ -28,6 +31,7 @@ export class SceneCrystals extends Entity {
|
|||||||
speen.children.push( smolCrystal );
|
speen.children.push( smolCrystal );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -- rings ------------------------------------------------------------------------------------
|
||||||
const rings = new Rings();
|
const rings = new Rings();
|
||||||
rings.transform.rotation = Quaternion.fromAxisAngle(
|
rings.transform.rotation = Quaternion.fromAxisAngle(
|
||||||
new Vector3( [ 1.0, 0.0, 0.0 ] ),
|
new Vector3( [ 1.0, 0.0, 0.0 ] ),
|
||||||
@@ -37,5 +41,29 @@ export class SceneCrystals extends Entity {
|
|||||||
0.1,
|
0.1,
|
||||||
) );
|
) );
|
||||||
this.children.push( rings );
|
this.children.push( rings );
|
||||||
|
|
||||||
|
// -- chaos torus ------------------------------------------------------------------------------
|
||||||
|
const rng = new Xorshift( 618954 );
|
||||||
|
const chaosToruses = [ ...Array( 6 ).keys() ].map( () => {
|
||||||
|
const pivot = new Entity();
|
||||||
|
pivot.transform.rotation = Quaternion.fromAxisAngle(
|
||||||
|
new Vector3( [ 1.0, 0.0, 0.0 ] ),
|
||||||
|
rng.gen() * 6.0,
|
||||||
|
).multiply( Quaternion.fromAxisAngle(
|
||||||
|
new Vector3( [ 0.0, 1.0, 0.0 ] ),
|
||||||
|
rng.gen() * 6.0,
|
||||||
|
) );
|
||||||
|
this.children.push( pivot );
|
||||||
|
|
||||||
|
const chaosTorus = new ChaosTorus();
|
||||||
|
chaosTorus.transform.position = new Vector3( [ 2.5, 0.0, 0.0 ] );
|
||||||
|
pivot.children.push( chaosTorus );
|
||||||
|
|
||||||
|
return pivot;
|
||||||
|
} );
|
||||||
|
|
||||||
|
auto( 'SceneCrystals/ChaosTorus/active', ( { uninit } ) => {
|
||||||
|
chaosToruses.map( ( entity ) => ( entity.visible = !uninit ) );
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
58
src/shaders/chaos-torus.frag
Normal file
58
src/shaders/chaos-torus.frag
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
const int MTL_PBR = 2;
|
||||||
|
|
||||||
|
in float vLife;
|
||||||
|
in vec3 vNormal;
|
||||||
|
in vec4 vPosition;
|
||||||
|
in vec4 vPositionShaft;
|
||||||
|
|
||||||
|
#ifdef FORWARD
|
||||||
|
out vec4 fragColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEFERRED
|
||||||
|
layout (location = 0) out vec4 fragPosition;
|
||||||
|
layout (location = 1) out vec4 fragNormal;
|
||||||
|
layout (location = 2) out vec4 fragColor;
|
||||||
|
layout (location = 3) out vec4 fragWTF;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEPTH
|
||||||
|
out vec4 fragColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform float time;
|
||||||
|
uniform vec2 cameraNearFar;
|
||||||
|
uniform vec3 cameraPos;
|
||||||
|
|
||||||
|
#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 noisep = vNormal.xyz + 4.0 * time + atan( vPositionShaft.x, vPositionShaft.z );
|
||||||
|
float noise = cyclicNoise( 4.0 * noisep ).x;
|
||||||
|
|
||||||
|
if ( noise < 0.0 ) { discard; }
|
||||||
|
|
||||||
|
#ifdef FORWARD
|
||||||
|
fragColor = vec4( 8.0 * vec3( 0.1, 0.4, 1.0 ), 1.0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEFERRED
|
||||||
|
fragPosition = vPosition;
|
||||||
|
fragNormal = vec4( normalize( vNormal ), 1.0 );
|
||||||
|
fragColor = vec4( vec3( 0.001 ), 1.0 );
|
||||||
|
fragWTF = vec4( vec3( 0.99, 0.01, 0.0 ), MTL_PBR );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEPTH
|
||||||
|
float depth = linearstep(
|
||||||
|
cameraNearFar.x,
|
||||||
|
cameraNearFar.y,
|
||||||
|
length( cameraPos - vPosition.xyz )
|
||||||
|
);
|
||||||
|
fragColor = vec4( depth, depth * depth, depth, 1.0 );
|
||||||
|
#endif
|
||||||
|
}
|
41
src/shaders/chaos-torus.vert
Normal file
41
src/shaders/chaos-torus.vert
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#version 300 es
|
||||||
|
|
||||||
|
const float TAU = 6.283185307;
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 position;
|
||||||
|
layout (location = 1) in vec3 normal;
|
||||||
|
|
||||||
|
out vec4 vPositionShaft;
|
||||||
|
out vec4 vPosition;
|
||||||
|
out vec3 vNormal;
|
||||||
|
|
||||||
|
uniform float time;
|
||||||
|
uniform vec2 resolution;
|
||||||
|
uniform mat4 projectionMatrix;
|
||||||
|
uniform mat4 viewMatrix;
|
||||||
|
uniform mat4 modelMatrix;
|
||||||
|
uniform mat4 normalMatrix;
|
||||||
|
|
||||||
|
#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
|
||||||
|
|
||||||
|
mat2 rotate2D( float t ) {
|
||||||
|
return mat2( cos( t ), sin( t ), -sin( t ), cos( t ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vNormal = normalize( ( normalMatrix * vec4( normal, 1.0 ) ).xyz );
|
||||||
|
|
||||||
|
vPosition = vPositionShaft = vec4( 3.0 * position, 1.0 );
|
||||||
|
vPosition.xyz += 0.3 * normal;
|
||||||
|
|
||||||
|
vec3 noisep = vNormal.xyz + time + atan( vPositionShaft.x, vPositionShaft.z );
|
||||||
|
vPosition.xyz += 0.5 * cyclicNoise( noisep + 3.0 );
|
||||||
|
|
||||||
|
vPosition = modelMatrix * vPosition;
|
||||||
|
|
||||||
|
vec4 outPos = projectionMatrix * viewMatrix * vPosition;
|
||||||
|
outPos.x *= resolution.y / resolution.x;
|
||||||
|
gl_Position = outPos;
|
||||||
|
|
||||||
|
vPosition.w = outPos.z / outPos.w;
|
||||||
|
}
|
Reference in New Issue
Block a user