Search Unity

Spotlight shows strange lit areas when sprites do vertex animations

Discussion in 'General Graphics' started by cwbeta, Jun 13, 2019.

  1. cwbeta

    cwbeta

    Joined:
    Jan 12, 2017
    Posts:
    32
    I made a shader which gives different offset to sprite vertexes to simulate the animation of leaves.
    Everything works perfectly when I use directional light in the scene, but when I add spot lights or point lights into the scene, strange lit areas shows like this:
    leaves.gif
    QQ截图20190613112419.jpg
    The bug shows more often when I add the Wind Amount param, which increase the vertex offset in the shader.

    I've tried to set the render mode of spotlight to important or increase the pixel light limit in Unity quality settings, but nothing helps.

    Modifying the vertex of sprites to grid can reduce the problem, but it may still occurs when the wind is strong:
    QQ截图20190613114356.jpg QQ截图20190613114407.jpg

    I guess the problem comes because the vertexes go across each other when play shader animations, but I'm not sure:
    QQ截图20190613113155.jpg
    Is there someone knows the reason and how to fix it? Many thanks!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    Unity’s built in forward rendering path’s lighting system is to blame here. The main directional light as rendered as part of the base pass of the shader, but all additional lights are an extra additive blend pass, one for each additional light. Because it’s an additive pass you get the problem you’re seeing above and correctly concluded was caused by the overlapping of the sprite mesh on heavy distortion. And yes, it’s additive even if you’re using an alpha blended shader.

    The easiest solution is don’t have extra lights, but that’s not exactly useful.
    The next best solution is to try to not do vertex distortions that cause the mesh to collapse on itself... which is harder said than done.
    The real solution is to not do lighting with multiple additive passes. This is how the LWRP works, but you can also get similar behavior with the built in rendering path by using non-important lights.

    Each object can support up to 4 non important point lights, and an infinite number of non-important directional lights. But point lights are by default calculated per vertex, which may lead to some unwanted visual artifacts when using small radius lights. A custom shader could be used to calculate the “per vertex” lights in the fragment shader, avoiding the problem.
     
    cwbeta likes this.
  3. cwbeta

    cwbeta

    Joined:
    Jan 12, 2017
    Posts:
    32
    I can't appreciate your answer more! Your solutions are so detailed and reasonable. The spotlights are added only for decoration and don't have to be pixel-rendered. The problem is gone by setting all the spotlights to non-important. The draw call also gets lower now and my game gets a higher FPS.

    I'm so grateful there are people like you here to help newbies in rendering like me. Thank you so much!