第二天 开始Unity Shader的学习之旅之熟悉顶点着色器和片元着色器

news2025/3/30 20:16:52

Shader初学者的学习笔记

第二天 开始Unity Shader的学习之旅之熟悉顶点着色器和片元着色器


文章目录

  • Shader初学者的学习笔记
  • 前言
  • 一、顶点/片元着色器的基本结构
    • ① Shader "Unity Shaders Book/Chapter 5/ Simple Shader"
    • ② SubShader
    • ③ CGPROGRAM和ENDCG
    • ④ 指明顶点着色器和片元着色器函数名称
    • ⑤ 顶点着色器
    • ⑥ 片元着色器
  • 二、模型数据从哪来?
    • ① a2v
    • ② 语义中的数据从何而来
    • ③ v2f
    • ④ 如何使用属性
  • 总结


前言

今天对入门精要第五章进行一个小小的总结和归纳,主要是学习顶点着色器和片元着色器的结构.


一、顶点/片元着色器的基本结构

Shader "Unity Shaders Book/Chapter 5/ Simple Shader"{
	SubShader														②
	{
		Pass
		{
			CGPROGRAM												③
			#pragma vertex vert										④
			#pragma fragment frag
			
			float4 vert (float4 : POSITION) : SV_POSITION			⑤
			{
				return mul (UNITY_MATRIX_MVP, v):
			}
			
			fixed4 frag() : SV_Target								⑥
			{
				return fixed4 (1.0, 1.0, 1.0, 1.0);
			}
			
			ENDCG
		}
	}
}

① Shader “Unity Shaders Book/Chapter 5/ Simple Shader”

该语句定义了Unity Shader的语义 – “Unity Shaders Book/Chapter 5/ Simple Shader”,这个名字有利于我们快速选择到自定义的Shader.

② SubShader

你会发现,我们没有声明任何的材质属性,因为Properties不是必须的, 同时在这个SubShader中没有Tags, RenderSetup等,因此SubShader会使用默认的渲染设置和标签设置.
并且我们在SubShader中定义的Pass也没有设置Tags和RenderSetup.

③ CGPROGRAM和ENDCG

我们把cg代码片段放在CGPROGRAM和ENDCG中;

④ 指明顶点着色器和片元着色器函数名称

#pragma vertex name1
#pragma fragment name2

name1, name2是我们自己指定的函数名,可以告诉Unity,name1包含了顶点着色器的代码,name2包含了片元着色器的代码,这个函数的名字不一定要使用vertex和frag,但是我们一般用使用这两个来定义函数,因为他们很直观.

⑤ 顶点着色器

float4 vert (float4 : POSITION) : SV_POSITION
{
	return mul (UNITY_MATRIX_MVP, v):
}

需要再提一次,顶点着色器是逐顶点执行的, vert函数的输入是float4类型的顶点位置,这是通过POSITION语义指定的,vert函数的输出也是float4类型的,即顶点在裁剪空间的位置,由SV_POSITION的语义指定的;
POSITION 和 SV_POSITION都是Cg/HLSL的语义,他们是不可忽略的,他们会告诉Unity输入和输出,例如:POSITION告诉Unity,将模型的顶点坐标填充到参数v中,SV_POSITION告诉Unity,顶点着色器的输出是裁剪空间的坐标,所以使用这些语义现在输入输出参数是非常有必要的.
再看顶点着色器的代码,这一句代码的含义就是将顶点坐标从模型空间转换到裁剪空间.
补充:UNITY_MATRIX_MVP矩阵是Unity内置的模型观察投影矩阵.

⑥ 片元着色器

fixed4 frag() : SV_Target
{
	return fixed4 (1.0, 1.0, 1.0, 1.0);
}

在片元着色器中,frag函数没有任何输入,他的输出是一个fixed4类型的变量,并且使用了SV_Target语义进行限定,SV_Target也是HSLSL中的一个系统语义,他等同于告诉渲染器,把用户的输出颜色存储到渲染目标中,这里将输出到默认的帧缓存中.
片元着色器的代码也很简单,返回一个白色的fixed4变量.

二、模型数据从哪来?

我们如果想要得到模型上的每个顶点的纹理坐标和法线方向,那么我们就不能只是将float4作为顶点着色器的输入了,我们就需要自己定义一个结构体,如下:

Shader "Unity Shaders Book/Chapter 5/ Simple Shader"
{
	Properties
	{
		_Color ("Color Tint", Color) = (1.0, 1.0, 1.0, 1.0)
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			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;
				c *= _Color.rgb;
				return fixed4(c, 1.0);
				
			}
			
			ENDCG
		}
	}
}

① a2v

在上面的代码中,我声明了新的结构体a2v,这里面包含很多数据:模型空间的顶点坐标,法线方向,以及模型的第一套纹理坐标,这些都是通过特定的语义进行修饰的,unity支持的语义有:POSITION, TANGENT, NORMAL, TEXCOORD0, TEXCOORD1, TEXCOORD2, TEXCOORD3, COLOR等
注意:语义是不可以被忽略的

是不是很疑惑为什么要起名字为a2v,因为a是应用,v表示顶点着色器,a2v的意思就是从应用阶段到顶点着色器.

② 语义中的数据从何而来

这些语义的数据是从哪来的呢?他们其实是由Mesh Render组件剔红的,在每帧调用Draw Call的时候, Mesh Render组件会把它负责渲染的模型数据发送给Unity Shader.
我们知道,一个模型通常包含一组三角面片,每个三角面片由三个顶点组成,每个顶点又包含一些数据:顶点位置,法线,切线,纹理坐标,顶点颜色等,通过上面的方法,我们就可以在顶点着色器中访问顶点的模型数据了.

③ v2f

我们在顶点着色器进行了一些变换之后,希望把模型的法线,纹理坐标等传递给片元着色器,那么这个传递过程是怎样的呢?
我们首先定义了一个v2f的结构体,用于在顶点着色器和片元着色器之前传递信息,为了将模型渲染到屏幕上,我们必须在顶点着色器的输出中定义一个变量,他的语义是SV_POSITION,COLOR0一般用于存储颜色,也可由用户自行定义.

④ 如何使用属性

在上面的代码中,我们声明了属性:_Color,为了可以在cg中访问它,我们需要在Cg代码片段中提前定义一个名称和类型与Properties中属性相匹配的变量.
下面表格记录了属性的类型和变量类型的匹配关系

ShaderLab属性的类型Cg变量的类型
Color, Vectorfloat4, half4, fixed4
Range, floatfloat, half, fixed
2Dsampler2D
CubesamplerCube
3Dsampler3D

补充

uniform fixed4 _Color;

在上述Cg变量前,有uniform变量进行修饰,他仅仅用于提供一些关于该变量的初始值是如何指定和存储的相关信息,在Unity Shader中是可以省略的.


总结

今天我对第五章的顶点着色器和片元着色器的知识进行了总结,为以后复杂的Unity Shader的学习打下了坚实的基础!!!

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

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

相关文章

大疆上云api直播功能如何实现

概述 流媒体服务器作为直播画面的中转站,它接收推流端的相机画面,同时拉流端找它获取相机的画面。整个流程如下: 在流媒体服务器上创建流媒体应用(app),一个流媒体服务器上面可以创建多个流媒体应用约定推拉流的地址。假设流媒体服务器工作在1935端口上面,假设创建的流…

理解文字识别:一文读懂OCR商业化产品的算法逻辑

文字识别是一项“历久弥新”的技术。早在上世纪初,工程师们就开始尝试使用当时有限的硬件设备扫描并识别微缩胶片、纸张上的字符。随着时代和技术的发展,人们在日常生活中使用的电子设备不断更新换代,文字识别的需求成为一项必备的技术基础&a…

使用 Cursor、MCP 和 Figma 实现工程化项目自动化,提升高达 200% 效率

直接上手不多说其他的! 一、准备动作 1、Cursor下载安卓 1.1访问官方网站 打开您的网络浏览器,访问 Cursor 的官方网站:https://www.cursor.com/cn 1.2开始下载: 点击"Download for free" 根据您的浏览器设置,会自…

Arduino、ESP32驱动GUVA-S12SD UV紫外线传感器(光照传感器篇)

目录 1、传感器特性 2、控制器和传感器连线图 3、驱动程序 UV紫外线传感器是一个测试紫外线总量的最佳传感器,它不需要使用波长滤波器,只对紫外线敏感。 Arduino UV紫外线传感器,直接输出对应紫外线指数(UV INDEX)的线性电压,输出电压范围大约0~1100mV(对应UV INDEX值…

PTA 1097-矩阵行平移

给定一个&#x1d45b;&#x1d45b;nn的整数矩阵。对任一给定的正整数&#x1d458;<&#x1d45b;k<n&#xff0c;我们将矩阵的奇数行的元素整体向右依次平移1、……、&#x1d458;、1、……、&#x1d458;、……1、……、k、1、……、k、……个位置&#xff0c;平移…

Notepad++ 替换 换行符 为 逗号

多行转一行&#xff0c;逗号分隔 SPO2025032575773 SPO2025032575772 SPO2025032575771 SPO2025032575771 SPO2025032575770为了方便快速替换&#xff0c;我们需要先知道这样类型的数据都存在哪些换行符。 点击【视图】-【显示符号】-【显示行尾符】 对于显示的行尾换行符【C…

使用飞书API自动化更新共享表格数据

飞书API开发之自动更新共享表格 天马行空需求需求拆解1、网站数据爬取2、飞书API调用2.1 开发流程2.2 创建应用2.3 配置应用2.4 发布应用2.5 修改表格权限2.6 获取tenant_access_token2.7 调用API插入数据 总结 天马行空 之前一直都是更新的爬虫逆向内容&#xff0c;工作中基本…

使用vscode搭建pywebview集成vue项目示例

文章目录 前言环境准备项目源码下载一、项目说明1 目录结构2 前端项目3 后端项目获取python安装包(选择对应版本及系统) 三、调试与生成可执行文件1 本地调试2 打包应用 四、核心代码说明1、package.json2、vite.config.ts设置3、main.py后端入口文件说明 参考文档 前言 本节我…

蓝桥杯嵌入式十六届模拟三

由硬件框图可以知道我们要配置LED 和按键 一.LED 先配置LED的八个引脚为GPIO_OutPut,锁存器PD2也是,然后都设置为起始高电平,生成代码时还要去解决引脚冲突问题 二.按键 按键配置,由原理图按键所对引脚要GPIO_Input 生成代码,在文件夹中添加code文件夹,code中添加fun.…

onedav一为导航批量自动化导入网址(完整教程)

OneNav作为一个功能强大的导航工具,支持后台管理、加密链接、浏览器书签批量导入等功能,能够帮助用户轻松打造专属的导航页面。今天,我将为大家详细介绍如何实现OneNav导航站的批量自动化导入网址。 1、建立要批量导入的表格 格局需要创建表格,表格的要求是一定要有需要,…

Linux之编辑器vim命令

vi/vim命令&#xff1a; 终端下编辑文件的首选工具&#xff0c;号称编辑器之神 基本上分为三种模式&#xff0c;分别是 命令模式&#xff08;command mode&#xff09;>输入vi的命令和快捷键&#xff0c;默认打开文件的时候的模式插入模式&#xff08;insert mode&#x…

备赛蓝桥杯之第十六届模拟赛2期职业院校组第四题:地址识别

提示&#xff1a;本篇文章仅仅是作者自己目前在备赛蓝桥杯中&#xff0c;自己学习与刷题的学习笔记&#xff0c;写的不好&#xff0c;欢迎大家批评与建议 由于个别题目代码量与题目量偏大&#xff0c;请大家自己去蓝桥杯官网【连接高校和企业 - 蓝桥云课】去寻找原题&#xff0…

多模态自动驾驶混合渲染HRMAD:将NeRF和3DGS进行感知验证和端到端AD测试

基于3DGS和NeRF的三维重建技术在过去的一年中取得了快速的进步&#xff0c;动态模型也变得越来越普遍&#xff0c;然而这些模型仅限于处理原始轨迹域内的对象。 HRMAD作为一种混合方案&#xff0c;将传统的基于网格的动态三维神经重建和物理渲染优势结合&#xff0c;支持在任意…

mac m3 pro 部署 stable diffusion webui

什么是Stable Diffusion WebUI &#xff1f; Stable Diffusion WebUI 是一个基于Stable Diffusion模型开发的图形用户界面&#xff08;GUI&#xff09;工具。通过这个工具&#xff0c;我们可以很方便的基于提示词&#xff0c;描述一段文本来指导模型生成相应的图像。相比较通过…

多层感知机实现

激活函数 非线性 ReLU函数 修正线性单元 rectified linear unit relu(x)max(0,x) relu的导数&#xff1a; sigmoid函数 s i g m o i d ( x ) 1 1 e − x sigmoid(x)\frac{1}{1e^{-x}} sigmoid(x)1e−x1​ 是一个早期的激活函数 缺点是&#xff1a; 幂运算相对耗时&…

Linux笔记---动静态库(使用篇)

目录 1. 库的概念 2. 静态库&#xff08;Static Libraries&#xff09; 2.1 静态库的制作 2.2 静态库的使用 2.2.1 显式指定库文件及头文件路径 2.2.2 将库文件安装到系统目录 2.2.3 将头文件安装到系统目录 3. 动态库 3.1 动态库的制作 3.2 动态库的使用 3.2.1 显式…

手机销售终端MPR+LTC项目项目总体方案P183(183页PPT)(文末有下载方式)

资料解读&#xff1a;手机销售终端 MPRLTC 项目项目总体方案 详细资料请看本解读文章的最后内容。在当今竞争激烈的市场环境下&#xff0c;企业的销售模式和流程对于其发展起着至关重要的作用。华为终端正处于销售模式转型的关键时期&#xff0c;波士顿 - 华为销售终端 MPRLTC …

【Python LeetCode Patterns】刷力扣,15 个学习模式总结

1. 前缀和&#xff08;Prefix Sum&#xff09;—— 查询子数组中元素和303. 区域和检索 - 数组不可变304. 二维区域和检索 - 矩阵不可变 2. 双指针&#xff08;Two Pointers&#xff09;—— 移向彼此或远离彼此3. 滑动窗口&#xff08;Sliding Window&#xff09;—— 找到满足…

蓝桥杯单片机刷题——串口发送显示

设计要求 通过串口接收字符控制数码管的显示&#xff0c;PC端发送字符A&#xff0c;数码管显示A&#xff0c;发送其它非法字符时&#xff0c;数码管显示E。 数码管显示格式如下&#xff1a; 备注&#xff1a; 单片机IRC振荡器频率设置为12MHz。 串口通信波特率&#xff1a;…

探索抓包利器ProxyPin,实现手机APP请求抓包,支持https请求

以下是ProxyPin的简单介绍&#xff1a; - ProxyPin是一个开源免费HTTP(S)流量捕获神器&#xff0c;支持 Windows、Mac、Android、IOS、Linux 全平台系统- 可以使用它来拦截、检查并重写HTTP(S)流量&#xff0c;支持捕获各种应用的网络请求。ProxyPin基于Flutter开发&#xff0…