问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Unity3D实现红外热成像效果

创作时间:
作者:
@小白创作中心

Unity3D实现红外热成像效果

引用
CSDN
1.
https://blog.csdn.net/zouxin_88/article/details/124181857

在Unity3D中实现红外热成像效果是一个有趣且实用的技术挑战。本文将详细介绍如何通过设置图层、创建相机、使用RenderTexture、编写C#脚本以及创建shader等步骤,实现一个基本的红外热成像效果。

实现步骤

  1. 设置图层
    将需要在红外图像中高亮的物体设置到图层PostProcessing。

  2. 创建相机CameraHighLight
    新建一个相机CameraHighLight,设置其Culling Mask为PostProcessing,这样在这个相机中只有PostProcessing图层的物体可见。

  3. 创建RenderTexture
    新建一个RenderTexture,命名为HightLightRt,将CameraHighLight的Target Texture设为HightLightRt。

  4. 创建相机Camera2
    新建一个相机Camera2,这个相机用于显示其他物体。

  5. 合并灰度图
    接下来将CameraHighLight和Camera2中画面转化为两张灰度图,再合并成一张图。合并的过程使用OnRenderImage函数,该函数中使用shader的片断着色器处理,取到两张图相同位置的像素后,谁的灰度值高就取谁的亮度。为了突出CameraHighLight的物体,取Camera2中像素时将适当缩小亮度值。

  6. 创建C#脚本ThermalVision.cs
    新建C#脚本ThermalVision.cs,将ThermalVision.cs挂载到Camera2。

    using UnityEngine;
    public class ThermalVision : MonoBehaviour
    {
        public bool IsInverse = false;
        public RenderTexture OtherTex;
        private Material material1;
        private Material material2;
        // Creates a private material used to the effect
        void Awake()
        {
            material1 = new Material(Shader.Find("Hidden/Thermal1"));
            material2 = new Material(Shader.Find("Hidden/Thermal2"));
        }
        // Postprocess the image
        void OnRenderImage(RenderTexture source, RenderTexture destination)
        {
            if (IsInverse)
            {
                material1.SetTexture("_OtherTex", OtherTex);
                Graphics.Blit(source, destination, material1);
            }
            else
            {
                material2.SetTexture("_OtherTex", OtherTex);
                Graphics.Blit(source, destination, material2);
            }
        }
    }
    
  7. 创建shader
    新建两个shader,分别为Thermal1、Thermal2,一个为白色模式,一个为黑色模式。

    Shader "Hidden/Thermal1" {
        Properties{
            _MainTex("Base (RGB)", 2D) = "white" {}
            _OtherTex("Other (RGB)", 2D) = "white" {}
        }
        SubShader{
            Pass {
                CGPROGRAM
                #pragma vertex vert_img
                #pragma fragment frag
                #include "UnityCG.cginc"
                uniform sampler2D _MainTex;
                uniform sampler2D _OtherTex;
                float4 frag(v2f_img i) : COLOR {
                    fixed4 renderTex = tex2D(_MainTex, i.uv);
                    fixed4 OtherTex = tex2D(_OtherTex, i.uv);
                    fixed gray1 = 0.2125 * renderTex.r + 0.7154 * renderTex.g + renderTex.b;
                    fixed gray2 = 0.2125 * OtherTex.r + 0.7154 * OtherTex.g + OtherTex.b;
                    fixed maxgr = gray1 * 0.1* step(gray2, gray1) + gray2 * step(gray1, gray2);
                    //fixed maxgr = max(gray1, gray2);
                    fixed3 grayColor = float3(maxgr, maxgr, maxgr);
                    float4 result = renderTex;
                    result.rgb = grayColor;
                    return result;
                }
                ENDCG
            }
        }
    }
    
    Shader "Hidden/Thermal2" {
        Properties{
            _MainTex("Base (RGB)", 2D) = "white" {}
            _OtherTex("Other (RGB)", 2D) = "white" {}
        }
        SubShader{
            Pass {
                CGPROGRAM
                #pragma vertex vert_img
                #pragma fragment frag
                #include "UnityCG.cginc"
                uniform sampler2D _MainTex;
                uniform sampler2D _OtherTex;
                float4 frag(v2f_img i) : COLOR {
                    fixed4 renderTex = tex2D(_MainTex, i.uv);
                    fixed4 OtherTex = tex2D(_OtherTex, i.uv);
                    fixed gray1 = 0.2125 * renderTex.r + 0.7154 * renderTex.g + renderTex.b;
                    fixed gray2 = 0.2125 * OtherTex.r + 0.7154 * OtherTex.g + OtherTex.b;
                    fixed maxgr = gray1 * 0.5* step(gray2, gray1) + gray2 * step(gray1, gray2);
                    fixed3 grayColor = float3(maxgr, maxgr, maxgr);
                    float4 result = renderTex;
                    result.rgb = float3(1- grayColor.r, 1 - grayColor.g, 1 - grayColor.b);
                    return result;
                }
                ENDCG
            }
        }
    }
    

最终效果

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号