[SOLVED] Is there workaround to createFullscreenQuad for vertexBuffer?

Hello, I’m trying to use a shader for water foam lines (based on this public project[0]) which was compiled with the function pc.createFullscreenQuad(this.app.graphicsDevice); that has been recently removed from the pc namespace in v1.29.0[1].

Is there a different approach you might take for defining the vertexBuffer? I tried the following attempt, but unfortunately I don’t have a good understanding of this topic so the resulting effect didn’t look very good:

// this.vertexBuffer = pc.createFullscreenQuad(this.app.graphicsDevice);
    var vertexFormat = new pc.VertexFormat(this.app.graphicsDevice, [
        { semantic: pc.SEMANTIC_POSITION, components: 4, type: pc.ELEMENTTYPE_FLOAT32 }
    ]);
    this.vertexBuffer = new pc.VertexBuffer(this.app.graphicsDevice, vertexFormat, 5000);

If it helps, my public project with this change[2], and the gif of effect I’m trying to achieve[3].


[0] https://playcanvas.com/project/661544/overview/waves
[1] https://github.com/playcanvas/engine/releases/tag/v1.29.0
[2] https://playcanvas.com/project/703128/overview/wave-foam-test
[3] gif of effect I’m trying to achieve

Hi @Vdizzle,

Indeed that method isn’t exposed in the public pc namespace anymore. I think there is a new pc.Mesh API that will allow you to do something similar.

In the meantime you can grab this method from the engine repo and add it, with some minor changes, to your script:

MyScript.prototype.createFullscreenQuad = function (device) {
  // Create the vertex format
  var vertexFormat = new pc.VertexFormat(device, [
    { semantic: pc.SEMANTIC_POSITION, components: 2, type: pc.TYPE_FLOAT32 },
  ]);

  // Create a vertex buffer
  var vertexBuffer = new pc.VertexBuffer(device, vertexFormat, 4);

  // Fill the vertex buffer
  var iterator = new pc.VertexIterator(vertexBuffer);
  iterator.element[pc.SEMANTIC_POSITION].set(-1.0, -1.0);
  iterator.next();
  iterator.element[pc.SEMANTIC_POSITION].set(1.0, -1.0);
  iterator.next();
  iterator.element[pc.SEMANTIC_POSITION].set(-1.0, 1.0);
  iterator.next();
  iterator.element[pc.SEMANTIC_POSITION].set(1.0, 1.0);
  iterator.end();

  return vertexBuffer;
};

And then use it like this:

this.vertexBuffer = this.createFullscreenQuad(this.app.graphicsDevice);
3 Likes

You are the king @Leonidas!!! Works perfectly

1 Like

Thanks @Leonidas, this is cool… but only 2 questions, please.

  1. After adding the method… the foam appears inverted (see attached image)… I tried to change the camera with no results… I tried to rotate the water plane and set cull mode to front faces and it works only in execution time… if I reload… the foam appears inverted again.
  2. If I animate an object inside the water… the wave effect still with the initial disposition… this need some work in the update method to regenerate the shader every frame?

Thanks!!!

Hi @Vdizzle,

Most likely your render target texture is flipped? Try setting this property to false on that:

https://developer.playcanvas.com/api/pc.Texture.html#flipY

Yes most likely you will have to re-render that render target for the foam to update. I am not aware on how that code works, you will have to study it and see what method should be called.

1 Like

Hi @Leonidas !

So, you were definitely correct about the renderTarget needing flipped. I was able to get the original waves project working by changing the prepareTextures() function to the following:

Water.prototype.prepareTextures = function() {
    this.textureA = new pc.Texture(this.app.graphicsDevice, {
        width: this.resolution,
        height: this.resolution,
        addressU: pc.ADDRESS_CLAMP_TO_EDGE,
        addressV: pc.ADDRESS_CLAMP_TO_EDGE,
    });
    
    this.textureB = new pc.Texture(this.app.graphicsDevice, {
        width: this.resolution / 2,
        height: this.resolution / 2,
        addressU: pc.ADDRESS_CLAMP_TO_EDGE,
        addressV: pc.ADDRESS_CLAMP_TO_EDGE,
    });
    
    this.renderTargetA = new pc.RenderTarget({
        colorBuffer: this.textureA,
        flipY: true
    });
    
    this.renderTargetB = new pc.RenderTarget({
        colorBuffer: this.textureB,
        flipY: true
    });
};
1 Like

Hey, Everyone, @Leonidas @Vdizzle @chewuaka

Sorry to re-iterate this problem.

I have reflected the update mentioned here and changed
opaqueMeshInstances to meshInstances only to avoid further error.
but still I got an error in pc code.
Waves | Editor (playcanvas.com)

Any idea?

/*
for(var i = 0; i < this.layer.opaqueMeshInstances.length; i++) {
var mesh = this.layer.opaqueMeshInstances[i];
mesh.material.onUpdateShader = onUpdateShader;
}
*/

for(var i = 0; i < this.layer.meshInstances.length; i++) {
    var mesh = this.layer.meshInstances[i];
    mesh.material.onUpdateShader = onUpdateShader;
}

This is an old thread and the API has changed since then. I would recommend to start from fixing all those deprecated error messages first. If you still have a problem, please create a new topic.