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

news2024/12/23 3:37:40

目录

一、前言

二、网格

三、方法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 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);
             //在这里去掉
             //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.coloradmin.cn/o/1936924.html

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

相关文章

云计算实训09——rsync远程同步、自动化推取文件、对rsyncd服务进行加密操作、远程监控脚本

一、rsync远程同步 1.rsync基本概述 &#xff08;1&#xff09;sync同步 &#xff08;2&#xff09;async异步 &#xff08;3&#xff09;rsync远程同步 2.rsync的特点 可以镜像保存整个目录树和文件系统 可以保留原有权限&#xff0c;owner,group,时间&#xff0c;软硬链…

IDEA的工程与模块管理

《IDEA破解、配置、使用技巧与实战教程》系列文章目录 第一章 IDEA破解与HelloWorld的实战编写 第二章 IDEA的详细设置 第三章 IDEA的工程与模块管理 第四章 IDEA的常见代码模板的使用 第五章 IDEA中常用的快捷键 第六章 IDEA的断点调试&#xff08;Debug&#xff09; 第七章 …

Harbor系列之1:介绍、架构及工作流程说明

Harbor介绍、架构及工作流程说明 Harbor 是一个用于存储、签名和扫描内容的企业级容器镜像注册表项目。由 VMware 开发并于 2016 年开源。Harbor 提供了一些关键特性&#xff0c;使其成为企业使用的理想选择。 1. Harbor 介绍 1.1 什么是 Harbor Harbor 是一个开源的云原生…

Python酷库之旅-第三方库Pandas(034)

目录 一、用法精讲 101、pandas.Series.__array__魔法方法 101-1、语法 101-2、参数 101-3、功能 101-4、返回值 101-5、说明 101-6、用法 101-6-1、数据准备 101-6-2、代码示例 101-6-3、结果输出 102、pandas.Series.get方法 102-1、语法 102-2、参数 102-3、…

ETL数据同步之DataX,附赠一套DataX通用模板

今天跟大家分享数据同步datax的模板&#xff0c;小伙伴们简单直接借鉴使用。 还记得上一篇关于大数据DS调度工具的分享嘛&#xff1f; 主流大数据调度工具DolphinScheduler之数据ETL流程-CSDN博客 里面的核心就是采用了DATAX的数据同步原理。 一&#xff0c;什么是DataX D…

linux远程主机和windows互传

一.winscp 最简单&#xff0c;但有时候会出现连不上 二 .MobaXterm 可以选择多种连接方式 二. 配置samba服务器 1. 新增samba用户 sudo pdbedit -L -v 查看当前samba用户 sudo smbpasswd -a guoziyi 添加samba用户 sudo smbpasswd -x guoziyi 删除samba用户 2. 编辑/etc…

LabVIEW多串口通信

随着现代工业控制对数据采集和处理效率的要求不断提升&#xff0c;传统的单串口通信已无法满足多通道数据传输与大规模数据存取的需求。开发一种基于LabVIEW的多串口通信及数据存储系统&#xff0c;以提升数据处理速度和存储效率&#xff0c;保障生产线的稳定运行显得尤为重要。…

常见排序算法总结

文章目录 比较排序冒泡排序选择排序插入排序归并排序快速排序堆排序希尔排序 非比较排序&#xff08;桶排序&#xff09;计数排序基数排序 比较排序 冒泡排序 嵌套循环&#xff0c;每次内层循环执行时&#xff0c;数组的每两个元素交换&#xff0c;将一个最大/小的数排到数组…

语音合成-TTS文字转语音(专业版)

语音合成-TTS文字转语音(专业版) 一、工具简介 *使用强大的智能AI语音库&#xff0c;合成独具特色接近真人语音的朗读音频。 *使用极具表现力和类似人类的声音&#xff0c;使文本阅读器和已启用语音的助理等方案栩栩如生。 *用途&#xff1a;这个语音工具&#xff0c;不仅可…

「实战应用」如何用DHTMLX将上下文菜单集成到JavaScript甘特图中(三)

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的所有需求&#xff0c;是最完善的甘特图图表库。 DHTMLX Gantt是一个高度可定制的工具&#xff0c;可以与项目管理应用程序所需的其他功能相补充。在本文中您将学习如何使用自定义上…

LeetCode岛屿的最大面积(深度搜索)/什么是深搜,简单案例回顾图用邻接表实现图的深度优先遍历。

看这道题不懂深度搜索的可以看看下面讲述 岛屿的最大面积 解题思路 代码 class Solution {int dfs(vector<vector<int>>& grid, int cur_i, int cur_j) {//确定边界if((cur_i >0 && cur_i < grid.size()) && (cur_j >0 &&…

【C语言】 作业11 链表+实现函数封装

递归实现链表数据互换&#xff0c;纯不会&#xff0c;明天再说 1、链表实现以下功能 链表&#xff0c;创建链表&#xff0c;申请节点&#xff0c;判空&#xff0c;头插&#xff0c;遍历输出&#xff0c;通过位置查找节点&#xff0c;任意位置插入&#xff0c;头删&#xff0c;…

技术成神之路:设计模式(八)责任链模式

介绍 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为设计模式&#xff0c;它允许多个对象依次处理请求&#xff0c;避免请求的发送者和接收者之间的显式耦合。该模式通过将多个可能处理请求的对象连接成一条链&#xff0c;并沿着这条链传递请求…

通过角点进行水果的果梗检测一种新方法

一、前言 在前面的《数字图像处理与机器视觉》案例一&#xff08;库尔勒香梨果梗提取和测量&#xff09;中主要使用数学形态学的方法进行果梗提取&#xff0c;下面给出一种提取果梗的新思路。 众所周知&#xff0c;一般果梗和果实在边缘处角度有较大突变&#xff0c;可以通过合…

Kafka介绍及Go操作kafka详解

文章目录 Kafka介绍及Go操作kafka详解项目背景解决方案面临的问题业界方案ELKELK方案的问题日志收集系统架构设计架构设计组件介绍将学到的技能消息队列的通信模型点对点模式 queue发布/订阅 topicKafka介绍Kafka的架构图工作流程选择partition的原则ACK应答机制Topic和数据日志…

亚信安全终端一体化解决方案入选应用创新典型案例

近日&#xff0c;由工业和信息化部信息中心主办的2024信息技术应用创新发展大会暨解决方案应用推广大会成功落幕&#xff0c;会上集中发布了一系列技术水平先进、应用效果突出、产业带动性强的信息技术创新工作成果。其中&#xff0c;亚信安全“终端一体化安全运营解决方案”在…

Jolt路线图

1. 引言 a16z crypto团队2024年7月更新了其Jolt路线图&#xff1a; 主要分为3大维度&#xff1a; 1&#xff09;链上验证维度&#xff1a; 1.1&#xff09;Zeromorph&#xff1a;见Aztec Labs团队2023年论文 Zeromorph: Zero-Knowledge Multilinear-Evaluation Proofs from…

iOS——编译链接

编译连接的过程 预处理编译汇编链接 预处理 clang -E main.m -o main.i“#define"删除并展开对应宏定义。处理所有的条件预编译指令。如#if/#ifdef/#else/#endif。”#include/#import"包含的文件递归插入到此处。删除所有的注释"//或/**/"。添加行号和文…

python—爬虫的初步了解

Python 爬虫&#xff08;Web Scraping&#xff09;是一种自动化从网站上提取数据的技术。Python 由于其简洁的语法、丰富的库和强大的社区支持&#xff0c;成为了实现网络爬虫的首选语言之一。下面是一些Python爬虫的基本概念和步骤&#xff1a; 1. 爬虫的基本概念 请求&…

JavaEE:Spring Web简单小项目实践三(留言板实现)

学习目的&#xff1a; 1、理解前后端交互过程 2、学习接口传参&#xff0c;数据返回以及页面展示 目录 1、准备工作 2、约定前后端交互接口 1、获取全部留言 2、发表新留言 3、实现服务器端代码 4、调整前端页面代码 5、运行测试 1、准备工作 创建SpringBoot项目&#x…