单相机做分屏混合

2023-11-15

  做了一个单相机实现分屏混合的功能, 需求大概就是在同一视角下, 相机通过不同的CullingMask获取不同的渲染图片RenderTexture之后, 通过某种方式一起显示在界面的功能. 其实核心逻辑就是怎样用一个相机渲染不同的图片罢了, 直接上代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class BlendRenderTexture : MonoBehaviour
{
    public enum BlendDirection
    {
        Horizontal = 0,
        Vertical = 1
    }

    [SerializeField]
    [Range(0, 1)]
    public float blend = 0.5f;
    [SerializeField]
    public BlendDirection blendDirection = BlendDirection.Horizontal;
    [SerializeField]
    public LayerMask tagLayerMask;
    [SerializeField]
    public RenderingTools.BlendRenderTextureTarget blendRenderTextureTarget;

    private bool m_grabbing = false;

    private void OnEnable()
    {
        if(blendRenderTextureTarget == null)
        {
            blendRenderTextureTarget = new RenderingTools.BlendRenderTextureTarget("Unlit/BlendRenderTexture");
        }
    }
    private void OnDisable()
    {
        if(blendRenderTextureTarget != null)
        {
            blendRenderTextureTarget.Release();
        }
    }

    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if(m_grabbing)
        {
            m_grabbing = false;
            Graphics.Blit(src, dest);
            return;
        }
        if(blendRenderTextureTarget.renderTexture && blendRenderTextureTarget.material)
        {
            blendRenderTextureTarget.material.SetTexture("_Left", src);
            blendRenderTextureTarget.material.SetTexture("_Right", blendRenderTextureTarget.renderTexture);
            blendRenderTextureTarget.material.SetFloat("_Blend", Mathf.Clamp01(blend));
            blendRenderTextureTarget.material.SetInt("_Direction", (int)blendDirection);
            Graphics.Blit(src, dest, blendRenderTextureTarget.material);
        }
        else
        {
            Graphics.Blit(src, dest);
        }
    }

    private void LateUpdate()
    {
        RenderTargetTexture();
    }
    
    public void RenderTargetTexture()
    {
        var material = blendRenderTextureTarget.GetMaterial();
        if (m_grabbing = material)
        {
            var lastMask = Camera.main.cullingMask;
            var lastTex = Camera.main.targetTexture;
            Camera.main.cullingMask = tagLayerMask;
            Camera.main.targetTexture = blendRenderTextureTarget.GetRenderTexture();
            Camera.main.Render();
            Camera.main.cullingMask = lastMask;
            Camera.main.targetTexture = lastTex;
        }      
    }
}

  在LateUpdate中请求目标图片渲染, 标记了m_grabbing之后, 调用到OnRenderImage, 直接就把目标渲染图片输出到我们的临时RenderTexture上了, 然后再通过正常渲染时调用OnRenderImage之后, 就会通过Material进行混合了.

BlendRenderTextureTarget 只是一个资源的封装:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public static class RenderingTools
{
    [System.Serializable]
    public class BlendRenderTextureTarget
    {
        [SerializeField]
        public Material material = null;
        [SerializeField]
        public string shaderName = string.Empty;

        public RenderTexture renderTexture { get; set; }

        public BlendRenderTextureTarget(string shaderName)
        {
            this.shaderName = shaderName;
        }

        public Material GetMaterial()
        {
            if(material == false)
            {
                var shader = Shader.Find(shaderName);
                if(shader)
                {
                    material = new Material(shader);
                    material.hideFlags = HideFlags.DontSave;
                }
            }
            return material;
        }

        public RenderTexture GetRenderTexture()
        {
            if(renderTexture)
            {
                if(renderTexture.width != Screen.width || renderTexture.height != Screen.height)
                {
                    RenderTexture.ReleaseTemporary(renderTexture);
                    renderTexture = null;
                }
            }
            if(renderTexture == false)
            {
                renderTexture = RenderTexture.GetTemporary(Screen.width, Screen.height, 24, RenderTextureFormat.ARGB32);
                renderTexture.hideFlags = HideFlags.DontSave;
            }
            return renderTexture;
        }

        public void Release()
        {
            if(renderTexture)
            {
                RenderTexture.ReleaseTemporary(renderTexture);
                renderTexture = null;
            }
            if(material)
            {
                material = null;
            }
        }
    }
}

 

  混用用到的Shader也很简单:

Shader "Unlit/BlendRenderTexture"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _Left("Texture", 2D) = "white" {}
        _Right("Texture", 2D) = "white" {}
        _Blend("Blend", Range(0,1)) = 0.5
        [Enum(Horizontal,0,Vertical,1)] _Direction("Blend Direction", Float) = 0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog
            
            #include "UnityCG.cginc"

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            sampler2D _Left;
            sampler2D _Right;
            float _Blend;
            float _Direction;
            
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target
            { 
                fixed4 col = 1;
                // sample the texture
                bool blend_left = (_Direction == 0) ? (i.uv.x <= _Blend) : (i.uv.y <= _Blend);
                if (blend_left)
                {
                    col = tex2D(_Left, i.uv);
                }
                else 
                {
                    col = tex2D(_Right, i.uv);
                }                
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);

                return col;
            }
            ENDCG
        }
    }
}

  

转载于:https://www.cnblogs.com/tiancaiwrk/p/11611578.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单相机做分屏混合 的相关文章

  • Macbook Pro 鼠标卡顿问题

    Macbook Pro 鼠标卡顿问题 目前无解 只能改善 该问题最早能追溯到 2015年 https jingyan baidu com article ff42efa93632c5c19e220208 html 原因 据说是无线频段冲突
  • 手把手教会机器学习(一)——特征工程

    Python机器学习 一 特征工程 特征工程 特征 Feature 当建立预测模型时 用以对结构经行分析预判 且与预测对象有较大相关性的变量 特征提取 Feature Extraction 特征的提取应注意避免提取到相关含义的变量 避免提取
  • mysql基本语句:DML(数据操作语言)

    目录 DML语言 1 INSERT 添加数据语句 2 UPDATE 更新数据语句 3 SQL中的运算符 4 DELETE 删除数据语句 DML语言 DML 数据操作语言 用于操作数据库对象中所包含的数据 DML包括 INSERT 添加数据语
  • dbeaver对数据进行可视化编辑

    进入数据编辑界面 然后在操作栏上点击编辑即可看到
  • java学习路线

    Java 学习路线 Java 学习路线一条龙版 by 程序员鱼皮 建议先观看视频导读 https www bilibili com video BV1Qf4y1K7ff 大纲 路线特点 最新 完整一条龙的大厂 Java 学习路线 从入门到入
  • 遥感影像分类之SVM

    目录 一 背景简介 二 环境介绍 三 分类步骤 3 1 训练数据预处理 3 2 导入相关扩展包 3 2 读取训练数据与训练标签 3 3 确定参数g和c 3 4 使用svm训练模型 3 5 使用模型进行分类 四 分类结果显示与保存 4 1 结
  • Thread类创建线程

    目录 1 在java中执行多线程编辑 1 1通过Thread类创建线程 1 2创建线程方法2 1 3创建线程方法3 1 4创建线程方法4 1 5创建线程方法5 2 多线程执行效率 2 1两个变量同时自增 3 Thread常见构造方法和属性
  • Git(三):暂存区处理与分支

    5 Git 操作 5 1 隐藏 Stash 在 Git 中 隐藏操作将能够修改跟踪文件 阶段更改 并将其保存在一系列未完成的更改中 并可以随时重新应用 当更改了文件的内容后 通过 git status 对跟踪文件进行检查 现在 要切换分支以
  • 使用预训练模型进行图片分类

    前言 TensorFlow js中加载预训练模型进行图片分类预测 项目结构 data mobileNet web model group1 shard1of1 bin model json mobileNet imagenet classe
  • 编写一个可跨平台的Logger模块

    编写项目时 不可避免要使用到日志模块 有时候还是十分有帮助的 用过的比较好的有log4cpp和其他一些 不多做介绍 这里也只是和大家分享以及记录自己编写的一个小的实用log模块而已 ccompat h ifndef CCOMPAT H de
  • 基于二阶锥规划的主动配电网最优潮流求解(Matlab代码实现)

    目录 1 概述 2 运行结果 3 Matlab代码 数据 详细文章讲解 4 参考文献 1 概述 文献来源 近年来 主动配电网发展受到了越来越多的关注 同时 各类分布式能源 distributed ener rgy resource DER
  • C++数据结构——哈希表

    文章目录 1 unordered map unordered set 2 底层结构 2 1哈希概念 2 3常见哈希函数 2 4 哈希冲突 3 闭散列 开放定址法 3 1线性探测 3 2闭散列扩容 载荷因子 3 3二次探测 4 开散列 4 1
  • 使用AI,做抖音漫画短视频,4个人2天的工作量,1人仅需5小时即可完成

    3 天前 ChatGPT云炬学长 关注 之前仅用一个多月就在抖音涨粉25w 虽然涨粉速度还可以 但账号至少需要4 5个人 其中包括1个文案 2个漫画师 一个剪辑师 一个运营 才能保证日更 一条视频至少需要2天时间 而2个漫画师就需要1天时间
  • 一个通过摄像头识别植物的python小程序

    安装必要的库 你需要安装 OpenCV 和 Tensorflow 库 你可以使用 pip 命令在终端中安装它们 pip install opencv python pip install tensorflow 收集数据 你需要收集一些不同植
  • React初级之大数计算器(二)函数组件

    废话少说 上代码 import React useState from react import BigNumber from bignumber js import styled from styled components const
  • Golang gin 框架在中间件中获取请求和响应的各种数据

    为 gin 框架做不同用途的中间件时一般都需要获取到请求体和响应体的一些数据 例如做签名插件需要获取到请求参数 请求内容和 header 做鉴权插件需要获取到 header 的某些值 做日志插件需要的数据就更多了 下面就使用代码演示各种数据
  • 基于SpringBoot的在线题库管理系统的设计与实现(源码+lw+部署文档+讲解等)

    前言 博主介绍 全网粉丝10W CSDN特邀作者 博客专家 CSDN新星计划导师 全栈领域优质创作者 博客之星 掘金 华为云 阿里云 InfoQ等平台优质作者 专注于Java 小程序技术领域和毕业项目实战 精彩专栏 推荐订阅 2023 20
  • 路径规划算法:基于战争策略优化的路径规划算法- 附代码

    路径规划算法 基于战争策略优化的路径规划算法 附代码 文章目录 路径规划算法 基于战争策略优化的路径规划算法 附代码 1 算法原理 1 1 环境设定 1 2 约束条件 1 3 适应度函数 2 算法结果 3 MATLAB代码 4 参考文献 摘
  • 两种方法实现用CSS切割图片只取图片中一部分

    http www jb51 net css 150036 html 切割图片这里不是真正的切割 只是用CSS取图片中的一部分而已 主要有两种方式 一是做为某一元素的背景图片 二是用img元素的属性 下面有个不错的示例 大家可以参考下 切割图
  • java跳转控制语句continue、break用法和Java语句的for循环嵌套

    java跳转控制语句continue和break用法 continue 结束这一次循环 break 结束整个循环 实例 package day4 continue 跳出本次循环 break 跳出整个循环 public class shift

随机推荐

  • WindowsAPI实现远程调启exe可执行程序,C++实现

    10 winAPI调用外部可执行程序 cpp 定义控制台应用程序的入口点 include stdafx h include
  • 【scala】IDEA运行scala程序:Error:scalac: bad option: ‘-make:transitive‘

    1 概述 转载 原文链接 https blog csdn net qq 38617531 article details 87935460 2 问题描述 IDEA运行scala程序报错 Error scalac bad option mak
  • NeuralEnhance: 提高图像分辨率的深度学习模型

    NeuralEnhance是使用深度学习训练的提高图像分辨率的模型 使用Python开发 项目地址 https github com alexjc neural enhance 貌似很多电影都有这样的情节 对看不清的低分辨率图像 车牌 面部
  • lattice diamond软件使用

    1 diamond软件破解 lisence坚果云下载 或者这个博主操作 环境变量设置 2 调用IP 有两种方式 依据芯片或者软件版本改变 传统的IPexpress 每个IP单独例化 新出的Clarity 多个IP在同一个顶层内调用 再将这个
  • [1148]python3.6使用ansible报Python 3.6 is no longer supported错

    ansible version usr local lib python3 6 site packages ansible parsing vault init py 44 CryptographyDeprecationWarning Py
  • Java中判断List集合中是否有重复元素的方法

    package cn tedu test import java util ArrayList import java util HashSet import java util List public class TestList pub
  • 移动适配的另一种方式—— vw / vh

    前言 哦吼 之前我们对移动适配的其中一种方式 rem 进行了学习 当时在学习的时候我们有提到过另一种的适配方式 那么今天 我们就一起来对移动适配的另一种方式 vw vh 进行学习 我们在学习了rem后 知道他是相对单位 而且是相对于根元素H
  • 关于无法卸载和安装VISIO2010的问题

    之前装个Visio2010突然就打不开了 并且最可恨的是 每次打开word编辑转化搜狗输入法就会提示什么安装错误程序停止工作问是否继续 虽然点击确定后不影响word的使用 但每次都这样就很闹心了 试了用软件助手强力卸载不行 采用window
  • 用豪斯霍尔德(Householder)变换进行矩阵的QR分解,及其Matlab和OpenCV实现

    1 豪斯霍尔德变换 一般地 对给定的 m m m维向量 a a a 考虑分块 a
  • 【目标检测】基于yolov5海上船舶目标检测(附代码和数据集)

    Hello 大家好 我是augustqi 今天给大家分享的目标检测项目是 基于yolov5海上船舶目标检测 附代码和数据集 Part1 前言 传统的海上目标检测是通过雷达来实现 但是随着技术的发展 各种隐形涂料的船舰层出不穷 通过雷达进行目
  • Java中的线程中断

    Java中的线程中断 1 线程中断相关方法介绍 Java多线程编程中的interrupt 方法 isInterrupted 方法和interrupted 方法都是跟线程中断相关的方法 都非常重要 这三个方法名称非常相似 不理解原理时容易混淆
  • 秋招笔试题——嵌入式软件开发

    某VO 给定一个非空字符串str 在最多可以删除一个字符的情况下 请编程判定其能否成为回文字符串 如果可以则输出首次删除一个字符所能得到的回文字符串 如果不行则输出字符串 false bool isSpecial char string i
  • C++ 类与对象 面向对象编程 继承

    https www bilibili com video BV1et411b73Z p 127https www bilibili com video BV1et411b73Z p 127 继承是面向对象三大特性之一 我们发现 定义一些类时
  • WordPress计数插件

    这几天在折腾这个blog 无非是加些插件改点代码 折腾的成果基本就是大家看到的这样了 可能国外用户不关心post的访问人数 WP基本功能里没有显示多少个views的功能 这时候就需要WP PostViews插件帮忙 我的WP版本比较高 安装
  • java中的异常 最详细的讲解

    一 异常的概念 异常 在程序执行的过程中 出现的非正常情况 最终会导致JVM非正常停止 在Java等面向对象的编程语言中 异常本身是一个类 产生异常就是创建异常对象并抛出了一个异常对象 Java处 理异常的方式是中断处理 异常指的并不是语法
  • Nginx基本入门

    本文转载至 http blog csdn net u012486840 article details 53098890 1 静态HTTP服务器 首先 Nginx是一个HTTP服务器 可以将服务器上的静态文件 如HTML 图片 通过HTTP
  • [leetcode] 适合打劫银行的日子 -前缀和

    题目链接 前缀和思想 用数组 l l l 表示前面有多少个数满足 a i
  • MySQL----内置函数

    MySQL gt 内置函数 函数 将经常使用的代码封装起来 需要的时候直接调用就可以 从函数定义角度 函数可分为 内置函数 系统内置的通用函数 自定义函数 需要根据需求编写的函数 MySQL提供的内置函数从实现的功能角度可以分为数值函数 字
  • 多益视频面试

    多益面试 有一种怀疑人生的感觉 向老师 我对不起你 去年刚学的网络安全 我竟然没说出来加密算法的名字 也并不是题很难 而是简单的就是说不出来 写不出来 而难的也就是听过而已 问题 1 说一下什么是线程安全 线程安全的场景 线程安全就是确保程
  • 单相机做分屏混合

    做了一个单相机实现分屏混合的功能 需求大概就是在同一视角下 相机通过不同的CullingMask获取不同的渲染图片RenderTexture之后 通过某种方式一起显示在界面的功能 其实核心逻辑就是怎样用一个相机渲染不同的图片罢了 直接上代码