Unity模型透明功能(HDRP)
先整理⼀下原来透明怎么设置的
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);//ShaderHelper是以前Buldin时的⼯具,现在没什么⽤,⾥⾯其实就是Shader.Find()了
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等参数。
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);
param namematerial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
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.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.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.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.SetShaderPassEnabled("ShadowCaster", false);
break;
}
}
}
}
3.HDRP
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);
var materialBack=new Material(material);//备份材质,后续还原⽤
backMaterials.Add(material,materialBack);//backMaterials是个Dictionary<Material,Material>,存⼀下材质的备份。
//还原的时候 material.CopyPropertiesFromMaterial(materialBack)
material.CopyPropertiesFromMaterial(m);
material.SetColor("_BaseColor", color);
material.SetTexture("_BaseColorMap", texture);
//透明也要有⾦属、光滑效果的话,其他属性也要设置⼀下。
}
由于历史原因,项⽬中多处存在透明代码,适⽤于不同的渲染关系,有空个时间统⼀⼀下,写⼀个统⼀处理三种情况的代码。
4.公司相关代码说明
TransparentHelper:最早的Build-in的透明功能
StartdarMaterialController:URP和HDRP的透明功能,调⽤StardarShaderMatHelper.SetMaterialRenderingMode ModelChange:⼯艺流程的透明功能,调⽤StardarShaderMatHelper.SetMaterialRenderingMode

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。