透明度在 WebGL 中无法正确呈现

Transparency not rendering properly in WebGL

我正在制作一款 3D 拼图视频游戏,我希望在拼图靠近其原始位置时在其原始位置显示拼图的半透明副本。换句话说,向玩家展示他们在正确的轨道上。

我已经这样做了,它工作正常,here's a 4 second quick gif for demonstration

但是,当我将游戏部署到 WebGL 时,它不起作用。 The copy of the object which should be translucent simply isn't.


这是我用来创建对象的半透明副本的函数。我在 this forum thread.

中找到了代码

基本上我所做的是实例化一个副本,删除不必要的组件,手动更改material设置使对象使用透明渲染模式,将不透明度更改为0,然后禁用渲染器,因为由于某些原因,当不透明度设置为 0 时,对象不是完全透明的。

GameObject CreateHighlight(GameObject gameObject)
    {
        GameObject highlight = Instantiate(gameObject);
        Destroy(highlight.GetComponent<Rigidbody>());
        Destroy(highlight.GetComponent<MeshCollider>());
        Destroy(highlight.GetComponent<StayInside>());
        Destroy(highlight.GetComponent<ObjectControl>());

        // Change render mode to Transparent
        Material material = highlight.GetComponent<Renderer>().material;
        material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
        material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
        material.SetInt("_ZWrite", 0);
        material.DisableKeyword("_ALPHATEST_ON");
        material.DisableKeyword("_ALPHABLEND_ON");
        material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
        material.renderQueue = 3000;
        // Change alpha to 0
        highlight.GetComponent<MeshRenderer>().material.color = new Color(1.0f, 1.0f, 1.0f, 0.0f);

        // Stop rendering the object because setting alpha to 0 does not make the object fully transparent
        highlight.GetComponent<MeshRenderer>().enabled = false;

        return highlight;
    }

我偶然发现了这个 Reddit thread,那个人遇到了和我一样的问题。他说他将渲染路径从 Deferred 切换到 Forward。我发现某个地方应该更改 MainCamera 中的设置,所以我做到了。我的设置为 Use Graphics Settings,所以我明确将其设置为 Forward,但没有任何改变。

OctangularPRISM Redditor saved the day on Reddit.

他的建议是创建一个新的 material,使其透明,然后在代码中实例化 material 并将其应用于突出显示的对象,而不是像我那样将渲染模式更改为透明试过了。

以下是更详细的步骤:

  1. 我首先在 中创建了 public Material matTransparentMat; 作为 public 变量ObjectControl 脚本。这意味着在所有具有 ObjectControl 脚本的对象上 additional menu to add a Material was created

  2. 然后,在项目window中我创建了一个新的Material并使其透明。您只需右键单击 -> 创建 -> Material,然后选择 material 并在检查器中按 Opaque 并选择 [=31= the drop down menu, and then click the white color and change the alpha from 255 to 0.

    中的透明
  3. 那么,drag and drop that Material to the Mat Transparent Mat public variable in the editor.

  4. 现在,我将将渲染模式更改为透明的代码更改为 /u/OctangularPRISM 的代码,该代码将实例化一个新的 material 并将其应用于副本对象的。

     public Material matTransparentMat;
    
     GameObject CreateHighlight(GameObject GO)
     {
     GameObject highlight = Instantiate(GO);
     Destroy(highlight.GetComponent<Rigidbody>());
     Destroy(highlight.GetComponent<MeshCollider>());
     Destroy(highlight.GetComponent<StayInside>());
     Destroy(highlight.GetComponent<ObjectControl>());
    
     Renderer targetRend = highlight.GetComponent<Renderer>();
     Renderer srcRend = GO.GetComponent<Renderer>();
     Material newMat = Instantiate(matTransparentMat);
     newMat.mainTexture = srcRend.material.mainTexture;
     targetRend.material = newMat;
     return highlight;
     }
    
  5. 完成!