mirror of
https://github.com/FMS-Cat/condition.git
synced 2025-09-02 01:42:37 +02:00
before the psy
This commit is contained in:
@@ -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
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@@ -5,8 +5,10 @@ export const
|
||||
// RTINSPECTOR_CAPTURE_NAME: string | null = 'PixelSorter/index',
|
||||
// RTINSPECTOR_CAPTURE_NAME: string | null = 'Greetings/intermediate0',
|
||||
// RTINSPECTOR_CAPTURE_NAME: string | null = 'main/postSwap0',
|
||||
// RTINSPECTOR_CAPTURE_NAME: string | null = 'EnvironmentMap/swap0',
|
||||
// RTINSPECTOR_CAPTURE_NAME: string | null = 'DeferredCamera/cameraTarget',
|
||||
RTINSPECTOR_CAPTURE_INDEX = 0,
|
||||
COMPONENT_UPDATE_BREAKPOINT: string | null = null,
|
||||
// COMPONENT_UPDATE_BREAKPOINT: string | null = 'ForwardCamera/camera',
|
||||
// COMPONENT_UPDATE_BREAKPOINT: string | null = 'lightDynamic1/shadowMapCamera',
|
||||
COMPONENT_DRAW_BREAKPOINT: string | null = null;
|
||||
|
@@ -8,10 +8,9 @@ import { Material } from '../heck/Material';
|
||||
import { Mesh, MeshCull } from '../heck/components/Mesh';
|
||||
import { Vector3 } from '@fms-cat/experimental';
|
||||
import { auto } from '../globals/automaton';
|
||||
import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget';
|
||||
import { dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget';
|
||||
import { genCube } from '../geometries/genCube';
|
||||
import { objectValuesMap } from '../utils/objectEntriesMap';
|
||||
import { randomTexture, randomTextureStatic } from '../globals/randomTexture';
|
||||
import crystalFrag from '../shaders/crystal.frag';
|
||||
import raymarchObjectVert from '../shaders/raymarch-object.vert';
|
||||
|
||||
@@ -50,22 +49,23 @@ export class Crystal extends Entity {
|
||||
},
|
||||
);
|
||||
|
||||
const depth = new Material(
|
||||
raymarchObjectVert,
|
||||
crystalFrag,
|
||||
{
|
||||
defines: [ 'SHADOW 1' ],
|
||||
initOptions: { geometry, target: dummyRenderTarget }
|
||||
},
|
||||
);
|
||||
// I don't think we need this
|
||||
// const depth = new Material(
|
||||
// raymarchObjectVert,
|
||||
// crystalFrag,
|
||||
// {
|
||||
// defines: [ 'DEPTH 1' ],
|
||||
// initOptions: { geometry, target: dummyRenderTarget }
|
||||
// },
|
||||
// );
|
||||
|
||||
const materials = { deferred, depth };
|
||||
const materials = { deferred };
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
module.hot.accept( '../shaders/crystal.frag', () => {
|
||||
deferred.replaceShader( raymarchObjectVert, crystalFrag );
|
||||
depth.replaceShader( raymarchObjectVert, crystalFrag );
|
||||
// depth.replaceShader( raymarchObjectVert, crystalFrag );
|
||||
} );
|
||||
}
|
||||
}
|
||||
@@ -73,9 +73,6 @@ export class Crystal extends Entity {
|
||||
objectValuesMap( materials, ( material ) => {
|
||||
material.addUniform( 'size', '2f', width, height );
|
||||
material.addUniform( 'noiseOffset', '1f', noiseOffset );
|
||||
|
||||
material.addUniformTexture( 'samplerRandom', randomTexture.texture );
|
||||
material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
} );
|
||||
|
||||
// -- updater ----------------------------------------------------------------------------------
|
||||
@@ -98,10 +95,6 @@ export class Crystal extends Entity {
|
||||
.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 && 'Crystal/updater',
|
||||
|
@@ -30,7 +30,6 @@ export class Cube extends Entity {
|
||||
0.4,
|
||||
) );
|
||||
|
||||
this.transform.position = new Vector3( [ 0.0, 0.0, 0.0 ] );
|
||||
this.transform.rotation = rot0;
|
||||
this.transform.scale = this.transform.scale.scale( 0.3 );
|
||||
|
||||
|
119
src/entities/CyclicBoard.ts
Normal file
119
src/entities/CyclicBoard.ts
Normal 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 );
|
||||
}
|
||||
}
|
@@ -12,6 +12,7 @@ import { dummyRenderTarget } from '../globals/dummyRenderTarget';
|
||||
import { gl } from '../globals/canvas';
|
||||
import { quadGeometry } from '../globals/quadGeometry';
|
||||
import { randomTexture } from '../globals/randomTexture';
|
||||
import { setLightUniforms } from '../utils/setLightUniforms';
|
||||
import aoFrag from '../shaders/ao.frag';
|
||||
import quadVert from '../shaders/quad.vert';
|
||||
import shadingFrag from '../shaders/shading.frag';
|
||||
@@ -111,18 +112,8 @@ export class DeferredCamera extends Entity {
|
||||
|
||||
const lambda = new Lambda( {
|
||||
onUpdate: ( { frameCount } ) => {
|
||||
const lights = options.lights.filter( ( light ) => (
|
||||
frameCount === light.lastUpdateFrame
|
||||
) );
|
||||
|
||||
const cameraView = this.transform.matrix.inverse!;
|
||||
|
||||
shadingMaterial.addUniform(
|
||||
'lightCount',
|
||||
'1i',
|
||||
lights.length,
|
||||
);
|
||||
|
||||
shadingMaterial.addUniformMatrixVector(
|
||||
'cameraView',
|
||||
'Matrix4fv',
|
||||
@@ -150,44 +141,7 @@ export class DeferredCamera extends Entity {
|
||||
...this.transform.position.elements
|
||||
);
|
||||
|
||||
shadingMaterial.addUniformVector(
|
||||
'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 ),
|
||||
);
|
||||
setLightUniforms( shadingMaterial, options.lights, frameCount );
|
||||
},
|
||||
name: process.env.DEV && 'DeferredCamera/shading/setCameraUniforms',
|
||||
} );
|
||||
|
92
src/entities/FlashyBall.ts
Normal file
92
src/entities/FlashyBall.ts
Normal 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',
|
||||
} ) );
|
||||
}
|
||||
}
|
@@ -66,7 +66,7 @@ const styles = [
|
||||
},
|
||||
{
|
||||
font: '96px Arial',
|
||||
spacing: 2.0,
|
||||
spacing: 1.3,
|
||||
},
|
||||
{
|
||||
font: 'Bold 96px Arial',
|
||||
@@ -89,7 +89,8 @@ const styles = [
|
||||
},
|
||||
{
|
||||
font: 'Bold 96px Arial',
|
||||
spacing: 1.5,
|
||||
scaleY: 1.2,
|
||||
spacing: 1.4,
|
||||
},
|
||||
{
|
||||
font: 'Bold 96px Arial',
|
||||
@@ -157,30 +158,40 @@ const charPosList = [
|
||||
'0x4015',
|
||||
'Alcatraz',
|
||||
'Altair',
|
||||
'ASD',
|
||||
'Astronomena',
|
||||
'CNCD',
|
||||
'Cocoon',
|
||||
'Conspiracy',
|
||||
'Ctrl+Alt+Test',
|
||||
'doxas',
|
||||
'Fairlight',
|
||||
'Flopine',
|
||||
'FRONTL1NE',
|
||||
'holon',
|
||||
'gam0022',
|
||||
'gaz',
|
||||
'jetlag',
|
||||
'Jugem-T',
|
||||
'kaneta',
|
||||
'Limp Ninja',
|
||||
'LJ',
|
||||
'Logicoma',
|
||||
'marcan',
|
||||
'Mercury',
|
||||
'mrdoob',
|
||||
'nikq::cube',
|
||||
'Ninjadev',
|
||||
'NuSan',
|
||||
'orange',
|
||||
'Poo-Brain',
|
||||
'Primitive',
|
||||
'Prismbeings',
|
||||
'Radium Software',
|
||||
'quite',
|
||||
'rgba',
|
||||
'Satori',
|
||||
'setchi',
|
||||
'sp4ghet',
|
||||
'Still',
|
||||
'Suricrasia Online',
|
||||
@@ -281,7 +292,7 @@ export class Greetings extends Entity {
|
||||
|
||||
const lambda = new Lambda( {
|
||||
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;
|
||||
}
|
||||
|
||||
|
112
src/entities/IFSAsUsual.ts
Normal file
112
src/entities/IFSAsUsual.ts
Normal 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',
|
||||
} ) );
|
||||
}
|
||||
}
|
@@ -41,7 +41,7 @@ export class IFSPistons extends Entity {
|
||||
raymarchObjectVert,
|
||||
ifsPistonFrag,
|
||||
{
|
||||
defines: [ 'SHADOW 1' ],
|
||||
defines: [ 'DEPTH 1' ],
|
||||
initOptions: { geometry, target: dummyRenderTarget }
|
||||
},
|
||||
);
|
||||
|
61
src/entities/LightCube.ts
Normal file
61
src/entities/LightCube.ts
Normal 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
108
src/entities/NoiseVoxels.ts
Normal 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 );
|
||||
}
|
||||
}
|
@@ -3,13 +3,13 @@ import { Entity } from '../heck/Entity';
|
||||
import { Lambda } from '../heck/components/Lambda';
|
||||
import { Material } from '../heck/Material';
|
||||
import { Mesh } from '../heck/components/Mesh';
|
||||
import { auto } from '../globals/automaton';
|
||||
import { dummyRenderTarget } from '../globals/dummyRenderTarget';
|
||||
import { gl } from '../globals/canvas';
|
||||
import { quadGeometry } from '../globals/quadGeometry';
|
||||
import { randomTexture } from '../globals/randomTexture';
|
||||
import phantomFrag from '../shaders/phantom.frag';
|
||||
import quadVert from '../shaders/quad.vert';
|
||||
import { auto } from '../globals/automaton';
|
||||
|
||||
export class Phantom extends Entity {
|
||||
private __forward: Material;
|
||||
@@ -65,9 +65,11 @@ export class Phantom extends Entity {
|
||||
this.components.push( mesh );
|
||||
|
||||
// -- auto -------------------------------------------------------------------------------------
|
||||
auto( 'Phantom/active', ( { uninit } ) => {
|
||||
mesh.active = !uninit;
|
||||
mesh.visible = !uninit;
|
||||
auto( 'Phantom/amp', ( { value } ) => {
|
||||
forward.addUniform( 'amp', '1f', value );
|
||||
|
||||
mesh.active = value > 0.0;
|
||||
mesh.visible = mesh.active;
|
||||
} );
|
||||
}
|
||||
|
||||
|
@@ -1,44 +1,44 @@
|
||||
import { Entity } from '../heck/Entity';
|
||||
import { Geometry } from '../heck/Geometry';
|
||||
import { InstancedGeometry } from '../heck/InstancedGeometry';
|
||||
import { Material } from '../heck/Material';
|
||||
import { Mesh } from '../heck/components/Mesh';
|
||||
import { Quaternion, Vector3 } from '@fms-cat/experimental';
|
||||
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 depthFrag from '../shaders/depth.frag';
|
||||
import flashyTerrainFrag from '../shaders/flashy-terrain.frag';
|
||||
import flashyTerrainVert from '../shaders/flashy-terrain.vert';
|
||||
import rectTorusFrag from '../shaders/rect-torus.frag';
|
||||
import rectTorusVert from '../shaders/rect-torus.vert';
|
||||
|
||||
export class FlashyTerrain extends Entity {
|
||||
export class RectTorus extends Entity {
|
||||
public mesh: Mesh;
|
||||
|
||||
public constructor() {
|
||||
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 ---------------------------------------------------------------------------------
|
||||
const plane = genPlane();
|
||||
const cube = genCube();
|
||||
|
||||
const geometry = new Geometry();
|
||||
const geometry = new InstancedGeometry();
|
||||
|
||||
geometry.vao.bindVertexbuffer( plane.position, 0, 3 );
|
||||
geometry.vao.bindIndexbuffer( plane.index );
|
||||
geometry.vao.bindVertexbuffer( cube.position, 0, 3 );
|
||||
geometry.vao.bindVertexbuffer( cube.normal, 1, 3 );
|
||||
geometry.vao.bindIndexbuffer( cube.index );
|
||||
|
||||
geometry.count = plane.count;
|
||||
geometry.mode = plane.mode;
|
||||
geometry.indexType = plane.indexType;
|
||||
const arrayInstanceId = [ ...Array( 4 ).keys() ];
|
||||
const bufferInstanceId = glCat.createBuffer();
|
||||
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 --------------------------------------------------------------------------------
|
||||
const deferred = new Material(
|
||||
flashyTerrainVert,
|
||||
flashyTerrainFrag,
|
||||
rectTorusVert,
|
||||
rectTorusFrag,
|
||||
{
|
||||
defines: [ 'DEFERRED 1' ],
|
||||
initOptions: { geometry: quadGeometry, target: dummyRenderTargetFourDrawBuffers },
|
||||
@@ -46,7 +46,7 @@ export class FlashyTerrain extends Entity {
|
||||
);
|
||||
|
||||
const depth = new Material(
|
||||
flashyTerrainVert,
|
||||
rectTorusVert,
|
||||
depthFrag,
|
||||
{ initOptions: { geometry: quadGeometry, target: dummyRenderTarget } },
|
||||
);
|
||||
@@ -57,12 +57,12 @@ export class FlashyTerrain extends Entity {
|
||||
if ( module.hot ) {
|
||||
module.hot.accept(
|
||||
[
|
||||
'../shaders/flashy-terrain.vert',
|
||||
'../shaders/flashy-terrain.frag',
|
||||
'../shaders/rect-torus.vert',
|
||||
'../shaders/rect-torus.frag',
|
||||
],
|
||||
() => {
|
||||
deferred.replaceShader( flashyTerrainVert, flashyTerrainFrag );
|
||||
depth.replaceShader( flashyTerrainVert, depthFrag );
|
||||
deferred.replaceShader( rectTorusVert, rectTorusFrag );
|
||||
depth.replaceShader( rectTorusVert, depthFrag );
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -70,9 +70,9 @@ export class FlashyTerrain extends Entity {
|
||||
|
||||
// -- mesh -------------------------------------------------------------------------------------
|
||||
this.mesh = new Mesh( {
|
||||
geometry,
|
||||
geometry: geometry,
|
||||
materials,
|
||||
name: process.env.DEV && 'FlashyTerrain/mesh',
|
||||
name: process.env.DEV && 'Cube/mesh',
|
||||
} );
|
||||
this.components.push( this.mesh );
|
||||
}
|
@@ -2,9 +2,11 @@ import { Entity } from '../heck/Entity';
|
||||
import { InstancedGeometry } from '../heck/InstancedGeometry';
|
||||
import { Material } from '../heck/Material';
|
||||
import { Mesh } from '../heck/components/Mesh';
|
||||
import { auto } from '../globals/automaton';
|
||||
import { dummyRenderTarget } from '../globals/dummyRenderTarget';
|
||||
import { genTorus } from '../geometries/genTorus';
|
||||
import { glCat } from '../globals/canvas';
|
||||
import { objectValuesMap } from '../utils/objectEntriesMap';
|
||||
import depthFrag from '../shaders/depth.frag';
|
||||
import ringsFrag from '../shaders/rings.frag';
|
||||
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 -------------------------------------------------------------------------------------
|
||||
const mesh = new Mesh( {
|
||||
geometry,
|
||||
|
@@ -4,15 +4,20 @@ import { Entity } from '../heck/Entity';
|
||||
import { LightEntity } from './LightEntity';
|
||||
import { Vector3 } from '@fms-cat/experimental';
|
||||
|
||||
|
||||
interface SceneBeginOptions {
|
||||
scenes: Entity[];
|
||||
}
|
||||
|
||||
export class SceneBegin extends Entity {
|
||||
public readonly lights: LightEntity[];
|
||||
|
||||
public constructor() {
|
||||
public constructor( { scenes }: SceneBeginOptions ) {
|
||||
super();
|
||||
|
||||
// -- lights -----------------------------------------------------------------------------------
|
||||
const light1 = new LightEntity( {
|
||||
scenes: [ this ],
|
||||
scenes,
|
||||
shadowMapFov: 30.0,
|
||||
shadowMapNear: 1.0,
|
||||
shadowMapFar: 20.0,
|
||||
@@ -22,7 +27,7 @@ export class SceneBegin extends Entity {
|
||||
light1.transform.lookAt( new Vector3( [ 4.0, 4.0, 4.0 ] ) );
|
||||
|
||||
const light2 = new LightEntity( {
|
||||
scenes: [ this ],
|
||||
scenes,
|
||||
shadowMapFov: 30.0,
|
||||
shadowMapNear: 1.0,
|
||||
shadowMapFar: 20.0,
|
||||
|
@@ -10,11 +10,15 @@ import { Quaternion, Vector3, Xorshift } from '@fms-cat/experimental';
|
||||
import { Rings } from './Rings';
|
||||
import { auto } from '../globals/automaton';
|
||||
|
||||
interface SceneCrystalsOptions {
|
||||
scenes: Entity[];
|
||||
}
|
||||
|
||||
export class SceneCrystals extends Entity {
|
||||
public readonly lights: LightEntity[];
|
||||
private __phantom: Phantom;
|
||||
|
||||
public constructor() {
|
||||
public constructor( { scenes }: SceneCrystalsOptions ) {
|
||||
super();
|
||||
|
||||
// -- crystals ---------------------------------------------------------------------------------
|
||||
@@ -79,15 +83,19 @@ export class SceneCrystals extends Entity {
|
||||
|
||||
// -- lights -----------------------------------------------------------------------------------
|
||||
const light1 = new LightEntity( {
|
||||
scenes: [ this ],
|
||||
scenes,
|
||||
shadowMapFov: 30.0,
|
||||
shadowMapNear: 1.0,
|
||||
shadowMapFar: 20.0,
|
||||
namePrefix: process.env.DEV && 'lightBegin1',
|
||||
namePrefix: process.env.DEV && 'lightCrystals1',
|
||||
} );
|
||||
light1.color = [ 400.0, 400.0, 400.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 ];
|
||||
|
||||
// -- children ---------------------------------------------------------------------------------
|
||||
|
91
src/entities/SceneDynamic.ts
Normal file
91
src/entities/SceneDynamic.ts
Normal 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 );
|
||||
} );
|
||||
}
|
||||
}
|
@@ -8,11 +8,15 @@ import { Quaternion, Vector3 } from '@fms-cat/experimental';
|
||||
import { SufferTexts } from './SufferTexts';
|
||||
import { Wobbleball } from './Wobbleball';
|
||||
|
||||
interface SceneNeuroOptions {
|
||||
scenes: Entity[];
|
||||
}
|
||||
|
||||
export class SceneNeuro extends Entity {
|
||||
public readonly lights: LightEntity[];
|
||||
private readonly __shafts: LightShaft[];
|
||||
|
||||
public constructor() {
|
||||
public constructor( { scenes }: SceneNeuroOptions ) {
|
||||
super();
|
||||
|
||||
// -- lights -----------------------------------------------------------------------------------
|
||||
@@ -26,7 +30,7 @@ export class SceneNeuro extends Entity {
|
||||
[ [ 20.0, 20.0, 20.0 ], [ 0.0, -2.0, 4.0 ], false ],
|
||||
] as TypeScriptSucks ).map( ( [ color, pos, isSpot ], i ) => {
|
||||
const light = new LightEntity( {
|
||||
scenes: [ this ],
|
||||
scenes,
|
||||
shadowMapFov: isSpot ? 15.0 : 50.0,
|
||||
shadowMapNear: 0.5,
|
||||
shadowMapFar: 20.0,
|
||||
@@ -35,7 +39,7 @@ export class SceneNeuro extends Entity {
|
||||
} );
|
||||
|
||||
light.color = color;
|
||||
light.spotness = isSpot ? 0.99 : 0.0;
|
||||
light.spotness = isSpot ? 0.9 : 0.0;
|
||||
light.transform.lookAt( new Vector3( pos ) );
|
||||
|
||||
if ( isSpot ) {
|
||||
|
0
src/entities/StoneParticles.ts
Normal file
0
src/entities/StoneParticles.ts
Normal file
@@ -1,10 +1,11 @@
|
||||
import { AutomatonWithGUI } from '@fms-cat/automaton-with-gui';
|
||||
import { Entity } from '../heck/Entity';
|
||||
import { GPUParticles } from './GPUParticles';
|
||||
import { InstancedGeometry } from '../heck/InstancedGeometry';
|
||||
import { Lambda } from '../heck/components/Lambda';
|
||||
import { Material } from '../heck/Material';
|
||||
import { TRIANGLE_STRIP_QUAD } from '@fms-cat/experimental';
|
||||
import { auto } from '../globals/automaton';
|
||||
import { auto, automaton } from '../globals/automaton';
|
||||
import { dummyRenderTarget } from '../globals/dummyRenderTarget';
|
||||
import { gl, glCat } from '../globals/canvas';
|
||||
import { quadGeometry } from '../globals/quadGeometry';
|
||||
@@ -141,6 +142,20 @@ export class SufferTexts extends Entity {
|
||||
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 ----------------------------------------------------------------------------
|
||||
const gpuParticles = new GPUParticles( {
|
||||
materialCompute,
|
||||
|
120
src/entities/Tetrahedron.ts
Normal file
120
src/entities/Tetrahedron.ts
Normal 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',
|
||||
} ) );
|
||||
}
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
import { Entity } from '../heck/Entity';
|
||||
import { GPUParticles } from './GPUParticles';
|
||||
import { InstancedGeometry } from '../heck/InstancedGeometry';
|
||||
import { Lambda } from '../heck/components/Lambda';
|
||||
import { Material } from '../heck/Material';
|
||||
import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers, dummyRenderTargetTwoDrawBuffers } from '../globals/dummyRenderTarget';
|
||||
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 --------------------------------------------------------------------------
|
||||
const geometryRender = new InstancedGeometry();
|
||||
|
||||
|
@@ -45,7 +45,7 @@ export class Wobbleball extends Entity {
|
||||
raymarchObjectVert,
|
||||
wobbleballFrag,
|
||||
{
|
||||
defines: [ 'SHADOW 1' ],
|
||||
defines: [ 'DEPTH 1' ],
|
||||
initOptions: { geometry, target: dummyRenderTarget }
|
||||
},
|
||||
);
|
||||
|
@@ -79,6 +79,10 @@ async function load(): Promise<void> {
|
||||
( automaton as AutomatonWithGUI ).play();
|
||||
}
|
||||
|
||||
if ( !process.env.DEV ) {
|
||||
document.write( 'Wait a moment... ' );
|
||||
}
|
||||
|
||||
await music.prepare();
|
||||
|
||||
if ( !process.env.DEV ) {
|
||||
|
@@ -406,24 +406,15 @@ vec2 mainAudio( vec4 time ) {
|
||||
dest += 0.25 * kick( t, 1.0 );
|
||||
}
|
||||
|
||||
// -- gabber -------------------------------------------------------------------------------------
|
||||
if (
|
||||
inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON ) &&
|
||||
inRange( mod( time.z, 8.0 * BEAT ), 4.0 * BEAT, 8.0 * BEAT )
|
||||
) {
|
||||
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 );
|
||||
// -- snare --------------------------------------------------------------------------------------
|
||||
if ( inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON - 4.0 * BEAT ) ) {
|
||||
float t = mod( time.z - 4.0 * BEAT, 8.0 * BEAT );
|
||||
dest += 0.1 * snare( t );
|
||||
}
|
||||
|
||||
// -- amen ---------------------------------------------------------------------------------------
|
||||
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 )
|
||||
) {
|
||||
float chunk = floor( 6.0 * fs( lofi( time.z, 0.5 * BEAT ) ) );
|
||||
@@ -473,7 +464,7 @@ vec2 mainAudio( vec4 time ) {
|
||||
}
|
||||
|
||||
// -- 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 );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
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 ---------------------------------------------------------------------------------------
|
||||
@@ -695,6 +692,10 @@ vec2 mainAudio( vec4 time ) {
|
||||
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 ) ) {
|
||||
dest += 0.3 * deepkick( mod( time.z, 8.0 * BEAT ) );
|
||||
}
|
||||
|
97
src/scene.ts
97
src/scene.ts
@@ -9,21 +9,25 @@ import { DeferredCamera } from './entities/DeferredCamera';
|
||||
import { Dog } from './heck/Dog';
|
||||
import { Entity } from './heck/Entity';
|
||||
import { EnvironmentMap } from './entities/EnvironmentMap';
|
||||
import { FlashyTerrain } from './entities/FlashyTerrain';
|
||||
import { FlashyBall } from './entities/FlashyBall';
|
||||
import { FlickyParticles } from './entities/FlickyParticles';
|
||||
import { ForwardCamera } from './entities/ForwardCamera';
|
||||
import { Glitch } from './entities/Glitch';
|
||||
import { IBLLUT } from './entities/IBLLUT';
|
||||
import { IFSAsUsual } from './entities/IFSAsUsual';
|
||||
import { Lambda } from './heck/components/Lambda';
|
||||
import { NoiseVoxels } from './entities/NoiseVoxels';
|
||||
import { PixelSorter } from './entities/PixelSorter';
|
||||
import { Post } from './entities/Post';
|
||||
import { RTInspector } from './entities/RTInspector';
|
||||
import { SceneBegin } from './entities/SceneBegin';
|
||||
import { SceneCrystals } from './entities/SceneCrystals';
|
||||
import { SceneDynamic } from './entities/SceneDynamic';
|
||||
import { SceneNeuro } from './entities/SceneNeuro';
|
||||
import { Serial } from './entities/Serial';
|
||||
import { SphereParticles } from './entities/SphereParticles';
|
||||
import { Swap, Vector3 } from '@fms-cat/experimental';
|
||||
import { Tetrahedron } from './entities/Tetrahedron';
|
||||
import { Trails } from './entities/Trails';
|
||||
import { arraySetDelete } from './utils/arraySetDelete';
|
||||
import { auto, automaton } from './globals/automaton';
|
||||
@@ -50,12 +54,10 @@ dog.root.components.push( new Lambda( {
|
||||
|
||||
// -- util -----------------------------------------------------------------------------------------
|
||||
class EntityReplacer<T extends Entity> {
|
||||
private __root: Entity;
|
||||
public current!: T;
|
||||
public creator: () => T;
|
||||
|
||||
public constructor( root: Entity, creator: () => T, name?: string ) {
|
||||
this.__root = root;
|
||||
public constructor( creator: () => T, name?: string ) {
|
||||
this.creator = creator;
|
||||
this.replace();
|
||||
|
||||
@@ -73,12 +75,12 @@ class EntityReplacer<T extends Entity> {
|
||||
public replace(): void {
|
||||
if ( process.env.DEV ) {
|
||||
if ( this.current ) {
|
||||
arraySetDelete( this.__root.children, this.current );
|
||||
arraySetDelete( dog.root.children, this.current );
|
||||
}
|
||||
}
|
||||
|
||||
this.current = this.creator();
|
||||
this.__root.children.push( this.current );
|
||||
dog.root.children.push( this.current );
|
||||
|
||||
// not visible by default
|
||||
this.current.active = false;
|
||||
@@ -95,7 +97,6 @@ const deferredRoot = new Entity();
|
||||
dog.root.children.push( deferredRoot );
|
||||
|
||||
const replacerSphereParticles = new EntityReplacer(
|
||||
deferredRoot,
|
||||
() => new SphereParticles(),
|
||||
'SphereParticles',
|
||||
);
|
||||
@@ -105,25 +106,57 @@ if ( process.env.DEV && module.hot ) {
|
||||
} );
|
||||
}
|
||||
|
||||
const replacerFlashyTerrain = new EntityReplacer(
|
||||
deferredRoot,
|
||||
() => new FlashyTerrain(),
|
||||
'FlashyTerrain',
|
||||
const replacerFlashyBall = new EntityReplacer(
|
||||
() => new FlashyBall(),
|
||||
'FlashyBall',
|
||||
);
|
||||
if ( process.env.DEV && module.hot ) {
|
||||
module.hot.accept( './entities/FlashyTerrain', () => {
|
||||
replacerFlashyTerrain.replace();
|
||||
module.hot.accept( './entities/FlashyBall', () => {
|
||||
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 ) {
|
||||
module.hot.accept( './entities/Trails', () => {
|
||||
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 ) {
|
||||
module.hot.accept( './entities/SceneBegin', () => {
|
||||
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 ) {
|
||||
module.hot.accept( './entities/SceneNeuro', () => {
|
||||
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 ) {
|
||||
module.hot.accept( './entities/SceneCrystals', () => {
|
||||
replacerSceneCrystals.current.lights.map( ( light ) => arraySetDelete( lights, light ) );
|
||||
@@ -157,7 +211,6 @@ const forwardRoot = new Entity();
|
||||
dog.root.children.push( forwardRoot );
|
||||
|
||||
const replacerFlickyParticles = new EntityReplacer(
|
||||
forwardRoot,
|
||||
() => new FlickyParticles(),
|
||||
'FlickyParticles',
|
||||
);
|
||||
@@ -187,6 +240,7 @@ const swap = new Swap(
|
||||
const lights = [
|
||||
...replacerSceneBegin.current.lights,
|
||||
...replacerSceneNeuro.current.lights,
|
||||
...replacerSceneDynamic.current.lights,
|
||||
...replacerSceneCrystals.current.lights,
|
||||
];
|
||||
|
||||
@@ -222,6 +276,7 @@ const deferredCamera = new DeferredCamera( {
|
||||
} );
|
||||
dog.root.children.push( deferredCamera );
|
||||
replacerSceneNeuro.current.setDefferedCameraTarget( deferredCamera.cameraTarget );
|
||||
replacerSceneDynamic.current.setDefferedCameraTarget( deferredCamera.cameraTarget );
|
||||
replacerSceneCrystals.current.setDefferedCameraTarget( deferredCamera.cameraTarget );
|
||||
|
||||
const forwardCamera = new ForwardCamera( {
|
||||
@@ -275,9 +330,9 @@ dog.root.components.push( new Lambda( {
|
||||
if ( shake > 0.0 ) {
|
||||
camera.transform.position = camera.transform.position.add(
|
||||
new Vector3( [
|
||||
Math.sin( 145.0 * time ),
|
||||
Math.sin( 2.0 + 148.0 * time ),
|
||||
Math.sin( 4.0 + 151.0 * time )
|
||||
Math.sin( 45.0 * time ),
|
||||
Math.sin( 2.0 + 48.0 * time ),
|
||||
Math.sin( 4.0 + 51.0 * time )
|
||||
] ).scale( shake )
|
||||
);
|
||||
}
|
||||
|
@@ -6,7 +6,6 @@ precision highp float;
|
||||
#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;
|
||||
const float foldcos = cos( PI / 5.0 );
|
||||
@@ -23,7 +22,7 @@ const vec3 foldface = vec3( 0.0, foldrem, foldcos );
|
||||
|
||||
in vec4 vPositionWithoutModel;
|
||||
|
||||
#ifdef SHADOW
|
||||
#ifdef DEPTH
|
||||
out vec4 fragColor;
|
||||
#endif
|
||||
|
||||
@@ -41,9 +40,6 @@ 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;
|
||||
@@ -73,7 +69,7 @@ vec3 fold( vec3 p ) {
|
||||
|
||||
float distFunc( vec3 p ) {
|
||||
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 = fold( p );
|
||||
return dot( p, foldface ) - size.x;
|
||||
@@ -98,6 +94,16 @@ void main() {
|
||||
vec3 rayPos = rayOri + rayDir * rayLen;
|
||||
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 ++ ) {
|
||||
dist = distFunc( rayPos );
|
||||
rayLen += 0.5 * dist;
|
||||
@@ -121,11 +127,11 @@ void main() {
|
||||
#ifdef DEFERRED
|
||||
fragPosition = vec4( modelPos.xyz, depth );
|
||||
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 );
|
||||
#endif
|
||||
|
||||
#ifdef SHADOW
|
||||
#ifdef DEPTH
|
||||
float shadowDepth = linearstep(
|
||||
cameraNearFar.x,
|
||||
cameraNearFar.y,
|
||||
|
195
src/shaders/cyclic-board.frag
Normal file
195
src/shaders/cyclic-board.frag
Normal 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
|
||||
}
|
@@ -61,17 +61,6 @@ float dOverlay( vec2 p ) {
|
||||
float d = 1E9;
|
||||
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
|
||||
{
|
||||
float d2 = 1E9;
|
||||
|
@@ -61,11 +61,12 @@ void main() {
|
||||
|
||||
float a = TAU * uv.x;
|
||||
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 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 );
|
||||
for ( int i = 0; i < SAMPLES; i ++ ) {
|
||||
|
@@ -18,23 +18,16 @@ in vec4 vPositionWithoutModel;
|
||||
|
||||
uniform float time;
|
||||
|
||||
#pragma glslify: orthBasis = require( ./modules/orthBasis );
|
||||
#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
|
||||
|
||||
void main() {
|
||||
float grid = max(
|
||||
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 )
|
||||
);
|
||||
float roughness = 0.3 + 0.1 * cyclicNoise( 4.0 * vPositionWithoutModel.xyz ).x;
|
||||
|
||||
#ifdef DEFERRED
|
||||
fragPosition = vPosition;
|
||||
fragNormal = vec4( 0.0, 0.0, 1.0, 1.0 );
|
||||
fragColor = vec4( grid * vec3( 2.0 ), 1.0 );
|
||||
fragWTF = vec4( 0.0, 0.0, 0.0, 1 );
|
||||
fragNormal = vec4( vNormal, 1.0 );
|
||||
fragColor = vec4( vec3( 0.2 ), 1.0 );
|
||||
fragWTF = vec4( roughness, 0.9, 0.0, 2 );
|
||||
#endif
|
||||
}
|
@@ -1,11 +1,14 @@
|
||||
#version 300 es
|
||||
|
||||
layout (location = 0) in vec3 position;
|
||||
layout (location = 1) in vec3 normal;
|
||||
|
||||
out vec4 vPositionWithoutModel;
|
||||
out vec3 vNormal;
|
||||
out vec4 vPosition;
|
||||
out vec4 vPositionWithoutModel;
|
||||
|
||||
uniform float time;
|
||||
uniform float distort;
|
||||
uniform vec2 resolution;
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform mat4 viewMatrix;
|
||||
@@ -15,12 +18,12 @@ uniform mat4 normalMatrix;
|
||||
#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
|
||||
|
||||
void main() {
|
||||
vNormal = normalize( ( normalMatrix * vec4( normal, 1.0 ) ).xyz );
|
||||
|
||||
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.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;
|
||||
outPos.x *= resolution.y / resolution.x;
|
@@ -36,13 +36,6 @@ uniform sampler2D samplerRandomStatic;
|
||||
out vec4 fragColor;
|
||||
#endif
|
||||
|
||||
#ifdef DEFERRED
|
||||
layout (location = 0) out vec4 fragPosition;
|
||||
layout (location = 1) out vec4 fragNormal;
|
||||
layout (location = 2) out vec4 fragColor;
|
||||
layout (location = 3) out vec4 fragWTF;
|
||||
#endif
|
||||
|
||||
#ifdef DEPTH
|
||||
out vec4 fragColor;
|
||||
#endif
|
||||
@@ -185,13 +178,6 @@ void main() {
|
||||
fragColor = vec4( color, 1.0 );
|
||||
#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
|
||||
float depth = linearstep(
|
||||
cameraNearFar.x,
|
||||
|
156
src/shaders/ifs-as-usual.frag
Normal file
156
src/shaders/ifs-as-usual.frag
Normal 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
|
||||
}
|
@@ -19,7 +19,7 @@ const float TAU = PI * 2.0;
|
||||
|
||||
in vec4 vPositionWithoutModel;
|
||||
|
||||
#ifdef SHADOW
|
||||
#ifdef DEPTH
|
||||
out vec4 fragColor;
|
||||
#endif
|
||||
|
||||
@@ -216,11 +216,11 @@ void main() {
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SHADOW
|
||||
#ifdef DEPTH
|
||||
float shadowDepth = linearstep(
|
||||
cameraNearFar.x,
|
||||
cameraNearFar.y,
|
||||
length( cameraPos - rayPos )
|
||||
length( cameraPos - modelPos.xyz )
|
||||
);
|
||||
fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 );
|
||||
#endif
|
||||
|
38
src/shaders/modules/doAnalyticLighting.glsl
Normal file
38
src/shaders/modules/doAnalyticLighting.glsl
Normal 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)
|
40
src/shaders/modules/doShadowMapping.glsl
Normal file
40
src/shaders/modules/doShadowMapping.glsl
Normal 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)
|
29
src/shaders/noise-voxels.frag
Normal file
29
src/shaders/noise-voxels.frag
Normal 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
|
||||
}
|
41
src/shaders/noise-voxels.vert
Normal file
41
src/shaders/noise-voxels.vert
Normal 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;
|
||||
}
|
@@ -12,8 +12,8 @@ const float TAU = PI * 2.0;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform float frameCount;
|
||||
uniform float time;
|
||||
uniform float amp;
|
||||
uniform vec2 resolution;
|
||||
uniform mat4 viewMatrix;
|
||||
uniform mat4 projectionMatrix;
|
||||
@@ -93,7 +93,7 @@ void main() {
|
||||
|
||||
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 ) );
|
||||
col *= ( 0.5 + 0.1 * flicker ) * accum;
|
||||
col *= amp * ( 0.5 + 0.1 * flicker ) * accum;
|
||||
|
||||
fragColor = vec4( col, 1.0 );
|
||||
}
|
||||
|
@@ -70,8 +70,9 @@ vec3 liftGammaGain( vec3 rgb ) {
|
||||
void main() {
|
||||
vec2 uv = vUv;
|
||||
|
||||
if ( mosaicAmp > 1.0 ) {
|
||||
uv = lofi( uv - 0.5, mosaicAmp / resolution ) + mosaicAmp * 0.5 / resolution + 0.5;
|
||||
float mosaic = mosaicAmp * resolution.y;
|
||||
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;
|
||||
|
33
src/shaders/rect-torus.frag
Normal file
33
src/shaders/rect-torus.frag
Normal 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
|
||||
}
|
43
src/shaders/rect-torus.vert
Normal file
43
src/shaders/rect-torus.vert
Normal 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;
|
||||
}
|
@@ -9,6 +9,7 @@ layout (location = 2) in float instanceId;
|
||||
out vec4 vPosition;
|
||||
out vec3 vNormal;
|
||||
|
||||
uniform float begin;
|
||||
uniform float time;
|
||||
uniform vec2 resolution;
|
||||
uniform mat4 projectionMatrix;
|
||||
@@ -36,7 +37,10 @@ void main() {
|
||||
|
||||
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.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();
|
||||
|
@@ -41,7 +41,7 @@ void main() {
|
||||
|
||||
// back to rgb
|
||||
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
|
||||
);
|
||||
|
||||
|
@@ -48,9 +48,9 @@ uniform sampler2D samplerRandom;
|
||||
|
||||
// == commons ======================================================================================
|
||||
#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: doAnalyticLighting = require( ./modules/doAnalyticLighting.glsl );
|
||||
#pragma glslify: doShadowMapping = require( ./modules/doShadowMapping.glsl );
|
||||
|
||||
vec3 catColor( float _p ) {
|
||||
return 0.5 + 0.5 * vec3(
|
||||
@@ -170,36 +170,31 @@ vec3 shadePBR( Isect isect ) {
|
||||
for ( int iLight = 0; iLight < 8; iLight ++ ) {
|
||||
if ( iLight >= lightCount ) { break; }
|
||||
|
||||
// calc vectors
|
||||
vec3 L = lightPos[ iLight ] - isect.position;
|
||||
float lenL = length( L );
|
||||
L = normalize( L );
|
||||
|
||||
vec3 H = normalize( V + L );
|
||||
float NdotL = clamp( dot( isect.normal, L ), EPSILON, 1.0 );
|
||||
float NdotH = clamp( dot( isect.normal, H ), EPSILON, 1.0 );
|
||||
float VdotH = clamp( dot( V, H ), EPSILON, 1.0 );
|
||||
|
||||
float decayL = 1.0 / ( lenL * lenL );
|
||||
// shading
|
||||
vec3 shade = doAnalyticLighting(
|
||||
V,
|
||||
L,
|
||||
isect.normal,
|
||||
isect.color,
|
||||
roughness,
|
||||
metallic
|
||||
) * lightColor[ iLight ] * ao;
|
||||
|
||||
// fetch shadowmap + spot lighting
|
||||
vec4 lightProj = lightPV[ iLight ] * vec4( isect.position, 1.0 );
|
||||
vec2 lightP = lightProj.xy / lightProj.w;
|
||||
|
||||
float shadow = mix(
|
||||
1.0,
|
||||
smoothstep( 1.0, 0.5, length( lightP ) ),
|
||||
shade *= doShadowMapping(
|
||||
L,
|
||||
isect.normal,
|
||||
fetchShadowMap( iLight, 0.5 + 0.5 * lightP ),
|
||||
lightP,
|
||||
lightNearFar[ iLight ],
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -208,16 +203,16 @@ vec3 shadePBR( Isect isect ) {
|
||||
|
||||
// diffuse ibl
|
||||
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
|
||||
);
|
||||
vec3 texEnvDiffuse = sampleEnvNearest( uvEnvDiffuse, 4.0 ).rgb;
|
||||
color += ao * texEnvDiffuse * albedo;
|
||||
|
||||
// reflective ibl
|
||||
vec3 reflEnvReflective = reflect( V, isect.normal );
|
||||
vec3 reflEnvReflective = reflect( -V, isect.normal );
|
||||
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
|
||||
);
|
||||
vec2 brdfEnvReflective = texture( samplerIBLLUT, vec2( NdotV, roughness ) ).xy;
|
||||
@@ -245,7 +240,7 @@ void main() {
|
||||
isect.screenUv = vUv;
|
||||
isect.position = tex0.xyz;
|
||||
isect.depth = tex0.w;
|
||||
isect.normal = tex1.xyz;
|
||||
isect.normal = normalize( tex1.xyz );
|
||||
isect.color = tex2.rgb;
|
||||
isect.materialId = int( tex3.w + 0.5 );
|
||||
isect.materialParams = tex3.xyz;
|
||||
@@ -272,9 +267,9 @@ void main() {
|
||||
color = shadePBR( isect );
|
||||
|
||||
// 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(
|
||||
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
|
||||
);
|
||||
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 = 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 = mix(
|
||||
// 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
|
||||
// );
|
||||
|
||||
|
134
src/shaders/tetrahedron.frag
Normal file
134
src/shaders/tetrahedron.frag
Normal 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
|
||||
}
|
@@ -15,6 +15,7 @@ layout (location = 0) out vec4 fragCompute0;
|
||||
layout (location = 1) out vec4 fragCompute1;
|
||||
|
||||
uniform bool init;
|
||||
uniform bool shouldUpdate;
|
||||
uniform float time;
|
||||
uniform float beat;
|
||||
uniform float trails;
|
||||
@@ -51,7 +52,7 @@ vec4 sampleRandom( vec2 _uv ) {
|
||||
}
|
||||
|
||||
#pragma glslify: prng = require( ./-prng );
|
||||
#pragma glslify: noise = require( ./-simplex4d );
|
||||
#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise );
|
||||
|
||||
vec3 randomSphere( inout vec4 seed ) {
|
||||
vec3 v;
|
||||
@@ -107,11 +108,16 @@ void main() {
|
||||
|
||||
// == if it is not head of particles =============================================================
|
||||
if ( 1.0 < gl_FragCoord.x ) {
|
||||
if ( shouldUpdate ) {
|
||||
uv.x -= 1.0 / resolution.x;
|
||||
}
|
||||
|
||||
vec4 tex0 = texture( samplerCompute0, uv );
|
||||
vec4 tex1 = texture( samplerCompute1, uv );
|
||||
|
||||
if ( shouldUpdate ) {
|
||||
tex0.w = saturate( tex0.w - 1.0 / trailLength ); // decrease the life
|
||||
}
|
||||
|
||||
fragCompute0 = tex0;
|
||||
fragCompute1 = tex1;
|
||||
@@ -157,11 +163,7 @@ void main() {
|
||||
|
||||
// == update particles ===========================================================================
|
||||
// noise field
|
||||
vel += 40.0 * vec3(
|
||||
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;
|
||||
vel += 40.0 * cyclicNoise( pos ) * dt;
|
||||
|
||||
// resistance
|
||||
vel *= exp( -10.0 * dt );
|
||||
|
@@ -34,11 +34,11 @@ mat2 rotate2D( float _t ) {
|
||||
void main() {
|
||||
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 );
|
||||
|
||||
fragPosition = vPosition;
|
||||
fragNormal = vec4( vNormal, 1.0 );
|
||||
fragColor = vColor;
|
||||
fragWTF = vec4( vec3( 0.9, 0.9, emissive ), MTL_PBR );
|
||||
fragWTF = vec4( vec3( 0.4, 0.1, emissive ), MTL_PBR );
|
||||
}
|
||||
|
@@ -7,10 +7,6 @@ precision highp float;
|
||||
#define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a)))
|
||||
|
||||
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 TAU = PI * 2.0;
|
||||
|
||||
@@ -23,7 +19,7 @@ const float TAU = PI * 2.0;
|
||||
|
||||
in vec4 vPositionWithoutModel;
|
||||
|
||||
#ifdef SHADOW
|
||||
#ifdef DEPTH
|
||||
out vec4 fragColor;
|
||||
#endif
|
||||
|
||||
@@ -143,14 +139,14 @@ void main() {
|
||||
fragPosition = vec4( modelPos.xyz, depth );
|
||||
fragNormal = vec4( modelNormal, 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
|
||||
|
||||
#ifdef SHADOW
|
||||
#ifdef DEPTH
|
||||
float shadowDepth = linearstep(
|
||||
cameraNearFar.x,
|
||||
cameraNearFar.y,
|
||||
length( cameraPos - rayPos )
|
||||
length( cameraPos - modelPos.xyz )
|
||||
);
|
||||
fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 );
|
||||
#endif
|
||||
|
57
src/utils/setLightUniforms.ts
Normal file
57
src/utils/setLightUniforms.ts
Normal 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 ),
|
||||
);
|
||||
}
|
@@ -33,6 +33,10 @@ const terserOptions = {
|
||||
]
|
||||
},
|
||||
},
|
||||
format: {
|
||||
ascii_only: true,
|
||||
ecma: 2020,
|
||||
},
|
||||
module: true,
|
||||
toplevel: true,
|
||||
};
|
||||
|
Reference in New Issue
Block a user