Trouble with Waves Project

Background to start: [SOLVED] Is there workaround to createFullscreenQuad for vertexBuffer? - #6 by eproasim

After debugging that, I set to work on attempting to implement this shader/script into a project of my own, but I have a behavior that I am entirely unsure how to address or investigate. It looks like the objects that I place in the WaveSources Layer appear in the very center of the texture at a very very small size and strangely I have waves coming from uniform spots across the plane…

And as I typed that out I realized that he camera must have it’s clear color set to #00000000 to fix that problem. Still, removing the terrain and relying on only a few rock for ripple result in a very small representation of the ripples in the center of the plane:

I’ve tried adjusting the Orthographic height of the Water Camera, adjusting both the land width and wave width, texture size, placement of objects, UV tiling, and I think I’ve run out of ideas. Any insight on this project, or how this might be overcome would be incredibly appreciated!

Hi @eproasim,

That seems indeed like a camera setup issue. Try previewing either in editor or on runtime what exactly that camera sees.

Then try playing again with ortho height and with the near/far planes to get it to render the objects that need to intersect with the water surface.

Thank you @Leonidas !

Fresh morning eyes revealed that the updateWater() function was actually setting the camera’s orthoHeight and position, meaning basically any of the changes I made with the camera were overwritten.

Now I’m getting a pretty good result that will be tweaked in the future. I decided to see if the shader could be updated, especially considering that I saw that the script registers an app level event to update the water to dirty the layer. I noticed that the event isn’t called anywhere in the script, so I’m guessing it was meant to be updatable. Firing the event produces a Trying to bind current color buffer as a texture error:

Unfortunately, I’m not familiar enough with the way shaders work to know where to start. Do you have any ideas? The event fires this function:

Water.prototype.updateWater = function() {
    // this.camera.camera.orthoHeight = this.entity.getLocalScale().x / 2;
    
    // var pos = this.entity.getPosition();
    // this.camera.setPosition(pos.x, 16, pos.z);
    
    var rot = this.entity.getEulerAngles();
    if (rot.x > 90 || rot.x < -90) {
        this.camera.setEulerAngles(-90, 180 - rot.y, 0);
    } else {
        this.camera.setEulerAngles(-90, rot.y, 0);
    }
    
    this.layer.enabled = true;
    this.rendering = true;
    this.app.renderer.renderComposition(this.layerComposition);
    this.rendering = false;
    this.layer.enabled = false;
    
    var scope = this.app.graphicsDevice.scope;
    
    scope.resolve("uWeights[0]").setValue(this.uBlurWeights);
    
    for(var i = 0; i < this.blurPasses; i++) {
        scope.resolve("uBaseTexture").setValue(this.textureA);
        scope.resolve("uOffsets[0]").setValue(this.uBlurOffsetsHorizontal);
        pc.drawFullscreenQuad(this.app.graphicsDevice, this.renderTargetB, this.vertexBuffer, this.quadShaderBlurHorizontal);

        scope.resolve("uBaseTexture").setValue(this.textureB);
        scope.resolve("uOffsets[0]").setValue(this.uBlurOffsetsVertical);
        pc.drawFullscreenQuad(this.app.graphicsDevice, this.renderTargetA, this.vertexBuffer, this.quadShaderBlurVertical);
    }
    
    this.material.diffuseMap = this.textureA;
    this.material.update();
    
    this.updateUniforms();
};

And I can see in the stack trace that the offending line is:

this.app.renderer.renderComposition(this.layerComposition);

Do you have any ideas?

Not sure what the issue is, that seems like a complex setup (using a second layer composition).

Normally to update your render target all you need is to enable for at least a single frame the camera that is rendering to that. That should be enough.

If you keep having trouble try sharing a sample project to take a look.

The issue is in the order of rendering to textures A/B using the drawFullScreenQuad. The renderer is trying to write to texture that is currently rendered, which is not allowed, hence the error.

2 Likes

Hey @eproasim,

Did you manage to fix this wave effect? Could you share your project with the solution?

Hi @Nelson_Alves,

I did! I haven’t touched that particular project in awhile, so let me make sure it still works and I will get back with you shortly.

Thanks!

Hi @Nelson_Alves !

Ok, so I managed to get a couple of minutes to take a look at this. While I did update the shader to survive the changes in 1.62+, it seems like there were changes in 1.63+ that are causing the shader in this thread to fail. (There are two shaders running in this project, the one in this thread, and another custom one I made called voronoiWater)

Here is the error that is being generated by the water shader:

Unfortunately, I am in the middle of a sprint so it may take me a bit of time for me to debug it myself.

You can check out a simplified fork of my project here:

https://playcanvas.com/editor/scene/1798427

Launch it with 1.62.2 using this link:

https://launch.playcanvas.com/1798427?debug=true&use_local_engine=https://code.playcanvas.com/playcanvas-1.62.2.js

Shaders are definitely not my specialty, so it will take me awhile to debug and throw things at the wall until it works, but I looked back at the PR’s for 1.63.0 which does break the water shader and I highly suspect that this has something to do with it:

but @mvaligursky would have WAY information than I would. Sorry I couldn’t be more helpful, but hopefully this information points you or someone else in the right direction faster than I can get to it.

Sure, it will help me!
Thanks a lot man!

I think this line is causing the problem in the water.js

    this.layer.shaderPass = 19;

why 19? What is it supposed to do here?

Hi @mvaligursky,

That line was carried over from the original project:

https://playcanvas.com/editor/scene/865024

I see @Leonidas is listed on the project, so maybe he can provide some insight for that line, but changing the value from 19 to 1, or removing the line results in the same error as above.

The original project was developed by Max, it seems I can’t find his forum handle to tag him.

this.layer.shaderPass = 19;

Not sure if that does anything, I think he just adds his own endPS shader chunk on update shader.

Good news everyone!

It took quite a lot of tinkering, but I did eventually clear the errors within the shader. Ultimately, the issue appears to be that before 1.63+ there were hard coded values for custom shader passes:

https://developer.playcanvas.com/en/api/pc.Layer.html#shaderPass

After pulling the shader pass object and realizing that no new pass was being generated, I then changed Water.prototype.prepareLayers() to read:

    var self = this;
    
    this.layer = this.app.scene.layers.getLayerByName('WaveSources');
    this.layer.renderTarget = this.renderTargetA;
    this.layer.passThrough = true;

    pc.ShaderPass.get(this.app.graphicsDevice).allocate('waves', {
        isForward: true
    });

    this.layer.shaderPass = pc.ShaderPass.get(this.app.graphicsDevice).getByName('waves').index;
    this.layer.enabled = false;
...

and then added the following to the onUpdateShader()function being sent to the renderer:

result.pass = self.layer.shaderPass;

This ensured that the appropriate shaderPass was created and then provided to the material for processing.

While this cleared the errors, it seems like the change altered the way that the waves were being generated, so I updated water.glsl to look a bit closer to how it was and adjusted my settings. Your mileage may vary, and it may take more tinkering with the shader itself to make everything work for your use-case.

I made all of the changes to the same project shared previously. I will keep it up for others to look at. Please feel free to fork it. I hope this is helpful and that the shaders work for you!

Paging @Nelson_Alves in case you don’t see this organically.

4 Likes

Wonderful!
Thanks a lot @eproasim and others for the effort, this project has plenty of great animated effects that will help me a lot in my journey with Playcanvas.