- Home /
Colour tinting layered textures with transparencies.
I'm trying to write a simple surface shader that takes several PNG images and layer them one on top of the other. I can do this easily, but the main problem starts when I try to add a colour tint to these images. I'd like to be able to colour tint each image individually so that I can change the colour of the game level in dramatic ways as the game progresses. Unfortunately I'm getting the result where The uppermost texture tints everything the same colour, regardless of what is beneath it.
All textures other than the lowest level have large amounts of transparencies - they're all basically detail textures - and I suspect that my code is colour tinting all pixels of the texture, not just those that are transparent. If I tint the lowest layer green, then the second layer red, everything goes red.
I'm not a coder by any means and much of what I've achieved already has been through copy/pasting of existing code. While I do understand much of what's going on I'm concerned that something I've done earlier is meddling with the output.
Shader "Toon/Toon with Normals and Outline"
{
Properties
{
_BaseColorTint ("Base 1 Color", Color) = (1,1,1,1)
_BaseTex ("Base", 2D) = "white"{}
_PlayAreaColorTint ("Play area color", Color) = (1,1,1,1)
_PlayAreaTex ("Play area", 2D) = "white"{}
_PlayAreaDetailColorTint ("Play area detail color", Color) = (1,1,1,1)
_PlayAreaDetailTex ("Play area detail", 2D) = "white"{}
_Extra1Tint ("Extra 1 color", Color) = (1,1,1,1)
_Extra1Tex ("Extra 1", 2D) = "white"{}
_Extra2Tint ("Extra 2 color", Color) = (1,1,1,1)
_Extra2Tex ("Extra 2", 2D) = "white"{}
_Ramp ("Shading Ramp", 2D) = "gray"{}
_Bump("Bump Map", 2D) = "Bump"{}
_Height("Height", Range (0.0, 2.0)) = 1.5
_Outline ("Outline", Range(0, 0.15)) = 0.08
}
SubShader
{
Tags {"RenderType"="Opaque" }
Pass
{
Cull Front
Lighting Off
ZWrite On
Tags { "LightMode"="ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float3 tangent : TANGENT;
};
struct v2f
{
float4 pos : POSITION;
};
float _Outline;
v2f vert (a2v v)
{
v2f o;
float4 pos = mul( UNITY_MATRIX_MV, v.vertex);
float3 normal = mul( (float3x3)UNITY_MATRIX_IT_MV, v.normal);
normal.z = -0.4;
pos = pos + float4(normalize(normal),0) * _Outline;
o.pos = mul(UNITY_MATRIX_P, pos);
return o;
}
float4 frag (v2f IN) : COLOR
{
return float(0);
}
ENDCG
}
CGPROGRAM
#pragma surface surf Lambert
sampler2D _Ramp;
float _Height;
float _Blend1;
half4 LightingRamp (SurfaceOutput s, half3 lightDir, half atten)
{
half NdotL = dot (s.Normal, lightDir);
half diff = NdotL * 0.5 + 0.5;
half3 ramp = tex2D (_Ramp, float2(diff)).rgb;
half4 c;
c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
c.a = s.Alpha;
return c;
}
struct Input
{
float2 uv_BaseTex;
float2 uv_PlayAreaTex;
float2 uv_PlayAreaDetailTex;
float2 uv_Extra1Tex;
float2 uv_Extra2Tex;
float2 uv_Bump;
};
sampler2D _BaseTex;
sampler2D _PlayAreaTex;
sampler2D _PlayAreaDetailTex;
sampler2D _Extra1Tex;
sampler2D _Extra2Tex;
sampler2D _Bump;
float4 _BaseColorTint;
float4 _PlayAreaColorTint;
float4 _PlayAreaDetailColorTint;
float4 _Extra1Tint;
float4 _Extra2Tint;
void surf (Input IN, inout SurfaceOutput o)
{
fixed4 mainCol = (tex2D(_BaseTex, IN.uv_BaseTex)*_BaseColorTint);
fixed4 texTwoCol = (tex2D(_PlayAreaTex, IN.uv_PlayAreaTex)*_PlayAreaColorTint);
fixed4 output = lerp(mainCol, texTwoCol, 1);
o.Albedo = output.rgb;
// o.Albedo = (tex2D(_BaseTex, IN.uv_BaseTex).rgb*_BaseColorTint) +
// (tex2D(_PlayAreaTex, IN.uv_PlayAreaTex).rgb*_PlayAreaColorTint) +
// (tex2D(_PlayAreaDetailTex, IN.uv_PlayAreaDetailTex).rgb*_PlayAreaDetailColorTint) +
// (tex2D(_Extra1Tex, IN.uv_Extra1Tex).rgb*_Extra1Tint) +
// (tex2D(_Extra2Tex, IN.uv_Extra2Tex).rgb*_Extra2Tint);
// o.Alpha = tex2D(_BaseTex, IN.uv_BaseTex).a +
// tex2D(_PlayAreaTex, IN.uv_PlayAreaTex).a +
// tex2D(_PlayAreaDetailTex, IN.uv_PlayAreaDetailTex).a +
// tex2D(_Extra1Tex, IN.uv_Extra1Tex).a +
// tex2D(_Extra2Tex, IN.uv_Extra2Tex).a;
// o.Alpha = tex2D(_PlayAreaTex, IN.uv_PlayAreaTex).a;
o.Alpha = output.a;
o.Normal = UnpackNormal(tex2D(_Bump, IN.uv_Bump));
float3 normal = UnpackNormal ( tex2D( _Bump, IN.uv_Bump ) );
normal.xy *= _Height;
o.Normal = normalize ( normal );
}
ENDCG
}
Fallback "Diffuse"
}
I've attached an image to illustrate what I'm trying to do and the problem that occurs. The second texture is red, while every other texture is white. The red texture is just for testing, to help me identify the problem; it'll be white for tinting in the final version.
Answer by jameskyle · Jul 30, 2013 at 03:38 PM
Answering my own question here...
I figured out what was wrong. The following line needed to be changed:
fixed4 output = lerp(mainCol, texTwoCol, 1);
to:
fixed4 output = lerp(mainCol, texTwoCol, texTwoCol.a);
As the value acts as a switch on how to blend the two layered pixels, when it was just set to 1 the top layer would colour everything. By using the alpha channel of the top layer I can switch it between prioritising the upper layer when it has colour and the lower layer when it's transparent. Exactly as I wanted. This thread was what pushed me in the right direction...
Your answer
Follow this Question
Related Questions
Changing Eye Colour (Colour only non-white parts of a texture?) 2 Answers
Material doesn't have a color property '_Color' 4 Answers
Fade Shader emit background color 0 Answers
Multiple Texture Colours 2 Answers