352 lines
14 KiB
Plaintext
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);
|
|
}
|
|
|
|
|