- Home /
How do I create a dynamicly spaced and UVed brick wall without having multiple material instances?
Hello, I'm trying to get world space uvs working to create a seamless facade without having to creating a seperate instance for each objects material. Here is an example of what I have achieved.
The red lines indicate seperate gameobjects that share a parent gameobject.
Windows can be added and removed from the facade. This causes seams between the objects if regular uvs are used.
The problem is that I have to pass in the worldToLocal matrix of parent that these objects share. This causes the material to turn into instances of the material.
I need a way to obtain the same effect without having to pass in the shared parents transformation matrix.
Shader "Tri-Planar World" {
Properties {
_Side("Side", 2D) = "white" {}
_SideScale("SideScale", Float) = 2
}
SubShader {
Tags {
"Queue"="Geometry"
"IgnoreProjector"="False"
"RenderType"="Opaque"
}
Cull Back
ZWrite On
CGPROGRAM
#pragma surface surf Lambert
#pragma exclude_renderers flash
sampler2D _Side, _SecondTone;
float _SideScale;
float4x4 _SharedParent;
struct Input {
float3 worldPos;
};
void surf (Input IN, inout SurfaceOutput o) {
float3 vertexPos = mul(_SharedParent, float4(IN.worldPos, 1)).xyz;
float2 texCoord = frac(vertexPos.xy * _SideScale);
o.Albedo = tex2D(_Side, texCoord);
}
ENDCG
}
Fallback "Diffuse"
}
I'm setting the _SharedParent variable through this bit of script.
/// <summary>
/// Set all the shared parent matrix variables in the dynamic uv materials that are child of the component.transform.
/// </summary>
/// <param name="component">Start of material search and set as the shared parent.</param>
protected static void SetWorldUvShaderMatrixInChildren(Component component)
{
Renderer[] renderers = component.GetComponentsInChildren<Renderer>();
foreach (var renderer in renderers)
{
foreach (var mat in renderer.materials)
{
//mat.HasProperty("_SharedParent") does not return true. probably because matrix4x4 is not supported in a property block.
if (mat.name.ToLower().Contains("triuv"))
{
mat.SetMatrix("_SharedParent", component.transform.worldToLocalMatrix);
}
}
}
}
The solution also has to work for rotated surfaces: