识别Unity着色器中的特定材质? (例如,用于热视觉)

时间:2018-03-24 06:47:58

标签: unity3d shader

如果我有一个Unity着色器作为基本的全屏幕图像滤镜,那么有没有办法(在制作材料发光/无阴影之外)“识别”材质的特定像素?假设我想要一个热视觉过滤器,并允许特定物体被认为是“热”。像素颜色着色器怎么能检查它们的颜色或其他任何东西并理解“这很热”? (如果我使它发光/无阴影,我可以将特定属性编码为微妙的rgb更改,例如,如果所有rgb都以*。*** 5结束,那将意味着热,但是这不适用于应用着色。)谢谢!

enter image description here

1 个答案:

答案 0 :(得分:1)

首先,你应该将你的图像转换为灰度,然后将颜色光谱应用于它。如果你看下面的图像, 更接近白色更暖和更接近黑色更冷。 然后您可以使用Replacement Shader添加此效果。

HeatMap

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
}
}
}

让我们再看一遍:

首先,您应该将图像转换为灰度。

Grayscale

然后尝试通过以下方法重新着色:

HeatMap Shader

使用ZBuffer

  

在计算机图形学中,z缓冲(也称为深度缓冲)是3D图形中图像深度坐标的管理,通常在硬件中完成,有时在软件中完成。   https://en.wikipedia.org/wiki/Z-buffering

Heat Vision

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
        }
    }
}