unity urp 视差卡牌

总体效果大概四层,从后往前排序为:卡背、背景、画像、边框

首先卡背比较简单,只要判断如果网格的背面就直接采样卡背图片展示即可

资源准备:

然后是背景,网上找到一张这样的图。

但他还不符合要求,我们的背景需要四方接续否则在视差下会看到不连续的接痕。关于如何处理四方接续的图。

首先是把这张图拽进ps里,裁切到512X512,然后在滤镜-其他-位移,将其水平垂直都移动512/2个像素,随后修补接痕位置使其连续即可。

然后是画像,这张图看过我上一个文章的应该很熟悉,而且我认为是很有趣的一件事,推荐去看一眼。Unity图片导入趣事随笔-CSDN博客

最后是边框,直接加在最顶层,这也是图片背景使用黑色的理由。

资源完毕,还需要视差的思路。红色为原本物体的uv位置,绿色是视觉上存在深度后所延长到的uv位置,理论上不需要计算z向量,但为了方便计算,原本物体的uv位置的z分量定为0。在红色上顶点的切线空间中,是右手坐标系,z向量向外,所以深度向量一定为(0,0,-1)根据这两个向量点乘可以求出深度向量和视角向量的cosθ,就可以根据深度反推出视角向量延长的距离,那么原本物体的uv位置 + 视角向量延长的距离就是视觉上存在深度后所延长到的uv位置,随后舍弃z分量就是视觉上存在深度后的uv位置。

这个方法根据输入的原uv坐标、视角向量(切线空间下)和深度来返回视觉上存在深度后的uv坐标

            float2 CalculateRealUVAfterDepth(float2 originUV, float3 viewDirTS, float depth)
            {
                //计算视角方向和深度方向的cos值
                float cosTheta = dot(normalize(viewDirTS), float3(0,0,-1));  //  一般来讲unity是左手坐标系,但在切线和观察空间较为特殊是右手坐标系,不过这并不影响z轴方向的判断
                //根据深度差算出两点间距离
                float dis = depth / cosTheta;
                //算出应用深度差后对应点位
                float3 originUVPoint = float3(originUV, 0);
                float3 afrerDepthUVPoint = originUVPoint + normalize(viewDirTS) * dis;
                //返回应用深度差后对应UV
                return afrerDepthUVPoint.xy;
            }

根据这些视差过后的uv坐标采样图片并叠加,就能做出视觉上有距离感的图片结构。

Shader "Kerzh/Tarol"
{
    Properties
    {
        [Space(50)]
        _FrameTexture("FrameTexture",2D) = "Black"{}
        
        [Space(50)]
        _ParallaxTexture1("Parallax Texture1",2D) = "Black"{}
        _ParallaxDepth1("Parallax Depth1",Float) = 0
        
        [Space(50)]
        _ParallaxTexture2("Parallax Texture2",2D) = "Black"{}
        _ParallaxDepth2("Parallax Depth2",Float) = 0
        _FlowVector2AndSpeed("FlowVector2AndSpeed",Vector) = (0,0,0,0)
        
        [Space(50)]
        _BackTexture("_BackTexture",2D) = "Black"{}
    }
    SubShader
    {
        Tags {"RenderPipeline" = "UniversalRenderPipeline" "Queue" = "Geometry" "RenderType" = "ReplaceMePlease" "ForceNoShadowCasting" = "false" "DisableBatching" = "False" "IgnoreProjector" = "False" "PreviewType" = "Plane"}
        LOD 100

        Pass
        {
            Cull Off
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include  "CommonCgInclude.cginc"

            V2FData vert (MeshData input)
            {
                V2FData output = FillBaseV2FData(input);
                return output;
            }

            sampler2D _FrameTexture;
            float4 _FrameTexture_ST;
            
            sampler2D _ParallaxTexture1;
            float4 _ParallaxTexture1_ST;
            float _ParallaxDepth1;
            
            sampler2D _ParallaxTexture2;
            float4 _ParallaxTexture2_ST;
            float _ParallaxDepth2;
            vector _FlowVector2AndSpeed;

            sampler2D _BackTexture;
            float4 _BackTexture_ST;

            float2 CalculateRealUVAfterDepth(float2 originUV, float3 viewDirTS, float depth)
            {
                //计算视角方向和深度方向的cos值
                float cosTheta = dot(normalize(viewDirTS), float3(0,0,-1));  //  一般来讲unity是左手坐标系,但在切线和观察空间较为特殊是右手坐标系,不过这并不影响z轴方向的判断
                //根据深度差算出两点间距离
                float dis = depth / cosTheta;
                //算出应用深度差后对应点位
                float3 originUVPoint = float3(originUV, 0);
                float3 afrerDepthUVPoint = originUVPoint + normalize(viewDirTS) * dis;
                //返回应用深度差后对应UV
                return afrerDepthUVPoint.xy;
            }
            

            fixed4 frag (V2FData input,float backFace:VFace) : SV_Target
            {
                
                float3 tangentWS = normalize(input.tangentWS);
                float3 normalWS = normalize(input.normalWS);
                float3 bitangentWS = normalize(input.bitangentWS);

                float3 lightDirWS = normalize(UnityWorldSpaceLightDir(input.posWS.xyz));
                float3 viewDirWS = normalize(UnityWorldSpaceViewDir(input.posWS.xyz));

                float2 uv = input.uv;

                //背面处理
                if(backFace<0)
                {
                    float2 backUV = float2(1-uv.x,uv.y);
                    float4 backTextureSample = tex2D(_BackTexture,backUV*_BackTexture_ST.xy + _BackTexture_ST.zw);
                    return backTextureSample;
                }

                //下面都是正面的了
                float3x3 TBN_WS2TS = float3x3(tangentWS,bitangentWS,normalWS);  //  世界-》切线变换矩阵
                float3 viewDirTS = mul(TBN_WS2TS, viewDirWS);
                //为什么需要在切线空间计算呢?因为深度值是相对于切线空间定义的
                //计算经深度值影响过后的uv
                float2 uv1AfterDepth = CalculateRealUVAfterDepth(uv, viewDirTS, _ParallaxDepth1);
                float2 uv2AfterDepth = CalculateRealUVAfterDepth(uv, viewDirTS, _ParallaxDepth2);

                //采样视差图1
                uv1AfterDepth = saturate(uv1AfterDepth);
                float4 _ParallaxTexture1Sample = tex2D(_ParallaxTexture1,uv1AfterDepth*_ParallaxTexture1_ST.xy + _ParallaxTexture1_ST.zw);

                //采样视差图2
                uv2AfterDepth += -_FlowVector2AndSpeed.xy * _Time.y * _FlowVector2AndSpeed.z;
                float4 _ParallaxTexture2Sample = tex2D(_ParallaxTexture2,uv2AfterDepth*_ParallaxTexture2_ST.xy + _ParallaxTexture2_ST.zw);

                //采样边框
                float4 _FrameTextureSample = tex2D(_FrameTexture,uv*_FrameTexture_ST.xy + _FrameTexture_ST.zw);
                
                float4 finalCol = float4(0,0,0,1);
                finalCol = _ParallaxTexture2Sample;
                finalCol = lerp(finalCol,_ParallaxTexture1Sample,_ParallaxTexture1Sample.a);
                finalCol += _FrameTextureSample;

                return finalCol;
            }
            ENDCG
        }
    }
}

库文件:CommonCGinclude.cginc

#ifndef COMMONCGINCLUDE
#define COMMONCGINCLUDE

struct MeshData
{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    float2 uv2 : TEXCOORD1;
    float4 tangentOS :TANGENT;
    float3 normalOS : NORMAL;
    float4 vertexColor : COLOR;
};

struct V2FData
{
    float4 pos : SV_POSITION; // 必须命名为pos ,因为 TRANSFER_VERTEX_TO_FRAGMENT 是这么命名的,为了正确地获取到Shadow
    float2 uv : TEXCOORD0;
    float3 tangentWS : TEXCOORD1;
    float3 bitangentWS : TEXCOORD2;
    float3 normalWS : TEXCOORD3;
    float3 posWS : TEXCOORD4;
    float3 posOS : TEXCOORD5;
    float3 normalOS : TEXCOORD6;
    float4 vertexColor : TEXCOORD7;
    float2 uv2 : TEXCOORD8;
};

V2FData FillBaseV2FData(MeshData input)
{
    V2FData output;
    output.pos = UnityObjectToClipPos(input.vertex);
    output.uv = input.uv;
    output.uv2 = input.uv2;
    output.normalWS = normalize(UnityObjectToWorldNormal(input.normalOS));
    output.posWS = mul(unity_ObjectToWorld, input.vertex);
    output.posOS = input.vertex.xyz;
    output.tangentWS = normalize(UnityObjectToWorldDir(input.tangentOS));
    output.bitangentWS = cross(output.normalWS, output.tangentWS) * input.tangentOS.w; //乘上input.tangentOS.w 是unity引擎的bug,有的模型是 1 有的模型是 -1,必须这么写
    output.normalOS = input.normalOS;
    output.vertexColor = input.vertexColor;
    return output;
}

#endif

在面板上这样赋值即可获得这样的效果

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

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

相关文章

Redis:原理速成+项目实战——Redis实战14(BitMap实现用户签到功能)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;Redis&#xff1a;原理速成项目实战——Redis实战13&#xff08;GEO实现附近商铺、滚动分页查询&#xff09; &#x1f4da;订阅…

计算机网络——应用层(3)

计算机网络——应用层&#xff08;3&#xff09; 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU) 点对点&#xff08;P2P&#xff09;P2P网络一般用途优点缺点总结 套接字编程基本步骤UDP套接字TCP套接字基本步骤 二者对比 小程一言 我的计算机网络专栏&#xff0c;是自…

从数据可视化到场景渲染:山海鲸的创新与实践

作为山海鲸的开发者&#xff0c;我们深知可视化模型场景渲染在数据分析和决策支持中的重要作用。因此在保证山海鲸可视化软件免费编辑、分享、部署的同时也在场景渲染方面不断优化&#xff0c;本文将介绍山海鲸在可视化模型场景渲染方面的技术革新与实践探索。 首先&#xff0…

USB_CH340一键下载电路

目录标题 1、CH340概述2、CH340芯片特点3、CH340系列芯片4、CH340引脚定义5、CH340传统的一键下载电路5.1、Stm32串口下载5.2、ESP32串口下载5.3、注意 6、免外围电路下载 1、CH340概述 CH340是一个USB总线的转接芯片&#xff0c;可实现USB转串口或者USB转打印口。 2、CH340芯…

不要再搞混标准化与归一化啦,数据标准化与数据归一化的区别!!

数据标准化与归一化 1. 数据的标准化&#xff08;Standardization&#xff09;&#xff1a;2. 数据的归一化&#xff08;Normalization&#xff09;&#xff1a;总结&#xff08;数据标准化和数据归一化的不同之处和相同之处&#xff09; 1. 数据的标准化&#xff08;Standardi…

2024趋势:ERP中数据分析的五大要点

2024 年&#xff0c;数据分析不仅仅是 ERP 实施中的一个额外功能;这就像第一步&#xff0c;将最终确定整个 ERP 实施项目的成功之路。忘记笨重的电子表格和无休止的报告——准备好驾驭这五种新兴趋势的浪潮&#xff1a; 一、人工智能和机器学习 (ML) 的兴起 人工智能驱动的数据…

由于找不到vcomp140.dll无法继续执行代码如何修复-亲测有效

本文将详细介绍vcomp140.dll的定义、作用以及丢失的原因和解决方法。 一、vcomp140.dll是什么&#xff1f; vcomp140.dll是Visual C 2015 Redistributable Package的一部分&#xff0c;它是运行某些基于C的应用程序所必需的动态链接库文件。它包含了许多用于支持C编程语言的函…

Go-安装与基础语法

TOC 1. Go 安装与环境变量 1.1 下载 需要从Go语言的官方网站下载适合你操作系统的Go语言安装包。Go语言支持多种操作系统&#xff0c;包括Windows、Linux和Mac OS。 对于Windows用户&#xff0c;下载.msi文件&#xff0c;然后双击该文件&#xff0c;按照提示进行安装即可。…

PADS9.5 : 元件库绘制

元件库绘制 1、打开PADS LOGIC 软件 2、先开始元件的电参数 这理面我们只需要先关注&#xff1a; 门 &#xff0c;就是当前画的元件有几个部分 示例&#xff1a;两个门&#xff1a;A、B 3、再开始编辑图形 选择创建2D线&#xff0c;绘制PARTA 外框 添加端点&#xff0c;就是接…

5.3 Verilog 带参数例化

5.3 Verilog 带参数例化 分类 Verilog 教程 关键词&#xff1a; defparam&#xff0c;参数&#xff0c;例化&#xff0c;ram 当一个模块被另一个模块引用例化时&#xff0c;高层模块可以对低层模块的参数值进行改写。这样就允许在编译时将不同的参数传递给多个相同名字的模块…

通过代理连接sftp

通过nginx代理连接sftp 1.问题描述2.代码实现3.nginx配置3.1 创建sftp.stream文件3.2 修改nginx配置 4.重启nginx生效 1.问题描述 问题是这样的。我们现在需要在微服务所在内网的A机器连接到外网的sftp&#xff0c;但是网络又不能直接到达。然后A机器到B机器是通过的&#xff…

我开源了一个 Go 学习仓库

前言 大家好&#xff0c;这里是白泽&#xff0c;我是21年8月接触的 Go 语言&#xff0c;学习 Go 也正好两年半&#xff0c;我决定重启我之前未完成的计划&#xff0c;继续阅读《The Go Programing Language》&#xff0c;一年多前我更新至第五章讲解的时候&#xff0c;工作的忙…

浅谈当下企业环境下建设企业微电网能效系统的重要性

一 案例介绍 随着新型电力系统进程加快&#xff0c;新能源装机占比逐步提高&#xff0c;发电侧波动性、随机性导致可靠容量降低。加之恶劣天气带动负荷快速增长&#xff0c;造成电力供需紧张、电网尖峰负荷屡创新高&#xff0c;对现有能源供应带来巨大挑战。 国家电投五凌电…

新手入门:软件在测试过程中可能出现哪些问题?走,去看看~

对于很多测试新手来说&#xff0c;想要把自己的测试技术练得更精进&#xff0c;扎实自己的理论知识是必不可少的一门功课。下面&#xff0c;我们就一起来复习一下&#xff0c;那些让我们一知半解或者记不全的理论知识吧。 01 什么是软件测试&#xff1f; 最老套&#xff0c;但…

手写Webpack-Plugin

Plugin原理 一、Plugin作用 通过插件我们可以扩展webpack&#xff0c;使webpack可以执行更广泛的任务&#xff0c;拥有更强的构建能力。 Plugin工作原理 webpack 就像一条生产线&#xff0c;要经过一系列处理流程后才能将源文件转换成输出结果。 这条生产线上的每个处理流程…

LeetCode讲解篇之90. 子集 II

文章目录 题目描述题解思路题解代码 题目描述 题解思路 初始化一个变量start表示当前从哪里开始遍历nums 搜索过程的数字组合加入结果集 从start开始遍历nums 如果当前元素和前一个元素相等&#xff0c;前一个元素没被使用&#xff0c;则触发剪枝去重操作&#xff0c;跳过当…

[蓝桥学习] 并查集

并查集基础 并查集用来存储图中结点的连通关系。 一个点的根结点是该点的父亲的父亲的...父亲&#xff0c;根&#xff1a;某个结点的父亲是自己 当两个点的根相同时&#xff0c;就说他们是同一类的&#xff0c;连通的 找根 但是&#xff0c;如果点特别多且形成链的话&#x…

【MySQL】本地创建MySQL数据库详解

文章目录 下载MySQL安装重置密码本地连接 下载MySQL 下载网址&#xff1a;https://dev.mysql.com/downloads/mysql/ 安装 将下载好的压缩包解压到D盘。 在解压好的文件夹中创建my.ini文件。 将以下代码复制粘贴到创建好的my.ini文件中。注意修改文件路径。 [mysqld] #设置…

2024/1/14周报

文章目录 摘要Abstract文献阅读题目问题与创新方法A.CEMDAN方法B.LSTM网络C. CEEMDAN-LSTM模型 实验过程数据集与数据预处理参数设置评价指标和参数 实验结果 深度学习GRUGRU前向传播GRU的训练过程 总结 摘要 本周阅读了一篇基于CEEMDAN-LSTM的金融时间序列预测模型的文章&…

FineBI实战项目一(22):各省份订单个数及订单总额分析开发

点击新建组件&#xff0c;创建各省份订单个数及订单总额组件。 选择自定义图表&#xff0c;将province拖拽到横轴&#xff0c;将cnt和total拖拽到纵轴。 调节纵轴的为指标并列。 修改横轴和纵轴的标题。 修改柱状图样式&#xff1a; 将组件拖拽到仪表板。 结果如下&#xff1a;…