GPU Picking is Broken on Some Meshes?

It seems like its related to VertexColor, but I have a good chunk of simple models I can supply that just simply break and do not support GPU picking.

If I can figure this last part out then Ill be able to have all the fancy information for a usable pick to come back on a single pass like we need.

@Evgeni_Popov you got any ideas what’s going on with this? I know its rather abstract but hopefully the video will demonstrate enough info.

https://playground.babylonjs.com/#NIMS34#19 BJS picker
https://playground.babylonjs.com/#NIMS34#21 My picker with the debug mat to show discontinuity in the mesh.

2 Likes

The problem is that the chair has a vertex alpha, which enables blending when drawing the mesh in the picking texture. By setting hasVertexAlpha = false, this works. Setting transparencyMode to MATERIAL_OPAQUE for the picking material is better, however, as it avoids modifying the mesh itself.

In addition, you may want to transform the normal in world space, so that users don’t have to do it themselves :

1 Like

Thank you, I had no clue that the vertexColors/Alpha would automatically get picked up by the shader material even though it was not using them.

@Evgeni_Popov really quick about the normal transformation, what uniform should I use to access the instances or the current meshes worldMatrix on the vertex shader? Id much rather do the normal transformation on the GPU than the CPU response.

Do you mean in std / PBR materials? The world matrix is accessible via finalWorld, whether you use instances or not.

1 Like

So can I just do:

 vNormal = (finalWorld * vec4(normal, 1.0)).xyz;

?

yes :slight_smile:

Yes. But if you have non uniform scaling, it will be a bit more involved. From the standard material:

	mat3 normalWorld = mat3(finalWorld);

    #if defined(INSTANCES) && defined(THIN_INSTANCES)
        vNormalW = normalUpdated / vec3(dot(normalWorld[0], normalWorld[0]), dot(normalWorld[1], normalWorld[1]), dot(normalWorld[2], normalWorld[2]));
        vNormalW = normalize(normalWorld * vNormalW);
    #else
        #ifdef NONUNIFORMSCALING
            normalWorld = transposeMat3(inverseMat3(normalWorld));
        #endif

        vNormalW = normalize(normalWorld * normalUpdated);
    #endif

The code for the instances / thin instances case is a faster implementation than doing the full transpose + inverse matrix, but the normal may not be exactly the right one.

1 Like

Whoa spooky, ok Ill look into that here at some point thank you.