refactor: gpu particles are now ppp free, shoutouts to drawBuffers

This commit is contained in:
FMS-Cat
2021-03-14 02:51:43 +09:00
parent efac759e05
commit d51a3ccb96
8 changed files with 62 additions and 81 deletions

View File

@@ -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;

View File

@@ -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`,

View File

@@ -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 ) {

View File

@@ -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 ) {

View File

@@ -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 );
}

View File

@@ -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;
}

View File

@@ -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 );
}

View File

@@ -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;
}