From 2d97364b3cdf1354e5b60807732d447217436523 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Sun, 24 Feb 2019 13:02:14 +0100 Subject: Extract interaction logic into separate shader The collide shader became to crowded for my taste. As a nice side benefit we can now execute interaction processing only when actual interaction is taking place. --- src/shader/code/collide.glsl | 84 +++++--------------------------------------- 1 file changed, 8 insertions(+), 76 deletions(-) (limited to 'src/shader/code/collide.glsl') diff --git a/src/shader/code/collide.glsl b/src/shader/code/collide.glsl index a73024e..0ddae7b 100644 --- a/src/shader/code/collide.glsl +++ b/src/shader/code/collide.glsl @@ -7,13 +7,6 @@ layout (std430, binding=1) buffer bufferCollide { float collideCells[]; }; layout (std430, binding=2) buffer bufferStream { float streamCells[]; }; layout (std430, binding=3) buffer bufferFluid { float fluidCells[]; }; -/// external influence - -uniform int prevMouseState; -uniform vec2 prevMousePos; -uniform int currMouseState; -uniform vec2 currMousePos; - /// LBM constants uniform uint nX; @@ -43,22 +36,6 @@ float norm(vec2 v) { return sqrt(dot(v,v)); } -float distanceToLineSegment(vec2 a, vec2 b, vec2 p) { - const vec2 ab = b - a; - - const vec2 pa = a - p; - if ( dot(ab, pa) > 0.0 ) { - return norm(pa); - } - - const vec2 bp = p - b; - if ( dot(ab, bp) > 0.0 ) { - return norm(bp); - } - - return norm(pa - ab * (dot(ab, pa) / dot(ab, ab))); -} - /// Array indexing uint indexOfDirection(int i, int j) { @@ -98,11 +75,6 @@ int getMaterial(uint x, uint y) { return int(fluidCells[idx + 2]); } -void setMaterial(uint x, uint y, int m) { - const uint idx = indexOfFluidVertex(x, y); - fluidCells[idx + 2] = m; -} - /// Moments float density(uint x, uint y) { @@ -127,50 +99,19 @@ float equilibrium(float d, vec2 v, int i, int j) { return w(i,j) * d * (1 + 3*comp(i,j,v) + 4.5*sq(comp(i,j,v)) - 1.5*sq(norm(v))); } -/// Disable wall interior - -void disableWallInterior(uint x, uint y) { - int wallNeighbors = 0; - - for ( int i = -1; i <= 1; ++i ) { - for ( int j = -1; j <= 1; ++j ) { - const int material = getMaterial(x+i,y+j); - if ( material == 0 || material == 2 || material == 3 ) { - ++wallNeighbors; - } - } - } +/// Material number meaning (geometry is only changed by the interaction shader) - if ( wallNeighbors == 9 ) { - setMaterial(x,y,0); - } -} - -/// Determine external influence - -bool isNearMouse(uint x, uint y, float eps) { - if ( prevMouseState == currMouseState ) { - return distanceToLineSegment(prevMousePos, currMousePos, vec2(x,y)) < eps; - } else { - return norm(vec2(x,y) - currMousePos) < eps; - } +bool isBulkFluidCell(int material) { + return material == 1 || material == 4; } -float getExternalPressureInflux(uint x, uint y) { - if ( currMouseState == 1 && isNearMouse(x, y, 3) ) { +float getExternalMassInflux(int material) { + if ( material == 4 ) { return 1.5; } else { return 0.0; } -} - -bool isWallRequestedAt(uint x, uint y) { - if ( currMouseState == 2 && isNearMouse(x, y, 3) ) { - return true; - } else { - return false; - } -} +}; /// Actual collide kernel @@ -184,17 +125,8 @@ void main() { const int material = getMaterial(x,y); - if ( isWallRequestedAt(x,y) && material == 1 ) { - setMaterial(x,y,3); - return; - } - - if ( material == 3 ) { // manually added wall - disableWallInterior(x,y); - } - - if ( material == 1 ) { // fluid - const float d = max(getExternalPressureInflux(x,y), density(x,y)); + if ( isBulkFluidCell(material) ) { + const float d = max(density(x,y), getExternalMassInflux(material)); const vec2 v = velocity(x,y,d); setFluid(x,y,v); -- cgit v1.2.3