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