0
\$\begingroup\$

I have a small shader that does the following things:

(First cgprogram block)

  1. Copy the current mesh and scales it along the normals
  2. Assign a color to the inflated mesh
  3. Draw the inflated mesh

(Second cgprogram block)

  1. Assign a color to the original mesh
  2. Draw the original mesh

In-game you can only see the inflated mesh because the smaller one gets inglobated.

Is there a way to re-order the rendering order, by drawing first the inflated mesh and then the original mesh, resulting in a sort of outline effect?

What I tried

  1. Setting Cull Front on the inflated mesh and Cull Back on the original mesh

    I copied this approach from an outline shader. Unfortunately it leads to other problems such as bad intersecting between inflated mesh in-game.

  2. Changing the Queue in the shader between the two CGPROGRAM blocks

    I set the first CGPROGRAM block on "Queue" = "Geometry-10" and the second on "Queue" = "Geometry+0" but.. no effect.

Is there a way to obtain the desired effect? Thanks in advance.

Here are some images to make the question a bit clearer:

Current wireframe situation

Original mesh inside, inflated mesh outside

enter image description here

Current shaded situation

enter image description here

Desired outcome

enter image description here

Inflated mesh set on Cull Front

This is the aforementioned problems between intersecting meshes. The inflated meshes have z-fighting going on.

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Rendering the outline shell inside-out is indeed the usual way this is done. Can you share with us the visual artifacts you're seeing? There may be other techniques to help correct for it. \$\endgroup\$ – DMGregory Mar 22 '18 at 11:30
  • \$\begingroup\$ @DMGregory thanks for the heads up. I added some images. \$\endgroup\$ – Shader Doe Mar 22 '18 at 12:21
  • \$\begingroup\$ Hm, I'm not sure I understand Your red is your outline blob and the white is the regular mesh, right? What are the blue and yellow? You have a second copy of the object being drawn in different colours? If that's the case, then it sounds like just regular vanilla z-fighting, and not anything related to the outlining effect you're using. What's leading you to position meshes so closely overlapped & parallel like this? Usually that's the root problem. \$\endgroup\$ – DMGregory Mar 22 '18 at 12:25
  • \$\begingroup\$ Sorry, I forgot to add text to the images. The white cylinder is the regular mesh, with a red outline. The yellow cylinder is another cylinder (with a blue outline) that I added to show that I can't use Cull Front on the "outline" because of the z-fighting. I am trying to simulate certain particles so sometimes they exist in the same position. \$\endgroup\$ – Shader Doe Mar 22 '18 at 12:32
  • \$\begingroup\$ Just because that's the way something "is" doesn't mean that's the way we need to implement it under the hood. Games, and especially game graphics, are all about cheating & faking to achieve the desired perceived result. Putting meshes co-planar is likely not the best solution here. You might want to ask the question "How can I draw a group of particles that might occupy the same position without z-fighting?" or something similar, including visual examples of the types of arrangements you need to support and the visual style/result you want to achieve. \$\endgroup\$ – DMGregory Mar 22 '18 at 13:07
1
\$\begingroup\$

Your problem here isn't rendering order. Since your regular colour mesh pass is second, it will come after the outline blob.

But, if your outline blob is writing to the z-buffer, then every fragment of your regular mesh will fail the depth test, because there's some part of the outline blob sitting between it and the camera.

You can turn off depth writes for the outline pass with

ZWrite Off

in the same section where you do your culling settings. This will prevent the blob from writing to the depth buffer, so by the time the regular mesh draws the depth buffer will still be in the state it was in before you even started drawing this material & mesh.

Note though that this will increase overdraw. In the typical case, we draw the outline inside-out, second, so that it's the outline mesh that fails the depth test and is discarded, and we only need to blend the smaller region of pixels making up the outline. By rendering the blob first, every pixel on the interior of the model is going to get written into at least twice, and more if the model has concave shapes. For just this one effect it won't be a big cost, but watch out for using this "painter's algorithm" for lots of effects all over your game.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.