Unity中URP下的菲涅尔效果实现(URP下的法线和视线向量怎么获取)

这篇具有很好参考价值的文章主要介绍了Unity中URP下的菲涅尔效果实现(URP下的法线和视线向量怎么获取)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

我们在这篇文章中,了解一下URP中Shader怎么实现菲涅尔效果,同时学习一下URP下怎么获取法线 和 视线向量。


一、实现思路

Lambert光照模型公式:

Diffuse = Ambient + Kd * LightColor * max(0,dot(N,L))

  • 实现灯光照射中间亮 周围暗的效果,核心是dot(N,L)
    urp 菲涅尔,Unity,unity,游戏引擎

  • Unity中Shader的Lambert光照的实现

  • 光照效果下, 视线单位向量 点积 法线单位向量的效果是 中间亮周围暗。我们需要的效果刚好相反,用 1 减去该结果即可得到菲尼尔效果。

  • 所以,我们主要要获取 N 和 L

我们在之前的文章中,实现过一次菲涅尔效果(模型中间暗周围亮的效果)

  • Unity中Shader的XRay透视效果

二、实现原理

为什么 NdotL 可以得到中间亮,周围亮的的效果
urp 菲涅尔,Unity,unity,游戏引擎

我们可以由下图直观的感受到 N 与 L夹角越小,点积越接近(白色)1。越趋近90°,点积越接近0(黑色)

urp 菲涅尔,Unity,unity,游戏引擎


三、实现URP下的菲涅尔效果

我们这里用一个 BRP 下的Shader来修改为 URP 下的该效果

1、我们新建一个Shader,修改为最简

Shader "MyShader/URP/P3_2_4"
{
    Properties
    {
        
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

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

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };
            
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return 1;
            }
            ENDCG
        }
    }
}

  • 在SubShader的Tags中,告诉引擎这是URP下的Shader

“RenderPipeline” = “UniversalPipeline”

  • 替换代码块申明

CGPROGRAM -> HLSLPROGRAM
ENDCG -> ENDHLSL

  • 替换我们的引入库为HLSL常用的几个

#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”
#include “Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl”

2、获取世界空间下的顶点法线 N

  • 在应用程序传入顶点着色器的 Attributes(appdata)结构体 加入本地法线
struct Attributes
{
	float3 vertexOS : POSITION;
	float3 normalOS : NORMAL;
};
  • 在顶点着色器传入片元着色器的 Varyings(v2f)结构体 加入世界法线
struct Varyings
{
	float4 vertexCS : SV_POSITION;
	float3 normalWS : TEXCOORD0;
};
  • 在顶点着色器进行法线坐标转化

o.normalWS = TransformObjectToWorld(v.normalOS);

3、获取顶点指向摄像机的视线单位向量 L

要获取该向量,需要知道 摄像机的世界空间坐标 和 我们顶点的世界空间坐标

  1. 摄像机的世界空间坐标

_WorldSpaceCameraPos

  1. 顶点世界空间下的坐标
  • 在顶点着色器传入片元着色器的 Varyings(v2f)结构体 加入世界顶点坐标

float3 vertexWS : TEXCOORD1;

  • 在顶点着色器进行顶点坐标的空间转化

o.vertexWS = TransformObjectToWorld(v.vertexOS);

  • 我们在片元着色器输出看看效果
    urp 菲涅尔,Unity,unity,游戏引擎
  1. 用世界空间下的 摄像机坐标 减去 模型顶点坐标 得到 L

half3 L = normalize(_WorldSpaceCameraPos - i.vertexWS);

4、在片元着色器中,计算得到 NdotL 值

half NdotL = dot(N,L);

  • 我们输出看看效果
    urp 菲涅尔,Unity,unity,游戏引擎

5、用1 - NdotL 值得到菲尼尔效果

需要调节效果强弱的话,我们使用pow函数即可

return 1 - NdotL;

urp 菲涅尔,Unity,unity,游戏引擎文章来源地址https://www.toymoban.com/news/detail-785334.html


四、测试代码

//URP下的菲涅尔效果
Shader "MyShader/URP/P3_2_4"
{
    Properties
    {
        
    }
    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;
            };
            
            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
            {
                //菲涅尔效果 1 - dot(N,L)
                half3 N = i.normalWS;
                half3 L = normalize(_WorldSpaceCameraPos - i.vertexWS);
                half NdotL = dot(N,L);
                return 1 - NdotL;
            }
            ENDHLSL
        }
    }
}

到了这里,关于Unity中URP下的菲涅尔效果实现(URP下的法线和视线向量怎么获取)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【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】URP屏幕后处理UI模糊效果实现

     这里Canvas(1)设置为Overlay能渲染出指定UI高清,其他UI模糊,然而这做法非常不好,如果此时再打开UI 以及 关闭模糊效果 要将这些置顶UI 恢复到原本Canvas里,也就是要管理2套Canvas Shader代码实现模糊  1个Canvas和2个摄像机 主要以上内容,实际上就是因为Render Pass Event是只能Af

    2024年02月10日
    浏览(41)
  • Unity中URP下的线性雾

    在之前的文章中,我们实现了URP下的雾效支持。 Unity中URP下的添加雾效支持 在上一篇文章中,我们解析了 URP 下统一不同平台下的z值是怎么实现的 Unity中URP下统一不同平台下的z值 我们在这篇文章中,看一下Unity在URP下线性雾是怎么实现的。 主要是使用上一篇统一好的z值,来

    2024年01月19日
    浏览(36)
  • Unity中URP下的顶点偏移

    在上篇文章中,我们实现了URP下的半透明效果。 Unity中URP下的半透明效果实现 在这篇文章中,我们实现一下像鬼魂一样的顶点偏移效果。 在顶点着色器中,对模型本地空间坐标在转化成齐次裁剪坐标前,进行赋值修改 y = A sin(ωx + φ) + B v.vertexOS.z += sin(_Time.y); 这里用模型顶点

    2024年02月04日
    浏览(49)
  • Unity中URP下的SimpleLit顶点着色器

    在上一篇文章中,我们了解了URP下SimpleLit的整体框架。 Unity中URP下 SimpleLit框架 我们在这篇文章中,来了解一下URP下SimpleLit中,光照核心部分的顶点着色器干了什么,方便之后我们自定义自己的光照Shader。 因为被Unity封装的原因。所以,顶点着色器 和 片元着色器 主要是在这

    2024年01月17日
    浏览(42)
  • Unity中URP下的SimpleLit片元着色器

    在上篇文章中,我们了解了Unity中URP下SimpleLit中的顶点着色器。 Unity中URP下的SimpleLit顶点着色器 我们在这篇文章中,来了解一下Unity中URP下SimpleLit中的片元着色器。有助于我们之后写自己的光照Shader。 这里传入参数为 顶点着色器输出的Varyings结构体 返回结果用 out修饰来代替

    2024年01月20日
    浏览(34)
  • Unity中URP下的添加雾效支持

    我们使用之前的棋盘格作为测试Shader来添加雾效。 Unity中 URP 下的棋盘格Shader #pragma multi_compile_fog float fogCoord : TEXCOORD2; o.fogCoord = ComputeFogFactor(o.vertexCS.z); col.rgb = MixFog(col,i.fogCoord);

    2024年04月25日
    浏览(35)
  • Unity中URP下的SimpleLit的 Lambert漫反射计算

    在之前的文章中,我们已经知道了 SimpleLit 下的主光数据怎么获取。 Unity中URP下获取主灯信息 Unity中ShaderGraph下获取主灯 有了这些数据,我们就可以计算 Lambert漫反射 和 BlinnPhone高光反射 了。 我们在获取了主光信息后 Light mainLight = GetMainLight1(inputData, shadowMask, aoFactor); 就来到了

    2024年01月21日
    浏览(92)
  • Unity中URP下的 额外灯 逐像素光 和 逐顶点光

    在之前的文章中,我们了解了 主光相关的反射计算。 Unity中URP下的SimpleLit的 Lambert漫反射计算 Unity中URP下的SimpleLit的 BlinnPhong高光反射计算 在这篇文章中,我们来了解一下额外灯的 逐像素光 和 逐顶点光。 在片元着色器 #if defined(_ADDITIONAL_LIGHTS) outColor = 1; #else outColor = 0; #end

    2024年01月23日
    浏览(38)
  • 法线贴图可以实现什么样的3D效果

    在线工具推荐: 3D数字孪生场景编辑器  -  GLTF/GLB材质纹理编辑器  -  3D模型在线转换  -  Three.js AI自动纹理开发包  -  YOLO 虚幻合成数据生成器  -  三维模型预览图生成器  -  3D模型语义搜索引擎 在 3D 建模中,曲面由多边形表示。照明计算是基于这些多边形的几何形状执

    2024年02月03日
    浏览(57)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包