《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提供的内置文件和变量

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

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

相关文章

opencv图形绘制2

目录 制作宣传语(中文) 制作宣传语(英文) 绘制标记 鼠标交互绘制十字线 鼠标交互绘制图形 鼠标交互制作几何画板 滚动条控制 鼠标事件练习 制作宣传语(中文) import cv2 import numpy as np from …

实现Element Select选择器滚动加载

<template><el-selectpopper-class"more-tag-data"v-model"tagId"filterableplaceholder"请选择"focus"focusTag"><el-optionv-for"(item, index) in taskTagLists":key"index":label"item.n…

互联网Java工程师面试题·Java 并发编程篇·第七弹

目录 16、CAS 的问题 17、什么是 Future&#xff1f; 18、什么是 AQS 19、AQS 支持两种同步方式&#xff1a; 20、ReadWriteLock 是什么 21、FutureTask 是什么 22、synchronized 和 ReentrantLock 的区别 23、什么是乐观锁和悲观锁 24、线程 B 怎么知道线程 A 修改了…

蓝桥杯 枚举算法 (c++)

枚举就是根据提出的问题&#xff0c;——列出该问题的所有可能的解&#xff0c;并在逐一列出的过程中&#xff0c;检验每个可能解是否是问题的真正解&#xff0c; 如果是就采纳这个解&#xff0c;如果不是就继续判断下一个。 枚举法一般比较直观&#xff0c;容易理解&#xff0…

完美解决lftp遇到put: Access failed: 553 Could not create file.

目录 一、问题 二、原因 三、解决方法 一、问题 put: Access failed: 553 Could not create file. 二、原因 &#xff08;1&#xff09;没有关闭SeLinux &#xff08;2&#xff09;linux默认安装vsftp服务之后只允许匿名用户的访问和下载&#xff0c;不支持上传。 三、解决方…

matlab 图像均值滤波

目录 一、算法原理二、代码实现三、结果展示本文由CSDN点云侠翻译,放入付费专栏只为防不要脸的爬虫。专栏值钱的不是本文,切勿因本文而订阅。 一、算法原理 均值滤波是一种常用的线性滤波方法,用于平滑图像并减少噪声。它的实现过程如下: 确定滤波器的大小:选择一个固定的…

P1443 马的遍历

#include <iostream> #include <queue> using namespace std; #define M 400 int arr[M 5][M 5]; typedef struct Node {int x, y; } Node; //将马能走的8个方向封装成一个二维数组 int dir[8][2] {{2, 1}, {2, -1}, {-2, 1}, {-2, -1},{1, 2}, {-1, 2}, {1, -2…

nginx的location的优先级和匹配方式

nginx的location的优先级和匹配方式 在http模块中有server&#xff0c;server模块中有location&#xff0c;location匹配的是uri 在一个server中&#xff0c;会有多个location&#xff0c;如何来确定匹配哪个location niginx的正则表达式 ^ 字符串的起始位置 $ 字符串的…

IDEA中查看整个项目代码行数

近期正在手撸Spring源码&#xff0c;想要看下自己写了多少行代码。记录下如何查看项目的代码行数&#xff0c;方便日后查阅

Hadoop3教程(六):HDFS中的DataNode

文章目录 &#xff08;63&#xff09;DataNode工作机制&#xff08;64&#xff09;数据完整性&#xff08;65&#xff09;掉线时限参数设置参考文献 &#xff08;63&#xff09;DataNode工作机制 DataNode内部存储了一个又一个Block&#xff0c;每个block由数据和数据元数据组…

【云计算】相关解决方案介绍

文章目录 1.1 云服务环境 Eucalyptus1.1.1 介绍1.1.2 开源协议及语言1.1.3 官方网站 1.2 开源云计算平台 abiCloud1.2.1 开源协议及语言1.2.2 官方网站 1.3 分布式文件系统 Hadoop1.3.1 开源协议及语言1.3.2 官方网站 1.4 JBoss云计算项目集 StormGrind1.4.1 开源协议及语言1.4…

【数据库——MySQL(实战项目1)】(3)图书借阅系统——存储函数

目录 1. 简述2. 功能代码2.1 创建存储函数&#xff0c;根据图书编号查借阅人姓名&#xff0c;并调用该函数查询‘ **小邓在森林** ’已借未还的图书情况&#xff1b;2.2 创建存储函数&#xff0c;计算某借阅人还能借阅的图书数目&#xff0c;学生限额 5 本&#xff0c;教师限额…

Vue3 + Nodejs 实战 ,文件上传项目--实现文件批量上传(显示实时上传进度)

目录 技术栈 1.后端接口实现 2.前端实现 2.1 实现静态结构 2.2 整合上传文件的数据 2.3 实现一键上传文件 2.4 取消上传 博客主页&#xff1a;専心_前端,javascript,mysql-CSDN博客 系列专栏&#xff1a;vue3nodejs 实战--文件上传 前端代码仓库&#xff1a;jiangjunjie…

树莓派部署.net core网站程序

1、发布你的项目 使用mobaxterm上传程序 回到mobaxterm,f进入目录输入&#xff1a; cd webpublish 运行程序&#xff1a;dotnet WebApplication1.dll 访问地址为&#xff1a;http://localhost:5000,尝访问如下&#xff1a; 已经出现 返回的json&#xff0c;证明是可以访问的…

MyBatis的缓存,一级缓存,二级缓存

10、MyBatis的缓存 10.1、MyBatis的一级缓存 一级缓存是SqlSession级别的&#xff0c;通过同一个SqlSession对象 查询的结果数据会被缓存&#xff0c;下次执行相同的查询语句&#xff0c;就 会从缓存中&#xff08;缓存在内存里&#xff09;直接获取&#xff0c;不会重新访问…

软件架构设计(业务架构、应用架构、数据架构、技术架构)

一、架构相关概念 1、系统 系统&#xff1a;由一群有关联的个体组成&#xff0c;根据某种规则运作&#xff0c;能完成个别原件不能独立完成的工作的群体。大的系统可以嵌套小系统&#xff0c;被嵌套的小系统往往称为大系统的子系统。 2、模块 模块是从逻辑上将系统分解&#…

Java也能做OCR!SpringBoot 整合 Tess4J 实现图片文字识别

前言 今天给大家分享一个SpringBoot整合Tess4j库实现图片文字识别的小案例&#xff0c;希望xdm喜欢。 文末有案例代码的Git地址&#xff0c;可以自己下载了去玩玩儿或继续扩展也行。 话不多说&#xff0c;开整吧。 什么是Tess4j库 先简单给没听过的xdm解释下&#xff0c;这里要…

风储联合系统的仿真模型研究

摘要 风能是目前国内外应用较为广泛的一种绿色可再生能源&#xff0c;近几年我国风电产业的发展十分迅速。然后&#xff0c;越来越多的风力发电系统建并网&#xff0c;风力发电产生的电能受外界因素影响较大&#xff0c;具有一定的随机性和波动性&#xff0c;给并网后的电力系统…

铜死亡+机器学习+WGCNA+分型生信思路

今天给同学们分享一篇单基因泛癌免疫实验生信文章“IGF2BP3 overexpression predicts poor prognosis and correlates with immune infiltration in bladder cancer”&#xff0c;这篇文章于2023年2月3日发表在BMC Cancer期刊上&#xff0c;影响因子为3.8。 膀胱癌是全球最常见…

【环境】Ubuntu20.04 安装 Anaconda 顺顺利利

ubuntu里面安装的Anaconda也是顺顺利利 别忘了source source一下 参考链接 中间遇到了一个问题&#xff0c;用下面的链接轻松解决了 关于修改anaconda安装路径的问题