mirror of
https://github.com/FMS-Cat/condition.git
synced 2025-08-29 16:19:54 +02:00
future: cubemap
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
export const
|
||||
RTINSPECTOR_MULTIPLE = false,
|
||||
RTINSPECTOR_CAPTURE_NAME: string | null = null,
|
||||
// RTINSPECTOR_CAPTURE_NAME: string | null = 'CameraEntity/cameraTarget',
|
||||
// RTINSPECTOR_CAPTURE_NAME: string | null = 'light1/shadowMap',
|
||||
// RTINSPECTOR_CAPTURE_NAME: string | null = 'EnvironmentMap/swap0',
|
||||
RTINSPECTOR_CAPTURE_INDEX = 0,
|
||||
COMPONENT_UPDATE_BREAKPOINT: string | null = null,
|
||||
// COMPONENT_UPDATE_BREAKPOINT: string | null = 'Bloom/quadDup3',
|
||||
|
@@ -1,6 +1,7 @@
|
||||
export const
|
||||
RANDOM_RESOLUTION = [ 64, 64 ],
|
||||
STATIC_RANDOM_RESOLUTION = [ 2048, 2048 ],
|
||||
CUBEMAP_RESOLUTION = [ 512, 512 ],
|
||||
AO_RESOLUTION_RATIO = 1.0,
|
||||
RESOLUTION = [ 1280, 720 ],
|
||||
MUSIC_BPM = 180,
|
||||
|
@@ -58,6 +58,7 @@ export class CameraEntity {
|
||||
near: 0.1,
|
||||
far: 20.0,
|
||||
name: 'CameraEntity/camera',
|
||||
materialTag: 'deferred',
|
||||
} );
|
||||
this.__entity.components.push( this.__camera );
|
||||
|
||||
|
@@ -2,16 +2,17 @@ import { Quaternion, Vector3 } from '@fms-cat/experimental';
|
||||
import { Mesh } from '../heck/components/Mesh';
|
||||
import { Entity } from '../heck/Entity';
|
||||
import { Geometry } from '../heck/Geometry';
|
||||
import { Material } from '../heck/Material';
|
||||
import { Material, MaterialMap } from '../heck/Material';
|
||||
import cubeVert from '../shaders/cube.vert';
|
||||
import cubeFrag from '../shaders/cube.frag';
|
||||
import depthFrag from '../shaders/depth.frag';
|
||||
import { genCube } from '../geometries/genCube';
|
||||
import { Lambda } from '../heck/components/Lambda';
|
||||
|
||||
export class Cube {
|
||||
public mesh: Mesh;
|
||||
public geometry: Geometry;
|
||||
public material: Material;
|
||||
public materials: MaterialMap<'deferred' | 'shadow'>;
|
||||
public entity: Entity;
|
||||
|
||||
public constructor() {
|
||||
@@ -29,11 +30,11 @@ export class Cube {
|
||||
this.entity.transform.scale = this.entity.transform.scale.scale( 0.8 );
|
||||
|
||||
this.geometry = this.__createGeometry();
|
||||
this.material = this.__createMaterial();
|
||||
this.materials = this.__createMaterials();
|
||||
|
||||
this.mesh = new Mesh( {
|
||||
geometry: this.geometry,
|
||||
material: this.material,
|
||||
materials: this.materials,
|
||||
name: process.env.DEV && 'Cube/mesh',
|
||||
} );
|
||||
this.entity.components.push( this.mesh );
|
||||
@@ -42,6 +43,10 @@ export class Cube {
|
||||
onUpdate: ( { time } ) => {
|
||||
this.entity.transform.rotation = rot0.multiply(
|
||||
Quaternion.fromAxisAngle( new Vector3( [ 0.0, 1.0, 0.0 ] ), time )
|
||||
).multiply(
|
||||
Quaternion.fromAxisAngle( new Vector3( [ 1.0, 0.0, 0.0 ] ), 1.0 )
|
||||
).multiply(
|
||||
Quaternion.fromAxisAngle( new Vector3( [ 0.0, 0.0, 1.0 ] ), 1.0 )
|
||||
);
|
||||
},
|
||||
visible: false,
|
||||
@@ -64,10 +69,14 @@ export class Cube {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
private __createMaterial(): Material {
|
||||
const material = new Material( cubeVert, cubeFrag );
|
||||
private __createMaterials(): MaterialMap<'deferred' | 'shadow'> {
|
||||
const deferred = new Material(
|
||||
cubeVert,
|
||||
cubeFrag,
|
||||
{ defines: { 'DEFERRED': 'true' } },
|
||||
);
|
||||
|
||||
material.addUniform( 'inflate', '1f', 0.01 );
|
||||
const shadow = new Material( cubeVert, depthFrag );
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
@@ -77,12 +86,13 @@ export class Cube {
|
||||
'../shaders/cube.frag',
|
||||
],
|
||||
() => {
|
||||
material.replaceShader( cubeVert, cubeFrag );
|
||||
deferred.replaceShader( cubeVert, cubeFrag );
|
||||
shadow.replaceShader( cubeVert, depthFrag );
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return material;
|
||||
return { deferred, shadow };
|
||||
}
|
||||
}
|
||||
|
39
src/entities/CubemapCameraEntity.ts
Normal file
39
src/entities/CubemapCameraEntity.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { Entity } from '../heck/Entity';
|
||||
import { LightEntity } from './LightEntity';
|
||||
import { PerspectiveCamera } from '../heck/components/PerspectiveCamera';
|
||||
import { CubemapRenderTarget } from '../heck/CubemapRenderTarget';
|
||||
import { CubemapCamera } from '../heck/components/CubemapCamera';
|
||||
import { CUBEMAP_RESOLUTION } from '../config';
|
||||
|
||||
export interface CubemapCameraEntityOptions {
|
||||
root: Entity;
|
||||
lights: LightEntity[];
|
||||
}
|
||||
|
||||
export class CubemapCameraEntity {
|
||||
public root: Entity;
|
||||
public camera: PerspectiveCamera;
|
||||
public readonly target: CubemapRenderTarget;
|
||||
public entity: Entity;
|
||||
|
||||
public constructor( options: CubemapCameraEntityOptions ) {
|
||||
this.root = options.root;
|
||||
|
||||
this.entity = new Entity();
|
||||
|
||||
this.target = new CubemapRenderTarget( {
|
||||
width: CUBEMAP_RESOLUTION[ 0 ],
|
||||
height: CUBEMAP_RESOLUTION[ 1 ],
|
||||
} );
|
||||
|
||||
this.camera = new CubemapCamera( {
|
||||
scene: this.root,
|
||||
renderTarget: this.target,
|
||||
near: 0.1,
|
||||
far: 20.0,
|
||||
name: 'CubemapCameraEntity/camera',
|
||||
materialTag: 'forward',
|
||||
} );
|
||||
this.entity.components.push( this.camera );
|
||||
}
|
||||
}
|
@@ -7,6 +7,7 @@ import quadVert from '../shaders/quad.vert';
|
||||
import { BufferRenderTarget } from '../heck/BufferRenderTarget';
|
||||
import { Swap, Xorshift } from '@fms-cat/experimental';
|
||||
import { Lambda } from '../heck/components/Lambda';
|
||||
import { CubemapRenderTarget } from '../heck/CubemapRenderTarget';
|
||||
|
||||
const WIDTH = 1024;
|
||||
const HEIGHT = 512;
|
||||
@@ -20,7 +21,9 @@ export class EnvironmentMap {
|
||||
return this.swap.o.texture;
|
||||
}
|
||||
|
||||
public constructor() {
|
||||
public constructor( { cubemap }: {
|
||||
cubemap: CubemapRenderTarget;
|
||||
} ) {
|
||||
this.entity = new Entity();
|
||||
this.entity.visible = false;
|
||||
|
||||
@@ -47,6 +50,7 @@ export class EnvironmentMap {
|
||||
);
|
||||
material.addUniform( 'uniformSeed', '4f', rng.gen(), rng.gen(), rng.gen(), rng.gen() );
|
||||
material.addUniformTexture( 'sampler0', this.swap.i.texture );
|
||||
material.addUniformCubemap( 'samplerCubemap', cubemap.texture );
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
|
@@ -2,7 +2,7 @@ import { Entity } from '../heck/Entity';
|
||||
import { GPUParticles } from './GPUParticles';
|
||||
import { Geometry } from '../heck/Geometry';
|
||||
import { InstancedGeometry } from '../heck/InstancedGeometry';
|
||||
import { Material } from '../heck/Material';
|
||||
import { Material, MaterialMap } from '../heck/Material';
|
||||
import quadVert from '../shaders/quad.vert';
|
||||
import flickyParticleComputeFrag from '../shaders/flicky-particles-compute.frag';
|
||||
import flickyParticleRenderFrag from '../shaders/flicky-particles-render.frag';
|
||||
@@ -16,24 +16,16 @@ const PARTICLES = PARTICLES_SQRT * PARTICLES_SQRT;
|
||||
|
||||
export class FlickyParticles {
|
||||
public get entity(): Entity {
|
||||
return this.__gpuParticles.entity;
|
||||
return this.gpuParticles.entity;
|
||||
}
|
||||
|
||||
private __gpuParticles: GPUParticles;
|
||||
|
||||
public get materialCompute(): Material {
|
||||
return this.__gpuParticles.materialCompute;
|
||||
}
|
||||
|
||||
public get materialRender(): Material {
|
||||
return this.__gpuParticles.materialRender;
|
||||
}
|
||||
public gpuParticles: GPUParticles;
|
||||
|
||||
public constructor() {
|
||||
this.__gpuParticles = new GPUParticles( {
|
||||
this.gpuParticles = new GPUParticles( {
|
||||
materialCompute: this.__createMaterialCompute(),
|
||||
geometryRender: this.__createGeometryRender(),
|
||||
materialRender: this.__createMaterialRender(),
|
||||
materialsRender: this.__createMaterialsRender(),
|
||||
computeWidth: PARTICLES_SQRT,
|
||||
computeHeight: PARTICLES_SQRT,
|
||||
computeNumBuffers: 1,
|
||||
@@ -99,36 +91,44 @@ export class FlickyParticles {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
private __createMaterialRender(): Material {
|
||||
const material = new Material(
|
||||
private __createMaterialsRender(): MaterialMap {
|
||||
const forward = new Material(
|
||||
flickyParticleRenderVert,
|
||||
flickyParticleRenderFrag,
|
||||
{ defines: { 'FORWARD': 'true' } },
|
||||
);
|
||||
material.addUniform( 'colorVar', '1f', 0.1 );
|
||||
material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
forward.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
|
||||
const deferred = new Material(
|
||||
flickyParticleRenderVert,
|
||||
flickyParticleRenderFrag,
|
||||
{ defines: { 'DEFERRED': 'true' } },
|
||||
);
|
||||
deferred.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
|
||||
const shadow = new Material(
|
||||
flickyParticleRenderVert,
|
||||
flickyParticleRenderFrag,
|
||||
{ defines: { 'SHADOW': 'true' } },
|
||||
);
|
||||
shadow.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
module.hot.accept( '../shaders/flicky-particles-render.vert', () => {
|
||||
material.replaceShader(
|
||||
flickyParticleRenderVert,
|
||||
flickyParticleRenderFrag,
|
||||
module.hot.accept(
|
||||
[
|
||||
'../shaders/flicky-particles-render.vert',
|
||||
'../shaders/flicky-particles-render.frag',
|
||||
],
|
||||
() => {
|
||||
forward.replaceShader( flickyParticleRenderVert, flickyParticleRenderFrag );
|
||||
deferred.replaceShader( flickyParticleRenderVert, flickyParticleRenderFrag );
|
||||
shadow.replaceShader( flickyParticleRenderVert, flickyParticleRenderFrag );
|
||||
}
|
||||
);
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
module.hot.accept( '../shaders/flicky-particles-render.frag', () => {
|
||||
material.replaceShader(
|
||||
flickyParticleRenderVert,
|
||||
flickyParticleRenderFrag,
|
||||
);
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
return material;
|
||||
return { forward, deferred, shadow };
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ import { BufferRenderTarget, BufferRenderTargetOptions } from '../heck/BufferRen
|
||||
import { Entity } from '../heck/Entity';
|
||||
import { Geometry } from '../heck/Geometry';
|
||||
import { Lambda } from '../heck/components/Lambda';
|
||||
import { Material } from '../heck/Material';
|
||||
import { Material, MaterialMap, MaterialTag } from '../heck/Material';
|
||||
import { Mesh } from '../heck/components/Mesh';
|
||||
import { Quad } from '../heck/components/Quad';
|
||||
import { Swap } from '@fms-cat/experimental';
|
||||
@@ -11,7 +11,7 @@ import { gl } from '../globals/canvas';
|
||||
export interface GPUParticlesOptions {
|
||||
materialCompute: Material;
|
||||
geometryRender: Geometry;
|
||||
materialRender: Material;
|
||||
materialsRender: Partial<MaterialMap<MaterialTag>>;
|
||||
computeWidth: number;
|
||||
computeHeight: number;
|
||||
computeNumBuffers: number;
|
||||
@@ -39,8 +39,8 @@ export class GPUParticles {
|
||||
return this.__quadCompute.material;
|
||||
}
|
||||
|
||||
public get materialRender(): Material {
|
||||
return this.__meshRender.material;
|
||||
public get materialsRender(): Partial<MaterialMap<MaterialTag>> {
|
||||
return this.__meshRender.materials;
|
||||
}
|
||||
|
||||
public constructor( options: GPUParticlesOptions ) {
|
||||
@@ -75,11 +75,14 @@ export class GPUParticles {
|
||||
`samplerCompute${ i }`,
|
||||
this.__swapCompute.i.getTexture( attachment )
|
||||
);
|
||||
this.materialRender.addUniformTexture(
|
||||
|
||||
for ( const material of Object.values( this.materialsRender ) ) {
|
||||
material?.addUniformTexture(
|
||||
`samplerCompute${ i }`,
|
||||
this.__swapCompute.o.getTexture( attachment )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.__quadCompute.target = this.__swapCompute.o;
|
||||
},
|
||||
@@ -98,15 +101,19 @@ export class GPUParticles {
|
||||
// -- render -----------------------------------------------------------------------------------
|
||||
this.__meshRender = new Mesh( {
|
||||
geometry: options.geometryRender,
|
||||
material: options.materialRender,
|
||||
materials: options.materialsRender,
|
||||
name: process.env.DEV && `${ options.namePrefix }/meshRender`,
|
||||
} );
|
||||
options.materialRender.addUniform(
|
||||
|
||||
for ( const material of Object.values( options.materialsRender ) ) {
|
||||
material?.addUniform(
|
||||
'resolutionCompute',
|
||||
'2f',
|
||||
options.computeWidth,
|
||||
options.computeHeight
|
||||
);
|
||||
}
|
||||
|
||||
this.__entity.components.push( this.__meshRender );
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,9 @@
|
||||
import { BufferRenderTarget } from '../heck/BufferRenderTarget';
|
||||
import { Entity } from '../heck/Entity';
|
||||
import { Lambda } from '../heck/components/Lambda';
|
||||
import { Material } from '../heck/Material';
|
||||
import { PerspectiveCamera } from '../heck/components/PerspectiveCamera';
|
||||
import { Quad } from '../heck/components/Quad';
|
||||
import { Swap } from '@fms-cat/experimental';
|
||||
import posToDepthFrag from '../shaders/pos-to-depth.frag';
|
||||
import quadVert from '../shaders/quad.vert';
|
||||
import shadowBlurFrag from '../shaders/shadow-blur.frag';
|
||||
|
||||
@@ -52,8 +50,8 @@ export class LightEntity {
|
||||
this.__entity = new Entity();
|
||||
|
||||
const swapOptions = {
|
||||
width: options.shadowMapWidth || 1024,
|
||||
height: options.shadowMapHeight || 1024
|
||||
width: options.shadowMapWidth ?? 1024,
|
||||
height: options.shadowMapHeight ?? 1024
|
||||
};
|
||||
|
||||
const swap = new Swap(
|
||||
@@ -68,9 +66,9 @@ export class LightEntity {
|
||||
);
|
||||
|
||||
// -- camera -----------------------------------------------------------------------------------
|
||||
const fov = options.shadowMapFov || 45.0;
|
||||
const near = options.shadowMapNear || 0.1;
|
||||
const far = options.shadowMapFar || 100.0;
|
||||
const fov = options.shadowMapFov ?? 45.0;
|
||||
const near = options.shadowMapNear ?? 0.1;
|
||||
const far = options.shadowMapFar ?? 100.0;
|
||||
|
||||
this.__shadowMapCamera = new PerspectiveCamera( {
|
||||
fov,
|
||||
@@ -79,44 +77,20 @@ export class LightEntity {
|
||||
renderTarget: swap.o,
|
||||
scene: this.__root,
|
||||
name: process.env.DEV && `${ options.namePrefix }/shadowMapCamera`,
|
||||
materialTag: 'shadow',
|
||||
} );
|
||||
this.__shadowMapCamera.clear = [ 1.0, 1.0, 1.0, 1.0 ];
|
||||
this.__entity.components.push( this.__shadowMapCamera );
|
||||
|
||||
this.__shadowMap = new BufferRenderTarget( {
|
||||
width: options.shadowMapWidth || 2048,
|
||||
height: options.shadowMapHeight || 2048,
|
||||
width: options.shadowMapWidth ?? 1024,
|
||||
height: options.shadowMapHeight ?? 1024,
|
||||
name: process.env.DEV && `${ options.namePrefix }/shadowMap`,
|
||||
} );
|
||||
|
||||
swap.swap();
|
||||
|
||||
// -- convert ----------------------------------------------------------------------------------
|
||||
const materialConvert = new Material(
|
||||
quadVert,
|
||||
posToDepthFrag
|
||||
);
|
||||
|
||||
materialConvert.addUniformTexture( 'sampler0', swap.i.texture );
|
||||
|
||||
this.__entity.components.push( new Lambda( {
|
||||
onUpdate: () => {
|
||||
materialConvert.addUniform( 'cameraPos', '3f', ...this.entity.transform.position.elements );
|
||||
materialConvert.addUniform( 'cameraNearFar', '2f', this.camera.near, this.camera.far );
|
||||
},
|
||||
visible: false,
|
||||
name: process.env.DEV && `${ options.namePrefix }/setCameraUniforms`,
|
||||
} ) );
|
||||
|
||||
this.__entity.components.push( new Quad( {
|
||||
target: swap.o,
|
||||
material: materialConvert,
|
||||
name: process.env.DEV && `${ options.namePrefix }/quadConvertPosToDepth`,
|
||||
} ) );
|
||||
|
||||
swap.swap();
|
||||
|
||||
// -- blur ---------------------------------------------------------------------------------------
|
||||
// -- blur -------------------------------------------------------------------------------------
|
||||
for ( let i = 0; i < 2; i ++ ) {
|
||||
const material = new Material(
|
||||
quadVert,
|
||||
|
@@ -1,70 +1,63 @@
|
||||
import { GLCatTexture } from '@fms-cat/glcat-ts';
|
||||
import { Mesh, MeshCull } from '../heck/components/Mesh';
|
||||
import { TRIANGLE_STRIP_QUAD, Vector3 } from '@fms-cat/experimental';
|
||||
import { gl, glCat } from '../globals/canvas';
|
||||
import { Entity } from '../heck/Entity';
|
||||
import { Geometry } from '../heck/Geometry';
|
||||
import { Material } from '../heck/Material';
|
||||
import { Material, MaterialMap } from '../heck/Material';
|
||||
import quadVert from '../shaders/quad.vert';
|
||||
import raymarcherFrag from '../shaders/raymarcher.frag';
|
||||
import { Lambda } from '../heck/components/Lambda';
|
||||
import { randomTexture, randomTextureStatic } from '../globals/randomTexture';
|
||||
|
||||
export class Raymarcher {
|
||||
private __mesh: Mesh;
|
||||
private __geometry: Geometry;
|
||||
|
||||
private __material: Material;
|
||||
|
||||
public get material(): Material {
|
||||
return this.__material;
|
||||
}
|
||||
|
||||
private __entity: Entity;
|
||||
|
||||
public get entity(): Entity {
|
||||
return this.__entity;
|
||||
}
|
||||
public materials: MaterialMap<'deferred' | 'shadow'>;
|
||||
public mesh: Mesh;
|
||||
public geometry: Geometry;
|
||||
public readonly entity: Entity;
|
||||
|
||||
public constructor() {
|
||||
this.__entity = new Entity();
|
||||
this.__entity.transform.position = new Vector3( [ 0.0, 0.0, 0.3 ] );
|
||||
this.__entity.transform.scale = new Vector3( [ 16.0, 9.0, 1.0 ] ).scale( 0.15 );
|
||||
this.entity = new Entity();
|
||||
this.entity.transform.position = new Vector3( [ 0.0, 0.0, 0.3 ] );
|
||||
this.entity.transform.scale = new Vector3( [ 16.0, 9.0, 1.0 ] ).scale( 0.15 );
|
||||
|
||||
this.__geometry = this.__createGeoemtry();
|
||||
this.__material = this.__createMaterial();
|
||||
this.geometry = this.__createGeoemtry();
|
||||
this.materials = this.__createMaterials();
|
||||
|
||||
this.__material.addUniform( 'range', '4f', -1.0, -1.0, 1.0, 1.0 );
|
||||
for ( const material of Object.values( this.materials ) ) {
|
||||
material.addUniform( 'range', '4f', -1.0, -1.0, 1.0, 1.0 );
|
||||
|
||||
this.__material.addUniformTexture( 'samplerRandom', randomTexture.texture );
|
||||
this.__material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
material.addUniformTexture( 'samplerRandom', randomTexture.texture );
|
||||
material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
}
|
||||
|
||||
this.__entity.components.push( new Lambda( {
|
||||
this.entity.components.push( new Lambda( {
|
||||
onDraw: ( event ) => {
|
||||
this.__material.addUniform(
|
||||
for ( const material of Object.values( this.materials ) ) {
|
||||
material.addUniform(
|
||||
'cameraNearFar',
|
||||
'2f',
|
||||
event.camera.near,
|
||||
event.camera.far
|
||||
);
|
||||
|
||||
this.__material.addUniformVector(
|
||||
material.addUniformVector(
|
||||
'inversePV',
|
||||
'Matrix4fv',
|
||||
event.projectionMatrix.multiply( event.viewMatrix ).inverse!.elements
|
||||
);
|
||||
}
|
||||
},
|
||||
active: false,
|
||||
name: process.env.DEV && 'Raymarcher/setCameraUniforms',
|
||||
} ) );
|
||||
|
||||
this.__mesh = new Mesh( {
|
||||
geometry: this.__geometry,
|
||||
material: this.__material,
|
||||
this.mesh = new Mesh( {
|
||||
geometry: this.geometry,
|
||||
materials: this.materials,
|
||||
name: process.env.DEV && 'Raymarcher/mesh',
|
||||
} );
|
||||
this.__mesh.cull = MeshCull.None;
|
||||
this.__entity.components.push( this.__mesh );
|
||||
this.mesh.cull = MeshCull.None;
|
||||
this.entity.components.push( this.mesh );
|
||||
}
|
||||
|
||||
protected __createGeoemtry(): Geometry {
|
||||
@@ -84,17 +77,19 @@ export class Raymarcher {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
protected __createMaterial(): Material {
|
||||
const material = new Material( quadVert, raymarcherFrag );
|
||||
protected __createMaterials(): MaterialMap<'deferred' | 'shadow'> {
|
||||
const deferred = new Material( quadVert, raymarcherFrag, { defines: { 'DEFERRED': 'true' } } );
|
||||
const shadow = new Material( quadVert, raymarcherFrag, { defines: { 'SHADOW': 'true' } } );
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
module.hot.accept( '../shaders/raymarcher.frag', () => {
|
||||
material.replaceShader( quadVert, raymarcherFrag );
|
||||
deferred.replaceShader( quadVert, raymarcherFrag );
|
||||
shadow.replaceShader( quadVert, raymarcherFrag );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
return material;
|
||||
return { deferred, shadow };
|
||||
}
|
||||
}
|
||||
|
@@ -4,39 +4,56 @@ import { Mesh } from '../heck/components/Mesh';
|
||||
import { Entity } from '../heck/Entity';
|
||||
import { Geometry } from '../heck/Geometry';
|
||||
import { InstancedGeometry } from '../heck/InstancedGeometry';
|
||||
import { Material } from '../heck/Material';
|
||||
import { Material, MaterialMap } from '../heck/Material';
|
||||
import depthFrag from '../shaders/depth.frag';
|
||||
import ringsVert from '../shaders/rings.vert';
|
||||
import ringsFrag from '../shaders/rings.frag';
|
||||
import { gl, glCat } from '../globals/canvas';
|
||||
import { Lambda } from '../heck/components/Lambda';
|
||||
|
||||
const PRIMCOUNT = 32;
|
||||
|
||||
export class Rings {
|
||||
public mesh: Mesh;
|
||||
public geometry: Geometry;
|
||||
public material: Material;
|
||||
public materials: MaterialMap;
|
||||
public entity: Entity;
|
||||
|
||||
public constructor() {
|
||||
this.entity = new Entity();
|
||||
|
||||
this.entity.transform.rotation = Quaternion.fromAxisAngle(
|
||||
const rot0 = Quaternion.fromAxisAngle(
|
||||
new Vector3( [ 1.0, 0.0, 0.0 ] ),
|
||||
0.4,
|
||||
).multiply( Quaternion.fromAxisAngle(
|
||||
new Vector3( [ 0.0, 0.0, 1.0 ] ),
|
||||
0.4,
|
||||
) );
|
||||
this.entity.transform.rotation = rot0;
|
||||
|
||||
this.geometry = this.__createGeometry();
|
||||
this.material = this.__createMaterial();
|
||||
this.materials = this.__createMaterials();
|
||||
|
||||
this.mesh = new Mesh( {
|
||||
geometry: this.geometry,
|
||||
material: this.material,
|
||||
materials: this.materials,
|
||||
name: process.env.DEV && 'Rings/mesh',
|
||||
} );
|
||||
this.entity.components.push( this.mesh );
|
||||
|
||||
this.entity.components.push( new Lambda( {
|
||||
onUpdate: ( { time } ) => {
|
||||
this.entity.transform.rotation = rot0.multiply(
|
||||
Quaternion.fromAxisAngle( new Vector3( [ 0.0, 1.0, 0.0 ] ), time )
|
||||
).multiply(
|
||||
Quaternion.fromAxisAngle( new Vector3( [ 1.0, 0.0, 0.0 ] ), 1.0 )
|
||||
).multiply(
|
||||
Quaternion.fromAxisAngle( new Vector3( [ 0.0, 0.0, 1.0 ] ), 1.0 )
|
||||
);
|
||||
},
|
||||
visible: false,
|
||||
name: process.env.DEV && 'Cube/speen',
|
||||
} ) );
|
||||
}
|
||||
|
||||
private __createGeometry(): Geometry {
|
||||
@@ -66,10 +83,20 @@ export class Rings {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
private __createMaterial(): Material {
|
||||
const material = new Material( ringsVert, ringsFrag );
|
||||
private __createMaterials(): MaterialMap {
|
||||
const forward = new Material(
|
||||
ringsVert,
|
||||
ringsFrag,
|
||||
{ defines: { 'FORWARD': 'true' } },
|
||||
);
|
||||
|
||||
material.addUniform( 'inflate', '1f', 0.01 );
|
||||
const deferred = new Material(
|
||||
ringsVert,
|
||||
ringsFrag,
|
||||
{ defines: { 'DEFERRED': 'true' } },
|
||||
);
|
||||
|
||||
const shadow = new Material( ringsVert, depthFrag );
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
@@ -79,12 +106,14 @@ export class Rings {
|
||||
'../shaders/rings.frag',
|
||||
],
|
||||
() => {
|
||||
material.replaceShader( ringsVert, ringsFrag );
|
||||
forward.replaceShader( ringsVert, ringsFrag );
|
||||
deferred.replaceShader( ringsVert, ringsFrag );
|
||||
shadow.replaceShader( ringsVert, depthFrag );
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return material;
|
||||
return { forward, deferred, shadow };
|
||||
}
|
||||
}
|
||||
|
@@ -2,8 +2,10 @@ import { Entity } from '../heck/Entity';
|
||||
import { GPUParticles } from './GPUParticles';
|
||||
import { Geometry } from '../heck/Geometry';
|
||||
import { InstancedGeometry } from '../heck/InstancedGeometry';
|
||||
import { Material } from '../heck/Material';
|
||||
import { Material, MaterialMap } from '../heck/Material';
|
||||
import { genOctahedron } from '../geometries/genOctahedron';
|
||||
import depthFrag from '../shaders/depth.frag';
|
||||
import discardFrag from '../shaders/discard.frag';
|
||||
import quadVert from '../shaders/quad.vert';
|
||||
import sphereParticleComputeFrag from '../shaders/sphere-particles-compute.frag';
|
||||
import sphereParticleRenderFrag from '../shaders/sphere-particles-render.frag';
|
||||
@@ -16,24 +18,16 @@ const PARTICLES = PARTICLES_SQRT * PARTICLES_SQRT;
|
||||
|
||||
export class SphereParticles {
|
||||
public get entity(): Entity {
|
||||
return this.__gpuParticles.entity;
|
||||
return this.gpuParticles.entity;
|
||||
}
|
||||
|
||||
private __gpuParticles: GPUParticles;
|
||||
|
||||
public get materialCompute(): Material {
|
||||
return this.__gpuParticles.materialCompute;
|
||||
}
|
||||
|
||||
public get materialRender(): Material {
|
||||
return this.__gpuParticles.materialRender;
|
||||
}
|
||||
public gpuParticles: GPUParticles;
|
||||
|
||||
public constructor() {
|
||||
this.__gpuParticles = new GPUParticles( {
|
||||
this.gpuParticles = new GPUParticles( {
|
||||
materialCompute: this.__createMaterialCompute(),
|
||||
geometryRender: this.__createGeometryRender(),
|
||||
materialRender: this.__createMaterialRender(),
|
||||
materialsRender: this.__createMaterialsRender(),
|
||||
computeWidth: PARTICLES_SQRT,
|
||||
computeHeight: PARTICLES_SQRT,
|
||||
computeNumBuffers: 2,
|
||||
@@ -59,7 +53,7 @@ export class SphereParticles {
|
||||
}
|
||||
|
||||
private __createGeometryRender(): Geometry {
|
||||
const octahedron = genOctahedron( { radius: 1.0, div: 1 } );
|
||||
const octahedron = genOctahedron( { radius: 1.0, div: 3 } );
|
||||
|
||||
const geometry = new InstancedGeometry();
|
||||
|
||||
@@ -96,42 +90,32 @@ export class SphereParticles {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
private __createMaterialRender(): Material {
|
||||
const material = new Material(
|
||||
private __createMaterialsRender(): MaterialMap<'deferred' | 'shadow'> {
|
||||
const deferred = new Material(
|
||||
sphereParticleRenderVert,
|
||||
sphereParticleRenderFrag,
|
||||
{
|
||||
defines: {
|
||||
'USE_CLIP': 'true',
|
||||
'USE_VERTEX_COLOR': 'true'
|
||||
},
|
||||
},
|
||||
{ defines: { 'DEFERRED': 'true' } },
|
||||
);
|
||||
material.addUniform( 'colorVar', '1f', 0.1 );
|
||||
material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
deferred.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
|
||||
const shadow = new Material( sphereParticleRenderVert, depthFrag );
|
||||
shadow.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
module.hot.accept( '../shaders/sphere-particles-render.vert', () => {
|
||||
material.replaceShader(
|
||||
sphereParticleRenderVert,
|
||||
sphereParticleRenderFrag,
|
||||
module.hot.accept(
|
||||
[
|
||||
'../shaders/sphere-particles-render.vert',
|
||||
'../shaders/sphere-particles-render.frag',
|
||||
],
|
||||
() => {
|
||||
deferred.replaceShader( sphereParticleRenderVert, sphereParticleRenderFrag );
|
||||
shadow.replaceShader( sphereParticleRenderVert, depthFrag );
|
||||
}
|
||||
);
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
module.hot.accept( '../shaders/sphere-particles-render.frag', () => {
|
||||
material.replaceShader(
|
||||
sphereParticleRenderVert,
|
||||
sphereParticleRenderFrag,
|
||||
);
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
return material;
|
||||
return { deferred, shadow };
|
||||
}
|
||||
}
|
||||
|
@@ -2,8 +2,9 @@ import { Entity } from '../heck/Entity';
|
||||
import { GPUParticles } from './GPUParticles';
|
||||
import { Geometry } from '../heck/Geometry';
|
||||
import { InstancedGeometry } from '../heck/InstancedGeometry';
|
||||
import { Material } from '../heck/Material';
|
||||
import { Material, MaterialMap } from '../heck/Material';
|
||||
import quadVert from '../shaders/quad.vert';
|
||||
import depthFrag from '../shaders/depth.frag';
|
||||
import trailsComputeFrag from '../shaders/trails-compute.frag';
|
||||
import trailsRenderFrag from '../shaders/trails-render.frag';
|
||||
import trailsRenderVert from '../shaders/trails-render.vert';
|
||||
@@ -15,24 +16,16 @@ const TRAIL_LENGTH = 64;
|
||||
|
||||
export class Trails {
|
||||
public get entity(): Entity {
|
||||
return this.__gpuParticles.entity;
|
||||
return this.gpuParticles.entity;
|
||||
}
|
||||
|
||||
private __gpuParticles: GPUParticles;
|
||||
|
||||
public get materialCompute(): Material {
|
||||
return this.__gpuParticles.materialCompute;
|
||||
}
|
||||
|
||||
public get materialRender(): Material {
|
||||
return this.__gpuParticles.materialRender;
|
||||
}
|
||||
public gpuParticles: GPUParticles;
|
||||
|
||||
public constructor() {
|
||||
this.__gpuParticles = new GPUParticles( {
|
||||
this.gpuParticles = new GPUParticles( {
|
||||
materialCompute: this.__createMaterialCompute(),
|
||||
geometryRender: this.__createGeometryRender(),
|
||||
materialRender: this.__createMaterialRender(),
|
||||
materialsRender: this.__createMaterialsRender(),
|
||||
computeWidth: TRAIL_LENGTH,
|
||||
computeHeight: TRAILS,
|
||||
computeNumBuffers: 2,
|
||||
@@ -140,33 +133,32 @@ export class Trails {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
private __createMaterialRender(): Material {
|
||||
const material = new Material(
|
||||
private __createMaterialsRender(): MaterialMap<'deferred' | 'shadow'> {
|
||||
const deferred = new Material(
|
||||
trailsRenderVert,
|
||||
trailsRenderFrag,
|
||||
{ defines: { 'DEFERRED': 'true' } },
|
||||
);
|
||||
material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
deferred.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
|
||||
const shadow = new Material( trailsRenderVert, depthFrag );
|
||||
shadow.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
module.hot.accept( '../shaders/trails-render.vert', () => {
|
||||
material.replaceShader(
|
||||
trailsRenderVert,
|
||||
trailsRenderFrag,
|
||||
);
|
||||
} );
|
||||
module.hot.accept(
|
||||
[
|
||||
'../shaders/trails-render.vert',
|
||||
'../shaders/trails-render.frag',
|
||||
],
|
||||
() => {
|
||||
deferred.replaceShader( trailsRenderVert, trailsRenderFrag );
|
||||
shadow.replaceShader( trailsRenderVert, depthFrag );
|
||||
}
|
||||
|
||||
if ( module.hot ) {
|
||||
module.hot.accept( '../shaders/trails-render.frag', () => {
|
||||
material.replaceShader(
|
||||
trailsRenderVert,
|
||||
trailsRenderFrag,
|
||||
);
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
return material;
|
||||
return { deferred, shadow };
|
||||
}
|
||||
}
|
||||
|
@@ -13,29 +13,10 @@ export interface BufferRenderTargetOptions {
|
||||
export class BufferRenderTarget extends RenderTarget {
|
||||
public static nameMap = new Map<string, BufferRenderTarget>();
|
||||
|
||||
private readonly __framebuffer: GLCatFramebuffer;
|
||||
|
||||
public get framebuffer(): GLCatFramebuffer {
|
||||
return this.__framebuffer;
|
||||
}
|
||||
|
||||
private __width: number;
|
||||
|
||||
public get width(): number {
|
||||
return this.__width;
|
||||
}
|
||||
|
||||
private __height: number;
|
||||
|
||||
public get height(): number {
|
||||
return this.__height;
|
||||
}
|
||||
|
||||
private __numBuffers: number;
|
||||
|
||||
public get numBuffers(): number {
|
||||
return this.__numBuffers;
|
||||
}
|
||||
public readonly framebuffer: GLCatFramebuffer;
|
||||
public readonly width: number;
|
||||
public readonly height: number;
|
||||
public readonly numBuffers: number;
|
||||
|
||||
private __name?: string;
|
||||
public get name(): string | undefined {
|
||||
@@ -67,18 +48,18 @@ export class BufferRenderTarget extends RenderTarget {
|
||||
public constructor( options: BufferRenderTargetOptions ) {
|
||||
super();
|
||||
|
||||
this.__framebuffer = glCat.lazyDrawbuffers(
|
||||
this.framebuffer = glCat.lazyDrawbuffers(
|
||||
options.width,
|
||||
options.height,
|
||||
options.numBuffers || 1,
|
||||
options.numBuffers ?? 1,
|
||||
{
|
||||
isFloat: options.isFloat || true
|
||||
isFloat: options.isFloat ?? true
|
||||
}
|
||||
);
|
||||
|
||||
this.__width = options.width;
|
||||
this.__height = options.height;
|
||||
this.__numBuffers = options.numBuffers || 1;
|
||||
this.width = options.width;
|
||||
this.height = options.height;
|
||||
this.numBuffers = options.numBuffers ?? 1;
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
this.name = options?.name;
|
||||
@@ -86,20 +67,20 @@ export class BufferRenderTarget extends RenderTarget {
|
||||
}
|
||||
|
||||
public get texture(): GLCatTexture {
|
||||
return this.__framebuffer.texture!;
|
||||
return this.framebuffer.texture!;
|
||||
}
|
||||
|
||||
public getTexture( attachment: number ): GLCatTexture | null {
|
||||
return this.__framebuffer.getTexture( attachment );
|
||||
return this.framebuffer.getTexture( attachment );
|
||||
}
|
||||
|
||||
public bind(): void {
|
||||
gl.bindFramebuffer( gl.FRAMEBUFFER, this.__framebuffer.raw );
|
||||
glCat.drawBuffers( this.__numBuffers );
|
||||
gl.bindFramebuffer( gl.FRAMEBUFFER, this.framebuffer.raw );
|
||||
glCat.drawBuffers( this.numBuffers );
|
||||
gl.viewport( 0, 0, this.width, this.height );
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this.__framebuffer.dispose();
|
||||
this.framebuffer.dispose();
|
||||
}
|
||||
}
|
||||
|
43
src/heck/CubemapRenderTarget.ts
Normal file
43
src/heck/CubemapRenderTarget.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { GLCatFramebuffer, GLCatTextureCubemap } from '@fms-cat/glcat-ts';
|
||||
import { gl, glCat } from '../globals/canvas';
|
||||
import { RenderTarget } from './RenderTarget';
|
||||
|
||||
export interface CubemapRenderTargetOptions {
|
||||
width: number;
|
||||
height: number;
|
||||
isFloat?: boolean;
|
||||
}
|
||||
|
||||
export class CubemapRenderTarget extends RenderTarget {
|
||||
public readonly framebuffer: GLCatFramebuffer;
|
||||
public readonly texture: GLCatTextureCubemap;
|
||||
public readonly width: number;
|
||||
public readonly height: number;
|
||||
|
||||
public constructor( options: CubemapRenderTargetOptions ) {
|
||||
super();
|
||||
|
||||
const { framebuffer, texture } = glCat.lazyCubemapFramebuffer(
|
||||
options.width,
|
||||
options.height,
|
||||
{
|
||||
isFloat: options.isFloat ?? true
|
||||
},
|
||||
);
|
||||
this.framebuffer = framebuffer;
|
||||
this.texture = texture;
|
||||
|
||||
this.width = options.width;
|
||||
this.height = options.height;
|
||||
}
|
||||
|
||||
public bind(): void {
|
||||
gl.bindFramebuffer( gl.FRAMEBUFFER, this.framebuffer.raw );
|
||||
glCat.drawBuffers( 1 );
|
||||
gl.viewport( 0, 0, this.width, this.height );
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this.framebuffer.dispose();
|
||||
}
|
||||
}
|
@@ -3,6 +3,7 @@ import { Component } from './components/Component';
|
||||
import { Matrix4 } from '@fms-cat/experimental';
|
||||
import { RenderTarget } from './RenderTarget';
|
||||
import { Transform } from './Transform';
|
||||
import { MaterialTag } from './Material';
|
||||
|
||||
export interface EntityUpdateEvent {
|
||||
frameCount: number;
|
||||
@@ -20,6 +21,8 @@ export interface EntityDrawEvent {
|
||||
viewMatrix: Matrix4;
|
||||
projectionMatrix: Matrix4;
|
||||
camera: Camera;
|
||||
cameraTransform: Transform;
|
||||
materialTag: MaterialTag;
|
||||
}
|
||||
|
||||
export class Entity {
|
||||
@@ -69,9 +72,11 @@ export class Entity {
|
||||
renderTarget: event.renderTarget,
|
||||
globalTransform,
|
||||
camera: event.camera,
|
||||
cameraTransform: event.cameraTransform,
|
||||
viewMatrix: event.viewMatrix,
|
||||
projectionMatrix: event.projectionMatrix,
|
||||
entity: this
|
||||
entity: this,
|
||||
materialTag: event.materialTag,
|
||||
} );
|
||||
} );
|
||||
|
||||
@@ -83,7 +88,9 @@ export class Entity {
|
||||
globalTransform,
|
||||
viewMatrix: event.viewMatrix,
|
||||
projectionMatrix: event.projectionMatrix,
|
||||
camera: event.camera
|
||||
camera: event.camera,
|
||||
cameraTransform: event.cameraTransform,
|
||||
materialTag: event.materialTag,
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
@@ -1,7 +1,14 @@
|
||||
import { GLCatProgram, GLCatProgramLinkOptions, GLCatProgramUniformType, GLCatTexture } from '@fms-cat/glcat-ts';
|
||||
import { GLCatProgram, GLCatProgramLinkOptions, GLCatProgramUniformType, GLCatTexture, GLCatTextureCubemap } from '@fms-cat/glcat-ts';
|
||||
import { gl } from '../globals/canvas';
|
||||
import { SHADERPOOL } from './ShaderPool';
|
||||
|
||||
export type MaterialTag =
|
||||
| 'deferred'
|
||||
| 'forward'
|
||||
| 'shadow';
|
||||
|
||||
export type MaterialMap<T extends MaterialTag = MaterialTag> = { [ tag in T ]: Material };
|
||||
|
||||
export class Material {
|
||||
protected __linkOptions: GLCatProgramLinkOptions;
|
||||
|
||||
@@ -29,6 +36,12 @@ export class Material {
|
||||
};
|
||||
} = {};
|
||||
|
||||
protected __uniformCubemaps: {
|
||||
[ name: string ]: {
|
||||
texture: GLCatTextureCubemap | null;
|
||||
};
|
||||
} = {};
|
||||
|
||||
private __vert: string;
|
||||
|
||||
public get vert(): string {
|
||||
@@ -89,6 +102,10 @@ export class Material {
|
||||
this.__uniformTextures[ name ] = { texture };
|
||||
}
|
||||
|
||||
public addUniformCubemap( name: string, texture: GLCatTextureCubemap | null ): void {
|
||||
this.__uniformCubemaps[ name ] = { texture };
|
||||
}
|
||||
|
||||
public setUniforms(): void {
|
||||
const program = this.program;
|
||||
|
||||
@@ -103,6 +120,10 @@ export class Material {
|
||||
Object.entries( this.__uniformTextures ).forEach( ( [ name, { texture } ] ) => {
|
||||
program.uniformTexture( name, texture );
|
||||
} );
|
||||
|
||||
Object.entries( this.__uniformCubemaps ).forEach( ( [ name, { texture } ] ) => {
|
||||
program.uniformCubemap( name, texture );
|
||||
} );
|
||||
}
|
||||
|
||||
public setBlendMode(): void {
|
||||
|
@@ -4,20 +4,18 @@ import { Matrix4 } from '@fms-cat/experimental';
|
||||
import { RenderTarget } from '../RenderTarget';
|
||||
import { Transform } from '../Transform';
|
||||
import { glCat } from '../../globals/canvas';
|
||||
import { MaterialTag } from '../Material';
|
||||
|
||||
export interface CameraOptions extends ComponentOptions {
|
||||
renderTarget?: RenderTarget;
|
||||
projectionMatrix: Matrix4;
|
||||
materialTag: MaterialTag;
|
||||
scene?: Entity;
|
||||
clear?: Array<number | undefined> | false;
|
||||
}
|
||||
|
||||
export abstract class Camera extends Component {
|
||||
protected __projectionMatrix: Matrix4;
|
||||
|
||||
public get projectionMatrix(): Matrix4 {
|
||||
return this.__projectionMatrix;
|
||||
}
|
||||
public projectionMatrix: Matrix4;
|
||||
|
||||
public renderTarget?: RenderTarget;
|
||||
|
||||
@@ -25,6 +23,8 @@ export abstract class Camera extends Component {
|
||||
|
||||
public clear: Array<number | undefined> | false = [];
|
||||
|
||||
public materialTag: MaterialTag;
|
||||
|
||||
public abstract get near(): number;
|
||||
|
||||
public abstract get far(): number;
|
||||
@@ -36,7 +36,8 @@ export abstract class Camera extends Component {
|
||||
|
||||
this.renderTarget = options.renderTarget;
|
||||
this.scene = options.scene;
|
||||
this.__projectionMatrix = options.projectionMatrix;
|
||||
this.projectionMatrix = options.projectionMatrix;
|
||||
this.materialTag = options.materialTag;
|
||||
if ( options.clear !== undefined ) { this.clear = options.clear; }
|
||||
}
|
||||
|
||||
@@ -63,10 +64,12 @@ export abstract class Camera extends Component {
|
||||
frameCount: event.frameCount,
|
||||
time: event.time,
|
||||
renderTarget: renderTarget,
|
||||
cameraTransform: event.globalTransform,
|
||||
globalTransform: new Transform(),
|
||||
viewMatrix,
|
||||
projectionMatrix: this.__projectionMatrix,
|
||||
camera: this
|
||||
projectionMatrix: this.projectionMatrix,
|
||||
camera: this,
|
||||
materialTag: this.materialTag,
|
||||
} );
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
|
@@ -6,6 +6,7 @@ import { Transform } from '../Transform';
|
||||
import { COMPONENT_DRAW_BREAKPOINT, COMPONENT_UPDATE_BREAKPOINT } from '../../config-hot';
|
||||
import { GPUTimer } from '../GPUTimer';
|
||||
import { getDivComponentsDraw, getDivComponentsUpdate } from '../../globals/dom';
|
||||
import { MaterialTag } from '../Material';
|
||||
|
||||
export interface ComponentUpdateEvent {
|
||||
frameCount: number;
|
||||
@@ -19,6 +20,8 @@ export interface ComponentDrawEvent {
|
||||
frameCount: number;
|
||||
time: number;
|
||||
camera: Camera;
|
||||
cameraTransform: Transform;
|
||||
materialTag: MaterialTag;
|
||||
renderTarget: RenderTarget;
|
||||
globalTransform: Transform;
|
||||
viewMatrix: Matrix4;
|
||||
|
81
src/heck/components/CubemapCamera.ts
Normal file
81
src/heck/components/CubemapCamera.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { Camera } from './Camera';
|
||||
import { Entity } from '../Entity';
|
||||
import { Matrix4, Quaternion, Vector3 } from '@fms-cat/experimental';
|
||||
import { ComponentOptions, ComponentUpdateEvent } from './Component';
|
||||
import { CubemapRenderTarget } from '../CubemapRenderTarget';
|
||||
import { gl } from '../../globals/canvas';
|
||||
import { Transform } from '../Transform';
|
||||
import { MaterialTag } from '../Material';
|
||||
|
||||
const INV_SQRT2 = 1.0 / Math.sqrt( 2.0 );
|
||||
|
||||
const CUBEMAP_ROTATIONS = [ // 🔥
|
||||
new Quaternion( [ 0.0, INV_SQRT2, 0.0, INV_SQRT2 ] ), // PX
|
||||
new Quaternion( [ 0.0, -INV_SQRT2, 0.0, INV_SQRT2 ] ), // NX
|
||||
new Quaternion( [ 0.0, INV_SQRT2, INV_SQRT2, 0.0 ] ), // PY
|
||||
new Quaternion( [ 0.0, INV_SQRT2, -INV_SQRT2, 0.0 ] ), // NY
|
||||
new Quaternion( [ 0.0, 1.0, 0.0, 0.0 ] ), // PZ
|
||||
new Quaternion( [ 0.0, 0.0, 0.0, 1.0 ] ), // NZ
|
||||
];
|
||||
|
||||
export interface CubemapCameraOptions extends ComponentOptions {
|
||||
materialTag: MaterialTag;
|
||||
renderTarget?: CubemapRenderTarget;
|
||||
near?: number;
|
||||
far?: number;
|
||||
scene?: Entity;
|
||||
clear?: Array<number | undefined> | false;
|
||||
}
|
||||
|
||||
export class CubemapCamera extends Camera {
|
||||
public renderTarget?: CubemapRenderTarget;
|
||||
public readonly near: number;
|
||||
public readonly far: number;
|
||||
|
||||
public constructor( options: CubemapCameraOptions ) {
|
||||
const projectionMatrix = Matrix4.perspective(
|
||||
90.0,
|
||||
options.near ?? 0.1,
|
||||
options.far ?? 20.0,
|
||||
);
|
||||
|
||||
super( {
|
||||
...options,
|
||||
projectionMatrix,
|
||||
renderTarget: options.renderTarget,
|
||||
scene: options.scene,
|
||||
clear: options.clear,
|
||||
materialTag: options.materialTag,
|
||||
} );
|
||||
|
||||
this.near = options.near ?? 0.1;
|
||||
this.far = options.far ?? 20.0;
|
||||
}
|
||||
|
||||
protected __updateImpl( event: ComponentUpdateEvent ): void {
|
||||
const { renderTarget } = this;
|
||||
|
||||
if ( !renderTarget ) {
|
||||
throw new Error( process.env.DEV && 'You must assign a renderTarget to the Camera' );
|
||||
}
|
||||
|
||||
for ( let i = 0; i < 6; i ++ ) {
|
||||
renderTarget.framebuffer.attachTexture(
|
||||
renderTarget.texture,
|
||||
{ textarget: gl.TEXTURE_CUBE_MAP_POSITIVE_X + i },
|
||||
);
|
||||
|
||||
const globalTransform = new Transform();
|
||||
globalTransform.matrix = Matrix4.compose(
|
||||
event.globalTransform.position,
|
||||
CUBEMAP_ROTATIONS[ i ],
|
||||
new Vector3( [ 1.0, 1.0, 1.0 ] ),
|
||||
);
|
||||
|
||||
super.__updateImpl( {
|
||||
...event,
|
||||
globalTransform,
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
import { Component, ComponentDrawEvent, ComponentOptions } from './Component';
|
||||
import { Geometry } from '../Geometry';
|
||||
import { Material } from '../Material';
|
||||
import { MaterialMap, MaterialTag } from '../Material';
|
||||
import { glCat } from '../../globals/canvas';
|
||||
|
||||
export enum MeshCull {
|
||||
@@ -18,12 +18,12 @@ const meshCullMap = {
|
||||
|
||||
export interface MeshOptions extends ComponentOptions {
|
||||
geometry: Geometry;
|
||||
material: Material;
|
||||
materials: Partial<MaterialMap<MaterialTag>>;
|
||||
}
|
||||
|
||||
export class Mesh extends Component {
|
||||
public geometry: Geometry;
|
||||
public material: Material;
|
||||
public materials: Partial<MaterialMap<MaterialTag>>;
|
||||
|
||||
public cull: MeshCull = MeshCull.Back;
|
||||
|
||||
@@ -33,16 +33,21 @@ export class Mesh extends Component {
|
||||
this.active = false;
|
||||
|
||||
this.geometry = options.geometry;
|
||||
this.material = options.material;
|
||||
this.materials = options.materials;
|
||||
}
|
||||
|
||||
protected __drawImpl( event: ComponentDrawEvent ): void {
|
||||
const gl = glCat.renderingContext;
|
||||
|
||||
const program = this.material.program;
|
||||
const material = this.materials[ event.materialTag ];
|
||||
if ( material == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const program = material.program;
|
||||
|
||||
glCat.useProgram( program );
|
||||
this.material.setBlendMode();
|
||||
material.setBlendMode();
|
||||
|
||||
if ( this.cull === MeshCull.None ) {
|
||||
gl.disable( gl.CULL_FACE );
|
||||
@@ -51,13 +56,15 @@ export class Mesh extends Component {
|
||||
gl.cullFace( meshCullMap[ this.cull ] );
|
||||
}
|
||||
|
||||
this.geometry.assignBuffers( this.material );
|
||||
this.geometry.assignBuffers( material );
|
||||
|
||||
this.material.setUniforms();
|
||||
material.setUniforms();
|
||||
|
||||
program.uniform1f( 'time', event.time );
|
||||
program.uniform1f( 'frameCount', event.frameCount );
|
||||
program.uniform2f( 'resolution', event.renderTarget.width, event.renderTarget.height );
|
||||
program.uniform3f( 'cameraPos', ...event.cameraTransform.position.elements );
|
||||
program.uniform2f( 'cameraNearFar', event.camera.near, event.camera.far );
|
||||
|
||||
program.uniformMatrix4fv( 'normalMatrix', event.globalTransform.matrix.inverse!.transpose.elements );
|
||||
program.uniformMatrix4fv( 'modelMatrix', event.globalTransform.matrix.elements );
|
||||
|
@@ -3,8 +3,10 @@ import { Entity } from '../Entity';
|
||||
import { Matrix4 } from '@fms-cat/experimental';
|
||||
import { RenderTarget } from '../RenderTarget';
|
||||
import { ComponentOptions } from './Component';
|
||||
import { MaterialTag } from '../Material';
|
||||
|
||||
export interface PerspectiveCameraOptions extends ComponentOptions {
|
||||
materialTag: MaterialTag;
|
||||
renderTarget?: RenderTarget;
|
||||
near?: number;
|
||||
far?: number;
|
||||
@@ -14,17 +16,8 @@ export interface PerspectiveCameraOptions extends ComponentOptions {
|
||||
}
|
||||
|
||||
export class PerspectiveCamera extends Camera {
|
||||
private __near: number;
|
||||
|
||||
public get near(): number {
|
||||
return this.__near;
|
||||
}
|
||||
|
||||
private __far: number;
|
||||
|
||||
public get far(): number {
|
||||
return this.__far;
|
||||
}
|
||||
public readonly near: number;
|
||||
public readonly far: number;
|
||||
|
||||
public constructor( options: PerspectiveCameraOptions ) {
|
||||
const projectionMatrix = Matrix4.perspective(
|
||||
@@ -38,10 +31,10 @@ export class PerspectiveCamera extends Camera {
|
||||
projectionMatrix,
|
||||
renderTarget: options.renderTarget,
|
||||
scene: options.scene,
|
||||
clear: options.clear
|
||||
clear: options.clear,
|
||||
} );
|
||||
|
||||
this.__near = options.near || 0.01;
|
||||
this.__far = options.far || 100.0;
|
||||
this.near = options.near || 0.01;
|
||||
this.far = options.far || 100.0;
|
||||
}
|
||||
}
|
||||
|
56
src/scene.ts
56
src/scene.ts
@@ -2,6 +2,7 @@ import { Swap, Vector3 } from '@fms-cat/experimental';
|
||||
import { Bloom } from './entities/Bloom';
|
||||
import { CameraEntity } from './entities/CameraEntity';
|
||||
import { Cube } from './entities/Cube';
|
||||
import { CubemapCameraEntity } from './entities/CubemapCameraEntity';
|
||||
import { EnvironmentMap } from './entities/EnvironmentMap';
|
||||
import { FlickyParticles } from './entities/FlickyParticles';
|
||||
import { Glitch } from './entities/Glitch';
|
||||
@@ -69,23 +70,20 @@ class EntityReplacer<T extends { entity: Entity }> {
|
||||
const ibllut = new IBLLUT();
|
||||
dog.root.children.push( ibllut.entity );
|
||||
|
||||
const environmentMap = new EnvironmentMap();
|
||||
dog.root.children.push( environmentMap.entity );
|
||||
|
||||
// -- "objects" ------------------------------------------------------------------------------------
|
||||
const replacerSphereParticles = new EntityReplacer( () => new SphereParticles() );
|
||||
if ( process.env.DEV && module.hot ) {
|
||||
module.hot.accept( './entities/SphereParticles', () => {
|
||||
replacerSphereParticles.replace();
|
||||
} );
|
||||
}
|
||||
// const replacerSphereParticles = new EntityReplacer( () => new SphereParticles() );
|
||||
// if ( process.env.DEV && module.hot ) {
|
||||
// module.hot.accept( './entities/SphereParticles', () => {
|
||||
// replacerSphereParticles.replace();
|
||||
// } );
|
||||
// }
|
||||
|
||||
const replacerTrails = new EntityReplacer( () => new Trails() );
|
||||
if ( process.env.DEV && module.hot ) {
|
||||
module.hot.accept( './entities/Trails', () => {
|
||||
replacerTrails.replace();
|
||||
} );
|
||||
}
|
||||
// const replacerTrails = new EntityReplacer( () => new Trails() );
|
||||
// if ( process.env.DEV && module.hot ) {
|
||||
// module.hot.accept( './entities/Trails', () => {
|
||||
// replacerTrails.replace();
|
||||
// } );
|
||||
// }
|
||||
|
||||
const replacerRings = new EntityReplacer( () => new Rings() );
|
||||
if ( process.env.DEV && module.hot ) {
|
||||
@@ -94,12 +92,12 @@ if ( process.env.DEV && module.hot ) {
|
||||
} );
|
||||
}
|
||||
|
||||
const replacerCube = new EntityReplacer( () => new Cube() );
|
||||
if ( process.env.DEV && module.hot ) {
|
||||
module.hot.accept( './entities/Cube', () => {
|
||||
replacerCube.replace();
|
||||
} );
|
||||
}
|
||||
// const replacerCube = new EntityReplacer( () => new Cube() );
|
||||
// if ( process.env.DEV && module.hot ) {
|
||||
// module.hot.accept( './entities/Cube', () => {
|
||||
// replacerCube.replace();
|
||||
// } );
|
||||
// }
|
||||
|
||||
const replacerFlickyParticles = new EntityReplacer( () => new FlickyParticles() );
|
||||
if ( process.env.DEV && module.hot ) {
|
||||
@@ -139,7 +137,7 @@ const light = new LightEntity( {
|
||||
shadowMapFar: 20.0,
|
||||
namePrefix: process.env.DEV && 'light1',
|
||||
} );
|
||||
light.color = [ 40.0, 40.0, 40.0 ];
|
||||
light.color = [ 0.1, 0.1, 0.1 ];
|
||||
light.entity.transform.lookAt( new Vector3( [ -1.0, 2.0, 8.0 ] ) );
|
||||
dog.root.children.push( light.entity );
|
||||
|
||||
@@ -154,6 +152,20 @@ dog.root.children.push( light.entity );
|
||||
// light2.entity.transform.lookAt( new Vector3( [ -4.0, -2.0, 6.0 ] ) );
|
||||
// dog.root.children.push( light2.entity );
|
||||
|
||||
const cubemapCamera = new CubemapCameraEntity( {
|
||||
root: dog.root,
|
||||
lights: [
|
||||
light,
|
||||
// light2
|
||||
],
|
||||
} );
|
||||
dog.root.children.push( cubemapCamera.entity );
|
||||
|
||||
const environmentMap = new EnvironmentMap( {
|
||||
cubemap: cubemapCamera.target,
|
||||
} );
|
||||
dog.root.children.push( environmentMap.entity );
|
||||
|
||||
const camera = new CameraEntity( {
|
||||
root: dog.root,
|
||||
target: swap.o,
|
||||
|
@@ -9,10 +9,12 @@ in vec3 vNormal;
|
||||
in vec4 vPosition;
|
||||
in vec4 vPositionWithoutModel;
|
||||
|
||||
layout (location = 0) out vec4 fragPosition;
|
||||
layout (location = 1) out vec4 fragNormal;
|
||||
layout (location = 2) out vec4 fragColor;
|
||||
layout (location = 3) out vec4 fragWTF;
|
||||
#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
|
||||
|
||||
#pragma glslify: noise = require( ./-simplex4d );
|
||||
|
||||
@@ -29,8 +31,10 @@ float fbm( vec4 p ) {
|
||||
void main() {
|
||||
float rough = sin( 14.0 * fbm( vPositionWithoutModel ) );
|
||||
|
||||
#ifdef DEFERRED
|
||||
fragPosition = vPosition;
|
||||
fragNormal = vec4( normalize( vNormal ), 1.0 );
|
||||
fragColor = vec4( vec3( 0.5 ), 1.0 );
|
||||
fragWTF = vec4( vec3( 0.2 + 0.03 * rough, 0.17, 0.0 ), MTL_PBR );
|
||||
fragColor = vec4( vec3( 0.02, 0.04, 0.9 ), 1.0 );
|
||||
fragWTF = vec4( vec3( 0.02 + 0.03 * rough, 0.87, 0.0 ), MTL_PBR );
|
||||
#endif
|
||||
}
|
||||
|
@@ -5,20 +5,18 @@ precision highp float;
|
||||
#define saturate(x) clamp(x,0.,1.)
|
||||
#define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a)))
|
||||
|
||||
in vec2 vUv;
|
||||
in vec4 vPosition;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform vec2 cameraNearFar;
|
||||
uniform vec3 cameraPos;
|
||||
uniform sampler2D sampler0;
|
||||
|
||||
void main() {
|
||||
vec4 tex = texture( sampler0, vUv );
|
||||
float depth = linearstep(
|
||||
cameraNearFar.x,
|
||||
cameraNearFar.y,
|
||||
length( cameraPos - tex.xyz )
|
||||
length( cameraPos - vPosition.xyz )
|
||||
);
|
||||
fragColor = vec4( depth, depth * depth, depth, 1.0 );
|
||||
}
|
@@ -22,6 +22,7 @@ uniform float head;
|
||||
uniform vec2 resolution;
|
||||
uniform vec4 uniformSeed;
|
||||
uniform sampler2D sampler0;
|
||||
uniform samplerCube samplerCubemap;
|
||||
|
||||
vec4 seed;
|
||||
|
||||
@@ -66,14 +67,7 @@ vec3 ImportanceSampleGGX( vec2 Xi, float roughness, vec3 N ) {
|
||||
}
|
||||
|
||||
vec3 haha( vec3 L ) {
|
||||
bool circ = dot( L, normalize( vec3( 1.0, 3.0, 3.0 ) ) ) > 0.9;
|
||||
vec3 c = circ ? 0.01 * vec3( 0.1, 0.1, 1.0 ) : vec3( 0.0 );
|
||||
|
||||
bool ring = abs( dot( L, vec3( -0.3, 1.0, 0.3 ) ) ) < 0.1;
|
||||
c += ring ? 10.0 * vec3( 0.1, 1.0, 0.3 ) : vec3( 0.0 );
|
||||
|
||||
return c;
|
||||
// return 0.5 + 0.5 * L;
|
||||
return texture( samplerCubemap, L ).xyz;
|
||||
}
|
||||
|
||||
void main() {
|
||||
@@ -92,11 +86,11 @@ 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 + N.xyzx;
|
||||
seed = uniformSeed + 500.0 * N.xyzx;
|
||||
|
||||
vec4 col = vec4( 0.0 );
|
||||
for ( int i = 0; i < SAMPLES; i ++ ) {
|
||||
@@ -113,7 +107,7 @@ void main() {
|
||||
|
||||
col.xyz = col.w <= 0.001 ? vec3( 0.0 ) : ( col.xyz / col.w );
|
||||
|
||||
tex.xyz = mix( tex.xyz, col.xyz, 1.0 / 16.0 );
|
||||
tex.xyz = mix( tex.xyz, col.xyz, 1.0 / 4.0 );
|
||||
|
||||
fragColor = vec4( tex, 1.0 );
|
||||
}
|
||||
|
@@ -29,14 +29,27 @@ in vec3 vNormal;
|
||||
in vec4 vPosition;
|
||||
in vec4 vDice;
|
||||
|
||||
layout (location = 0) out vec4 fragPosition;
|
||||
layout (location = 1) out vec4 fragNormal;
|
||||
layout (location = 2) out vec4 fragColor;
|
||||
layout (location = 3) out vec4 fragWTF;
|
||||
|
||||
uniform float time;
|
||||
uniform sampler2D samplerRandomStatic;
|
||||
|
||||
#ifdef FORWARD
|
||||
out vec4 fragColor;
|
||||
#endif
|
||||
|
||||
#ifdef DEFERRED
|
||||
layout (location = 0) out vec4 fragPosition;
|
||||
layout (location = 1) out vec4 fragNormal;
|
||||
layout (location = 2) out vec4 fragColor;
|
||||
layout (location = 3) out vec4 fragWTF;
|
||||
#endif
|
||||
|
||||
#ifdef SHADOW
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform vec2 cameraNearFar;
|
||||
uniform vec3 cameraPos;
|
||||
#endif
|
||||
|
||||
// == utils ========================================================================================
|
||||
mat2 rotate2D( float t ) {
|
||||
return mat2( cos( t ), sin( t ), -sin( t ), cos( t ) );
|
||||
@@ -163,8 +176,23 @@ void main() {
|
||||
|
||||
}
|
||||
|
||||
#ifdef FORWARD
|
||||
fragColor = vec4( 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 SHADOW
|
||||
float depth = linearstep(
|
||||
cameraNearFar.x,
|
||||
cameraNearFar.y,
|
||||
length( cameraPos - vPosition.xyz )
|
||||
);
|
||||
fragColor = vec4( depth, depth * depth, depth, 1.0 );
|
||||
#endif
|
||||
}
|
||||
|
@@ -82,9 +82,8 @@ vec2 filterSaw( vec2 time, float freq, float cutoff, float resonance ) {
|
||||
float kick( float t ) {
|
||||
if ( t < 0.0 ) { return 0.0; }
|
||||
|
||||
float phase = 50.0 * t - 12.0 * exp( -200.0 * t ) - 7.4 * exp( -40.0 * t );
|
||||
float fm = 0.7 * exp( -40.0 * t ) * sin( 2.0 * TAU * phase );
|
||||
return exp( -4.0 * t ) * sin( TAU * phase + fm );
|
||||
float phase = 50.0 * t - 15.0 * exp( -200.0 * t ) - 9.4 * exp( -30.0 * t );
|
||||
return exp( -4.0 * t ) * sin( TAU * phase );
|
||||
}
|
||||
|
||||
vec2 longsnare( float t ) {
|
||||
@@ -145,7 +144,7 @@ vec2 crash( float t ) {
|
||||
if ( t < 0.0 ) { return vec2( 0.0 ); }
|
||||
|
||||
t = t + 0.01 * sin( 0.5 * exp( -40.0 * t ) + 3.0 );
|
||||
t = lofi( t, 0.00004 );
|
||||
t = lofi( 0.8 * t, 0.00004 );
|
||||
float fmamp = -3.4 * exp( -1.0 * t );
|
||||
vec2 fm = fmamp * sin( vec2( 38855.0, 38865.0 ) * t );
|
||||
float amp = exp( -3.0 * t );
|
||||
@@ -234,7 +233,7 @@ vec2 mainAudio( vec4 time ) {
|
||||
: time.x;
|
||||
float sidechain = smoothstep( 0.0, 0.7 * BEAT, tKick );
|
||||
{
|
||||
dest += 0.2 * kick( tKick );
|
||||
dest += 0.25 * kick( tKick );
|
||||
}
|
||||
|
||||
// -- snare --------------------------------------------------------------------------------------
|
||||
@@ -262,7 +261,7 @@ vec2 mainAudio( vec4 time ) {
|
||||
}
|
||||
|
||||
if (
|
||||
inRange( time.w, SECTION_PSY + 32.0 * BEAT, 1E9 )
|
||||
inRange( time.w, SECTION_PSY + 31.5 * BEAT, 1E9 )
|
||||
) {
|
||||
float t = mod( time.x - 0.5 * BEAT, BEAT );
|
||||
dest += 0.1 * mix( 0.3, 1.0, sidechain ) * hihat( t, 20.0 );
|
||||
@@ -299,7 +298,7 @@ vec2 mainAudio( vec4 time ) {
|
||||
|
||||
// -- amen ---------------------------------------------------------------------------------------
|
||||
if (
|
||||
inRange( time.w, SECTION_PORTER_FUCKING_ROBINSON, SECTION_AAAA - 8.0 * BEAT ) &&
|
||||
inRange( time.w, SECTION_PORTER_FUCKING_ROBINSON, SECTION_AAAA - 8.0 * BEAT ) ||
|
||||
inRange( time.w, SECTION_AAAA, SECTION_PSY )
|
||||
) {
|
||||
float chunk = floor( 6.0 * fs( lofi( time.z, 0.5 * BEAT ) ) );
|
||||
@@ -336,6 +335,7 @@ vec2 mainAudio( vec4 time ) {
|
||||
// -- superbass ----------------------------------------------------------------------------------
|
||||
if ( inRange( time.w, SECTION_PORTER_FUCKING_ROBINSON, SECTION_AAAA ) ) {
|
||||
float t = mod( time.z, 8.0 * BEAT );
|
||||
t += 1.0 * inRangeInteg( time.z, 28.0 * BEAT, 31.5 * BEAT, 50.0 );
|
||||
float freq = n2f( float( chordsB[ progB ] ) ) * 0.125;
|
||||
float fadetime = max( 0.0, time.w - SECTION_AAAA + 8.0 * BEAT );
|
||||
dest += 0.1 * exp( -1.0 * fadetime ) * mix( 0.1, 1.0, sidechain ) * superbass( t, freq, exp( -2.0 * fadetime ) );
|
||||
@@ -401,7 +401,7 @@ vec2 mainAudio( vec4 time ) {
|
||||
sum += 0.3 * mix( 0.2, 1.0, sidechain ) * choir( t * rate * 0.5 );
|
||||
}
|
||||
|
||||
dest += 0.1 * aSaturate( sum );
|
||||
dest += 0.12 * aSaturate( sum );
|
||||
}
|
||||
|
||||
// -- harp ---------------------------------------------------------------------------------------
|
||||
@@ -469,7 +469,7 @@ vec2 mainAudio( vec4 time ) {
|
||||
|
||||
dest += 0.2 * kick( t ) * exp( -decay * t );
|
||||
dest += 0.1 * inRangeFloat( time.w, SECTION_PSY - 32.0 * BEAT, 1E9 ) * clap( t );
|
||||
dest += 0.1 * ph * inRangeFloat( time.w, SECTION_PSY - 16.0 * BEAT, 1E9 ) * snare909( t );
|
||||
dest += 0.05 * ph * inRangeFloat( time.w, SECTION_PSY - 16.0 * BEAT, 1E9 ) * snare909( t );
|
||||
}
|
||||
|
||||
// -- fill, before psy ---------------------------------------------------------------------------
|
||||
|
@@ -13,14 +13,21 @@ const int MTL_IRIDESCENT = 4;
|
||||
|
||||
in vec2 vUv;
|
||||
|
||||
layout (location = 0) out vec4 fragPosition;
|
||||
layout (location = 1) out vec4 fragNormal;
|
||||
layout (location = 2) out vec4 fragColor;
|
||||
layout (location = 3) out vec4 fragWTF;
|
||||
#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 SHADOW
|
||||
out vec4 fragColor;
|
||||
#endif
|
||||
|
||||
uniform float time;
|
||||
uniform vec2 resolution;
|
||||
uniform vec2 cameraNearFar;
|
||||
uniform vec3 cameraPos;
|
||||
uniform mat4 viewMatrix;
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform mat4 inversePV;
|
||||
@@ -76,8 +83,19 @@ void main() {
|
||||
float depth = projPos.z / projPos.w;
|
||||
gl_FragDepth = 0.5 + 0.5 * depth;
|
||||
|
||||
#ifdef DEFERRED
|
||||
fragPosition = vec4( rayPos, depth );
|
||||
fragNormal = vec4( normal, 1.0 );
|
||||
fragColor = color;
|
||||
fragWTF = vec4( vec3( 0.8, 0.8, 0.0 ), MTL_PBR );
|
||||
fragWTF = vec4( vec3( 0.2, 0.2, 0.0 ), MTL_PBR );
|
||||
#endif
|
||||
|
||||
#ifdef SHADOW
|
||||
float shadowDepth = linearstep(
|
||||
cameraNearFar.x,
|
||||
cameraNearFar.y,
|
||||
length( cameraPos - rayPos )
|
||||
);
|
||||
fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 );
|
||||
#endif
|
||||
}
|
||||
|
@@ -8,16 +8,28 @@ in float vLife;
|
||||
in vec4 vPosition;
|
||||
in vec3 vNormal;
|
||||
|
||||
layout (location = 0) out vec4 fragPosition;
|
||||
layout (location = 1) out vec4 fragNormal;
|
||||
layout (location = 2) out vec4 fragColor;
|
||||
layout (location = 3) out vec4 fragWTF;
|
||||
#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
|
||||
|
||||
uniform float time;
|
||||
|
||||
void main() {
|
||||
#ifdef FORWARD
|
||||
fragColor = vec4( 28.0 * vec3( 0.2, 0.9, 0.5 ), 1.0 );
|
||||
#endif
|
||||
|
||||
#ifdef DEFERRED
|
||||
fragPosition = vPosition;
|
||||
fragNormal = vec4( normalize( vNormal ), 1.0 );
|
||||
fragColor = vec4( 0.2, 0.9, 0.5, 1.0 );
|
||||
fragWTF = vec4( vec3( 0.2, 0.2, 4.0 ), MTL_PBR );
|
||||
#endif
|
||||
}
|
||||
|
@@ -19,10 +19,12 @@ in vec3 vNormal;
|
||||
in vec4 vColor;
|
||||
in vec4 vRandom;
|
||||
|
||||
layout (location = 0) out vec4 fragPosition;
|
||||
layout (location = 1) out vec4 fragNormal;
|
||||
layout (location = 2) out vec4 fragColor;
|
||||
layout (location = 3) out vec4 fragWTF;
|
||||
#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;
|
||||
|
||||
@@ -35,8 +37,10 @@ mat2 rotate2D( float _t ) {
|
||||
void main() {
|
||||
if ( vColor.a < 0.0 ) { discard; }
|
||||
|
||||
#ifdef DEFERRED
|
||||
fragPosition = vPosition;
|
||||
fragNormal = vec4( vNormal, 1.0 );
|
||||
fragColor = vec4( vColor.xyz, 1.0 );
|
||||
fragWTF = vec4( vec3( 0.4, 0.4, 0.0 ), MTL_PBR );
|
||||
fragWTF = vec4( vec3( 0.1, 0.2, 0.0 ), MTL_PBR );
|
||||
#endif
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@ export class RandomTexture {
|
||||
this.__rng = new Xorshift();
|
||||
this.__array = new Uint8Array( width * height * 4 );
|
||||
this.__texture = glCat.createTexture()!;
|
||||
this.__texture.textureFilter( gl.LINEAR );
|
||||
this.__texture.textureWrap( gl.REPEAT );
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user