VirtualFramework/Assets/PiFu/sources/ShinShaderT.shader
2025-04-24 17:58:40 +08:00

223 lines
11 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Shader "Unlit/ShinShaderT"
{
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
_Alpha("Alpha",Range(0,1))=1
}
SubShader
{
Tags { "Queue"="Transparent" }
LOD 100
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
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;
float _Alpha;
//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防止背面出现高光直接光高光乘上ndhsss散射采样预计算贴图不需要乘直接光结果要乘上光照颜色
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,_Alpha);
}
ENDHLSL
}
//UsePass "Universal Render Pipeline/Lit/ShadowCaster"
}
}