From d51a3ccb96e9603ca8a39ba80e99371dc7ad391a Mon Sep 17 00:00:00 2001 From: FMS-Cat Date: Sun, 14 Mar 2021 02:51:43 +0900 Subject: [PATCH] refactor: gpu particles are now ppp free, shoutouts to drawBuffers --- src/config-hot.ts | 2 +- src/entities/GPUParticles.ts | 16 +++++++- src/entities/SphereParticles.ts | 14 ++----- src/entities/Trails.ts | 10 ++--- src/shaders/sphere-particles-compute.frag | 24 +++++------- src/shaders/sphere-particles-render.vert | 14 +++---- src/shaders/trails-compute.frag | 47 +++++++++-------------- src/shaders/trails-render.vert | 16 ++++---- 8 files changed, 62 insertions(+), 81 deletions(-) diff --git a/src/config-hot.ts b/src/config-hot.ts index 2bf4ef6..a30f9a3 100644 --- a/src/config-hot.ts +++ b/src/config-hot.ts @@ -4,4 +4,4 @@ export const RTINSPECTOR_CAPTURE_INDEX = 0, COMPONENT_UPDATE_BREAKPOINT: string | null = null, // COMPONENT_UPDATE_BREAKPOINT: string | null = 'Bloom/quadDup3', - COMPONENT_DRAW_BREAKPOINT: string | null = 'Rings/meshRender'; + COMPONENT_DRAW_BREAKPOINT: string | null = null; diff --git a/src/entities/GPUParticles.ts b/src/entities/GPUParticles.ts index f4363bc..3cc0415 100644 --- a/src/entities/GPUParticles.ts +++ b/src/entities/GPUParticles.ts @@ -6,6 +6,7 @@ import { Material } from '../heck/Material'; import { Mesh } from '../heck/components/Mesh'; import { Quad } from '../heck/components/Quad'; import { Swap } from '@fms-cat/experimental'; +import { DISPLAY } from '../heck/DISPLAY'; export interface GPUParticlesOptions { materialCompute: Material; @@ -67,9 +68,20 @@ export class GPUParticles { onUpdate: () => { this.__swapCompute.swap(); - this.materialCompute.addUniformTexture( 'samplerCompute', this.__swapCompute.i.texture ); + for ( let i = 0; i < options.computeNumBuffers; i ++ ) { + const attachment = DISPLAY.gl.COLOR_ATTACHMENT0 + i; + + this.materialCompute.addUniformTexture( + `samplerCompute${ i }`, + this.__swapCompute.i.getTexture( attachment ) + ); + this.materialRender.addUniformTexture( + `samplerCompute${ i }`, + this.__swapCompute.o.getTexture( attachment ) + ); + } + this.__quadCompute.target = this.__swapCompute.o; - this.materialRender.addUniformTexture( 'samplerCompute', this.__swapCompute.o.texture ); }, visible: false, name: process.env.DEV && `${ options.namePrefix }/swapper`, diff --git a/src/entities/SphereParticles.ts b/src/entities/SphereParticles.ts index 2f126a3..f522905 100644 --- a/src/entities/SphereParticles.ts +++ b/src/entities/SphereParticles.ts @@ -18,8 +18,6 @@ export interface SphereParticlesOptions { } export class SphereParticles { - private static __ppp = 2; - public get entity(): Entity { return this.__gpuParticles.entity; } @@ -39,9 +37,9 @@ export class SphereParticles { materialCompute: this.__createMaterialCompute( options ), geometryRender: this.__createGeometryRender( options ), materialRender: this.__createMaterialRender( options ), - computeWidth: SphereParticles.__ppp * options.particlesSqrt, + computeWidth: options.particlesSqrt, computeHeight: options.particlesSqrt, - computeNumBuffers: 1, + computeNumBuffers: 2, namePrefix: process.env.DEV && 'SphereParticles', } ); } @@ -53,7 +51,6 @@ export class SphereParticles { const material = new Material( quadVert, sphereParticleComputeFrag ); material.addUniform( 'particlesSqrt', '1f', particlesSqrt ); material.addUniform( 'particles', '1f', particles ); - material.addUniform( 'ppp', '1f', SphereParticles.__ppp ); material.addUniformTexture( 'samplerRandom', options.textureRandom ); if ( process.env.DEV ) { @@ -85,10 +82,8 @@ export class SphereParticles { for ( let iy = 0; iy < particlesSqrt; iy ++ ) { for ( let ix = 0; ix < particlesSqrt; ix ++ ) { const i = ix + iy * particlesSqrt; - const s = ( SphereParticles.__ppp * ix + 0.5 ) - / ( SphereParticles.__ppp * particlesSqrt ); - const t = ( iy + 0.5 ) - / ( particlesSqrt ); + const s = ( ix + 0.5 ) / particlesSqrt; + const t = ( iy + 0.5 ) / particlesSqrt; ret[ i * 2 + 0 ] = s; ret[ i * 2 + 1 ] = t; } @@ -122,7 +117,6 @@ export class SphereParticles { }, ); material.addUniform( 'colorVar', '1f', 0.1 ); - material.addUniform( 'ppp', '1f', SphereParticles.__ppp ); material.addUniformTexture( 'samplerRandomStatic', options.textureRandomStatic ); if ( process.env.DEV ) { diff --git a/src/entities/Trails.ts b/src/entities/Trails.ts index d431adc..d2a91ad 100644 --- a/src/entities/Trails.ts +++ b/src/entities/Trails.ts @@ -18,8 +18,6 @@ export interface TrailsOptions { } export class Trails { - private static __ppp = 2; - public get entity(): Entity { return this.__gpuParticles.entity; } @@ -39,9 +37,9 @@ export class Trails { materialCompute: this.__createMaterialCompute( options ), geometryRender: this.__createGeometryRender( options ), materialRender: this.__createMaterialRender( options ), - computeWidth: Trails.__ppp * options.trailLength, + computeWidth: options.trailLength, computeHeight: options.trails, - computeNumBuffers: 1, + computeNumBuffers: 2, namePrefix: process.env.DEV && 'Trails', } ); } @@ -50,7 +48,6 @@ export class Trails { const material = new Material( quadVert, trailsComputeFrag ); material.addUniform( 'trails', '1f', options.trails ); material.addUniform( 'trailLength', '1f', options.trailLength ); - material.addUniform( 'ppp', '1f', Trails.__ppp ); material.addUniformTexture( 'samplerRandom', options.textureRandom ); if ( process.env.DEV ) { @@ -71,7 +68,7 @@ export class Trails { bufferComputeU.setVertexbuffer( ( () => { const ret = new Float32Array( options.trailLength * 3 ); for ( let i = 0; i < options.trailLength; i ++ ) { - const u = ( Trails.__ppp * i + 0.5 ) / ( Trails.__ppp * options.trailLength ); + const u = ( 0.5 + i ) / options.trailLength; ret[ i * 3 + 0 ] = u; ret[ i * 3 + 1 ] = u; ret[ i * 3 + 2 ] = u; @@ -159,7 +156,6 @@ export class Trails { }, ); material.addUniform( 'colorVar', '1f', 0.1 ); - material.addUniform( 'ppp', '1f', Trails.__ppp ); material.addUniformTexture( 'samplerRandomStatic', options.textureRandomStatic ); if ( process.env.DEV ) { diff --git a/src/shaders/sphere-particles-compute.frag b/src/shaders/sphere-particles-compute.frag index acb1340..ccb27d5 100644 --- a/src/shaders/sphere-particles-compute.frag +++ b/src/shaders/sphere-particles-compute.frag @@ -11,19 +11,20 @@ const float TAU = 6.283185307; #define lofi(i,m) (floor((i)/(m))*(m)) #define lofir(i,m) (floor((i)/(m)+.5)*(m)) -out vec4 fragColor; +layout (location = 0) out vec4 fragCompute0; +layout (location = 1) out vec4 fragCompute1; uniform bool init; uniform float time; uniform float beat; uniform float particlesSqrt; -uniform float ppp; uniform float totalFrame; uniform float deltaTime; uniform float noiseScale; uniform float noisePhase; uniform vec2 resolution; -uniform sampler2D samplerCompute; +uniform sampler2D samplerCompute0; +uniform sampler2D samplerCompute1; uniform sampler2D samplerRandom; // uniform float velScale; // uniform float genRate; @@ -105,18 +106,15 @@ vec3 randomBox( inout vec4 seed ) { void main() { vec2 uv = gl_FragCoord.xy / resolution; - vec2 puv = vec2( ( floor( gl_FragCoord.x / ppp ) * ppp + 0.5 ) / resolution.x, uv.y ); - float pixId = mod( gl_FragCoord.x, ppp ); - vec2 dpix = vec2( 1.0 ) / resolution; float dt = deltaTime; // == prepare some vars ========================================================================== - vec4 seed = texture( samplerRandom, puv ); + vec4 seed = texture( samplerRandom, uv ); prng( seed ); - vec4 tex0 = texture( samplerCompute, puv ); - vec4 tex1 = texture( samplerCompute, puv + dpix * vec2( 1.0, 0.0 ) ); + vec4 tex0 = texture( samplerCompute0, uv ); + vec4 tex1 = texture( samplerCompute1, uv ); vec3 pos = tex0.xyz; float life = tex0.w; @@ -125,7 +123,7 @@ void main() { float timing = mix( 0.0, PARTICLE_LIFE_LENGTH, - ( floor( puv.x * particlesSqrt ) / particlesSqrt + floor( puv.y * particlesSqrt ) ) / particlesSqrt + ( floor( uv.x * particlesSqrt ) / particlesSqrt + floor( uv.y * particlesSqrt ) ) / particlesSqrt ); timing += lofi( time, PARTICLE_LIFE_LENGTH ); @@ -174,8 +172,6 @@ void main() { pos += vel * dt; life -= dt / PARTICLE_LIFE_LENGTH; - fragColor = ( - pixId < 1.0 ? vec4( pos, life ) : - vec4( vel, 1.0 ) - ); + fragCompute0 = vec4( pos, life ); + fragCompute1 = vec4( vel, 1.0 ); } diff --git a/src/shaders/sphere-particles-render.vert b/src/shaders/sphere-particles-render.vert index a78b661..bd5180c 100644 --- a/src/shaders/sphere-particles-render.vert +++ b/src/shaders/sphere-particles-render.vert @@ -40,7 +40,8 @@ uniform mat4 projectionMatrix; uniform mat4 viewMatrix; uniform mat4 modelMatrix; uniform mat4 normalMatrix; -uniform sampler2D samplerCompute; +uniform sampler2D samplerCompute0; +uniform sampler2D samplerCompute1; uniform sampler2D samplerRandomStatic; // ------------------------------------------------------------------------------------------------- @@ -64,15 +65,12 @@ mat2 rotate2D( float _t ) { // ------------------------------------------------------------------------------------------------- void main() { - vec2 puv = vec2( computeUV ); - vec2 dppix = vec2( 1.0 ) / resolutionCompute; - // == fetch texture ============================================================================== - vec4 tex0 = texture( samplerCompute, puv ); - vec4 tex1 = texture( samplerCompute, puv + dppix * vec2( 1.0, 0.0 ) ); + vec4 tex0 = texture( samplerCompute0, computeUV ); + vec4 tex1 = texture( samplerCompute1, computeUV ); // == assign varying variables =================================================================== - vDice = random( puv.xy * 182.92 ); + vDice = random( computeUV.xy * 182.92 ); vColor.xyz = 0.8 * mix( catColor( 2.0 + 40.0 * vDice.x ), vec3( 0.9 ), 0.0 ); vColor.xyz = vec3( 0.2 ); @@ -103,6 +101,4 @@ void main() { gl_Position = outPos; vPosition.w = outPos.z / outPos.w; - - // gl_PointSize = resolution.y * size / outPos.z; } diff --git a/src/shaders/trails-compute.frag b/src/shaders/trails-compute.frag index c53cb9f..6dfebcb 100644 --- a/src/shaders/trails-compute.frag +++ b/src/shaders/trails-compute.frag @@ -11,25 +11,20 @@ const float TAU = 6.283185307; #define lofi(i,m) (floor((i)/(m))*(m)) #define lofir(i,m) (floor((i)/(m)+.5)*(m)) -// ------ - -out vec4 fragColor; +layout (location = 0) out vec4 fragCompute0; +layout (location = 1) out vec4 fragCompute1; +uniform bool init; uniform float time; uniform float beat; - uniform float trails; uniform float trailLength; -uniform float ppp; - uniform float totalFrame; -uniform bool init; uniform float deltaTime; uniform vec2 resolution; - -uniform sampler2D samplerCompute; +uniform sampler2D samplerCompute0; +uniform sampler2D samplerCompute1; uniform sampler2D samplerRandom; - uniform float noiseScale; uniform float noisePhase; // uniform float velScale; @@ -122,40 +117,36 @@ vec3 uneune3( float i, float p ) { void main() { vec2 uv = gl_FragCoord.xy / resolution; - vec2 puv = vec2( ( floor( gl_FragCoord.x / ppp ) * ppp + 0.5 ) / resolution.x, uv.y ); - float pixId = mod( gl_FragCoord.x, ppp ); - vec2 dpix = vec2( 1.0 ) / resolution; float dt = deltaTime; // == if it is not head of particles ============================================================= - if ( ppp < gl_FragCoord.x ) { - puv.x -= ppp / resolution.x; - vec4 tex0 = texture( samplerCompute, puv ); - vec4 tex1 = texture( samplerCompute, puv + dpix * vec2( 1.0, 0.0 ) ); + if ( 1.0 < gl_FragCoord.x ) { + uv.x -= 1.0 / resolution.x; + vec4 tex0 = texture( samplerCompute0, uv ); + vec4 tex1 = texture( samplerCompute1, uv ); tex0.w = saturate( tex0.w - 1.0 / trailLength ); // decrease the life - fragColor = ( - pixId < 1.0 ? tex0 : - tex1 - ); + fragCompute0 = tex0; + fragCompute1 = tex1; + return; } // == prepare some vars ========================================================================== - vec4 seed = texture( samplerRandom, puv ); + vec4 seed = texture( samplerRandom, uv ); prng( seed ); - vec4 tex0 = texture( samplerCompute, puv ); - vec4 tex1 = texture( samplerCompute, puv + dpix * vec2( 1.0, 0.0 ) ); + vec4 tex0 = texture( samplerCompute0, uv ); + vec4 tex1 = texture( samplerCompute1, uv ); vec3 pos = tex0.xyz; float life = tex0.w; vec3 vel = tex1.xyz; float jumpFlag = tex1.w; - float timing = mix( 0.0, PARTICLE_LIFE_LENGTH, floor( puv.y * trails ) / trails ); + float timing = mix( 0.0, PARTICLE_LIFE_LENGTH, floor( uv.y * trails ) / trails ); timing += lofi( time, PARTICLE_LIFE_LENGTH ); if ( time - deltaTime + PARTICLE_LIFE_LENGTH < timing ) { @@ -211,8 +202,6 @@ void main() { pos += v * dt; life -= dt / PARTICLE_LIFE_LENGTH; - fragColor = ( - pixId < 1.0 ? vec4( pos, life ) : - vec4( vel, jumpFlag ) - ); + fragCompute0 = vec4( pos, life ); + fragCompute1 = vec4( vel, jumpFlag ); } diff --git a/src/shaders/trails-render.vert b/src/shaders/trails-render.vert index f175a3d..4c017c7 100644 --- a/src/shaders/trails-render.vert +++ b/src/shaders/trails-render.vert @@ -31,7 +31,8 @@ uniform mat4 projectionMatrix; uniform mat4 viewMatrix; uniform mat4 modelMatrix; uniform mat4 normalMatrix; -uniform sampler2D samplerCompute; +uniform sampler2D samplerCompute0; +uniform sampler2D samplerCompute1; uniform sampler2D samplerRandomStatic; // ------------------------------------------------------------------------------------------------- @@ -75,18 +76,17 @@ mat2 rotate2D( float _t ) { // ------------------------------------------------------------------------------------------------- void main() { - vec2 puv = vec2( computeU, computeV ); - vec2 dppix = vec2( 1.0 ) / resolutionCompute; + vec2 uv = vec2( computeU, computeV ); // == fetch texture ============================================================================== - vec4 pos = texture( samplerCompute, puv ); - vec4 vel = texture( samplerCompute, puv + dppix * vec2( 1.0, 0.0 ) ); - vec4 velp = texture( samplerCompute, puv + dppix * vec2( -ppp + 1.0, 0.0 ) ); + vec4 pos = texture( samplerCompute0, uv ); + vec4 vel = texture( samplerCompute1, uv ); + vec4 velp = texture( samplerCompute1, uv - vec2( 1.0, 0.0 ) / resolutionCompute ); // == assign varying variables =================================================================== vLife = pos.w; - vRandom = random( puv.yy * 182.92 ); + vRandom = random( uv.yy * 182.92 ); vColor.xyz = ( vRandom.y < 0.8 @@ -118,6 +118,4 @@ void main() { gl_Position = outPos; vPosition.w = outPos.z / outPos.w; - - // gl_PointSize = resolution.y * size / outPos.z; }