129 lines
3.4 KiB
Plaintext
129 lines
3.4 KiB
Plaintext
|
|
Shader "Hidden/MicroSplatMeshBrush"
|
|
{
|
|
Properties
|
|
{
|
|
_MainTex ("Texture", 2D) = "white" {}
|
|
}
|
|
SubShader
|
|
{
|
|
Tags { "RenderType"="Opaque" }
|
|
LOD 100
|
|
|
|
Pass
|
|
{
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
|
|
#include "UnityCG.cginc"
|
|
|
|
struct appdata
|
|
{
|
|
float4 vertex : POSITION;
|
|
float3 normal : NORMAL;
|
|
float2 uv : TEXCOORD0;
|
|
float2 uv2 : TEXCOORD1;
|
|
};
|
|
|
|
struct v2f
|
|
{
|
|
float4 vertex : SV_POSITION;
|
|
float3 normal : TEXCOORD0;
|
|
float4 brushClipSpace : TEXCOORD1;
|
|
float3 worldPos : TEXCOORD2;
|
|
};
|
|
|
|
sampler2D _MainTex;
|
|
float4x4 _BrushWorldToProjMtx;
|
|
float4x4 _Obj2World;
|
|
float4x4 _Obj2Scale;
|
|
float useUV2;
|
|
float3 _MouseWorldPos;
|
|
float2 _AngleFilter;
|
|
float _IsFill;
|
|
float4 _UVMeshRange;
|
|
float _ProjectionFilter;
|
|
float _BrushSize;
|
|
|
|
half InverseLerp(half x, half y, half v) { return (v-x)/max(y-x, 0.001); }
|
|
half2 InverseLerp(half2 x, half2 y, half2 v) { return (v-x)/max(y-x, half2(0.001, 0.001)); }
|
|
half3 InverseLerp(half3 x, half3 y, half3 v) { return (v-x)/max(y-x, half3(0.001, 0.001, 0.001)); }
|
|
half4 InverseLerp(half4 x, half4 y, half4 v) { return (v-x)/max(y-x, half4(0.001, 0.001, 0.001, 0.001)); }
|
|
|
|
v2f vert (appdata v)
|
|
{
|
|
v2f o;
|
|
float2 uv = v.uv;
|
|
if (useUV2 > 0.5)
|
|
{
|
|
uv = v.uv2;
|
|
}
|
|
|
|
uv = InverseLerp(_UVMeshRange.xy, _UVMeshRange.zw, uv); // remap into range
|
|
|
|
#if UNITY_UV_STARTS_AT_TOP
|
|
uv.y = 1 - uv.y;
|
|
#endif
|
|
uv = uv * 2 - 1;
|
|
o.vertex = float4(uv.xy, 0, 1);
|
|
|
|
// Use the world position to set the texture tiling projection
|
|
float4 worldPos = mul(_Obj2World, mul(_Obj2Scale, v.vertex));
|
|
o.normal = mul(_Obj2World, float4(v.normal, 0)).xyz;
|
|
// Also use the world position to project to the brush camera space
|
|
o.brushClipSpace = mul(_BrushWorldToProjMtx, worldPos);
|
|
o.worldPos = worldPos.xyz;
|
|
return o;
|
|
}
|
|
|
|
fixed4 frag (v2f i) : SV_Target
|
|
{
|
|
// Now, convert the brush clip space to UV coordinate space...
|
|
// Divide by w to which is the perspective divide
|
|
float4 brushClipSpace = i.brushClipSpace / i.brushClipSpace.wwww;
|
|
|
|
// Space is from -1 to +1, remap it
|
|
float2 brushUV = (brushClipSpace.xy + 1) / 2.0;
|
|
|
|
|
|
float4 brushTex = tex2D(_MainTex, brushUV);
|
|
brushTex.a = 1;
|
|
|
|
//float face = (dot(normalize(i.normal), normalize(_WorldSpaceCameraPos - i.worldPos)));
|
|
//if (_ProjectionFilter <= 1)
|
|
//{
|
|
// face = abs(face);
|
|
//}
|
|
|
|
|
|
float str = 1;
|
|
|
|
if (_IsFill > 0.5)
|
|
{
|
|
brushTex.rgb = 1;
|
|
str = 1;
|
|
}
|
|
|
|
float ang = dot(i.normal, float3(0,1,0));
|
|
if (ang < _AngleFilter.x || ang > _AngleFilter.y)
|
|
str = 0;
|
|
|
|
// distance falloff (sharp, it's more of a filter)
|
|
float dist = distance(_MouseWorldPos, i.worldPos);
|
|
if (dist > _BrushSize)
|
|
{
|
|
str = 0;
|
|
}
|
|
|
|
brushTex.rgb *= str;
|
|
brushTex.g = 1;
|
|
return brushTex;
|
|
|
|
}
|
|
ENDCG
|
|
}
|
|
}
|
|
}
|
|
|