文章目录
- 前言
- 一、我们修正一下上篇文章中,可能遗留的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 On
HLSLPROGRAM
#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_END
Varyings 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
}
}
}