forked from BilalY/Rasagar
87 lines
3.1 KiB
Markdown
87 lines
3.1 KiB
Markdown
# Custom Terrain Tool shaders
|
|
|
|
If you don't want to use the built-in painting Material, you need to create your own shader. You can then use that shader to create a Material, and use that Material instead to modify Terrain Texture data.
|
|
|
|
Here is an example Terrain Tool shader.
|
|
|
|
```
|
|
Shader "TerrainTool/CustomTerrainTool"
|
|
{
|
|
Properties { _MainTex ("Texture", any) = "" {} }
|
|
|
|
SubShader
|
|
{
|
|
ZTest Always Cull Off ZWrite Off
|
|
|
|
HLSLINCLUDE
|
|
|
|
#include "UnityCG.cginc"
|
|
#include "Packages/com.unity.terrain-tools/Shaders/TerrainTools.hlsl"
|
|
|
|
sampler2D _MainTex;
|
|
float4 _MainTex_TexelSize; // 1/width, 1/height, width, height
|
|
|
|
sampler2D _BrushTex;
|
|
|
|
float4 _BrushParams;
|
|
#define BRUSH_STRENGTH (_BrushParams[0])
|
|
#define BRUSH_TARGETHEIGHT (_BrushParams[1])
|
|
#define kMaxHeight (32766.0f/65535.0f)
|
|
|
|
struct appdata_t
|
|
{
|
|
float4 vertex : POSITION;
|
|
float2 pcUV : TEXCOORD0;
|
|
};
|
|
|
|
struct v2f
|
|
{
|
|
float4 vertex : SV_POSITION;
|
|
float2 pcUV : TEXCOORD0;
|
|
};
|
|
|
|
v2f vert(appdata_t v)
|
|
{
|
|
v2f o;
|
|
o.vertex = UnityObjectToClipPos(v.vertex);
|
|
o.pcUV = v.pcUV;
|
|
return o;
|
|
}
|
|
|
|
ENDHLSL
|
|
|
|
Pass
|
|
{
|
|
Name "CustomTerrainTool"
|
|
|
|
HLSLPROGRAM
|
|
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
|
|
float4 frag(v2f i) : SV_Target
|
|
{
|
|
float2 brushUV = PaintContextUVToBrushUV(i.pcUV);
|
|
|
|
// out of bounds multiplier
|
|
float oob = all(saturate(brushUV) == brushUV) ? 1.0f : 0.0f;
|
|
|
|
// Sample the MainTex, which should be a region of the source Heightmap texture, to get the current height value at the provided UV
|
|
// UnpackHeightmap is necessary here because it unpacks the height value from R and G channels if the current platform/graphics device does not support R16_UNorm texture formats. If R16_UNorm formats are supported, UnpackHeightmap just reads from the R channel.
|
|
float height = UnpackHeightmap(tex2D(_MainTex, i.pcUV));
|
|
// Calculate the influence from the brush mask at this fragment
|
|
float brushShape = oob * UnpackHeightmap(tex2D(_BrushTex, brushUV));
|
|
// Calculate the new height value
|
|
height = height + BRUSH_STRENGTH * brushShape;
|
|
|
|
// Store the new height into the destination RenderTexture. Clamp between 0.0f and 0.5f because the Heightmap itself is signed but is treated as an unsigned texture when rendering the Terrain
|
|
// PackHeightmap is necessary here because it packs the height value into R and G channels if the current platform/graphics device does not support R16_UNorm texture formats. If R16_UNorm formats are supported, PackHeightmap just writes to the R channel.
|
|
return PackHeightmap(clamp(height, 0, kMaxHeight));
|
|
}
|
|
|
|
ENDHLSL
|
|
}
|
|
}
|
|
}
|
|
```
|