I'm trying to texture atlas in realtime, with 5 smaller texture2Ds to be placed on a larger base texture2D...
This shader code only shows the first texture and not the others - and even though it is smaller, seems to scale to size of base texture.
Is what I am trying to do possible with shaders? How do we fix / do this?
Shader "Custom/OverlayShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_OverlayTex0 ("Overlay Texture 0", 2D) = "white" {}
_OverlayTex1 ("Overlay Texture 1", 2D) = "white" {}
_OverlayTex2 ("Overlay Texture 2", 2D) = "white" {}
_OverlayTex3 ("Overlay Texture 3", 2D) = "white" {}
_OverlayTex4 ("Overlay Texture 4", 2D) = "white" {}
_OverlayPos0 ("Overlay Position 0", Vector) = (0,0,0,0)
_OverlayPos1 ("Overlay Position 1", Vector) = (0,0,0,0)
_OverlayPos2 ("Overlay Position 2", Vector) = (0,0,0,0)
_OverlayPos3 ("Overlay Position 3", Vector) = (0,0,0,0)
_OverlayPos4 ("Overlay Position 4", Vector) = (0,0,0,0)
_OverlayAspectRatio0 ("Overlay Aspect Ratio 0", float) = 1.0
_OverlayAspectRatio1 ("Overlay Aspect Ratio 1", float) = 1.0
_OverlayAspectRatio2 ("Overlay Aspect Ratio 2", float) = 1.0
_OverlayAspectRatio3 ("Overlay Aspect Ratio 3", float) = 1.0
_OverlayAspectRatio4 ("Overlay Aspect Ratio 4", float) = 1.0
_MainAspectRatio ("Main Texture Aspect Ratio", float) = 1.0
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
sampler2D _OverlayTex0;
sampler2D _OverlayTex1;
sampler2D _OverlayTex2;
sampler2D _OverlayTex3;
sampler2D _OverlayTex4;
float4 _OverlayPos0;
float4 _OverlayPos1;
float4 _OverlayPos2;
float4 _OverlayPos3;
float4 _OverlayPos4;
float _OverlayAspectRatio0;
float _OverlayAspectRatio1;
float _OverlayAspectRatio2;
float _OverlayAspectRatio3;
float _OverlayAspectRatio4;
float _MainAspectRatio;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 mainColor = tex2D(_MainTex, i.uv);
fixed4 overlayColor0 = tex2D(_OverlayTex0, (i.uv - _OverlayPos0.xy) * (_OverlayAspectRatio0 / _MainAspectRatio));
fixed4 overlayColor1 = tex2D(_OverlayTex1, (i.uv - _OverlayPos1.xy) * (_OverlayAspectRatio1 / _MainAspectRatio));
fixed4 overlayColor2 = tex2D(_OverlayTex2, (i.uv - _OverlayPos2.xy) * (_OverlayAspectRatio2 / _MainAspectRatio));
fixed4 overlayColor3 = tex2D(_OverlayTex3, (i.uv - _OverlayPos3.xy) * (_OverlayAspectRatio3 / _MainAspectRatio));
fixed4 overlayColor4 = tex2D(_OverlayTex4, (i.uv - _OverlayPos4.xy) * (_OverlayAspectRatio4 / _MainAspectRatio));
fixed4 overlayColor = overlayColor0.a > 0 ? overlayColor0 : (overlayColor1.a > 0 ? overlayColor1 : (overlayColor2.a > 0 ? overlayColor2 : (overlayColor3.a > 0 ? overlayColor3 : (overlayColor4.a > 0 ? overlayColor4 : mainColor))));
return overlayColor;
}
ENDCG
}
}
}
```
Graphics.CopyTexture
. This does a direct GPU-side block copy of just the rectangle of pixels covered by the source at a given offset, rather than invoking complex shader logic for every pixel in the destination texture, so it will scale better as you increase the number of images in your atlas. \$\endgroup\$Graphics.Blit
, which can handle blending the masks rather than replacing whole rectangles. \$\endgroup\$