310 lines
9.9 KiB
Plaintext
310 lines
9.9 KiB
Plaintext
|
|
BEGIN_OPTIONS
|
|
name "Hidden/ProceduralRoad_Base"
|
|
END_OPTIONS
|
|
|
|
BEGIN_PROPERTIES
|
|
[Header(Main)]
|
|
_Asphalt_Albedo("Albedo", 2D) = "white" {}
|
|
_AlphaThreshold("Alpha Threshold", Range(0,1)) = 0.0
|
|
_Asphalt_Tint("Tint", Color) = (1,1,1,1)
|
|
_Asphalt_NormalSAO("NSAO (Smoothness, NormalY, AO, NormalX)", 2D) = "bump" {}
|
|
_Asphalt_MaskMap("Mask Map", 2D) = "black" {}
|
|
_Asphalt_NormalStrength("Normal Strength", Range(0,1)) = 1
|
|
_Asphalt_Smoothness("Smoothness Modifier", Range(-1,1)) = 0
|
|
_Asphalt_Metallic ("Metallic Modifier", Range(-1,1)) = 0
|
|
_AsphaltStochasticContrast("Asphalt Stochastic Contrast", Range(0.01, 0.99)) = 0.7
|
|
_AsphaltStochasticScale("Asphalt Stochastic Scale", Range(0,2)) = 1
|
|
|
|
_Mask("LineA/LineB/WearUV/WearWorld", 2D) = "black" {}
|
|
|
|
[Header(Lines)]
|
|
_LineColorA("Line Color A", Color) = (1,1,1,1)
|
|
_LineColorB("Line Color B", Color) = (1,1,0,1)
|
|
_LineEmissiveA("Line Emission", Float) = 0
|
|
_LineEmissiveB("Line Emission", Float) = 0
|
|
|
|
[Header(Wear Noise)]
|
|
_WearNoise("Wear Noise Texture", 2D) = "black" {}
|
|
_LineWear("Line Wear", Range(0,1)) = 0.5
|
|
|
|
[Header(WearA)]
|
|
_WearMapA("Normal", 2D) = "bump" {}
|
|
_WearA_Tint("Tint", Color) = (0.5,0.5,0.5,0.5)
|
|
_WearA_PBR("Smoothness, Occlusion, Normal", Vector) = (0, 0, 0, 1)
|
|
_WearA_NoiseParams("Contrast, Invert", Vector) = (8, 0, 0, 0)
|
|
|
|
[Header(WearB)]
|
|
_WearMapB("Normal", 2D) = "bump" {}
|
|
_WearB_Tint("Tint", Color) = (0.5,0.5,0.5,0.5)
|
|
_WearB_PBR("Smoothness, Occlusion, Normal, Strength", Vector) = (0, 0, 0, 1)
|
|
_WearB_NoiseParams("Contrast, Invert", Vector) = (8, 0, 0, 0)
|
|
|
|
[Header(Overlay)]
|
|
_Overlay_Albedo("Overlay Albedo", 2D) = "white" {}
|
|
_Overlay_Normal("Overlay Normal", 2D) = "bump" {}
|
|
_Overlay_Mask("Overlay Mask", 2D) = "black" {}
|
|
_Overlay_VariationMask("Variation Mask", 2D) = "white" {}
|
|
|
|
END_PROPERTIES
|
|
|
|
BEGIN_DEFINES
|
|
|
|
#pragma shader_feature_local _ _WEAR_A
|
|
#pragma shader_feature_local _ _WEAR_B
|
|
|
|
#pragma shader_feature_local _ _PACKEDFAST
|
|
#pragma shader_feature_local _ _ASPHALTSTOCHASTIC
|
|
#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR
|
|
|
|
#pragma shader_feature_local _ _OVERLAY
|
|
|
|
#pragma shader_feature_local _ _ALPHACUT
|
|
|
|
#define __ROADSHADER__ 1
|
|
#define _ROADWEAR 1
|
|
|
|
END_DEFINES
|
|
|
|
BEGIN_CBUFFER
|
|
|
|
half4 _Asphalt_Tint;
|
|
half _Asphalt_Metallic;
|
|
half _Asphalt_Smoothness;
|
|
float4 _Asphalt_Albedo_ST;
|
|
half _AlphaThreshold;
|
|
half _Asphalt_NormalStrength;
|
|
half _AsphaltStochasticScale;
|
|
half _AsphaltStochasticContrast;
|
|
|
|
half4 _WearA_Tint;
|
|
half4 _WearA_PBR;
|
|
float4 _WearMapA_ST;
|
|
half4 _WearA_NoiseParams;
|
|
|
|
|
|
half4 _WearB_Tint;
|
|
half4 _WearB_PBR;
|
|
float4 _WearMapB_ST;
|
|
half4 _WearB_NoiseParams;
|
|
|
|
float4 _WearNoise_ST;
|
|
|
|
half4 _LineColorA;
|
|
half4 _LineColorB;
|
|
half _LineEmissiveA;
|
|
half _LineEmissiveB;
|
|
half _LineWear;
|
|
|
|
float4 _Mask_TexelSize;
|
|
|
|
float4 _Overlay_Albedo_ST;
|
|
float4 _Overlay_VariationMask_ST;
|
|
|
|
END_CBUFFER
|
|
|
|
BEGIN_BLACKBOARD
|
|
half roadWear;
|
|
END_BLACKBOARD
|
|
|
|
|
|
BEGIN_CODE
|
|
|
|
sampler2D _Asphalt_Albedo;
|
|
sampler2D _Asphalt_NormalSAO;
|
|
sampler2D _Asphalt_MaskMap;
|
|
|
|
TEXTURE2D(_WearMapA);
|
|
TEXTURE2D(_WearMapB);
|
|
TEXTURE2D(_WearNoise);
|
|
sampler2D _Mask;
|
|
TEXTURE2D(_Overlay_Albedo);
|
|
TEXTURE2D(_Overlay_Normal);
|
|
TEXTURE2D(_Overlay_Mask);
|
|
TEXTURE2D(_Overlay_VariationMask);
|
|
|
|
SamplerState road_linear_repeat_sampler;
|
|
SamplerState road_linear_clamp_sampler;
|
|
|
|
void SurfaceFunction(inout Surface o, inout ShaderData d)
|
|
{
|
|
|
|
float2 uv = d.texcoord0.xy;
|
|
|
|
#if _ASPHALT_WORLDTRIPLANAR
|
|
// base layer, triplanar
|
|
half3 triblend = saturate(pow(d.worldSpaceNormal, 4));
|
|
triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);
|
|
|
|
float2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;
|
|
float2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;
|
|
float2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;
|
|
uvY += 0.33;
|
|
uvZ += 0.67;
|
|
half3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;
|
|
uvX.x *= axisSign.x;
|
|
uvY.x *= axisSign.y;
|
|
uvZ.x *= -axisSign.z;
|
|
|
|
// 1 sample triplanar
|
|
float2 uvT = uvZ;
|
|
if (triblend.x > triblend.y && triblend.x > triblend.z)
|
|
{
|
|
uvT = uvX;
|
|
}
|
|
else if (triblend.y > triblend.z)
|
|
{
|
|
uvT = uvY;
|
|
}
|
|
#else
|
|
float2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;
|
|
#endif
|
|
|
|
#if _ASPHALTSTOCHASTIC
|
|
float w1, w2, w3;
|
|
int2 vertex1, vertex2, vertex3;
|
|
float2 dx = ddx(uvT);
|
|
float2 dy = ddy(uvT);
|
|
TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);
|
|
|
|
// Assign random offset to each triangle vertex
|
|
float2 uv0 = uvT;
|
|
float2 uv1 = uvT;
|
|
float2 uv2 = uvT;
|
|
|
|
uv0.xy += SimpleHash2(vertex1);
|
|
uv1.xy += SimpleHash2(vertex2);
|
|
uv2.xy += SimpleHash2(vertex3);
|
|
half3 weights = half3(w1, w2, w3);
|
|
|
|
half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);
|
|
half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);
|
|
half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);
|
|
|
|
weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);
|
|
half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;
|
|
half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);
|
|
half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);
|
|
half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);
|
|
half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;
|
|
|
|
half metallic = 0;
|
|
#if !_PACKEDFAST
|
|
half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);
|
|
half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);
|
|
half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);
|
|
half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;
|
|
nsao.r = mmap.a;
|
|
nsao.b = mmap.g;
|
|
metallic = mmap.r;
|
|
#endif
|
|
|
|
|
|
#else
|
|
half4 col = tex2D(_Asphalt_Albedo, uvT);
|
|
half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);
|
|
half metallic = 0;
|
|
#if !_PACKEDFAST
|
|
half4 mmap = tex2D(_Asphalt_MaskMap, uvT);
|
|
nsao.r = mmap.a;
|
|
nsao.b = mmap.g;
|
|
metallic = mmap.r;
|
|
#endif
|
|
#endif
|
|
|
|
#if _ALPHACUT
|
|
clip(col.a - _AlphaThreshold);
|
|
#endif
|
|
|
|
o.Albedo = col.rgb * _Asphalt_Tint.rgb;
|
|
o.Height = col.a;
|
|
|
|
fixed3 normal;
|
|
normal.xy = nsao.wy * 2 - 1;
|
|
normal.xy *= _Asphalt_NormalStrength;
|
|
normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));
|
|
|
|
o.Normal = normal;
|
|
|
|
o.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);
|
|
o.Metallic = metallic + _Asphalt_Metallic;
|
|
o.Occlusion = nsao.b;
|
|
|
|
// lines
|
|
float fw = fwidth(d.texcoord0.xy);
|
|
float lod = saturate(fw * _Mask_TexelSize.zw);
|
|
half4 mask = tex2D(_Mask, d.texcoord0.xy);
|
|
// soften in mips to prevent aliasing
|
|
mask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);
|
|
|
|
half4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);
|
|
|
|
float2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;
|
|
o.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);
|
|
o.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);
|
|
|
|
o.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);
|
|
o.Smoothness = lerp(o.Smoothness, 0, maskStr);
|
|
o.Metallic *= 1.0 - maskStr;
|
|
o.Occlusion = lerp(o.Occlusion, 1, maskStr);
|
|
o.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;
|
|
o.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;
|
|
|
|
// wear
|
|
#if _WEAR_A
|
|
mask.z = abs(_WearA_NoiseParams.y - mask.z);
|
|
float2 wAUV = d.worldSpacePosition.xz;
|
|
wAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;
|
|
float noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;
|
|
half3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));
|
|
half heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));
|
|
heightA = saturate(heightA * 4);
|
|
half wearAWeight = _WearA_PBR.w * noiseA * mask.z;
|
|
|
|
o.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);
|
|
o.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);
|
|
o.Occlusion += wearAWeight * _WearA_PBR.y;
|
|
o.Smoothness += wearAWeight * _WearA_PBR.x;
|
|
d.blackboard.roadWear = wearAWeight;
|
|
|
|
#endif
|
|
|
|
#if _WEAR_B
|
|
mask.w = abs(_WearB_NoiseParams.y - mask.w);
|
|
float2 wBUV = d.worldSpacePosition.xz;
|
|
wBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;
|
|
float noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;
|
|
half3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));
|
|
half heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));
|
|
heightB = saturate(heightB * 4);
|
|
half wearBWeight = _WearB_PBR.w * noiseB * mask.w;
|
|
|
|
o.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);
|
|
o.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);
|
|
o.Occlusion += wearBWeight * _WearB_PBR.y;
|
|
o.Smoothness += wearBWeight * _WearB_PBR.x;
|
|
#endif
|
|
|
|
#if _OVERLAY
|
|
float2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;
|
|
half4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);
|
|
half3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));
|
|
half4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);
|
|
float2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;
|
|
half varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;
|
|
oAlbedo.a *= varyWorldSpace;
|
|
o.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);
|
|
o.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);
|
|
o.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);
|
|
o.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);
|
|
o.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);
|
|
#endif
|
|
|
|
o.Albedo = saturate(o.Albedo);
|
|
o.Smoothness = saturate(o.Smoothness);
|
|
o.Occlusion = saturate(o.Occlusion);
|
|
}
|
|
|
|
END_CODE
|
|
|