430 lines
12 KiB
GLSL
430 lines
12 KiB
GLSL
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
|
|
|
|
Shader "Hidden/Gaia/BaseOperation" {
|
|
|
|
Properties {
|
|
//The main texture
|
|
_MainTex ("Main Texture", any) = "" {}
|
|
//The global mask texture
|
|
_GlobalMaskTex ("Global Mask Texture", any) = "" {}
|
|
//Flag to determine whether the image mask affects the total stamp result (global) or the stamp itself only (local)
|
|
// _ImageMaskIsGlobal("Image Mask is Global", Float) = 0
|
|
//Flag to determine whether the image mask is inverted or not
|
|
//_InvertImageMask("Invert Image Mask", Float) = 0
|
|
//1-pixel high gradient texture to bring the distance mask curve information in the shader
|
|
//_DistanceMaskTex ("Distance Mask Texture", any) = "" {}
|
|
//Flag to determine whether the distance mask affects the total stamp result (global) or the stamp itself only (local)
|
|
//_DistanceMaskIsGlobal("Distance Mask is Global", Float) = 0
|
|
//1-pixel high gradient texture to bring the transform height curve information in the shader
|
|
//_TransformHeightTex ("Transform Height Texture", any) = "" {}
|
|
//the y position of the stamp, in 0 to 1 relative to terrain height
|
|
_yPos ("y Position", Float) = 0
|
|
//the base level of the stamp
|
|
_BaseLevel ("Base Level", Float) = 0
|
|
//Flag to determine whether the base should be stamped or not
|
|
_StampBase("Stamp Base", Float) = 0
|
|
//Flag to determine whether the stamp should be adjusted automatically to the terrain when a base level is used
|
|
_AdaptiveBase("Adaptive Base", Float) = 0
|
|
//Blend strength from 0 to 1 for the blend terrain pass
|
|
//_BlendStrength ("Blend Strength", Float) = 0
|
|
//Erosion texture, contains the original heightmap changed by Erosion
|
|
//_ErosionTex("Erosion Texture", any) = ""
|
|
|
|
}
|
|
|
|
SubShader {
|
|
|
|
ZTest Always Cull Off ZWrite Off
|
|
|
|
CGINCLUDE
|
|
|
|
#include "UnityCG.cginc"
|
|
#include "TerrainTool.cginc"
|
|
|
|
sampler2D _MainTex;
|
|
sampler2D _GlobalMaskTex;
|
|
//float _ImageMaskIsGlobal;
|
|
//float _InvertImageMask;
|
|
//sampler2D _DistanceMaskTex;
|
|
//float _DistanceMaskIsGlobal;
|
|
//sampler2D _TransformHeightTex;
|
|
float _yPos;
|
|
float _BaseLevel;
|
|
float _StampBase;
|
|
float _AdaptiveBase;
|
|
float _BlendStrength;
|
|
//sampler2D _ErosionTex;
|
|
float4 _MainTex_TexelSize; // 1/width, 1/height, width, height
|
|
|
|
sampler2D _BrushTex;
|
|
|
|
float4 _BrushParams;
|
|
#define BRUSH_STRENGTH (_BrushParams[0])
|
|
#define BRUSH_TARGETHEIGHT (_BrushParams[1])
|
|
|
|
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;
|
|
}
|
|
|
|
float ApplyBrush(float height, float brushStrength)
|
|
{
|
|
float targetHeight = BRUSH_TARGETHEIGHT;
|
|
if (targetHeight > height)
|
|
{
|
|
height += brushStrength;
|
|
height = height < targetHeight ? height : targetHeight;
|
|
}
|
|
else
|
|
{
|
|
height -= brushStrength;
|
|
height = height > targetHeight ? height : targetHeight;
|
|
}
|
|
return height;
|
|
}
|
|
|
|
float GetFinalHeight(v2f i)
|
|
{
|
|
float2 brushUV = PaintContextUVToBrushUV(i.pcUV);
|
|
float2 heightmapUV = PaintContextUVToHeightmapUV(i.pcUV);
|
|
float height = UnpackHeightmap(tex2D(_MainTex, heightmapUV));
|
|
// out of bounds multiplier
|
|
float oob = all(saturate(brushUV) == brushUV) ? 1.0f : 0.0f;
|
|
//value from the image mask texture multiplied with the multiplicator
|
|
float globalMaskValue = UnpackHeightmap(tex2D(_GlobalMaskTex, brushUV));
|
|
float brushShape = oob * UnpackHeightmap(tex2D(_BrushTex, brushUV));
|
|
float finalBrushLevel = BRUSH_STRENGTH * brushShape; // * transformheight * localMaskValue;
|
|
|
|
//only return the height value changed by the brush if we are actually in bounds
|
|
//otherwise we get an ugly square base when rotating stamps
|
|
if(all(saturate(brushUV) == brushUV))
|
|
{
|
|
float finalResult = _yPos + finalBrushLevel;
|
|
return clamp(((_yPos + finalBrushLevel) * globalMaskValue) + height * (1.0f - globalMaskValue), 0, 1.0f);
|
|
}
|
|
else
|
|
{
|
|
return height;
|
|
}
|
|
}
|
|
|
|
ENDCG
|
|
|
|
Pass // 0 raise heights
|
|
{
|
|
Name "Raise Heights"
|
|
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment RaiseHeight
|
|
|
|
float4 RaiseHeight(v2f i) : SV_Target
|
|
{
|
|
float2 brushUV = PaintContextUVToBrushUV(i.pcUV);
|
|
float2 heightmapUV = PaintContextUVToHeightmapUV(i.pcUV);
|
|
float height = UnpackHeightmap(tex2D(_MainTex, heightmapUV));
|
|
float finalheight = GetFinalHeight(i);
|
|
|
|
//process baseLevel
|
|
if(_StampBase>0 || finalheight>_BaseLevel)
|
|
{
|
|
if(!all(saturate(brushUV) == brushUV))
|
|
{
|
|
_BaseLevel = 0;
|
|
}
|
|
if(_AdaptiveBase && _BaseLevel > height)
|
|
{
|
|
finalheight -= _BaseLevel - height;
|
|
}
|
|
else
|
|
{
|
|
finalheight = clamp (finalheight, _BaseLevel,0.5f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
finalheight = 0;
|
|
}
|
|
|
|
if(finalheight>=height)
|
|
return PackHeightmap(finalheight);
|
|
else
|
|
return PackHeightmap(height);
|
|
|
|
}
|
|
ENDCG
|
|
}
|
|
|
|
Pass // 1 Lower heights
|
|
{
|
|
Name "Lower Heights"
|
|
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment LowerHeight
|
|
|
|
float4 LowerHeight(v2f i) : SV_Target
|
|
{
|
|
float2 brushUV = PaintContextUVToBrushUV(i.pcUV);
|
|
float2 heightmapUV = PaintContextUVToHeightmapUV(i.pcUV);
|
|
float height = UnpackHeightmap(tex2D(_MainTex, heightmapUV));
|
|
float finalheight = GetFinalHeight(i);
|
|
|
|
//process baseLevel
|
|
if(_StampBase>0 || finalheight<_BaseLevel)
|
|
{
|
|
if(!all(saturate(brushUV) == brushUV))
|
|
{
|
|
_BaseLevel = 0.5f;
|
|
}
|
|
if(_AdaptiveBase && _BaseLevel < height)
|
|
{
|
|
finalheight += height - _BaseLevel;
|
|
}
|
|
else
|
|
{
|
|
finalheight = clamp (finalheight, 0.0f, _BaseLevel);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
finalheight = 0.5f;
|
|
}
|
|
|
|
if(finalheight<=height)
|
|
return PackHeightmap(finalheight);
|
|
else
|
|
return PackHeightmap(height);
|
|
|
|
}
|
|
ENDCG
|
|
}
|
|
|
|
Pass // 2 Blend Heights
|
|
{
|
|
Name "Blend Heights"
|
|
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment BlendHeight
|
|
|
|
float4 BlendHeight(v2f i) : SV_Target
|
|
{
|
|
float2 heightmapUV = PaintContextUVToHeightmapUV(i.pcUV);
|
|
float height = UnpackHeightmap(tex2D(_MainTex, heightmapUV));
|
|
float finalheight = GetFinalHeight(i);
|
|
|
|
return PackHeightmap((finalheight * _BlendStrength) + (height * (1-_BlendStrength)));
|
|
}
|
|
ENDCG
|
|
}
|
|
|
|
Pass // 3 Set Height
|
|
{
|
|
Name "Set Height"
|
|
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment SetHeight
|
|
|
|
float4 SetHeight(v2f i) : SV_Target
|
|
{
|
|
float2 heightmapUV = PaintContextUVToHeightmapUV(i.pcUV);
|
|
float height = UnpackHeightmap(tex2D(_MainTex, heightmapUV));
|
|
float finalheight = GetFinalHeight(i);
|
|
return PackHeightmap(finalheight);
|
|
}
|
|
ENDCG
|
|
}
|
|
|
|
Pass // 4 Add Height
|
|
{
|
|
Name "Add Height"
|
|
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment AddHeight
|
|
|
|
float4 AddHeight(v2f i) : SV_Target
|
|
{
|
|
float2 brushUV = PaintContextUVToBrushUV(i.pcUV);
|
|
float2 heightmapUV = PaintContextUVToHeightmapUV(i.pcUV);
|
|
float height = UnpackHeightmap(tex2D(_MainTex, heightmapUV));
|
|
float oob = all(saturate(brushUV) == brushUV) ? 1.0f : 0.0f;
|
|
if(!oob)
|
|
{
|
|
return height;
|
|
}
|
|
float finalheight = GetFinalHeight(i);
|
|
|
|
|
|
|
|
//add the existing height
|
|
finalheight += height;
|
|
|
|
//process baseLevel
|
|
if(_StampBase>0 || finalheight>_BaseLevel)
|
|
{
|
|
if(!all(saturate(brushUV) == brushUV))
|
|
{
|
|
_BaseLevel = 0;
|
|
}
|
|
if(_AdaptiveBase && _BaseLevel > height)
|
|
{
|
|
finalheight -= _BaseLevel - height;
|
|
}
|
|
else
|
|
{
|
|
finalheight = clamp (finalheight, _BaseLevel,0.5f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
finalheight = 0;
|
|
}
|
|
|
|
if(finalheight>=height)
|
|
return PackHeightmap(finalheight);
|
|
else
|
|
return PackHeightmap(height);
|
|
|
|
|
|
}
|
|
ENDCG
|
|
}
|
|
|
|
Pass // 5 Subrtract Height
|
|
{
|
|
Name "Subtract Height"
|
|
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment SubtractHeight
|
|
|
|
float4 SubtractHeight(v2f i) : SV_Target
|
|
{
|
|
//invert ypos for better usability
|
|
_yPos*=-1;
|
|
|
|
|
|
float2 brushUV = PaintContextUVToBrushUV(i.pcUV);
|
|
float2 heightmapUV = PaintContextUVToHeightmapUV(i.pcUV);
|
|
float height = UnpackHeightmap(tex2D(_MainTex, heightmapUV));
|
|
float oob = all(saturate(brushUV) == brushUV) ? 1.0f : 0.0f;
|
|
if(!oob)
|
|
{
|
|
return height;
|
|
}
|
|
float finalheight = GetFinalHeight(i);
|
|
|
|
//subtract the existing height
|
|
finalheight = height - finalheight;
|
|
|
|
//process baseLevel
|
|
if(_StampBase>0 || finalheight<_BaseLevel)
|
|
{
|
|
if(!all(saturate(brushUV) == brushUV))
|
|
{
|
|
finalheight = height;
|
|
}
|
|
else
|
|
{
|
|
if(_AdaptiveBase && _BaseLevel < height)
|
|
{
|
|
finalheight += height - _BaseLevel;
|
|
}
|
|
else
|
|
{
|
|
finalheight = clamp (finalheight, 0.0f, _BaseLevel);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
finalheight = height;
|
|
}
|
|
|
|
if(finalheight<=height)
|
|
return PackHeightmap(finalheight);
|
|
else
|
|
return PackHeightmap(height);
|
|
|
|
}
|
|
ENDCG
|
|
}
|
|
|
|
//This pass is special in so far as it relies on the heightmap changes being passed in
|
|
//_MainTex, it will not alter the heightmap by itself
|
|
|
|
Pass // 6 Effects
|
|
|
|
{
|
|
Name "Effects"
|
|
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment Effects
|
|
|
|
float4 Effects(v2f i) : SV_Target
|
|
{
|
|
|
|
float2 brushUV = PaintContextUVToBrushUV(i.pcUV);
|
|
float2 heightmapUV = PaintContextUVToHeightmapUV(i.pcUV);
|
|
float height = UnpackHeightmap(tex2D(_MainTex, heightmapUV));
|
|
float finalheight = GetFinalHeight(i);
|
|
return PackHeightmap(finalheight);
|
|
|
|
//float erodedHeight = UnpackHeightmap(tex2D(_ErosionTex, heightmapUV));
|
|
|
|
// out of bounds multiplier
|
|
/*float oob = all(saturate(brushUV) == brushUV) ? 1.0f : 0.0f;
|
|
//value from the image mask texture multiplied with the multiplicator
|
|
float imageMask = UnpackHeightmap(tex2D(_ImageMaskTex, brushUV));
|
|
if(_InvertImageMask>0)
|
|
{
|
|
//Invert the imagemask
|
|
imageMask=1.0f-imageMask;
|
|
}
|
|
|
|
float distanceMask = UnpackHeightmap(tex2D(_DistanceMaskTex, smoothstep(0,sqrt(1)/2,distance(brushUV,float2(0.5f,0.5f)))));
|
|
|
|
|
|
|
|
float globalMaskValue = 1.0f;
|
|
globalMaskValue *= imageMask;
|
|
globalMaskValue *= distanceMask;*/
|
|
|
|
|
|
//only return the height value changed by the brush if we are actually in bounds
|
|
//otherwise we get an ugly square base when rotating stamps
|
|
/*if(all(saturate(brushUV) == brushUV))
|
|
{
|
|
return PackHeightmap(clamp(erodedHeight, 0, 0.5f));
|
|
}
|
|
else
|
|
{
|
|
return PackHeightmap(height);;
|
|
}*/
|
|
|
|
|
|
}
|
|
ENDCG
|
|
}
|
|
|
|
}
|
|
Fallback Off
|
|
}
|