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

news/2025/3/28 16:19:40/

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 fragfloat4 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 fragfixed4 _Colorstruct 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.ppmy.cn/news/1582856.html

相关文章

论文阅读 EEGNet

EEGNet: A Compact Convolutional Neural Network for EEG-based Brain-Computer Interfaces EEGNET网络结构解析与复现 | 青椒的学习笔记 0. 摘要 传统基于CNN的脑机接口(BCI)研究多针对单一类型的任务(如P300分类、运动想象分类&#xff…

STC89C52单片机学习——第35节: [16-1] AD/DA

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.03.23 51单片机学习——第35节: [16-1] AD/DA 前言开发板说明引用解答和科普一、AD问题…

Jackson的核心类与API方法:ObjectMapper、JsonNode、ObjectNode、ArrayNode

JSON数据的操作,系列文章: 《Jackson的核心类与API方法:ObjectMapper、JsonNode、ObjectNode、ArrayNode》 《Jackson的使用与创建Jackson工具类》 《Jackson使用ObjectNode对象实现JSON对象数据(一):增、删、改、查》 《Jackson使用ArrayNode对象实现JSON列表数据(二)…

VS代码生成工具ReSharper v2024.3——支持C# 13

ReSharper 是 Microsoft Visual Studio Marketplace上热门的扩展程序,您可以进行深度代码分析、智能代码协助、实时错误代码高亮显示、解决方案范围内代码分析、快速代码更正、一步完成代码格式化和清理、业界领先的自动代码重构、高级的集成单元测试方案&#xff0…

Vue 3 自定义指令:实现自动滚动效果

Vue 3 自定义指令:实现自动滚动效果的深度解析 在前端开发中,尤其是在使用 Vue 3 框架构建用户界面时,自定义指令为我们提供了一种强大且灵活的方式来扩展 HTML 元素的行为。今天,我们将深入探讨一个实用的 Vue 3 自定义指令——…

AI 生成 PPT 网站介绍与优缺点分析

随着人工智能技术不断发展,利用 AI 自动生成 PPT 已成为提高演示文稿制作效率的热门方式。本文将介绍几款主流的 AI PPT 工具,重点列出免费使用机会较多的网站,并对各平台的优缺点进行详细分析,帮助用户根据自身需求选择合适的工具…

Spring MVC 执行流程:一个请求在 Spring MVC 中是如何执行的?

当用户发送一个 HTTP 向 Spring MVC 应用,该请求在 Spring MVC 的执行流程如下: 当用户向 Spring MVC 发起一个 HTTP 请求,该请求会被 Dispatcher Servlet(前端控制器)拦截;DispatcherServlet 调用 Handler…

双核锁步技术在汽车芯片软错误防护中的应用详解

摘要 本文深入探讨了双核锁步技术在保障汽车芯片安全性中的应用。文章首先分析了国产车规芯片在高安全可靠领域面临的软错误难点及攻克方向,然后详细介绍了双核锁步技术的基本原理及其在汽车芯片防软错误的重要性。通过对比国内外多家厂商的芯片技术,分析…