mirror of
https://github.com/FMS-Cat/condition.git
synced 2025-08-17 02:54:02 +02:00
performance: Material.d3dSucks
This commit is contained in:
@@ -1,13 +1,14 @@
|
|||||||
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, MaterialMap } from '../heck/Material';
|
import { Material } from '../heck/Material';
|
||||||
import svgVert from '../shaders/svg.vert';
|
import svgVert from '../shaders/svg.vert';
|
||||||
import conditionCharFrag from '../shaders/condition-char.frag';
|
import conditionCharFrag from '../shaders/condition-char.frag';
|
||||||
import { gl, glCat } from '../globals/canvas';
|
import { gl, glCat } from '../globals/canvas';
|
||||||
import { Vector3 } from '@fms-cat/experimental';
|
import { Vector3 } from '@fms-cat/experimental';
|
||||||
import { GLCatTexture } from '@fms-cat/glcat-ts';
|
import { GLCatTexture } from '@fms-cat/glcat-ts';
|
||||||
import { auto } from '../globals/automaton';
|
import { auto } from '../globals/automaton';
|
||||||
|
import { dummyRenderTargetFourDrawBuffers, dummyRenderTargetOneDrawBuffers } from '../globals/dummyRenderTarget';
|
||||||
|
|
||||||
const POINTS_MAX = 256;
|
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 ] ) );
|
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 ---------------------------------------------------------------------------
|
// -- create buffers ---------------------------------------------------------------------------
|
||||||
const arrayPos = [];
|
const arrayPos = [];
|
||||||
const arrayInd = [];
|
const arrayInd = [];
|
||||||
@@ -80,7 +53,7 @@ export class ConditionChar extends Entity {
|
|||||||
const bufferInd = glCat.createBuffer();
|
const bufferInd = glCat.createBuffer();
|
||||||
bufferInd.setIndexbuffer( new Uint16Array( arrayInd ) );
|
bufferInd.setIndexbuffer( new Uint16Array( arrayInd ) );
|
||||||
|
|
||||||
// -- create attributes ------------------------------------------------------------------------
|
// -- create geometry --------------------------------------------------------------------------
|
||||||
const geometry = new Geometry();
|
const geometry = new Geometry();
|
||||||
|
|
||||||
geometry.vao.bindVertexbuffer( bufferPos, 0, 2 );
|
geometry.vao.bindVertexbuffer( bufferPos, 0, 2 );
|
||||||
@@ -90,27 +63,38 @@ export class ConditionChar extends Entity {
|
|||||||
geometry.mode = gl.TRIANGLES;
|
geometry.mode = gl.TRIANGLES;
|
||||||
geometry.indexType = gl.UNSIGNED_SHORT;
|
geometry.indexType = gl.UNSIGNED_SHORT;
|
||||||
|
|
||||||
return geometry;
|
// -- create materials -------------------------------------------------------------------------
|
||||||
}
|
const initOptions = {
|
||||||
|
geometry,
|
||||||
|
target: dummyRenderTargetFourDrawBuffers,
|
||||||
|
};
|
||||||
|
|
||||||
private __createMaterials(): MaterialMap<'forward' | 'deferred' | 'shadow'> {
|
const materials = {
|
||||||
const forward = new Material(
|
forward: new Material(
|
||||||
svgVert,
|
svgVert,
|
||||||
conditionCharFrag,
|
conditionCharFrag,
|
||||||
{ defines: { 'FORWARD': 'true' } },
|
{
|
||||||
);
|
defines: { 'FORWARD': 'true' },
|
||||||
|
initOptions: { geometry, target: dummyRenderTargetOneDrawBuffers },
|
||||||
const deferred = new Material(
|
},
|
||||||
|
),
|
||||||
|
deferred: new Material(
|
||||||
svgVert,
|
svgVert,
|
||||||
conditionCharFrag,
|
conditionCharFrag,
|
||||||
{ defines: { 'DEFERRED': 'true' } },
|
{
|
||||||
);
|
defines: { 'DEFERRED': 'true' },
|
||||||
|
initOptions: { geometry, target: dummyRenderTargetFourDrawBuffers },
|
||||||
const shadow = new Material(
|
},
|
||||||
|
),
|
||||||
|
shadow: new Material(
|
||||||
svgVert,
|
svgVert,
|
||||||
conditionCharFrag,
|
conditionCharFrag,
|
||||||
{ defines: { 'SHADOW': 'true' } },
|
{
|
||||||
);
|
defines: { 'SHADOW': 'true' },
|
||||||
|
initOptions: { geometry, target: dummyRenderTargetOneDrawBuffers },
|
||||||
|
},
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
if ( process.env.DEV ) {
|
if ( process.env.DEV ) {
|
||||||
if ( module.hot ) {
|
if ( module.hot ) {
|
||||||
@@ -120,14 +104,34 @@ export class ConditionChar extends Entity {
|
|||||||
'../shaders/condition-char.frag',
|
'../shaders/condition-char.frag',
|
||||||
],
|
],
|
||||||
() => {
|
() => {
|
||||||
forward.replaceShader( svgVert, conditionCharFrag );
|
materials.forward.replaceShader( svgVert, conditionCharFrag );
|
||||||
deferred.replaceShader( svgVert, conditionCharFrag );
|
materials.deferred.replaceShader( svgVert, conditionCharFrag );
|
||||||
shadow.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 { 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, MaterialMap } from '../heck/Material';
|
import { Material } 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';
|
||||||
import { auto } from '../globals/automaton';
|
import { auto } from '../globals/automaton';
|
||||||
|
import { dummyRenderTargetFourDrawBuffers, dummyRenderTargetOneDrawBuffers } from '../globals/dummyRenderTarget';
|
||||||
|
|
||||||
export class Raymarcher {
|
export class Raymarcher {
|
||||||
public materials: MaterialMap<'deferred' | 'shadow'>;
|
|
||||||
public mesh: Mesh;
|
public mesh: Mesh;
|
||||||
public geometry: Geometry;
|
|
||||||
public readonly entity: Entity;
|
public readonly entity: Entity;
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
@@ -21,19 +20,57 @@ export class Raymarcher {
|
|||||||
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();
|
// -- geometry ---------------------------------------------------------------------------------
|
||||||
this.materials = this.__createMaterials();
|
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.addUniform( 'range', '4f', -1.0, -1.0, 1.0, 1.0 );
|
||||||
|
|
||||||
material.addUniformTexture( 'samplerRandom', randomTexture.texture );
|
material.addUniformTexture( 'samplerRandom', randomTexture.texture );
|
||||||
material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -- updater ----------------------------------------------------------------------------------
|
||||||
this.entity.components.push( new Lambda( {
|
this.entity.components.push( new Lambda( {
|
||||||
onDraw: ( event ) => {
|
onDraw: ( event ) => {
|
||||||
for ( const material of Object.values( this.materials ) ) {
|
for ( const material of Object.values( materials ) ) {
|
||||||
material.addUniform(
|
material.addUniform(
|
||||||
'cameraNearFar',
|
'cameraNearFar',
|
||||||
'2f',
|
'2f',
|
||||||
@@ -56,42 +93,13 @@ export class Raymarcher {
|
|||||||
name: process.env.DEV && 'Raymarcher/updater',
|
name: process.env.DEV && 'Raymarcher/updater',
|
||||||
} ) );
|
} ) );
|
||||||
|
|
||||||
|
// -- mesh -------------------------------------------------------------------------------------
|
||||||
this.mesh = new Mesh( {
|
this.mesh = new Mesh( {
|
||||||
geometry: this.geometry,
|
geometry: geometry,
|
||||||
materials: this.materials,
|
materials: 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 {
|
|
||||||
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 { 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 { injectCodeToShader } from '../utils/injectCodeToShader';
|
||||||
|
import { Geometry } from './Geometry';
|
||||||
|
import { RenderTarget } from './RenderTarget';
|
||||||
import { SHADERPOOL } from './ShaderPool';
|
import { SHADERPOOL } from './ShaderPool';
|
||||||
|
|
||||||
export type MaterialTag =
|
export type MaterialTag =
|
||||||
@@ -10,6 +12,11 @@ export type MaterialTag =
|
|||||||
|
|
||||||
export type MaterialMap<T extends MaterialTag = MaterialTag> = { [ tag in T ]: Material };
|
export type MaterialMap<T extends MaterialTag = MaterialTag> = { [ tag in T ]: Material };
|
||||||
|
|
||||||
|
export interface MaterialInitOptions {
|
||||||
|
target: RenderTarget;
|
||||||
|
geometry: Geometry;
|
||||||
|
}
|
||||||
|
|
||||||
export class Material {
|
export class Material {
|
||||||
protected __linkOptions: GLCatProgramLinkOptions;
|
protected __linkOptions: GLCatProgramLinkOptions;
|
||||||
|
|
||||||
@@ -76,15 +83,24 @@ export class Material {
|
|||||||
public constructor(
|
public constructor(
|
||||||
vert: string,
|
vert: string,
|
||||||
frag: string,
|
frag: string,
|
||||||
options?: {
|
{ defines, linkOptions, initOptions }: {
|
||||||
defines?: { [ key: string ]: ( string | undefined ) },
|
defines?: { [ key: string ]: ( string | undefined ) },
|
||||||
linkOptions?: GLCatProgramLinkOptions,
|
linkOptions?: GLCatProgramLinkOptions,
|
||||||
},
|
initOptions?: MaterialInitOptions,
|
||||||
|
} = {},
|
||||||
) {
|
) {
|
||||||
this.__vert = vert;
|
this.__vert = vert;
|
||||||
this.__frag = frag;
|
this.__frag = frag;
|
||||||
this.__linkOptions = options?.linkOptions ?? {};
|
this.__linkOptions = linkOptions ?? {};
|
||||||
this.__defines = options?.defines ?? {};
|
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 {
|
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 {
|
protected __withDefines( code: string ): string {
|
||||||
let inject = '';
|
let inject = '';
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user