How to map texture across multiple objects?

Hi, I’m in the middle of creating a procedural dungeon that is built out of cubic template models. How do I apply a giant texture that spreads across multiple meshes (multiple models) and that tiles seamlessly (assuming the texture is tiled)? I’m trying to achieve a realistic look and this isn’t possible if each tile has the same, small texture.

Would I have to write my own shader using CG or is this possible without resorting to that?


actually i have done exact same thing for a big block of city, a jungle, a cave… However i didn’t make a shader. What i did was simply inside belender or maya, and put all the uv set in one layout and then applied one single material that had that texture and ofcourse they were all multiple objects. The cave or the road was used in a procedural case. You just have to setup the uvs properly. I hope that helps.

No need to write your own shader, just make your meshes to share the same UV name in your 3D model application.
e.g.: We have a room with 3 meshes: floor, walls and ceiling.
We want to bake a Lightmap in the 3D software and use in these 3 meshes.
You can make 3 UVs with same name like “lm_uv”.
This UV will be shared with the meshes.

Your shader is doing a front projection. Switch to xz for a top projection. Your shader:

void surf (Input IN, inout SurfaceOutput o) {
  float3 worlduv = IN.worldPos;
  o.Albedo = tex2D (_MainTex, worlduv);

The texture lookup (last line) uses a float2. Since your worlduv is a float3, it just slices off the last part and uses worlduv.xy for the lookup, which is a front projection.

For a top down, change the last line to:

tex2D (_MainTex, worlduv.xz); // FYI, yz is a side projection

Of course, that will map the floor just fine, but smear over the sides of walls. [EDIT] If your objects will always have flat sides facing at 0,90,180,270 degrees, you could guess a front/side/top projection using the normal (code has been tested):

struct Input {
float2 uv_MainTex; // unused
float3 worldNormal;
float3 worldPos;

void surf (Input IN, inout SurfaceOutput o) {
  // Guess correct planar map from normal. 0.5 is an arbitrary cutoff
  float2 UV;
  // NOTE: assuming no bottom-facing, otherwise use abs()
  if(IN.worldNormal.y>0.5) UV = IN.worldPos.xz; // top
  else if(abs(IN.worldNormal.x)>0.5) UV = IN.worldPos.yz; // side
  else UV = IN.worldPos.xy; // front

  // 0.1 is an arbitrary x10 texture size scale 
  half4 c = tex2D (_MainTex, UV*0.1);
  o.Albedo = c.rgb;
  o.Alpha = c.a;

The edges all have bad seems, but there’s no way around that.

Hey cabot, what did you end up using in the end?

Also, did you ever get Owen Reynolds world based uv shader to work?