KopMap/Assets/Sandbox/Shader/NewUnlitTerrainShader.shader
2025-04-03 02:30:16 +08:00

112 lines
3.8 KiB
Plaintext
Raw Permalink 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/NewUnlitTerrainShader"
{
Properties
{
_MainTex ("Texture Array", 2DArray) = "white" {}
_TexNo ("TexNo", 2D) = "white" {}
_MaskNo ("MaskNo", 2D) = "black" {}
_MaskTex ("Mask", 2DArray) = "black" {}
_BorderColor ("BorderColor", Color) = (1,1,1,1)
_BorderWidth ("BorderWidth", Range(0,0.1)) = 0.05
_MapSize ("Map Size", Vector) = (256,256,0,0)
_TileSize ("Tile Size", Vector) = (1,1,0,0)
}
SubShader
{
Tags
{
"RenderType"="Opaque"
}
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float2 uv : TEXCOORD0; // 用于采样 _TexNo 与 _MaskNo
float2 uv2 : TEXCOORD1; // 用于采样纹理数组 _MainTex 与 _MaskTex
float4 vertex : SV_POSITION;
};
UNITY_DECLARE_TEX2DARRAY(_MainTex);
sampler2D _TexNo;
sampler2D _MaskNo;
UNITY_DECLARE_TEX2DARRAY(_MaskTex);
float4 _TexNo_TexelSize;
float4 _BorderColor;
float _BorderWidth;
float4 _MapSize; // 整个地图的宽高X: Width, Y: Height
float4 _TileSize; // 每个瓦块的尺寸(默认 1x1
v2f vert(appdata v)
{
v2f o;
float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
// 整体 UV以整个地图为基准归一化
o.uv = worldPos.xz / _MapSize.xy;
// 局部 tile 内 UV取 worldPos.xz 除以瓦块尺寸后的小数部分
o.uv2 = frac(worldPos.xz / _TileSize.xy);
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
// 根据遮罩与纹理编号混合采样
float4 Blend(float4 color, float2 uv, float mask, int layer)
{
float4 col2 = UNITY_SAMPLE_TEX2DARRAY(_MainTex, float3(uv, layer));
int idx = round(mask * 16);
float4 maskTexCol = UNITY_SAMPLE_TEX2DARRAY(_MaskTex, float3(uv, idx));
return lerp(color, col2, maskTexCol);
}
int GetTexNo(float f)
{
float idx = f * 64;
return round(idx);
}
fixed4 frag(v2f i) : SV_Target
{
// 微调 uv模拟原来的偏移
float2 uv = i.uv + float2(0, _TexNo_TexelSize.y);
float4 texNo = tex2D(_TexNo, uv);
int layer1 = GetTexNo(texNo.r);
int layer2 = GetTexNo(texNo.g);
int layer3 = GetTexNo(texNo.b);
int layer4 = GetTexNo(texNo.a);
float4 maskNo = tex2D(_MaskNo, uv);
float4 col = UNITY_SAMPLE_TEX2DARRAY(_MainTex, float3(i.uv2, layer1));
// if (layer2 > 0)
// col = Blend(col, i.uv2, maskNo.g, layer2);
// if (layer3 > 0)
// col = Blend(col, i.uv2, maskNo.b, layer3);
// if (layer4 > 0)
// col = Blend(col, i.uv2, maskNo.a, layer4);
// // 显示边框,当局部 UV 靠近边缘时显示边框颜色
// if (i.uv2.x < _BorderWidth || i.uv2.y < _BorderWidth || i.uv2.x > 1 - _BorderWidth || i.uv2.y > 1 -
// _BorderWidth)
// {
// col = _BorderColor;
// }
return col;
}
ENDCG
}
}
}