文章目录
- 前言
- 一、实现半透明的步骤
- 1、修改Blend模式,使之透明
- 2、打开深度写入,防止透明对象穿模
- 3、在Tags中,修改渲染类型和渲染队列为半透明 Transparent
- 二、对透明效果实现从下到上的透明渐变
- 1、 我们在 Varying 中,定义一个vertexOS,用于把顶点的本地空间坐标传给片元着色器
- 2、 在顶点着色器中,把Attribute中的模型顶点本地坐标 传入给 vertexOS
- 3、 我们输出看一下模型顶点本地坐标的xyz
- 4、使用模型顶点本地坐标中的 y 坐标实现效果
- 5、定义一个可调节参数 _Offset ,调节透明开始的位置
- 6、使用saturate(x)限制蒙版区域在(0,1)之间
- 7、与之前的菲涅尔效果相乘输出
- 8、修改透明效果为斜着透明(凭个人喜好添加)
- 9、使头部的菲涅尔效果更加明显,脚部的菲尼尔效果正常
- 请添加图片描述
- 三、最终测试代码
前言
URP下的半透明效果的实现方式,和BRP下的实现是一样的。
我们在上一篇文章实现了菲涅尔效果的基础上,继续添加半透明效果。
- Unity中URP下的菲涅尔效果实现(个性化修改)
一、实现半透明的步骤
1、修改Blend模式,使之透明
- Unity中Shader的混合模式Blend
Blend One One
2、打开深度写入,防止透明对象穿模
ZWrite On
3、在Tags中,修改渲染类型和渲染队列为半透明 Transparent
Tags
{//告诉引擎,该Shader只用于 URP 渲染管线"RenderPipeline"="UniversalPipeline"//渲染类型"RenderType"="Transparent"//渲染队列"Queue"="Transparent"
}
- 我们的菲尼尔效果变透明了
二、对透明效果实现从下到上的透明渐变
- 实现思路
要实现模型从上到下的渐变效果,我们一般使用模型的本地坐标。
1、 我们在 Varying 中,定义一个vertexOS,用于把顶点的本地空间坐标传给片元着色器
float3 vertexOS : TEXCOORD0;
2、 在顶点着色器中,把Attribute中的模型顶点本地坐标 传入给 vertexOS
3、 我们输出看一下模型顶点本地坐标的xyz
- i.vertexOS.x
- i.vertexOS.y
- i.vertexOS.z
4、使用模型顶点本地坐标中的 y 坐标实现效果
我们要实现从下到上,从透明渐变到不透明的效果,则把 y 坐标取反即可(这里每个人的不一样,自己调试)
return i.vertexOS.y * -1;
5、定义一个可调节参数 _Offset ,调节透明开始的位置
- 定义的方法在之前文章中
- Unity中 URP Shader 常量缓冲区CBUFFER
return i.vertexOS.y * -1 + _Offset;
- 这样就可调节调节透明开始的位置
6、使用saturate(x)限制蒙版区域在(0,1)之间
saturate(i.vertexOS.y * -1 + _Offset);
7、与之前的菲涅尔效果相乘输出
saturate(i.vertexOS.y * -1 + _Offset) * fresnel1
8、修改透明效果为斜着透明(凭个人喜好添加)
经测试,我这里使用 模型顶点本地坐标的 x 可以调试出这种效果(每个人的模型可能不一样)
- i.vertexOS.y * -1 + i.vertexOS.x * -1
return saturate(i.vertexOS.y * -1 + i.vertexOS.x * -1 + _Offset) * fresnel1;
9、使头部的菲涅尔效果更加明显,脚部的菲尼尔效果正常
这样的效果,我们很容易联想到使用线性插值的方法实现
- 上面计算的计算结果作为 插值数a
half fresnel = 1 - saturate(NdotL);
//菲涅尔自定义
half4 fresnel1 = pow(fresnel,_Fresnel.x) * _Fresnel.y * _FresnelColor;
//透明渐变效果
float alphaMask = saturate(i.vertexOS.y * -1 + i.vertexOS.x * -1 + _Offset);
fresnel1 = alphaMask * fresnel1;
- 使菲涅尔效果更加明显 作为 插值数b
_FresnelColor * alphaMask * fresnel1
- 把alphaMask作为被插值的变量
fresnel1 = lerp(fresnel1,_FresnelColor * alphaMask * fresnel1,alphaMask * _Fresnel.z);
三、最终测试代码
//URP下的菲涅尔效果
//URP下的透明效果
Shader "MyShader/URP/P3_2_5"
{Properties{_FresnelColor("FresnelColor",Color) = (0,0,0,0)_Fresnel("Fade(X) Intensity(Y) Top(Z) Offset(W)",Vector) = (4,1,1,0)}SubShader{Tags{//告诉引擎,该Shader只用于 URP 渲染管线"RenderPipeline"="UniversalPipeline"//渲染类型"RenderType"="Transparent"//渲染队列"Queue"="Transparent"}Blend One One ZWrite OnPass{HLSLPROGRAM#pragma vertex vert#pragma fragment frag#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"struct Attributes{float3 vertexOS : POSITION;float3 normalOS : NORMAL;};struct Varyings{float3 vertexOS : TEXCOORD0;float4 vertexCS : SV_POSITION;float3 vertexWS : TEXCOORD1;float3 normalWS : TEXCOORD2;};CBUFFER_START(UnityPerMaterial)half4 _FresnelColor;half4 _Fresnel;float _Offset;CBUFFER_ENDVaryings vert (Attributes v){Varyings o;o.vertexOS = v.vertexOS;o.vertexWS = TransformObjectToWorld(v.vertexOS);o.vertexCS = TransformWorldToHClip(o.vertexWS);o.normalWS = TransformObjectToWorldNormal(v.normalOS);return o;}half4 frag (Varyings i) : SV_Target{//dot(N,L)half3 N = normalize(i.normalWS);half3 L = normalize(_WorldSpaceCameraPos - i.vertexWS);half NdotL = dot(N,L);//菲涅尔效果 1 - dot(N,L)half fresnel = 1 - saturate(NdotL);//菲涅尔自定义half4 fresnel1 = pow(fresnel,_Fresnel.x) * _Fresnel.y * _FresnelColor;//透明渐变效果float alphaMask = saturate(i.vertexOS.y * -1 + i.vertexOS.x * -1 + _Fresnel.w);fresnel1 = alphaMask * fresnel1;//头部菲涅尔效果和下部菲涅尔效果做出区别fresnel1 = lerp(fresnel1,_FresnelColor * alphaMask * fresnel1,alphaMask * _Fresnel.z);return fresnel1;}ENDHLSL}}
}