Unity | Shader基础知识(第十九集:顶点着色器的进一步理解-易错点讲解)

目录

一、前言

二、网格

三、方法UnityObjectToClipPos

四、顶点着色器和片元着色器的POSITION

五、作者的碎碎念


一、前言

之前我们简单讲解过顶点着色器,也简单讲解了表面着色器,并且一起做了一些案例,因为顶点着色器本身是更自由一些的,后续很多效果是基于顶点着色器之上的,所以我们对顶点着色器做进一步理解。

二、网格

之前讲过,顶点着色器就是把每个顶点上了颜色,然后再上线,再面,所以我们必须了解一下物体的网格。这里以unity常见的平面:Plane和Quad举例。

备注:

如果你想调出来后面的界面,只需要换显示界面为wireframe(线框)。(如图1所示)

图1 线框界面

plane的网格(如图2所示)。

图2 plane的网格

在unity中,无论你的plane有多大,都是由宽10格和高10格的方块组成的,每个方块分成两个三角形。 

Quad的网格(如图3所示)。

图3 quad的网格

同样,无论你的quad有多大,都是由一个方块组成的,方块分成两个三角形。  

所以,我们之前说过,如果需要显示地形之类比较细致的纹理,你就用plane,如果你只是要播放视频,就用quad就足够了,就是这个原因。 


备注:(这里不想看可以不看哦)

在这里我们也可以通过程序来打印出来模型顶点的坐标,代码如下:

    void Start(){//声明网格                获取网格过滤器中的网格Mesh mesh = GetComponent<MeshFilter>().mesh;//把顶点坐标提取出来Vector3[] vertics = mesh.vertices;foreach (Vector3 v in vertics){//打印顶点坐标Debug.Log(v);}}

三、方法UnityObjectToClipPos

之前也粗略说过,unityObjectToClipPos的作用是把3d的坐标,转换成2D的坐标,所以我们在这里可以一起看看,它到底变成了什么。

我们知道在颜色里r通道,0及以下就是黑色,1及以上就是红色。那么,我们只要在顶点方法中,把我们的坐标赋值进去就可以了。代码如下:

Shader "Custom/015"
{SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag//自己写了一个结构体struct appdata{float4 vertex:POSITION;};//自己又写了一个结构体struct v2f{float4 vertex:SV_POSITION;float4 color:COLOR;};v2f vert(appdata v){v2f o;//坐标变换o.vertex = UnityObjectToClipPos(v.vertex);//变换以后吧x的值放到颜色里,我们就可以通过颜色来反推x的值o.color.r = v.vertex.x;return o;}fixed4 frag (v2f i): SV_Target{return i.color;}ENDCG}}
}

把这个shader分别放到plane和quad身上。

quad:

可以明显看到从方块中间到最右边是红色逐渐变深的一个过程,但没有完全变红。(如图4所示)我们并不知道它到底是到了1还是没有到。

图4 方块颜色

为了得出具体数据,我们把shader下方部分做一下修改。我们假设最右边是0.5,如果减去以后没有红色了,就说明它小于等于0.5。

//o.color.r = v.vertex.x;
o.color.r = v.vertex.x-0.5;

于是我们得到了全黑的图。(如图5所示)

图5 全黑

如果我们改成0.4,右边是有红色的。(如图6所示)

图6 稍微有点红色

 那么我们就可以推测出,它的x是从0到0.5,因为是对称的,所以左边就是0到-0.5。 再仔细想一下,这是一个网格组层的,如果边长是1,那么刚好左右各0.5。

plane:

我们可以看到,从黑色到红色过度的部分是0到1,后面的长度刚好是前面的4个那么长,那我们就推测,后面是0到5,前面是-5到0。(如图7所示)

图7 plane的着色

如果你继续测试,会发现你即使放大scale,也是不会改变现在的颜色布局的。

我们可以继续推测出,我们的坐标实际上和我们的网格有关系,这篇文章的第二部分,plane刚好是左边5个右边5个,所以坐标就是左边是-5,右边是5。

四、顶点着色器和片元着色器的POSITION

上面的内容,我们都是把vertex放在顶点着色器中的,如果我们放到片元着色器中,会出现奇怪的现象。代码如下:

Shader "Custom/015"
{SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment fragstruct appdata{float4 vertex:POSITION;};struct v2f{float4 vertex:SV_POSITION;float4 color:COLOR;};v2f vert(appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);//在这里去掉//o.color.r = v.vertex.x;return o;}fixed4 frag (v2f i): SV_Target{//写在这里i.color.r = i.vertex.x;return i.color;}ENDCG}}
}

你就会发现,全红了。(如图8所示)

图8 全红的方块

 然后我们可以和之前一样,通过去减少数字去测试。(测试过程略,自己去测吧,宝子们)

这里直接放结果:

你会发现这里的0在左下角,最右边是1920(如图9所示)

图9 界面

所以,片元着色器中的坐标和顶点着色器中是不一样的, 在这里的坐标已经变成了屏幕坐标,因为我的屏幕分辨率设置的是1920*1080(左上角那里能看见),所以我红色的方块坐标也是按照这个设定了,因为我所有的方块都在0的右边,都是大于1的数,所以都是红色。

结论:顶点坐标系中的坐标是根据网格来计算的,片元着色器中的坐标是按屏幕坐标来的。(片元着色器中的z坐标是0哦,你可以去试试)

五、作者的碎碎念

这一章没有什么应用是不是怪无趣的,但是基础打好了以后,后面才好写啊~

看到这里了,点个赞吧,宝子们~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RT-Thread必考面试题及参考答案

目录 RT-Thread操作系统的核心架构是什么? RT-Thread支持哪些微处理器架构? RT-Thread中任务调度的基本原则是什么? 如何在RT-Thread中创建一个新的线程? RT-Thread中的线程优先级如何影响调度? RT-Thread中的信号量和互斥锁有何区别? 描述一下RT-Thread中消息队列…

【Git多人协作开发】不同的分支下的多人协作开发模式

目录 0.前言背景 1.开发者1☞完成准备工作&协作开发 1.1查看分支情况 1.2创建本地分支feature-1 1.3三板斧 1.4push推本地分支feature-1到远程仓库 2.开发者2☞完成准备工作&协作开发 2.1创建本地分支feature-2 2.2三板斧 2.2push推送本地feature-2到远程仓库…

Sprong Boot学习|使用 guava-retrying 实现重试

背景 后端业务系统可能会在接口调用失败、网络拥塞超时、任务执行失败、系统错误等异常情况出现的时候进行重试操作&#xff0c;然而不同的场景对于重试的延迟间隔&#xff0c;频次等会有不同的要求&#xff0c;如果自己编排重试代码会比较繁琐&#xff0c;使用 guava-retryin…

LeetCode:合并2个有序数组(C语言)

1、2个非递减排序的整数数组nums1和nums2&#xff0c;2个整数m和n&#xff0c;代表nums1和nums2中的元素个数。合并nums2到nums1&#xff0c;合并后的数组也进行非递减排序 2、示例 示例 1&#xff1a; 输入&#xff1a;nums1 [1,2,3,0,0,0], m 3, nums2 [2,5,6], n 3 输出…

springSecurity学习之springSecurity web如何取得用户信息

web如何取得用户信息 之前说过SecurityContextHolder默认使用的是ThreadLocal来进行存储的&#xff0c;而且每次都会清除&#xff0c;但是web每次请求都会验证用户权限&#xff0c;这是如何做到的呢&#xff1f; 这是通过SecurityContextPersistenceFilter来实现的&#xff0…

FineBI连接MySQL5.7

一、在FineBI系统管理中&#xff0c;点击【新建数据库连接】 选择MySQL数据库 配置数据库连接&#xff0c;如下&#xff0c;其中数据库名称就是需要连接的目标数据库

《昇思 25 天学习打卡营第 21 天 | LSTM+CRF序列标注模型实现 》

《昇思 25 天学习打卡营第 21 天 | LSTMCRF序列标注模型实现 》 活动地址&#xff1a;https://xihe.mindspore.cn/events/mindspore-training-camp 签名&#xff1a;Sam9029 序列标注问题概述 序列标注是信息抽取中的一个关键任务&#xff0c;包括分词、词性标注、命名实体识别…

【通信协议-RTCM】MSM语句(2) - RINEXMSM7语句总结(重要!自动化开发计算卫星状态常用)

注释&#xff1a; 在工作中主要负责的是RTCM-MSM7语句相关开发工作&#xff0c;所以主要介绍的就是MSM7语句相关内容 1. 相位校准参考信号 2. MSM1、MSM2、MSM3、MSM4、MSM5、MSM6和MSM7的消息头内容 DATA FIELDDF NUMBERDATA TYPENO. OF BITSNOTES Message Number - 消息编…

四、Object 通⽤⽅法

Object是Java中所有类的基类&#xff0c;是最顶级的父类。在Java中&#xff0c;每个类都直接或间接地继承自Object类&#xff0c;即使没有显式地声明继承关系&#xff0c;Java也会自动为每个类添加extends Object。这意味着&#xff0c;Object类中定义的方法可以被所有Java类使…

React组件定义

一、定义 组件是是构建用户界面&#xff08;UI&#xff09;的基础&#xff0c;它可以是一个输入框、按钮、也可以是一整个页面。组件可以分为以下2种类型&#xff1a; 1、函数组件&#xff08;Functional Components&#xff09; 顾名思义就是用来函数定义的组件&#xff0c…

DML数据操作语句和基本的DQL语句

一、MySQL对数据的增删改查 1.DML语句 1.1 增加数据(INSERT) insert into 表名 (字段名,字段名,...字段名) values/value (值,值,...值) 1.1.1 新增数据的具体实现 &#xff08;1&#xff09;全字段的插入 方式一&#xff1a; insert into student (sid,sname,birthday,ssex,…

C++的智能指针

说实话以前用这个很少&#xff0c;一个指针打天下&#xff0c;不过都智能了&#xff0c;分配了就不管了&#xff0c;想来还是很方便。。。 1 unique_ptr 代码示例&#xff1a; #include <iostream> #include <memory>class MyClass { public:MyClass() { std::c…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 开源项目热度排行榜(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆Coding ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线评测,专栏文章质量平均 93 分 最新华为OD机试目录…

Linux网络-配置IP

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 本来IP配置应该放在Linux安装完成的就要配置的&#xff0c;但是由于那个时候对Linux不怎么熟悉&#xff0c;所以单独列了一个…

JVM系列(一) -浅谈虚拟机的成长史

一、摘要 众所周知&#xff0c;Java 经过多年的发展&#xff0c;已经从一门单纯的计算机编程语言&#xff0c;发展成了一套成熟的软件解决方案。从互联网到企业平台&#xff0c;Java 是目前使用最广泛的编程语言。 以下这段内容是来自 Java 的官方介绍&#xff01; 从笔记本电…

图片变更检测

20240723 By wdhuag 目录 前言&#xff1a; 参考&#xff1a; 文件监控&#xff1a; 图片占用问题&#xff1a; 源码&#xff1a; 前言&#xff1a; 由于第三方图像处理软件不能回传图片&#xff08;正常都能做&#xff0c;这里只是不想做&#xff09;&#xff0c;只能在…

Postman接口测试工具的使用

一、postman简介 Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。作用&#xff1a;常用于进行接口测试。不需要安装。 特征&#xff1a;简单&#xff0c;实用&#xff0c;美观&#xff0c;大方。 二、Postman接口测试工具的使用 Postman不需要安…

Emacs vs IDE:用Emacs写程序真的更方便吗?

前言 在程序员的世界里&#xff0c;选择合适的开发工具至关重要。Emacs作为一种历史悠久且功能强大的文本编辑器&#xff0c;因其灵活性和扩展性吸引了许多程序员。那么&#xff0c;Emacs究竟有哪些优点&#xff1f;用Emacs写程序真的比使用现代IDE更方便吗&#xff1f;本文将…

MySQL的账户管理

目录 1 密码策略 1.1 查看数据库当前密码策略&#xff1a; 1.2 查看密码设置策略 1.3 密码强度检查等级解释&#xff08;validate_password.policy&#xff09; 2 新建登录账户 3 账户授权 3.1 赋权原则 3.2 常见的用户权限 3.3 查看权限 3.4 赋权语法 4 实例 4.1 示例1&#x…

python脚本制作循环执行命令行

python import subprocess import sysif __name____main__:ret 1while ret!0:ret subprocess.call(sys.argv[1:], textTrue)pack pip install pyinstaller pyinstaller --onefile loop.py 使用场景 使用上面生成的loop.exe调用cmd命令&#xff0c;执行失败了返回值&#xf…