Sunday, July 2, 2017

unity - How to make a palette swap shader that works withn non-pixel art sprites?



I´m trying to build a tool inside Unity that allows our artists to create different color palettes for our characters.


The big problem is that since every single sprite is hand-drawn and hand-painted with different brushes there are no "traditional" color palettes defined for our base sprites. We use around 10-15 base colors for our characters but each character has tons of different shades and saturation variants to their base color on every frame (again, the art is brush-painted like).


Since color indexing is not really an option (unless I want to create a really big color index texture with a gazillion colors) I was wondering if there was a way to create a shader that, given a set of "base colors" and an equivalent color palette, swaps every "similar color" of the character with the color from the new palette (i.e. swap every single reddish color within a tolerance range with a newly defined color).


The goal here is to do this on a shader in real time. I could just write a script that does this and generates a new spritesheet with the swapped colors, but managing one spritesheet per character variation (we aim to have 10 variations per character) is really problematic for our workflow.


I really hope you can help me. I've been trying to find an answer for this for a week.



Answer



Chroma key effect used for removing colors but you can change colors Instead of removing them.



Chroma key compositing, or chroma keying, is a visual effects / post-production technique for compositing (layering) two images or video streams together based on color hues (chroma range). The technique has been used heavily in many fields to remove a background from the subject of a photo or video – particularly the newscasting, motion picture and videogame industries. https://en.wikipedia.org/wiki/Chroma_key




Here Is the Chroma Key Shader for non-pixel art sprites :


RGB ColorFul


ColorReplacement


Shader "SmkGames/ColorReplacement"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}



[HideInInspector] _color("Color", Color) = (1.0,1.0,1.0,1.0)

[HideInInspector]_Red("Filter Color 1", Color) = (1.0,0,0,1.0) //Red
[HideInInspector]_Green("Filter Color 2", Color) = (0,1.0,0,1.0) //Green
[HideInInspector]_Blue("Filter Color 3", Color) = (0,0,1.0,1.0) //Blue
[HideInInspector]_Yellow("Filter Color 4", Color) = (1.0,1.0,0,1.0) //Yellow
[HideInInspector]_Purple("Filter Color 5", Color) = (1.0,0,1.0,1.0) //Purple
[HideInInspector]_Cyan("Filter Color 6", Color) = (0,1.0,1.0,1.0) //Cyan
[HideInInspector]_White("Filter Color 7", Color) = (1.0,1.0,1.0,1.0) //Cyan



_ColorReplacement1("Red", Color) = (1.0,0,0,1.0) //Red
_LerpValue1("_LerpValue1",Range(0,1)) = 0
_ColorReplacement2("Green", Color) = (0,1.0,0,1.0) //Green
_LerpValue2("_LerpValue2",Range(0,1)) = 0
_ColorReplacement3("Blue", Color) = (0,0,1.0,1.0) //Blue
_LerpValue3("_LerpValue3",Range(0,1)) = 0
_ColorReplacement4("Yellow", Color) = (1.0,1.0,0,1.0) //Yellow
_LerpValue4("_LerpValue4",Range(0,1)) = 0
_ColorReplacement5("Purple", Color) = (1.0,0,1.0,1.0) //Purple

_LerpValue5("_LerpValue5",Range(0,1)) = 0
_ColorReplacement6("Cyan", Color) = (0,1.0,1.0,1.0) //Cyan
_LerpValue6("_LerpValue5",Range(0,1)) = 0
_ColorReplacement7("White", Color) = (1.0,1.0,1.0,1.0) //White
_LerpValue7("_LerpValue6",Range(0,1)) = 0
}

SubShader
{
Tags {"Queue" = "Transparent"} ZWrite Off Blend SrcAlpha OneMinusSrcAlpha

LOD 100

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"


uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
fixed4 _color;

//MainColors
uniform float4 _Red;
uniform float4 _Green;
uniform float4 _Blue;
uniform float4 _Yellow;
uniform float4 _Purple;

uniform float4 _Cyan;
uniform float4 _White;

//Colors Replacement
uniform float4 _ColorReplacement1;
uniform float4 _ColorReplacement2;
uniform float4 _ColorReplacement3;
uniform float4 _ColorReplacement4;
uniform float4 _ColorReplacement5;
uniform float4 _ColorReplacement6;

uniform float4 _ColorReplacement7;



uniform float _LerpValue1;
uniform float _LerpValue2;
uniform float _LerpValue3;
uniform float _LerpValue4;
uniform float _LerpValue5;
uniform float _LerpValue6;

uniform float _LerpValue7;

float _LerpValue;


struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};


struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};



v2f vert (appdata v)

{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}

half dis(float4 c){
half result = (pow(_color.r - c.r,2.0)+pow(_color.g - c.g,2.0)+pow(_color.b - c.b,2.0));
return result;

}

fixed4 frag (v2f i) : Color
{
_color = tex2D(_MainTex, i.uv);

if(_color.a<=0.15){
return half4(0,0,0,0);
}


float4 transparent = float4(0,0,0,0);
float4 Red = lerp(_ColorReplacement1,transparent,smoothstep(0,_LerpValue1,dis(_Red)));
float4 Green = lerp(_ColorReplacement2,transparent,smoothstep(0,_LerpValue2,dis(_Green)));
float4 Blue = lerp(_ColorReplacement3,transparent,smoothstep(0,_LerpValue3,dis(_Blue)));
float4 Yellow = lerp(_ColorReplacement4,transparent,smoothstep(0,_LerpValue4,dis(_Yellow)));
float4 Purple = lerp(_ColorReplacement5,transparent,smoothstep(0,_LerpValue5,dis(_Purple)));
float4 Cyan = lerp(_ColorReplacement6,transparent,smoothstep(0,_LerpValue6,dis(_Cyan)));
float4 White = lerp(_ColorReplacement7,transparent,smoothstep(0,_LerpValue7,dis(_White)));

return _color + (Green + Red + Blue + Yellow + Purple + Cyan + White);

}
ENDCG
}
}
}

useful links: Chroma Key Shader 2 , Chroma Key Shader 1


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...