mirror of
https://github.com/FMS-Cat/condition.git
synced 2025-08-14 01:33:58 +02:00
performance: Material.d3dSucks
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
import { Mesh } from '../heck/components/Mesh';
|
||||
import { Entity } from '../heck/Entity';
|
||||
import { Geometry } from '../heck/Geometry';
|
||||
import { Material, MaterialMap } from '../heck/Material';
|
||||
import { Material } from '../heck/Material';
|
||||
import svgVert from '../shaders/svg.vert';
|
||||
import conditionCharFrag from '../shaders/condition-char.frag';
|
||||
import { gl, glCat } from '../globals/canvas';
|
||||
import { Vector3 } from '@fms-cat/experimental';
|
||||
import { GLCatTexture } from '@fms-cat/glcat-ts';
|
||||
import { auto } from '../globals/automaton';
|
||||
import { dummyRenderTargetFourDrawBuffers, dummyRenderTargetOneDrawBuffers } from '../globals/dummyRenderTarget';
|
||||
|
||||
const POINTS_MAX = 256;
|
||||
|
||||
@@ -23,34 +24,6 @@ export class ConditionChar extends Entity {
|
||||
|
||||
this.transform.position = this.transform.position.add( new Vector3( [ 2 * pos, 0, 0 ] ) );
|
||||
|
||||
// -- create geometries / materials ------------------------------------------------------------
|
||||
const geometry = this.__createGeometry();
|
||||
const materials = this.__createMaterials();
|
||||
|
||||
// -- create meshes ----------------------------------------------------------------------------
|
||||
const mesh = new Mesh( {
|
||||
geometry,
|
||||
materials,
|
||||
name: process.env.DEV && `ConditionChar/mesh${ i }`,
|
||||
} );
|
||||
this.components.push( mesh );
|
||||
|
||||
// -- material uniforms ------------------------------------------------------------------------
|
||||
for ( const material of Object.values( materials ) ) {
|
||||
material.addUniform( 'svgi', '1f', i );
|
||||
material.addUniformTexture( 'samplerSvg', table );
|
||||
|
||||
auto( 'Condition/phaseOffset', ( { value } ) => {
|
||||
material.addUniform( 'phaseOffset', '1f', value );
|
||||
} );
|
||||
|
||||
auto( 'Condition/phaseWidth', ( { value } ) => {
|
||||
material.addUniform( 'phaseWidth', '1f', value );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
private __createGeometry(): Geometry {
|
||||
// -- create buffers ---------------------------------------------------------------------------
|
||||
const arrayPos = [];
|
||||
const arrayInd = [];
|
||||
@@ -80,7 +53,7 @@ export class ConditionChar extends Entity {
|
||||
const bufferInd = glCat.createBuffer();
|
||||
bufferInd.setIndexbuffer( new Uint16Array( arrayInd ) );
|
||||
|
||||
// -- create attributes ------------------------------------------------------------------------
|
||||
// -- create geometry --------------------------------------------------------------------------
|
||||
const geometry = new Geometry();
|
||||
|
||||
geometry.vao.bindVertexbuffer( bufferPos, 0, 2 );
|
||||
@@ -90,27 +63,38 @@ export class ConditionChar extends Entity {
|
||||
geometry.mode = gl.TRIANGLES;
|
||||
geometry.indexType = gl.UNSIGNED_SHORT;
|
||||
|
||||
return geometry;
|
||||
}
|
||||
// -- create materials -------------------------------------------------------------------------
|
||||
const initOptions = {
|
||||
geometry,
|
||||
target: dummyRenderTargetFourDrawBuffers,
|
||||
};
|
||||
|
||||
private __createMaterials(): MaterialMap<'forward' | 'deferred' | 'shadow'> {
|
||||
const forward = new Material(
|
||||
svgVert,
|
||||
conditionCharFrag,
|
||||
{ defines: { 'FORWARD': 'true' } },
|
||||
);
|
||||
|
||||
const deferred = new Material(
|
||||
svgVert,
|
||||
conditionCharFrag,
|
||||
{ defines: { 'DEFERRED': 'true' } },
|
||||
);
|
||||
|
||||
const shadow = new Material(
|
||||
svgVert,
|
||||
conditionCharFrag,
|
||||
{ defines: { 'SHADOW': 'true' } },
|
||||
);
|
||||
const materials = {
|
||||
forward: new Material(
|
||||
svgVert,
|
||||
conditionCharFrag,
|
||||
{
|
||||
defines: { 'FORWARD': 'true' },
|
||||
initOptions: { geometry, target: dummyRenderTargetOneDrawBuffers },
|
||||
},
|
||||
),
|
||||
deferred: new Material(
|
||||
svgVert,
|
||||
conditionCharFrag,
|
||||
{
|
||||
defines: { 'DEFERRED': 'true' },
|
||||
initOptions: { geometry, target: dummyRenderTargetFourDrawBuffers },
|
||||
},
|
||||
),
|
||||
shadow: new Material(
|
||||
svgVert,
|
||||
conditionCharFrag,
|
||||
{
|
||||
defines: { 'SHADOW': 'true' },
|
||||
initOptions: { geometry, target: dummyRenderTargetOneDrawBuffers },
|
||||
},
|
||||
),
|
||||
};
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
@@ -120,14 +104,34 @@ export class ConditionChar extends Entity {
|
||||
'../shaders/condition-char.frag',
|
||||
],
|
||||
() => {
|
||||
forward.replaceShader( svgVert, conditionCharFrag );
|
||||
deferred.replaceShader( svgVert, conditionCharFrag );
|
||||
shadow.replaceShader( svgVert, conditionCharFrag );
|
||||
materials.forward.replaceShader( svgVert, conditionCharFrag );
|
||||
materials.deferred.replaceShader( svgVert, conditionCharFrag );
|
||||
materials.shadow.replaceShader( svgVert, conditionCharFrag );
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return { forward, deferred, shadow };
|
||||
// -- create meshes ----------------------------------------------------------------------------
|
||||
const mesh = new Mesh( {
|
||||
geometry,
|
||||
materials,
|
||||
name: process.env.DEV && `ConditionChar/mesh${ i }`,
|
||||
} );
|
||||
this.components.push( mesh );
|
||||
|
||||
// -- material uniforms ------------------------------------------------------------------------
|
||||
for ( const material of Object.values( materials ) ) {
|
||||
material.addUniform( 'svgi', '1f', i );
|
||||
material.addUniformTexture( 'samplerSvg', table );
|
||||
|
||||
auto( 'Condition/phaseOffset', ( { value } ) => {
|
||||
material.addUniform( 'phaseOffset', '1f', value );
|
||||
} );
|
||||
|
||||
auto( 'Condition/phaseWidth', ( { value } ) => {
|
||||
material.addUniform( 'phaseWidth', '1f', value );
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,17 +3,16 @@ 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, MaterialMap } from '../heck/Material';
|
||||
import { Material } 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';
|
||||
import { auto } from '../globals/automaton';
|
||||
import { dummyRenderTargetFourDrawBuffers, dummyRenderTargetOneDrawBuffers } from '../globals/dummyRenderTarget';
|
||||
|
||||
export class Raymarcher {
|
||||
public materials: MaterialMap<'deferred' | 'shadow'>;
|
||||
public mesh: Mesh;
|
||||
public geometry: Geometry;
|
||||
public readonly entity: Entity;
|
||||
|
||||
public constructor() {
|
||||
@@ -21,19 +20,57 @@ export class Raymarcher {
|
||||
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.materials = this.__createMaterials();
|
||||
// -- geometry ---------------------------------------------------------------------------------
|
||||
const geometry = new Geometry();
|
||||
|
||||
for ( const material of Object.values( this.materials ) ) {
|
||||
const bufferPos = glCat.createBuffer();
|
||||
bufferPos.setVertexbuffer( new Float32Array( TRIANGLE_STRIP_QUAD ) );
|
||||
|
||||
geometry.vao.bindVertexbuffer( bufferPos, 0, 2 );
|
||||
|
||||
geometry.count = 4;
|
||||
geometry.mode = gl.TRIANGLE_STRIP;
|
||||
|
||||
// -- materials --------------------------------------------------------------------------------
|
||||
const materials = {
|
||||
deferred: new Material(
|
||||
quadVert,
|
||||
raymarcherFrag,
|
||||
{
|
||||
defines: { 'DEFERRED': 'true' },
|
||||
initOptions: { geometry, target: dummyRenderTargetFourDrawBuffers },
|
||||
},
|
||||
),
|
||||
shadow: new Material(
|
||||
quadVert,
|
||||
raymarcherFrag,
|
||||
{
|
||||
defines: { 'SHADOW': 'true' },
|
||||
initOptions: { geometry, target: dummyRenderTargetOneDrawBuffers }
|
||||
},
|
||||
),
|
||||
};
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
module.hot.accept( '../shaders/raymarcher.frag', () => {
|
||||
materials.deferred.replaceShader( quadVert, raymarcherFrag );
|
||||
materials.shadow.replaceShader( quadVert, raymarcherFrag );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
for ( const material of Object.values( materials ) ) {
|
||||
material.addUniform( 'range', '4f', -1.0, -1.0, 1.0, 1.0 );
|
||||
|
||||
material.addUniformTexture( 'samplerRandom', randomTexture.texture );
|
||||
material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||
}
|
||||
|
||||
// -- updater ----------------------------------------------------------------------------------
|
||||
this.entity.components.push( new Lambda( {
|
||||
onDraw: ( event ) => {
|
||||
for ( const material of Object.values( this.materials ) ) {
|
||||
for ( const material of Object.values( materials ) ) {
|
||||
material.addUniform(
|
||||
'cameraNearFar',
|
||||
'2f',
|
||||
@@ -56,42 +93,13 @@ export class Raymarcher {
|
||||
name: process.env.DEV && 'Raymarcher/updater',
|
||||
} ) );
|
||||
|
||||
// -- mesh -------------------------------------------------------------------------------------
|
||||
this.mesh = new Mesh( {
|
||||
geometry: this.geometry,
|
||||
materials: this.materials,
|
||||
geometry: geometry,
|
||||
materials: materials,
|
||||
name: process.env.DEV && 'Raymarcher/mesh',
|
||||
} );
|
||||
this.mesh.cull = MeshCull.None;
|
||||
this.entity.components.push( this.mesh );
|
||||
}
|
||||
|
||||
protected __createGeoemtry(): Geometry {
|
||||
const geometry = new Geometry();
|
||||
|
||||
const bufferPos = glCat.createBuffer();
|
||||
bufferPos.setVertexbuffer( new Float32Array( TRIANGLE_STRIP_QUAD ) );
|
||||
|
||||
geometry.vao.bindVertexbuffer( bufferPos, 0, 2 );
|
||||
|
||||
geometry.count = 4;
|
||||
geometry.mode = gl.TRIANGLE_STRIP;
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
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', () => {
|
||||
deferred.replaceShader( quadVert, raymarcherFrag );
|
||||
shadow.replaceShader( quadVert, raymarcherFrag );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
return { deferred, shadow };
|
||||
}
|
||||
}
|
||||
|
13
src/globals/dummyRenderTarget.ts
Normal file
13
src/globals/dummyRenderTarget.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { BufferRenderTarget } from '../heck/BufferRenderTarget';
|
||||
|
||||
export const dummyRenderTargetOneDrawBuffers = new BufferRenderTarget( {
|
||||
width: 1,
|
||||
height: 1,
|
||||
numBuffers: 4,
|
||||
} );
|
||||
|
||||
export const dummyRenderTargetFourDrawBuffers = new BufferRenderTarget( {
|
||||
width: 1,
|
||||
height: 1,
|
||||
numBuffers: 4,
|
||||
} );
|
@@ -1,6 +1,8 @@
|
||||
import { GLCatProgram, GLCatProgramLinkOptions, GLCatProgramUniformType, GLCatTexture, GLCatTextureCubemap } from '@fms-cat/glcat-ts';
|
||||
import { gl } from '../globals/canvas';
|
||||
import { gl, glCat } from '../globals/canvas';
|
||||
import { injectCodeToShader } from '../utils/injectCodeToShader';
|
||||
import { Geometry } from './Geometry';
|
||||
import { RenderTarget } from './RenderTarget';
|
||||
import { SHADERPOOL } from './ShaderPool';
|
||||
|
||||
export type MaterialTag =
|
||||
@@ -10,6 +12,11 @@ export type MaterialTag =
|
||||
|
||||
export type MaterialMap<T extends MaterialTag = MaterialTag> = { [ tag in T ]: Material };
|
||||
|
||||
export interface MaterialInitOptions {
|
||||
target: RenderTarget;
|
||||
geometry: Geometry;
|
||||
}
|
||||
|
||||
export class Material {
|
||||
protected __linkOptions: GLCatProgramLinkOptions;
|
||||
|
||||
@@ -76,15 +83,24 @@ export class Material {
|
||||
public constructor(
|
||||
vert: string,
|
||||
frag: string,
|
||||
options?: {
|
||||
{ defines, linkOptions, initOptions }: {
|
||||
defines?: { [ key: string ]: ( string | undefined ) },
|
||||
linkOptions?: GLCatProgramLinkOptions,
|
||||
},
|
||||
initOptions?: MaterialInitOptions,
|
||||
} = {},
|
||||
) {
|
||||
this.__vert = vert;
|
||||
this.__frag = frag;
|
||||
this.__linkOptions = options?.linkOptions ?? {};
|
||||
this.__defines = options?.defines ?? {};
|
||||
this.__linkOptions = linkOptions ?? {};
|
||||
this.__defines = defines ?? {};
|
||||
|
||||
if ( initOptions ) {
|
||||
this.d3dSucks( initOptions );
|
||||
} else {
|
||||
if ( process.env.DEV ) {
|
||||
console.warn( 'Material created without initOptions' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public addUniform( name: string, type: GLCatProgramUniformType, ...value: number[] ): void {
|
||||
@@ -163,6 +179,16 @@ export class Material {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* https://scrapbox.io/fms-cat/WebGL:_%E3%82%B7%E3%82%A7%E3%83%BC%E3%83%80%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E3%81%8C%E9%81%85%E3%81%84
|
||||
*/
|
||||
public d3dSucks( { geometry, target }: MaterialInitOptions ): void {
|
||||
target.bind();
|
||||
glCat.useProgram( this.program, () => {
|
||||
geometry.drawElementsOrArrays();
|
||||
} );
|
||||
}
|
||||
|
||||
protected __withDefines( code: string ): string {
|
||||
let inject = '';
|
||||
|
||||
|
Reference in New Issue
Block a user