先整理一下原來透明怎么設定的
1.Build-in
獲取透明的Shader,修改模型材質的Shader,修改顏色引數透明度,修改材質是否為空
/// <summary>
/// 將游戲物體設定成透明的(包括子物體也都設定成透明的)
/// </summary>
/// <param name="go"></param>
/// <param name="transparent"></param>
/// <param name="color"></param>
/// <param name="isSpecular"></param>
/// <param name="removeTexture"></param>
/// <returns></returns>
public static bool SetTransparent(this GameObject go, Color color, bool isSpecular, bool removeTexture = false)
{
Renderer render = go.GetComponent<Renderer>();
if (render == null) return false;
Shader shader = ShaderHelper.GetTransparentShader(isSpecular);
for (int i = 0; i < render.materials.Length; i++)
{
SetTransparentMaterial(render, i, shader, color, removeTexture);
//StardardShaderSet.SetMaterialRenderingMode(mm, RenderingMode.Transparent);
}
return true;
}
/// <summary>
/// 修改材質,達到透明的效果
/// </summary>
/// <param name="render"></param>
/// <param name="i"></param>
/// <param name="shader"></param>
/// <param name="color"></param>
/// <param name="removeTexture"></param>
private static void SetTransparentMaterial(Renderer render, int i, Shader shader, Color color, bool removeTexture)
{
//Material mm = new Material(render.materials[i]);
//Material mm = render.materials[i];
//render.materials[i] = mm;
render.materials[i].shader = shader;
render.materials[i].color = color;
if (removeTexture)
{
render.materials[i].mainTexture = null;
}
}
2.URP
修改URP/Lit材質的_SurfaceType,_Mode等引數,
參考:https://answers.unity.com/questions/1608815/change-surface-type-with-lwrp.html?_ga=2.257083661.724107984.1607480798-60239732.1590568025
using UnityEngine;
using System;
public class DisplayController : MonoBehaviour
{
public enum SurfaceType
{
Opaque,
Transparent
}
public enum BlendMode
{
Alpha,
Premultiply,
Additive,
Multiply
}
public Material wallMaterial;
public void ChangeWallTransparency(bool transparent)
{
if (transparent)
{
wallMaterial.SetFloat("_Surface", (float)SurfaceType.Transparent);
wallMaterial.SetFloat("_Blend", (float)BlendMode.Alpha);
}
else
{
wallMaterial.SetFloat("_Surface", (float)SurfaceType.Opaque);
}
SetupMaterialBlendMode(wallMaterial);
}
void SetupMaterialBlendMode(Material material)
{
if (material == null)
throw new ArgumentNullException("material");
bool alphaClip = material.GetFloat("_AlphaClip") == 1;
if (alphaClip)
material.EnableKeyword("_ALPHATEST_ON");
else
material.DisableKeyword("_ALPHATEST_ON");
SurfaceType surfaceType = (SurfaceType)material.GetFloat("_Surface");
if (surfaceType == 0)
{
material.SetOverrideTag("RenderType", "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = -1;
material.SetShaderPassEnabled("ShadowCaster", true);
}
else
{
BlendMode blendMode = (BlendMode)material.GetFloat("_Blend");
switch (blendMode)
{
case BlendMode.Alpha:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
material.SetShaderPassEnabled("ShadowCaster", false);
break;
case BlendMode.Premultiply:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt("_ZWrite", 0);
material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
material.SetShaderPassEnabled("ShadowCaster", false);
break;
case BlendMode.Additive:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
material.SetShaderPassEnabled("ShadowCaster", false);
break;
case BlendMode.Multiply:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
material.SetShaderPassEnabled("ShadowCaster", false);
break;
}
}
}
}
3.HDRP
參考:https://forum.unity.com/threads/hdrp-make-surface-transparent-in-runtime.663025/#post-4439554
It seems like the proper thing to do is to have 2 materials, one opaque and one transparent, and switch materials on the mesh as needed.
根據查到的資料,運行程序中修改_SurfaceType,沒有效果,建議給模型設定一個透明的材質,切換材質來達到透明的效果,
測驗發現也可以使用將透明材質的屬性全部Copy過來,一樣能夠透明,需要將原材質的資訊備份(顏色、材質),Copy透明材質,還原原資訊,
var color=material.GetColor("_BaseColor");
var texture=material.GetTexture("_BaseColorMap");
if(Transparent_Mat==null){
Transparent_Mat=Resources.Load<Material>("HDRPLit_Transparent_Double");
}
if(EnableTransparent==true){
Material m=GameObject.Instantiate(Transparent_Mat);
material.CopyPropertiesFromMaterial(m);
material.SetColor("_BaseColor", color);
material.SetTexture("_BaseColorMap", texture);
}
由于歷史原因,專案中多處存在透明代碼,適用于不同的渲染關系,有空找個時間統一一下,寫一個統一處理三種情況的代碼,
4.公司相關代碼說明
TransparentHelper:最早的Build-in的透明功能
StartdarMaterialController:URP和HDRP的透明功能,呼叫StardarShaderMatHelper.SetMaterialRenderingMode
ModelChange:工藝流程的透明功能,呼叫StardarShaderMatHelper.SetMaterialRenderingMode
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/233057.html
標籤:其他
上一篇:廣州大學城——橋
下一篇:第二次上機題目
