首页 > 其他分享 >Unity URP Shader之高级光照技术之IBL

Unity URP Shader之高级光照技术之IBL

时间:2023-01-05 15:36:08浏览次数:55  
标签:IBL color float Shader half3 Unity world dir float3

首先声明以下素材和shader代码都来自Kerry佬,我只做整理和学习之用,写此随笔是为了做个笔记方便以后查阅。

 

IBL,英文全称Image Based Lighting,即基于图像的照明,是一种通过采样图片从而模拟出光照的技术。

IBL不需要在shader中进行直接光源的光照计算,而是将周围环境提前做成一个CubeMap,或者用反射探针在unity中烘焙好。

采样CubeMap时,可根据粗糙度贴图等生成动态mipmap值,根据mipmap值来采样CubeMap,从而模拟出如金属表面有污渍的效果。

IBL镜面反射和漫反射都可模拟,两者区别在于:

1. 如下图,镜面反射选择Specular,漫反射选择Diffuse。

 2. 当采样CubeMap时,镜面反射还是用视角方向基于法线的反射向量来采样,漫反射则可使用法线方向来采样。

 

shader如下:

  1 Shader "MyURP/Kerry/IBL/URPIBLProbe"
  2 {
  3     Properties
  4     {
  5         //_MainTex ("Texture", 2D) = "white" {}
  6         _CubeMap("Cube Map",Cube) = "white"{}
  7         _Tint("Tint",Color) = (1,1,1,1)
  8         _Expose("Expose",Float) = 1.0
  9         _Rotate("Rotate",Range(0,360)) = 0
 10         _NormalMap("Normal Map",2D) = "bump"{}
 11         _NormalIntensity("Normal Intensity",Float) = 1.0
 12         _AOMap("AO Map",2D) = "white"{}
 13         _AOAdjust("AO Adjust",Range(0,1)) = 1
 14         _RoughnessMap("Roughness Map",2D) = "black"{}
 15         _RoughnessContrast("Roughness Contrast",Range(0.01,10)) = 1
 16         _RoughnessBrightness("Roughness Brightness",Float) = 1
 17         _RoughnessMin("Rough Min",Range(0,1)) = 0
 18         _RoughnessMax("Rough Max",Range(0,1)) = 1
 19     }
 20     SubShader
 21     {
 22         Tags
 23         {
 24             "RenderType" = "Opaque"
 25             "RenderPipeling" = "UniversalPipeline"
 26         }
 27         LOD 100
 28 
 29         Pass
 30         {
 31             HLSLPROGRAM
 32             #pragma vertex vert
 33             #pragma fragment frag
 34             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
 35             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
 36 
 37             struct appdata
 38             {
 39                 float4 vertex : POSITION;
 40                 float2 texcoord : TEXCOORD0;
 41                 float3 normal : NORMAL;
 42                 float4 tangent : TANGENT;
 43             };
 44 
 45             struct v2f
 46             {
 47                 float2 uv : TEXCOORD0;
 48                 float4 pos : SV_POSITION;
 49                 float3 normal_world : TEXCOORD1;
 50                 float3 pos_world : TEXCOORD2;
 51                 float3 tangent_world : TEXCOORD3;
 52                 float3 binormal_world : TEXCOORD4;
 53             };
 54 
 55             //sampler2D _MainTex;
 56             //float4 _MainTex_ST;
 57             TEXTURECUBE(_CubeMap); SAMPLER(sampler_CubeMap);
 58             float4 _Tint;
 59             float _Expose;
 60 
 61             TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap);
 62             float4 _NormalMap_ST;
 63             float _NormalIntensity;
 64             TEXTURE2D(_AOMap); SAMPLER(sampler_AOMap);
 65             float _AOAdjust;
 66             float _Rotate;
 67             float _Roughness;
 68             TEXTURE2D(_RoughnessMap); SAMPLER(sampler_RoughnessMap);
 69             float _RoughnessContrast;
 70             float _RoughnessBrightness;
 71             float _RoughnessMin;
 72             float _RoughnessMax;
 73 
 74             float3 RotateAround(float degree, float3 target)
 75             {
 76                 float rad = degree * PI / 180;
 77                 float2x2 m_rotate = float2x2(cos(rad), -sin(rad),
 78                     sin(rad), cos(rad));
 79                 float2 dir_rotate = mul(m_rotate, target.xz);
 80                 target = float3(dir_rotate.x, target.y, dir_rotate.y);
 81                 return target;
 82             }
 83 
 84             inline float3 ACES_Tonemapping(float3 x)
 85             {
 86                 float a = 2.51f;
 87                 float b = 0.03f;
 88                 float c = 2.43f;
 89                 float d = 0.59f;
 90                 float e = 0.14f;
 91                 float3 encode_color = saturate((x*(a*x + b)) / (x*(c*x + d) + e));
 92                 return encode_color;
 93             };
 94 
 95             v2f vert (appdata v)
 96             {
 97                 v2f o;
 98                 o.pos = TransformObjectToHClip(v.vertex.xyz);
 99                 o.uv = v.texcoord * _NormalMap_ST.xy + _NormalMap_ST.zw;
100                 o.pos_world = mul(unity_ObjectToWorld, v.vertex).xyz;
101                 o.normal_world = normalize(mul(float4(v.normal, 0.0), unity_WorldToObject).xyz);
102                 o.tangent_world = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz, 0.0)).xyz);
103                 o.binormal_world = normalize(cross(o.normal_world, o.tangent_world)) * v.tangent.w;
104                 return o;
105             }
106             
107             half4 frag (v2f i) : SV_Target
108             {
109                 half3 normal_dir = normalize(i.normal_world);
110                 half3 normaldata = UnpackNormal(SAMPLE_TEXTURE2D(_NormalMap,sampler_NormalMap,i.uv));
111                 normaldata.xy = normaldata.xy* _NormalIntensity;
112                 half3 tangent_dir = normalize(i.tangent_world);
113                 half3 binormal_dir = normalize(i.binormal_world);
114                 normal_dir = normalize(tangent_dir * normaldata.x + binormal_dir * normaldata.y + normal_dir * normaldata.z);
115 
116                 half ao = SAMPLE_TEXTURE2D(_AOMap, sampler_AOMap, i.uv).r;
117                 ao = lerp(1.0,ao, _AOAdjust);
118                 half3 view_dir = GetWorldSpaceNormalizeViewDir(i.pos_world);
119                 half3 reflect_dir = reflect(-view_dir, normal_dir);
120 
121                 reflect_dir = RotateAround(_Rotate, reflect_dir);
122                 
123                 float roughness = SAMPLE_TEXTURE2D(_RoughnessMap, sampler_RoughnessMap, i.uv).r;
124                 roughness = saturate(pow(roughness, _RoughnessContrast) * _RoughnessBrightness);
125                 roughness = lerp(_RoughnessMin, _RoughnessMax, roughness);
126                 roughness = roughness * (1.7 - 0.7 * roughness);
127                 float mip_level = roughness * 6.0;
128                 
129                 half4 color_cubemap = SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, reflect_dir, mip_level);
130                 half3 env_color = DecodeHDREnvironment(color_cubemap, unity_SpecCube0_HDR);//确保在移动端能拿到HDR信息
131                 half3 final_color = env_color * ao * _Tint.rgb * _Tint.rgb * _Expose;
132                 //half3 final_color_linear = pow(final_color, 2.2);
133                 //final_color = ACES_Tonemapping(final_color_linear);
134                 //half3 final_color_gamma = pow(final_color, 1.0 / 2.2);
135                 
136                 return float4(final_color, 1.0);
137             }
138             ENDHLSL
139         }
140     }
141     FallBack "Hidden/Universal Render Pipeline/FallbackError"
142 }

 

效果如下:

 

转载请注明出处:https://www.cnblogs.com/jietian331/p/17027723.html

标签:IBL,color,float,Shader,half3,Unity,world,dir,float3
From: https://www.cnblogs.com/jietian331/p/17027723.html

相关文章

  • UGUI之Mask切割图像shader应用
    在我之前的一篇文章写到使用Mask切割图像的方法。具体链接​​http://www.manew.com/thread-93954-1-1.html​​正如一些朋友所说上面这种方法把图放大之后确实存在有边缘出......
  • unity3d异步加载场景
    ​​unity3d​​​​loading界面​​​​异步加载​​​​进度条​​根据宣雨松前辈的教程来做的,因为我用到的场景不是在游戏里的那种(本人做增强现实的,完全把unity拿来做应......
  • [unity3D插件]Unity界面插件NGUI核…
    本文转载于互联网,是一个比较经典帖子,特来分享:UICamera-可以添加到任何相机,包含事件系统.UICamera是每个UI的重要组成部分.它负责发送Camera中所有NGUI的活动.如果场景中......
  • 圣诞树拼图游戏unity制作
    2022年圣诞节到来啦,很高兴这次我们又能一起度过~一、前言提示:使用unity来制作一个拼图游戏,图片便是圣诞树。二、创意名圣诞树拼图游戏三、效果展示圣诞树拼图游戏最终效果。......
  • unity和VS2019联调问题解决
    以前使用VS2015和17的时候联调的时候是可以附加到unity进行联调的,今天用的2019发现不可以了。研究了一下是少装了一个插件。装上插件就解决了。过程如下:当前使用VS版本2019......
  • unity如何检测第一次打开APP
    一般软件或app都会在第一次有指引和提示功能,例如第一次打开一个app要出现指引,第二次及以后就不会出现了。这个功能在​​unity​​里如何实现呢?下面用实例讲一下我的方法。......
  • Unity小地图Minimap制作全面功能介绍篇
    本系列文章将讲述如何制作小地图。功能如下:  小地图的局部放大地图,缩小功能。小地图展开成为大地图,以及与大地图的互相切换  大地图的人物图标跟随角色旋转和移动 ......
  • Unity游戏副本地图点击图标移动功能
    本篇讲相同的功能即:点击地图中的一个位置,让图标瞬间移动到点击位置,同时3D场景中人物也可以抵达场景中对应的点击位置。如图:操作方法和之前一样:找到大地图的渲染的Rawimage。......
  • unity3D实现镜头拉近拉远及视角旋转
    镜头拉近拉远的代码(无限拉远拉近) 代码如下: if(Input.GetAxis("MouseScrollWheel")!=0){this.gameObject.transform.Translate(newVector3(0,0,Input.GetAxis("Mouse......
  • unity读取Excel
    使用unity5.6的和Excel是2016版本。新建工程,新建文件夹Plugins,然后导入两个dll,一个是EXCEL一个system.Data。  读取脚本如下:usingSystem.Collections.Generic;usingUnit......