[SOLVED] When camera rotates some parts of the character mesh are hidden in the water

When the camera rotates some parts of the character mesh are hidden in the water, as you can see in the video;
What could be the problem? I followed this tutorial: PlayCanvas | HTML5 Game Engine

Hi @Ertugrul_Cetin,

Are you using a separate layer for the water model rendering? If not, try that and play with the layer render order.

I’m not sure what’s the problem here, but in some cases that may help.

Off hand, it looks like a render order issue where the model is being rendered after the water in some cases. You can check this with Spectre.js to check how the scene is being rendered.

I’m not doing any layering, here is my render order and code that creates mesh and material;
Screen Shot 2022-12-19 at 14.23.11

Code:

    // Make the actual model
    var node = new pc.GraphNode();
    var material = this.CreateWaterMaterial();
   
    // Create the mesh 
    var mesh = pc.createMesh(this.app.graphicsDevice, positions, {
        normals: normals,
        uvs: uvs,
        indices: indices
    });

    var meshInstance = new pc.MeshInstance(node, mesh, material);
    
    // Add it to this entity 
    var model = new pc.Model();
    model.graph = node;
    model.meshInstances.push(meshInstance);
    
    this.entity.addComponent('model');
    this.entity.model.model = model;
    this.entity.model.castShadows = false; // We don't want the water surface itself to cast a shadow 
    
    // Set the culling masks 
    var bit = this.isMask ? 3 : 2; 
    meshInstance.mask = 0; 
    meshInstance.mask |= (1 << bit);

Material;

Water.prototype.CreateWaterMaterial = function(){
    // Create a new blank material  
    var material = new pc.Material();
    // A name just makes it easier to identify when debugging 
    material.name = "DynamicWater_Material";
    
    // Create the shader definition 
    // dynamically set the precision depending on device.
    var gd = this.app.graphicsDevice;
    var fragmentShader = "precision " + gd.precision + " float;\n";
    fragmentShader = fragmentShader + this.fs.resource;
    
    var vertexShader = this.vs.resource;

    // A shader definition used to create a new shader.
    var shaderDefinition = {
        attributes: {           
            aPosition: pc.gfx.SEMANTIC_POSITION,
            aUv0: pc.SEMANTIC_TEXCOORD0,
        },
        vshader: vertexShader,
        fshader: fragmentShader
    };
    
    // Create the shader from the definition
    this.shader = new pc.Shader(gd, shaderDefinition);
    
    // Set blending 
    material.blendType = pc.BLEND_NORMAL;
    //material.alphaToCoverage = true;
    
    // Define our uniforms
    if(!this.camera){
        this.camera = this.app.root.findByName("camera").camera;
    }
    var camera = this.camera; 
    var n = camera.nearClip;
    var f = camera.farClip;
    var camera_params = [
        1/f,
        f,
        (1-f / n) / 2,
        (1 + f / n) / 2
    ];
            
    material.setParameter('camera_params', camera_params);
    material.setParameter('uTime',this.time);
    material.setParameter('uSurfaceTexture',this.surfaceTexture.resource);
    material.setParameter('isMask',this.isMask);
    this.material = material; // Save a reference to this material
    
    // Apply shader to this material 
    material.setShader(this.shader);
    
    return material;
};

Also, I can see the character all the time when I set material.alphaToCoverage = true
Screen Shot 2022-12-19 at 14.33.20

try to turn off depth write on the water material

1 Like

@mvaligursky I got another weird stuff when material.depthWrite = false here;
Could it be some problem with blending?

I would say the problem is with the ordering as mentioned before.
It seems your character material has blending enabled? And so it’s sorted with the water.
You could disable blending on it to make it always render first.

If you need blending, you’d need to use 3 layers. I assume currently everything is in World layer. Create new layer called Water and insert it right after all opaque layers, but before all transparent layers. Or something like that :wink:

2 Likes

Thanks! @mvaligursky it seems that BLEND_NONE fixes it!