C for Graphic:视差渲染(一)

      记录一下最近优化场景的做法:视差渲染
      原理:通过视口坐标的变化,观察不同采样画面的功能,画面的载体为低模平面
      我早期工作,在小作坊全栈的时候,做过一段时间web开发,做了一个古董藏品的h5展示,做法是360度拍摄各个角度的照片,然后在js中通过用户滑动屏幕切换不同角度的古董照片,模拟3d渲染的功能。
      三维引擎中照样也可以使用这招,照片列表可以用大图uv切分或texture3d
      这里我用texture3d,原理以前讲过,这里不再重复
      首先需要写一个camera路径采样objectRT并生成texture3d的工具

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

[ExecuteInEditMode]
public class OpticalParallaxPanoramaTextureCreator : MonoBehaviour
{
    public Camera capCamera;

    public Transform viewPoint;                     //视点
    public Transform fromPos;                       //起点
    public Transform toPos;                         //终点

    public int MAX_SAMPLE_COUNT = 32;               //最大采样次数

    public int sampleWidth = 512;
    public int sampleHeight = 512;

    private float sampleDistance = 0;
    private int sampleCount = 0;

    private Texture2D[] sampleTexes;

    void Start()
    {

    }

#if UNITY_EDITOR
    private void Update()
    {
        Debug.DrawLine(viewPoint.position, fromPos.position, Color.red);
        Debug.DrawLine(viewPoint.position, toPos.position, Color.red);
    }
#endif

    public void OnCreate()
    {
        sampleCount = 0;
        sampleDistance = 0;
        sampleTexes = new Texture2D[MAX_SAMPLE_COUNT];

        for (int i = 0; i < MAX_SAMPLE_COUNT; i++)
        {
            Vector3 wpos = Vector3.Lerp(fromPos.position, toPos.position, (float)i / (float)(MAX_SAMPLE_COUNT - 1));
            capCamera.transform.position = wpos;
            capCamera.transform.LookAt(viewPoint);
            SampleTex();
        }

        CreateTex3D(sampleWidth, sampleHeight, sampleTexes);
    }

    /// <summary>
    /// 采样单张图
    /// </summary>
    public void SampleTex()
    {
        Texture2D tex2d = CaptureCamera(capCamera, sampleWidth, sampleHeight);
        sampleTexes[sampleCount] = tex2d;
        sampleCount++;
    }
    /// <summary>
    /// 组装texture3d
    /// </summary>
    /// <param name="wid"></param>
    /// <param name="hei"></param>
    /// <param name="texarr"></param>
    public void CreateTex3D(int wid, int hei, Texture2D[] texarr)
    {
        Texture3D tex3d = new Texture3D(wid, hei, texarr.Length, TextureFormat.RGBA32, false);

        List<Color> collist = new List<Color>();

        for (int i = 0; i < texarr.Length; i++)
        {
            Color[] cols = texarr[i].GetPixels();
            collist.AddRange(cols);
        }

        tex3d.SetPixels(collist.ToArray());

        tex3d.Apply();

        AssetDatabase.CreateAsset(tex3d, "Assets/OpticalParallax/parallax_tex3d.asset");
        AssetDatabase.Refresh();
    }
    /// <summary>
    /// 采样camera
    /// </summary>
    /// <param name="cam"></param>
    /// <param name="wid"></param>
    /// <param name="hei"></param>
    /// <returns></returns>
    private Texture2D CaptureCamera(Camera cam, int wid, int hei)
    {
        RenderTexture rt = new RenderTexture(wid, hei, 0);

        cam.targetTexture = rt;
        cam.Render();

        RenderTexture.active = rt;
        Texture2D tex = new Texture2D(wid, hei, TextureFormat.ARGB32, false);
        tex.ReadPixels(new Rect(0, 0, wid, hei), 0, 0);
        tex.Apply();

        cam.targetTexture = null;
        RenderTexture.active = null;
        RenderTexture.Destroy(rt);

        return tex;
    }
}

      效果如下:

在这里插入图片描述
      这里两条红线代表可视范围张角
      我采样了32张512*512 RGBA四通道的texture3d,纹理大小达到了32mb,算是比较大了,想要缩小容量,可以降低采样数量、分辨率、RGB三通道

      接下来实现视差渲染效果

Shader "OpticalParallax/OP Panorama UnlitShader"
{
    Properties
    {
        _MainTex ("Texture", 3D) = "white" {}
        _ZDimen("Z Dimension",Range(0,1)) = 0
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 100

        Pass
        {
            Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

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

            struct v2f
            {
                float3 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler3D _MainTex;
            float4 _MainTex_ST;

            float _ZDimen;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = float3(TRANSFORM_TEX(v.uv, _MainTex),_ZDimen);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex3D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
    }
}

      着色器中简简单单一个texture3d zdimention采样

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

public class OPPanoramaPanel : MonoBehaviour
{
    public int MAX_SAMPLE_COUNT = 32;           //最大采样次数

    public Transform viewPoint;                 //使用相对坐标系
    public Transform fromPos;
    public Transform toPos;

    private Transform mainCam;

    public Material mat;

    private Vector3 vp2FromNDir;
    private Vector3 vp2ToNDir;

    public float sampleOffset = 0.5f;

    void Start()
    {
        mainCam = Camera.main.transform;

        vp2FromNDir = fromPos.localPosition.normalized;
        vp2ToNDir = toPos.localPosition.normalized;
    }

    void Update()
    {
        Vector3 vp2cam = mainCam.position - viewPoint.position;
        float vp2camlen = vp2cam.magnitude;
        Vector3 vp2fromext = vp2camlen * vp2FromNDir;
        Vector3 vp2toext = vp2camlen * vp2ToNDir;
        float zdimen = (vp2cam - vp2fromext).magnitude / (vp2toext - vp2fromext).magnitude;
        //texture3d从0-n的纹理储存方式存在起始的0.5的线性插值
        //进行0.5的偏移uv采样,即可保证采样精准
        if (zdimen < 0)
        {
            zdimen = sampleOffset / (float)MAX_SAMPLE_COUNT;
        }
        else if (zdimen > 1)
        {
            zdimen = (float)MAX_SAMPLE_COUNT - sampleOffset / (float)MAX_SAMPLE_COUNT;
        }
        else
        {
            zdimen = (Mathf.FloorToInt(zdimen * (float)MAX_SAMPLE_COUNT) + sampleOffset) / (float)MAX_SAMPLE_COUNT;
        }
        mat.SetFloat("_ZDimen", zdimen);
    }
}

      控制器无非就是根据camerapos进行插值计算。需要注意视点和起始终止相对坐标和texture3d采样配参一致,同时注意因为texture3d的储存方式从0号纹理开始已经有0.5的插值预留,所以我们进行zdimension计算的时候,用0.5的偏移做精准采样,避免模糊。
      最终效果如下:
在这里插入图片描述
      这样就只用一个quad就模拟出从这辆车旁走来走去的感觉
      当然这种“穷举”采样的方式优缺点明显
      优点:视差范围可控,想小就小想大就大,采样方式可自主控制
      缺点:采样纹理过大,所以想要达到正向效果,必须采样的对象是超精细场景或模型,不然得不偿失
      适用范围:比较适合做不用交互但是又要看到的动态场景
      ok,今天到这,后面有时间说一下另外一种视差渲染

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/899547.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【传知代码】机器学习在情绪预测中的应用(论文复现)

在科技迅猛发展的今天&#xff0c;我们不仅在追求更强大的计算能力和更高的精度&#xff0c;还希望我们的机器能够理解和回应我们复杂的情感世界。设想一下&#xff0c;当你面对挫折时&#xff0c;设备不仅能识别你的情绪&#xff0c;还能以一种富有同情心和洞察力的方式作出反…

开放式耳机哪个牌子好?开放式蓝牙耳机排行榜分享

​耳机已经成为我们日常生活中的必需品&#xff0c;但长时间佩戴传统入耳式耳机可能会导致耳朵不适&#xff0c;甚至影响健康。为了应对这一挑战&#xff0c;开放式耳机应运而生。这类耳机不侵入耳道&#xff0c;有效减轻了耳朵的压力&#xff0c;同时减少了感染风险&#xff0…

fmql之Linux中I2C总线框架

正点原子第44章 I2C zynq I2C pcf8563芯片 我们用的是ds3231. Linux I2C总线框架 I2C总线驱动 这部分内容是半导体厂商编写的。 I2C总线设备 zynq I2C适配器驱动 I2C设备驱动编写 使用设备树 代码编写 设备树修改 设备驱动编写 因为用的是ds3231&#xff0c;所以先找…

使用 PyTorch 构建 LSTM 股票价格预测模型

目录 引言准备工作1. 训练模型&#xff08;train.py&#xff09;2. 模型定义&#xff08;model.py&#xff09;3. 测试模型和可视化&#xff08;test.py&#xff09;使用说明模型调整结论 引言 在金融领域&#xff0c;股票价格预测是一个重要且具有挑战性的任务。随着深度学习…

1024软件推荐-rubick

开源的插件化桌面端效率工具箱。插件是基于 npm 进行安装和卸载&#xff0c;非常轻便。插件数据支持 webdav 多端同步&#xff0c;非常安全。支持内网部署&#xff0c;可二次定制化开发&#xff0c;非常灵活。 前言 rubick 之前的插件管理&#xff0c;依托于云服务器存储&…

滴水逆向三期笔记与作业——02C语言——13 指针(3)(4)

滴水逆向三期笔记与作业——02C语言——13 指针3、4 一、模拟实现CE的数据搜索功能 OneNote迁移 一、模拟实现CE的数据搜索功能 //其中有0xAA&#xff0c;超过有符号char范围&#xff0c;在vscode中会报错&#xff0c;所以使用unsigned char unsigned char data[100] {0x00,0…

一起搭WPF架构之完结总结篇

一起搭WPF架构之完结总结篇 前言设计总结设计介绍页面一页面二页面三 结束 前言 整体基于WPF架构&#xff0c;根据自己的需求简单设计与实现了衣橱的数据统计、增加与读取数据、并展示数据的小软件。我知道自己在设计方面还有很多不足&#xff0c;暂时先做到这里了&#xff0c…

gbase8s权限管理

一 权限分类 分片级权限&#xff08;分片表&#xff09; 表引用 类型级权限 例程级权限 语言级权限 序列级权限 等... 其中常用的为 数据库级权限&#xff0c;表级权限&#xff0c;序列级权限以及例程级权限 二 权限控制 当创建一个用户时&#xff0c;该用户没有任何权…

为了数清还有几天到周末,我用python绘制了日历

日历的秘密 昨天&#xff0c;在看小侄子写作业的时候&#xff0c;发现了一个秘密&#xff1a;他在“演算纸”&#xff08;计算数学题用的草纸&#xff09;上画了非常多的日历。对此我感到了非常的困惑&#xff0c;“这是做什么的&#xff1f;” 后来&#xff0c;经过了我不懈…

机器学习面试笔试知识点-线性回归、逻辑回归(Logistics Regression)和支持向量机(SVM)

机器学习面试笔试知识点-线性回归、逻辑回归Logistics Regression和支持向量机SVM 一、线性回归1.线性回归的假设函数2.线性回归的损失函数(Loss Function)两者区别3.简述岭回归与Lasso回归以及使用场景4.什么场景下用L1、L2正则化5.什么是ElasticNet回归6.ElasticNet回归的使…

【设计模式】MyBatis 与经典设计模式:从ORM到设计的智慧

作者&#xff1a;后端小肥肠 &#x1f347; 我写过的文章中的相关代码放到了gitee&#xff0c;地址&#xff1a;xfc-fdw-cloud: 公共解决方案 &#x1f34a; 有疑问可私信或评论区联系我。 &#x1f951; 创作不易未经允许严禁转载。 姊妹篇&#xff1a; 【设计模式】揭秘Spri…

计算机网络:数据链路层 —— 以太网(Ethernet)

文章目录 局域网局域网的主要特征 以太网以太网的发展100BASE-T 以太网物理层标准 吉比特以太网载波延伸物理层标准 10吉比特以太网汇聚层交换机物理层标准 40/100吉比特以太网传输媒体 局域网 局域网&#xff08;Local Area Network, LAN&#xff09;是一种计算机网络&#x…

GitLab-删除仓库分支(删除远程分支)

进入对应仓库选择对应的分支进行删除操作。

为什么学习使用数控加工中心吗?

现代制造业现代制造业对高精度、高效率的加工需求日益增长&#xff0c;数控加工中心作为核心设备&#xff0c;其操作和维护技能成为企业招聘的重要考量。企业需要能够熟练操作数控加工中心&#xff0c;并具备解决复杂加工问题的能力的人才。 学校通过系学习和实践&#xff0c;学…

不用编程,快速实现多台西门子PLC跟三菱PLC之间数据通讯

PLC通讯智能网关IGT-DSER模块支持汇川、西门子、三菱、欧姆龙、罗克韦尔AB、GE等各种品牌的PLC之间通讯&#xff0c;同时也支持PLC与Modbus协议的变频器、智能仪表等设备通讯。网关有多个网口、串口&#xff0c;也可选择WIFI无线通讯。PLC内无需编程开发&#xff0c;在智能网关…

基于SSM健身国际俱乐部系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;场地类别管理&#xff0c;场地信息管理&#xff0c;运动项目管理&#xff0c;场地类型管理&#xff0c;项目类型管理 用户账号功能包括&#xff1a;系统首页&#xff0c;个人中心…

使用SearXNG-搭建个人搜索引擎(附国内可用Docker镜像源)

介绍 SearXNG是聚合了七十多种搜索服务的开源搜索工具。我们可以匿名浏览页面&#xff0c;不会被记录和追踪。作为开发者&#xff0c;SearXNG也提供了清晰的API接口以及完整的开发文档。 部署 我们可以很方便地使用Docker和Docker compose部署SearXNG。下面给出Docker部署Se…

ChartCheck: Explainable Fact-Checking over Real-World Chart Images

论文地址: https://aclanthology.org/2024.findings-acl.828.pdfhttps://aclanthology.org/2024.findings-acl.828.pdf 1.概述 事实验证技术在自然语言处理领域获得了广泛关注,尤其是在针对误导性陈述的检查方面。然而,利用图表等数据可视化来传播信息误导的情况却很少受到…

反弹shell的小汇总

前提 理解正向连接和反向连接 正向连接&#xff1a;客户端主动发起连接到服务器或目标系统客户端充当主动方&#xff0c;向服务器发起连接请求&#xff0c;然后服务器接受并处理请求。 反向连接&#xff1a;目标系统&#xff08;通常是受害者&#xff09;主动建立与控制系统…

手机拍证件照,换正装有领衣服及底色的方法

证件照在我们的职业生涯的关键节点是经常会用到的&#xff0c;比如毕业入职、人事档案建立、升迁履历、执业资格考试和领证等&#xff0c;这些重要的证件照往往要求使用正装照&#xff0c;有时候手头没有合适的衣服&#xff0c;或者原先的证件照背景色不符合要求&#xff0c;就…