文章目录
- 前言
- 一、我们修正一下上篇文章中,可能遗留的Bug
- 1、N向量 变为 单位向量
- 2、使颜色范围在合理区间
- 二、实现菲涅尔效果强弱可自定义调节
- 三、修改菲涅尔效果颜色
- 1、在属性面板定义颜色属性
- 2、在常量缓冲区申明该参数
- 3、在片元着色器中,用颜色和菲涅尔效果相乘输出
- 四、测试代码
- 最终效果
前言
在上篇文章中,我们实现了 URP 下的菲涅尔基础效果,我们在这篇文章中,对其进行自定义化修改。
- Unity中URP下的菲涅尔效果实现(URP下的法线和视线向量怎么获取)
一、我们修正一下上篇文章中,可能遗留的Bug
1、N向量 变为 单位向量
虽然我们在顶点着色器中,进行法线坐标转化时,内置进行了向量归一化。但是,顶点着色器到片元着色器会进行线性插值,可能导致归一化后的向量又有变化。所以,我们在片元着色器中对法线再进行一次归一化。
half3 N = normalize(i.normalWS);
2、使颜色范围在合理区间
- 在上篇文章中,我们直接使用了 NdotL。但是,NdotL是可能存在负数结果的。所以,我们要对其进行处理
- 使用 saturate(x) 函数。当x < 0时,返回0;当x > 1时,返回1;
half NdotL = dot(N,L);
half fresnel = 1 - saturate(NdotL);
二、实现菲涅尔效果强弱可自定义调节
- 我们可以发现,使用Pow函数,可以使我们的数值在(0,1)区间变得陡峭
- 我们在属性面板定义一个参数用于 调节pow指数
_Fresnel(“Fade(X) Intensity(Y)”,Vector) = (4,1,0,0)
这里用 x 调节 pow 指数,用 y 调节亮度
- 在常量缓冲区CBUFFER 区间申明该参数
CBUFFER_START(UnityPerMaterial)
half4 _Fresnel;
CBUFFER_END
- 在片元着色器,用该算法修改菲尼尔效果
half fresnel = 1 - saturate(NdotL);
half col = pow(fresnel,_Fresnel.x) * _Fresnel.y;
三、修改菲涅尔效果颜色
1、在属性面板定义颜色属性
_FresnelColor(“FresnelColor”,Color) = (0,0,0,0)
2、在常量缓冲区申明该参数
CBUFFER_START(UnityPerMaterial)
half4 _FresnelColor;
half4 _Fresnel;
CBUFFER_END
3、在片元着色器中,用颜色和菲涅尔效果相乘输出
half4 col = pow(fresnel,_Fresnel.x) * _Fresnel.y;
col *= _FresnelColor;
return col;
四、测试代码
//URP下的菲涅尔效果
Shader "MyShader/URP/P3_2_4"
{Properties{_FresnelColor("FresnelColor",Color) = (0,0,0,0)_Fresnel("Fade(X) Intensity(Y)",Vector) = (4,1,0,0)}SubShader{Tags{//告诉引擎,该Shader只用于 URP 渲染管线"RenderPipeline"="UniversalPipeline"//渲染类型"RenderType"="Opaque"//渲染队列"Queue"="Geometry"}Pass{Cull Back Blend One Zero ZTest LEqual ZWrite OnHLSLPROGRAM#pragma vertex vert#pragma fragment frag#pragma target 2.0#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{float4 vertexCS : SV_POSITION;float3 normalWS : TEXCOORD0;float3 vertexWS : TEXCOORD1;};CBUFFER_START(UnityPerMaterial)half4 _FresnelColor;half4 _Fresnel;CBUFFER_ENDVaryings vert (Attributes v){Varyings o;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 col = pow(fresnel,_Fresnel.x) * _Fresnel.y;col *= _FresnelColor;return col;}ENDHLSL}}
}