mirror of
https://github.com/FMS-Cat/condition.git
synced 2025-08-21 12:51:57 +02:00
greetings and stuff
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -3,7 +3,7 @@ export const
|
|||||||
// RTINSPECTOR_MULTIPLE = true,
|
// RTINSPECTOR_MULTIPLE = true,
|
||||||
RTINSPECTOR_CAPTURE_NAME: string | null = null,
|
RTINSPECTOR_CAPTURE_NAME: string | null = null,
|
||||||
// RTINSPECTOR_CAPTURE_NAME: string | null = 'PixelSorter/index',
|
// RTINSPECTOR_CAPTURE_NAME: string | null = 'PixelSorter/index',
|
||||||
// RTINSPECTOR_CAPTURE_NAME: string | null = 'Bloom/swap1',
|
// RTINSPECTOR_CAPTURE_NAME: string | null = 'Greetings/intermediate0',
|
||||||
// RTINSPECTOR_CAPTURE_NAME: string | null = 'main/postSwap0',
|
// RTINSPECTOR_CAPTURE_NAME: string | null = 'main/postSwap0',
|
||||||
// RTINSPECTOR_CAPTURE_NAME: string | null = 'DeferredCamera/cameraTarget',
|
// RTINSPECTOR_CAPTURE_NAME: string | null = 'DeferredCamera/cameraTarget',
|
||||||
RTINSPECTOR_CAPTURE_INDEX = 0,
|
RTINSPECTOR_CAPTURE_INDEX = 0,
|
||||||
|
@@ -5,7 +5,7 @@ export const
|
|||||||
AO_RESOLUTION_RATIO = 1.0,
|
AO_RESOLUTION_RATIO = 1.0,
|
||||||
RESOLUTION = [ 1280, 720 ],
|
RESOLUTION = [ 1280, 720 ],
|
||||||
MUSIC_BPM = 180,
|
MUSIC_BPM = 180,
|
||||||
START_POSITION = 45,
|
START_POSITION = 112,
|
||||||
MUSIC_LENGTH = 213,
|
MUSIC_LENGTH = 213,
|
||||||
MUSIC_AUTOMATON_TEXTURE_HEIGHT = 16,
|
MUSIC_AUTOMATON_TEXTURE_HEIGHT = 16,
|
||||||
IBLLUT_ITER = 400,
|
IBLLUT_ITER = 400,
|
||||||
|
@@ -4,12 +4,12 @@ import { Entity } from '../heck/Entity';
|
|||||||
import { Material } from '../heck/Material';
|
import { Material } from '../heck/Material';
|
||||||
import { Quad } from '../heck/components/Quad';
|
import { Quad } from '../heck/components/Quad';
|
||||||
import { RenderTarget } from '../heck/RenderTarget';
|
import { RenderTarget } from '../heck/RenderTarget';
|
||||||
|
import { auto } from '../globals/automaton';
|
||||||
import { dummyRenderTarget } from '../globals/dummyRenderTarget';
|
import { dummyRenderTarget } from '../globals/dummyRenderTarget';
|
||||||
import { quadGeometry } from '../globals/quadGeometry';
|
import { quadGeometry } from '../globals/quadGeometry';
|
||||||
import { randomTexture } from '../globals/randomTexture';
|
import { randomTexture } from '../globals/randomTexture';
|
||||||
import dviFrag from '../shaders/dvi.frag';
|
import dviFrag from '../shaders/dvi.frag';
|
||||||
import quadVert from '../shaders/quad.vert';
|
import quadVert from '../shaders/quad.vert';
|
||||||
import { auto } from '../globals/automaton';
|
|
||||||
|
|
||||||
export interface DViOptions {
|
export interface DViOptions {
|
||||||
input: BufferRenderTarget;
|
input: BufferRenderTarget;
|
||||||
|
@@ -15,7 +15,6 @@ import { randomTexture } from '../globals/randomTexture';
|
|||||||
import aoFrag from '../shaders/ao.frag';
|
import aoFrag from '../shaders/ao.frag';
|
||||||
import quadVert from '../shaders/quad.vert';
|
import quadVert from '../shaders/quad.vert';
|
||||||
import shadingFrag from '../shaders/shading.frag';
|
import shadingFrag from '../shaders/shading.frag';
|
||||||
import { auto } from '../globals/automaton';
|
|
||||||
|
|
||||||
export interface DeferredCameraOptions {
|
export interface DeferredCameraOptions {
|
||||||
scenes: Entity[];
|
scenes: Entity[];
|
||||||
|
319
src/entities/Greetings.ts
Normal file
319
src/entities/Greetings.ts
Normal file
@@ -0,0 +1,319 @@
|
|||||||
|
import { BufferRenderTarget } from '../heck/BufferRenderTarget';
|
||||||
|
import { Entity } from '../heck/Entity';
|
||||||
|
import { GLCatTexture } from '@fms-cat/glcat-ts';
|
||||||
|
import { InstancedGeometry } from '../heck/InstancedGeometry';
|
||||||
|
import { Lambda } from '../heck/components/Lambda';
|
||||||
|
import { Material } from '../heck/Material';
|
||||||
|
import { Mesh } from '../heck/components/Mesh';
|
||||||
|
import { Quad } from '../heck/components/Quad';
|
||||||
|
import { SPRITE_SHEET_SIZE, createFontSpriteSheet } from '../utils/createFontSpriteSheet';
|
||||||
|
import { Swap, TRIANGLE_STRIP_QUAD } from '@fms-cat/experimental';
|
||||||
|
import { auto } from '../globals/automaton';
|
||||||
|
import { calcCharPos } from '../utils/calcCharPos';
|
||||||
|
import { dummyRenderTarget } from '../globals/dummyRenderTarget';
|
||||||
|
import { gl, glCat } from '../globals/canvas';
|
||||||
|
import { quadGeometry } from '../globals/quadGeometry';
|
||||||
|
import blurFrag from '../shaders/blur.frag';
|
||||||
|
import greetingsFrag from '../shaders/greetings.frag';
|
||||||
|
import greetingsPreBeatmaniaFrag from '../shaders/greetings-pre-beatmania.frag';
|
||||||
|
import greetingsPreLainFrag from '../shaders/greetings-pre-lain.frag';
|
||||||
|
import greetingsVert from '../shaders/greetings.vert';
|
||||||
|
import quadVert from '../shaders/quad.vert';
|
||||||
|
|
||||||
|
const INSTANCES = 256;
|
||||||
|
|
||||||
|
// -- preprocessor ---------------------------------------------------------------------------------
|
||||||
|
const materialBlurH = new Material(
|
||||||
|
quadVert,
|
||||||
|
blurFrag,
|
||||||
|
{ initOptions: { geometry: quadGeometry, target: dummyRenderTarget } },
|
||||||
|
);
|
||||||
|
|
||||||
|
const materialBlurV = new Material(
|
||||||
|
quadVert,
|
||||||
|
blurFrag,
|
||||||
|
{
|
||||||
|
defines: [ 'IS_VERTICAL 1' ],
|
||||||
|
initOptions: { geometry: quadGeometry, target: dummyRenderTarget }
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const materialPreBeatmania = new Material(
|
||||||
|
quadVert,
|
||||||
|
greetingsPreBeatmaniaFrag,
|
||||||
|
{ initOptions: { geometry: quadGeometry, target: dummyRenderTarget } },
|
||||||
|
);
|
||||||
|
|
||||||
|
const materialPreLain = new Material(
|
||||||
|
quadVert,
|
||||||
|
greetingsPreLainFrag,
|
||||||
|
{ initOptions: { geometry: quadGeometry, target: dummyRenderTarget } },
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not add me to its components!
|
||||||
|
* It's just for preprocessing
|
||||||
|
*/
|
||||||
|
const quadPreprocessor = new Quad( {
|
||||||
|
name: process.env.DEV && 'Greetings/quadPreprocessor',
|
||||||
|
} );
|
||||||
|
|
||||||
|
// -- spritesheets ---------------------------------------------------------------------------------
|
||||||
|
const styles = [
|
||||||
|
{
|
||||||
|
font: 'Bold 96px Courier New',
|
||||||
|
preprocessorMaterials: [ materialPreLain ],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
font: '96px Arial',
|
||||||
|
spacing: 2.0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
font: 'Bold 96px Arial',
|
||||||
|
preprocessorMaterials: [
|
||||||
|
materialBlurH,
|
||||||
|
materialBlurV,
|
||||||
|
materialBlurH, // fuck you
|
||||||
|
materialBlurV, // fuck you (2)
|
||||||
|
materialPreBeatmania,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
font: '96px Times New Roman',
|
||||||
|
scaleY: 1.2,
|
||||||
|
spacing: 1.9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
font: 'Bold 96px Courier New',
|
||||||
|
preprocessorMaterials: [ materialPreLain ],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
font: 'Bold 96px Arial',
|
||||||
|
spacing: 1.5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
font: 'Bold 96px Arial',
|
||||||
|
preprocessorMaterials: [
|
||||||
|
materialBlurH,
|
||||||
|
materialBlurV,
|
||||||
|
materialBlurH, // fuck you
|
||||||
|
materialBlurV, // fuck you (2)
|
||||||
|
materialPreBeatmania,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
font: '96px Times New Roman',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const swapIntermediate = new Swap(
|
||||||
|
new BufferRenderTarget( {
|
||||||
|
width: SPRITE_SHEET_SIZE,
|
||||||
|
height: SPRITE_SHEET_SIZE,
|
||||||
|
name: process.env.DEV && 'Greetings/intermediate0',
|
||||||
|
} ),
|
||||||
|
new BufferRenderTarget( {
|
||||||
|
width: SPRITE_SHEET_SIZE,
|
||||||
|
height: SPRITE_SHEET_SIZE,
|
||||||
|
name: process.env.DEV && 'Greetings/intermediate0',
|
||||||
|
} ),
|
||||||
|
);
|
||||||
|
|
||||||
|
const spritesheets = styles.map( ( style, iStyle ) => {
|
||||||
|
const textureSpriteSheet = createFontSpriteSheet( style );
|
||||||
|
let texture: GLCatTexture = textureSpriteSheet;
|
||||||
|
|
||||||
|
( style.preprocessorMaterials ?? [] ).map( ( material, i ) => {
|
||||||
|
material.addUniformTexture(
|
||||||
|
'sampler0',
|
||||||
|
i === 0 ? textureSpriteSheet : swapIntermediate.o.texture,
|
||||||
|
);
|
||||||
|
|
||||||
|
quadPreprocessor.material = material;
|
||||||
|
quadPreprocessor.target = swapIntermediate.i;
|
||||||
|
quadPreprocessor.drawImmediate();
|
||||||
|
|
||||||
|
swapIntermediate.swap();
|
||||||
|
texture = swapIntermediate.o.texture;
|
||||||
|
} );
|
||||||
|
|
||||||
|
const dest = new BufferRenderTarget( {
|
||||||
|
width: SPRITE_SHEET_SIZE,
|
||||||
|
height: SPRITE_SHEET_SIZE,
|
||||||
|
name: process.env.DEV && `Greetings/spriteSheet${ iStyle }`,
|
||||||
|
} );
|
||||||
|
|
||||||
|
materialBlurH.addUniformTexture( 'sampler0', texture );
|
||||||
|
|
||||||
|
quadPreprocessor.material = materialBlurH;
|
||||||
|
quadPreprocessor.target = dest;
|
||||||
|
quadPreprocessor.drawImmediate();
|
||||||
|
|
||||||
|
return dest.texture;
|
||||||
|
} );
|
||||||
|
|
||||||
|
// -- greetings! -----------------------------------------------------------------------------------
|
||||||
|
const charPosList = [
|
||||||
|
'0x4015',
|
||||||
|
'Alcatraz',
|
||||||
|
'Altair',
|
||||||
|
'Astronomena',
|
||||||
|
'CNCD',
|
||||||
|
'Cocoon',
|
||||||
|
'Conspiracy',
|
||||||
|
'Fairlight',
|
||||||
|
'Flopine',
|
||||||
|
'FRONTL1NE',
|
||||||
|
'holon',
|
||||||
|
'gam0022',
|
||||||
|
'jetlag',
|
||||||
|
'Jugem-T',
|
||||||
|
'kaneta',
|
||||||
|
'Limp Ninja',
|
||||||
|
'LJ',
|
||||||
|
'Logicoma',
|
||||||
|
'Mercury',
|
||||||
|
'nikq::cube',
|
||||||
|
'Ninjadev',
|
||||||
|
'NuSan',
|
||||||
|
'Poo-Brain',
|
||||||
|
'Prismbeings',
|
||||||
|
'Radium Software',
|
||||||
|
'rgba',
|
||||||
|
'Satori',
|
||||||
|
'sp4ghet',
|
||||||
|
'Still',
|
||||||
|
'Suricrasia Online',
|
||||||
|
'tdhooper',
|
||||||
|
'Ümlaüt Design',
|
||||||
|
'Virgill',
|
||||||
|
'Wrighter',
|
||||||
|
'yx',
|
||||||
|
].map( ( text, iGreeting ) => {
|
||||||
|
const style = styles[ iGreeting % styles.length ];
|
||||||
|
const spacing = style.spacing ?? 1.0;
|
||||||
|
const { totalWidth, chars } = calcCharPos( text, style.font );
|
||||||
|
|
||||||
|
return {
|
||||||
|
totalWidth: totalWidth * spacing,
|
||||||
|
scaleY: style.scaleY ?? 1.0,
|
||||||
|
chars: chars.map( ( { char, x } ) => ( {
|
||||||
|
char: char.charCodeAt( 0 ),
|
||||||
|
x: ( x - 0.5 * totalWidth ) / 96.0 * spacing * 1.4 // what the fuck is this magic number
|
||||||
|
} ) ),
|
||||||
|
};
|
||||||
|
} );
|
||||||
|
|
||||||
|
export class Greetings extends Entity {
|
||||||
|
public constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// -- geometry ---------------------------------------------------------------------------------
|
||||||
|
const geometry = new InstancedGeometry();
|
||||||
|
|
||||||
|
const bufferP = glCat.createBuffer();
|
||||||
|
bufferP.setVertexbuffer( new Float32Array( TRIANGLE_STRIP_QUAD ) );
|
||||||
|
|
||||||
|
geometry.vao.bindVertexbuffer( bufferP, 0, 2 );
|
||||||
|
|
||||||
|
const arrayParams = new Float32Array( 4 * INSTANCES ); // char, posFromCenter, width, time
|
||||||
|
const arrayParams2 = new Float32Array( 4 * INSTANCES ); // totalWidth, scaleY
|
||||||
|
for ( let i = 0; i < INSTANCES; i ++ ) {
|
||||||
|
arrayParams[ 4 * i + 0 ] = 0;
|
||||||
|
arrayParams[ 4 * i + 1 ] = 0;
|
||||||
|
arrayParams[ 4 * i + 2 ] = 0;
|
||||||
|
arrayParams[ 4 * i + 3 ] = 0;
|
||||||
|
arrayParams2[ 4 * i + 0 ] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bufferParams = glCat.createBuffer();
|
||||||
|
bufferParams.setVertexbuffer( arrayParams, gl.STREAM_DRAW );
|
||||||
|
geometry.vao.bindVertexbuffer( bufferParams, 1, 4, 1 );
|
||||||
|
|
||||||
|
const bufferParams2 = glCat.createBuffer();
|
||||||
|
bufferParams2.setVertexbuffer( arrayParams2, gl.STREAM_DRAW );
|
||||||
|
geometry.vao.bindVertexbuffer( bufferParams2, 2, 4, 1 );
|
||||||
|
|
||||||
|
geometry.count = 4;
|
||||||
|
geometry.mode = gl.TRIANGLE_STRIP;
|
||||||
|
geometry.primcount = INSTANCES;
|
||||||
|
|
||||||
|
// -- material render --------------------------------------------------------------------------
|
||||||
|
const forward = new Material(
|
||||||
|
greetingsVert,
|
||||||
|
greetingsFrag,
|
||||||
|
{
|
||||||
|
initOptions: { geometry: geometry, target: dummyRenderTarget },
|
||||||
|
blend: [ gl.ONE, gl.ONE ],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const materials = { forward };
|
||||||
|
|
||||||
|
forward.addUniformTextureArray( 'samplerSpriteSheets', spritesheets );
|
||||||
|
|
||||||
|
if ( process.env.DEV ) {
|
||||||
|
if ( module.hot ) {
|
||||||
|
module.hot.accept(
|
||||||
|
[
|
||||||
|
'../shaders/greetings.vert',
|
||||||
|
'../shaders/greetings.frag',
|
||||||
|
],
|
||||||
|
() => {
|
||||||
|
forward.replaceShader( greetingsVert, greetingsFrag );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- mesh -------------------------------------------------------------------------------------
|
||||||
|
const mesh = new Mesh( {
|
||||||
|
geometry,
|
||||||
|
materials,
|
||||||
|
name: process.env.DEV && 'Greetings/mesh',
|
||||||
|
} );
|
||||||
|
|
||||||
|
// -- buffer updater ---------------------------------------------------------------------------
|
||||||
|
let headInstance = 0;
|
||||||
|
let headGreetings = 0;
|
||||||
|
|
||||||
|
const lambda = new Lambda( {
|
||||||
|
onUpdate: ( { time, deltaTime } ) => {
|
||||||
|
if ( Math.floor( 6.0 * time ) === Math.floor( 6.0 * ( time - deltaTime ) ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { totalWidth, scaleY, chars } = charPosList[ headGreetings ];
|
||||||
|
|
||||||
|
chars.map( ( { char, x } ) => {
|
||||||
|
arrayParams[ 4 * headInstance + 0 ] = char;
|
||||||
|
arrayParams[ 4 * headInstance + 1 ] = x;
|
||||||
|
arrayParams[ 4 * headInstance + 2 ] = headGreetings;
|
||||||
|
arrayParams[ 4 * headInstance + 3 ] = time;
|
||||||
|
arrayParams2[ 4 * headInstance + 0 ] = totalWidth;
|
||||||
|
arrayParams2[ 4 * headInstance + 1 ] = scaleY;
|
||||||
|
|
||||||
|
headInstance = ( headInstance + 1 ) % INSTANCES;
|
||||||
|
} );
|
||||||
|
|
||||||
|
headGreetings = ( headGreetings + 1 ) % charPosList.length;
|
||||||
|
|
||||||
|
bufferParams.setVertexbuffer( arrayParams, gl.STREAM_DRAW );
|
||||||
|
bufferParams2.setVertexbuffer( arrayParams2, gl.STREAM_DRAW );
|
||||||
|
},
|
||||||
|
name: process.env.DEV && 'Greetings/spawner',
|
||||||
|
} );
|
||||||
|
|
||||||
|
// -- components -------------------------------------------------------------------------------
|
||||||
|
this.components.push(
|
||||||
|
lambda,
|
||||||
|
mesh,
|
||||||
|
);
|
||||||
|
|
||||||
|
// -- auto -------------------------------------------------------------------------------------
|
||||||
|
auto( 'Greetings/active', ( { uninit } ) => {
|
||||||
|
mesh.active = !uninit;
|
||||||
|
mesh.visible = !uninit;
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
@@ -65,5 +65,9 @@ export class Post extends Entity {
|
|||||||
material.addUniform( 'colorGamma', '4f', ...preset.gamma );
|
material.addUniform( 'colorGamma', '4f', ...preset.gamma );
|
||||||
material.addUniform( 'colorGain', '4f', ...preset.gain );
|
material.addUniform( 'colorGain', '4f', ...preset.gain );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
auto( 'Post/mixInvert', ( { value } ) => {
|
||||||
|
material.addUniform( 'mixInvert', '1f', value );
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import { ChaosTorus } from '../automaton-fxs/ChaosTorus';
|
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 { Greetings } from './Greetings';
|
||||||
import { Lambda } from '../heck/components/Lambda';
|
import { Lambda } from '../heck/components/Lambda';
|
||||||
import { Quaternion, Vector3, Xorshift } from '@fms-cat/experimental';
|
import { Quaternion, Vector3, Xorshift } from '@fms-cat/experimental';
|
||||||
import { Rings } from './Rings';
|
import { Rings } from './Rings';
|
||||||
@@ -12,10 +13,8 @@ export class SceneCrystals extends Entity {
|
|||||||
|
|
||||||
// -- crystals ---------------------------------------------------------------------------------
|
// -- 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 );
|
|
||||||
|
|
||||||
const speen = new Entity();
|
const speen = new Entity();
|
||||||
this.children.push( speen );
|
|
||||||
|
|
||||||
const up = new Vector3( [ 0.0, 1.0, 0.0 ] );
|
const up = new Vector3( [ 0.0, 1.0, 0.0 ] );
|
||||||
this.components.push( new Lambda( {
|
this.components.push( new Lambda( {
|
||||||
@@ -40,12 +39,12 @@ export class SceneCrystals extends Entity {
|
|||||||
new Vector3( [ 0.0, 0.0, 1.0 ] ),
|
new Vector3( [ 0.0, 0.0, 1.0 ] ),
|
||||||
0.1,
|
0.1,
|
||||||
) );
|
) );
|
||||||
this.children.push( rings );
|
|
||||||
|
|
||||||
// -- chaos torus ------------------------------------------------------------------------------
|
// -- chaos torus ------------------------------------------------------------------------------
|
||||||
const rng = new Xorshift( 618954 );
|
const rng = new Xorshift( 618954 );
|
||||||
const chaosToruses = [ ...Array( 6 ).keys() ].map( () => {
|
const chaosToruses = [ ...Array( 6 ).keys() ].map( () => {
|
||||||
const pivot = new Entity();
|
const pivot = new Entity();
|
||||||
|
pivot.visible = false;
|
||||||
pivot.transform.rotation = Quaternion.fromAxisAngle(
|
pivot.transform.rotation = Quaternion.fromAxisAngle(
|
||||||
new Vector3( [ 1.0, 0.0, 0.0 ] ),
|
new Vector3( [ 1.0, 0.0, 0.0 ] ),
|
||||||
rng.gen() * 6.0,
|
rng.gen() * 6.0,
|
||||||
@@ -53,7 +52,6 @@ export class SceneCrystals extends Entity {
|
|||||||
new Vector3( [ 0.0, 1.0, 0.0 ] ),
|
new Vector3( [ 0.0, 1.0, 0.0 ] ),
|
||||||
rng.gen() * 6.0,
|
rng.gen() * 6.0,
|
||||||
) );
|
) );
|
||||||
this.children.push( pivot );
|
|
||||||
|
|
||||||
const chaosTorus = new ChaosTorus();
|
const chaosTorus = new ChaosTorus();
|
||||||
chaosTorus.transform.position = new Vector3( [ 2.5, 0.0, 0.0 ] );
|
chaosTorus.transform.position = new Vector3( [ 2.5, 0.0, 0.0 ] );
|
||||||
@@ -65,5 +63,17 @@ export class SceneCrystals extends Entity {
|
|||||||
auto( 'SceneCrystals/ChaosTorus/active', ( { uninit } ) => {
|
auto( 'SceneCrystals/ChaosTorus/active', ( { uninit } ) => {
|
||||||
chaosToruses.map( ( entity ) => ( entity.visible = !uninit ) );
|
chaosToruses.map( ( entity ) => ( entity.visible = !uninit ) );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
// -- greetings --------------------------------------------------------------------------------
|
||||||
|
const greetings = new Greetings();
|
||||||
|
|
||||||
|
// -- children ---------------------------------------------------------------------------------
|
||||||
|
this.children.push(
|
||||||
|
crystal,
|
||||||
|
speen,
|
||||||
|
rings,
|
||||||
|
...chaosToruses,
|
||||||
|
greetings,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,7 @@ import { Lambda } from '../heck/components/Lambda';
|
|||||||
import { Material } from '../heck/Material';
|
import { Material } from '../heck/Material';
|
||||||
import { TRIANGLE_STRIP_QUAD } from '@fms-cat/experimental';
|
import { TRIANGLE_STRIP_QUAD } from '@fms-cat/experimental';
|
||||||
import { auto } from '../globals/automaton';
|
import { auto } from '../globals/automaton';
|
||||||
import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget';
|
import { dummyRenderTarget } from '../globals/dummyRenderTarget';
|
||||||
import { gl, glCat } from '../globals/canvas';
|
import { gl, glCat } from '../globals/canvas';
|
||||||
import { quadGeometry } from '../globals/quadGeometry';
|
import { quadGeometry } from '../globals/quadGeometry';
|
||||||
import { randomTextureStatic } from '../globals/randomTexture';
|
import { randomTextureStatic } from '../globals/randomTexture';
|
||||||
@@ -86,7 +86,7 @@ export class SufferTexts extends Entity {
|
|||||||
sufferTextsRenderVert,
|
sufferTextsRenderVert,
|
||||||
sufferTextsRenderFrag,
|
sufferTextsRenderFrag,
|
||||||
{
|
{
|
||||||
initOptions: { geometry: geometryRender, target: dummyRenderTargetFourDrawBuffers },
|
initOptions: { geometry: geometryRender, target: dummyRenderTarget },
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -5,8 +5,8 @@ import { gl, glCat } from '../../globals/canvas';
|
|||||||
import { quadGeometry } from '../../globals/quadGeometry';
|
import { quadGeometry } from '../../globals/quadGeometry';
|
||||||
|
|
||||||
export interface QuadOptions extends ComponentOptions {
|
export interface QuadOptions extends ComponentOptions {
|
||||||
material: Material;
|
material?: Material;
|
||||||
target: RenderTarget;
|
target?: RenderTarget;
|
||||||
range?: [ number, number, number, number ];
|
range?: [ number, number, number, number ];
|
||||||
clear?: Array<number | undefined> | false;
|
clear?: Array<number | undefined> | false;
|
||||||
}
|
}
|
||||||
@@ -15,8 +15,8 @@ export interface QuadOptions extends ComponentOptions {
|
|||||||
* Renders a fullscreen quad.
|
* Renders a fullscreen quad.
|
||||||
*/
|
*/
|
||||||
export class Quad extends Component {
|
export class Quad extends Component {
|
||||||
public material: Material;
|
public material?: Material;
|
||||||
public target: RenderTarget;
|
public target?: RenderTarget;
|
||||||
public range: [ number, number, number, number ] = [ -1.0, -1.0, 1.0, 1.0 ];
|
public range: [ number, number, number, number ] = [ -1.0, -1.0, 1.0, 1.0 ];
|
||||||
public clear: Array<number | undefined> | false = false;
|
public clear: Array<number | undefined> | false = false;
|
||||||
|
|
||||||
@@ -31,11 +31,17 @@ export class Quad extends Component {
|
|||||||
if ( options.clear !== undefined ) { this.clear = options.clear; }
|
if ( options.clear !== undefined ) { this.clear = options.clear; }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected __updateImpl( event: ComponentUpdateEvent ): void {
|
public drawImmediate( event?: Partial<ComponentUpdateEvent> ): void {
|
||||||
glCat.useProgram( this.material.program );
|
const { target, material } = this;
|
||||||
|
|
||||||
this.target.bind();
|
if ( target == null || material == null ) {
|
||||||
this.material.setBlendMode();
|
throw process.env.DEV && new Error( 'Quad: You must assign target and material before draw' );
|
||||||
|
}
|
||||||
|
|
||||||
|
glCat.useProgram( material.program );
|
||||||
|
|
||||||
|
target.bind();
|
||||||
|
material.setBlendMode();
|
||||||
|
|
||||||
gl.enable( gl.DEPTH_TEST );
|
gl.enable( gl.DEPTH_TEST );
|
||||||
gl.depthMask( true );
|
gl.depthMask( true );
|
||||||
@@ -44,16 +50,20 @@ export class Quad extends Component {
|
|||||||
glCat.clear( ...this.clear );
|
glCat.clear( ...this.clear );
|
||||||
}
|
}
|
||||||
|
|
||||||
this.material.setUniforms();
|
material.setUniforms();
|
||||||
|
|
||||||
const program = this.material.program;
|
const program = material.program;
|
||||||
|
|
||||||
program.uniform( 'time', '1f', event.time );
|
program.uniform( 'time', '1f', event?.time ?? 0.0 );
|
||||||
program.uniform( 'deltaTime', '1f', event.deltaTime );
|
program.uniform( 'deltaTime', '1f', event?.deltaTime ?? 0.0 );
|
||||||
program.uniform( 'frameCount', '1f', event.frameCount );
|
program.uniform( 'frameCount', '1f', event?.frameCount ?? 0 );
|
||||||
program.uniform( 'resolution', '2f', this.target.width, this.target.height );
|
program.uniform( 'resolution', '2f', target.width, target.height );
|
||||||
program.uniform( 'range', '4f', ...this.range );
|
program.uniform( 'range', '4f', ...this.range );
|
||||||
|
|
||||||
quadGeometry.draw();
|
quadGeometry.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected __updateImpl( event: ComponentUpdateEvent ): void {
|
||||||
|
this.drawImmediate( event );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -43,7 +43,7 @@ void main() {
|
|||||||
#ifdef DEFERRED
|
#ifdef DEFERRED
|
||||||
fragPosition = vPosition;
|
fragPosition = vPosition;
|
||||||
fragNormal = vec4( normalize( vNormal ), 1.0 );
|
fragNormal = vec4( normalize( vNormal ), 1.0 );
|
||||||
fragColor = vec4( vec3( 0.001 ), 1.0 );
|
fragColor = vec4( vec3( 1.0 ), 1.0 );
|
||||||
fragWTF = vec4( vec3( 0.99, 0.01, 0.0 ), MTL_PBR );
|
fragWTF = vec4( vec3( 0.99, 0.01, 0.0 ), MTL_PBR );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
13
src/shaders/greetings-pre-beatmania.frag
Normal file
13
src/shaders/greetings-pre-beatmania.frag
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
in vec2 vUv;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
uniform sampler2D sampler0;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
fragColor = step( 0.9, texture( sampler0, vUv ) );
|
||||||
|
}
|
18
src/shaders/greetings-pre-lain.frag
Normal file
18
src/shaders/greetings-pre-lain.frag
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
in vec2 vUv;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
uniform sampler2D sampler0;
|
||||||
|
|
||||||
|
#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = vUv;
|
||||||
|
uv += 0.001 * sin( 20.0 * cyclicNoise( vec3( 4.0 * uv, 1.0 ) ).xy );
|
||||||
|
|
||||||
|
fragColor = texture( sampler0, uv );
|
||||||
|
}
|
41
src/shaders/greetings.frag
Normal file
41
src/shaders/greetings.frag
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
in float vTime;
|
||||||
|
in vec2 vUv;
|
||||||
|
in vec4 vCharParams;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
uniform sampler2D samplerSpriteSheets[ 8 ];
|
||||||
|
|
||||||
|
|
||||||
|
// this is BAD
|
||||||
|
vec4 fetchSpriteSheet( int iFont ) {
|
||||||
|
if ( iFont == 0 ) {
|
||||||
|
return texture( samplerSpriteSheets[ 0 ], vUv );
|
||||||
|
} else if ( iFont == 1 ) {
|
||||||
|
return texture( samplerSpriteSheets[ 1 ], vUv );
|
||||||
|
} else if ( iFont == 2 ) {
|
||||||
|
return texture( samplerSpriteSheets[ 2 ], vUv );
|
||||||
|
} else if ( iFont == 3 ) {
|
||||||
|
return texture( samplerSpriteSheets[ 3 ], vUv );
|
||||||
|
} else if ( iFont == 4 ) {
|
||||||
|
return texture( samplerSpriteSheets[ 4 ], vUv );
|
||||||
|
} else if ( iFont == 5 ) {
|
||||||
|
return texture( samplerSpriteSheets[ 5 ], vUv );
|
||||||
|
} else if ( iFont == 6 ) {
|
||||||
|
return texture( samplerSpriteSheets[ 6 ], vUv );
|
||||||
|
} else if ( iFont == 7 ) {
|
||||||
|
return texture( samplerSpriteSheets[ 7 ], vUv );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// gl.ONE, gl.ONE
|
||||||
|
void main() {
|
||||||
|
if ( vTime < 0.0 ) { discard; }
|
||||||
|
|
||||||
|
int font = int( vCharParams.z ) % 8;
|
||||||
|
fragColor = exp( -17.0 * vTime ) * fetchSpriteSheet( font ) * vec4( 3.0, 0.4, 7.0, 1.0 );
|
||||||
|
}
|
56
src/shaders/greetings.vert
Normal file
56
src/shaders/greetings.vert
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#version 300 es
|
||||||
|
|
||||||
|
#define fs(i) (fract(sin((i)*114.514)*1919.810))
|
||||||
|
#define saturate(i) clamp(i,0.,1.)
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 position;
|
||||||
|
layout (location = 1) in vec4 charParams;
|
||||||
|
layout (location = 2) in vec4 charParams2;
|
||||||
|
|
||||||
|
out float vTime;
|
||||||
|
out vec2 vUv;
|
||||||
|
out vec4 vCharParams;
|
||||||
|
out vec4 vPosition;
|
||||||
|
|
||||||
|
uniform float time;
|
||||||
|
uniform vec2 resolution;
|
||||||
|
|
||||||
|
// == utils ========================================================================================
|
||||||
|
vec2 yflip( vec2 uv ) {
|
||||||
|
return vec2( 0.0, 1.0 ) + vec2( 1.0, -1.0 ) * uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// == main procedure ===============================================================================
|
||||||
|
void main() {
|
||||||
|
vCharParams = charParams;
|
||||||
|
|
||||||
|
float char = vCharParams.x;
|
||||||
|
|
||||||
|
vUv = yflip( 0.5 + 0.499 * position );
|
||||||
|
vUv = ( vUv + floor( mod( vec2( char / vec2( 1.0, 16.0 ) ), 16.0 ) ) ) / 16.0;
|
||||||
|
|
||||||
|
vTime = time - vCharParams.w;
|
||||||
|
|
||||||
|
// == compute size ===============================================================================
|
||||||
|
vPosition = vec4( 0.0, 0.0, 0.0, 1.0 );
|
||||||
|
|
||||||
|
vec2 shape = 0.5 * position;
|
||||||
|
shape.y *= charParams2.y;
|
||||||
|
|
||||||
|
vec2 offset = ( 0.6 - 0.2 * exp( -5.0 * vTime ) ) * vec2( vCharParams.y, 0.0 );
|
||||||
|
vPosition.xy += ( offset + shape ) * min( 500.0 / charParams2.x, 1.0 );
|
||||||
|
|
||||||
|
vPosition.xy += 1.0
|
||||||
|
* ( fs( vCharParams.z + vec2( 2.66, 1.79 ) ) * 2.0 - 1.0 )
|
||||||
|
* pow( fs( vCharParams.z + 7.8 ), 2.0 );
|
||||||
|
|
||||||
|
// == send the vertex position ===================================================================
|
||||||
|
vPosition = vPosition;
|
||||||
|
vec4 outPos = vPosition;
|
||||||
|
outPos.x *= resolution.y / resolution.x;
|
||||||
|
gl_Position = outPos;
|
||||||
|
|
||||||
|
vPosition.w = outPos.z / outPos.w;
|
||||||
|
}
|
@@ -18,6 +18,7 @@ in vec2 vUv;
|
|||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
uniform float time;
|
uniform float time;
|
||||||
|
uniform float mixInvert;
|
||||||
uniform vec2 resolution;
|
uniform vec2 resolution;
|
||||||
uniform vec4 colorLift;
|
uniform vec4 colorLift;
|
||||||
uniform vec4 colorGamma;
|
uniform vec4 colorGamma;
|
||||||
@@ -86,6 +87,7 @@ void main() {
|
|||||||
|
|
||||||
vec3 col = tex.xyz;
|
vec3 col = tex.xyz;
|
||||||
vec4 seed = texture( samplerRandom, uv );
|
vec4 seed = texture( samplerRandom, uv );
|
||||||
|
col = mix( col, 1.0 - 5.0 * col, mixInvert );
|
||||||
prng( seed );
|
prng( seed );
|
||||||
prng( seed );
|
prng( seed );
|
||||||
col = aces( max( 2.0 * col, 0.0 ) ) / aces( vec3( 11.2 ) );
|
col = aces( max( 2.0 * col, 0.0 ) ) / aces( vec3( 11.2 ) );
|
||||||
|
@@ -288,9 +288,12 @@ void main() {
|
|||||||
|
|
||||||
// color = 0.5 + 0.5 * isect.normal;
|
// color = 0.5 + 0.5 * isect.normal;
|
||||||
// color = vec3( calcDepth( tex0.xyz ) );
|
// color = vec3( calcDepth( tex0.xyz ) );
|
||||||
// color = vec3( 0.5, 0.9, 0.6 ) * ( 1.0 - texture( samplerAo, isect.screenUv ).xyz );
|
// color = vec3( 0.5, 0.2, 0.9 ) * ( 1.0 - texture( samplerAo, isect.screenUv ).xyz );
|
||||||
// color = vec3( 0.5, 0.9, 0.6 ) * ( texture( samplerAo, isect.screenUv ).xyz );
|
// color = mix(
|
||||||
// xfdA = shadeGradient( isect );
|
// color,
|
||||||
|
// vec3( 0.96 ) * smoothstep( 0.9, 0.1, texture( samplerAo, isect.screenUv ).xyz ),
|
||||||
|
// 1.0
|
||||||
|
// );
|
||||||
|
|
||||||
fragColor = vec4( color, 1.0 );
|
fragColor = vec4( color, 1.0 );
|
||||||
// fragColor.xyz *= smoothstep( 1.0, 0.7, calcDepth( tex0.xyz ) );
|
// fragColor.xyz *= smoothstep( 1.0, 0.7, calcDepth( tex0.xyz ) );
|
||||||
|
30
src/utils/calcCharPos.ts
Normal file
30
src/utils/calcCharPos.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
const canvas = document.createElement( 'canvas' );
|
||||||
|
const context = canvas.getContext( '2d' )!;
|
||||||
|
|
||||||
|
export function calcCharPos(
|
||||||
|
text: string,
|
||||||
|
font: string,
|
||||||
|
): {
|
||||||
|
totalWidth: number;
|
||||||
|
chars: {
|
||||||
|
char: string;
|
||||||
|
x: number;
|
||||||
|
}[];
|
||||||
|
} {
|
||||||
|
let totalWidth = 0;
|
||||||
|
let currentText = '';
|
||||||
|
|
||||||
|
context.font = font;
|
||||||
|
|
||||||
|
const chars = text.split( '' ).map( ( char ) => {
|
||||||
|
const charWidth = context.measureText( char ).width;
|
||||||
|
|
||||||
|
currentText += char;
|
||||||
|
totalWidth = context.measureText( currentText ).width;
|
||||||
|
const x = totalWidth - 0.5 * charWidth;
|
||||||
|
|
||||||
|
return { x, char };
|
||||||
|
} );
|
||||||
|
|
||||||
|
return { totalWidth, chars };
|
||||||
|
}
|
42
src/utils/createFontSpriteSheet.ts
Normal file
42
src/utils/createFontSpriteSheet.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// yoinked from https://github.com/mapbox/tiny-sdf (BSD 2-Clause)
|
||||||
|
|
||||||
|
import { GLCatTexture } from '@fms-cat/glcat-ts';
|
||||||
|
import { glCat } from '../globals/canvas';
|
||||||
|
|
||||||
|
const SPRITE_SIZE = 128;
|
||||||
|
export const SPRITE_SHEET_SIZE = 16 * SPRITE_SIZE;
|
||||||
|
|
||||||
|
const CHARS = [ ...new Array( 256 ).keys() ].map( ( i ) => String.fromCharCode( i ) );
|
||||||
|
|
||||||
|
export function createFontSpriteSheet( { font, baseline }: {
|
||||||
|
font: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 0.8 is recommended
|
||||||
|
*/
|
||||||
|
baseline?: number;
|
||||||
|
} ): GLCatTexture {
|
||||||
|
const texture = glCat.createTexture();
|
||||||
|
|
||||||
|
const canvas = document.createElement( 'canvas' );
|
||||||
|
canvas.width = SPRITE_SHEET_SIZE;
|
||||||
|
canvas.height = SPRITE_SHEET_SIZE;
|
||||||
|
|
||||||
|
const context = canvas.getContext( '2d' )!;
|
||||||
|
context.textAlign = 'center';
|
||||||
|
context.fillStyle = '#fff';
|
||||||
|
|
||||||
|
context.font = font;
|
||||||
|
|
||||||
|
for ( let i = 0; i < 256; i ++ ) {
|
||||||
|
const char = CHARS[ i ];
|
||||||
|
const x = ( ( i % 16 ) + 0.5 ) * SPRITE_SIZE;
|
||||||
|
const y = ( Math.floor( i / 16 ) + ( baseline ?? 0.7 ) ) * SPRITE_SIZE;
|
||||||
|
|
||||||
|
context.fillText( char, x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
texture.setTexture( canvas );
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
Reference in New Issue
Block a user