Seamless texture shader unlit query

I have no experience with shaders, but it looks like I might have to learn! I just wondered if someone can confirm whether this is possible before I dive in?

I need a shader that will modify uvs in order to “line up” a texture across adjacent objects (2D), so that it looks seamless.

The shader posted in an answer here does what I want, except I don’t need/want lighting. My question is whether this is possible without using a Surface shader? The docs state not to use surface shaders if the surface isn’t using light, I guess for performance.

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
 
sampler2D _MainTex;
float4 _Color;
float _Scale;
 
struct vOut {
float4 texCoords;
};
 
vOut vert ( appdata_base i )
{
vOut o;
float3 worldNormal = normalize( mul( float4( i.normal, 0.0 ), _World2Object ).xyz );
float3 worldPos = mul( UNITY_MATRIX_MVP, i.vertex );
o.texCoords = i.texcoord;

if(worldNormal.y>0.5) UV = o.texCoords.xy = worldPos.xz;
else if(abs(worldNormal.x)>0.5) o.texCoords.xy = worldPos.yz; // side
else o.texCoords.xy = worldPos.xy;

return o;
}

fixed4 frag ( vOut f )
{
fixed4 mainTex = tex2D( _MainTex, f.texCoords.xy * _Scale) * _Color;
return mainTex;
}

ENDCG

That’s a vertex/fragment shader that I think may do something similar to what the subshader does. There may be some errors in places but it’s the basic idea.

Thank you that’s very helpful! I’m working through the errors, but stuck on one at the moment.

Try

fixed4 frag ( vOut f ) : COLOR

Thanks. The texture is now showing and is “seamless”, but the texture “moves” with the camera. I thought using another built in matrix might fix it but no luck.
Thanks for the help and sorry for being a bit useless :slight_smile:

Shader "Custom/SimpleUnlitWorldAligned" {
	Properties { 
	 	_MainTex ("Texture", 2D) = ""
		_Scale ("Texture Scale Multiplier", Float) = 0.1 
	}

	SubShader { 
		Pass {
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag 
			#include "UnityCG.cginc"

			sampler2D _MainTex;
			float _Scale;

			struct vOut {
				float4 texCoords;
				float4 position : POSITION;
			};

			vOut vert ( appdata_base i )
			{
				vOut o;
				o.position = mul (UNITY_MATRIX_MVP, i.vertex);
				
				float3 worldNormal = normalize( mul( float4( i.normal, 0.0 ), _World2Object ).xyz );
				float3 worldPos =  (float3) mul( UNITY_MATRIX_MV, i.vertex );
				o.texCoords = i.texcoord; 

				if(worldNormal.y>0.5) 
					o.texCoords.xy = worldPos.xz; // top
				else if(abs(worldNormal.x)>0.5) 
					o.texCoords.xy = worldPos.yz; // side
				else 
					o.texCoords.xy = worldPos.xy; // front			

				return o;
			}

			fixed4 frag ( vOut f ) : COLOR
			{
				fixed4 mainTex = tex2D( _MainTex, f.texCoords.xy * _Scale);
				return mainTex;
			}

			ENDCG
		}
	}
}

OK this seems to be working. Just one warning now!

vOut vert ( appdata_base i )
{
	vOut o;
	o.position = mul (UNITY_MATRIX_MVP, i.vertex);
	
	float3 worldNormal = normalize( mul( _Object2World, float4( i.normal, 0.0 ) ).xyz );
	float3 worldPos = mul (_Object2World, i.vertex).xyz;
	o.texCoords = i.texcoord; 

	if(worldNormal.y>0.5) 
		o.texCoords.xy = worldPos.xz; // top
	else if(abs(worldNormal.x)>0.5) 
		o.texCoords.xy = worldPos.yz; // side
	else 
		o.texCoords.xy = worldPos.xy; // front			

	return o;
}

Warning:

Will have another look on Monday.

Seems OK now. Here’s the final shader. Don’t ask me if it’s perfect. :stuck_out_tongue:

Shader "Custom/UnlitWorldAligned2D" {
	Properties { 
	 	_MainTex ("Texture", 2D) = ""
		_Scale ("Texture Scale Multiplier", Float) = 0.1 
	}

	SubShader { 
		Pass {
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag 
			#include "UnityCG.cginc"

			sampler2D _MainTex;
			float _Scale;

			struct vOut {
				fixed4 texCoords : TEXCOORD0;
				fixed4 position : POSITION;
			};

			vOut vert (appdata_base i) {
				vOut o;				
				o.position = mul(UNITY_MATRIX_MVP, i.vertex);
				o.texCoords = i.texcoord;
				
				float3 worldPos = mul(_Object2World, i.vertex).xyz;		
		
				// remove comments on following lines for a 3D shader							
		//		float3 worldNormal = normalize(mul(float4(i.normal, 0.0 ), _World2Object).xyz);
		//		if (worldNormal.y > 0.5) 
		//			o.texCoords.xy = worldPos.xz; // top
		//		else if (abs(worldNormal.x) > 0.5) 
		//			o.texCoords.xy = worldPos.yz; // side
		//		else 
					o.texCoords.xy = worldPos.xy; // front			

				return o;
			}

			fixed4 frag (vOut f) : COLOR {
				fixed4 mainTex = tex2D(_MainTex, f.texCoords.xy * _Scale);
				return mainTex;
			}

			ENDCG
		}
	}
}

thank you sooooooooooooo much, thank you sooooo sooo sooo much. i was about to ask a doubt but while typing itself i found the answer. for those who cant get the texture repeated, change the texture from clamped to repeat mode in inspector. thank you soo much guys. love you all

Hey looks it’s 2018 and I just had to tip my hat to Hamstar, Shader works like a dream
<3