《UnityShader入门精要》学习4
一个最简单的顶点/片元着色器
一个最简单的顶点/片元着色器
Unity Shader的基本结构。它包含了Shader、Properties、SubShader、Fallback等语义块。顶点/片元着色器的结构与之大体类似
Shader "MyShaderName" {Properties {// 属性}SubShader {// 针对显卡A的SubShaderPass {// 设置渲染状态和标签// 开始CG代码片段CGPROGRAM// 该代码片段的编译指令,例如:#pragma vertex vert#pragma fragment frag// CG代码写在这里ENDCG// 其他设置}// 其他需要的Pass}SubShader {// 针对显卡B的SubShader}// 上述SubShader都失败后用于回调的Unity ShaderFallback "VertexLit"}
一个简单的代码:
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Unity Shaders Book/Chapter 5/Simple Shader" {SubShader{Pass {CGPROGRAM#pragma vertex vert#pragma fragment fragfloat4 vert(float4 v : POSITION) : SV_POSITION {return UnityObjectToClipPos(v);}fixed4 frag() : SV_Target {return fixed4(1.0, 1.0, 1.0, 1.0);}ENDCG}}
}
效果:

讲解:
代码的第一行通过Shader语义定义了这个Unity Shader的名字——“Unity Shaders Book/Chapter 5/Simple Shader
Properties语义并不是必需的,我们可以选择不声明任何材质属性
两条编译指令:
#pragma vertex vert
#pragma fragment frag
它们告诉Unity,哪个函数包含了顶点着色器的代码,哪个函数包含了片元着色器的代码
更一般的形式:
#pragma vertex name
#pragma fragment name //其中name 就是我们指定的函数名
float4 vert(float4 v : POSITION) : SV_POSITION {return mul (UNITY_MATRIX_MVP, v);}
这就是本例使用的顶点着色器代码,它是逐顶点执行的。vert函数的输入v包含了这个顶点的位置,这是通过POSITION语义指定的。它的返回值是一个float4类型的变量,它是该顶点在裁剪空间中的位置,POSITION和SV_POSITION都是CG/HLSL中的语义(semantics),它们是不可省略的,这些语义将告诉系统用户需要哪些输入值,以及用户的输出是什么
例如这里,POSITION将告诉Unity,把模型的顶点坐标填充到输入参数v中,SV_POSITION将告诉Unity,顶点着色器的输出是裁剪空间中的顶点坐标
return 执行的代码的意思是:把顶点坐标从模型空间转换到裁剪空间中。UNITY_MATRIX_MVP矩阵是Unity内置的模型·观察·投影矩阵
fixed4 frag() : SV_Target {return fixed4(1.0, 1.0, 1.0, 1.0);}
在本例中,frag函数没有任何输入。它的输出是一个fixed4类型的变量,并且使用了SV_Target语义进行限定。SV_Target也是HLSL中的一个系统语义,它等同于告诉渲染器,把用户的输出颜色存储到一个渲染目标(render target)中,这里将输出到默认的帧缓存中。片元着色器中的代码很简单,返回了一个表示白色的fixed4类型的变量。片元着色器输出的颜色的每个分量范围在[0, 1],其中(0, 0,0)表示黑色,而(1, 1, 1)表示白色。
模型数据从哪里来

为了自建一个自定义的结构体,我们必须使用如下格式来定义它:
struct StructName {Type Name : Semantic;Type Name : Semantic;.......};
其中,语义是不可以被省略的
我们修改了vert函数的输入参数类型,把它设置为我们新定义的结构体a2v。通过这种自定义结构体的方式,我们就可以在顶点着色器中访问模型数据。
在Unity中,填充到POSITION, TANGENT, NORMAL这些语义中的数据是由使用该材质的Mesh Render组件提供的。在每帧调用Draw Call的时候,Mesh Render组件会把它负责渲染的模型数据发送给Unity Shader
我们知道,一个模型通常包含了一组三角面片,每个三角面片由3个顶点构成,而每个顶点又包含了一些数据,例如顶点位置、法线、切线、纹理坐标、顶点颜色等
顶点着色器和片元着色器之间如何通信
顶点着色器是逐顶点调用的,而片元着色器是逐片元调用的。片元着色器中的输入实际上是把顶点着色器的输出进行插值后得到的结果。
Shader "Unity Shaders Book/Chapter 5/Simple Shader" {SubShader {Pass {CGPROGRAM#pragma vertex vert#pragma fragment fragstruct a2v {float4 vertex : POSITION;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;};// 使用一个结构体来定义顶点着色器的输出struct v2f {// SV_POSITION语义告诉Unity, pos里包含了顶点在裁剪空间中的位置信息float4 pos : SV_POSITION;// COLOR0语义可以用于存储颜色信息fixed3 color : COLOR0;};v2f vert(a2v v) : SV_POSITION {// 声明输出结构v2f o;o.pos = mul(UNITY_MATRIX_MVP, v.vertex);// v.normal包含了顶点的法线方向,其分量范围在[-1.0, 1.0]// 下面的代码把分量范围映射到了[0.0, 1.0]// 存储到o.color中传递给片元着色器o.color = v.normal * 0.5 + fixed3(0.5, 0.5, 0.5);return o;}fixed4 frag(v2f i) : SV_Target {// 将插值后的i.color显示到屏幕上return fixed4(i.color, 1.0);}ENDCG}}}
在上面的代码中,我们声明了一个新的结构体v2f。v2f用于在顶点着色器和片元着色器之间传递信息。同样的,v2f中也需要指定每个变量的语义。在本例中,我们使用了SV_POSITION和COLOR0语义。顶点着色器的输出结构中,必须包含一个变量,它的语义是SV_POSITION。否则,渲染器将无法得到裁剪空间中的顶点坐标,也就无法把顶点渲染到屏幕上。COLOR0语义中的数据则可以由用户自行定义,但一般都是存储颜色,例如逐顶点的漫反射颜色或逐顶点的高光反射颜色
如何使用属性
Shader "Unity Shaders Book/Chapter 5/Simple Shader" {Properties {// 声明一个Color类型的属性_Color ("Color Tint", Color) = (1.0,1.0,1.0,1.0)}SubShader {Pass {CGPROGRAM#pragma vertex vert#pragma fragment frag// 在CG代码中,我们需要定义一个与属性名称和类型都匹配的变量fixed4 _Color;struct a2v {float4 vertex : POSITION;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;};struct v2f {float4 pos : SV_POSITION;fixed3 color : COLOR0;};v2f vert(a2v v) : SV_POSITION {v2f o;o.pos = mul(UNITY_MATRIX_MVP, v.vertex);o.color = v.normal * 0.5 + fixed3(0.5, 0.5, 0.5);return o;}fixed4 frag(v2f i) : SV_Target {fixed3 c = i.color;// 使用_Color属性来控制输出颜色c *= _Color.rgb;return fixed4(c, 1.0);}ENDCG}}}
在上面的代码中,我们首先添加了Properties语义块中,并在其中声明了一个属性_Color,它的类型是Color,初始值是(1.0,1.0,1.0,1.0),对应白色。为了在CG代码中可以访问它,我们还需要在CG代码片段中提前定义一个新的变量,这个变量的名称和类型必须与Properties语义块中的属性定义相匹配。

强大的援手:Unity提供的内置文件和变量
相关文章:
《UnityShader入门精要》学习4
一个最简单的顶点/片元着色器 一个最简单的顶点/片元着色器 Unity Shader的基本结构。它包含了Shader、Properties、SubShader、Fallback等语义块。顶点/片元着色器的结构与之大体类似 Shader "MyShaderName" {Properties {// 属性}SubShader {// 针对显卡A的S…...
kaggle新赛:写作质量预测大赛【数据挖掘】
赛题名称:Linking Writing Processes to Writing Quality 赛题链接:https://www.kaggle.com/competitions/linking-writing-processes-to-writing-quality 赛题背景 写作过程中存在复杂的行为动作和认知活动,不同作者可能采用不同的计划修…...
导入导出Excel
Springboot Easyexcel导入导出excel EasyExcel 的导出导入支持两种方式进行处理*easyexcel 导出不用监听器,导入需要写监听器* 一、导入:简单实现1. 导入依赖,阿里的easyexcel插件2. 程序2-1. 实体类:2-2. 定义一个 监听类&#…...
C# Thread.Sleep(0)有什么用?
一、理论分析 回答这个要先从线程时间精度(时间片)开始说起。很多参考书说,默认情况下,时间片为15ms 左右,但是这是已经过时的知识。在老的 Windows 操作系统里,应用程序模式时时间片 15ms 左右࿰…...
二十四、【参考素描三大面和五大调】
文章目录 三种色面(黑白灰)五种色调 这个可以参考素描对物体受光的理解:素描调子的基本规律与素描三大面五大调物体的明暗规律 三种色面(黑白灰) 如下图所示,我们可以看到光源是从亮面所对应的方向射过来的,所以我们去分析图形的时候,首先要…...
【Python 千题 —— 基础篇】进制转换:十进制转二进制
题目描述 题目描述 计算机底层原理中常使用二进制来表示相关机器码,学会将十进制数转换成二进制数是一个非常重要的技能。现在编写一个程序,输入一个十进制数,将其转换成二进制数。 输入描述 输入一个十进制数。 输出描述 程序将输入的…...
[ spring boot入门 ] java: 错误: 无效的源发行版:17
因为我目前idea中使用的是jdK8,而在pom.xml文件里是17,所以我需要将所有地方修改为jdk8 pom.xml的jdk版本为8 maven的setting.xml文件 jdk为8 还有Java Compiler 还有Project Structure 里面的project 和 module...
【计算机组成体系结构】电路基本原理与加法器设计
一、算术逻辑单元—ALU 1.基本的逻辑运算(1bit的运算) 基本逻辑运算分为,与、或、非。大家应该很熟悉了,与:全1为1,否则为0。或:全0为0,否则为1。非:取反。三个基本的逻…...
MyBatisPlus之基本CRUD、常用注解
文章目录 前言一、MyBatisPlus简介1.简介2.特性 二、基本CRUD1.依赖2.搭建基本结构3.BaseMapper4.使用插入删除(1)通过id删除记录(2)通过id批量删除记录(3)通过map条件删除记录 修改查询(1&…...
采集EtherNET/IP转Profinet在西门子plc中的应用
远创智控网关YC-EIPM-PN,让你的设备和云平台实时连接! 远创智控YC-EIPM-PN网关产品支持各种数据接口,无论是工业领域的仪表、PLC、计量设备,还是设备数据,都能实时采集并整合。它将这些设备中的运行数据、状态数据等信…...
Paddle build_cinn_pass_test源码阅读(fluid目录下)
代码位置在 paddle\fluid\framework\paddle2cinn\build_cinn_pass_test.cc ,因为paddle CINN和PIR部分依旧在高频更新,所以各位看到的可能和我的不一样 inline bool CheckNodeExisted(const std::unordered_set<Node*>& nodes,const std::str…...
函数调用:为什么会发生stack overflow?
在开发软件的过程中我们经常会遇到错误,如果你用 Google 搜过出错信息,那你多少应该都访问过Stack Overflow这个网站。作为全球最大的程序员问答网站,Stack Overflow 的名字来自于一个常见的报错,就是栈溢出(stack ove…...
git log
git log -p 是一个用于显示git commit历史的命令,它会展示每个commit的详细信息,包括每个修改文件的清单、添加/删除的行所在的位置以及具体的实际更改。这个命令能够让用户深入了解仓库的历史记录。 与git log相比,git log -p 提供了更多的…...
在面试提问环节应该问那些内容
在面试提问环节应该问那些内容 薪资和福利: 你可以询问关于薪资、福利和其他福利待遇的细节,包括工资结构、健康保险、退休计划、带薪休假等。 了解关于加班、绩效奖金和涨薪机会的信息。 工作时间和灵活性: 询问工作时间、工作日和工作日…...
【vb.net】轻量JSON序列及反序列化
这个代码写的有点时间了,可能有点小bug,欢迎评论区反馈 作用是将Json文本转化成一个HarryNode类进行相关的Json对象处理或者读取,也可以将一个HarryNode对象用ToString变为Json文本。 举例: 1、读取节点数据 dim harryNode N…...
【Vue】vue2与netcore webapi跨越问题解决
系列文章 C#底层库–记录日志帮助类 本文链接:https://blog.csdn.net/youcheng_ge/article/details/124187709 文章目录 系列文章前言一、技术介绍二、问题描述三、问题解决3.1 方法一:前端Vue修改3.2 方法二:后端允许Cors跨越访问 四、资源…...
SpringSecurity + jwt + vue2 实现权限管理 , 前端Cookie.set() 设置jwt token无效问题(已解决)
问题描述 今天也是日常写程序的一天 , 还是那个熟悉的IDEA , 还是那个熟悉的Chrome浏览器 , 还是那个熟悉的网站 , 当我准备登录系统进行登录的时候 , 发现会直接重定向到登录页 , 后端也没有报错 , 前端也没有报错 , 于是我得脸上又多了一张痛苦面具 , 紧接着在前端疯狂debug…...
【21】c++设计模式——>装饰模式
装饰模式的定义 装饰模式也可以称为封装模式,所谓的封装就是在原有行为之上进行扩展,并不会改变该行为; 例如网络通信: 在进行网络通信的时候,数据是基于IOS七层或四层网络模型(某些层合并之后就是四层模型…...
【博客707】模版化拆解并获取victoriametrics的metricsql各个元素
golang解析victoriametrics的metricsql 场景: 需要拆解metricsql中的部分元素,比如:rollup function,label filter等需要对语法合法性进行判断,同时拒绝某些查询函数我们需要拆解metricsql并进行改造 使用victoriam…...
nodejs + express 实现 http文件下载服务程序
nodejs express 实现 http文件下载服务程序, 主要包括两个功能:指定目录的文件列表,某个文件的下载。 假设已经安装好 nodejs ; cd /js/node_js ; 安装在当前目录的 node_modules/ npm install express --save npm install express-gene…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...
