- Home /
Simple infrared shader, how to lerp multiple colors in 4 'stages'?
Hello,
I am working on a simple infrared shader. The basic idea is that it should show a color based on the temperature. I have 4 colors, (black, red, blue and white) the coldest object should shade black, the hottest object should shade white. In between I wanna have a gradient. Each frame i pass the temperature range to the shader. This is the max temperature - min temperature (e.g: range= 500 - 100 = 400)
I made a setup, which shades the right color per 'stage':
this is what i want, but now i want the colors to blend into each other. Because I have 4 colors i decided i needed 3 lerps. That gave me the next result:
The first screen is based on 4 'stages', the second one is based on 3 'stages' because of the 3 lerps. How can i make a shader which blends the colors into each other from the first image?
This is my shader till now:
Shader "Unlit/Infrared" //This shader displays a red gradient
{
Properties{
//define some properties
_Texture("Normal Texture",2D) = "white" {}
_temperature("Temperature",float) = 0.0
_infraOn("Infrared On/Off",int) = 0
_whiteColor("White color",Color) = (1,1,1,1)
_redColor("Red color",Color) = (1,0,0,1)
_blueColor("Blue color",Color) = (0,0,1,1)
_blackColor("Black color",Color) = (0,0,0,1)
_temperatureRange("Temperature range",float) = 0
}
SubShader
{
Tags { "Queue" = "Transparent" } //enable when making transparent texture
Pass
{
Blend SrcAlpha OneMinusSrcAlpha //enable when making transparent texture
CGPROGRAM
//tell CG what functions to use
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
//uniform so the texture stays in for multiple sessions
uniform sampler2D _Texture;
uniform sampler2D _TextureInfrared;
uniform float4 _whiteColor;
uniform float4 _redColor;
uniform float4 _blueColor;
uniform float4 _blackColor;
uniform float _temperature;
uniform float _maxTemperature;
uniform float _minTemperature;
uniform float _temperatureRange;
uniform int _infraOn;
//from unity to shader
struct AppData {
float4 position : POSITION; //right semantics
float4 uv : TEXCOORD0; //
};
//from vertex to fragment
struct VertexToFragment{
float4 position : SV_POSITION;
float4 uv : TEXCOORD0;
float4 objectOrigin : TEXCOORD2;
float3 localPos : TEXTCOORD1;
};
VertexToFragment vert(AppData input){
VertexToFragment output; // define output for fragment shader
output.localPos = input.position; // like position
output.position = mul(UNITY_MATRIX_MVP,input.position); // multiply the position by the matrix model view projection
output.uv = input.uv; // copy uv
//determine center:
output.objectOrigin = unity_ObjectToWorld[3];
return output;
}
//return the right color
float4 frag(VertexToFragment v) : SV_Target{
float normalizedIntensity;
float normalizedTemperature;
float colorIntensity;
float4 color;
if (_infraOn==1) { // return the infrared texture
float4 center = v.objectOrigin;
float distanceToCenter = distance(v.localPos, center); // between 0.5 and 1.0
normalizedTemperature = _temperature / _temperatureRange; // between 0 and 1
colorIntensity = normalizedTemperature * distanceToCenter; // should be between 0 and 1, not sure though
//debug for all intensity colors, the 4 'stages' according to the first screen:
if (colorIntensity >= 0.0f && colorIntensity <= 0.25f) { /// coldest color
color = _blackColor;
}
else if (colorIntensity >= 0.25f && colorIntensity <= 0.5f) { // almost coldest
color = _blueColor;
}
else if (colorIntensity >= 0.5f && colorIntensity <= 0.75f) { // almost hottest
color = _redColor;
}
else if (colorIntensity >= 0.75f && colorIntensity <= 1.0f) { // hottest color
color = _whiteColor;
}
float normalizedIntensity;
//Lerp with 3 stages, according to the second screenshot:
// 4 colors, 3 lerps but normalize intensity to make right gradient.
//works with 1 lerp on each object...
//TODO:: make sure only 1 lerp happens per object
if (colorIntensity >= 0.0f && colorIntensity <= 0.33f) {
normalizedIntensity = colorIntensity / 0.33f;
color = lerp(_blackColor, _blueColor, normalizedIntensity);
}
if (colorIntensity >= 0.33f && colorIntensity <= 0.66f) {
normalizedIntensity = colorIntensity / 0.66f;
color = lerp(_redColor, _blueColor, normalizedIntensity);
}
if (colorIntensity >= 0.66f && colorIntensity <= 1.0f) {
normalizedIntensity = colorIntensity / 1.f;
color = lerp(_redColor, _whiteColor, normalizedIntensity);
}
}
else { // just return the normal texture
color = tex2D(_Texture,v.uv);
}
return color;
}
ENDCG
}
}
}
Thanks in advance! Thomas
just noticed this isn't the right place. is it possible to move this to graphics->shaders?
Your answer
![](https://koobas.hobune.stream/wayback/20220612121541im_/https://answers.unity.com/themes/thub/images/avi.jpg)