unity shader 入门 全透明与半透明效果实现

这篇具有很好参考价值的文章主要介绍了unity shader 入门 全透明与半透明效果实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

片元函数的fixed4类型的返回值的第4位即为阿尔法值,0代表完全不显示(透明),1代表完全显示。中间的数值代表半透明。但只修改这个值是不能直接修改透明度的,因为还要对队列等进行修改。

本文介绍透明度测试与透明度混合,前者只能制作全透明效果,后者可制作半透明效果。

透明度测试/全透明效果:

如果要将纹理贴图的一部分显示为不透明,另一部分显示为完全透明,可以使用这个方法。方法很简单,在片元函数中加入如下内容:

if((texColor.a - _Cutoff)<0)//条件根据需要改
{
    discard;//剪除、不显示该片元
}

这里的_Cutoff是设置的一个可以修改的系数,texColor.a为纹理贴图的阿尔法通道。当满足条件(texColor.a- _Cutoff)<0)时剪除该片元,也就是完全透明。具体条件可根据需要改。

同时建议使用标签Tags { "Queue"="AlphaTest" "IgnoreProjector"="True" },含义分别为选择渲染队列为AlphaTest(在渲染不透明物体之后、透明物体之前渲染该物体);不产生阴影;

一个透明度测试/全透明效果的完整例子:

Shader "Test"
{
     Properties
	{
		_MainTex("MainTex", 2D) = "white" {}//纹理贴图
		_Diffuse("Diffuse", Color) = (1,1,1,1)//漫反射颜色
		_Cutoff("Alpha Cutoff", Range(0,1)) = 0.5//设置的控制透明部分的系数
	}

	SubShader
	{
		Tags { 
			"Queue"="AlphaTest" //在不透明物体之后、透明物体之前渲染该物体;
			"IgnoreProjector"="True" //不产生阴影;
			}
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"
			#include "Lighting.cginc"

			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed4 _Diffuse;
			float _Cutoff;

			struct v2f
			{
				float4 vertex : SV_POSITION;
				fixed3 worldNormal: TEXCOORD0;//世界空间法线
				float3 worldPos: TEXCOORD1;//世界空间顶点坐标
				float2 uv : TEXCOORD2;//uv坐标
			};

			v2f vert (appdata_base v)//appdata_base是自带的一个结构体,含有vertex、normal等的定义,这样就不用自己再定义一个类似的结构体了。
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				fixed3 worldNormal = UnityObjectToWorldNormal( v.normal);
				o.worldNormal = worldNormal;
				o.worldPos = mul(unity_ObjectToWorld, v.vertex);
				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;//环境光
				fixed4 texColor = tex2D(_MainTex, i.uv);//读取纹理贴图颜色值

				if((texColor.a - _Cutoff)<0)//满足条件时不显示该片元,这里的条件为纹理贴图的α通道的值小于_Cutoff
				{
					discard;//剪除、不显示该片元
				}

				//漫反射
				fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
				fixed3 diffuse = _LightColor0.rgb * texColor.rgb * _Diffuse.rgb * (dot(worldLightDir,i.worldNormal)*0.5+0.5);

				fixed3 color = ambient + diffuse;
				return fixed4(color,1);
			}
			ENDCG
		}
	}
	FallBack "VertexLit"//虽然之前的标签了设置了不产生阴影,但FallBack的方案也会产生阴影
}

使用一张渐变的一半透明的纹理贴图,调整_Cutoff可以调整透明的面积。

unity 透明贴图 使用,Shader,Unity3D,Unity,unity,游戏引擎

制作草时可以使用透明度测试让贴图除草之外的部分全透明。但使用这个方法只能得到全透明的效果,而不能产生半透明的效果。

 透明度混合/半透明效果:

先讲几个概念:深度测试、深度写入、深度缓存、颜色缓存。

在渲染时都要进行深度测试,当渲染不透明物体时,将深度与深度缓存中的值比较,发现新片元更靠近摄像机时,就将新深度写入深度缓存,并更新颜色缓存。这样最后渲染出的颜色就是最接近摄像机的片元的颜色,被其遮挡的则不会渲染。

渲染半透明物体,需要在不透明物体渲染结束后。渲染半透明物体依然会进行深度测试,剔除掉被不透明物体遮挡的片元。但需要关闭深度写入,不再更新深度缓存。发现是需要渲染的颜色时,不是直接替换颜色缓冲,而是以一定方式进行混合。下面是一些常见混合类型,和ps中的图层叠加比较相似:

常见混合操作类型:

//正常(Normal)透明度混合

Blend SrcAlpha OneMinusSrcAlpha

//柔和相加

Blend OneMinusDstColor One

//正片叠底

Blend DstColor Zero

//两倍相乘

Blend DstColor SrcColor

//变暗

BlendOp min

Blend One One

//变亮

Blend OneMinusDstColor One

Blend One OneMinusSrcColor

//线性减淡

Blend One One

通常,半透明shader都有如下3个标签:
        Tags { 
            "Queue"="Transparent" //选择渲染队列为Transparent,这样会在渲染不透明物体之后再渲染该物体
            "IgnoreProjector"="True" //不受阴影投射器影响
            "RenderType"="Transparent"//将该shader归入预先设置的类Transparent,这个标标签的功能常被用于shader替换
            }

并且需要在pass中关闭深度写入和选择颜色混合方案:

            ZWrite Off //关闭深度写入
            Blend SrcAlpha OneMinusSrcAlpha //颜色混合方案

一个完整的代码例子:

Shader "Test"
{
      Properties
	{
		_MainTex("MainTex", 2D) = "white" {}
		_Diffuse("Diffuse", Color) = (1,1,1,1)
		_AlphaScale("Alpha Scale", Range(0,1)) = 1//透明度系数,0表示完全透明
	}

	SubShader
	{
		//半透明shader通常都包含这3个标签
		Tags { 
			"Queue"="Transparent" //选择渲染队列为Transparent,这样会在渲染不透明物体之后再渲染该物体
			"IgnoreProjector"="True" //不受阴影投射器影响
			"RenderType"="Transparent"//将该shader归入预先设置的类,常被用于shader替换
			}
		LOD 100
		ZWrite Off //关闭深度写入
		Blend SrcAlpha OneMinusSrcAlpha //开启普通混合


		Pass
		{
			Tags{"LightMode"="ForwardBase"}//光照模式
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"
			#include "Lighting.cginc"

			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed4 _Diffuse;
			float _AlphaScale;

			struct v2f
			{
				float4 vertex : SV_POSITION;
				fixed3 worldNormal: TEXCOORD0;
				float3 worldPos: TEXCOORD1;
				float2 uv : TEXCOORD2;
			};

			v2f vert (appdata_base v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				fixed3 worldNormal = UnityObjectToWorldNormal( v.normal);
				o.worldNormal = worldNormal;
				o.worldPos = mul(unity_ObjectToWorld, v.vertex);
				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;//环境光颜色

				fixed4 texColor = tex2D(_MainTex, i.uv);//纹理贴图颜色

				//漫反射
				fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
				fixed3 diffuse = _LightColor0.rgb * texColor.rgb * _Diffuse.rgb * (dot(worldLightDir,i.worldNormal)*0.5+0.5);

				fixed3 color = ambient + diffuse;
				return fixed4(color, texColor.a * _AlphaScale);//使用纹理贴图的阿尔法通道*_AlphaScale作为新阿尔法值,0为全透明
			}
			ENDCG
		}
	}
	FallBack "VertexLit"
}

半透明物体的背面信息也被剔除了,所以是不会显示的。如果需要显示背面信息,在pass中使用Cull Off关闭剔除。如果需要先渲染背面内容,再渲染正面内容,以便从前到后正确混合颜色,就将pass复制为2个,上方的pass用Cull Front只渲染背部,下方的pass用Cull Back只渲染前部。文章来源地址https://www.toymoban.com/news/detail-623874.html

到了这里,关于unity shader 入门 全透明与半透明效果实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity Shader学习3:透明效果

    Unity中的透明效果由透明通道控制(RGBA中的A),其值为0是完全透明,为1时完全不透明。有两种方法可以实现透明效果: 透明度测试(Alpha Test) 和 透明度混合(Alpha Blend) 。 透明度测试是指通过特定的条件(通常是Alpha通道的值是否超过某个阈值)来判断片元是否透明,只

    2024年01月19日
    浏览(62)
  • 学习100个Unity Shader (14) ---透明效果

    由”Queue“ 标签决定,索引号越小越早被渲染: 名称 队列索引号 Background 1000 Geometry 2000 AlphaTest 2450 Transparent 3000 Overlay 4000 某一片元的透明度小于某个阈值,即被舍弃,反之,按非透明物体处理,进行正常的深度测试和深度写入【不需要关闭深度写入】。 UnityObjectToClipPos 将顶

    2024年04月29日
    浏览(45)
  • 【Unity Shader Graph URP渲染管线下的自定义半透明效果_半透明案例分享】

    URP的渲染管线下 在项目设置里找到“Graphic” 找到URP Asset文件 索引到Renderer List文件——“ForwardRenderer” 在这个“ForwardRenderer”文件里找到“Add Renderer Feature” 添加一个渲染对象,类似下图:Render Object (Experimental) 如图设置,将“Event”设置成 AfterRenderingSkybox ,然后“Layer M

    2024年02月09日
    浏览(59)
  • unity Shader实现半透明阴影

    在shader中,要对移动端的兼容,还不想实现两套分开兼容的话, 这两句话一定要改掉,第一行代码直接剔除了gles的渲染,而恰恰大部分移动端都是用的gles(安卓平台)所以,第一行要去掉。第二行是针对于ShaderMod,也就是一些shader新特性,可以调低,内置的lit里面是实现了

    2024年02月01日
    浏览(38)
  • 【unity实战】使用shader和shader Graph实现2d图片描边效果(附源码)

    最近在学习shader Graph相关内容,其实关于实现2d图片描边效果,网上可以看到很多教程,但是我发现大多数都是基于比较老旧的2018unity版本,可是我们实际开发使用可能是比较新的2021及以上版本,差别还是有的,实际在升级或者使用过程中,会遇到诸多问题,而且也很少有人

    2024年02月16日
    浏览(56)
  • Unity入门精要03---透明效果

    本节知识架构      如果采用了透明度混合即要是实现半透明效果,那么就要关闭深度写入,那么此时渲染顺序就会变得非常非常重要,不然会出现不正确的遮挡效果。具体的分析可见书中解释 一句话概括就是因为没有写入深度,会导致之后读取的时候没有读取到深度,就可

    2024年02月04日
    浏览(63)
  • 【实现100个unity特效之2】使用shader和shader Graph实现2d图片描边效果(附源码)

    最近在学习shader Graph相关内容,其实关于实现2d图片描边效果,网上可以看到很多教程,但是我发现大多数都是基于比较老旧的2018unity版本,可是我们实际开发使用可能是比较新的2021及以上版本,差别还是有的,实际在升级或者使用过程中,会遇到诸多问题,而且也很少有人

    2024年01月21日
    浏览(66)
  • 《Unity 入门精要》第8章 透明效果

    在 Unity 中,我们通常使用两种方法来实现透明效果: 透明度测试(Alpha Test) 和 透明度混合(Alpha Blending) 。 当我们渲染不透明物体时,我们不需要特别考虑渲染顺序的问题,因为有 深度缓冲(depth buffer,也称 z-buffer) 的存在,它的基本思想是:根据深度缓存中的来判断

    2024年02月10日
    浏览(46)
  • Unity地面交互效果——2、动态法线贴图实现轨迹效果

    回到目录 Unity引擎动态法线贴图制作球滚动轨迹   大家好,我是阿赵。   之前说了一个使用局部UV采样来实现轨迹的方法。这一篇在之前的基础上,使用法线贴图进行凹凸轨迹的绘制。   先来回顾一下,上一篇最终我们已经绘制了一个轨迹的贴图   可以思考一下,

    2024年02月06日
    浏览(73)
  • UE4带Alpha通道透明效果贴图的相关问题

    镂空效果 (黑色部分透明):UE4中,一张贴图同时显示color与opacity, 问题一:最初贴图只呈现颜色,应该透明的区域是黑色的 修改步骤如下 : ps中魔棒选中黑色区域-反选-右键存储选区-生成alpha通道-删除黑色区域-形成透明部分只有灰白像素 导出为png--导入UE4内容浏览器 材

    2023年04月20日
    浏览(77)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包