FourSplatBlendWrapShader

From Unify Community Wiki
Jump to: navigation, search

The following shader blends four textures while wrapping the textures by a power of two times.

FourSplatBlendWrapShader.jpg

COLOR specifies the splat index. With 16 splats, that fits in the 256 range.

TEXCOORD expects barycentric coords.

TEXCOORD1 indicates how many times to wrap the splats.

TEXCOORD and TEXCOORD1 generate semi-random orientations.

The main texture sheet should contain 4x4 splats. I.e. 128x128 splats in a 512x512 texture.

Shader "FourSplatBlendWrapShader" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {} 
	}
	SubShader {
        Pass {

CGPROGRAM

#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

uniform sampler2D _MainTex;

// vertex input: position, uv1, uv2
struct appdata {
    float4 vertex : POSITION;
    float4 texcoord : TEXCOORD0;
    float4 texcoord1 : TEXCOORD1;
    float4 color : COLOR;
};

struct v2f {
    float4 pos : POSITION;
    float4 texcoord : TEXCOORD0;
    float4 texcoord1 : TEXCOORD1;
    float4 color : COLOR;
};

v2f vert (appdata v) {
    v2f o;
    o.pos = mul( glstate.matrix.mvp, v.vertex);
    o.texcoord = v.texcoord;
    o.texcoord1 = v.texcoord1;
    o.color = v.color;
    return o;
}

float GetScaledRemainder(float k, float scaler)
{
	k *= scaler;
	int reduction = k;
	return k-reduction;
}  

float4 GetTileWrapColor(float height, float intensity, float2 uvs, float2 wrap)
{
	int index = 15.99 * height;
	int col = index % 4; // 0 to 3
    int row = height * 3.99; // to 0 to 3
    
    uvs.x = (col+GetScaledRemainder(uvs.x, wrap.x))*0.25;
    uvs.y = (row+GetScaledRemainder(uvs.y, wrap.y))*0.25;

    float4 color = tex2D(_MainTex, uvs);    
    return lerp(float4(0,0,0,0), color, intensity);
}

float4 frag(v2f i) : COLOR
{
	//define the splat colors
	float4 tile1Color;
	float4 tile2Color;
	float4 tile3Color;
	float4 tile4Color;
	
	//introduce varying orientations
	int orientationX = i.texcoord.x * i.texcoord1.x;
	int orientationY = i.texcoord.y * i.texcoord1.y;
	int orientation = (orientationX + orientationY) % 4;
	
   //get the splat colors
   float2 uv;
   if (orientation == 0)
   {
      uv = float2(i.texcoord.x, i.texcoord.y);
   }

   else if (orientation == 1)
   {
      uv = float2(i.texcoord.y, 1-i.texcoord.x);
   }
   
   else if (orientation == 2)
   {
      uv = float2(1-i.texcoord.x, 1-i.texcoord.y);
   }
   
   else
   {
      uv = float2(1-i.texcoord.y, i.texcoord.x);
   }

   // top left
   tile1Color = GetTileWrapColor(i.color.r, (1-i.texcoord.x) * (1-i.texcoord.y), uv, wrapX, wrapZ);

   // top right
   tile2Color = GetTileWrapColor(i.color.g, i.texcoord.x * (1-i.texcoord.y), uv, wrapX, wrapZ);

   // bottom left
   tile3Color = GetTileWrapColor(i.color.b, (1-i.texcoord.x) * i.texcoord.y, uv, wrapX, wrapZ);

   // bottom right
   tile4Color = GetTileWrapColor(i.color.a, i.texcoord.x * i.texcoord.y, uv, wrapX, wrapZ);

   // additive blending
   return tile1Color + tile2Color + tile3Color + tile4Color;
}

ENDCG

        }
	} 
	Fallback "Diffuse", 1
}
Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Tools