首页 > 其他分享 >Unity URP Shader之各向异性头发高光之KK高光模型

Unity URP Shader之各向异性头发高光之KK高光模型

时间:2023-01-06 10:12:38浏览次数:61  
标签:高光 KK Shader TdotH half3 ShiftMap half dir

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

 

关于各向异性头发高光,效果可参考:

 

 首先弄清以下知识点:

1. KK高光模型,即 Kajiya-Kay Model

 

传统的Phong高光模型使用 NdotH做为因子,这里采用 TsinH,即 sqrt(1 - TdotH * TdotH),注意这里是假设切线方向与发丝方向一致。

即高光公式改为如下:

half dirH = normalize(viewDir + lightDir);

half TdotH = dot(worldTangent, dirH);

half TsinH = sqrt(1 - TdotH * TdotH);

half3 specCol = pow(TsinH, _Gloss) * lightCol;

 

我们来用一个Sphere来做测试,由于sphere的切线方向是水平的,副法线方向是垂直分布的,所以这里我们用副法线方向来代替切线。

看下sphere的切线(绿色),副法线(红色),法线(蓝色)分布

 

 

修改高光公式之后效果如下

 

2. 这里还需要实现发丝的效果,即高光区域,使用如下图来对切线沿法线方向做扰动

 

具体公式如下,我们修改上面公式中的worldTangent值,即完整代码如下:

half shiftnoise = SAMPLE_TEXTURE2D(_ShiftMap, sampler_ShiftMap, uv);

half3 newWorldTanget = worldTangent + shiftnoise * worldNormal;

half dirH = normalize(viewDir + lightDir);

half TdotH = dot(newWorldTanget, dirH);

half TsinH = sqrt(1 - TdotH * TdotH);

half3 specCol = pow(TsinH, _Gloss) * lightCol;

最终效果如下:

 

shader代码如下:

 1 Shader "MyURP/Kerry/Lit/KKAniso"
 2 {
 3     Properties
 4     {
 5         _Shininess("Shininess",Range(0.01,1000)) = 1.0
 6         _ShiftOffset("_ShiftOffset",Range(-1,1)) = 0
 7         _ShiftMap("ShitfMap",2D) = "white"{}
 8         _FlowMap("_FlowMap",2D) = "gray"{}
 9     }
10     SubShader
11     {
12         Tags
13         {
14             "RenderType" = "Opaque"
15             "RenderPipeline" = "UniversalPipeline"
16         }
17         LOD 100
18 
19         Pass
20         {
21             Tags
22             {
23                 "LightMode" = "UniversalForward"
24             }
25             HLSLPROGRAM
26             #pragma vertex vert
27             #pragma fragment frag
28             #pragma multi_compile_fwdbase
29             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
30             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
31 
32             struct appdata
33             {
34                 float4 vertex : POSITION;
35                 float2 texcoord : TEXCOORD0;
36                 float3 normal  : NORMAL;
37                 float4 tangent : TANGENT;
38             };
39 
40             struct v2f
41             {
42                 float4 pos : SV_POSITION;
43                 float2 uv : TEXCOORD0;
44                 float3 normal_dir : TEXCOORD1;
45                 float3 tangent_dir : TEXCOORD2;
46                 float3 binormal_dir : TEXCOORD3;
47                 float3 pos_world : TEXCOORD4;
48             };
49 
50             TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
51             float4 _MainTex_ST;
52             float4 _LightColor0;
53             float _Shininess;
54             float _ShiftOffset;
55             TEXTURE2D(_ShiftMap); SAMPLER(sampler_ShiftMap);
56             float4 _ShiftMap_ST;
57             TEXTURE2D(_FlowMap); SAMPLER(sampler_FlowMap);
58 
59 
60             v2f vert(appdata v)
61             {
62                 v2f o;
63                 o.pos = TransformObjectToHClip(v.vertex.xyz);
64                 o.uv = v.texcoord;
65                 o.normal_dir = normalize(mul(float4(v.normal, 0.0), unity_WorldToObject).xyz);
66                 o.tangent_dir = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz, 0.0)).xyz);
67                 o.binormal_dir = normalize(cross(o.normal_dir, o.tangent_dir)) * v.tangent.w;
68                 o.pos_world = mul(unity_ObjectToWorld, v.vertex).xyz;
69                 return o;
70             }
71 
72             half4 frag(v2f i) : SV_Target
73             {
74                 Light mainLight = GetMainLight();
75                 half3 light_dir = mainLight.direction;
76                 half3 view_dir = GetWorldSpaceNormalizeViewDir(i.pos_world);
77                 half3 normal_dir = normalize(i.normal_dir);
78                 half3 tangent_dir = normalize(i.tangent_dir);
79                 half3 binormal_dir = normalize(i.binormal_dir);
80 
81                 half3 dirH = normalize(view_dir + light_dir);
82                 half2 uv_shift = i.uv * _ShiftMap_ST.xy + _ShiftMap_ST.zw;
83                 half shiftnoise = SAMPLE_TEXTURE2D(_ShiftMap, sampler_ShiftMap, uv_shift).r;
84                 half3 offsetBinormal = binormal_dir + (shiftnoise + _ShiftOffset) * normal_dir;
85                 half TdotH = dot(offsetBinormal, dirH);
86                 half sinTH = sqrt(1 - TdotH * TdotH);
87                 half3 specCol = pow(sinTH, _Shininess) * mainLight.color;
88 
89                 return half4(specCol, 1);
90             }
91             ENDHLSL
92         }
93     }
94     FallBack "Hidden/Universal Render Pipeline/FallbackError"
95 }

 

3. 双层高光

 

 

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

标签:高光,KK,Shader,TdotH,half3,ShiftMap,half,dir
From: https://www.cnblogs.com/jietian331/p/17029603.html

相关文章

  • R语言多元(多变量)GARCH :GO-GARCH、BEKK、DCC-GARCH和CCC-GARCH模型和可视化|附代码数据
    全文链接:http://tecdat.cn/?p=30647最近我们被客户要求撰写关于GARCH的研究报告,包括一些图形和统计输出。从Engle在1982发表自回归条件异方差(ARCH)模型的论文以来,金融......
  • Unity URP Shader之高级光照技术之SH
    首先声明以下素材和shader代码都来自Kerry佬,我只做整理和学习之用,写此随笔是为了做个笔记方便以后查阅。 SH,英文全称SphericalHarmonicsLighting,即球谐光照,主要用来模......
  • Unity URP Shader之高级光照技术之IBL
    首先声明以下素材和shader代码都来自Kerry佬,我只做整理和学习之用,写此随笔是为了做个笔记方便以后查阅。 IBL,英文全称ImageBasedLighting,即基于图像的照明,是一种通过......
  • UGUI之Mask切割图像shader应用
    在我之前的一篇文章写到使用Mask切割图像的方法。具体链接​​http://www.manew.com/thread-93954-1-1.html​​正如一些朋友所说上面这种方法把图放大之后确实存在有边缘出......
  • 告警日志中报错ORA-07445 kkqstcrf
    问题描述:数据库例行巡检时发现告警日志中报错ORA-07445kkqstcrf,如下所示:数据库:oracle11.2.0.1告警日志:SunDec2522:08:222022BeginautomaticSQLTuningAdvisorrun......
  • Unity URP Shader之用Matcap渲染天牛
    以下素材来自Kerry佬,关于Matcap技术,参考以下资料:shader如下:1Shader"MyURP/Kerry/URPMatcap"2{3Properties4{5_MainTex("MainTexture"......
  • Unity URP Shader之标准的BlinnPhong光照模型
    shader如下:1Shader"MyURP/Kerry/URPBlinnPhong"2{3Properties4{5_BaseMap("BaseMap",2D)="white"{}6_NormalMap(......
  • Unity shader cube纹理采样
    使用cube进行纹理采样,可以很方便的预览全景图,可以用立方体去显示全景图,而不必非得用球甚至还可以用更复杂的网格去贴全景图,只要保证网格的形状和全景图里的内容能对应上就......
  • 使用Akka、Kafka和ElasticSearch等构建分析引擎 -- good
    本文翻译自​​BuildingAnalyticsEngineUsingAkka,Kafka&ElasticSearch​​,已获得原作者SatendraKumar和网站授权。在这篇文章里,我将和大家分享一下我用Scala、Akka......
  • 使用Kk单节点安装KubeSphere和K8S
    1.安装之前要安装这些包。yum-yinstallsocatconntrackebtablesipset2.安装KubeSphere和K8S之前需要安装docker容器运行时wgethttps://mirrors.aliyun.com/docker......