Unity中URP下的菲涅尔效果实现(个性化修改)

2023-12-18 11:28

本文主要是介绍Unity中URP下的菲涅尔效果实现(个性化修改),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、我们修正一下上篇文章中,可能遗留的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}}
}

最终效果

请添加图片描述

这篇关于Unity中URP下的菲涅尔效果实现(个性化修改)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/508205

相关文章

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

MySQL双主搭建+keepalived高可用的实现

《MySQL双主搭建+keepalived高可用的实现》本文主要介绍了MySQL双主搭建+keepalived高可用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、测试环境准备二、主从搭建1.创建复制用户2.创建复制关系3.开启复制,确认复制是否成功4.同

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

opencv图像处理之指纹验证的实现

《opencv图像处理之指纹验证的实现》本文主要介绍了opencv图像处理之指纹验证的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、简介二、具体案例实现1. 图像显示函数2. 指纹验证函数3. 主函数4、运行结果三、总结一、