Shader "Unlit/DecalGizmos" { Properties { _MainTex ("Texture", 2D) = "white" {} _Color("Color", Color) = (1,1,1,1) _Position("Position", Vector) = (0.5,0.5,0,0) _Rotation("Rotation", Float) = 0 _Scale("Scale", Vector) = (1,1,0,0) _Offset("Scale Offset", Vector) = (0,0,0,0) _DecalTex("Decal Texture", 2D) = "white" {} _UVChannel("UV Channel", Int) = 0 } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent" } LOD 100 Pass { Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv0 : TEXCOORD0; float2 uv1 : TEXCOORD1; float2 uv2 : TEXCOORD2; float2 uv3 : TEXCOORD3; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; float4 _Color; sampler2D _DecalTex; float4 _Position; float _Rotation; float4 _Scale; float4 _Offset; int _UVChannel; float2 remap(float2 x, float2 minOld, float2 maxOld, float2 minNew = 0, float2 maxNew = 1) { return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld); } float2 decalUV(float2 uv, float2 position, half rotation, half rotationSpeed, half2 scale, float4 scaleOffset, float depth) { scaleOffset = float4(-scaleOffset.x, scaleOffset.y, -scaleOffset.z, scaleOffset.w); float2 centerOffset = float2((scaleOffset.x + scaleOffset.y)/2, (scaleOffset.z + scaleOffset.w)/2); float2 decalCenter = position + centerOffset; float theta = radians(rotation + _Time.z * rotationSpeed); float cs = cos(theta); float sn = sin(theta); uv = float2((uv.x - decalCenter.x) * cs - (uv.y - decalCenter.y) * sn + decalCenter.x, (uv.x - decalCenter.x) * sn + (uv.y - decalCenter.y) * cs + decalCenter.y); uv = remap(uv, float2(0, 0) - scale / 2 + position + scaleOffset.xz, scale / 2 + position + scaleOffset.yw, float2(0, 0), float2(1, 1)); return uv; } v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = decalUV(v.uv0, _Position.xy, _Rotation, 0, _Scale.xy, _Offset, 0); return o; } float2 isBox(float2 uv, float2 p1, float2 p2, float2 width) { if (uv.x >= p1.x - width.x && uv.x <= p2.x + width.x && uv.y >= p1.y - width.y && uv.y <= p2.y + width.y) { bool isInside = uv.x >= p1.x + width.x && uv.x <= p2.x - width.x && uv.y >= p1.y + width.y && uv.y <= p2.y - width.y; return float2(1, !isInside ? 1 : 0); } return float2(0, 0); } #define LINE_WIDTH 0.003 #define CORNER_BOX_SIZE 0.02 #define EDGE_BOX_SIZE 0.01 fixed4 frag (v2f i) : SV_Target { fixed4 col = _Color; col.a = 0; float2 aspectAdjust = float2(_Scale.x + _Offset.x + _Offset.y, _Scale.y + _Offset.z + _Offset.w); float2 smallBoxSizeScaled = float2(CORNER_BOX_SIZE / aspectAdjust.x, CORNER_BOX_SIZE / aspectAdjust.y); float2 edgeBoxSizeScaled = float2(EDGE_BOX_SIZE / aspectAdjust.x, EDGE_BOX_SIZE / aspectAdjust.y); float2 lineWidthScaled = float2(LINE_WIDTH / aspectAdjust.x, LINE_WIDTH / aspectAdjust.y); float2 isSmallBox = isBox(i.uv, -smallBoxSizeScaled + float2(0,0), smallBoxSizeScaled + float2(0,0), lineWidthScaled); isSmallBox += isBox(i.uv, -smallBoxSizeScaled + float2(0,1), smallBoxSizeScaled + float2(0,1), lineWidthScaled); isSmallBox += isBox(i.uv, -smallBoxSizeScaled + float2(1,0), smallBoxSizeScaled + float2(1,0), lineWidthScaled); isSmallBox += isBox(i.uv, -smallBoxSizeScaled + float2(1,1), smallBoxSizeScaled + float2(1,1), lineWidthScaled); float2 isEdgeBox = isBox(i.uv, -edgeBoxSizeScaled + float2(0.5,0), edgeBoxSizeScaled + float2(0.5,0), lineWidthScaled); isEdgeBox += isBox(i.uv, -edgeBoxSizeScaled + float2(0,0.5), edgeBoxSizeScaled + float2(0,0.5), lineWidthScaled); isEdgeBox += isBox(i.uv, -edgeBoxSizeScaled + float2(1,0.5), edgeBoxSizeScaled + float2(1,0.5), lineWidthScaled); isEdgeBox += isBox(i.uv, -edgeBoxSizeScaled + float2(0.5,1), edgeBoxSizeScaled + float2(0.5,1), lineWidthScaled); if (isSmallBox.y > 0) col.a = 1; else if (isEdgeBox.x > 0) col.a = 1; else if (isSmallBox.x == 0 && isBox(i.uv, float2(0, 0), float2(1, 1), lineWidthScaled).y) col.a = 1; if(col.a == 0 && i.uv.x >= 0 && i.uv.x <= 1 && i.uv.y >= 0 && i.uv.y <= 1) col = tex2D(_DecalTex, i.uv); return col; } ENDCG } } }