Skip to content

Commit

Permalink
refractor add source shader
Browse files Browse the repository at this point in the history
  • Loading branch information
jintaoyugithub committed Nov 24, 2024
1 parent c1f2c2f commit e368cd9
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 37 deletions.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@

- [ ] Need to implement the glfw mouse button callback to make sure glfw send the mouse event to the imgui

### 2024.11.24

- [ ] interpolate the color


## Bugs & Questions

Expand Down Expand Up @@ -85,7 +89,9 @@ In the file `bgfxToolUtils.cmake`, comment the line `list(APPEND PROFILES s_4_0)

The origin of gl_FragCoord is bottom left, however the origin of glfwGetCursorPos() is top left

6. uniforms structure
**6. uniforms**

- Uniform structure

If you want to send a struct uniform, for example:

Expand Down Expand Up @@ -121,10 +127,20 @@ void init(data* _data) {
}
```

- Uniform data

the value you sent to the uniform must be **represent as float**, which means for example:

```cpp
_data = 0.0f; // Correct
_data = 0.0; // false, will be consider as double
```

7. Framerate issues

I'm not sure why the frame rate in this project changes with the display's maximum refresh rate. For example, with a 60Hz monitor, the frame rate is capped at 60, but when I switch to a 140Hz monitor, it reaches 140. Disabling V-Sync in the NVIDIA control panel under 3D settings unlocks the frame rate limit.

8. `.sh` file doesn't update after modified it

You should update the shader, for example, add some comments, in order to make the `bgfx` rebuild the shader.

59 changes: 50 additions & 9 deletions examples/fluidSim/fluidSim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#include <memory>
#include <utils/common.hpp>

#include "GLFW/glfw3.h"
#include "bgfx/bgfx.h"
#include "bx/string.h"
#include "gleq.hpp"
#include "velocityField.hpp"

enum ViewportType
Expand Down Expand Up @@ -50,6 +53,7 @@ static const uint16_t quadIndices[] = {
float lastFrame = 0.0f;
double lastMousePosX = 0.0f;
double lastMousePosY = 0.0f;
bool isPressed = false;

bool densityEnable = false;
bool velocityAdvectEnable = false;
Expand Down Expand Up @@ -84,7 +88,8 @@ class ExampleFluidSim : public shift::AppBaseGLFW

_quadProgram = shift::loadProgram({"quad_vs.sc", "quad_fs.sc"});

velocity = new VelocityField();
velocity = new VelocityField(getWidth(), getHeight(), 0.02f, 10.0f);

velocity->dispatch(ProgramType::reset, 0);
}
}
Expand Down Expand Up @@ -125,6 +130,8 @@ class ExampleFluidSim : public shift::AppBaseGLFW
bgfx::setVertexBuffer(0, _vbhQuad);
bgfx::setIndexBuffer(_ibhQuad);
bgfx::setBuffer(0, velocity->getBufferHandle(BufferType::isFluid), bgfx::Access::Read);
bgfx::setBuffer(1, velocity->getBufferHandle(BufferType::curVelX), bgfx::Access::Read);
bgfx::setBuffer(2, velocity->getBufferHandle(BufferType::curVelY), bgfx::Access::Read);
// check https://bkaradzic.github.io/bgfx/bgfx.html#_CPPv4N4bgfx7Encoder8setStateE8uint64_t8uint32_t
bgfx::setState(BGFX_STATE_DEFAULT);
bgfx::submit(0, _quadProgram);
Expand All @@ -138,19 +145,53 @@ class ExampleFluidSim : public shift::AppBaseGLFW
{
case GLEQ_BUTTON_PRESSED:
std::cout << "left button pressed" << std::endl;
isPressed = true;
break;
case GLEQ_CURSOR_MOVED:
// set up uniforms
double x, y;
glfwGetCursorPos(_window, &x, &y);

// for calculating the velocity of the mouse
lastMousePosX = x;
lastMousePosY = y;

case GLEQ_CURSOR_MOVED: {
if (isPressed)
{
// set up uniforms
double x, y;
glfwGetCursorPos(_window, &x, &y);

// calculate the velocity dir
glm::vec2 velDir = glm::vec2(x - lastMousePosX, y - lastMousePosY);
velDir = glm::normalize(velDir);

// update uniforms
velocity->updateUniforms(UniformType::mousePosX, x);
velocity->updateUniforms(UniformType::mousePosY, y);
velocity->updateUniforms(UniformType::mouseVelX, velDir.x);
// the origin is in the top left
velocity->updateUniforms(UniformType::mouseVelY, -velDir.y);

// for calculating the velocity dir of the mouse
lastMousePosX = _event.pos.x;
lastMousePosY = _event.pos.y;

// dispatch shader
velocity->dispatch(ProgramType::addSource, 0);
// Debug info
// std::cout << velDir.x << " " << velDir.y << std::endl;
}
break;
}

case GLEQ_BUTTON_RELEASED:
std::cout << "left button released" << std::endl;
isPressed = false;
break;

case GLEQ_KEY_PRESSED:
if (_event.keyboard.key == GLFW_KEY_R)
{
std::cout << "Reset the program" << std::endl;
velocity->dispatch(ProgramType::reset, 0);
}
break;

case GLEQ_KEY_RELEASED:
break;
}

Expand Down
31 changes: 15 additions & 16 deletions examples/fluidSim/velocityField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,22 @@
#include "velocityField.hpp"
#include <intrin.h>

// VelocityField::VelocityField(int width, int height, float dt, float speed)
VelocityField::VelocityField()
VelocityField::VelocityField(int _width, int _height, float _dt, float _speed)
{
// init uniforms and uniform handle
_uParams.mousePosX = 3.40e+38; // avoid the origin problem of the addSource compute shader
_uParams.mousePosY = 3.40e+38;
_uParams.mouseVelX = 0.0f;
_uParams.mouseVelY = 0.0f;
_uParams.radius = 5.0f;
_uParams.simResX = SHIFT_DEFAULT_WIDTH;
_uParams.simResY = SHIFT_DEFAULT_HEIGHT;
_uParams.simResZ = 1;
_uParams.persist = false;
_uParams.deltaTime = 0.002;
_uParams.speed = 75;
_uParams.simResX = float(_width);
_uParams.simResY = float(_height);
_uParams.simResZ = 1.0f;
_uParams.persist = float(false);
_uParams.deltaTime = _dt;
_uParams.speed = _speed;

_uhParams = bgfx::createUniform("uParams", bgfx::UniformType::Vec4, int(UniformType::count / 4));
_uhParams = bgfx::createUniform("uParams", bgfx::UniformType::Vec4, int(UniformType::count / 4) + 1);

// init the compute shader group size
_groupSizeX = _uParams.simResX / kThreadGroupSizeX;
Expand All @@ -46,9 +45,9 @@ VelocityField::VelocityField()

// init compute shaders
_csReset = shift::loadProgram({"velocity_reset_cs.sc"});
//_csAddSource = shift::loadProgram({"velocity_addSource_cs.sc"});
//_csAdvect = shift::loadProgram({"velocity_advect_cs.sc"});
//_csProject = shift::loadProgram({"velocity_project_cs.sc"});
_csAddSource = shift::loadProgram({"velocity_addSource_cs.sc"});
_csAdvect = shift::loadProgram({"velocity_advect_cs.sc"});
_csProject = shift::loadProgram({"velocity_project_cs.sc"});
}

VelocityField::~VelocityField()
Expand All @@ -72,7 +71,7 @@ void VelocityField::Reset(int _viewID)
bgfx::setBuffer(2, _curVelX, bgfx::Access::Write);
bgfx::setBuffer(3, _curVelY, bgfx::Access::Write);
bgfx::setBuffer(4, _isFluid, bgfx::Access::Write);
bgfx::setUniform(_uhParams, &_uParams, int(UniformType::count / 4));
bgfx::setUniform(_uhParams, &_uParams, int(UniformType::count / 4) + 1);
bgfx::dispatch(_viewID, _csReset, _groupSizeX, _groupSizeY, _groupSizeZ);
}

Expand All @@ -84,7 +83,7 @@ void VelocityField::AddSource(int _viewID)
bgfx::setBuffer(3, _curVelY, bgfx::Access::ReadWrite);
// might need to change the access????
bgfx::setBuffer(4, _isFluid, bgfx::Access::Read);
bgfx::setUniform(_uhParams, &_uParams, int(UniformType::count / 4));
bgfx::setUniform(_uhParams, &_uParams, int(UniformType::count / 4) + 1);
bgfx::dispatch(_viewID, _csAddSource, _groupSizeX, _groupSizeY, _groupSizeZ);
}

Expand All @@ -95,7 +94,7 @@ void VelocityField::Advect(int _viewID)
bgfx::setBuffer(2, _curVelX, bgfx::Access::ReadWrite);
bgfx::setBuffer(3, _curVelY, bgfx::Access::ReadWrite);
bgfx::setBuffer(4, _isFluid, bgfx::Access::Read);
bgfx::setUniform(_uhParams, &_uParams, int(UniformType::count / 4));
bgfx::setUniform(_uhParams, &_uParams, int(UniformType::count / 4) + 1);
bgfx::dispatch(_viewID, _csAdvect, _groupSizeX, _groupSizeY, _groupSizeZ);
}

Expand All @@ -106,6 +105,6 @@ void VelocityField::Project(int _viewID)
bgfx::setBuffer(2, _curVelX, bgfx::Access::ReadWrite);
bgfx::setBuffer(3, _curVelY, bgfx::Access::ReadWrite);
bgfx::setBuffer(4, _isFluid, bgfx::Access::Read);
bgfx::setUniform(_uhParams, &_uParams, int(UniformType::count / 4));
bgfx::setUniform(_uhParams, &_uParams, int(UniformType::count / 4) + 1);
bgfx::dispatch(_viewID, _csProject, _groupSizeX, _groupSizeY, _groupSizeZ);
}
8 changes: 6 additions & 2 deletions examples/fluidSim/velocityField.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ class VelocityField
void Project(int _viewID);

public:
// VelocityField(int width, int height, float dt, float speed);
VelocityField();
VelocityField(int _width, int _height, float _dt, float _speed);
// VelocityField();
~VelocityField();

public:
Expand Down Expand Up @@ -109,6 +109,7 @@ class VelocityField
break;
case BufferType::curVelY:
return _curVelY;
break;
case BufferType::isFluid:
return _isFluid;
break;
Expand All @@ -122,10 +123,13 @@ class VelocityField
{
case ProgramType::reset:
return _csReset;
break;
case ProgramType::advect:
return _csAdvect;
break;
case ProgramType::project:
return _csProject;
break;
}
return BGFX_INVALID_HANDLE;
}
Expand Down
4 changes: 0 additions & 4 deletions ext/gleq/gleq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ extern "C"
GLEQ_CODEPOINT_INPUT,
GLEQ_MONITOR_CONNECTED,
GLEQ_MONITOR_DISCONNECTED,
GLEQ_IMGUI_BUTTON_PPRESSED,
GLEQ_IMGUI_BUTTON_RELEASED,
#if GLFW_VERSION_MINOR >= 1
GLEQ_FILE_DROPPED,
#endif
Expand Down Expand Up @@ -145,8 +143,6 @@ extern "C"
}
#endif

#define GLEQ_IMPLEMENTATION

#ifdef GLEQ_IMPLEMENTATION

#include <assert.h>
Expand Down
17 changes: 14 additions & 3 deletions shaders/examples/fluidSim/quad_fs.sc
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,22 @@ $input v2f_texCoord0
#define bufferSize 512

BUFFER_RO(_isFluid, float, 0);

BUFFER_RO(_curVelX, float, 1);
BUFFER_RO(_curVelY, float, 2);

void main() {
int index = int(gl_FragCoord.x) + bufferSize * int(gl_FragCoord.y);

//gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
gl_FragColor = vec4(1-_isFluid[index].xxx, 1.0);
if(_isFluid[index] == 0) {
// draw the boundary
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
} else {
// draw the velocity
float colorX = _curVelX[index] == 0 ? 0 : _curVelX[index] * 0.5 + 0.5;
float colorY = _curVelY[index] == 0 ? 0 : _curVelY[index] * 0.5 + 0.5;
gl_FragColor = vec4(0.0, colorX, colorY, 1.0);

// Debug
//gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
}
15 changes: 15 additions & 0 deletions shaders/examples/fluidSim/velocity_addSource_cs.sc
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
#include "../../utils/bgfx_compute.sh"
#include "velocity_uniforms.sh"

BUFFER_RO(_prevVelX, float, 0);
BUFFER_RO(_prevVelY, float, 1);
BUFFER_RW(_curVelX, float, 2);
BUFFER_RW(_curVelY, float, 3);
BUFFER_WO(_isFluid, float, 4);

NUM_THREADS(8, 8, 1)
void main() {
uvec2 pos = gl_GlobalInvocationID.xy;
uint index = Index2D(pos.x, pos.y, uSimResX);

// calculate the distance from the current cell to the mouse position
float dis = distance(pos, vec2(uMousePosX, uSimResY - uMousePosY));

if(dis < uRadius) {
_curVelX[index] += uMouseVelX * uDeltaTime * uSpeed + _prevVelX[index];
_curVelY[index] += uMouseVelY * uDeltaTime * uSpeed + _prevVelY[index];
}
}
4 changes: 2 additions & 2 deletions shaders/examples/fluidSim/velocity_reset_cs.sc
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ NUM_THREADS(8, 8, 1)
void main() {
// init the density field and velocity field
vec2 pos = gl_GlobalInvocationID.xy;
uint index = Index2D(uint(pos.x), uint(pos.y), 512.0);
uint index = Index2D(uint(pos.x), uint(pos.y), uSimResX);

_prevVelX[index] = 0.0;
_prevVelY[index] = 0.0;
_curVelX[index] = 0.0;
_curVelY[index] = 0.0;

// determine if the current grid is inside the sim area
if(pos.x > 100 && pos.y > 100 && pos.x < uSimResX - 100 && pos.y < uSimResY - 100) {
if(pos.x > 0 && pos.y > 0 && pos.x < uSimResX - 1 && pos.y < uSimResY - 1) {
_isFluid[index] = 1.0;
return;
}
Expand Down
6 changes: 6 additions & 0 deletions shaders/examples/fluidSim/velocity_uniforms.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@ uniform vec4 uParams[3];
#define uDeltaTime uParams[2].y
#define uSpeed uParams[2].z

#define LEFT(idx) ((idx) - 1)
#define RIGHT(idx) ((idx) + 1)
#define UP(idx) ((idx) + uSimResX)
#define DOWN(idx) ((idx) - uSimResX)

uint Index2D(uint x, uint y, float simResX) {
return x + uint(simResX) * y;
}

uint Index3D(uint x, uint y, uint z, float simResX, float simResY) {
return 0;
}

0 comments on commit e368cd9

Please sign in to comment.