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

文章目录

  • 前言
  • 一、实现思路
  • 二、实现原理
    • 我们可以由下图直观的感受到 N 与 L夹角越小,点积越接近(白色)1。越趋近90°,点积越接近0(黑色)
  • 三、实现URP下的菲涅尔效果
    • 1、我们新建一个Shader,修改为最简
    • 2、获取世界空间下的顶点法线 N
    • 3、获取顶点指向摄像机的视线单位向量 L
    • 4、在片元着色器中,计算得到 NdotL 值
    • 5、用1 - NdotL 值得到菲尼尔效果
  • 四、测试代码


前言

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


一、实现思路

Lambert光照模型公式:

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

  • 实现灯光照射中间亮 周围暗的效果,核心是dot(N,L)
    在这里插入图片描述

  • Unity中Shader的Lambert光照的实现

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

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

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

  • Unity中Shader的XRay透视效果

二、实现原理

为什么 NdotL 可以得到中间亮,周围亮的的效果
在这里插入图片描述

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

请添加图片描述


三、实现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);

  • 我们在片元着色器输出看看效果
    请添加图片描述
  1. 用世界空间下的 摄像机坐标 减去 模型顶点坐标 得到 L

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

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

half NdotL = dot(N,L);

  • 我们输出看看效果
    请添加图片描述

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

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

return 1 - NdotL;

请添加图片描述


四、测试代码

//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
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/253286.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

beebox靶场A1 low 命令注入通关教程(上)

一:html注入 get HTML注入,就是当用户进行输入时,服务器没有对用户输入的数据进行过滤或转义,导致所有输入均被返回前端,网页解析器会将这些数据当作html代码进行解析,这就导致一些恶意代码会被正常执行。 首先进行简…

lv12 交叉开发环境搭建 3

1 ubuntu网络环境配置 目的:让Ubuntu可以上外网,让开发板可以与ubuntu互通 2 tftp 服务器环境搭建 tftp(Trivial File Transfer Protocol)即简单文件传输协议 是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件 传输…

人工智能知识蒸馏:模型精简与迁移的奇妙之旅

导言 在人工智能领域,知识蒸馏作为一种模型精简和知识迁移的技术手段,逐渐成为提高模型效能和适应更广泛场景的关键工具。知识蒸馏是近年来在深度学习领域备受瞩目的技术,其通过将大模型的知识传递给小模型,旨在实现模型的轻量化与…

实验报告九、使用枚举法验证6174猜想

一、实验目的: 1、了解6174猜想的内容。 2、熟练使用选择结构和循环结构。 3、了解标准库itertools中combinations()函数的用法。 4、熟练使用字符串的join(方法。 5、熟练使用内置函数int()、str()、 sorted()。 二、实验内容: 1955…

使用邮件群发平台,轻松实现高效沟通的4大优势!

新媒体带动着众多线上平台的发展,使得流量为企业带来了可观的营收。但是,随着短视频市场的饱和,想要再次获得初始时的流量就变得越发困难。在这个时候,企业不妨将眼光往邮件群发这个传统的营销方式上倾斜,特别是出海、…

HTTP 403错误:禁止访问,如何解除

“HTTP 403错误,禁止访问!”这句话是不是听起来就像是在告诉你:“嘿,你没有权限进这个房间!”没错,这就是你尝试访问某个网站或资源时可能会遇到的问题。别急,这里有一份秘籍,教你如…

【设计模式-2.4】创建型——抽象工厂模式

说明:本文介绍设计模式中,创建型设计模式的抽象工厂设计模式; 工厂模式的问题 在【设计模式-2.2】创建型——简单工厂和工厂模式这篇博文中,介绍过飞机大战游戏里,使用简单工厂和工厂模式来创建坦克、飞机、Boss对象…

解读Amazon Q | 用AI聊天机器人连接你与未来的无限可能

授权声明:本篇文章授权活动官方亚马逊云科技文章转发、改写权,包括不限于在 亚马逊云科技开发者社区, 知乎,自媒体平台,第三方开发者媒体等亚马逊云科技官方渠道 在美国当地时间11月28日,亚马逊云科技在拉斯维加斯举办…

vue中实现使用相框点击拍照,canvas进行前端图片合并下载

拍照和相框合成,下载图片dome 一、canvas介绍 Canvas是一个HTML5元素,它提供了一个用于在网页上绘制图形、图像和动画的2D渲染上下文。Canvas可以用于创建各种图形,如线条、矩形、圆形、文本等,并且可以通过JavaScript进行编程操作。 Canvas元素本身是一个矩形框,可以通…

【JavaScript】闭包的理解

闭包是指在一个函数内部创建另一个函数,并且内部函数可以访问外部函数的变量、参数以及其他内部函数,即使外部函数已经执行完毕。这种机制使得内部函数保留了对外部作用域的引用,即使外部作用域已经不再活跃。 为什么闭包重要? 闭…

Python之初识类与对象

类的概念与定义 在生活中,我们走在路边,看到一辆车,大脑中首先想到的是“这是一辆车,然后才是这是一辆什么牌子的车”,在这里,我们就用到了编程中的类的概念。同样的,看到一条小狗,…

php 使用box打包

1.安装box 2.检查是否安装成功 3.查看路径,把路径添加到环境变量,方便使用 4.php项目根目录增加box.json配置文件 5.运行命令生成。这个是在cmd中运行的,记得切换到php源码目录 6.使用 php FastAdmin.phar运行。 说明:如果是常驻…

LVS-DR模式部署

实验准备: 节点服务器 192.168.116.20 #web1 192.168.116.30 #web2 1.部署NFS共享存储 2.部署Web节点服务器 将两台服务器的网关注释掉 #重启网卡 systemctl restart network 修改节点服务器的内核参数|vim /etc/sysctl.conf net.ipv4.conf.lo.arp_ign…

WPF——命令commond的实现方法

命令commond的实现方法 属性通知的方式 鼠标监听绑定事件 行为:可以传递界面控件的参数 第一种: 第二种: 附加属性 propa:附加属性快捷方式

大厂痴迷DDD:从高德portal重构,看DDD的巨大价值

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中,最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题: 谈谈你的DDD落地经验? 谈谈你对DDD的理解&#x…

Vim入门

Vim使用入门 1.Vim编辑器的三种常用模式 一般模式:刚打开文件是它,从编辑模式按“ESC”退回的模式也是它。可以执行各种编辑操作,如移动光标、复制、粘贴、删除、查找替换等 ; 编辑模式:在一般模式下按下 i、I、a、A、o、O 等键…

JavaScript 事件冒泡与捕获机制 --- 带动态图理解

&#xff08;1&#xff09;.事件捕获 从根元素往上传递 --- ---&#xff08;由外到内&#xff09; &#xff08;2&#xff09;.事件冒泡 从元素传递到它的根源素 --- --- &#xff08;由内到外&#xff09; 代码&#xff1a; <!DOCTYPE html> <html lang"en&q…

Linux(操作系统)面经——part 1(持续更新中......)

1、说一说常用的 Linux 命令 mkdir创建文件夹&#xff0c;touch创建文件&#xff0c;mv移动文件内容或改名 rm-r 文件名&#xff1a;删除文件 cp拷贝&#xff1a;cp 文件1 文件2&#xff0c;cp-r跨目录拷贝 cp-r 路径1 路径2 vi 插入 &#xff1a;wqb保存退出 :q!强制退出…

k8s - container

1、容器的生命周期&#xff1a; (1) 简介&#xff1a; Kubernetes 会跟踪 Pod 中每个容器的状态&#xff0c;就像它跟踪 Pod 总体上的阶段一样。 可以使用容器生命周期回调&#xff0c;在容器生命周期中的特定状态点触发事件。 ● 容器生命周期回调&#xff1a; 在容器的生…

【员工工资册】————大一期末答辩近满分作业分享

前言 大家好吖&#xff0c;欢迎来到 YY 滴项目系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C语言的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; PS&#xff1a;以下内容是部分展示&am…