惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Forbes - Security
Forbes - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
L
LangChain Blog
量子位
GbyAI
GbyAI
B
Blog RSS Feed
月光博客
月光博客
人人都是产品经理
人人都是产品经理
腾讯CDC
Recent Announcements
Recent Announcements
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
The Cloudflare Blog
D
Docker
Cyberwarzone
Cyberwarzone
U
Unit 42
NISL@THU
NISL@THU
C
Check Point Blog
B
Blog
大猫的无限游戏
大猫的无限游戏
Cisco Talos Blog
Cisco Talos Blog
Recorded Future
Recorded Future
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
G
GRAHAM CLULEY
Engineering at Meta
Engineering at Meta
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
P
Proofpoint News Feed
F
Fortinet All Blogs
V
V2EX
T
Threat Research - Cisco Blogs
T
Threatpost
S
SegmentFault 最新的问题
Know Your Adversary
Know Your Adversary
雷峰网
雷峰网
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - 司徒正美
P
Privacy & Cybersecurity Law Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
TaoSecurity Blog
TaoSecurity Blog
Latest news
Latest news
Apple Machine Learning Research
Apple Machine Learning Research
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Y
Y Combinator Blog
P
Privacy International News Feed
L
Lohrmann on Cybersecurity
AWS News Blog
AWS News Blog
G
Google Developers Blog
美团技术团队

音视频开发进阶

音视频教程-第三节 音视频教程-第二节 真的,AI 可能就是新时代的信息差 充值 Cursor 之后,工作有了哪些变化?🤔 个人'蒸馏'大模型能做哪些有意思的事情 DeepSeek 大模型在 Mac 上的部署和运行 音视频教程-第一节 【WebRTC 专栏】-- Android 开发集成 WebRTC 库的几种方式 【WebRTC 专栏】-- 在 Mac M1 等系列芯片编译和开发 WebRTC-Android 库 Meta Llama3 大模型在 Mac 上的部署和运行 iOS VideoToolBox 解码 HEVC Open-GOP 视频的问题排查 Flutter 状态管理之 InheritedWidget 使用和分析 用 ChatGPT 回答技术问题怎么样 ? 音视频开发系统入门大致路线 UE 4.27 添加自定义 ShadingModel 用 UE4 虚幻引擎做个捏脸小功能~~ UE4 材质练习 之 凹凸贴图偏移的使用 UE4 材质练习系列基础 OpenGL上下文创建以及共享机制 007 | 播放器系列专栏-解析 MP4 文件读取信息 006 | 播放器系列专栏-在 Mac 上查看 MP4 格式信息 干货 | 快速抽取缩略图是怎么练成的? 关于直播、WebRTC、FFmpeg 的那些事 005 | 播放器系列专栏-在 Windows 上查看 MP4 格式信息 将音视频中的花屏、绿屏、黑屏问题一网打尽 关于音视频里面的解码帧率和渲染帧率 004 | 播放器系列专栏-认识MP4视频(下) 003 | 播放器系列专栏-认识MP4视频(上) 入门或者转行音视频,应该要怎么做? H264视频文件如何缩放分辨率 002 | 播放器系列专栏-FFmpeg依赖库的配置 001 | 播放器系列专栏-关于播放器项目的一个小实践 Seek策略以及在有B帧情况下的处理 目前流媒体开发工程师工作内容主要是什么? 一个音视频领域专业问答的小圈子 干货收藏 || Vulkan Game Engine 视频教程 音视频春节假期内卷指南(实操) Vulkan 在 FFmpeg 中的支持 Windows 下 FFmpeg 和 LibX264 的编译和配置 Metal 开发 | 使用 C++ 进行接口调用 音视频开发工作经验分享 || 视频版 FFmpeg 调用 MediaCodec 硬解码到 Surface 上 代码吸猫 | 用 OpenGL 图像渲染的养猫计划 百倍变速--解码到底能不能丢 非参考帧 ?FFmpeg 有话说!!! 老生常谈-FFmpeg 的编译问题轻松搞定 FFmpeg 调用 Android MediaCodec 进行硬解码(附源码) 【WebRTC 专栏】--创建相机预览 Unity Shader 光照基础之 Half Lambert 光照模型 Unity Shader 光照基础之Lambert光照模型 Unity Shader 光照基础内容 Unity Shader 显示一张图片纹理 Unity 物体的基本操作 C++ 模板系列小结07-尾置返回类型 C++ 模板系列小结06-可变参数模板特性 C++ 中的多线程的使用和线程池建设 C++ 模板系列小结05-模板类型作为模板参数 C++ 模板系列小结04-类模板中的成员模板 C++ 模板系列小结03-在模板中指定变量类型 C++ 模板系列小结02-非类型模板参数 C++ 模板系列小结01-函数模板和类模板 从零打造渲染引擎系列01-什么是渲染引擎 iOS开发 - 在 Swift 中去调用 C/C++ 代码 2021 技术新番 - 从零打造渲染引擎系列 iOS 音视频开发的一些基础准备工作 音视频交流群又来啦~~~ 【WebRTC 专栏】WebRTC & Android 开发学习环境搭建~ 【喜大普奔】域名终于备案通过啦 Shader 优化 | OpenGL 绘制网格效果 【音视频连载-011】第二季 FFmpeg 一层一层获取文件信息 KodeLife | Shader 实时编辑预览的强大工具使用实践 推荐几个堪称教科书级别的 Android 音视频入门项目 【音视频连载-010】第二季 FFmpeg 日志打印 【音视频连载-008】基础学习篇-SDL 播放 PCM 音频文件(下) 【音视频连载-007】基础学习篇-SDL 播放 PCM 音频文件(上) 【音视频连载-006】基础学习篇-SDL 播放 YUV 视频文件 【音视频连载-005】基础学习篇-SDL 加载 YUV 文件并显示 【音视频连载-004】基础学习篇-SDL 加载图片并显示 【音视频连载-003】基础学习篇-SDL 消息循环和事件响应 【音视频连载-002】基础学习篇-SDL 创建窗口并显示颜色 【音视频连载-001】基础学习篇- SDL 介绍以及工程配置 LearnOpenGL 源码在 MAC 上的编译与调试 2019 年终总结与回顾 Android NDK 开发的免费技术视频来啦~~ OpenGL 实现视频编辑中的转场效果 OpenGL 实践之贝塞尔曲线绘制 图像库 libjpeg-turbo 编译与实践 图像库 libpng 编译与实践 rust 开发编译 Android 动态库实践 Android NDK 开发 —— 从 Assets 文件夹加载图片并上传纹理 简单易用的图像解码库介绍 —— stb_image 博客图床迁移记 进击的 Vulkan 移动开发之 SwapChain 进击的 Vulkan 移动开发之 Command Buffer 进击的 Vulkan 移动开发之 Instance & Device & Queue 进击的 Vulkan 移动开发(一)之今生前世 Java 显式锁 Lock 与条件队列 C++ 标准容器库小结 MediaCodec 硬编码之相机内容编码成 H264 文件 一文读懂 YUV 的采样与格式 《OpenGL ES 3.x 游戏开发》碰撞检测之 AABB 包围盒
UnityShader 的基本概念
音视频开发进阶 · 2021-08-15 · via 音视频开发进阶

一个专注音视频领域的小圈子

Unity 中的 Shader 不同于 OpenGL 的 GLSL ,它是通过 ShaderLab 语言编写的。 ShaderLab 是 Unity 为开发者提供的高层级的渲染抽象层,它是一种说明性语言。 ShaderLab 使用了一些嵌套在花括号内部的语义来描述一个 Unity Shader 文件的结构,这些结构包含了许多渲染所需的数据。

$a_{1}$

一个 Unity Shader 的基本结构如下:

Shader "shaderName" {
    Properties{
        // 属性
    }
    
    SubShader{
        // 显卡 A 使用的子着色器
    }
    
    SubShader{
        // 显卡 B 使用的子着色器
    }
    Fallback "VertexLit"
}

可以在 Properties 语句块中定义着色器所需的各种属性,这些属性将会出现在材质面板中。

UnityShader 中共有 8 种属性类型,如下代码所示:

Shader "Basic/BasicPropertiesShader"
{
    Properties
    {
        _Int ("Int",Int) = 100
        _Float("Float",Float) = 10.0
        _Range("Range",Range(0.0,5.0)) = 3.0
        _Color("Color",Color) = (1,1,1,1)
        _Vector("Vector",Vector) = (2,3,6,1)
        _2D("2D",2D) = ""{}
        _Cube("Cube",Cube) = "while"{}
        _3D("3D",3D) = "black"{}
    }
    Fallback "Diffuse"
}

Int、Float、Range 类型对应单独的数字,Color、Vector 类型对应四维向量,2D、3D、Cube 对应纹理类型,默认值通过一个字符串和花括号来指定,字符串要么是空的,要么是内置的纹理名称,比如“while”、“black”、“gray”等。

定义这些属性之后就可以在参数面板里面去调节对应值。

![[9982b5e6d65970f8349220a7bf3b2f1c_MD5.png]]

要想真正使用这些值去调节 Shader 效果,还需要在 SubShader 中再定义一遍。

SubShader 的使用

每一个 UnityShader 可以包含多个 SubShader 语义块,但最少要有一个。

SubShader 语义块中包含的定义如下:

SubShader {
   // 可选
   [Tags] 
   
   // 可选
   [RenderSetup]
   
   Pass{
   
   }
   
   // Other Pass
}

SubShader 中定义了一系列 Pass 和可选的状态(RenderSetup)和标签(Tags),每个 Pass 定义了一次完整的渲染流程。

Pass 中也可以定义状态(RenderSetup)和标签(Tags)。

但是 SubShader 中的标签是特定的,和 Pass 中使用的标签是不一样的。

而状态设置的语法是相同的,但 SubShader 中设置了状态,会是全局生效作用于所有的 Pass ,不过 Pass 中不想用全局状态可以在 Pass 另外定义状态来修改。

状态设置

ShaderLab 中提供的状态设置主要就是渲染时是否开启深度测试、混合模式等。

如果有了解 OpenGL 渲染的,就应该对这些不陌生了,只是 OpenGL 通过 API 调用来设定,而 ShaderLab 通过在 Shader 中来指定了。

ShaderLab 中提供的渲染状态如下,直接摘抄自 《Unity Shader 入门精要》的附图了。

![[a488e6e1ba1262a518701dbe0a7f9bf7_MD5.png]]

Tag 标签

SubShader 的标签是一个键值对,键和值都是字符串类型,这些键值对是 SubShader 和渲染引擎之间的沟通桥梁,它们用来告诉 Unity 的渲染引擎:SubShader 希望怎样以及何时渲染这个对象。

具体的标签类型如下,,直接摘抄自 《Unity Shader 入门精要》的附图了。

![[393e39a248c10ffef93dfa8abb303de2_MD5.png]]

Pass 块

Pass 语义块的结构如下:

Pass {
    [Name]
    [Tags]
    [RenderSetup]
    // render code
}

在 Pass 语义块进行渲染之前也有一些状态要设置,Name 就是该 Pass 的名字,渲染状态和 SubShader 中提到的渲染状态一致。

Pass 中的标签不同于 SubShader 中的标签,可用的如下:

![[47b2eb0171b46d7445dbafca80b51979_MD5.png]]

Fallback

最后的 Fallback 块就是当前面的渲染都不行才会走到这里了,相当于是兜底了。

另外,当 UnityShader 有问题的话,物体的颜色会出现粉红色的异常。

![[37250fe5578c47ac6eb5563234eb486e_MD5.png]]

Shader 分类

UnityShader 共有三种类型的 Shader ,分别是表面着色器、顶点/片元着色器、固定函数着色器。

表面着色器 Surface Shader

表面着色器是 Unity 自己创造的一种着色器代码类型,需要的代码量很少,但渲染的代价很大。

Unity 在表面着色器背后做了很多工作,将它们转换成对应的顶点/片元着色器。

顶点/片元着色器 Vertex/Fragment Shader

顶点/片元着色器就是 OpenGL 中常用的着色器了,只不过这里统一在一个文件中描述,而且渲染流程和 OpenGL 的流程也大同小异,代码上会有些区别,原理都是一样的。

固定函数着色器

固定函数着色器用的就比较少了,也渐渐淘汰了,实际上它最后也被 Unity 转换成了顶点/片元着色器。

小结

以上就是关于 UnityShader 的基本概念,也算是 《UntiyShader入门精要》的读书笔记了。

看完一遍书,再来博客总结一遍内容,用输出促进输入,从而学的更牢固一点,接下来就要进入正式的 UnityShader 编写了。

原创文章,转载请注明来源:    UnityShader 的基本概念