So I'm fairly new to the shader and I've been trying to achieve this kind of effect from Ronja Tutorials, but instead of using it for normal mesh object, I'm trying to use it for Screen Space UI Image instead, this is what I've done so far
Shader "UI/CustomScreenSpaceTexture"
{
Properties
{
[PerRendererData] _MainTex ("Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile_local _ UNITY_UI_CLIP_RECT
#pragma multi_compile_local _ UNITY_UI_ALPHACLIP
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
float4 screenPosition : TEXCOORD2;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex;
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
float4 _MainTex_ST;
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.screenPosition = ComputeScreenPos(OUT.vertex);
OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
OUT.color = v.color * _Color;
return OUT;
}
fixed4 frag(v2f IN) : SV_Target
{
float screenAspect = _ScreenParams.x / _ScreenParams.y;
float2 coord = IN.screenPosition.xy / IN.screenPosition.w;
coord.x = coord.x * screenAspect;
coord = TRANSFORM_TEX(coord, _MainTex);
half4 color = tex2D(_MainTex, coord);
color *= _Color;
return color;
}
ENDCG
}
}
}
This is my texture atlas
I was going to use the leftmost image that looks like a grid, the problem is if I use the shader this happened
- The Image uses whole texture instead of the specified one (Yes, I use the texture as atlas so I could use specific child texture)
- Because of the image uses whole texture, I have no control over options like Tiling, like what from Ronja Tutorials has (The option is still there on Image component, but it has no effect)
For comparison, this is what the Image look like if it uses default material/shader
So I'm trying to achieve Screen Space Texture style of mapping so the background will fits nicely if I have more than 1 Image with the different position but using the same texture without worrying the "Visible Seam" but still be able to do something like "Tiling" so I can control how big/small the grid tile is for the whole screen like default example as seen above.
This is what I was trying to solve with the shader
- So how would I achieve that? What part from my shader is wrong? (Again, I'm fairly new, so maybe the whole shader is wrong)