Use GeometryBuffer to get normal sampler


I’m currently working on shaders and I’ve seen that I can use GeometryBuffer to get a normal sampler but the result does not correspond to the normals (as you can easily see on the cubes) :

In my custom post process class I use :

this.onApply = (effect) => {
    if (this._geometryBufferRenderer) {
        effect.setTexture("normalSampler", this._geometryBufferRenderer.getGBuffer().textures[1]);
        effect.setTexture("positionSampler", this._geometryBufferRenderer.getGBuffer().textures[2]);

And in my custom shader I use :

vec4 normalBuffer = normalize(texture2D(normalSampler, vUV));

Can somebody tell me what I’m doing wrong please ?

Have a nice day ! :slight_smile:

not directly an answer to your question, but the normal material already exists in this folder : Babylon.js/dist/materialsLibrary at master · BabylonJS/Babylon.js · GitHub

you can use it out-of-the-box :slight_smile:

My goal is to reuse the normal buffer to detect the edges on the meshes.

Thanks anyway :smiley:

Pinging our gbuffer expert @julien-moreau

Heu @Kheod,
Normals are in world space so I guess that you would like to translate the normals into the view space. Just translate like:

vec3 normal = (vec4(texture2D(textureSampler, vUV).rgb, 1.0) * viewMatrix).rgb;
gl_FragColor = vec4(normal.rgb, 1.0);

Is that working for you?

I don’t think this is my main issue.

The thing i don’t understand is why I can’t see the edges on the cubes.
Even if I’m in the bad space, shouldn’t I see the separation between the different faces (instead of a gradient)?

Like this for example :
(comment / uncomment the lines in the fragment shader)

Note: I wrote something wrong beucase I’m tired: you translate to world space in my example

That’s not a need. In some effects you need view space normals, and others you need world space normals
In the case of Babylon.js it is in view space by default so you have to translate to world space in your case.
In the case of SSAO2, it uses normals in view space to reconstruct tangents etc. Babylon.js/ssao2.fragment.fx at master · BabylonJS/Babylon.js · GitHub

If I understood you correctly, I should change my space reference, but even if I’m not in the world space, shouldn’t I have the same color on each face of the cube?

The normal is the same for each point of a face no matter which space I use, right?

effect.setTexture(“normalSampler”, this._geometryBufferRenderer.getGBuffer().textures[1]);

Why when using the previous code, don’t I get a unique value per face of the cube?

Possibly something to do with color assignment to vertices and whether the mesh is flat shaded or not


That’s it!

I used converToFlatShadedMesh on my meshes and then I’ve the correct values on the faces.

Thanks a lot :slight_smile:

1 Like