Files
2025-06-04 09:09:39 +08:00

352 lines
14 KiB
Plaintext

TEXTURE2D_ARRAY(_ClusterDiffuse2);
TEXTURE2D_ARRAY(_ClusterNormal2);
#if _PACKINGHQ
TEXTURE2D_ARRAY(_ClusterSmoothAO2);
#endif
#if _USEEMISSIVEMETAL
TEXTURE2D_ARRAY(_ClusterEmissiveMetal2);
#endif
#if _TEXTURECLUSTER3
TEXTURE2D_ARRAY(_ClusterDiffuse3);
TEXTURE2D_ARRAY(_ClusterNormal3);
#if _PACKINGHQ
TEXTURE2D_ARRAY(_ClusterSmoothAO3);
#endif
#if _USEEMISSIVEMETAL
TEXTURE2D_ARRAY(_ClusterEmissiveMetal3);
#endif
#endif
TEXTURE2D(_ClusterNoise);
#if _TEXTURECLUSTERNOISE2
TEXTURE2D(_ClusterNoise2);
#endif
half3 ClusterWeights2(half4 iWeights, half h0, half h1)
{
half2 blend = iWeights.xy / dot(iWeights.xy, half2(1,1));
float2 heights = float2(h0, h1) + (blend * 3.0);
half height_start = max(heights.x, heights.y) - iWeights.w;
half2 h = max(heights - height_start.xx, half2(0,0));
blend = h / dot(h, half2(1,1));
return half3(blend, 0);
}
half3 ClusterWeights3(half4 iWeights, half h0, half h1, half h2)
{
half3 blend = iWeights.xyz / dot(iWeights.xyz, half3(1,1,1));
float3 heights = float3(h0, h1, h2) + (blend * 3.0);
half height_start = max(max(heights.x, heights.y), heights.z) - iWeights.w;
half3 h = max(heights - height_start.xxx, half3(0,0,0));
blend = h / dot(h, half3(1,1,1));
return blend;
}
half4 ClusterSampleDiffuse(float3 uv, inout half4 cluster, MIPFROMATRAW mipLevel)
{
half4 a0 = MICROSPLAT_SAMPLE_SAMPLER(_Diffuse, sampler_Diffuse, uv, mipLevel);
COUNTSAMPLE
half4 a1 = MICROSPLAT_SAMPLE_SAMPLER(_ClusterDiffuse2, sampler_Diffuse, float3(uv.xy * (1 + _ClusterScaleVar), uv.z), mipLevel);
COUNTSAMPLE
#if _TEXTURECLUSTER3
half4 a2 = MICROSPLAT_SAMPLE_SAMPLER(_ClusterDiffuse3, sampler_Diffuse, float3(uv.xy * (1 - _ClusterScaleVar), uv.z), mipLevel);
COUNTSAMPLE
cluster.rgb = ClusterWeights3(cluster, a0.a, a1.a, a2.a);
return a0 * cluster.x + a1 * cluster.y + a2 * cluster.z;
#else
cluster.rgb = ClusterWeights2(cluster, a0.a, a1.a);
return a0 * cluster.x + a1 * cluster.y;
#endif
}
half4 ClusterSampleEmis(float3 uv, inout half4 cluster, MIPFROMATRAW mipLevel)
{
#if _USEEMISSIVEMETAL
half4 a0 = half4(0, 0, 0, 0);
half4 a1 = half4(0, 0, 0, 0);
half4 a2 = half4(0, 0, 0, 0);
MSBRANCHCLUSTER(cluster.x)
{
a0 = MICROSPLAT_SAMPLE_SAMPLER(_EmissiveMetal, sampler_Diffuse, uv, mipLevel);
COUNTSAMPLE
}
MSBRANCHCLUSTER(cluster.y)
{
a1 = MICROSPLAT_SAMPLE_SAMPLER(_ClusterEmissiveMetal2, sampler_Diffuse, float3(uv.xy * (1 + _ClusterScaleVar), uv.z), mipLevel);
COUNTSAMPLE
}
#if _TEXTURECLUSTER3
MSBRANCHCLUSTER(cluster.z)
{
a2 = MICROSPLAT_SAMPLE_SAMPLER(_ClusterEmissiveMetal3, sampler_Diffuse, float3(uv.xy * (1 - _ClusterScaleVar), uv.z), mipLevel);
COUNTSAMPLE
}
return a0 * cluster.x + a1 * cluster.y + a2 * cluster.z;
#else
return a0 * cluster.x + a1 * cluster.y;
#endif
#endif
return 0;
}
half4 ClusterSampleDiffuseLOD(float3 uv, inout half4 cluster, float mipLevel)
{
half4 a0 = SAMPLE_TEXTURE2D_ARRAY_LOD(_Diffuse, sampler_Diffuse, uv.xy, uv.z, mipLevel);
half4 a1 = SAMPLE_TEXTURE2D_ARRAY_LOD(_ClusterDiffuse2, sampler_Diffuse, uv.xy * (1 + _ClusterScaleVar), uv.z, mipLevel);
#if _TEXTURECLUSTER3
half4 a2 = SAMPLE_TEXTURE2D_ARRAY_LOD(_ClusterDiffuse3, sampler_Diffuse, uv.xy * (1 - _ClusterScaleVar), uv.z, mipLevel);
cluster.rgb = ClusterWeights3(cluster, a0.a, a1.a, a2.a);
return a0 * cluster.x + a1 * cluster.y + a2 * cluster.z;
#else
cluster.rgb = ClusterWeights2(cluster, a0.a, a1.a);
return a0 * cluster.x + a1 * cluster.y;
#endif
}
half4 ClusterSampleNormal(float3 uv, half4 cluster, MIPFROMATRAW mipLevel)
{
#ifdef UNITY_COLORSPACE_GAMMA
cluster.rgb *= cluster.rgb;
#endif
half4 a0 = half4(0.5, 0.5, 0, 1);
half4 a1 = half4(0.5, 0.5, 0, 1);
half4 a2 = half4(0.5, 0.5, 0, 1);
#if _PACKINGHQ
MSBRANCHCLUSTER(cluster.x)
{
a0 = half4(MICROSPLAT_SAMPLE_SAMPLER(_NormalSAO, sampler_NormalSAO, uv, mipLevel).ga, MICROSPLAT_SAMPLE_SAMPLER(_SmoothAO, sampler_SmoothAO, uv, mipLevel).ga).brag;
COUNTSAMPLE
}
#else
MSBRANCHCLUSTER(cluster.x)
{
a0 = MICROSPLAT_SAMPLE_SAMPLER(_NormalSAO, sampler_NormalSAO, uv, mipLevel);
COUNTSAMPLE
}
#endif
a0.ga *= 2;
a0.ga -= 1;
float3 uv2 = float3(uv.xy * (1 + _ClusterScaleVar), uv.z);
#if _PACKINGHQ
MSBRANCHCLUSTER(cluster.y)
{
a1 = half4(MICROSPLAT_SAMPLE_SAMPLER(_ClusterNormal2, sampler_NormalSAO, uv2, mipLevel).ga, MICROSPLAT_SAMPLE_SAMPLER(_ClusterSmoothAO2, sampler_SmoothAO, uv2, mipLevel).ga).brag;
COUNTSAMPLE
}
#else
MSBRANCHCLUSTER(cluster.y)
{
a1 = MICROSPLAT_SAMPLE_SAMPLER(_ClusterNormal2, sampler_NormalSAO, uv2, mipLevel);
COUNTSAMPLE
}
#endif
a1.ga *= 2;
a1.ga -= 1;
#if _TEXTURECLUSTER3
float3 uv3 = float3(uv.xy * (1 - _ClusterScaleVar), uv.z);
#if _PACKINGHQ
MSBRANCHCLUSTER(cluster.z)
{
a2 = half4(MICROSPLAT_SAMPLE_SAMPLER(_ClusterNormal3, sampler_NormalSAO, uv3, mipLevel).ga, MICROSPLAT_SAMPLE_SAMPLER(_ClusterSmoothAO3, sampler_SmoothAO, uv3, mipLevel).ga).brag;
COUNTSAMPLE
COUNTSAMPLE
}
#else
MSBRANCHCLUSTER(cluster.z)
{
a2 = MICROSPLAT_SAMPLE_SAMPLER(_ClusterNormal3, sampler_NormalSAO, uv3, mipLevel);
COUNTSAMPLE
}
#endif
a2.ga *= 2;
a2.ga -= 1;
half4 ret = a0 * cluster.x + a1 * cluster.y + a2 * cluster.z;
ret.ga *= 0.5;
ret.ga += 0.5;
return ret;
#else
half4 ret = a0 * cluster.x + a1 * cluster.y;
ret.ga *= 0.5;
ret.ga += 0.5;
return ret;
#endif
}
#undef MICROSPLAT_SAMPLE_DIFFUSE
#undef MICROSPLAT_SAMPLE_NORMAL
#undef MICROSPLAT_SAMPLE_DIFFUSE_LOD
#undef MICROSPLAT_SAMPLE_EMIS
#define MICROSPLAT_SAMPLE_DIFFUSE(u, cl, l) ClusterSampleDiffuse(u, cl, l)
#define MICROSPLAT_SAMPLE_NORMAL(u, cl, l) ClusterSampleNormal(u, cl, l)
#define MICROSPLAT_SAMPLE_DIFFUSE_LOD(u, cl, l) ClusterSampleDiffuseLOD(u, cl, l)
#define MICROSPLAT_SAMPLE_EMIS(u, cl, l) ClusterSampleEmis(u, cl, l)
void PrepClusterData(half4 noise, inout Config c)
{
noise.a = _ClusterContrast;
#if _PERTEXCLUSTERBOOST || _PERTEXCLUSTERCONTRAST
SAMPLE_PER_TEX(pt, 10.5, c, 0.5);
#endif
#if _PERTEXCLUSTERBOOST
c.cluster0 = noise;
c.cluster1 = noise;
c.cluster2 = noise;
c.cluster3 = noise;
c.cluster0.rgb = pow(c.cluster0.rgb, abs(pt0.g));
c.cluster1.rgb = pow(c.cluster1.rgb, abs(pt1.g));
#if !_MAX2LAYER
c.cluster2.rgb = pow(c.cluster2.rgb, abs(pt2.g));
#endif
#if !_MAX3LAYER || !_MAX2LAYER
c.cluster3.rgb = pow(c.cluster3.rgb, abs(pt3.g));
#endif
#if _TEXTURECLUSTER3
c.cluster0.rgb = TotalOne(c.cluster0.rgb);
c.cluster1.rgb = TotalOne(c.cluster1.rgb);
c.cluster2.rgb = TotalOne(c.cluster2.rgb);
c.cluster3.rgb = TotalOne(c.cluster3.rgb);
#else
c.cluster0.rg = TotalOne(c.cluster0.rg);
c.cluster1.rg = TotalOne(c.cluster1.rg);
c.cluster2.rg = TotalOne(c.cluster2.rg);
c.cluster3.rg = TotalOne(c.cluster3.rg);
#endif
#else
noise.rgb = pow(noise.rgb, abs(_ClusterBoost));
#if _TEXTURECLUSTER3
noise.rgb = TotalOne(noise.rgb);
#else
noise.rg = TotalOne(noise.rg);
#endif
c.cluster0 = noise;
c.cluster1 = noise;
c.cluster2 = noise;
c.cluster3 = noise;
#endif
#if _PERTEXCLUSTERCONTRAST
c.cluster0.a = max(pt0.r, 0.01);
c.cluster1.a = max(pt1.r, 0.01);;
#if !_MAX2LAYER
c.cluster2.a = max(pt2.r, 0.01);
#endif
#if !_MAX3LAYER || !_MAX2LAYER
c.cluster3.a = max(pt3.r, 0.01);
#endif
#endif
}
void PrepClusters(float2 uv, inout Config c, float3 worldPos, float3 normal)
{
#if _TEXTURECLUSTERTRIPLANARNOISE
float3 pn = pow(abs(normal), 0.7);
pn = pn / (pn.x + pn.y + pn.z);
half3 axisSign = sign(normal);
float2 uv0 = (worldPos.zy * _ClusterParams.xy + _ClusterParams.zw) * axisSign.x;
float2 uv1 = (worldPos.xz * _ClusterParams.xy + _ClusterParams.zw) * axisSign.y;
float2 uv2 = (worldPos.xy * _ClusterParams.xy + _ClusterParams.zw) * axisSign.z;
half4 n0 = SAMPLE_TEXTURE2D(_ClusterNoise, sampler_Diffuse, uv0);
half4 n1 = SAMPLE_TEXTURE2D(_ClusterNoise, sampler_Diffuse, uv1);
half4 n2 = SAMPLE_TEXTURE2D(_ClusterNoise, sampler_Diffuse, uv2);
half4 noise = n0 * pn.x + n1 * pn.y + n2 * pn.z;
#if _TEXTURECLUSTERNOISE2
uv0 = (worldPos.zy * _ClusterParams2.xy + _ClusterParams2.zw) * axisSign.x;
uv1 = (worldPos.xz * _ClusterParams2.xy + _ClusterParams2.zw) * axisSign.y;
uv2 = (worldPos.xy * _ClusterParams2.xy + _ClusterParams2.zw) * axisSign.z;
n0 = SAMPLE_TEXTURE2D(_ClusterNoise2, sampler_Diffuse, uv0);
n1 = SAMPLE_TEXTURE2D(_ClusterNoise2, sampler_Diffuse, uv1);
n2 = SAMPLE_TEXTURE2D(_ClusterNoise2, sampler_Diffuse, uv2);
half4 noise2 = n0 * pn.x + n1 * pn.y + n2 * pn.z;
noise += noise2;
noise *= 0.5;
#endif
#else
float2 nuv = uv * _ClusterParams.xy + _ClusterParams.zw;
half4 noise = SAMPLE_TEXTURE2D(_ClusterNoise, sampler_Diffuse, nuv);
#if _TEXTURECLUSTERNOISE2
nuv = uv * _ClusterParams2.xy + _ClusterParams2.zw;
half4 noise2 = SAMPLE_TEXTURE2D(_ClusterNoise2, sampler_Diffuse, nuv);
noise += noise2;
noise *= 0.5;
#endif
#endif
PrepClusterData(noise, c);
}
void PrepClustersDisplace(float2 uv, inout Config c, float3 worldPos, float3 normal)
{
#if _TRIPLANAR
float3 pn = pow(abs(normal), 0.7);
pn = pn / (pn.x + pn.y + pn.z);
half3 axisSign = sign(normal);
float2 uv0 = (worldPos.zy * _ClusterParams.xy + _ClusterParams.zw) * axisSign.x;
float2 uv1 = (worldPos.xz * _ClusterParams.xy + _ClusterParams.zw) * axisSign.y;
float2 uv2 = (worldPos.xy * _ClusterParams.xy + _ClusterParams.zw) * axisSign.z;
half4 n0 = SAMPLE_TEXTURE2D_LOD(_ClusterNoise, sampler_Diffuse, uv0, 0);
half4 n1 = SAMPLE_TEXTURE2D_LOD(_ClusterNoise, sampler_Diffuse, uv1, 0);
half4 n2 = SAMPLE_TEXTURE2D_LOD(_ClusterNoise, sampler_Diffuse, uv2, 0);
half4 noise = n0 * pn.x + n1 * pn.y + n2 * pn.z;
#if _TEXTURECLUSTERNOISE2
uv0 = (worldPos.zy * _ClusterParams2.xy + _ClusterParams2.zw) * axisSign.x;
uv1 = (worldPos.xz * _ClusterParams2.xy + _ClusterParams2.zw) * axisSign.y;
uv2 = (worldPos.xy * _ClusterParams2.xy + _ClusterParams2.zw) * axisSign.z;
n0 = SAMPLE_TEXTURE2D_LOD(_ClusterNoise2, sampler_Diffuse, uv0, 0);
n1 = SAMPLE_TEXTURE2D_LOD(_ClusterNoise2, sampler_Diffuse, uv1, 0);
n2 = SAMPLE_TEXTURE2D_LOD(_ClusterNoise2, sampler_Diffuse, uv2, 0);
half4 noise2 = n0 * pn.x + n1 * pn.y + n2 * pn.z;
noise += noise2;
noise *= 0.5;
#endif
#else
float2 nuv = uv * _ClusterParams.xy + _ClusterParams.zw;
uv = uv * _ClusterParams.xy + _ClusterParams.zw;
half4 noise = SAMPLE_TEXTURE2D_LOD(_ClusterNoise, sampler_Diffuse, nuv, 0);
#if _TEXTURECLUSTERNOISE2
nuv = uv * _ClusterParams2.xy + _ClusterParams2.zw;
half4 noise2 = SAMPLE_TEXTURE2D_LOD(_ClusterNoise2, sampler_Diffuse, nuv, 0);
noise += noise2;
noise *= 0.5;
#endif
#endif
PrepClusterData(noise, c);
}