Unity中URP下的菲涅尔效果实现(个性化修改)
2023-12-17 21:41:45
文章目录
前言
在上篇文章中,我们实现了 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
}
}
}
最终效果
文章来源:https://blog.csdn.net/qq_51603875/article/details/135048926
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!