如果我有一个Unity着色器作为基本的全屏幕图像滤镜,那么有没有办法(在制作材料发光/无阴影之外)“识别”材质的特定像素?假设我想要一个热视觉过滤器,并允许特定物体被认为是“热”。像素颜色着色器怎么能检查它们的颜色或其他任何东西并理解“这很热”? (如果我使它发光/无阴影,我可以将特定属性编码为微妙的rgb更改,例如,如果所有rgb都以*。*** 5结束,那将意味着热,但是这不适用于应用着色。)谢谢!
答案 0 :(得分:1)
首先,你应该将你的图像转换为灰度,然后将颜色光谱应用于它。如果你看下面的图像, 更接近白色更暖和更接近黑色更冷。 然后您可以使用Replacement Shader添加此效果。
Shader"Hidden/HeatMap"{
Properties{
_MainTex("_MainTex", 2D) = "white"{}
_Amount("Amount",Float) = 1
[Toggle]_Enable("Enable",Float) = 1
}
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct appdata{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float _Amount,_Enable;
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed greyScale(fixed3 rgb) {
return dot(rgb, fixed3(0.29, 0.60, 0.11));
}
fixed3 heatMap(fixed greyValue) {
fixed3 heat = fixed3(0,0,0);
heat.r = smoothstep(0.4, 0.8, greyValue);
half OutColorGreen = smoothstep(0.0, 0.7, greyValue);
half InColorGreen = smoothstep(1.0, 0.7, greyValue);
heat.g = min(InColorGreen,OutColorGreen);
float OutColorBlue = smoothstep(1.0, 0.0, greyValue);
float InColorBlue = smoothstep(0.0, 0.25, greyValue);
heat.b = min(OutColorBlue,InColorBlue);
return heat;
}
fixed4 frag(v2f i) : COLOR{
fixed2 uv = i.uv;
fixed3 mainTex = tex2D(_MainTex, uv).rgb;
fixed grayValueA = greyScale(mainTex);
fixed3 rgbOut;
rgbOut = heatMap(uv.y);
rgbOut = heatMap(grayValueA * _Amount);
return fixed4(lerp(mainTex,rgbOut,_Enable),1);
}ENDCG
}
}
}
让我们再看一遍:
首先,您应该将图像转换为灰度。
然后尝试通过以下方法重新着色:
在计算机图形学中,z缓冲(也称为深度缓冲)是3D图形中图像深度坐标的管理,通常在硬件中完成,有时在软件中完成。 https://en.wikipedia.org/wiki/Z-buffering
using UnityEngine;
[ExecuteInEditMode]
public class CameraScript : MonoBehaviour {
public Material mat;
void Start()
{
GetComponent<Camera>().depthTextureMode = DepthTextureMode.Depth;
}
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Graphics.Blit(source, destination, mat);
}
}
Shader "Custom/HeatVision"
{
SubShader
{
Tags { "RenderType"="Opaque" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float4 screenuv : TEXCOORD1;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.screenuv = ComputeScreenPos(o.pos);
return o;
}
sampler2D _CameraDepthTexture;
fixed greyScale(fixed3 rgb) {
return dot(rgb, fixed3(0.29, 0.60, 0.11));
}
fixed3 heatMap(fixed greyValue) {
fixed3 heat = fixed3(0,0,0);
heat.r = smoothstep(0.4, 0.8, greyValue);
half OutColorGreen = smoothstep(0.0, 0.7, greyValue);
half InColorGreen = smoothstep(1.0, 0.7, greyValue);
heat.g = min(InColorGreen,OutColorGreen);
float OutColorBlue = smoothstep(1.0, 0.0, greyValue);
float InColorBlue = smoothstep(0.0, 0.25, greyValue);
heat.b = min(OutColorBlue,InColorBlue);
return heat;
}
fixed4 frag (v2f i) : SV_Target
{
float2 uv = i.screenuv.xy / i.screenuv.w;
fixed3 mainTex = tex2D(_CameraDepthTexture, uv).rgb;
fixed grayValueA = greyScale(mainTex);
fixed3 rgbOut;
float Intensity = 15;
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv)*Intensity;
rgbOut = heatMap(uv.y);
rgbOut = heatMap(depth);
return float4(rgbOut.rgb,1);
}
ENDCG
}
}
}