How to run post process on different groups of objects without re-renders

So I’m trynna make a depth based edge detection post process for achieving an outline effect for almost every object in the scene.

The problem here is, I have groups of objects that I want to have differing line widths.

1 way to achieve this is using a RenderTargetTexture and render out each group and run the post process on them separately and then recombine them.

but some objects in the scene are kinda heavy (and there’s a lot of them) and I wanna avoid rendering them twice if I can.

Is there another way I can achieve this without re-rendering stuff?

Can you achieve what you want with the existing mesh highlighting?
Highlighting Meshes | Babylon.js Documentation (babylonjs.com)

2 Likes

sadly no, I can w/ EdgeRenderer but it slow : /

@sebavan, @Evgeni_Popov, @PatrickRyan any other ideas for this?

1 Like

Would you render these objects for the edge detection effect with the same material used for the final render? I’m guessing not, so you’d have to render these objects twice anyway (?).

1 Like

I’ve achieved similar results in the past.

Rewrite EdgeRenderer’s algorithm, put edge visibility info into new vertex data.
one triangle face has three vertexs v0, v1, v2 and three edges, e01, e12, e20.

e01: v0 → v1
e12: v1 → v2
e20: v2 → v0

new vertex data is vector3, storing e01, e12, e20 is visible or invisible. 1 is visible, 0 is insible.
three vertexs in one triangle share same edges visibility info, so have same new vertex data.

new verte data: new Vector3(e01Visibility, e12Visibility, e20Visibility);

then use new vertex data in material plugin, renders visible wireframes using a method based on the coordinates of the center of gravity, you can refer to meshDebugPluginMaterial.ts in babylon source code.

the vertex shader code as follow:

        CUSTOM_VERTEX_DEFINITIONS: `
attribute vec3 edgesVisibility;   // new vertex data
varying vec3 v_wireframeBarycentric;
        `,
        CUSTOM_VERTEX_MAIN_END: `
float wireframeVertexIndex = mod(float(gl_VertexID), 3.);
if (wireframeVertexIndex == 0.0) { 
    v_wireframeBarycentric = vec3(1.,0.,0.);
} else if (wireframeVertexIndex == 1.0) { 
    v_wireframeBarycentric = vec3(0.,1.,0.);
} else { 
    v_wireframeBarycentric = vec3(0.,0.,1.);
}

// hide invisible edges

if(edgesVisibility.y < 1.0) {
  // e12 edge is invisible
  v_wireframeBarycentric.x = 1.0;
}

if(edgesVisibility.z < 1.0) {
  // e20 edge is invisible
  v_wireframeBarycentric.y = 1.0;
}

if(edgesVisibility.x < 1.0) {
  // e01 edge is invisible
  v_wireframeBarycentric.z = 1.0;
}
        `,
1 Like

Would you render these objects for the edge detection effect with the same material used for the final render?

Nope, I just need a depth/stencil texture.

I’m guessing not, so you’d have to render these objects twice anyway (?).

wdym : O

tysm! I’ll try this out : D

the implementation use material plugin, doesnt increase draw callbacks, just cost extra time to compute new vertex data before render scene.

1 Like

yepp : )
ty!