Files
2025-06-09 23:23:13 +08:00

99 lines
2.7 KiB
Plaintext

Shader "Hidden/MicroVerse/TreePasteStamp"
{
Properties
{
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _TreePos;
sampler2D _TreeRand;
sampler2D _Heightmap;
float4x4 _StampTransform;
float4x4 _TerrainTransform;
float3 _RealSize;
float _Indexes[32];
sampler2D _ClearMask;
sampler2D _PlacementMask;
float _ClearLayer;
sampler2D _RandomTex;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
struct FragmentOutput
{
half4 posWeight : SV_Target0;
half4 randoms : SV_Target1;
};
FragmentOutput frag(v2f i)
{
FragmentOutput o = (FragmentOutput)0;
half4 posData = tex2D(_TreePos, i.uv);
half4 randData = tex2D(_TreeRand, i.uv);
posData.xz -= 0.5;
// to worldspace
posData.xz = mul(_StampTransform, float4(posData.xyz, 1)).xz;
// to terrain space
posData.xz = mul(_TerrainTransform, float4(posData.xyz, 1)).xz;
// recenter
posData.xz += 0.5;
// to 0-1 space
posData.xz /= _RealSize.xz;
// clip terrain bounds
bool cp = (posData.x <= 0 || posData.x >= 1 || posData.z <= 0 || posData.z >= 1);
if (cp)
{
posData.w = 0;
o.posWeight = posData;
o.randoms = randData;
return o;
}
posData.w *= 1.0 - tex2D(_PlacementMask, posData.xz).b;
float2 clearMask = tex2D(_ClearMask, posData.xz).xy;
if (round(clearMask.r * 256) > _ClearLayer+0.5)
posData.w *= 1.0 - clearMask.g;
// remap height data
half height = UnpackHeightmap(tex2D(_Heightmap, posData.xz));
posData.y = height;
o.posWeight = posData;
o.randoms = randData;
return o;
}
ENDCG
}
}
}