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

推荐订阅源

OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Cloudbric
Cloudbric
T
The Blog of Author Tim Ferriss
美团技术团队
S
SegmentFault 最新的问题
罗磊的独立博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
IT之家
IT之家
P
Privacy & Cybersecurity Law Blog
N
News and Events Feed by Topic
爱范儿
爱范儿
T
Threatpost
The Cloudflare Blog
Spread Privacy
Spread Privacy
Latest news
Latest news
Last Week in AI
Last Week in AI
V
Vulnerabilities – Threatpost
Hugging Face - Blog
Hugging Face - Blog
T
Tor Project blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Project Zero
Project Zero
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
Tenable Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 司徒正美
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
The Exploit Database - CXSecurity.com
Security Latest
Security Latest
C
CERT Recently Published Vulnerability Notes
T
Threat Research - Cisco Blogs
Hacker News - Newest:
Hacker News - Newest: "LLM"
有赞技术团队
有赞技术团队
P
Proofpoint News Feed
Hacker News: Ask HN
Hacker News: Ask HN
L
Lohrmann on Cybersecurity
阮一峰的网络日志
阮一峰的网络日志
C
Cyber Attacks, Cyber Crime and Cyber Security
量子位
I
Intezer
C
Check Point Blog
Stack Overflow Blog
Stack Overflow Blog
博客园 - 【当耐特】
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
N
Netflix TechBlog - Medium
H
Heimdal Security Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Blog — PlanetScale
Blog — PlanetScale
G
Google Developers Blog

元视角

.NET 生态下的 Agent 框架选型:从 ReAct 到原生推理 - 元视角 从「能用」到「好用」:LLM 流式响应实现方式的探索之路 - 元视角 当我用 2000 条聊天记录,让 AI 为我画一幅自画像 - 元视角 基于 Supabase 的 AI 应用开发探索 - 元视角 微博 × MCP:社交媒体新玩法解锁 - 元视角 四点钟海棠花未眠 - 元视角 Semantic Kernel × MCP:智能体的上下文增强探索 - 元视角 基于 K-Means 聚类分析实现人脸照片的快速分类 - 元视角 容器技术驱动下的代码沙箱实践与思考 - 元视角 温故而知新:后端通用查询方案的再思考 - 元视角 浅议 CancellationToken 在前后端协同取消场景中的应用 - 元视角 Semantic Kernel 视角下的 Text2SQL 实践与思考 - 元视角 关于 ChatGPT 的流式传输,你需要知道的一切 - 元视角 RAG 的是与非、Rewrite 和 Rerank - 元视角 使用 EFCore 和 PostgreSQL 实现向量存储及检索 - 元视角 基于 LLaMA 和 LangChain 实践本地 AI 知识库 - 元视角 使用 llama.cpp 在本地部署 AI 大模型的一次尝试 - 元视角 如何为 Git 配置多个 SSH Key - 元视角 C# 使用 LibUsbDotNet 实现 USB 设备检测 - 元视角 基于 C# 实现样式与数据分离的打印方案 - 元视角 基于 SVG 的图形交互方案实践 - 元视角 前端视频播放技术概览 - 元视角 温故而知新,再话 Python 动态导入 - 元视角 后 GPT 时代,NLP 不存在了? - 元视角 视频是不能 P 的系列:使用 Milvus 实现海量人脸快速检索 - 元视角 GDI+下字体大小自适应方案初探 - 元视角 小爱音箱集成 ChatGPT 的不完全教程 - 元视角 程序员视角下的三体世界随想 - 元视角 关于 Docker 容器配置信息的渐进式思考 - 元视角 在 Docker 容器内集成 Crontab 定时任务 - 元视角 为你的服务器集成 LDAP 认证 - 元视角 似花还似非花 - 元视角 视频是不能 P 的系列:使用 Dlib 实现人脸识别 - 元视角 浅议分布式链路追踪与日志的整合 - 元视角 关于 Git 大文件上传这件小事 - 元视角 .NET 进程内队列 Channel 的入门与应用 - 元视角 使用 Fody 实现 .NET 的静态编织 - 元视角 .NET Core + ELK 搭建可视化日志分析平台(下) - 元视角 聊一聊前端图片懒加载背后的故事 - 元视角 支持外部链接跳转的 Vue Router 扩展实现 - 元视角 视频是不能 P 的系列:OpenCV 和 Dlib 实现表情包 - 元视角 不得不说的 ASP.NET Core 集成测试 - 元视角 再议 DDD 视角下的 EFCore 与 领域事件 - 元视角 Vue.js 前端项目容器化部署实践极简教程 - 元视角 再见,人间四月天 - 元视角 Python 图像风格化迁移助力画家梦想 - 元视角 利用 ASP.NET Core 中的标头传播实现分布式链路追踪 - 元视角 利用 gRPC 实现文件的上传与下载 - 元视角 七种武器:延迟队列的原理和实现总结 - 元视角 gRPC 流式传输极简入门指南 - 元视角 Envoy 集成 Jaeger 实现分布式链路追踪 - 元视角 浅议非典型 Web 应用场景下的身份认证 - 元视角 gRPC 借助 Any 类型实现接口的泛化调用 - 元视角 分布式丛林探险系列之 Redis 集群模式 - 元视角 分布式丛林探险系列之 Redis 主从复制模式 - 元视角 通过 Python 预测 2021 年双十一交易额 - 元视角 gRPC 搭配 Swagger 实现微服务文档化 - 元视角 SSL/TLS 加密传输与数字证书的前世今生 - 元视角 使用 Python 自动识别防疫健康码 - 元视角 你不可不知的容器编排进阶技巧 - 元视角 ASP.NET Core 搭载 Envoy 实现 gRPC 服务代理 - 元视角 再话 AOP,从简化缓存操作说起 - 元视角 ASP.NET Core 搭载 Envoy 实现微服务身份认证(JWT) - 元视角 ASP.NET Core 搭载 Envoy 实现微服务的监控预警 - 元视角 ASP.NET Core 搭载 Envoy 实现微服务的反向代理 - 元视角 ASP.NET Core gRPC 打通前端世界的尝试 - 元视角 EFCore 实体命名约定库:EFCore.NamingConventions - 元视角 ASP.NET Core gRPC 集成 Polly 实现优雅重试 - 元视角 ASP.NET Core gRPC 健康检查的探索与实现 - 元视角 ASP.NET Core gRPC 拦截器的使用技巧分享 - 元视角 SnowNLP 使用自定义语料进行模型训练 - 元视角 使用 HttpMessageHandler 实现 HttpClient 请求管道自定义 - 元视角 ABP vNext 的实体与服务扩展技巧分享 - 元视角 ABP vNext 对接 Ant Design Vue 实现分页查询 - 元视角 源代码探案系列之 .NET Core 跨域中间件 CORS - 元视角 源代码探案系列之 .NET Core 限流中间件 AspNetCoreRateLimit - 元视角 源代码探案系列之 .NET Core 并发限制中间件 ConcurrencyLimiter - 元视角 通过 EmbededFileProvider 实现 Blazor 的静态文件访问 - 元视角 低代码,想说爱你不容易 - 元视角 记一次失败的 ThoughtWorks 面试经历 - 元视角 从 C# 1.0 到 C# 9.0,历代 C# 语言特性一览 - 元视角 通过 Python 分析 2020 年全年微博热搜数据 - 元视角 基于 Python 和 Selenium 实现 CSDN 一键三连自动化 - 元视角 使用多线程为你的 Python 爬虫提速的 N 种姿势,你会几种? - 元视角 实现网页长截图的常见思路总结 - 元视角 温故而知新,由 ADO.NET 与 Dapper 所联想到的 - 元视角 视频是不能 P 的系列:OpenCV 人脸检测 - 元视角 作为技术宅的我,是这样追鬼滅の刃的 - 元视角 使用 Python 抽取《半泽直树》原著小说人物关系 - 元视角 厉害了!打工人用 Python 分析西安市职位信息 - 元视角 使用 dotTrace 对 .NET 应用进行性能分析与优化 - 元视角 一道 HashSet 面试题引发的蝴蝶效应 - 元视角 基于选项模式实现.NET Core 的配置热更新 - 元视角 Dapper.Contrib 在 Oracle 环境下引发 ORA-00928 异常问题的解决 - 元视角 .NET Core 中对象池(Object Pool)的使用 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(下):EventBus 篇 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(中):RabbitMQ 篇 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(上):基础篇 - 元视角 记一次从已损坏的 Git 仓库中找回代码的经历 - 元视角 .NET Core 原生 DI 扩展之属性注入实现 - 元视角
《Cg Programming in Unity》读书笔记 - 元视角
飞鸿踏雪 · 2015-12-25 · via 元视角

  最近开始着手Shader语言的学习,因为Unity3D没有提供类似虚幻四引擎的材质编辑器功能,所以当在Unity3D中碰到需要提供引擎默认材质以外的效果的时候,就需要我们来编写Shader以实现各种特效,本文主要是结合《Cg Programming in Unity》这本书和浅墨博客中关于Shader的这部分内容来学习和整理,目的是帮助博主快速掌握Shader语言。

Unity3D中的Shader概述

  为Unity3D编写Sahder代码相对OpenGL和DirectX要简单。Unity3D没有刻意地区分Cg语言和HLSL语言,因为这两者是非常相似的,这意味着使用HLSL编写的代码可以直接在Cg中使用,更为深入地探索HLSL和Cg的渊源你会戏剧性地发现Cg是Microsoft和NVIDIA联手推出并试图从硬件和软件上和GLSL相抗衡的一种产物。

  其中CgNvidia提供的一种Shader编写语言,HLSL是DirectX提供的一种Shader编写语言,这意味着大部分的Cg代码同样可以被HLSL支持。Unity3D中使用的Shader编写语言是ShaderLab,其本质是对Cg进行了封装,因此在Unity3D中编写Shader本质上在给DirectX或者OpenGL写Shader,因为我猜测在引擎内部存在HLSL和GLSL的相互转换使得Unity3D能够在不同的平台都有较好的图形表现。

  Unity3D中Shader程序的编写可以参考这里。我们知道计算机图形学的中渲染管线一般可以分为两种类型,即固定功能渲染管线和可编程渲染管线。因此从这个角度来看,Unity3D中主要有三种着色器,即固定功能着色器(Fixed Function Shader)、表面着色器(Surface Shader)和 顶点着色器&片段着色器 (Vertex Shader & Fragment Shader)。

Unity3D中Shader的基本结构

  首先,Unity3D中Shader的基本结构是:

Shader 
{ 
    //------【属性】------//
    Properties
    {

    } 

    //------【子着色器】------//
    SubShaders
    {
    }
       
    //------【回滚】------//
    Fallback
}

对这个结构我们的理解是,Shader代码首先是一些属性定义,用来指定这段代码将有哪些输入。接下来是一个或者多个的子着色器,在实际运行中,哪一个子着色器被使用是由运行的平台所决定的。子着色器是代码的主体,每一个子着色器中包含一个或者多个的Pass。在计算着色时,平台先选择最优先可以使用的着色器,然后依次运行其中的Pass,然后得到输出的结果。最后指定一个Fallback,用来处理所有SubShader都不能运行的情况称为回滚。下面来分别介绍Shader基本结构中的各个部分:

Shader中的Properties

Properties是由多条标签组成的Shader属性定义,这些属性能够在Unity3D中的编辑器中显示出来,以此来确定这段Shader代码由哪些输入。常见的标签定义有:

name("display name", Range(min, max)) = number

定义一个在编辑器中可通过滑动条修改的浮点数属性

name("display name", Color) = (number,number,number,number)

定义一个在编辑器中可通过拾色器来设置RGBA的颜色值属性

name("display name", 2D) = "name" {options }

定义一个在编辑器中可编辑的2D纹理属性,其中options可选表示即纹理自动生成纹理坐标时的模式,通常是ObjectLinear、EyeLinear、SphereMap、 CubeReflect、CubeNormal其中之一。

name("display name", Rect) = "name"{ options }

定义一个在编辑器中可编辑的非二次方2D纹理属性

name("display name", Cube) = "name"{ options }

定义一个在编辑器中可编辑的立方贴图纹理属性

name("display name", Float) = number

定义一个在编辑器中可通过输入框修改的浮点数值属性

name("display name", Vector) =(number,number,number,number)

定义一个在编辑器中可通过输入框修改的Vector4属性

Shader中的SubShader

  SubShader,即子着色器。子着色器是代码的主体,每一个子着色器中包含一个或者多个的Pass。在计算着色时,平台先选择最优先可以使用的着色器,然后依次运行其中的Pass,然后得到输出的结果。子着色器的基本结构是:

Subshader
{ 
    //------【Tags标签】------//
    Tags{}

    //------【Pass通道】------//
    Pass
    {

    }
}

Tags标签

在这里子着色器使用Tags标签来告诉渲染引擎期望何时和如何渲染对象,其语法是:

Tags { "TagName1" = "Value1" "TagName2" = "Value2" }

即采用一个键值对来表示标签的名称及其对应的值,通常由三种标签可以在这里使用:

"Queue" = "Transparent"

表示决定渲染次序的队列标签,其取值定义如下:

  • Background在所有队列渲染之前被渲染,如天空盒等。
  • Geometry默认渲染大部分的对象,如不透明的几何体等。
  • Transparent在所有队列渲染之后被渲染采用由后到前的次序,如玻璃、粒子效果等。
  • Overlay主要实现叠加效果的渲染,如镜头光晕等。
Tags { "Queue" = "Geometry+1" }

表示自定义中间渲染队列,当默认的渲染队列不能满足要求时可选用当前渲染队列。在Unity实现中每一个队列都被一个整数的索引值所代表。Background为1000、Geometry为2000、Transparent为3000、Overlay为4000.

Tags { "IgnoreProjector" ="True" }

表示忽略投影标签,其值为True表示忽略投影反之表示受投影影响。

Pass通道

Pass通道块控制被渲染的对象的几何体。其结构定义如下:

Pass 
{ 
    //------【名称与标签】------//
    [Name and Tags] 
    //------【渲染设置】------//
    [RenderSetup]
    //------【纹理设置】------//
    [TextureSetup] 
}

名称与标签

在通道中可以定义其名称和任意数目的标签,通过使用tags来告诉渲染引擎在什么时候该如何渲染他们所期望的效果,其语法和Tags标签完全相同,即采用键值对来定义标签的名称和其对应的值。常用的标签有:

Tags { "LightMode" = "Always" }

表示一个光照模式标签,该标签的取值可以是:

  • Always总是渲染。没有运用光照。
  • ForwardBase用于正向渲染,环境光、方向光和顶点光等
  • ForwardAdd用于正向渲染,用于设定附加的像素光,每个光照对应一个pass
  • PrepassBase用于延迟光照,渲染法线/镜面光。
  • PrepassFinal用于延迟光照,通过结合纹理,光照和自发光渲染最终颜色
  • Vertex用于顶点光照渲染,当物体没有光照映射时,应用所有的顶点光照
  • VertexLMRGBM用于顶点光照渲染,当物体有光照映射的时候使用顶点光照渲染。在平台上光照映射是RGBM 编码
  • VertexLM用于顶点光照渲染,当物体有光照映射的时候使用顶点光照渲染。在平台上光照映射是double-LDR 编码(移动平台,及老式台式CPU)
  • ShadowCaster使物体投射阴影。
  • ShadowCollector为正向渲染对象的路径,将对象的阴影收集到屏幕空间缓冲区中。

渲染设置

渲染设置设定显示硬件的各种状态,常用的命令如下:

Material 
{ 
    Diffuse Color(R,G,B,A)
    //漫反射颜色构成,即对象的基本颜色。

    Ambient Color(R,G,B,A)
    //环境色颜色构成,即当对象被RenderSettings中设定的环境色所照射时对象所表现的颜色。

    Specular Color(R,G,B,A)
    //对象反射高光的颜色。
    //(R,G,B,A)四个分量分别代表红绿蓝和Alpha,取值为0到1之间。

    Shininess Number
    //加亮时的光泽度,在0和1之间。

    Emission Color
    //自发光颜色,即当不被任何光照所照到时对象的颜色。
    //(R,G,B,A)四个分量分别代表红绿蓝和Alpha,取值为0到1之间。


    //【备注】对象上的完整光照颜色最终是:
    //FinalColor = Ambient * RenderSettings ambientsetting + 
    //(Light Color * Diffuse + Light Color *Specular) + Emission
}

定义一个使用顶点光照管线的材质

Lighting On | Off

开启或关闭顶点光照

Cull Back | Front | Off

设置多边形剔除模式

ZTest (Less | Greater | LEqual | GEqual |Equal | NotEqual | Always)

设置深度测试模式

ZWrite On | Off

设置深度写模式

Fog { Fog Block }

设置雾参数

AlphaTest (Less | Greater | LEqual | GEqual| Equal | NotEqual | Always) CutoffValue

开启alpha测试

Blend SourceBlendMode | DestBlendMode

设置alpha混合模式

Color Color value

设置当顶点光照关闭时所使用的颜色

ColorMask RGB | A | 0 | any combination of R, G, B, A

设置颜色写遮罩。设置为0将关闭所有颜色通道的渲染

Offset OffsetFactor , OffsetUnits

设置深度偏移

SeparateSpecular On | Off

开启或关闭顶点光照相关的平行高光颜色

ColorMaterial AmbientAndDiffuse | Emission

当计算顶点光照时使用每顶点的颜色

纹理设置

纹理设置的作用是在完成渲染设定后指定一定数目的纹理及其混合模式:

SetTexture [texture property]{ [Combineoptions] }

Shader中的Fallback

Fallback就像switch-case结构中的default,其作用是定义当处理所有SubShader都不能运行时采取的一个补救方案,这个主要是为了解决不同的显卡对Shader支持的差异问题。

Unity3D中Shader的语法

Unity3D中Shader的语法主要针对Cg代码而言,Cg代码是可编程着色器和表面着色器中的核心内容,Cg代码从CGPROGRAM开始到ENDCG结束

Unity3D中的三种着色器