Introducing the smart shader.

Hello,
I have created a shader called a smart shader. What it does is allow you to determine if the texture that it uses is a world texture or an object texture or half and half, or 75/25 etc. and what the rotations of the texture is along with the offset and scale. Object textures are textures that stick to the object, so if the object moves, the textures stays with the object. World textures are textures that stay in one spot, so when the object moves or rotates, the textures don’t.

You can set what kind of a texture it is by the, “World texture level” range bar. If the bar is at the very far left, it is an object texture. If it is at the very far right, it is a world texture. If it is not a world texture, then, “Non world texture rotation” is what to set if you want to rotate the texture, otherwise you can set the xyRotation, xzRotation and yzRotation for world textures.

Setting the X, Y and Z offsets and the Tile Factors are specially made for world textures while setting the image’s tilings and offsets next to the image only effects non world textures.

Another thing I made for smart textures is better alpha control. The “Alpha” setting is for the overall alpha and can be anywhere between 1 and 0. The “Alpha color” tool is the color that when everything is calculated, if the texture matches the alpha color, the alpha becomes 0, so you can have an image with a green background and select that shade of green for the alpha color. The “Alpha color range” is like in Photoshop. Set it to 0 to not use the alpha color. Increase the alpha color range and notice that more areas have 0 alpha. The alpha texture has nothing to do with these settings, and these settings have nothing to do with the alpha texture.

The alpha texture is what determines what part of the overall image is transparent, what part isn’t and what part is semi-transparent depending on the alpha image’s black and white color scale. Hue color is what strengthens the dark and bright colors. When using rotations, rotations are based from 0 to 1. 1 means that it is 360 degrees. Here is the code…

Shader “Smart shader” {
Properties
{
_Color (“Main Color”, Color) = (1,1,1,1)
_HueColor (“Hue Color”, Color) = (1,1,1,1)
_MainTex(“Texture”, 2D) = “white” {}
_AlphaTex(“Alpha Texture”, 2D) = “white” {}
_AlphaColor (“Alpha Color”, Color) = (1,1,1,1)
_AlphaColorRange (“Alpha Color Range”, Float) = 0
_Alpha(“Alpha”, Float) = 1
_TileFac(“Tile factor”, Float) = 5
_xOffset(“X Offset”, Float) = 0
_yOffset(“Y Offset”, Float) = 0
_zOffset(“Z Offset”, Float) = 0
_xyRotation(“XY World Rotation”, Float) = 0
_xzRotation(“XZ World Rotation”, Float) = 0
_yzRotation(“YZ World Rotation”, Float) = 0
_imgRotation(“Non world texture Rotation”, Float) = 0
_worldTexture(“World texture level”, Range(0,1)) = 0
}

SubShader {
Tags {“Queue”=“Transparent” “RenderType”=“Transparent”}

Blend SrcAlpha OneMinusSrcAlpha

CGPROGRAM
#pragma surface surf Lambert
#pragma target 3.0

struct Input {
float2 uv_MainTex;
float3 worldPos;
float3 worldNormal;
};

uniform float3 _Color;
uniform float3 _HueColor;
uniform sampler2D _MainTex;
uniform sampler2D _AlphaTex;
uniform float _TileFac;
uniform float _xOffset;
uniform float _yOffset;
uniform float _zOffset;
uniform float _Alpha;
uniform float3 _AlphaColor;
uniform float _AlphaColorRange;
uniform float _xyRotation;
uniform float _xzRotation;
uniform float _yzRotation;
uniform float _imgRotation;
uniform float _worldTexture;

void surf (Input IN, inout SurfaceOutput o) {

float2 s = float2(_TileFac, -_TileFac);

float2 tex0 = IN.worldPos.xy/s;
float2 tex1 = IN.worldPos.zx/s;
float2 tex2 = IN.worldPos.zy/s;

float2 xyOff = float2(_xOffset,_yOffset);
float2 zxOff = float2(_zOffset,_xOffset);
float2 zyOff = float2(_zOffset,_yOffset);

tex0 += xyOff;
tex1 += zxOff;
tex2 += zyOff;

float2 fpos;
float xpos;
float ypos;
xpos = IN.uv_MainTex.x;
ypos = IN.uv_MainTex.y;
fpos.x = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_imgRotation6.28))) + (((.5 - ypos) * 1.0 / 1) * sin((_imgRotation6.28)));
fpos.y = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_imgRotation6.28)+1.57)) + (((.5 - ypos) * 1.0 / 1) * sin((_imgRotation6.28)+1.57));

xpos = tex0.x;
ypos = tex0.y;
tex0.x = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_xyRotation6.28))) + (((.5 - ypos) * 1.0 / 1) * sin((_xyRotation6.28)));
tex0.y = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_xyRotation6.28)+1.57)) + (((.5 - ypos) * 1.0 / 1) * sin((_xyRotation6.28)+1.57));

xpos = tex1.x;
ypos = tex1.y;
tex1.x = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_xzRotation6.28))) + (((.5 - ypos) * 1.0 / 1) * sin((_xzRotation6.28)));
tex1.y = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_xzRotation6.28)+1.57)) + (((.5 - ypos) * 1.0 / 1) * sin((_xzRotation6.28)+1.57));

xpos = tex2.x;
ypos = tex2.y;
tex2.x = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_yzRotation6.28))) + (((.5 - ypos) * 1.0 / 1) * sin((_yzRotation6.28)));
tex2.y = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_yzRotation6.28)+1.57)) + (((.5 - ypos) * 1.0 / 1) * sin((_yzRotation6.28)+1.57));

float4 color0_ = tex2D(_MainTex, (tex0 * _worldTexture)+(fpos * (1 - worldTexture)));
float4 color1
= tex2D(_MainTex, (tex1 * _worldTexture)+(fpos * (1 - worldTexture)));
float4 color2
= tex2D(_MainTex, (tex2 * _worldTexture)+(fpos * (1 - _worldTexture)));

float4 color0a_ = tex2D(_AlphaTex, (tex0 * _worldTexture)+(fpos * (1 - worldTexture)));
float4 color1a
= tex2D(_AlphaTex, (tex1 * _worldTexture)+(fpos * (1 - worldTexture)));
float4 color2a
= tex2D(_AlphaTex, (tex2 * _worldTexture)+(fpos * (1 - _worldTexture)));

IN.worldNormal = normalize(IN.worldNormal);
float3 projnormal = saturate(pow(IN.worldNormal*1.5, 4));

float3 color = lerp(color1_, color0_, projnormal.z);
color = lerp(color, color2_, projnormal.x);

float3 colora = lerp(color1a_, color0a_, projnormal.z);
colora = lerp(colora, color2a_, projnormal.x);

float3 ca = colora;

float alp = ((ca.r+ca.b+ca.g)/3);

float3 c = color;

if ((3 - (abs(c.r - _AlphaColor.r)+abs(c.g - _AlphaColor.g)+abs(c.b - _AlphaColor.b))) > (3 - (_AlphaColorRange * 1.0 / 33))) {
alp = 0;
}

c.r = (.5 - ((.5 - c.r) * 5 * _HueColor.r)) * _Color.r;
c.b = (.5 - ((.5 - c.b) * 5 * _HueColor.b)) * _Color.b;
c.g = (.5 - ((.5 - c.g) * 5 * _HueColor.g)) * _Color.g;
color = c;

o.Albedo = color;
o.Alpha = _Alpha*alp;
}

ENDCG
}

Fallback “Diffuse”
}

I have added to my “smart shader” the ability to use ranges instead of having to type in numbers in each box. I also added another range bar called “Auto detect alpha color” which I plan on making the alpha color the most frequently used color in the main image so that virtually, the background color of the image becomes transparent. If the range bar is at 0 (to the left) the alpha color is the selected alpha color. If it is 1 (to the right), the alpha color is so far, the top-left most pixel of the image. I want to hopefully make it one day the most frequently used color. Here is the new shader code so far…

Shader “Smart shader” {
Properties
{
_Color (“Main Color”, Color) = (1,1,1,1)
_HueColor (“Hue Color”, Color) = (1,1,1,1)
_MainTex(“Texture”, 2D) = “white” {}
_AlphaTex(“Alpha Texture”, 2D) = “white” {}
_imgRotation(“Non world texture Rotation”, Range(0,1)) = 0
_AutoAlpha(“Auto detect alpha color”, Range(0,1)) = 1
_AlphaColor (“Alpha Color”, Color) = (1,1,1,1)
_AlphaColorRange (“Alpha Color Range”, Range(0,255)) = 0
_Alpha(“Overall alpha”, Range(0,1)) = 1
_TileFac(“World Texture Tile factor”, Float) = 5
_xOffset(“World Texture X Offset”, Range(0,1)) = 0
_yOffset(“World Texture Y Offset”, Range(0,1)) = 0
_zOffset(“World Texture Z Offset”, Range(0,1)) = 0
_xyRotation(“World Texture XY World Rotation”, Range(0,1)) = 0
_xzRotation(“World Texture XZ World Rotation”, Range(0,1)) = 0
_yzRotation(“World Texture YZ World Rotation”, Range(0,1)) = 0
_worldTexture(“World texture level”, Range(0,1)) = 0
}

SubShader {
Tags {“Queue”=“Transparent” “RenderType”=“Transparent”}

Blend SrcAlpha OneMinusSrcAlpha

CGPROGRAM
#pragma surface surf Lambert
#pragma target 3.0

struct Input {
float2 uv_MainTex;
float3 worldPos;
float3 worldNormal;
};

uniform float3 _Color;
uniform float3 _HueColor;
uniform sampler2D _MainTex;
uniform sampler2D _AlphaTex;
uniform float _TileFac;
uniform float _xOffset;
uniform float _yOffset;
uniform float _zOffset;
uniform float _Alpha;
uniform float3 _AlphaColor;
uniform float _AlphaColorRange;
uniform float _xyRotation;
uniform float _xzRotation;
uniform float _yzRotation;
uniform float _imgRotation;
uniform float _worldTexture;
uniform float _AutoAlpha;
uniform float4 autoColor = float4(0,0,0,0);

void surf (Input IN, inout SurfaceOutput o) {

autoColor = tex2D(_MainTex, float2(0.0,0.0));

float2 s = float2(_TileFac, -_TileFac);

float2 tex0 = IN.worldPos.xy/s;
float2 tex1 = IN.worldPos.zx/s;
float2 tex2 = IN.worldPos.zy/s;

float2 xyOff = float2(_xOffset,_yOffset);
float2 zxOff = float2(_zOffset,_xOffset);
float2 zyOff = float2(_zOffset,_yOffset);

tex0 += xyOff;
tex1 += zxOff;
tex2 += zyOff;

float2 fpos;
float xpos;
float ypos;
xpos = IN.uv_MainTex.x;
ypos = IN.uv_MainTex.y;
fpos.x = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_imgRotation6.28))) + (((.5 - ypos) * 1.0 / 1) * sin((_imgRotation6.28)));
fpos.y = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_imgRotation6.28)+1.57)) + (((.5 - ypos) * 1.0 / 1) * sin((_imgRotation6.28)+1.57));

xpos = tex0.x;
ypos = tex0.y;
tex0.x = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_xyRotation6.28))) + (((.5 - ypos) * 1.0 / 1) * sin((_xyRotation6.28)));
tex0.y = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_xyRotation6.28)+1.57)) + (((.5 - ypos) * 1.0 / 1) * sin((_xyRotation6.28)+1.57));

xpos = tex1.x;
ypos = tex1.y;
tex1.x = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_xzRotation6.28))) + (((.5 - ypos) * 1.0 / 1) * sin((_xzRotation6.28)));
tex1.y = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_xzRotation6.28)+1.57)) + (((.5 - ypos) * 1.0 / 1) * sin((_xzRotation6.28)+1.57));

xpos = tex2.x;
ypos = tex2.y;
tex2.x = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_yzRotation6.28))) + (((.5 - ypos) * 1.0 / 1) * sin((_yzRotation6.28)));
tex2.y = .5 - (((.5 - xpos) * 1.0 / 1) * cos((_yzRotation6.28)+1.57)) + (((.5 - ypos) * 1.0 / 1) * sin((_yzRotation6.28)+1.57));

float4 color0_ = tex2D(_MainTex, (tex0 * _worldTexture)+(fpos * (1 - worldTexture)));
float4 color1
= tex2D(_MainTex, (tex1 * _worldTexture)+(fpos * (1 - worldTexture)));
float4 color2
= tex2D(_MainTex, (tex2 * _worldTexture)+(fpos * (1 - _worldTexture)));

float4 color0a_ = tex2D(_AlphaTex, (tex0 * _worldTexture)+(fpos * (1 - worldTexture)));
float4 color1a
= tex2D(_AlphaTex, (tex1 * _worldTexture)+(fpos * (1 - worldTexture)));
float4 color2a
= tex2D(_AlphaTex, (tex2 * _worldTexture)+(fpos * (1 - _worldTexture)));

IN.worldNormal = normalize(IN.worldNormal);
float3 projnormal = saturate(pow(IN.worldNormal*1.5, 4));

float3 color = lerp(color1_, color0_, projnormal.z);
color = lerp(color, color2_, projnormal.x);

float3 colora = lerp(color1a_, color0a_, projnormal.z);
colora = lerp(colora, color2a_, projnormal.x);

float3 ca = colora;

float alp = ((ca.r+ca.b+ca.g)/3);

float3 c = color;

float3 aColor = _AlphaColor;
aColor = aColor - ((aColor - autoColor.rgb) * (_AutoAlpha));

if ((3 - (abs(c.r - aColor.r)+abs(c.g - aColor.g)+abs(c.b - aColor.b))) > (3 - (_AlphaColorRange * 1.0 / 33))) {
alp = 0;
}

c.r = (.5 - ((.5 - c.r) * 5 * _HueColor.r)) * _Color.r;
c.b = (.5 - ((.5 - c.b) * 5 * _HueColor.b)) * _Color.b;
c.g = (.5 - ((.5 - c.g) * 5 * _HueColor.g)) * _Color.g;
color = c;

o.Albedo = color;
o.Alpha = _Alpha*alp;
}

ENDCG
}

Fallback “Diffuse”
}