222 lines
11 KiB
Plaintext
222 lines
11 KiB
Plaintext
|
|
Shader "Unlit/ShinShader"
|
|||
|
|
{
|
|||
|
|
Properties
|
|||
|
|
{
|
|||
|
|
_MainTex ("Texture", 2D) = "white" {}
|
|||
|
|
_SSSLut("SSSLut",2D)="white"{}
|
|||
|
|
|
|||
|
|
_KelemenLUT("KelemenLUT",2D)="white"{}
|
|||
|
|
_Roughness0("Roughness0",float)=0.1
|
|||
|
|
_Roughness1("Roughness1",float)=0.8
|
|||
|
|
|
|||
|
|
_Normal("Normal",2D)="bump"{}
|
|||
|
|
_NormalScale("NormalScale",float)=1
|
|||
|
|
_DetailNormal("DetailNormal",2D)="bump"{}
|
|||
|
|
_DetailNormalScale("DetailNormalScale",float)=1
|
|||
|
|
_NormalBlend("NormalBlend",range(0,1))=0.5
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
SubShader
|
|||
|
|
{
|
|||
|
|
Tags { "RenderType"="Opaque" }
|
|||
|
|
LOD 100
|
|||
|
|
|
|||
|
|
Pass
|
|||
|
|
{
|
|||
|
|
HLSLPROGRAM
|
|||
|
|
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS //接受主光源阴影
|
|||
|
|
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE //投射主光源的阴影
|
|||
|
|
#pragma multi_compile _ _SHADOWS_SOFT //软阴影
|
|||
|
|
#pragma multi_compile _ _ADDITIONAL_LIGHTS //附加光源
|
|||
|
|
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
|
|||
|
|
#pragma shader_feature _ALPHATEST_ON
|
|||
|
|
#pragma vertex vert
|
|||
|
|
#pragma fragment frag
|
|||
|
|
|
|||
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|||
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
|||
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
|
|||
|
|
//#include "UnityCG.cginc"
|
|||
|
|
//#include "Lighting.cginc"
|
|||
|
|
//#include "AutoLight.cginc"
|
|||
|
|
struct appdata
|
|||
|
|
{
|
|||
|
|
float4 vertex : POSITION;
|
|||
|
|
float2 uv : TEXCOORD0;
|
|||
|
|
float3 normal:NORMAL;
|
|||
|
|
float4 tangent:TANGENT;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
struct v2f
|
|||
|
|
{
|
|||
|
|
float2 uv : TEXCOORD0;
|
|||
|
|
float4 vertex : SV_POSITION;
|
|||
|
|
float3 worldNormal:TEXCOORD1;
|
|||
|
|
float3 worldPos:TEXCOORD2;
|
|||
|
|
float3 TtW0:TEXCOORD3;
|
|||
|
|
float3 TtW1:TEXCOORD4;
|
|||
|
|
float3 TtW2:TEXCOORD5;
|
|||
|
|
float4 shadow:TEXCOORD6;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
|
|||
|
|
float4 _MainTex_ST;
|
|||
|
|
float3 _SSSColor;
|
|||
|
|
float _SSSY;
|
|||
|
|
TEXTURE2D(_SSSLut);SAMPLER(sampler_SSSLut);
|
|||
|
|
TEXTURE2D(_KelemenLUT);SAMPLER(sampler_KelemenLUT);
|
|||
|
|
//sampler2D _KelemenLUT;
|
|||
|
|
TEXTURE2D(_Normal);SAMPLER(sampler_Normal);
|
|||
|
|
//sampler2D _Normal;
|
|||
|
|
float _NormalScale;
|
|||
|
|
float4 _Normal_TexSize;
|
|||
|
|
TEXTURE2D(_DetailNormal);SAMPLER(sampler_DetailNormal);
|
|||
|
|
//sampler2D _DetailNormal;
|
|||
|
|
float _DetailNormalScale;
|
|||
|
|
|
|||
|
|
sampler2D _Roughness;
|
|||
|
|
|
|||
|
|
|
|||
|
|
float _Roughness0;
|
|||
|
|
float _Roughness1;
|
|||
|
|
|
|||
|
|
|
|||
|
|
//直接光的菲尼尔
|
|||
|
|
half3 F_schilick(float F0,float VdH)
|
|||
|
|
{
|
|||
|
|
return F0 + (1 - F0) * pow( 1 - saturate(VdH), 5);
|
|||
|
|
}
|
|||
|
|
//间接光的菲尼尔
|
|||
|
|
half F_inDir(float F0,float NdV ,float roughness)
|
|||
|
|
{
|
|||
|
|
return F0 + (max(1.0 - roughness, F0) - F0) * pow(1.0 - NdV, 5.0);
|
|||
|
|
}
|
|||
|
|
v2f vert (appdata v)
|
|||
|
|
{
|
|||
|
|
v2f o;
|
|||
|
|
o.vertex = TransformObjectToHClip(v.vertex);
|
|||
|
|
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
|||
|
|
o.worldPos=mul(UNITY_MATRIX_M,v.vertex);
|
|||
|
|
o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);
|
|||
|
|
float3 worldTangent=TransformObjectToWorldDir(v.tangent.xyz);
|
|||
|
|
float3 worldBinormal=cross(o.worldNormal,worldTangent)*v.tangent.w;
|
|||
|
|
o.TtW0=float3(worldTangent.x,worldBinormal.x,o.worldNormal.x);
|
|||
|
|
o.TtW1=float3(worldTangent.y,worldBinormal.y,o.worldNormal.y);
|
|||
|
|
o.TtW2=float3(worldTangent.z,worldBinormal.z,o.worldNormal.z);
|
|||
|
|
|
|||
|
|
o.shadow=TransformWorldToShadowCoord(o.worldPos);
|
|||
|
|
return o;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
float4 frag (v2f i) : SV_Target
|
|||
|
|
{
|
|||
|
|
//曲率
|
|||
|
|
float curvature=saturate(length(fwidth(i.worldNormal))*0.001/length(fwidth(i.worldPos))+0.4);
|
|||
|
|
//return float4(curvature.xxx,1);
|
|||
|
|
float3 nTs=UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal,sampler_Normal,i.uv),_NormalScale);
|
|||
|
|
float3 nTsM=UnpackNormalScale(SAMPLE_TEXTURE2D(_DetailNormal,sampler_DetailNormal,i.uv*4),_DetailNormalScale);
|
|||
|
|
nTsM=normalize(float3(dot(i.TtW0.xyz,nTsM),dot(i.TtW1.xyz,nTsM),dot(i.TtW2.xyz,nTsM)));
|
|||
|
|
nTs=normalize(float3(dot(i.TtW0.xyz,nTs),dot(i.TtW1.xyz,nTs),dot(i.TtW2.xyz,nTs)));
|
|||
|
|
float3 nTsBlur=UnpackNormalScale(SAMPLE_TEXTURE2D_LOD(_Normal,sampler_Normal, i.uv,5),_NormalScale);
|
|||
|
|
float3 nTsMBlur=UnpackNormalScale(SAMPLE_TEXTURE2D_LOD(_DetailNormal,sampler_DetailNormal, i.uv*4,5),_DetailNormalScale);
|
|||
|
|
nTsMBlur=normalize(float3(dot(i.TtW0.xyz,nTsMBlur),dot(i.TtW1.xyz,nTsMBlur),dot(i.TtW2.xyz,nTsMBlur)));
|
|||
|
|
nTsBlur=normalize(float3(dot(i.TtW0.xyz,nTsBlur),dot(i.TtW1.xyz,nTsBlur),dot(i.TtW2.xyz,nTsBlur)));
|
|||
|
|
//得到正常法线和模糊后的发线
|
|||
|
|
nTs=normalize(lerp(nTs,nTsM,0.5));
|
|||
|
|
nTsBlur=normalize(lerp(nTsBlur,nTsMBlur,0.5));
|
|||
|
|
|
|||
|
|
half3 vDirWS = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
|
|||
|
|
half3 lDirWS = normalize(_MainLightPosition);
|
|||
|
|
half3 hDirWS = normalize(lDirWS + vDirWS);
|
|||
|
|
|
|||
|
|
|
|||
|
|
//dot
|
|||
|
|
//half ndotl=dot(nDirWS,lDirWS);
|
|||
|
|
half ndoth=max(dot(nTs,hDirWS),0.0001);
|
|||
|
|
half ndotl=max(dot(nTs,lDirWS),0.0001);
|
|||
|
|
//Texture sample
|
|||
|
|
half4 var_Albedo=SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.uv.xy);
|
|||
|
|
//return float4(var_Albedo*0.03);
|
|||
|
|
//直接光漫反射,对rgb三个方向的ndl进行模糊,分别采样rgb的SSS颜色
|
|||
|
|
half rndotl=dot(nTsBlur,lDirWS)*0.5+0.5;//红色穿透性最高,所以模糊度最高
|
|||
|
|
half gndotl=lerp(rndotl,dot(nTs,lDirWS)*0.5+0.5,0.3);
|
|||
|
|
half bndotl=lerp(rndotl,dot(nTs,lDirWS)*0.5+0.5,0.7);//蓝色穿透性最弱,所以模糊度最低
|
|||
|
|
float2 RUV=float2(rndotl,curvature);
|
|||
|
|
float2 GUV=float2(gndotl,curvature);
|
|||
|
|
float2 BUV=float2(bndotl,curvature);
|
|||
|
|
//sss就是通过采样Lut得到的漫反射颜色
|
|||
|
|
float3 sss;
|
|||
|
|
sss.r=SAMPLE_TEXTURE2D(_SSSLut,sampler_SSSLut,RUV).r;
|
|||
|
|
sss.g=SAMPLE_TEXTURE2D(_SSSLut,sampler_SSSLut,GUV).g;
|
|||
|
|
sss.b=SAMPLE_TEXTURE2D(_SSSLut,sampler_SSSLut,BUV).b;
|
|||
|
|
|
|||
|
|
float ndl=dot(nTs,hDirWS)*0.5+0.5;
|
|||
|
|
//漫反射要乘上ndl,sss散射采样预计算贴图不需要乘ndl,直接光结果要乘上灯光颜色
|
|||
|
|
half3 dirDiffCol=sss*_MainLightColor*var_Albedo.rgb*ndl;//+var_Albedo.rgb*0.5*max(ndotl,0.3);
|
|||
|
|
|
|||
|
|
//float3 diff=sss*DisneyDiffuse(ndotv,ndl,ldotv,sqrt(0.1))*ndl*var_Albedo.rgb*_MainLightColor*PI;
|
|||
|
|
|
|||
|
|
//直接光高光,一层表达比较粗糙的高光,一层表达比较集中的高亮高光。
|
|||
|
|
half lobe0=SAMPLE_TEXTURE2D(_KelemenLUT,sampler_KelemenLUT,float2(ndoth,_Roughness0*0.01)).r;
|
|||
|
|
half lobe1=SAMPLE_TEXTURE2D(_KelemenLUT,sampler_KelemenLUT,float2(ndoth,_Roughness1*0.01)).r;
|
|||
|
|
half PH0=pow(1*lobe0,5);
|
|||
|
|
half PH1=pow(1*lobe1,5);
|
|||
|
|
//f是为了遵循能量守恒,高光大的地方漫反射少
|
|||
|
|
float f=lerp(PH0,PH1,0.45)*PI;
|
|||
|
|
half3 lobe0Col=(max(PH0,0));
|
|||
|
|
half3 lobe1Col=(max(PH1,0));
|
|||
|
|
|
|||
|
|
float mainLight=MainLightRealtimeShadow(i.shadow);
|
|||
|
|
//乘以ndotl防止背面出现高光,直接光高光乘上ndh,sss散射采样预计算贴图不需要乘,直接光结果要乘上光照颜色
|
|||
|
|
half3 specCol=lerp(lobe0Col,lobe1Col,0.45)*pow(ndotl,0.5)*PI;
|
|||
|
|
half3 dirCol=(dirDiffCol*(1-f)+specCol)*mainLight;
|
|||
|
|
|
|||
|
|
//return float4((f).xxx,1);
|
|||
|
|
float3 addColor=float3(0,0,0);
|
|||
|
|
int addCount=GetAdditionalLightsCount();
|
|||
|
|
//点光源漫反射和高光
|
|||
|
|
for (int k=0;k<addCount;k++)
|
|||
|
|
{
|
|||
|
|
Light light=GetAdditionalLight(k,i.worldPos);
|
|||
|
|
float3 L=light.direction;
|
|||
|
|
half3 hDirWS = normalize(L + vDirWS);
|
|||
|
|
half ndotl=max(dot(nTs,L),0.0001);
|
|||
|
|
half ndoth=max(dot(nTs,hDirWS),0.0001);
|
|||
|
|
half rndotl=dot(nTsBlur,L)*0.5+0.5;
|
|||
|
|
float2 RUV=float2(rndotl,curvature);
|
|||
|
|
float3 sss=SAMPLE_TEXTURE2D(_SSSLut,sampler_SSSLut,RUV);
|
|||
|
|
half3 dirDiffCol=sss*light.color*var_Albedo.rgb*0.8+var_Albedo.rgb*0.5*max(ndotl,0.3)*light.distanceAttenuation*light.shadowAttenuation;
|
|||
|
|
|
|||
|
|
half vdoth=max(dot(vDirWS,hDirWS),0.0001);
|
|||
|
|
half lobe0=SAMPLE_TEXTURE2D(_KelemenLUT,sampler_KelemenLUT,float2(ndoth,_Roughness0*0.011)).r;
|
|||
|
|
half lobe1=SAMPLE_TEXTURE2D(_KelemenLUT,sampler_KelemenLUT,float2(ndoth,_Roughness1*0.01)).r;
|
|||
|
|
half PH0=pow(2*lobe0,5);
|
|||
|
|
half PH1=pow(2*lobe1,5);
|
|||
|
|
half3 F=F_schilick(0.05,vdoth);
|
|||
|
|
half3 lobe0Col=(max(PH0*F,0));
|
|||
|
|
half3 lobe1Col=(max(PH1*F,0));
|
|||
|
|
|
|||
|
|
half3 specCol=lerp(lobe0Col,lobe1Col,0.3)*pow(ndotl,0.8)*light.distanceAttenuation*light.color*light.shadowAttenuation;
|
|||
|
|
half3 dirCol=dirDiffCol*(1-F)+specCol*light.distanceAttenuation*light.color*light.shadowAttenuation;
|
|||
|
|
addColor+=(specCol+dirCol);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//环境光
|
|||
|
|
float aa=1;
|
|||
|
|
BRDFData brdfData;
|
|||
|
|
InitializeBRDFData(var_Albedo.rgb,0,1,0.6,aa, brdfData);
|
|||
|
|
half3 ambient_contrib = SampleSH(float4(nTsBlur, 1));
|
|||
|
|
float3 ambient = 0.3 * var_Albedo.rgb;// 随便乘个暗的系数
|
|||
|
|
float3 iblDiffuse = max(half3(0, 0, 0), ambient.rgb + ambient_contrib);
|
|||
|
|
float3 inssp= GlobalIllumination(brdfData,iblDiffuse,1,i.worldPos,nTsBlur,vDirWS);
|
|||
|
|
half3 finaColor=inssp+dirCol;//+addColor;
|
|||
|
|
|
|||
|
|
return half4(finaColor,1.0);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
ENDHLSL
|
|||
|
|
}
|
|||
|
|
//UsePass "Universal Render Pipeline/Lit/ShadowCaster"
|
|||
|
|
}
|
|||
|
|
}
|