Skip to content

Feature:: Add FBO support + Grid-Displacement-Mouse effect demo#74

Open
Robpayot wants to merge 33 commits into
wix-incubator:masterfrom
Robpayot:feat/fbo-grid-effect
Open

Feature:: Add FBO support + Grid-Displacement-Mouse effect demo#74
Robpayot wants to merge 33 commits into
wix-incubator:masterfrom
Robpayot:feat/fbo-grid-effect

Conversation

@Robpayot

@Robpayot Robpayot commented Mar 1, 2025

Copy link
Copy Markdown
Contributor
  1. Adding FBO effects support
  2. Adding a demo section 14 with the new grid Displacement Mouse effect.

FBOs

To have a FBO effect you need at least one program running in parallel of the "Kampos effect". I preferred to manage the FBO data in a separate object called fbo.

Example when creating a Kampos effect that needs a FBO map:

    // init kampos
  const  instance = new Kampos({
        target,
        effects: [gridMouseDisplacement],
        fbo: {
            size: 256, // FBO texture size width and height
            effects: [flowmapGrid],
        },
    });

Your fbo effect can be different, In the example I made one for a flowMap grid effect in src/fbo/flowmap-grid.js . But we could add another one for a more simple flowmap effect in src/fbo/flowmap.js and do something like this example

Notes: For now this should be only used for flowmap I think, other FBO like GPGPU effects can be more complex and needs more textures: Example here (tutorial) where it's using a velocityMap to move particles

Modifcation in core.js

If using a FBO when creating a Kampos() instance. the core.js js will create a FBO program _initFBOProgram(gl, plane, fbo) in a object that gather all important information: fboData .
Then if fboData exists, the draw function will call drawFBO where all the FBO drawing logic exists. Notice that they are other thing to take care of if fboData exists like binding textures that I couldn't put in drawFBO for order reason.

Notes: For the grid effect I had to use a gl.FLOAT type texture, so I created a function for that. But I think in the future we might want a default Texture in a FBO effect. In that case we could add a parameters say textureType and use default or float texture based on that.

Demo

The demo is using grid-mouse-displacement.js effect with different parameters. Some of them like aspectRatio needs to be updated both in the effect and the fboEffect programs.

grid-effect.mp4

Comment thread src/core.js
* @return {{gl: WebGLRenderingContext, data: kamposSceneData, [dimensions]: {width: number, height: number}}}
*/
export function init({ gl, plane, effects, dimensions, noSource }) {
export function init({ gl, plane, effects, dimensions, noSource, fbo }) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, my initial thought was to allow a programs property to allow providing multiple programs instead of effects. Do you this that would make sense? Or just be an overkill?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean but the fbo programs needs to be rendered in a specific order to draw / clear framebuffers and textures, and then "classic" effects can be drawn. So I think if we put all the logics in the same effets array, it might be difficult/overkilled to sorts them or do the checks on these rather than a separated object right?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not same effects array. I meant you could specify something like programs: { effects, plane }[]. But I can do this generalization later.

Comment thread src/core.js

if (vao) {
extensions.vao.bindVertexArrayOES(vao);
if (fboData) _enableVertexAttributes(gl, attributes);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're using VAO here why do we need to reenable attributes here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason I need to enable the positions here otherwise the program is invisible (only with FBO program rendered before). It might be because after clearing the framebuffer it needs to enable the other program's attributes?

But let me know if you find a solution to make it work only using the vao.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, cool, don't get stuck on it, I'll try investigating later

Comment thread src/core.js Outdated
// bind fbo texture
gl.activeTexture(startTex);
gl.bindTexture(gl.TEXTURE_2D, fboData.oldInfo.tex);
gl.uniform1i(gl.getUniformLocation(program, 'u_flowMap'), 0);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very specific to the FlowMap effect. Either we use some generic uniform name here, or we extract this logic to be some how connected to the effect using the FBO?
I think I rather have the former

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, like I said here, I think for now the FBO is moslty meant to be for flowMaps. BUT I agree to make it more generic. I replaced it by u_FBOMap

Notes: For now this should be only used for flowmap I think, other FBO like GPGPU effects can be more complex and needs more textures: Example here (tutorial) where it's using a velocityMap to move particles

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, let's start with that

Comment thread src/core.js Outdated

// // Set uniforms
_setUniforms(gl, uniforms);
gl.uniform1i(gl.getUniformLocation(program, 'u_flowMap'), 0);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, specific to FlowMap

Comment thread src/core.js Outdated
return TEXTURE_WRAP[key] || TEXTURE_WRAP['stretch'];
}

function createFloatTexture(gl, data, width, height) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not API, internal:

Suggested change
function createFloatTexture(gl, data, width, height) {
function _createFloatTexture(gl, data, width, height) {

Comment thread src/core.js
Comment on lines +848 to +849
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you use NEAREST because of the need to make the hard cut for the grid effect specifically?
Perhaps this should (at least later if not now) should be configurable?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it was for that. I think like we discussed on Google Chat, in the future, it would be nice to make the FBO texture configurable in parameters like (textureType = FLOAT, textureCut = 'LINEAR' or 'NEAREST') ...

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, np

Comment thread src/core.js Outdated
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is the coords for clip space? Could we use same ones used for the main program? I mean not the buffer/array itself, but perhaps the same config?

@Robpayot Robpayot Mar 5, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated so now it's similar to the default attributes like for other effects

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants