当前位置: 首页 > article >正文

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

              

     


http://www.kler.cn/a/350489.html

相关文章:

  • 云上贵州多彩宝荣获仓颉社区先锋应用奖 | 助力数字政务新突破
  • 使用docker部署mysql和tomcat服务器发现的问题整理
  • 详解构造函数和析构函数
  • 【数据分享】1929-2024年全球站点的逐日平均气温数据(Shp\Excel\免费获取)
  • VIVADO FIFO (同步和异步) IP 核详细使用配置步骤
  • vben5 admin ant design vue如何使用时间范围组件RangePicker
  • C# Attribute 介绍
  • 微信小程序后台搭建—node+mysql
  • 农业机器人综述:技术现状、应用场景及未来展望
  • YOLOv8改进 - 注意力篇 - 引入ShuffleAttention注意力机制
  • 小米电机与STM32——CAN通信
  • 2024年第九届数维杯大学生数学建模挑战赛赛题和数维杯国际数学建模 LaTeX 模板
  • Android 未来可能支持 Linux 应用,Linux 终端可能登陆 Android 平台
  • 绕过MIME-Type验证
  • 算法知识点————【DFS】【BFS】【树】【图】
  • 发送URL请求中的问题记录
  • [LeetCode] 844. 比较含退格的字符串
  • ubuntu22.04安装mysql5.7
  • 综合小案例
  • foxy moveit2 小鱼
  • 珠海自闭症寄宿学校:打造温馨家庭般的学习氛围
  • mongodb的相关关键字说明
  • 记录使用datagrip备份数据库信息
  • 基于Java微信小程序的学生签到系统的详细设计和实现(源码+lw+部署文档+讲解等)
  • 【SPIE独立出版】第四届计算机、信息工程与电子材料国际学术会议 (CTIEEM 2024,2024年11月15-17日 )
  • CrossSim安装教程