before the psy

This commit is contained in:
FMS-Cat
2021-04-02 01:41:14 +09:00
parent 441844d296
commit 1449c8fd00
54 changed files with 1789 additions and 264 deletions

View File

@@ -1,4 +1,9 @@
# <placeholder> # Condition
## `#define COMPROMISE 1`
I'm so embarrassed that this project contains so many dumb strategies about size / performance optimization because deadline matters.
You totally shouldn't reference this project to do something by yourself.
## Build ## Build

File diff suppressed because one or more lines are too long

View File

@@ -5,8 +5,10 @@ export const
// RTINSPECTOR_CAPTURE_NAME: string | null = 'PixelSorter/index', // RTINSPECTOR_CAPTURE_NAME: string | null = 'PixelSorter/index',
// RTINSPECTOR_CAPTURE_NAME: string | null = 'Greetings/intermediate0', // 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 = 'EnvironmentMap/swap0',
// RTINSPECTOR_CAPTURE_NAME: string | null = 'DeferredCamera/cameraTarget', // RTINSPECTOR_CAPTURE_NAME: string | null = 'DeferredCamera/cameraTarget',
RTINSPECTOR_CAPTURE_INDEX = 0, RTINSPECTOR_CAPTURE_INDEX = 0,
COMPONENT_UPDATE_BREAKPOINT: string | null = null, COMPONENT_UPDATE_BREAKPOINT: string | null = null,
// COMPONENT_UPDATE_BREAKPOINT: string | null = 'ForwardCamera/camera', // COMPONENT_UPDATE_BREAKPOINT: string | null = 'ForwardCamera/camera',
// COMPONENT_UPDATE_BREAKPOINT: string | null = 'lightDynamic1/shadowMapCamera',
COMPONENT_DRAW_BREAKPOINT: string | null = null; COMPONENT_DRAW_BREAKPOINT: string | null = null;

View File

@@ -8,10 +8,9 @@ import { Material } from '../heck/Material';
import { Mesh, MeshCull } from '../heck/components/Mesh'; import { Mesh, MeshCull } from '../heck/components/Mesh';
import { Vector3 } from '@fms-cat/experimental'; import { Vector3 } from '@fms-cat/experimental';
import { auto } from '../globals/automaton'; import { auto } from '../globals/automaton';
import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget'; import { dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget';
import { genCube } from '../geometries/genCube'; import { genCube } from '../geometries/genCube';
import { objectValuesMap } from '../utils/objectEntriesMap'; import { objectValuesMap } from '../utils/objectEntriesMap';
import { randomTexture, randomTextureStatic } from '../globals/randomTexture';
import crystalFrag from '../shaders/crystal.frag'; import crystalFrag from '../shaders/crystal.frag';
import raymarchObjectVert from '../shaders/raymarch-object.vert'; import raymarchObjectVert from '../shaders/raymarch-object.vert';
@@ -50,22 +49,23 @@ export class Crystal extends Entity {
}, },
); );
const depth = new Material( // I don't think we need this
raymarchObjectVert, // const depth = new Material(
crystalFrag, // raymarchObjectVert,
{ // crystalFrag,
defines: [ 'SHADOW 1' ], // {
initOptions: { geometry, target: dummyRenderTarget } // defines: [ 'DEPTH 1' ],
}, // initOptions: { geometry, target: dummyRenderTarget }
); // },
// );
const materials = { deferred, depth }; const materials = { deferred };
if ( process.env.DEV ) { if ( process.env.DEV ) {
if ( module.hot ) { if ( module.hot ) {
module.hot.accept( '../shaders/crystal.frag', () => { module.hot.accept( '../shaders/crystal.frag', () => {
deferred.replaceShader( raymarchObjectVert, crystalFrag ); deferred.replaceShader( raymarchObjectVert, crystalFrag );
depth.replaceShader( raymarchObjectVert, crystalFrag ); // depth.replaceShader( raymarchObjectVert, crystalFrag );
} ); } );
} }
} }
@@ -73,9 +73,6 @@ export class Crystal extends Entity {
objectValuesMap( materials, ( material ) => { objectValuesMap( materials, ( material ) => {
material.addUniform( 'size', '2f', width, height ); material.addUniform( 'size', '2f', width, height );
material.addUniform( 'noiseOffset', '1f', noiseOffset ); material.addUniform( 'noiseOffset', '1f', noiseOffset );
material.addUniformTexture( 'samplerRandom', randomTexture.texture );
material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
} ); } );
// -- updater ---------------------------------------------------------------------------------- // -- updater ----------------------------------------------------------------------------------
@@ -98,10 +95,6 @@ export class Crystal extends Entity {
.inverse! .inverse!
.elements .elements
); );
material.addUniform( 'deformAmp', '1f', auto( 'Music/NEURO_WUB_AMP' ) );
material.addUniform( 'deformFreq', '1f', auto( 'Music/NEURO_WUB_FREQ' ) + auto( 'Music/NEURO_DETUNE' ) );
material.addUniform( 'deformTime', '1f', auto( 'Music/NEURO_TIME' ) );
} ); } );
}, },
name: process.env.DEV && 'Crystal/updater', name: process.env.DEV && 'Crystal/updater',

View File

@@ -30,7 +30,6 @@ export class Cube extends Entity {
0.4, 0.4,
) ); ) );
this.transform.position = new Vector3( [ 0.0, 0.0, 0.0 ] );
this.transform.rotation = rot0; this.transform.rotation = rot0;
this.transform.scale = this.transform.scale.scale( 0.3 ); this.transform.scale = this.transform.scale.scale( 0.3 );

119
src/entities/CyclicBoard.ts Normal file
View File

@@ -0,0 +1,119 @@
import { Entity } from '../heck/Entity';
import { Geometry } from '../heck/Geometry';
import { Lambda } from '../heck/components/Lambda';
import { LightEntity } from './LightEntity';
import { Material } from '../heck/Material';
import { Mesh, MeshCull } from '../heck/components/Mesh';
import { Vector3 } from '@fms-cat/experimental';
import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget';
import { genCube } from '../geometries/genCube';
import { objectValuesMap } from '../utils/objectEntriesMap';
import { setLightUniforms } from '../utils/setLightUniforms';
import cyclicBoardFrag from '../shaders/cyclic-board.frag';
import raymarchObjectVert from '../shaders/raymarch-object.vert';
export class CyclicBoard extends Entity {
public lights: LightEntity[] = [];
public constructor() {
super();
this.transform.position = new Vector3( [ 0.0, 0.0, 0.0 ] );
this.transform.scale = new Vector3( [ 1.0, 1.0, 1.0 ] );
// -- geometry ---------------------------------------------------------------------------------
const cube = genCube( { dimension: [ 100.0, 1.0, 100.0 ] } );
const geometry = new Geometry();
geometry.vao.bindVertexbuffer( cube.position, 0, 3 );
geometry.vao.bindIndexbuffer( cube.index );
geometry.count = cube.count;
geometry.mode = cube.mode;
geometry.indexType = cube.indexType;
// -- materials --------------------------------------------------------------------------------
const forward = new Material(
raymarchObjectVert,
cyclicBoardFrag,
{
defines: [ 'FORWARD 1' ],
initOptions: { geometry, target: dummyRenderTarget },
},
);
const deferred = new Material(
raymarchObjectVert,
cyclicBoardFrag,
{
defines: [ 'DEFERRED 1' ],
initOptions: { geometry, target: dummyRenderTargetFourDrawBuffers },
},
);
// it was way too expensive,,,
// const depth = new Material(
// raymarchObjectVert,
// cyclicBoardFrag,
// {
// defines: [ 'DEPTH 1' ],
// initOptions: { geometry, target: dummyRenderTarget }
// },
// );
const materials = { cubemap: forward, deferred };
if ( process.env.DEV ) {
if ( module.hot ) {
module.hot.accept( '../shaders/cyclic-board.frag', () => {
forward.replaceShader( raymarchObjectVert, cyclicBoardFrag );
deferred.replaceShader( raymarchObjectVert, cyclicBoardFrag );
// depth.replaceShader( raymarchObjectVert, cyclicBoardFrag );
} );
}
}
// -- forward lights ---------------------------------------------------------------------------
this.components.push( new Lambda( {
onDraw: ( { frameCount } ) => {
setLightUniforms( forward, this.lights, frameCount );
},
name: process.env.DEV && 'CyclicBoard/setLightUniforms',
} ) );
// -- updater ----------------------------------------------------------------------------------
this.components.push( new Lambda( {
onDraw: ( event ) => {
objectValuesMap( materials, ( material ) => {
material.addUniform(
'cameraNearFar',
'2f',
event.camera.near,
event.camera.far
);
material.addUniformMatrixVector(
'inversePVM',
'Matrix4fv',
event.projectionMatrix
.multiply( event.viewMatrix )
.multiply( event.globalTransform.matrix )
.inverse!
.elements
);
} );
},
name: process.env.DEV && 'CyclicBoard/updater',
} ) );
// -- mesh -------------------------------------------------------------------------------------
const mesh = new Mesh( {
geometry,
materials,
name: process.env.DEV && 'CyclicBoard/mesh',
} );
mesh.cull = MeshCull.None;
this.components.push( mesh );
}
}

View File

@@ -12,6 +12,7 @@ import { dummyRenderTarget } from '../globals/dummyRenderTarget';
import { gl } from '../globals/canvas'; import { gl } from '../globals/canvas';
import { quadGeometry } from '../globals/quadGeometry'; import { quadGeometry } from '../globals/quadGeometry';
import { randomTexture } from '../globals/randomTexture'; import { randomTexture } from '../globals/randomTexture';
import { setLightUniforms } from '../utils/setLightUniforms';
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';
@@ -111,18 +112,8 @@ export class DeferredCamera extends Entity {
const lambda = new Lambda( { const lambda = new Lambda( {
onUpdate: ( { frameCount } ) => { onUpdate: ( { frameCount } ) => {
const lights = options.lights.filter( ( light ) => (
frameCount === light.lastUpdateFrame
) );
const cameraView = this.transform.matrix.inverse!; const cameraView = this.transform.matrix.inverse!;
shadingMaterial.addUniform(
'lightCount',
'1i',
lights.length,
);
shadingMaterial.addUniformMatrixVector( shadingMaterial.addUniformMatrixVector(
'cameraView', 'cameraView',
'Matrix4fv', 'Matrix4fv',
@@ -150,44 +141,7 @@ export class DeferredCamera extends Entity {
...this.transform.position.elements ...this.transform.position.elements
); );
shadingMaterial.addUniformVector( setLightUniforms( shadingMaterial, options.lights, frameCount );
'lightNearFar',
'2fv',
lights.map( ( light ) => [ light.camera.near, light.camera.far ] ).flat(),
);
shadingMaterial.addUniformVector(
'lightPos',
'3fv',
lights.map( ( light ) => light.globalTransformCache.position.elements ).flat(),
);
shadingMaterial.addUniformVector(
'lightColor',
'3fv',
lights.map( ( light ) => light.color ).flat(),
);
shadingMaterial.addUniformVector(
'lightParams',
'4fv',
lights.map( ( light ) => [ light.spotness, 0.0, 0.0, 0.0 ] ).flat(),
);
shadingMaterial.addUniformMatrixVector(
'lightPV',
'Matrix4fv',
lights.map( ( light ) => (
light.camera.projectionMatrix.multiply(
light.globalTransformCache.matrix.inverse!
).elements
) ).flat(),
);
shadingMaterial.addUniformTextureArray(
'samplerShadow',
lights.map( ( light ) => light.shadowMap.texture ),
);
}, },
name: process.env.DEV && 'DeferredCamera/shading/setCameraUniforms', name: process.env.DEV && 'DeferredCamera/shading/setCameraUniforms',
} ); } );

View File

@@ -0,0 +1,92 @@
import { Entity } from '../heck/Entity';
import { Geometry } from '../heck/Geometry';
import { Lambda } from '../heck/components/Lambda';
import { Material } from '../heck/Material';
import { Mesh } from '../heck/components/Mesh';
import { Quaternion, Vector3 } from '@fms-cat/experimental';
import { auto } from '../globals/automaton';
import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget';
import { genOctahedron } from '../geometries/genOctahedron';
import { objectValuesMap } from '../utils/objectEntriesMap';
import { quadGeometry } from '../globals/quadGeometry';
import depthFrag from '../shaders/depth.frag';
import flashyBallFrag from '../shaders/flashy-ball.frag';
import flashyBallVert from '../shaders/flashy-ball.vert';
export class FlashyBall extends Entity {
public mesh: Mesh;
public constructor() {
super();
// -- geometry ---------------------------------------------------------------------------------
const octahedron = genOctahedron( { div: 5 } );
const geometry = new Geometry();
geometry.vao.bindVertexbuffer( octahedron.position, 0, 3 );
geometry.vao.bindVertexbuffer( octahedron.normal, 1, 3 );
geometry.vao.bindIndexbuffer( octahedron.index );
geometry.count = octahedron.count;
geometry.mode = octahedron.mode;
geometry.indexType = octahedron.indexType;
// -- materials --------------------------------------------------------------------------------
const deferred = new Material(
flashyBallVert,
flashyBallFrag,
{
defines: [ 'DEFERRED 1' ],
initOptions: { geometry: quadGeometry, target: dummyRenderTargetFourDrawBuffers },
},
);
const depth = new Material(
flashyBallVert,
depthFrag,
{ initOptions: { geometry: quadGeometry, target: dummyRenderTarget } },
);
const materials = { deferred, depth };
if ( process.env.DEV ) {
if ( module.hot ) {
module.hot.accept(
[
'../shaders/flashy-ball.vert',
'../shaders/flashy-ball.frag',
],
() => {
deferred.replaceShader( flashyBallVert, flashyBallFrag );
depth.replaceShader( flashyBallVert, depthFrag );
},
);
}
}
// -- mesh -------------------------------------------------------------------------------------
this.mesh = new Mesh( {
geometry,
materials,
name: process.env.DEV && 'FlashyBall/mesh',
} );
this.components.push( this.mesh );
// -- speen ------------------------------------------------------------------------------------
const axis = new Vector3( [ 1.0, -1.0, 1.0 ] ).normalized;
this.components.push( new Lambda( {
onUpdate: ( { time } ) => {
this.transform.rotation = Quaternion.fromAxisAngle( axis, time );
objectValuesMap( materials, ( material ) => {
material.addUniform(
'distort',
'1f',
auto( 'FlashyBall/distortAmp' )
);
} );
},
name: process.env.DEV && 'FlashyBall/update',
} ) );
}
}

View File

@@ -66,7 +66,7 @@ const styles = [
}, },
{ {
font: '96px Arial', font: '96px Arial',
spacing: 2.0, spacing: 1.3,
}, },
{ {
font: 'Bold 96px Arial', font: 'Bold 96px Arial',
@@ -89,7 +89,8 @@ const styles = [
}, },
{ {
font: 'Bold 96px Arial', font: 'Bold 96px Arial',
spacing: 1.5, scaleY: 1.2,
spacing: 1.4,
}, },
{ {
font: 'Bold 96px Arial', font: 'Bold 96px Arial',
@@ -157,30 +158,40 @@ const charPosList = [
'0x4015', '0x4015',
'Alcatraz', 'Alcatraz',
'Altair', 'Altair',
'ASD',
'Astronomena', 'Astronomena',
'CNCD', 'CNCD',
'Cocoon', 'Cocoon',
'Conspiracy', 'Conspiracy',
'Ctrl+Alt+Test',
'doxas',
'Fairlight', 'Fairlight',
'Flopine', 'Flopine',
'FRONTL1NE', 'FRONTL1NE',
'holon', 'holon',
'gam0022', 'gam0022',
'gaz',
'jetlag', 'jetlag',
'Jugem-T', 'Jugem-T',
'kaneta', 'kaneta',
'Limp Ninja', 'Limp Ninja',
'LJ', 'LJ',
'Logicoma', 'Logicoma',
'marcan',
'Mercury', 'Mercury',
'mrdoob',
'nikq::cube', 'nikq::cube',
'Ninjadev', 'Ninjadev',
'NuSan', 'NuSan',
'orange',
'Poo-Brain', 'Poo-Brain',
'Primitive',
'Prismbeings', 'Prismbeings',
'Radium Software', 'Radium Software',
'quite',
'rgba', 'rgba',
'Satori', 'Satori',
'setchi',
'sp4ghet', 'sp4ghet',
'Still', 'Still',
'Suricrasia Online', 'Suricrasia Online',
@@ -281,7 +292,7 @@ export class Greetings extends Entity {
const lambda = new Lambda( { const lambda = new Lambda( {
onUpdate: ( { time, deltaTime } ) => { onUpdate: ( { time, deltaTime } ) => {
if ( Math.floor( 6.0 * time ) === Math.floor( 6.0 * ( time - deltaTime ) ) ) { if ( Math.floor( 8.0 * time ) === Math.floor( 8.0 * ( time - deltaTime ) ) ) {
return; return;
} }

112
src/entities/IFSAsUsual.ts Normal file
View File

@@ -0,0 +1,112 @@
import { Entity } from '../heck/Entity';
import { Geometry } from '../heck/Geometry';
import { Lambda } from '../heck/components/Lambda';
import { Material } from '../heck/Material';
import { Mesh, MeshCull } from '../heck/components/Mesh';
import { Quaternion, Vector3 } from '@fms-cat/experimental';
import { auto } from '../globals/automaton';
import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget';
import { genCube } from '../geometries/genCube';
import { objectValuesMap } from '../utils/objectEntriesMap';
import { randomTexture, randomTextureStatic } from '../globals/randomTexture';
import ifsAsUsualFrag from '../shaders/ifs-as-usual.frag';
import raymarchObjectVert from '../shaders/raymarch-object.vert';
export class IFSAsUsual extends Entity {
public constructor() {
super();
// -- geometry ---------------------------------------------------------------------------------
const cube = genCube( { dimension: [ 1.1, 1.1, 1.1 ] } );
const geometry = new Geometry();
geometry.vao.bindVertexbuffer( cube.position, 0, 3 );
geometry.vao.bindIndexbuffer( cube.index );
geometry.count = cube.count;
geometry.mode = cube.mode;
geometry.indexType = cube.indexType;
// -- materials --------------------------------------------------------------------------------
const deferred = new Material(
raymarchObjectVert,
ifsAsUsualFrag,
{
defines: [ 'DEFERRED 1' ],
initOptions: { geometry, target: dummyRenderTargetFourDrawBuffers },
},
);
const depth = new Material(
raymarchObjectVert,
ifsAsUsualFrag,
{
defines: [ 'DEPTH 1' ],
initOptions: { geometry, target: dummyRenderTarget }
},
);
const materials = { deferred, depth };
if ( process.env.DEV ) {
if ( module.hot ) {
module.hot.accept( '../shaders/ifs-as-usual.frag', () => {
deferred.replaceShader( raymarchObjectVert, ifsAsUsualFrag );
depth.replaceShader( raymarchObjectVert, ifsAsUsualFrag );
} );
}
}
objectValuesMap( materials, ( material ) => {
material.addUniformTexture( 'samplerRandom', randomTexture.texture );
material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
} );
// -- updater ----------------------------------------------------------------------------------
this.components.push( new Lambda( {
onDraw: ( event ) => {
objectValuesMap( materials, ( material ) => {
material.addUniform(
'cameraNearFar',
'2f',
event.camera.near,
event.camera.far
);
material.addUniformMatrixVector(
'inversePVM',
'Matrix4fv',
event.projectionMatrix
.multiply( event.viewMatrix )
.multiply( event.globalTransform.matrix )
.inverse!
.elements
);
} );
},
name: process.env.DEV && 'IFSAsUsual/updater',
} ) );
// -- mesh -------------------------------------------------------------------------------------
const mesh = new Mesh( {
geometry,
materials,
name: process.env.DEV && 'IFSAsUsual/mesh',
} );
mesh.cull = MeshCull.None;
this.components.push( mesh );
// -- speen ------------------------------------------------------------------------------------
const axis = new Vector3( [ 1.0, -1.0, 1.0 ] ).normalized;
this.components.push( new Lambda( {
onUpdate: ( { time } ) => {
this.transform.rotation = Quaternion.fromAxisAngle( axis, time );
objectValuesMap( materials, ( material ) => {
material.addUniform( 'ifsSeed', '1f', auto( 'IFSAsUsual/ifsSeed' ) );
} );
},
name: process.env.DEV && 'IFSAsUsual/update',
} ) );
}
}

View File

@@ -41,7 +41,7 @@ export class IFSPistons extends Entity {
raymarchObjectVert, raymarchObjectVert,
ifsPistonFrag, ifsPistonFrag,
{ {
defines: [ 'SHADOW 1' ], defines: [ 'DEPTH 1' ],
initOptions: { geometry, target: dummyRenderTarget } initOptions: { geometry, target: dummyRenderTarget }
}, },
); );

61
src/entities/LightCube.ts Normal file
View File

@@ -0,0 +1,61 @@
import { Entity } from '../heck/Entity';
import { Geometry } from '../heck/Geometry';
import { Lambda } from '../heck/components/Lambda';
import { Material } from '../heck/Material';
import { Mesh } from '../heck/components/Mesh';
import { dummyRenderTarget } from '../globals/dummyRenderTarget';
import { genCube } from '../geometries/genCube';
import { gl } from '../globals/canvas';
import colorFrag from '../shaders/color.frag';
import objectVert from '../shaders/object.vert';
export class LightCube extends Entity {
public mesh: Mesh;
public color = [ 1.0, 1.0, 1.0 ];
private __forward: Material;
public constructor() {
super();
// -- geometry ---------------------------------------------------------------------------------
const cube = genCube( { dimension: [ 1.0, 1.0, 1.0 ] } );
const geometry = new Geometry();
geometry.vao.bindVertexbuffer( cube.position, 0, 3 );
geometry.vao.bindVertexbuffer( cube.normal, 1, 3 );
geometry.vao.bindIndexbuffer( cube.index );
geometry.count = cube.count;
geometry.mode = cube.mode;
geometry.indexType = cube.indexType;
// -- materials --------------------------------------------------------------------------------
const forward = this.__forward = new Material(
objectVert,
colorFrag,
{
blend: [ gl.ONE, gl.ONE ],
initOptions: { geometry, target: dummyRenderTarget },
},
);
const materials = { forward, cubemap: forward };
// -- updater ----------------------------------------------------------------------------------
this.components.push( new Lambda( {
onUpdate: () => {
this.__forward.addUniform( 'color', '4f', ...this.color, 1.0 );
},
name: 'LightBar/updater',
} ) );
// -- mesh -------------------------------------------------------------------------------------
this.mesh = new Mesh( {
geometry,
materials,
name: process.env.DEV && 'LightBar/mesh',
} );
this.components.push( this.mesh );
}
}

108
src/entities/NoiseVoxels.ts Normal file
View File

@@ -0,0 +1,108 @@
import { Entity } from '../heck/Entity';
import { InstancedGeometry } from '../heck/InstancedGeometry';
import { Lambda } from '../heck/components/Lambda';
import { Material } from '../heck/Material';
import { Mesh } from '../heck/components/Mesh';
import { Quaternion, Vector3, matrix3d } from '@fms-cat/experimental';
import { auto } from '../globals/automaton';
import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget';
import { genCube } from '../geometries/genCube';
import { glCat } from '../globals/canvas';
import { objectValuesMap } from '../utils/objectEntriesMap';
import { quadGeometry } from '../globals/quadGeometry';
import depthFrag from '../shaders/depth.frag';
import noiseVoxelsFrag from '../shaders/noise-voxels.frag';
import noiseVoxelsVert from '../shaders/noise-voxels.vert';
const CUBE_PER_AXIS = 8;
const PRIMCOUNT = CUBE_PER_AXIS * CUBE_PER_AXIS * CUBE_PER_AXIS;
export class NoiseVoxels extends Entity {
public mesh: Mesh;
public constructor() {
super();
this.transform.scale = Vector3.one.scale( 0.7 );
// -- updater ----------------------------------------------------------------------------------
this.components.push( new Lambda( {
onUpdate: ( { time } ) => {
this.transform.rotation = Quaternion.fromAxisAngle(
new Vector3( [ 1.0, 0.5, -2.0 ] ).normalized,
0.4 * time,
).multiply( Quaternion.fromAxisAngle(
new Vector3( [ 0.0, 1.0, 0.2 ] ).normalized,
time,
) );
},
} ) );
// -- geometry ---------------------------------------------------------------------------------
const cube = genCube();
const geometry = new InstancedGeometry();
geometry.vao.bindVertexbuffer( cube.position, 0, 3 );
geometry.vao.bindVertexbuffer( cube.normal, 1, 3 );
geometry.vao.bindIndexbuffer( cube.index );
const arrayInstancePos = matrix3d( CUBE_PER_AXIS, CUBE_PER_AXIS, CUBE_PER_AXIS );
const bufferInstancePos = glCat.createBuffer();
bufferInstancePos.setVertexbuffer( new Float32Array( arrayInstancePos ) );
geometry.vao.bindVertexbuffer( bufferInstancePos, 2, 3, 1 );
geometry.count = cube.count;
geometry.mode = cube.mode;
geometry.indexType = cube.indexType;
geometry.primcount = PRIMCOUNT;
// -- materials --------------------------------------------------------------------------------
const deferred = new Material(
noiseVoxelsVert,
noiseVoxelsFrag,
{
defines: [ 'DEFERRED 1' ],
initOptions: { geometry: quadGeometry, target: dummyRenderTargetFourDrawBuffers },
},
);
const depth = new Material(
noiseVoxelsVert,
depthFrag,
{ initOptions: { geometry: quadGeometry, target: dummyRenderTarget } },
);
const materials = { deferred, depth };
if ( process.env.DEV ) {
if ( module.hot ) {
module.hot.accept(
[
'../shaders/noise-voxels.vert',
'../shaders/noise-voxels.frag',
],
() => {
deferred.replaceShader( noiseVoxelsVert, noiseVoxelsFrag );
depth.replaceShader( noiseVoxelsVert, depthFrag );
},
);
}
}
// -- auto -------------------------------------------------------------------------------------
auto( 'NoiseVoxels/phase', ( { value } ) => {
objectValuesMap( materials, ( material ) => {
material.addUniform( 'phase', '1f', value );
} );
} );
// -- mesh -------------------------------------------------------------------------------------
this.mesh = new Mesh( {
geometry: geometry,
materials,
name: process.env.DEV && 'NoiseVoxels/mesh',
} );
this.components.push( this.mesh );
}
}

View File

@@ -3,13 +3,13 @@ import { Entity } from '../heck/Entity';
import { Lambda } from '../heck/components/Lambda'; import { Lambda } from '../heck/components/Lambda';
import { Material } from '../heck/Material'; import { Material } from '../heck/Material';
import { Mesh } from '../heck/components/Mesh'; import { Mesh } from '../heck/components/Mesh';
import { auto } from '../globals/automaton';
import { dummyRenderTarget } from '../globals/dummyRenderTarget'; import { dummyRenderTarget } from '../globals/dummyRenderTarget';
import { gl } from '../globals/canvas'; import { gl } from '../globals/canvas';
import { quadGeometry } from '../globals/quadGeometry'; import { quadGeometry } from '../globals/quadGeometry';
import { randomTexture } from '../globals/randomTexture'; import { randomTexture } from '../globals/randomTexture';
import phantomFrag from '../shaders/phantom.frag'; import phantomFrag from '../shaders/phantom.frag';
import quadVert from '../shaders/quad.vert'; import quadVert from '../shaders/quad.vert';
import { auto } from '../globals/automaton';
export class Phantom extends Entity { export class Phantom extends Entity {
private __forward: Material; private __forward: Material;
@@ -65,9 +65,11 @@ export class Phantom extends Entity {
this.components.push( mesh ); this.components.push( mesh );
// -- auto ------------------------------------------------------------------------------------- // -- auto -------------------------------------------------------------------------------------
auto( 'Phantom/active', ( { uninit } ) => { auto( 'Phantom/amp', ( { value } ) => {
mesh.active = !uninit; forward.addUniform( 'amp', '1f', value );
mesh.visible = !uninit;
mesh.active = value > 0.0;
mesh.visible = mesh.active;
} ); } );
} }

View File

@@ -1,44 +1,44 @@
import { Entity } from '../heck/Entity'; import { Entity } from '../heck/Entity';
import { Geometry } from '../heck/Geometry'; import { InstancedGeometry } from '../heck/InstancedGeometry';
import { Material } from '../heck/Material'; import { Material } from '../heck/Material';
import { Mesh } from '../heck/components/Mesh'; import { Mesh } from '../heck/components/Mesh';
import { Quaternion, Vector3 } from '@fms-cat/experimental';
import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget'; import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget';
import { genPlane } from '../geometries/genPlane'; import { genCube } from '../geometries/genCube';
import { glCat } from '../globals/canvas';
import { quadGeometry } from '../globals/quadGeometry'; import { quadGeometry } from '../globals/quadGeometry';
import depthFrag from '../shaders/depth.frag'; import depthFrag from '../shaders/depth.frag';
import flashyTerrainFrag from '../shaders/flashy-terrain.frag'; import rectTorusFrag from '../shaders/rect-torus.frag';
import flashyTerrainVert from '../shaders/flashy-terrain.vert'; import rectTorusVert from '../shaders/rect-torus.vert';
export class FlashyTerrain extends Entity { export class RectTorus extends Entity {
public mesh: Mesh; public mesh: Mesh;
public constructor() { public constructor() {
super(); super();
this.transform.position = new Vector3( [ 0.0, -4.0, 0.0 ] );
this.transform.rotation = Quaternion.fromAxisAngle(
new Vector3( [ 1.0, 0.0, 0.0 ] ),
-0.5 * Math.PI,
);
this.transform.scale = this.transform.scale.scale( 8.0 );
// -- geometry --------------------------------------------------------------------------------- // -- geometry ---------------------------------------------------------------------------------
const plane = genPlane(); const cube = genCube();
const geometry = new Geometry(); const geometry = new InstancedGeometry();
geometry.vao.bindVertexbuffer( plane.position, 0, 3 ); geometry.vao.bindVertexbuffer( cube.position, 0, 3 );
geometry.vao.bindIndexbuffer( plane.index ); geometry.vao.bindVertexbuffer( cube.normal, 1, 3 );
geometry.vao.bindIndexbuffer( cube.index );
geometry.count = plane.count; const arrayInstanceId = [ ...Array( 4 ).keys() ];
geometry.mode = plane.mode; const bufferInstanceId = glCat.createBuffer();
geometry.indexType = plane.indexType; bufferInstanceId.setVertexbuffer( new Float32Array( arrayInstanceId ) );
geometry.vao.bindVertexbuffer( bufferInstanceId, 2, 1, 1 );
geometry.count = cube.count;
geometry.mode = cube.mode;
geometry.indexType = cube.indexType;
geometry.primcount = 4;
// -- materials -------------------------------------------------------------------------------- // -- materials --------------------------------------------------------------------------------
const deferred = new Material( const deferred = new Material(
flashyTerrainVert, rectTorusVert,
flashyTerrainFrag, rectTorusFrag,
{ {
defines: [ 'DEFERRED 1' ], defines: [ 'DEFERRED 1' ],
initOptions: { geometry: quadGeometry, target: dummyRenderTargetFourDrawBuffers }, initOptions: { geometry: quadGeometry, target: dummyRenderTargetFourDrawBuffers },
@@ -46,7 +46,7 @@ export class FlashyTerrain extends Entity {
); );
const depth = new Material( const depth = new Material(
flashyTerrainVert, rectTorusVert,
depthFrag, depthFrag,
{ initOptions: { geometry: quadGeometry, target: dummyRenderTarget } }, { initOptions: { geometry: quadGeometry, target: dummyRenderTarget } },
); );
@@ -57,12 +57,12 @@ export class FlashyTerrain extends Entity {
if ( module.hot ) { if ( module.hot ) {
module.hot.accept( module.hot.accept(
[ [
'../shaders/flashy-terrain.vert', '../shaders/rect-torus.vert',
'../shaders/flashy-terrain.frag', '../shaders/rect-torus.frag',
], ],
() => { () => {
deferred.replaceShader( flashyTerrainVert, flashyTerrainFrag ); deferred.replaceShader( rectTorusVert, rectTorusFrag );
depth.replaceShader( flashyTerrainVert, depthFrag ); depth.replaceShader( rectTorusVert, depthFrag );
}, },
); );
} }
@@ -70,9 +70,9 @@ export class FlashyTerrain extends Entity {
// -- mesh ------------------------------------------------------------------------------------- // -- mesh -------------------------------------------------------------------------------------
this.mesh = new Mesh( { this.mesh = new Mesh( {
geometry, geometry: geometry,
materials, materials,
name: process.env.DEV && 'FlashyTerrain/mesh', name: process.env.DEV && 'Cube/mesh',
} ); } );
this.components.push( this.mesh ); this.components.push( this.mesh );
} }

View File

@@ -2,9 +2,11 @@ import { Entity } from '../heck/Entity';
import { InstancedGeometry } from '../heck/InstancedGeometry'; import { InstancedGeometry } from '../heck/InstancedGeometry';
import { Material } from '../heck/Material'; import { Material } from '../heck/Material';
import { Mesh } from '../heck/components/Mesh'; import { Mesh } from '../heck/components/Mesh';
import { auto } from '../globals/automaton';
import { dummyRenderTarget } from '../globals/dummyRenderTarget'; import { dummyRenderTarget } from '../globals/dummyRenderTarget';
import { genTorus } from '../geometries/genTorus'; import { genTorus } from '../geometries/genTorus';
import { glCat } from '../globals/canvas'; import { glCat } from '../globals/canvas';
import { objectValuesMap } from '../utils/objectEntriesMap';
import depthFrag from '../shaders/depth.frag'; import depthFrag from '../shaders/depth.frag';
import ringsFrag from '../shaders/rings.frag'; import ringsFrag from '../shaders/rings.frag';
import ringsVert from '../shaders/rings.vert'; import ringsVert from '../shaders/rings.vert';
@@ -82,6 +84,13 @@ export class Rings extends Entity {
} }
} }
// -- begin ------------------------------------------------------------------------------------
auto( 'Rings/begin', ( { value } ) => {
objectValuesMap( materials, ( material ) => {
material.addUniform( 'begin', '1f', value );
} );
} );
// -- mesh ------------------------------------------------------------------------------------- // -- mesh -------------------------------------------------------------------------------------
const mesh = new Mesh( { const mesh = new Mesh( {
geometry, geometry,

View File

@@ -4,15 +4,20 @@ import { Entity } from '../heck/Entity';
import { LightEntity } from './LightEntity'; import { LightEntity } from './LightEntity';
import { Vector3 } from '@fms-cat/experimental'; import { Vector3 } from '@fms-cat/experimental';
interface SceneBeginOptions {
scenes: Entity[];
}
export class SceneBegin extends Entity { export class SceneBegin extends Entity {
public readonly lights: LightEntity[]; public readonly lights: LightEntity[];
public constructor() { public constructor( { scenes }: SceneBeginOptions ) {
super(); super();
// -- lights ----------------------------------------------------------------------------------- // -- lights -----------------------------------------------------------------------------------
const light1 = new LightEntity( { const light1 = new LightEntity( {
scenes: [ this ], scenes,
shadowMapFov: 30.0, shadowMapFov: 30.0,
shadowMapNear: 1.0, shadowMapNear: 1.0,
shadowMapFar: 20.0, shadowMapFar: 20.0,
@@ -22,7 +27,7 @@ export class SceneBegin extends Entity {
light1.transform.lookAt( new Vector3( [ 4.0, 4.0, 4.0 ] ) ); light1.transform.lookAt( new Vector3( [ 4.0, 4.0, 4.0 ] ) );
const light2 = new LightEntity( { const light2 = new LightEntity( {
scenes: [ this ], scenes,
shadowMapFov: 30.0, shadowMapFov: 30.0,
shadowMapNear: 1.0, shadowMapNear: 1.0,
shadowMapFar: 20.0, shadowMapFar: 20.0,

View File

@@ -10,11 +10,15 @@ import { Quaternion, Vector3, Xorshift } from '@fms-cat/experimental';
import { Rings } from './Rings'; import { Rings } from './Rings';
import { auto } from '../globals/automaton'; import { auto } from '../globals/automaton';
interface SceneCrystalsOptions {
scenes: Entity[];
}
export class SceneCrystals extends Entity { export class SceneCrystals extends Entity {
public readonly lights: LightEntity[]; public readonly lights: LightEntity[];
private __phantom: Phantom; private __phantom: Phantom;
public constructor() { public constructor( { scenes }: SceneCrystalsOptions ) {
super(); super();
// -- crystals --------------------------------------------------------------------------------- // -- crystals ---------------------------------------------------------------------------------
@@ -79,15 +83,19 @@ export class SceneCrystals extends Entity {
// -- lights ----------------------------------------------------------------------------------- // -- lights -----------------------------------------------------------------------------------
const light1 = new LightEntity( { const light1 = new LightEntity( {
scenes: [ this ], scenes,
shadowMapFov: 30.0, shadowMapFov: 30.0,
shadowMapNear: 1.0, shadowMapNear: 1.0,
shadowMapFar: 20.0, shadowMapFar: 20.0,
namePrefix: process.env.DEV && 'lightBegin1', namePrefix: process.env.DEV && 'lightCrystals1',
} ); } );
light1.color = [ 400.0, 400.0, 400.0 ]; light1.color = [ 400.0, 400.0, 400.0 ];
light1.transform.lookAt( new Vector3( [ 0.0, 4.0, 1.0 ] ) ); light1.transform.lookAt( new Vector3( [ 0.0, 4.0, 1.0 ] ) );
auto( 'SceneCrystals/light/amp', ( { value } ) => {
light1.color = [ 400.0 * value, 400.0 * value, 400.0 * value ];
} );
this.lights = [ light1 ]; this.lights = [ light1 ];
// -- children --------------------------------------------------------------------------------- // -- children ---------------------------------------------------------------------------------

View File

@@ -0,0 +1,91 @@
import { BufferRenderTarget } from '../heck/BufferRenderTarget';
import { CyclicBoard } from './CyclicBoard';
import { Entity } from '../heck/Entity';
import { LightEntity } from './LightEntity';
import { LightShaft } from './LightShaft';
import { Quaternion, Vector3 } from '@fms-cat/experimental';
import { RectTorus } from './RectTorus';
interface SceneDynamicOptions {
scenes: Entity[];
}
export class SceneDynamic extends Entity {
public readonly lights: LightEntity[];
private readonly __shafts: LightShaft[];
public constructor( { scenes }: SceneDynamicOptions ) {
super();
// -- rectTorus --------------------------------------------------------------------------------
const rectToruses = [ ...new Array( 4 ).keys() ].map( ( i ) => {
const rectTorus = new RectTorus();
rectTorus.transform.position = new Vector3( [ 0.0, 0.0, -0.5 - 0.5 * i ] );
rectTorus.transform.rotation = Quaternion.fromAxisAngle(
new Vector3( [ 1.0, 0.0, 0.0 ] ).normalized,
1.57
).multiply( Quaternion.fromAxisAngle(
new Vector3( [ 0.0, 1.0, 0.0 ] ).normalized,
i
).multiply( Quaternion.fromAxisAngle(
new Vector3( [ 1.0, 0.0, 1.0 ] ).normalized,
0.1
) ) );
return rectTorus;
} );
// -- cyclic board -----------------------------------------------------------------------------
const cyclicBoard = new CyclicBoard();
cyclicBoard.transform.position = new Vector3( [ 0.0, -2.0, 0.0 ] );
// -- lights -----------------------------------------------------------------------------------
this.__shafts = [];
const light1 = new LightEntity( {
scenes,
shadowMapFov: 70.0,
shadowMapNear: 1.0,
shadowMapFar: 20.0,
namePrefix: process.env.DEV && 'lightDynamic1',
} );
light1.color = [ 50.0, 50.0, 50.0 ];
light1.transform.lookAt( new Vector3( [ 5.0, 5.0, 5.0 ] ) );
const light2 = new LightEntity( {
scenes,
shadowMapFov: 30.0,
shadowMapNear: 1.0,
shadowMapFar: 20.0,
namePrefix: process.env.DEV && 'lightDynamic2',
} );
light2.spotness = 0.9;
light2.color = [ 300.0, 360.0, 400.0 ];
light2.transform.lookAt( new Vector3( [ 0.0, 6.0, 1.0 ] ) );
const shaft = new LightShaft( {
light: light2,
namePrefix: process.env.DEV && 'sceneDynamic/light2/Shaft',
intensity: 0.06,
} );
light2.children.push( shaft );
this.__shafts.push( shaft );
this.lights = [ light1, light2 ];
cyclicBoard.lights.push( ...this.lights );
// -- scene ------------------------------------------------------------------------------------
this.children.push(
...rectToruses,
cyclicBoard,
...this.lights,
);
}
public setDefferedCameraTarget( deferredCameraTarget: BufferRenderTarget ): void {
this.__shafts.map( ( shaft ) => {
shaft.setDefferedCameraTarget( deferredCameraTarget );
} );
}
}

View File

@@ -8,11 +8,15 @@ import { Quaternion, Vector3 } from '@fms-cat/experimental';
import { SufferTexts } from './SufferTexts'; import { SufferTexts } from './SufferTexts';
import { Wobbleball } from './Wobbleball'; import { Wobbleball } from './Wobbleball';
interface SceneNeuroOptions {
scenes: Entity[];
}
export class SceneNeuro extends Entity { export class SceneNeuro extends Entity {
public readonly lights: LightEntity[]; public readonly lights: LightEntity[];
private readonly __shafts: LightShaft[]; private readonly __shafts: LightShaft[];
public constructor() { public constructor( { scenes }: SceneNeuroOptions ) {
super(); super();
// -- lights ----------------------------------------------------------------------------------- // -- lights -----------------------------------------------------------------------------------
@@ -26,7 +30,7 @@ export class SceneNeuro extends Entity {
[ [ 20.0, 20.0, 20.0 ], [ 0.0, -2.0, 4.0 ], false ], [ [ 20.0, 20.0, 20.0 ], [ 0.0, -2.0, 4.0 ], false ],
] as TypeScriptSucks ).map( ( [ color, pos, isSpot ], i ) => { ] as TypeScriptSucks ).map( ( [ color, pos, isSpot ], i ) => {
const light = new LightEntity( { const light = new LightEntity( {
scenes: [ this ], scenes,
shadowMapFov: isSpot ? 15.0 : 50.0, shadowMapFov: isSpot ? 15.0 : 50.0,
shadowMapNear: 0.5, shadowMapNear: 0.5,
shadowMapFar: 20.0, shadowMapFar: 20.0,
@@ -35,7 +39,7 @@ export class SceneNeuro extends Entity {
} ); } );
light.color = color; light.color = color;
light.spotness = isSpot ? 0.99 : 0.0; light.spotness = isSpot ? 0.9 : 0.0;
light.transform.lookAt( new Vector3( pos ) ); light.transform.lookAt( new Vector3( pos ) );
if ( isSpot ) { if ( isSpot ) {

View File

View File

@@ -1,10 +1,11 @@
import { AutomatonWithGUI } from '@fms-cat/automaton-with-gui';
import { Entity } from '../heck/Entity'; import { Entity } from '../heck/Entity';
import { GPUParticles } from './GPUParticles'; import { GPUParticles } from './GPUParticles';
import { InstancedGeometry } from '../heck/InstancedGeometry'; import { InstancedGeometry } from '../heck/InstancedGeometry';
import { Lambda } from '../heck/components/Lambda'; 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, automaton } from '../globals/automaton';
import { dummyRenderTarget } 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';
@@ -141,6 +142,20 @@ export class SufferTexts extends Entity {
name: process.env.DEV && 'SufferTexts/logic', name: process.env.DEV && 'SufferTexts/logic',
} ) ); } ) );
if ( process.env.DEV ) {
( automaton as AutomatonWithGUI ).on( 'play', () => {
this.queue = [];
} );
( automaton as AutomatonWithGUI ).on( 'pause', () => {
this.queue = [];
} );
( automaton as AutomatonWithGUI ).on( 'seek', () => {
this.queue = [];
} );
}
// -- gpu particles ---------------------------------------------------------------------------- // -- gpu particles ----------------------------------------------------------------------------
const gpuParticles = new GPUParticles( { const gpuParticles = new GPUParticles( {
materialCompute, materialCompute,

120
src/entities/Tetrahedron.ts Normal file
View File

@@ -0,0 +1,120 @@
import { Entity } from '../heck/Entity';
import { Geometry } from '../heck/Geometry';
import { Lambda } from '../heck/components/Lambda';
import { Material } from '../heck/Material';
import { Mesh, MeshCull } from '../heck/components/Mesh';
import { Quaternion, Vector3 } from '@fms-cat/experimental';
import { auto } from '../globals/automaton';
import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget';
import { genCube } from '../geometries/genCube';
import { objectValuesMap } from '../utils/objectEntriesMap';
import { randomTexture, randomTextureStatic } from '../globals/randomTexture';
import raymarchObjectVert from '../shaders/raymarch-object.vert';
import tetrahedronFrag from '../shaders/tetrahedron.frag';
export class Tetrahedron extends Entity {
public constructor() {
super();
// -- geometry ---------------------------------------------------------------------------------
const cube = genCube( { dimension: [ 1.1, 1.1, 1.1 ] } );
const geometry = new Geometry();
geometry.vao.bindVertexbuffer( cube.position, 0, 3 );
geometry.vao.bindIndexbuffer( cube.index );
geometry.count = cube.count;
geometry.mode = cube.mode;
geometry.indexType = cube.indexType;
// -- materials --------------------------------------------------------------------------------
const deferred = new Material(
raymarchObjectVert,
tetrahedronFrag,
{
defines: [ 'DEFERRED 1' ],
initOptions: { geometry, target: dummyRenderTargetFourDrawBuffers },
},
);
const depth = new Material(
raymarchObjectVert,
tetrahedronFrag,
{
defines: [ 'DEPTH 1' ],
initOptions: { geometry, target: dummyRenderTarget }
},
);
const materials = { deferred, depth };
if ( process.env.DEV ) {
if ( module.hot ) {
module.hot.accept( '../shaders/tetrahedron.frag', () => {
deferred.replaceShader( raymarchObjectVert, tetrahedronFrag );
depth.replaceShader( raymarchObjectVert, tetrahedronFrag );
} );
}
}
objectValuesMap( materials, ( material ) => {
material.addUniformTexture( 'samplerRandom', randomTexture.texture );
material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
} );
// -- updater ----------------------------------------------------------------------------------
this.components.push( new Lambda( {
onDraw: ( event ) => {
objectValuesMap( materials, ( material ) => {
material.addUniform(
'cameraNearFar',
'2f',
event.camera.near,
event.camera.far
);
material.addUniformMatrixVector(
'inversePVM',
'Matrix4fv',
event.projectionMatrix
.multiply( event.viewMatrix )
.multiply( event.globalTransform.matrix )
.inverse!
.elements
);
material.addUniform( 'deformAmp', '1f', auto( 'Music/NEURO_WUB_AMP' ) );
material.addUniform( 'deformFreq', '1f', auto( 'Music/NEURO_WUB_FREQ' ) + auto( 'Music/NEURO_DETUNE' ) );
material.addUniform( 'deformTime', '1f', auto( 'Music/NEURO_TIME' ) );
} );
},
name: process.env.DEV && 'Tetrahedron/updater',
} ) );
// -- mesh -------------------------------------------------------------------------------------
const mesh = new Mesh( {
geometry,
materials,
name: process.env.DEV && 'Tetrahedron/mesh',
} );
mesh.cull = MeshCull.None;
this.components.push( mesh );
// -- speen ------------------------------------------------------------------------------------
const axis = new Vector3( [ 1.0, -1.0, 1.0 ] ).normalized;
this.components.push( new Lambda( {
onUpdate: ( { time } ) => {
this.transform.rotation = Quaternion.fromAxisAngle( axis, time );
objectValuesMap( materials, ( material ) => {
material.addUniform(
'distort',
'1f',
auto( 'Tetrahedron/distortAmp' )
);
} );
},
name: process.env.DEV && 'Tetrahedron/update',
} ) );
}
}

View File

@@ -1,6 +1,7 @@
import { Entity } from '../heck/Entity'; import { Entity } from '../heck/Entity';
import { GPUParticles } from './GPUParticles'; import { GPUParticles } from './GPUParticles';
import { InstancedGeometry } from '../heck/InstancedGeometry'; import { InstancedGeometry } from '../heck/InstancedGeometry';
import { Lambda } from '../heck/components/Lambda';
import { Material } from '../heck/Material'; import { Material } from '../heck/Material';
import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers, dummyRenderTargetTwoDrawBuffers } from '../globals/dummyRenderTarget'; import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers, dummyRenderTargetTwoDrawBuffers } from '../globals/dummyRenderTarget';
import { gl, glCat } from '../globals/canvas'; import { gl, glCat } from '../globals/canvas';
@@ -38,6 +39,15 @@ export class Trails extends Entity {
} }
} }
// -- lambda to say update ---------------------------------------------------------------------
this.components.push( new Lambda( {
onUpdate: ( { time, deltaTime } ) => {
const shouldUpdate
= Math.floor( 60.0 * time ) !== Math.floor( 60.0 * ( time - deltaTime ) );
materialCompute.addUniform( 'shouldUpdate', '1i', shouldUpdate ? 1 : 0 );
},
} ) );
// -- geometry render -------------------------------------------------------------------------- // -- geometry render --------------------------------------------------------------------------
const geometryRender = new InstancedGeometry(); const geometryRender = new InstancedGeometry();

View File

@@ -45,7 +45,7 @@ export class Wobbleball extends Entity {
raymarchObjectVert, raymarchObjectVert,
wobbleballFrag, wobbleballFrag,
{ {
defines: [ 'SHADOW 1' ], defines: [ 'DEPTH 1' ],
initOptions: { geometry, target: dummyRenderTarget } initOptions: { geometry, target: dummyRenderTarget }
}, },
); );

View File

@@ -79,6 +79,10 @@ async function load(): Promise<void> {
( automaton as AutomatonWithGUI ).play(); ( automaton as AutomatonWithGUI ).play();
} }
if ( !process.env.DEV ) {
document.write( 'Wait a moment... ' );
}
await music.prepare(); await music.prepare();
if ( !process.env.DEV ) { if ( !process.env.DEV ) {

View File

@@ -406,24 +406,15 @@ vec2 mainAudio( vec4 time ) {
dest += 0.25 * kick( t, 1.0 ); dest += 0.25 * kick( t, 1.0 );
} }
// -- gabber ------------------------------------------------------------------------------------- // -- snare --------------------------------------------------------------------------------------
if ( if ( inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON - 4.0 * BEAT ) ) {
inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON ) && float t = mod( time.z - 4.0 * BEAT, 8.0 * BEAT );
inRange( mod( time.z, 8.0 * BEAT ), 4.0 * BEAT, 8.0 * BEAT ) dest += 0.1 * snare( t );
) {
const int pattern[16] = int[](
0, 1, 0, 1,
2, 3, 4, 0,
1, 2, 0, 1,
2, 3, 4, 5
);
float tHeadKick = 0.25 * BEAT * float( pattern[ int( time.y / 0.25 / BEAT ) ] );
float tKick = tHeadKick + mod( time.y, 0.25 * BEAT );
} }
// -- amen --------------------------------------------------------------------------------------- // -- amen ---------------------------------------------------------------------------------------
if ( if (
inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON ) && inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON - 4.0 * BEAT ) &&
inRange( mod( time.z, 8.0 * BEAT ), 4.0 * BEAT, 8.0 * BEAT ) inRange( mod( time.z, 8.0 * BEAT ), 4.0 * BEAT, 8.0 * BEAT )
) { ) {
float chunk = floor( 6.0 * fs( lofi( time.z, 0.5 * BEAT ) ) ); float chunk = floor( 6.0 * fs( lofi( time.z, 0.5 * BEAT ) ) );
@@ -473,7 +464,7 @@ vec2 mainAudio( vec4 time ) {
} }
// -- choir -------------------------------------------------------------------------------------- // -- choir --------------------------------------------------------------------------------------
if ( inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON ) ) { if ( inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON - 0.5 * BEAT ) ) {
vec2 sum = vec2( 0.0 ); vec2 sum = vec2( 0.0 );
float t = mod( time.z, 8.0 * BEAT ); float t = mod( time.z, 8.0 * BEAT );
@@ -492,7 +483,13 @@ vec2 mainAudio( vec4 time ) {
sum += 0.4 * mix( 0.0, 1.0, sidechain ) * choir( t * rate * 0.5 ); sum += 0.4 * mix( 0.0, 1.0, sidechain ) * choir( t * rate * 0.5 );
} }
dest += 0.09 * inRangeSmooth( t, 0.0, 4.0 * BEAT, 1E3 ) * aSaturate( 2.0 * sum ); float release = ( ( time.z > 60.0 * BEAT ) ? 2.0 : 1E3 );
dest += 0.09 * inRangeSmooth( t, 0.0, 4.0 * BEAT, release ) * aSaturate( 2.0 * sum );
}
// -- reversecrash -------------------------------------------------------------------------------
if ( inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON - 0.5 * BEAT ) ) {
dest += 0.1 * crash( max( 0.0, 63.5 * BEAT - time.z ) );
} }
// -- kick --------------------------------------------------------------------------------------- // -- kick ---------------------------------------------------------------------------------------
@@ -695,6 +692,10 @@ vec2 mainAudio( vec4 time ) {
dest += 0.3 * deepkick( time.z ); dest += 0.3 * deepkick( time.z );
} }
if ( inRange( time.w, SECTION_PORTER_FUCKING_ROBINSON - 4.0 * BEAT, SECTION_PORTER_FUCKING_ROBINSON - 0.5 * BEAT ) ) {
dest += 0.3 * deepkick( time.y );
}
if ( inRange( time.w, SECTION_AAAA - 8.0 * BEAT, SECTION_AAAA ) ) { if ( inRange( time.w, SECTION_AAAA - 8.0 * BEAT, SECTION_AAAA ) ) {
dest += 0.3 * deepkick( mod( time.z, 8.0 * BEAT ) ); dest += 0.3 * deepkick( mod( time.z, 8.0 * BEAT ) );
} }

View File

@@ -9,21 +9,25 @@ import { DeferredCamera } from './entities/DeferredCamera';
import { Dog } from './heck/Dog'; import { Dog } from './heck/Dog';
import { Entity } from './heck/Entity'; import { Entity } from './heck/Entity';
import { EnvironmentMap } from './entities/EnvironmentMap'; import { EnvironmentMap } from './entities/EnvironmentMap';
import { FlashyTerrain } from './entities/FlashyTerrain'; import { FlashyBall } from './entities/FlashyBall';
import { FlickyParticles } from './entities/FlickyParticles'; import { FlickyParticles } from './entities/FlickyParticles';
import { ForwardCamera } from './entities/ForwardCamera'; import { ForwardCamera } from './entities/ForwardCamera';
import { Glitch } from './entities/Glitch'; import { Glitch } from './entities/Glitch';
import { IBLLUT } from './entities/IBLLUT'; import { IBLLUT } from './entities/IBLLUT';
import { IFSAsUsual } from './entities/IFSAsUsual';
import { Lambda } from './heck/components/Lambda'; import { Lambda } from './heck/components/Lambda';
import { NoiseVoxels } from './entities/NoiseVoxels';
import { PixelSorter } from './entities/PixelSorter'; import { PixelSorter } from './entities/PixelSorter';
import { Post } from './entities/Post'; import { Post } from './entities/Post';
import { RTInspector } from './entities/RTInspector'; import { RTInspector } from './entities/RTInspector';
import { SceneBegin } from './entities/SceneBegin'; import { SceneBegin } from './entities/SceneBegin';
import { SceneCrystals } from './entities/SceneCrystals'; import { SceneCrystals } from './entities/SceneCrystals';
import { SceneDynamic } from './entities/SceneDynamic';
import { SceneNeuro } from './entities/SceneNeuro'; import { SceneNeuro } from './entities/SceneNeuro';
import { Serial } from './entities/Serial'; import { Serial } from './entities/Serial';
import { SphereParticles } from './entities/SphereParticles'; import { SphereParticles } from './entities/SphereParticles';
import { Swap, Vector3 } from '@fms-cat/experimental'; import { Swap, Vector3 } from '@fms-cat/experimental';
import { Tetrahedron } from './entities/Tetrahedron';
import { Trails } from './entities/Trails'; import { Trails } from './entities/Trails';
import { arraySetDelete } from './utils/arraySetDelete'; import { arraySetDelete } from './utils/arraySetDelete';
import { auto, automaton } from './globals/automaton'; import { auto, automaton } from './globals/automaton';
@@ -50,12 +54,10 @@ dog.root.components.push( new Lambda( {
// -- util ----------------------------------------------------------------------------------------- // -- util -----------------------------------------------------------------------------------------
class EntityReplacer<T extends Entity> { class EntityReplacer<T extends Entity> {
private __root: Entity;
public current!: T; public current!: T;
public creator: () => T; public creator: () => T;
public constructor( root: Entity, creator: () => T, name?: string ) { public constructor( creator: () => T, name?: string ) {
this.__root = root;
this.creator = creator; this.creator = creator;
this.replace(); this.replace();
@@ -73,12 +75,12 @@ class EntityReplacer<T extends Entity> {
public replace(): void { public replace(): void {
if ( process.env.DEV ) { if ( process.env.DEV ) {
if ( this.current ) { if ( this.current ) {
arraySetDelete( this.__root.children, this.current ); arraySetDelete( dog.root.children, this.current );
} }
} }
this.current = this.creator(); this.current = this.creator();
this.__root.children.push( this.current ); dog.root.children.push( this.current );
// not visible by default // not visible by default
this.current.active = false; this.current.active = false;
@@ -95,7 +97,6 @@ const deferredRoot = new Entity();
dog.root.children.push( deferredRoot ); dog.root.children.push( deferredRoot );
const replacerSphereParticles = new EntityReplacer( const replacerSphereParticles = new EntityReplacer(
deferredRoot,
() => new SphereParticles(), () => new SphereParticles(),
'SphereParticles', 'SphereParticles',
); );
@@ -105,25 +106,57 @@ if ( process.env.DEV && module.hot ) {
} ); } );
} }
const replacerFlashyTerrain = new EntityReplacer( const replacerFlashyBall = new EntityReplacer(
deferredRoot, () => new FlashyBall(),
() => new FlashyTerrain(), 'FlashyBall',
'FlashyTerrain',
); );
if ( process.env.DEV && module.hot ) { if ( process.env.DEV && module.hot ) {
module.hot.accept( './entities/FlashyTerrain', () => { module.hot.accept( './entities/FlashyBall', () => {
replacerFlashyTerrain.replace(); replacerFlashyBall.replace();
} ); } );
} }
const replacerTrails = new EntityReplacer( deferredRoot, () => new Trails(), 'Trails' ); const replacerTetrahedron = new EntityReplacer(
() => new Tetrahedron(),
'Tetrahedron',
);
if ( process.env.DEV && module.hot ) {
module.hot.accept( './entities/Tetrahedron', () => {
replacerTetrahedron.replace();
} );
}
const replacerNoiseVoxels = new EntityReplacer(
() => new NoiseVoxels(),
'NoiseVoxels',
);
if ( process.env.DEV && module.hot ) {
module.hot.accept( './entities/NoiseVoxels', () => {
replacerNoiseVoxels.replace();
} );
}
const replacerIFSAsUsual = new EntityReplacer(
() => new IFSAsUsual(),
'IFSAsUsual',
);
if ( process.env.DEV && module.hot ) {
module.hot.accept( './entities/IFSAsUsual', () => {
replacerIFSAsUsual.replace();
} );
}
const replacerTrails = new EntityReplacer( () => new Trails(), 'Trails' );
if ( process.env.DEV && module.hot ) { if ( process.env.DEV && module.hot ) {
module.hot.accept( './entities/Trails', () => { module.hot.accept( './entities/Trails', () => {
replacerTrails.replace(); replacerTrails.replace();
} ); } );
} }
const replacerSceneBegin = new EntityReplacer( deferredRoot, () => new SceneBegin(), 'SceneBegin' ); const replacerSceneBegin = new EntityReplacer(
() => new SceneBegin( { scenes: [ dog.root ] } ),
'SceneBegin'
);
if ( process.env.DEV && module.hot ) { if ( process.env.DEV && module.hot ) {
module.hot.accept( './entities/SceneBegin', () => { module.hot.accept( './entities/SceneBegin', () => {
replacerSceneBegin.current.lights.map( ( light ) => arraySetDelete( lights, light ) ); replacerSceneBegin.current.lights.map( ( light ) => arraySetDelete( lights, light ) );
@@ -132,7 +165,25 @@ if ( process.env.DEV && module.hot ) {
} ); } );
} }
const replacerSceneNeuro = new EntityReplacer( deferredRoot, () => new SceneNeuro(), 'SceneNeuro' ); const replacerSceneDynamic = new EntityReplacer(
() => new SceneDynamic( { scenes: [ dog.root ] } ),
'SceneDynamic',
);
if ( process.env.DEV && module.hot ) {
module.hot.accept( './entities/SceneDynamic', () => {
replacerSceneDynamic.current.lights.map( ( light ) => arraySetDelete( lights, light ) );
replacerSceneDynamic.replace();
lights.push( ...replacerSceneDynamic.current.lights );
replacerSceneDynamic.current.setDefferedCameraTarget( deferredCamera.cameraTarget );
} );
}
const replacerSceneNeuro = new EntityReplacer(
() => new SceneNeuro( { scenes: [ dog.root ] } ),
'SceneNeuro'
);
if ( process.env.DEV && module.hot ) { if ( process.env.DEV && module.hot ) {
module.hot.accept( './entities/SceneNeuro', () => { module.hot.accept( './entities/SceneNeuro', () => {
replacerSceneNeuro.current.lights.map( ( light ) => arraySetDelete( lights, light ) ); replacerSceneNeuro.current.lights.map( ( light ) => arraySetDelete( lights, light ) );
@@ -142,7 +193,10 @@ if ( process.env.DEV && module.hot ) {
} ); } );
} }
const replacerSceneCrystals = new EntityReplacer( deferredRoot, () => new SceneCrystals(), 'SceneCrystals' ); const replacerSceneCrystals = new EntityReplacer(
() => new SceneCrystals( { scenes: [ dog.root ] } ),
'SceneCrystals',
);
if ( process.env.DEV && module.hot ) { if ( process.env.DEV && module.hot ) {
module.hot.accept( './entities/SceneCrystals', () => { module.hot.accept( './entities/SceneCrystals', () => {
replacerSceneCrystals.current.lights.map( ( light ) => arraySetDelete( lights, light ) ); replacerSceneCrystals.current.lights.map( ( light ) => arraySetDelete( lights, light ) );
@@ -157,7 +211,6 @@ const forwardRoot = new Entity();
dog.root.children.push( forwardRoot ); dog.root.children.push( forwardRoot );
const replacerFlickyParticles = new EntityReplacer( const replacerFlickyParticles = new EntityReplacer(
forwardRoot,
() => new FlickyParticles(), () => new FlickyParticles(),
'FlickyParticles', 'FlickyParticles',
); );
@@ -187,6 +240,7 @@ const swap = new Swap(
const lights = [ const lights = [
...replacerSceneBegin.current.lights, ...replacerSceneBegin.current.lights,
...replacerSceneNeuro.current.lights, ...replacerSceneNeuro.current.lights,
...replacerSceneDynamic.current.lights,
...replacerSceneCrystals.current.lights, ...replacerSceneCrystals.current.lights,
]; ];
@@ -222,6 +276,7 @@ const deferredCamera = new DeferredCamera( {
} ); } );
dog.root.children.push( deferredCamera ); dog.root.children.push( deferredCamera );
replacerSceneNeuro.current.setDefferedCameraTarget( deferredCamera.cameraTarget ); replacerSceneNeuro.current.setDefferedCameraTarget( deferredCamera.cameraTarget );
replacerSceneDynamic.current.setDefferedCameraTarget( deferredCamera.cameraTarget );
replacerSceneCrystals.current.setDefferedCameraTarget( deferredCamera.cameraTarget ); replacerSceneCrystals.current.setDefferedCameraTarget( deferredCamera.cameraTarget );
const forwardCamera = new ForwardCamera( { const forwardCamera = new ForwardCamera( {
@@ -275,9 +330,9 @@ dog.root.components.push( new Lambda( {
if ( shake > 0.0 ) { if ( shake > 0.0 ) {
camera.transform.position = camera.transform.position.add( camera.transform.position = camera.transform.position.add(
new Vector3( [ new Vector3( [
Math.sin( 145.0 * time ), Math.sin( 45.0 * time ),
Math.sin( 2.0 + 148.0 * time ), Math.sin( 2.0 + 48.0 * time ),
Math.sin( 4.0 + 151.0 * time ) Math.sin( 4.0 + 51.0 * time )
] ).scale( shake ) ] ).scale( shake )
); );
} }

View File

@@ -6,7 +6,6 @@ precision highp float;
#define saturate(x) clamp(x,0.,1.) #define saturate(x) clamp(x,0.,1.)
#define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a))) #define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a)))
const int MARCH_ITER = 90;
const float PI = 3.14159265; const float PI = 3.14159265;
const float TAU = PI * 2.0; const float TAU = PI * 2.0;
const float foldcos = cos( PI / 5.0 ); const float foldcos = cos( PI / 5.0 );
@@ -23,7 +22,7 @@ const vec3 foldface = vec3( 0.0, foldrem, foldcos );
in vec4 vPositionWithoutModel; in vec4 vPositionWithoutModel;
#ifdef SHADOW #ifdef DEPTH
out vec4 fragColor; out vec4 fragColor;
#endif #endif
@@ -41,9 +40,6 @@ uniform mat4 modelMatrix;
uniform mat4 viewMatrix; uniform mat4 viewMatrix;
uniform mat4 projectionMatrix; uniform mat4 projectionMatrix;
uniform mat4 inversePVM; uniform mat4 inversePVM;
uniform sampler2D samplerRandom;
uniform sampler2D samplerRandomStatic;
uniform sampler2D samplerCapture;
vec3 divideByW( vec4 v ) { vec3 divideByW( vec4 v ) {
return v.xyz / v.w; return v.xyz / v.w;
@@ -73,7 +69,7 @@ vec3 fold( vec3 p ) {
float distFunc( vec3 p ) { float distFunc( vec3 p ) {
p.zx = rot2d( 0.5 * time ) * p.zx; p.zx = rot2d( 0.5 * time ) * p.zx;
p -= size.xyx * vec3( 0.02, 0.2, 0.02 ) * cyclicNoise( vec3( 1.0, 0.04, 1.0 ) / size.xyx * p + noiseOffset ); p -= size.xyx * vec3( 0.02, 0.2, 0.02 ) * cyclicNoise( vec3( 1.0, 0.1, 1.0 ) / size.xyx * p + noiseOffset );
p.y -= min( 0.8 * size.y - size.x, abs( p.y ) ) * sign( p.y ); p.y -= min( 0.8 * size.y - size.x, abs( p.y ) ) * sign( p.y );
p = fold( p ); p = fold( p );
return dot( p, foldface ) - size.x; return dot( p, foldface ) - size.x;
@@ -98,6 +94,16 @@ void main() {
vec3 rayPos = rayOri + rayDir * rayLen; vec3 rayPos = rayOri + rayDir * rayLen;
float dist; float dist;
int MARCH_ITER;
#ifdef DEFERRED
MARCH_ITER = 60;
#endif
#ifdef DEPTH
MARCH_ITER = 10;
#endif
for ( int i = 0; i < MARCH_ITER; i ++ ) { for ( int i = 0; i < MARCH_ITER; i ++ ) {
dist = distFunc( rayPos ); dist = distFunc( rayPos );
rayLen += 0.5 * dist; rayLen += 0.5 * dist;
@@ -121,11 +127,11 @@ void main() {
#ifdef DEFERRED #ifdef DEFERRED
fragPosition = vec4( modelPos.xyz, depth ); fragPosition = vec4( modelPos.xyz, depth );
fragNormal = vec4( modelNormal, 1.0 ); fragNormal = vec4( modelNormal, 1.0 );
fragColor = vec4( vec3( 0.5, 0.52, 1.0 ), 1.0 ); fragColor = vec4( vec3( 0.5 ), 1.0 );
fragWTF = vec4( vec3( 0.04, 1.0, 0.0 ), 3 ); fragWTF = vec4( vec3( 0.04, 1.0, 0.0 ), 3 );
#endif #endif
#ifdef SHADOW #ifdef DEPTH
float shadowDepth = linearstep( float shadowDepth = linearstep(
cameraNearFar.x, cameraNearFar.x,
cameraNearFar.y, cameraNearFar.y,

View File

@@ -0,0 +1,195 @@
#version 300 es
precision highp float;
#define fs(i) (fract(sin((i)*114.514)*1919.810))
#define saturate(x) clamp(x,0.,1.)
#define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a)))
const float PI = 3.14159265;
const float TAU = PI * 2.0;
#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
in vec4 vPositionWithoutModel;
#ifdef DEPTH
out vec4 fragColor;
#endif
uniform int lightCount;
uniform float deformAmp;
uniform float deformFreq;
uniform float deformTime;
uniform float time;
uniform float noiseOffset;
uniform vec2 lightNearFar[ 8 ];
uniform vec2 resolution;
uniform vec2 size;
uniform vec2 cameraNearFar;
uniform vec3 lightPos[ 8 ];
uniform vec3 lightColor[ 8 ];
uniform vec3 cameraPos;
uniform vec4 lightParams[ 8 ];
uniform mat4 lightPV[ 8 ];
uniform mat4 normalMatrix;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 inversePVM;
uniform sampler2D samplerRandom;
uniform sampler2D samplerRandomStatic;
uniform sampler2D samplerCapture;
uniform sampler2D samplerShadow[ 8 ];
vec3 divideByW( vec4 v ) {
return v.xyz / v.w;
}
#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
#pragma glslify: doAnalyticLighting = require( ./modules/doAnalyticLighting.glsl );
#pragma glslify: doShadowMapping = require( ./modules/doShadowMapping.glsl );
vec4 fetchShadowMap( int iLight, vec2 uv ) {
if ( iLight == 0 ) {
return texture( samplerShadow[ 0 ], uv );
} else if ( iLight == 1 ) {
return texture( samplerShadow[ 1 ], uv );
} else if ( iLight == 2 ) {
return texture( samplerShadow[ 2 ], uv );
} else if ( iLight == 3 ) {
return texture( samplerShadow[ 3 ], uv );
} else if ( iLight == 4 ) {
return texture( samplerShadow[ 4 ], uv );
} else if ( iLight == 5 ) {
return texture( samplerShadow[ 5 ], uv );
} else if ( iLight == 6 ) {
return texture( samplerShadow[ 6 ], uv );
} else if ( iLight == 7 ) {
return texture( samplerShadow[ 7 ], uv );
}
}
float distFunc( vec3 p ) {
float d = p.y;
d += 0.2 * cyclicNoise( p ).x;
return d;
}
vec3 normalFunc( vec3 p, float dd ) {
vec2 d = vec2( 0.0, dd );
return normalize( vec3(
distFunc( p + d.yxx ) - distFunc( p - d.yxx ),
distFunc( p + d.xyx ) - distFunc( p - d.xyx ),
distFunc( p + d.xxy ) - distFunc( p - d.xxy )
) );
}
void main() {
vec2 p = ( gl_FragCoord.xy * 2.0 - resolution ) / resolution.y;
vec3 rayOri = divideByW( inversePVM * vec4( p, 0.0, 1.0 ) );
vec3 farPos = divideByW( inversePVM * vec4( p, 1.0, 1.0 ) );
vec3 rayDir = normalize( farPos - rayOri );
float rayLen = length( vPositionWithoutModel.xyz - rayOri );
vec3 rayPos = rayOri + rayDir * rayLen;
float dist;
int MARCH_ITER;
#ifdef FORWARD
MARCH_ITER = 30;
#endif
#ifdef DEFERRED
MARCH_ITER = 60;
#endif
#ifdef DEPTH
MARCH_ITER = 10;
#endif
for ( int i = 0; i < MARCH_ITER; i ++ ) {
dist = distFunc( rayPos );
rayLen += 0.5 * dist;
rayPos = rayOri + rayDir * rayLen;
if ( abs( dist ) < 1E-3 ) { break; }
if ( rayLen > cameraNearFar.y ) { break; }
}
if ( 0.01 < dist ) {
discard;
}
vec3 modelNormal = normalize( normalMatrix * vec4( normalFunc( rayPos, 1E-2 ), 1.0 ) ).xyz;
vec4 modelPos = modelMatrix * vec4( rayPos, 1.0 );
vec4 projPos = projectionMatrix * viewMatrix * modelPos; // terrible
float depth = projPos.z / projPos.w;
gl_FragDepth = 0.5 + 0.5 * depth;
#ifdef FORWARD
vec3 color = vec3( 0.0 );
// for each lights
for ( int iLight = 0; iLight < 8; iLight ++ ) {
if ( iLight >= lightCount ) { break; }
vec3 V = cameraPos - modelPos.xyz;
vec3 L = lightPos[ iLight ] - modelPos.xyz;
// shading
vec3 shade = doAnalyticLighting(
V,
L,
modelNormal,
vec3( 0.6, 0.5, 0.4 ),
0.5,
0.2
) * lightColor[ iLight ];
// fetch shadowmap + spot lighting
vec4 lightProj = lightPV[ iLight ] * modelPos;
vec2 lightP = lightProj.xy / lightProj.w;
shade *= doShadowMapping(
L,
modelNormal,
fetchShadowMap( iLight, 0.5 + 0.5 * lightP ),
lightP,
lightNearFar[ iLight ],
lightParams[ iLight ].x
);
color += shade;
}
fragColor = vec4( color, 1.0 );
#endif
#ifdef DEFERRED
fragPosition = vec4( modelPos.xyz, depth );
fragNormal = vec4( modelNormal, 1.0 );
fragColor = vec4( vec3( 0.6, 0.5, 0.4 ), 1.0 );
fragWTF = vec4( vec3( 0.5, 0.2, 0.0 ), 3 );
#endif
#ifdef DEPTH
float shadowDepth = linearstep(
cameraNearFar.x,
cameraNearFar.y,
length( cameraPos - modelPos.xyz )
);
fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 );
#endif
}

View File

@@ -61,17 +61,6 @@ float dOverlay( vec2 p ) {
float d = 1E9; float d = 1E9;
float t = time + offset; float t = time + offset;
// center bar
d = min( d, sdbox( p, vec2( 0.12, 0.002 ) ) );
// circles
{
vec2 pt = abs( p );
d = min( d, dCirc( pt - vec2( 0.0, 0.05 ) ) );
d = min( d, dCirc( pt - vec2( 0.07, 0.05 ) ) );
d = min( d, dCirc( pt - vec2( 0.035, 0.05 + 0.035 * sqrt( 3.0 ) ) ) );
}
// rings // rings
{ {
float d2 = 1E9; float d2 = 1E9;

View File

@@ -61,11 +61,12 @@ void main() {
float a = TAU * uv.x; float a = TAU * uv.x;
float b = PI * ( uv.y - 0.5 ); float b = PI * ( uv.y - 0.5 );
vec3 N = vec3( -sin( a ) * cos( b ), sin( b ), -cos( a ) * cos( b ) ); vec3 N = vec3( -sin( a ) * cos( b ), -sin( b ), -cos( a ) * cos( b ) );
vec3 R = N; vec3 R = N;
vec3 V = R; vec3 V = R;
seed = uniformSeed + 500.0 * vec4( N.xy, uv00 ); seed = uniformSeed + 10.0 + 500.0 * vec4( uv00, N.xy );
prng( seed );
vec4 col = vec4( 0.0 ); vec4 col = vec4( 0.0 );
for ( int i = 0; i < SAMPLES; i ++ ) { for ( int i = 0; i < SAMPLES; i ++ ) {

View File

@@ -18,23 +18,16 @@ in vec4 vPositionWithoutModel;
uniform float time; uniform float time;
#pragma glslify: orthBasis = require( ./modules/orthBasis );
#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise ); #pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
void main() { void main() {
float grid = max( float roughness = 0.3 + 0.1 * cyclicNoise( 4.0 * vPositionWithoutModel.xyz ).x;
step( 0.996, cos( 16.0 * TAU * vPositionWithoutModel.x ) ),
step( 0.996, cos( 16.0 * TAU * vPositionWithoutModel.y ) )
);
vec2 cell = floor( 16.0 * vPositionWithoutModel.xy );
grid = max(
grid,
smoothstep( 0.2, 0.3, cyclicNoise( vec3( cell.xy, 4.0 * time ) ).x )
);
#ifdef DEFERRED #ifdef DEFERRED
fragPosition = vPosition; fragPosition = vPosition;
fragNormal = vec4( 0.0, 0.0, 1.0, 1.0 ); fragNormal = vec4( vNormal, 1.0 );
fragColor = vec4( grid * vec3( 2.0 ), 1.0 ); fragColor = vec4( vec3( 0.2 ), 1.0 );
fragWTF = vec4( 0.0, 0.0, 0.0, 1 ); fragWTF = vec4( roughness, 0.9, 0.0, 2 );
#endif #endif
} }

View File

@@ -1,11 +1,14 @@
#version 300 es #version 300 es
layout (location = 0) in vec3 position; layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
out vec4 vPositionWithoutModel; out vec3 vNormal;
out vec4 vPosition; out vec4 vPosition;
out vec4 vPositionWithoutModel;
uniform float time; uniform float time;
uniform float distort;
uniform vec2 resolution; uniform vec2 resolution;
uniform mat4 projectionMatrix; uniform mat4 projectionMatrix;
uniform mat4 viewMatrix; uniform mat4 viewMatrix;
@@ -15,12 +18,12 @@ uniform mat4 normalMatrix;
#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise ); #pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
void main() { void main() {
vNormal = normalize( ( normalMatrix * vec4( normal, 1.0 ) ).xyz );
vPositionWithoutModel = vec4( position, 1.0 ); vPositionWithoutModel = vec4( position, 1.0 );
float n = 0.5 + 0.5 * cyclicNoise( 2.0 * vPositionWithoutModel.xyz - vec3( 0.0, time, 0.0 ) ).x;
vPositionWithoutModel.z += 1.0 * n * exp( -2.0 * length( vPositionWithoutModel.xy ) );
vPosition = modelMatrix * vPositionWithoutModel; vPosition = modelMatrix * vPositionWithoutModel;
vPosition.xyz -= distort * cyclicNoise( 0.3 * vPosition.xyz + 0.3 * time );
vNormal = normalize( vNormal + distort * cyclicNoise( 1.0 + 0.3 * vPosition.xyz + 0.3 * time ) );
vec4 outPos = projectionMatrix * viewMatrix * vPosition; vec4 outPos = projectionMatrix * viewMatrix * vPosition;
outPos.x *= resolution.y / resolution.x; outPos.x *= resolution.y / resolution.x;

View File

@@ -36,13 +36,6 @@ uniform sampler2D samplerRandomStatic;
out vec4 fragColor; out vec4 fragColor;
#endif #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 #ifdef DEPTH
out vec4 fragColor; out vec4 fragColor;
#endif #endif
@@ -185,13 +178,6 @@ void main() {
fragColor = vec4( color, 1.0 ); fragColor = vec4( color, 1.0 );
#endif #endif
#ifdef DEFERRED
fragPosition = vPosition;
fragNormal = vec4( vNormal, 1.0 );
fragColor = vec4( color, 1.0 );
fragWTF = vec4( vec3( 0.0 ), MTL_UNLIT );
#endif
#ifdef DEPTH #ifdef DEPTH
float depth = linearstep( float depth = linearstep(
cameraNearFar.x, cameraNearFar.x,

View File

@@ -0,0 +1,156 @@
#version 300 es
precision highp float;
#define fs(i) (fract(sin((i)*114.514)*1919.810))
#define saturate(x) clamp(x,0.,1.)
#define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a)))
const int MARCH_ITER = 90;
const float PI = 3.14159265;
const float TAU = PI * 2.0;
#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
in vec4 vPositionWithoutModel;
#ifdef DEPTH
out vec4 fragColor;
#endif
uniform float time;
uniform float ifsSeed;
uniform vec2 resolution;
uniform vec2 cameraNearFar;
uniform vec3 cameraPos;
uniform mat4 normalMatrix;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 inversePVM;
uniform sampler2D samplerRandom;
uniform sampler2D samplerRandomStatic;
uniform sampler2D samplerCapture;
vec3 divideByW( vec4 v ) {
return v.xyz / v.w;
}
// https://www.iquilezles.org/www/articles/smin/smin.htm
float smin( float a, float b, float k ) {
float h = max( k - abs( a - b ), 0.0 ) / k;
return min( a, b ) - h * h * h * k * ( 1.0 / 6.0 );
}
mat2 rot2d( float t ) {
float c = cos( t );
float s = sin( t );
return mat2( c, -s, s, c );
}
#pragma glslify: orthBasis = require( ./modules/orthBasis );
#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
vec3 ifs( vec3 p, vec3 r, vec3 t ) {
vec3 s = t;
mat3 bas = orthBasis( r );
for ( int i = 0; i < 5; i ++ ) {
p = abs( p ) - abs( s ) * pow( 1.8, -float( i ) );
s = bas * s;
p.xy = p.x < p.y ? p.yx : p.xy;
p.yz = p.y < p.z ? p.zy : p.yz;
}
return p;
}
float box( vec3 p, vec3 s ) {
vec3 d = abs( p ) - s;
return min( 0.0, max( d.x, max( d.y, d.z ) ) ) + length( max( vec3( 0.0 ), d ) );
}
float map( vec3 p ) {
vec4 isect;
vec3 pt = p;
float clampbox = box( pt, vec3( 1.0, 1.0, 1.0 ) );
vec3 r = mix(
fs( vec3( 4.7, 3.2, 4.3 ) + floor( ifsSeed ) ),
fs( vec3( 4.7, 3.2, 4.3 ) + floor( ifsSeed + 1.0 ) ),
fract( ifsSeed )
);
vec3 t = vec3( 4.8, 3.8, 4.2 );
pt = ifs( pt, r, 0.2 * t );
pt = ifs( pt, r.yzx, 0.1 * t.yzx );
float d = max( box( pt, vec3( 0.08 ) ), clampbox );
return d;
}
vec3 normalFunc( vec3 p, float dd ) {
vec2 d = vec2( 0.0, dd );
return normalize( vec3(
map( p + d.yxx ) - map( p - d.yxx ),
map( p + d.xyx ) - map( p - d.xyx ),
map( p + d.xxy ) - map( p - d.xxy )
) );
}
void main() {
vec2 p = ( gl_FragCoord.xy * 2.0 - resolution ) / resolution.y;
vec3 rayOri = divideByW( inversePVM * vec4( p, 0.0, 1.0 ) );
vec3 farPos = divideByW( inversePVM * vec4( p, 1.0, 1.0 ) );
vec3 rayDir = normalize( farPos - rayOri );
float rayLen = length( vPositionWithoutModel.xyz - rayOri );
vec3 rayPos = rayOri + rayDir * rayLen;
float isect;
for ( int i = 0; i < MARCH_ITER; i ++ ) {
isect = map( rayPos );
rayLen += 0.5 * isect;
rayPos = rayOri + rayDir * rayLen;
if ( abs( isect ) < 1E-3 ) { break; }
if ( rayLen > cameraNearFar.y ) { break; }
}
if ( 0.01 < isect ) {
discard;
}
vec3 modelNormal = normalize( normalMatrix * vec4( normalFunc( rayPos, 1E-3 ), 1.0 ) ).xyz;
vec4 modelPos = modelMatrix * vec4( rayPos, 1.0 );
vec4 projPos = projectionMatrix * viewMatrix * modelPos; // terrible
float depth = projPos.z / projPos.w;
gl_FragDepth = 0.5 + 0.5 * depth;
#ifdef DEFERRED
fragPosition = vec4( modelPos.xyz, depth );
fragNormal = vec4( modelNormal, 1.0 );
fragColor = vec4( vec3( 0.2 ), 1.0 );
fragWTF = vec4( vec3( 0.6, 0.8, 0.0 ), 2 );
#endif
#ifdef DEPTH
float shadowDepth = linearstep(
cameraNearFar.x,
cameraNearFar.y,
length( cameraPos - modelPos.xyz )
);
fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 );
#endif
}

View File

@@ -19,7 +19,7 @@ const float TAU = PI * 2.0;
in vec4 vPositionWithoutModel; in vec4 vPositionWithoutModel;
#ifdef SHADOW #ifdef DEPTH
out vec4 fragColor; out vec4 fragColor;
#endif #endif
@@ -216,11 +216,11 @@ void main() {
#endif #endif
#ifdef SHADOW #ifdef DEPTH
float shadowDepth = linearstep( float shadowDepth = linearstep(
cameraNearFar.x, cameraNearFar.x,
cameraNearFar.y, cameraNearFar.y,
length( cameraPos - rayPos ) length( cameraPos - modelPos.xyz )
); );
fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 ); fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 );
#endif #endif

View File

@@ -0,0 +1,38 @@
const float PI = 3.14159265359;
const float EPSILON = 1E-3;
const vec3 DIELECTRIC_SPECULAR = vec3( 0.04 );
const vec3 ONE_SUB_DIELECTRIC_SPECULAR = 1.0 - DIELECTRIC_SPECULAR;
#pragma glslify: brdfLambert = require( ./brdfLambert.glsl );
#pragma glslify: brdfSpecularGGX = require( ./brdfSpecularGGX.glsl );
vec3 doAnalyticLighting(
vec3 V,
vec3 L, // MUST NOT be normalized
vec3 N,
vec3 color,
float roughness,
float metallic
) {
vec3 albedo = mix( color * ONE_SUB_DIELECTRIC_SPECULAR, vec3( 0.0 ), metallic );
vec3 f0 = mix( DIELECTRIC_SPECULAR, color, metallic );
V = normalize( V );
float lenL = length( L );
L = normalize( L );
vec3 H = normalize( V + L );
float NdotL = clamp( dot( N, L ), EPSILON, 1.0 );
float NdotH = clamp( dot( N, H ), EPSILON, 1.0 );
float VdotH = clamp( dot( V, H ), EPSILON, 1.0 );
float NdotV = clamp( dot( N, V ), EPSILON, 1.0 );
float decayL = 1.0 / ( lenL * lenL );
vec3 diffuse = brdfLambert( f0, albedo, VdotH );
vec3 spec = brdfSpecularGGX( f0, roughness, VdotH, NdotL, NdotV, NdotH );
return PI * decayL * NdotL * ( diffuse + spec );
}
#pragma glslify: export(doAnalyticLighting)

View File

@@ -0,0 +1,40 @@
const float PI = 3.14159265359;
const float EPSILON = 1E-3;
float doShadowMapping(
vec3 L, // MUST NOT be normalized
vec3 N, // have to be normalized
vec4 tex,
vec2 lightP, // lightPV * vec4( isect.position, 1.0 ), then its xy / w
vec2 lightNearFar,
float spotness
) {
float depth = clamp( ( length( L ) - lightNearFar.x ) / ( lightNearFar.y - lightNearFar.x ), 0.0, 1.0 ); // linearstep
L = normalize( L );
float NdotL = clamp( dot( N, L ), EPSILON, 1.0 );
float shadow = mix(
1.0,
smoothstep( 1.0, 0.5, length( lightP ) ),
spotness
);
float bias = 0.0001 + 0.0001 * ( 1.0 - NdotL );
depth -= bias;
float variance = clamp( tex.y - tex.x * tex.x, 0.0, 1.0 );
float md = depth - tex.x;
float p = variance / ( variance + md * md );
p = clamp( ( p - 0.2 ) / 0.8, 0.0, 1.0 ); // linearstep
shadow *= mix(
md < 0.0 ? 1.0 : p,
1.0,
smoothstep( 0.8, 1.0, max( abs( lightP.x ), abs( lightP.y ) ) ) // edgeclip
);
return shadow;
}
#pragma glslify: export(doShadowMapping)

View File

@@ -0,0 +1,29 @@
#version 300 es
precision highp float;
in vec3 vNormal;
in vec3 vPositionForNoise;
in vec4 vPosition;
#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
uniform float time;
#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
void main() {
float roughness = 0.6 + 0.1 * cyclicNoise( 1.0 * vPositionForNoise.xyz ).x;
#ifdef DEFERRED
fragPosition = vPosition;
fragNormal = vec4( normalize( vNormal ), 1.0 );
fragColor = vec4( vec3( 0.1, 0.1, 0.12 ), 1.0 );
fragWTF = vec4( vec3( roughness, 0.77, 0.0 ), 2 );
#endif
}

View File

@@ -0,0 +1,41 @@
#version 300 es
#define fs(i) (fract(sin((i)*114.514)*1919.810))
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec3 instancePos;
out vec3 vNormal;
out vec3 vPositionForNoise;
out vec4 vPosition;
uniform float phase;
uniform vec2 resolution;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 normalMatrix;
#pragma glslify: noise = require( ./-simplex4d );
void main() {
vNormal = normalize( ( normalMatrix * vec4( normal, 1.0 ) ).xyz );
float good = clamp(
0.5 + noise( vec4( 0.3 * instancePos, phase ) ),
0.0,
1.0
);
vPosition = vec4( good * position / 8.0, 1.0 );
vPosition.xyz += mix( vec3( -1.0 ), vec3( 1.0 ), instancePos / 7.0 );
vPosition = modelMatrix * vPosition;
vPositionForNoise = position + 2.0 * instancePos;
vec4 outPos = projectionMatrix * viewMatrix * vPosition;
outPos.x *= resolution.y / resolution.x;
gl_Position = outPos;
vPosition.w = outPos.z / outPos.w;
}

View File

@@ -12,8 +12,8 @@ const float TAU = PI * 2.0;
out vec4 fragColor; out vec4 fragColor;
uniform float frameCount;
uniform float time; uniform float time;
uniform float amp;
uniform vec2 resolution; uniform vec2 resolution;
uniform mat4 viewMatrix; uniform mat4 viewMatrix;
uniform mat4 projectionMatrix; uniform mat4 projectionMatrix;
@@ -93,7 +93,7 @@ void main() {
float flicker = step( 0.5, fract( 30.0 * time ) ); float flicker = step( 0.5, fract( 30.0 * time ) );
vec3 col = 0.3 + 0.3 * sin( 3.5 + 1.0 * accum + vec3( 0.0, 2.0, 4.0 ) ); vec3 col = 0.3 + 0.3 * sin( 3.5 + 1.0 * accum + vec3( 0.0, 2.0, 4.0 ) );
col *= ( 0.5 + 0.1 * flicker ) * accum; col *= amp * ( 0.5 + 0.1 * flicker ) * accum;
fragColor = vec4( col, 1.0 ); fragColor = vec4( col, 1.0 );
} }

View File

@@ -70,8 +70,9 @@ vec3 liftGammaGain( vec3 rgb ) {
void main() { void main() {
vec2 uv = vUv; vec2 uv = vUv;
if ( mosaicAmp > 1.0 ) { float mosaic = mosaicAmp * resolution.y;
uv = lofi( uv - 0.5, mosaicAmp / resolution ) + mosaicAmp * 0.5 / resolution + 0.5; if ( mosaic > 1.0 ) {
uv = lofi( uv - 0.5, mosaic / resolution ) + mosaic * 0.5 / resolution + 0.5;
} }
vec2 p = ( uv * resolution * 2.0 - resolution ) / resolution.y; vec2 p = ( uv * resolution * 2.0 - resolution ) / resolution.y;

View File

@@ -0,0 +1,33 @@
#version 300 es
#define lofi(i,m) (floor((i)/(m))*(m))
precision highp float;
const int MTL_PBR = 2;
in vec3 vNormal;
in vec4 vPosition;
in vec4 vPositionWithoutModel;
#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
uniform float time;
#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
void main() {
float rough = 0.2 + 0.2 * cyclicNoise( 4.0 * vPositionWithoutModel.xyz ).x;
#ifdef DEFERRED
fragPosition = vPosition;
fragNormal = vec4( normalize( vNormal ), 1.0 );
fragColor = vec4( vec3( 0.1 ), 1.0 );
fragWTF = vec4( vec3( 0.2 + 0.5 * rough, 0.9, 0.0 ), MTL_PBR );
#endif
}

View File

@@ -0,0 +1,43 @@
#version 300 es
#define fs(i) (fract(sin((i)*114.514)*1919.810))
const float PI = 3.14159265;
const float TAU = 6.28318531;
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in float instanceId;
out vec3 vNormal;
out vec4 vPositionWithoutModel;
out vec4 vPosition;
uniform vec2 resolution;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 normalMatrix;
mat2 rotate2D( float t ) {
return mat2( cos( t ), sin( t ), -sin( t ), cos( t ) );
}
void main() {
mat2 rot = rotate2D( 0.25 * instanceId * TAU );
vNormal = normal;
vNormal.zx = rot * vNormal.zx;
vNormal = normalize( ( normalMatrix * vec4( vNormal, 1.0 ) ).xyz );
vPositionWithoutModel = vec4( vec3( 3.1, 0.1, 0.1 ) * position + vec3( 0.0, 0.0, 3.0 ), 1.0 );
vPositionWithoutModel.zx = rot * vPositionWithoutModel.zx;
vPosition = modelMatrix * vPositionWithoutModel;
vec4 outPos = projectionMatrix * viewMatrix * vPosition;
outPos.x *= resolution.y / resolution.x;
gl_Position = outPos;
vPosition.w = outPos.z / outPos.w;
}

View File

@@ -9,6 +9,7 @@ layout (location = 2) in float instanceId;
out vec4 vPosition; out vec4 vPosition;
out vec3 vNormal; out vec3 vNormal;
uniform float begin;
uniform float time; uniform float time;
uniform vec2 resolution; uniform vec2 resolution;
uniform mat4 projectionMatrix; uniform mat4 projectionMatrix;
@@ -36,7 +37,10 @@ void main() {
vNormal = normalize( ( normalMatrix * vec4( normal, 1.0 ) ).xyz ); vNormal = normalize( ( normalMatrix * vec4( normal, 1.0 ) ).xyz );
vPosition = vec4( mix( 2.0, 2.7, random() ) * position, 1.0 ); float radius = mix( 2.0, 2.7, random() );
radius *= 1.0 - exp( -10.0 * max( 0.0, begin - 0.2 * random() ) );
vPosition = vec4( radius * position, 1.0 );
vPosition.xyz += mix( 0.005, 0.01, random() ) * normal; vPosition.xyz += mix( 0.005, 0.01, random() ) * normal;
vPosition.y += sin( random() * time + random() * vPosition.x + TAU * random() ) * 0.2 * random(); vPosition.y += sin( random() * time + random() * vPosition.x + TAU * random() ) * 0.2 * random();
vPosition.y += sin( random() * time + random() * vPosition.z + TAU * random() ) * 0.2 * random(); vPosition.y += sin( random() * time + random() * vPosition.z + TAU * random() ) * 0.2 * random();

View File

@@ -41,7 +41,7 @@ void main() {
// back to rgb // back to rgb
vec3 col = YCBCR_TO_RGB * vec3( vec3 col = YCBCR_TO_RGB * vec3(
saturate( 1.2 * ( linearstep( CHROMA_AMP, 1.0 - CHROMA_AMP, y ) - 0.5 ) + 0.5 ), saturate( 0.07 + 1.2 * ( linearstep( CHROMA_AMP, 1.0 - CHROMA_AMP, y ) - 0.5 ) + 0.5 ),
PI * cbcr / CHROMA_AMP PI * cbcr / CHROMA_AMP
); );

View File

@@ -48,9 +48,9 @@ uniform sampler2D samplerRandom;
// == commons ====================================================================================== // == commons ======================================================================================
#pragma glslify: prng = require( ./-prng ); #pragma glslify: prng = require( ./-prng );
#pragma glslify: brdfLambert = require( ./modules/brdfLambert.glsl );
#pragma glslify: brdfSpecularGGX = require( ./modules/brdfSpecularGGX.glsl );
#pragma glslify: importanceSampleGGX = require( ./modules/importanceSampleGGX.glsl ); #pragma glslify: importanceSampleGGX = require( ./modules/importanceSampleGGX.glsl );
#pragma glslify: doAnalyticLighting = require( ./modules/doAnalyticLighting.glsl );
#pragma glslify: doShadowMapping = require( ./modules/doShadowMapping.glsl );
vec3 catColor( float _p ) { vec3 catColor( float _p ) {
return 0.5 + 0.5 * vec3( return 0.5 + 0.5 * vec3(
@@ -170,36 +170,31 @@ vec3 shadePBR( Isect isect ) {
for ( int iLight = 0; iLight < 8; iLight ++ ) { for ( int iLight = 0; iLight < 8; iLight ++ ) {
if ( iLight >= lightCount ) { break; } if ( iLight >= lightCount ) { break; }
// calc vectors
vec3 L = lightPos[ iLight ] - isect.position; vec3 L = lightPos[ iLight ] - isect.position;
float lenL = length( L );
L = normalize( L );
vec3 H = normalize( V + L ); // shading
float NdotL = clamp( dot( isect.normal, L ), EPSILON, 1.0 ); vec3 shade = doAnalyticLighting(
float NdotH = clamp( dot( isect.normal, H ), EPSILON, 1.0 ); V,
float VdotH = clamp( dot( V, H ), EPSILON, 1.0 ); L,
isect.normal,
float decayL = 1.0 / ( lenL * lenL ); isect.color,
roughness,
metallic
) * lightColor[ iLight ] * ao;
// fetch shadowmap + spot lighting // fetch shadowmap + spot lighting
vec4 lightProj = lightPV[ iLight ] * vec4( isect.position, 1.0 ); vec4 lightProj = lightPV[ iLight ] * vec4( isect.position, 1.0 );
vec2 lightP = lightProj.xy / lightProj.w; vec2 lightP = lightProj.xy / lightProj.w;
float shadow = mix( shade *= doShadowMapping(
1.0, L,
smoothstep( 1.0, 0.5, length( lightP ) ), isect.normal,
fetchShadowMap( iLight, 0.5 + 0.5 * lightP ),
lightP,
lightNearFar[ iLight ],
lightParams[ iLight ].x lightParams[ iLight ].x
); );
shadow *= castShadow( iLight, lightP * 0.5 + 0.5, isect, NdotL );
// do shading
vec3 diffuse = brdfLambert( f0, albedo, VdotH );
vec3 spec = brdfSpecularGGX( f0, roughness, VdotH, NdotL, NdotV, NdotH );
vec3 shade = PI * lightColor[ iLight ] * decayL * ao * shadow * NdotL * ( diffuse + spec );
color += shade; color += shade;
} }
@@ -208,16 +203,16 @@ vec3 shadePBR( Isect isect ) {
// diffuse ibl // diffuse ibl
vec2 uvEnvDiffuse = vec2( vec2 uvEnvDiffuse = vec2(
0.5 + atan( nEnvDiffuse.x, -nEnvDiffuse.z ) / TAU, 0.5 + atan( nEnvDiffuse.x, nEnvDiffuse.z ) / TAU,
0.5 + atan( nEnvDiffuse.y, length( nEnvDiffuse.zx ) ) / PI 0.5 + atan( nEnvDiffuse.y, length( nEnvDiffuse.zx ) ) / PI
); );
vec3 texEnvDiffuse = sampleEnvNearest( uvEnvDiffuse, 4.0 ).rgb; vec3 texEnvDiffuse = sampleEnvNearest( uvEnvDiffuse, 4.0 ).rgb;
color += ao * texEnvDiffuse * albedo; color += ao * texEnvDiffuse * albedo;
// reflective ibl // reflective ibl
vec3 reflEnvReflective = reflect( V, isect.normal ); vec3 reflEnvReflective = reflect( -V, isect.normal );
vec2 uvEnvReflective = vec2( vec2 uvEnvReflective = vec2(
0.5 + atan( reflEnvReflective.x, -reflEnvReflective.z ) / TAU, 0.5 + atan( reflEnvReflective.x, reflEnvReflective.z ) / TAU,
0.5 + atan( reflEnvReflective.y, length( reflEnvReflective.zx ) ) / PI 0.5 + atan( reflEnvReflective.y, length( reflEnvReflective.zx ) ) / PI
); );
vec2 brdfEnvReflective = texture( samplerIBLLUT, vec2( NdotV, roughness ) ).xy; vec2 brdfEnvReflective = texture( samplerIBLLUT, vec2( NdotV, roughness ) ).xy;
@@ -245,7 +240,7 @@ void main() {
isect.screenUv = vUv; isect.screenUv = vUv;
isect.position = tex0.xyz; isect.position = tex0.xyz;
isect.depth = tex0.w; isect.depth = tex0.w;
isect.normal = tex1.xyz; isect.normal = normalize( tex1.xyz );
isect.color = tex2.rgb; isect.color = tex2.rgb;
isect.materialId = int( tex3.w + 0.5 ); isect.materialId = int( tex3.w + 0.5 );
isect.materialParams = tex3.xyz; isect.materialParams = tex3.xyz;
@@ -272,9 +267,9 @@ void main() {
color = shadePBR( isect ); color = shadePBR( isect );
// really really cheap full spectrum // really really cheap full spectrum
vec3 refrEnvRefractive = refract( V, isect.normal, 1.0 / 2.56 ); vec3 refrEnvRefractive = refract( -V, isect.normal, 1.0 / 2.56 );
vec2 uvEnvRefractive = vec2( vec2 uvEnvRefractive = vec2(
0.5 + atan( refrEnvRefractive.x, -refrEnvRefractive.z ) / TAU, 0.5 + atan( refrEnvRefractive.x, refrEnvRefractive.z ) / TAU,
0.5 + atan( refrEnvRefractive.y, length( refrEnvRefractive.zx ) ) / PI 0.5 + atan( refrEnvRefractive.y, length( refrEnvRefractive.zx ) ) / PI
); );
vec3 texEnvRefractive = sampleEnvLinear( uvEnvRefractive, 0.5 ).rgb; vec3 texEnvRefractive = sampleEnvLinear( uvEnvRefractive, 0.5 ).rgb;
@@ -283,7 +278,6 @@ void main() {
} }
float lenV = length( cameraPos - isect.position );
color *= exp( -0.4 * max( lenV - 3.0, 0.0 ) ); color *= exp( -0.4 * max( lenV - 3.0, 0.0 ) );
// color = 0.5 + 0.5 * isect.normal; // color = 0.5 + 0.5 * isect.normal;
@@ -291,7 +285,7 @@ void main() {
// color = vec3( 0.5, 0.2, 0.9 ) * ( 1.0 - texture( samplerAo, isect.screenUv ).xyz ); // color = vec3( 0.5, 0.2, 0.9 ) * ( 1.0 - texture( samplerAo, isect.screenUv ).xyz );
// color = mix( // color = mix(
// color, // color,
// vec3( 0.96 ) * smoothstep( 0.9, 0.1, texture( samplerAo, isect.screenUv ).xyz ), // vec3( 0.96 ) * smoothstep( 0.5, 0.9, texture( samplerAo, isect.screenUv ).xyz ),
// 1.0 // 1.0
// ); // );

View File

@@ -0,0 +1,134 @@
#version 300 es
precision highp float;
#define fs(i) (fract(sin((i)*114.514)*1919.810))
#define saturate(x) clamp(x,0.,1.)
#define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a)))
const float PI = 3.14159265;
const float TAU = PI * 2.0;
const float foldcos = cos( PI / 3.0 );
const float foldrem = sqrt( 0.75 - foldcos * foldcos );
const vec3 foldvec = vec3( -0.5, -foldcos, foldrem );
const vec3 foldface = vec3( 0.0, foldrem, foldcos );
#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
in vec4 vPositionWithoutModel;
#ifdef DEPTH
out vec4 fragColor;
#endif
uniform float distort;
uniform float time;
uniform vec2 resolution;
uniform vec2 cameraNearFar;
uniform vec3 cameraPos;
uniform mat4 normalMatrix;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 inversePVM;
uniform sampler2D samplerRandom;
uniform sampler2D samplerRandomStatic;
uniform sampler2D samplerCapture;
vec3 divideByW( vec4 v ) {
return v.xyz / v.w;
}
#pragma glslify: noise = require( ./-simplex4d );
#pragma glslify: orthBasis = require( ./modules/orthBasis );
vec3 fold( vec3 p ) {
for ( int i = 0; i < 5; i ++ ) {
p.xy = abs( p.xy );
p -= 2.0 * min( dot( foldvec, p ), 0.0 ) * foldvec;
}
return p;
}
float distFunc( vec3 p ) {
vec3 pt = p;
pt = fold( pt );
float d = dot( pt, foldface ) - 0.36;
d += ( 0.001 + 0.02 * distort ) * noise(
vec4( 8.0 * p.xyz, 8.0 * time )
);
return d;
}
vec3 normalFunc( vec3 p, float dd ) {
vec2 d = vec2( 0.0, dd );
return normalize( vec3(
distFunc( p + d.yxx ) - distFunc( p - d.yxx ),
distFunc( p + d.xyx ) - distFunc( p - d.xyx ),
distFunc( p + d.xxy ) - distFunc( p - d.xxy )
) );
}
void main() {
vec2 p = ( gl_FragCoord.xy * 2.0 - resolution ) / resolution.y;
vec3 rayOri = divideByW( inversePVM * vec4( p, 0.0, 1.0 ) );
vec3 farPos = divideByW( inversePVM * vec4( p, 1.0, 1.0 ) );
vec3 rayDir = normalize( farPos - rayOri );
float rayLen = length( vPositionWithoutModel.xyz - rayOri );
vec3 rayPos = rayOri + rayDir * rayLen;
float dist;
int MARCH_ITER;
#ifdef DEFERRED
MARCH_ITER = 50;
#endif
#ifdef DEPTH
MARCH_ITER = 30;
#endif
for ( int i = 0; i < MARCH_ITER; i ++ ) {
dist = distFunc( rayPos );
rayLen += 0.5 * dist;
rayPos = rayOri + rayDir * rayLen;
if ( abs( dist ) < 1E-3 ) { break; }
if ( rayLen > cameraNearFar.y ) { break; }
}
if ( 0.01 < dist ) {
discard;
}
vec3 modelNormal = normalize( normalMatrix * vec4( normalFunc( rayPos, 1E-3 ), 1.0 ) ).xyz;
vec4 modelPos = modelMatrix * vec4( rayPos, 1.0 );
vec4 projPos = projectionMatrix * viewMatrix * modelPos; // terrible
float depth = projPos.z / projPos.w;
gl_FragDepth = 0.5 + 0.5 * depth;
#ifdef DEFERRED
fragPosition = vec4( modelPos.xyz, depth );
fragNormal = vec4( modelNormal, 1.0 );
fragColor = vec4( vec3( 0.2 ), 1.0 );
fragWTF = vec4( vec3( 0.05 , 0.93, 0.0 ), 2 );
#endif
#ifdef DEPTH
float shadowDepth = linearstep(
cameraNearFar.x,
cameraNearFar.y,
length( cameraPos - modelPos.xyz )
);
fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 );
#endif
}

View File

@@ -15,6 +15,7 @@ layout (location = 0) out vec4 fragCompute0;
layout (location = 1) out vec4 fragCompute1; layout (location = 1) out vec4 fragCompute1;
uniform bool init; uniform bool init;
uniform bool shouldUpdate;
uniform float time; uniform float time;
uniform float beat; uniform float beat;
uniform float trails; uniform float trails;
@@ -51,7 +52,7 @@ vec4 sampleRandom( vec2 _uv ) {
} }
#pragma glslify: prng = require( ./-prng ); #pragma glslify: prng = require( ./-prng );
#pragma glslify: noise = require( ./-simplex4d ); #pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
vec3 randomSphere( inout vec4 seed ) { vec3 randomSphere( inout vec4 seed ) {
vec3 v; vec3 v;
@@ -107,11 +108,16 @@ void main() {
// == if it is not head of particles ============================================================= // == if it is not head of particles =============================================================
if ( 1.0 < gl_FragCoord.x ) { if ( 1.0 < gl_FragCoord.x ) {
uv.x -= 1.0 / resolution.x; if ( shouldUpdate ) {
uv.x -= 1.0 / resolution.x;
}
vec4 tex0 = texture( samplerCompute0, uv ); vec4 tex0 = texture( samplerCompute0, uv );
vec4 tex1 = texture( samplerCompute1, uv ); vec4 tex1 = texture( samplerCompute1, uv );
tex0.w = saturate( tex0.w - 1.0 / trailLength ); // decrease the life if ( shouldUpdate ) {
tex0.w = saturate( tex0.w - 1.0 / trailLength ); // decrease the life
}
fragCompute0 = tex0; fragCompute0 = tex0;
fragCompute1 = tex1; fragCompute1 = tex1;
@@ -157,11 +163,7 @@ void main() {
// == update particles =========================================================================== // == update particles ===========================================================================
// noise field // noise field
vel += 40.0 * vec3( vel += 40.0 * cyclicNoise( pos ) * dt;
noise( vec4( pos.xyz, 1.485 + sin( time * 0.1 ) + noisePhase ) ),
noise( vec4( pos.xyz, 3.485 + sin( time * 0.1 ) + noisePhase ) ),
noise( vec4( pos.xyz, 5.485 + sin( time * 0.1 ) + noisePhase ) )
) * dt;
// resistance // resistance
vel *= exp( -10.0 * dt ); vel *= exp( -10.0 * dt );

View File

@@ -34,11 +34,11 @@ mat2 rotate2D( float _t ) {
void main() { void main() {
if ( vColor.a < 0.0 ) { discard; } if ( vColor.a < 0.0 ) { discard; }
float emissive = 5.0; float emissive = 0.0;
// emissive *= 0.5 + 0.5 * sin( TAU * vRandom.z + 20.0 * time ); // emissive *= 0.5 + 0.5 * sin( TAU * vRandom.z + 20.0 * time );
fragPosition = vPosition; fragPosition = vPosition;
fragNormal = vec4( vNormal, 1.0 ); fragNormal = vec4( vNormal, 1.0 );
fragColor = vColor; fragColor = vColor;
fragWTF = vec4( vec3( 0.9, 0.9, emissive ), MTL_PBR ); fragWTF = vec4( vec3( 0.4, 0.1, emissive ), MTL_PBR );
} }

View File

@@ -7,10 +7,6 @@ precision highp float;
#define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a))) #define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a)))
const int MARCH_ITER = 90; const int MARCH_ITER = 90;
const int MTL_UNLIT = 1;
const int MTL_PBR = 2;
const int MTL_GRADIENT = 3;
const int MTL_IRIDESCENT = 4;
const float PI = 3.14159265; const float PI = 3.14159265;
const float TAU = PI * 2.0; const float TAU = PI * 2.0;
@@ -23,7 +19,7 @@ const float TAU = PI * 2.0;
in vec4 vPositionWithoutModel; in vec4 vPositionWithoutModel;
#ifdef SHADOW #ifdef DEPTH
out vec4 fragColor; out vec4 fragColor;
#endif #endif
@@ -143,14 +139,14 @@ void main() {
fragPosition = vec4( modelPos.xyz, depth ); fragPosition = vec4( modelPos.xyz, depth );
fragNormal = vec4( modelNormal, 1.0 ); fragNormal = vec4( modelNormal, 1.0 );
fragColor = vec4( vec3( 0.3 ), 1.0 ); fragColor = vec4( vec3( 0.3 ), 1.0 );
fragWTF = vec4( vec3( 1.0, 0.1, 0.0 ), MTL_PBR ); fragWTF = vec4( vec3( 1.0, 0.1, 0.0 ), 2 );
#endif #endif
#ifdef SHADOW #ifdef DEPTH
float shadowDepth = linearstep( float shadowDepth = linearstep(
cameraNearFar.x, cameraNearFar.x,
cameraNearFar.y, cameraNearFar.y,
length( cameraPos - rayPos ) length( cameraPos - modelPos.xyz )
); );
fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 ); fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 );
#endif #endif

View File

@@ -0,0 +1,57 @@
import { LightEntity } from '../entities/LightEntity';
import { Material } from '../heck/Material';
export function setLightUniforms(
material: Material,
lights: LightEntity[],
frameCount: number,
): void {
const activeLights = lights.filter( ( light ) => (
frameCount === light.lastUpdateFrame
) );
material.addUniform(
'lightCount',
'1i',
activeLights.length,
);
material.addUniformVector(
'lightNearFar',
'2fv',
activeLights.map( ( light ) => [ light.camera.near, light.camera.far ] ).flat(),
);
material.addUniformVector(
'lightPos',
'3fv',
activeLights.map( ( light ) => light.globalTransformCache.position.elements ).flat(),
);
material.addUniformVector(
'lightColor',
'3fv',
activeLights.map( ( light ) => light.color ).flat(),
);
material.addUniformVector(
'lightParams',
'4fv',
activeLights.map( ( light ) => [ light.spotness, 0.0, 0.0, 0.0 ] ).flat(),
);
material.addUniformMatrixVector(
'lightPV',
'Matrix4fv',
activeLights.map( ( light ) => (
light.camera.projectionMatrix.multiply(
light.globalTransformCache.matrix.inverse!
).elements
) ).flat(),
);
material.addUniformTextureArray(
'samplerShadow',
activeLights.map( ( light ) => light.shadowMap.texture ),
);
}

View File

@@ -33,6 +33,10 @@ const terserOptions = {
] ]
}, },
}, },
format: {
ascii_only: true,
ecma: 2020,
},
module: true, module: true,
toplevel: true, toplevel: true,
}; };