Unity URP shader ———魔系符文宝石是如何练成的

各位同学大家好  

       我已经很久没有没有写教程了,最近项目比较忙。各种加班各种带小孩儿,不过,老师一有机会也在给尽可能服务大家,今天来一个硬菜:移动端高效魔系符文如何制作,国庆起来,老师抽了点儿时间做了一个宝石模型和贴图:

       老规矩,先看效果:

           

Unity URP Shader——魔系符文宝石是如何练成的

实现原理:

         1:菲尼尔实现边缘光,

               菲尼尔共公式:Fresnel =(1-dot (v,n))^power  ;

                        v  : ViewDir            n: normalWorld 

        2:模拟反射

              因为移动端处理,所以我们做模拟,不做真实的,大致原理是:

               取一张贴图*2次菲尼尔运算。最后去控制强度和颜色,实现我们想要的效果。 

     

 half4 Reflect =reflect * saturate(XionmgMaoWuDao_Fresnel(normalWorld,viewDir,3)*XionmgMaoWuDao_Fresnel(normalWorld,viewDir,3)) *_ReflectIntensity*_ReflectColor;

       3:模拟宝石内部效果

            UV计算: 宝石是在不同的视角下观看宝石,会看见 视乎宝石里面的画面与镜子相同,都是无穷大。那么计算机科学也是同样的原理,也是从观察角度去看,所以UV的计算方式如下:

           视角方向的(XY方向)-原点的XY方向,然后再做模型的Tiling运算。最后再计算出模型法线在世界空间中的XY方向  。加在一起实现视觉错觉运算。

        

   half2 InsideUV = (viewDir.xy - float3 (0,0,0).xy)*_InsideUvTiling.xy+_InsideUvTiling.zw;
			          InsideUV+= normalWorld.xy * _InsideUvIntensity ;

 

最终代码如下:

 

//熊猫悟道
Shader "XiongMaoWuDao/XiongMaoLaoShi_Gem"
{
    Properties
    {
	    _normalPaner ("normal Panner",vector) =(0,0,0,0)
        [MainColor] _BaseColor("BaseColor", Color) = (1,1,1,1)
		_ReflectColor ("Reflect Color ",Color) = (1,1,1,1)
		[HDR]_RimColor ("Rim Color" ,Color)= (1,1,1,1)
		_EimissionMap ("Eimiss Map",2D) = "white" {}
		_ReflectIntensity ("Reflect Intensity",float) =1
		_InsideUvTiling ("Inside UV Tiling" , vector) =(1,1,1,1)
		_InsideUvIntensity ("Inside Uv Intensity" ,float) = 1
		_InsideMap ("Inside Map",2D)="white"{}    
		
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalRenderPipeline" "Queue"="Geometry"}

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes
            {
                float4 positionOS   : POSITION;
				half3 normal        :NORMAL ;
                half2 uv           : TEXCOORD0;
            };

            struct Varyings
            {
                half2 uv           : TEXCOORD0;
                float4 positionHCS  : SV_POSITION;
				half3  viewDir      :TEXCOORD1;
				half3  normalWorld  :TEXCOORD2 ;
            };

            TEXTURE2D(_EimissionMap);
            SAMPLER(sampler_EimissionMap);
			TEXTURE2D(_InsideMap);
            SAMPLER(sampler_InsideMap);

            CBUFFER_START(UnityPerMaterial)
            float4 _EimissionMap_ST;
            half4 _RimColor;
			half3 _normalPaner;
			half  _ReflectIntensity;
			half4 _InsideUvTiling;
			half  _InsideUvIntensity;
			half4 _InsideMap_ST;
			half4 _BaseColor;
			half4 _ReflectColor;
            CBUFFER_END

			//宝石菲尼尔反射
			half XionmgMaoWuDao_Fresnel( half3 normal ,half3 viewDir ,half power)
			{
			//菲尼尔公式: (1-dot (v,n))^power ;
			return pow( 1.0- saturate(dot(normal,viewDir).x) ,power);
			}

            Varyings vert(Attributes v)
            {
                Varyings o;
				half3 posWS = TransformObjectToWorld (v.positionOS.xyz);
                o.positionHCS = TransformObjectToHClip(v.positionOS.xyz);
				o.normalWorld = TransformObjectToWorldNormal (v.normal +_normalPaner);
				o.viewDir  =GetWorldSpaceNormalizeViewDir(posWS);
                o.uv = TRANSFORM_TEX(v.uv, _EimissionMap);
                return o;
            }

            half4 frag(Varyings i) : SV_Target
            {
			   //初始化数据
			   half3 normalWorld = normalize (i.normalWorld);
			   half3 viewDir = normalize (i.viewDir);
			   //DIFFUSE
			   half4 Emiss = SAMPLE_TEXTURE2D(_EimissionMap, sampler_EimissionMap, i.uv);
			   half4 DiffuseA = (XionmgMaoWuDao_Fresnel(normalWorld,viewDir,3)+Emiss.r)*_RimColor;
			   //reflect
			   half reflect = SAMPLE_TEXTURE2D(_EimissionMap, sampler_EimissionMap, normalWorld.xy).g;
			   half4 Reflect =reflect * saturate(XionmgMaoWuDao_Fresnel(normalWorld,viewDir,3)*XionmgMaoWuDao_Fresnel(normalWorld,viewDir,3)) *_ReflectIntensity*_ReflectColor;
			   //Inside
			   half2 InsideUV = (viewDir.xy - float3 (0,0,0).xy)*_InsideUvTiling.xy+_InsideUvTiling.zw;
			          InsideUV+= normalWorld.xy * _InsideUvIntensity ;
		       half4 InsideMap = SAMPLE_TEXTURE2D(_InsideMap, sampler_InsideMap, InsideUV);
			   half4 totalColor = (DiffuseA+InsideMap)*_BaseColor + Reflect ;
                return totalColor;
            }
            ENDHLSL
        }
    }
}

              

     

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

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

相关文章

六西格玛设计DFSS方法论在消费级无人机设计中的应用——张驰咨询

本文基于六西格玛设计方法论,对消费级无人机的设计流程进行系统化研究,探讨如何通过六西格玛设计的理念、工具和方法提升无人机产品的设计质量和市场竞争力。文章从市场定位、客户需求分析出发,深入到关键KPI指标的制定,并逐步阐述…

vulnhub-Web Developer 1靶机

vulnhub:Web Developer: 1 ~ VulnHub 导入靶机,放在kali同网段,扫描 靶机在192.168.114.129,扫描端口 有网站服务,访问 没什么东西,扫目录 真不少,访问一下,也只是一些普通的Wordpr…

滑雪——记忆化搜索

题目 代码 //#pragma GCC optimize(3)#include <bits/stdc.h> const int N 310; using namespace std; int dx[4] {-1, 0, 1, 0}, dy[4] {0, 1, 0, -1}; int ans; int g[N][N]; int r, c; int f[N][N]; int dfs(int x, int y) {if(~f[x][y]) return f[x][y];f[x][y] …

【JavaSE基础】Java 变量

为什么需要变量 变量是程序的基本组成单位 class Test{public static void main(String[] args){int a 1; //定义一个变量&#xff0c;类型为int&#xff0c;变量名为a&#xff0c;并赋值为1int b 3; //定义另一个变量&#xff0c;类型为int&#xff0c;变量名为b&#xff0…

2-120 基于matlab的滑动平均滤波下通过幅度谱最大值方法估计太阳黑子的周期

基于matlab的滑动平均滤波下通过幅度谱最大值方法估计太阳黑子的周期。具体步骤为&#xff1a;1&#xff09;在Matlab 环境下读取太阳黑子数目序列&#xff0c;并绘制其时域波形&#xff1b; 2&#xff09;采用离散时间卷积计算方法对太阳黑子数据序列进行滑动平均滤波&#xf…

vue后台管理系统从0到1搭建(4)各组件的搭建

文章目录 vue后台管理系统从0到1搭建&#xff08;4&#xff09;各组件的搭建Main.vue 组件的初构 vue后台管理系统从0到1搭建&#xff08;4&#xff09;各组件的搭建 Main.vue 组件的初构 根据我们的效果来看&#xff0c;分析一下&#xff0c;我们把左边的区域分为一个组件&am…

前端的全栈之路:基于 Vue3 + Nest.js 全栈开发的后台应用

☘️ 项目简介 Vue3 Admin 是一个前端基于 Soybean Admin 二次开发&#xff0c;后端基于 Nest.js 的全栈后台应用&#xff0c;适合学习全栈开发的同学参考学习。 &#x1f341; 前端技术栈&#xff1a; Vue3.5、Ant Design Vue、UnoCSS、Pinia &#x1f341; 后端技术栈&…

【浏览器】如何正确使用Microsoft Edge

1、清理主页广告 如今的Microsoft Edge 浏览器 主页太乱了&#xff0c;各种广告推送&#xff0c;点右上角⚙️设置&#xff0c;把快速链接、网站导航、信息提要、背景等全部关闭。这样你就能得到一个超级清爽的主页。 网站导航       关闭 …

线程基础学习

线程的实现 通过实现Runnable接口的方式&#xff0c;实现其中的run方法。继承Thread类&#xff0c;然后重写其中的run方法。通过线程池创建线程&#xff0c;默认采用DefaultThreadFactory。有返回值的callable&#xff0c;实现callable接口&#xff0c;实行call方法。 本质上…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-13

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-13 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-13目录1. The Cognitive Capabilities of Generative AI: A Comparative Analysis with Human Benchmarks2. WALL-E: World Alig…

动态规划的优化与高级应用

姊妹篇&#xff1a; 动态规划基础与经典问题-CSDN博客 贪心算法&#xff1a;原理、应用与优化_最优解-CSDN博客​​​​​​贪心算法&#xff1a;原理、应用与优化_最优解-CSDN博客 一、动态规划的优化策 动态规划在提高时间效率的同时&#xff0c;往往会占用较多的空间。因…

Unity3d折叠Inspector中的变量

InspectorFoldoutGroup插件 [Pixeye.Unity.Foldout("【曲线图】")] public BrokenLineUpDownGraph aimStabilityGraph;[Pixeye.Unity.Foldout("【曲线图】")] public BrokenLineUpGraph aimDensityGraph;[Pixeye.Unity.Foldout("【曲线图】")] p…

Xilinx远程固件升级(二)——STARTUPE2原语的使用

通过&#xff08;一&#xff09;可以看出&#xff0c;对于远程固件升级实际上是通过调用flash不同区域的bit实现&#xff0c;通过golden image和update image共同保障了系统的稳定性。在项目中如果将flash的时钟直接绑定FPGA后进行约束&#xff0c;在综合编译时是无法通过的。这…

优先算法1--双指针

“一念既出&#xff0c;万山无阻。”加油陌生人&#xff01; 目录 1.双指针--移动零 2.双指针-复写零 ok&#xff0c;首先在学习之前&#xff0c;为了方便大家后面的学习&#xff0c;我们这里需要补充一个知识点&#xff0c;我这里所谓的指针&#xff0c;不是之前学习的带有…

【原创】Android Studio 中安装大模型辅助编码插件:通义灵码

在 Android Studio 中内置了 Ginimi 预览版&#xff0c;但需要“加速器”才可使用。 在国内有平替的软件同样可以使用&#xff0c;比如 阿里的通义灵码&#xff0c;智谱的CodeGeeX等&#xff0c;从功能和使用上来说都是大同小异。 这里我们以通义灵码为例来讲解其安装和使用 通…

《机器学习与数据挖掘综合实践》实训课程教学解决方案

一、引言 随着信息技术的飞速发展&#xff0c;人工智能已成为推动社会进步的重要力量。作为人工智能的核心技术之一&#xff0c;机器学习与数据挖掘在各行各业的应用日益广泛。本方案旨在通过系统的理论教学、丰富的实践案例和先进的实训平台&#xff0c;帮助学生掌握机器学习…

selenium-Alert类用于操作提示框/确认弹框(4)

之前文章我们提到&#xff0c;在webdriver.WebDriver类有一个switch_to方法&#xff0c;通过switch_to.alert()可以返回Alert对象&#xff0c;而Alert对象主要用于网页中弹出的提示框/确认框/文本输入框的确认或者取消等动作。 Alert介绍 当在页面定位到提示框/确认框/文本录入…

Vulnhub靶场案例渗透[7]- DC7

文章目录 1. 靶场搭建2. 信息收集2.1 确定靶机ip2.2 服务信息收集2.3 社工信息收集 3. 提权 1. 靶场搭建 靶场源地址 检验下载文件的检验码&#xff0c;对比没问题使用vmware打开 # windwos 命令 Get-FileHash <filePath> -Algorithm MD5 # linux md5sum filepath2. 信…

计算机网络(以Linux讲解)

计算机网络 网络协议初识协议分层OSI七层模型TCP/IP五层模型--初识 网络中的地址管理IP地址MAC地址 网络传输基本流程网络编程套接字预备知识网络字节序socket编程UDP socketTCP socket地址转换函数Jsoncpp 进程间关系与守护进程进程组会话控制终端作业控制守护进程 网络命令TC…

线性代数 行列式

一、行列式 1、定义 一个数学概念&#xff0c;主要用于 线性代数中&#xff0c;它是一个可以从方阵&#xff08;即行数和列数相等的矩阵&#xff09;形成的一个标量&#xff08;即一个单一的数值&#xff09; 2、二阶行列式 &#xff0c;像这样将一个式子收缩称为一个 2*2 的…