mirror of
https://github.com/FMS-Cat/condition.git
synced 2025-08-20 12:21:38 +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_CAPTURE_NAME: string | null = null,
|
||||
// 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 = 'DeferredCamera/cameraTarget',
|
||||
RTINSPECTOR_CAPTURE_INDEX = 0,
|
||||
|
@@ -5,7 +5,7 @@ export const
|
||||
AO_RESOLUTION_RATIO = 1.0,
|
||||
RESOLUTION = [ 1280, 720 ],
|
||||
MUSIC_BPM = 180,
|
||||
START_POSITION = 45,
|
||||
START_POSITION = 112,
|
||||
MUSIC_LENGTH = 213,
|
||||
MUSIC_AUTOMATON_TEXTURE_HEIGHT = 16,
|
||||
IBLLUT_ITER = 400,
|
||||
|
@@ -4,12 +4,12 @@ import { Entity } from '../heck/Entity';
|
||||
import { Material } from '../heck/Material';
|
||||
import { Quad } from '../heck/components/Quad';
|
||||
import { RenderTarget } from '../heck/RenderTarget';
|
||||
import { auto } from '../globals/automaton';
|
||||
import { dummyRenderTarget } from '../globals/dummyRenderTarget';
|
||||
import { quadGeometry } from '../globals/quadGeometry';
|
||||
import { randomTexture } from '../globals/randomTexture';
|
||||
import dviFrag from '../shaders/dvi.frag';
|
||||
import quadVert from '../shaders/quad.vert';
|
||||
import { auto } from '../globals/automaton';
|
||||
|
||||
export interface DViOptions {
|
||||
input: BufferRenderTarget;
|
||||
|
@@ -15,7 +15,6 @@ import { randomTexture } from '../globals/randomTexture';
|
||||
import aoFrag from '../shaders/ao.frag';
|
||||
import quadVert from '../shaders/quad.vert';
|
||||
import shadingFrag from '../shaders/shading.frag';
|
||||
import { auto } from '../globals/automaton';
|
||||
|
||||
export interface DeferredCameraOptions {
|
||||
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( 'colorGain', '4f', ...preset.gain );
|
||||
} );
|
||||
|
||||
auto( 'Post/mixInvert', ( { value } ) => {
|
||||
material.addUniform( 'mixInvert', '1f', value );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { ChaosTorus } from '../automaton-fxs/ChaosTorus';
|
||||
import { Crystal } from './Crystal';
|
||||
import { Entity } from '../heck/Entity';
|
||||
import { Greetings } from './Greetings';
|
||||
import { Lambda } from '../heck/components/Lambda';
|
||||
import { Quaternion, Vector3, Xorshift } from '@fms-cat/experimental';
|
||||
import { Rings } from './Rings';
|
||||
@@ -12,10 +13,8 @@ export class SceneCrystals extends Entity {
|
||||
|
||||
// -- crystals ---------------------------------------------------------------------------------
|
||||
const crystal = new Crystal( { width: 0.4, height: 1.5, noiseOffset: 7.0 } );
|
||||
this.children.push( crystal );
|
||||
|
||||
const speen = new Entity();
|
||||
this.children.push( speen );
|
||||
|
||||
const up = new Vector3( [ 0.0, 1.0, 0.0 ] );
|
||||
this.components.push( new Lambda( {
|
||||
@@ -40,12 +39,12 @@ export class SceneCrystals extends Entity {
|
||||
new Vector3( [ 0.0, 0.0, 1.0 ] ),
|
||||
0.1,
|
||||
) );
|
||||
this.children.push( rings );
|
||||
|
||||
// -- chaos torus ------------------------------------------------------------------------------
|
||||
const rng = new Xorshift( 618954 );
|
||||
const chaosToruses = [ ...Array( 6 ).keys() ].map( () => {
|
||||
const pivot = new Entity();
|
||||
pivot.visible = false;
|
||||
pivot.transform.rotation = Quaternion.fromAxisAngle(
|
||||
new Vector3( [ 1.0, 0.0, 0.0 ] ),
|
||||
rng.gen() * 6.0,
|
||||
@@ -53,7 +52,6 @@ export class SceneCrystals extends Entity {
|
||||
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 ] );
|
||||
@@ -65,5 +63,17 @@ export class SceneCrystals extends Entity {
|
||||
auto( 'SceneCrystals/ChaosTorus/active', ( { 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 { TRIANGLE_STRIP_QUAD } from '@fms-cat/experimental';
|
||||
import { auto } from '../globals/automaton';
|
||||
import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget';
|
||||
import { dummyRenderTarget } from '../globals/dummyRenderTarget';
|
||||
import { gl, glCat } from '../globals/canvas';
|
||||
import { quadGeometry } from '../globals/quadGeometry';
|
||||
import { randomTextureStatic } from '../globals/randomTexture';
|
||||
@@ -86,7 +86,7 @@ export class SufferTexts extends Entity {
|
||||
sufferTextsRenderVert,
|
||||
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';
|
||||
|
||||
export interface QuadOptions extends ComponentOptions {
|
||||
material: Material;
|
||||
target: RenderTarget;
|
||||
material?: Material;
|
||||
target?: RenderTarget;
|
||||
range?: [ number, number, number, number ];
|
||||
clear?: Array<number | undefined> | false;
|
||||
}
|
||||
@@ -15,8 +15,8 @@ export interface QuadOptions extends ComponentOptions {
|
||||
* Renders a fullscreen quad.
|
||||
*/
|
||||
export class Quad extends Component {
|
||||
public material: Material;
|
||||
public target: RenderTarget;
|
||||
public material?: Material;
|
||||
public target?: RenderTarget;
|
||||
public range: [ number, number, number, number ] = [ -1.0, -1.0, 1.0, 1.0 ];
|
||||
public clear: Array<number | undefined> | false = false;
|
||||
|
||||
@@ -31,11 +31,17 @@ export class Quad extends Component {
|
||||
if ( options.clear !== undefined ) { this.clear = options.clear; }
|
||||
}
|
||||
|
||||
protected __updateImpl( event: ComponentUpdateEvent ): void {
|
||||
glCat.useProgram( this.material.program );
|
||||
public drawImmediate( event?: Partial<ComponentUpdateEvent> ): void {
|
||||
const { target, material } = this;
|
||||
|
||||
this.target.bind();
|
||||
this.material.setBlendMode();
|
||||
if ( target == null || material == null ) {
|
||||
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.depthMask( true );
|
||||
@@ -44,16 +50,20 @@ export class Quad extends Component {
|
||||
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( 'deltaTime', '1f', event.deltaTime );
|
||||
program.uniform( 'frameCount', '1f', event.frameCount );
|
||||
program.uniform( 'resolution', '2f', this.target.width, this.target.height );
|
||||
program.uniform( 'time', '1f', event?.time ?? 0.0 );
|
||||
program.uniform( 'deltaTime', '1f', event?.deltaTime ?? 0.0 );
|
||||
program.uniform( 'frameCount', '1f', event?.frameCount ?? 0 );
|
||||
program.uniform( 'resolution', '2f', target.width, target.height );
|
||||
program.uniform( 'range', '4f', ...this.range );
|
||||
|
||||
quadGeometry.draw();
|
||||
}
|
||||
|
||||
protected __updateImpl( event: ComponentUpdateEvent ): void {
|
||||
this.drawImmediate( event );
|
||||
}
|
||||
}
|
||||
|
@@ -43,7 +43,7 @@ void main() {
|
||||
#ifdef DEFERRED
|
||||
fragPosition = vPosition;
|
||||
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 );
|
||||
#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;
|
||||
|
||||
uniform float time;
|
||||
uniform float mixInvert;
|
||||
uniform vec2 resolution;
|
||||
uniform vec4 colorLift;
|
||||
uniform vec4 colorGamma;
|
||||
@@ -86,6 +87,7 @@ void main() {
|
||||
|
||||
vec3 col = tex.xyz;
|
||||
vec4 seed = texture( samplerRandom, uv );
|
||||
col = mix( col, 1.0 - 5.0 * col, mixInvert );
|
||||
prng( seed );
|
||||
prng( seed );
|
||||
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 = vec3( calcDepth( tex0.xyz ) );
|
||||
// color = vec3( 0.5, 0.9, 0.6 ) * ( 1.0 - texture( samplerAo, isect.screenUv ).xyz );
|
||||
// color = vec3( 0.5, 0.9, 0.6 ) * ( texture( samplerAo, isect.screenUv ).xyz );
|
||||
// xfdA = shadeGradient( isect );
|
||||
// color = vec3( 0.5, 0.2, 0.9 ) * ( 1.0 - texture( samplerAo, isect.screenUv ).xyz );
|
||||
// color = mix(
|
||||
// color,
|
||||
// vec3( 0.96 ) * smoothstep( 0.9, 0.1, texture( samplerAo, isect.screenUv ).xyz ),
|
||||
// 1.0
|
||||
// );
|
||||
|
||||
fragColor = vec4( color, 1.0 );
|
||||
// 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