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

时间:2021-01-04 15:53:03

标签: unity3d transparency opacity transparent unity-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.

中找到了代码

基本上我正在做的是实例化一个副本,删除不必要的组件,手动更改材质设置使对象使用透明渲染模式,将不透明度更改为 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,但没有任何更改。

Forward rendering path

1 个答案:

答案 0 :(得分:0)

OctangularPRISM Redditor saved the day on Reddit

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

以下是更详细的步骤:

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

  2. 然后,在项目窗口中,我创建了一个新材质并使其透明。您只需右键单击 -> 创建 -> 材质,然后选择材质,然后在检查器中按 Opaque 的位置,然后在 the drop down menu 中选择 Transparent,然后点击 the white color 并更改 alpha from 255 to 0

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

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

     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. 完成!