前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Unity Shader基础

Unity Shader基础

原创
作者头像
Zero Two
发布于 2024-07-14 11:59:55
发布于 2024-07-14 11:59:55
16900
代码可运行
举报
文章被收录于专栏:Unity LearningUnity Learning
运行总次数:0
代码可运行

我也是一个学习者,有错误请指出。 References: 《Unity Shader 入门精要》

Unity Shader概述

材质Material与Unity shader

Unity中,我们需要配合使用材质和unity shader,它们的关系和流程是:

首先创建Unity Shader,它定义了各种着色器(如顶点着色器、片元着色器)、属性和指令,将其赋给材质。可以在材质面板上调整Unity Shader的属性,最后将其赋给某个要渲染的对象(模型)来得到最终的效果。

Unity中的材质

创建好一个材质后,一般要结合一个GameObject的Mesh或者Particle System来工作。

从Unity 5.0版本开始,默认情况下创建的Material使用的是Unity内置的Standard Shader。这种默认行为一直持续到现在。Standard Shader提供了丰富的物理材质(PBR)功能,允许用户创建各种复杂和逼真的材质效果。

材质的Inspector界面中,这个选可以简单调整光照,并且这个界面本身有预览功能,可以按住右键移动查看效果。

Unity Shader

Unity Shader与传统的vs和fs有很大不同。

Unity中提供了5种Unity Shader模板:

  1. Standard Surface Shader: 包含了一个标准光照模型的表面着色器模板
  2. Unlit Shader:产生一个不包含光照(但包含雾效)的基本顶点/片元着色器
  3. Image Effect Shader:实现屏幕后处理效果的模板
  4. Computer Shader:特殊的shader,利用GPU的并行性计算与常规渲染管线无关的计算
  5. Ray Tracing Shader:用于实现光线追踪效果的模板

材质可以选择使用的shader,这样在材质的Inspector界面可以设置shader的各种属性。

在Unity Shader的Inspector界面中,可以看到和设置很多信息,在Compiled Code选项中,可以看到该Shader针对不同图形API接口编译的代码。

ShaderLab

如果直接使用某一个图形API进行渲染,要进行很多工作,一不注意就会出错(当初我就是设置错了一个渲染状态导致我调试了2小时OpenGL)

而Unity Shader为开发者提供了一个渲染抽象层,使得开发者可以更加轻松。

所有的Unity Shader都是使用ShaderLab来编写的,ShaderLab是Unity提供的编写Unity Shader的一种说明性语言,它使用了一些嵌套在花括号内的语义来描述Unity Shader文件的结构,这些结构包含了许多渲染所需的数据,例如Properties语句块中定义了着色器所需的各种属性,这些属性会出现材质面板中。

Unity Shader的结构

之前我们提到了Unity Shader是通过Shader Lab分为了多个语义块,下面将分块介绍Unity Shader。

Properties

这个语义块包含了一系列属性,这些属性会出现在材质面板中。

代码一般为这样的形式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Properties {
     Name ("display name", Type) = DefaultValue
     // 更多其他属性
}

Properties的属性类型:

语义块中定义的属性的作用就是为了在材质面板中显示,这样开发者可以在面板上直接调整属性的值。shader中要想使用这些变量,需要直接在shader中使用相应的Uniform变量,属性和Uniform变量的名字通常是一致的,这样系统才会正确将属性传给Uniform变量;或者通过脚本传递。

SubShader

每个Unity Shader文件可以包含多个SubShader块,至少要有一个SubShader块。当Unity加载这个Unity Shader时,Unity会扫描所有的SubShader块,然后选择第一个能够在目标平台上运行的SubShader。

这样做的原因是,不同的显卡具有不同的能力,我们希望在旧显卡上运行计算复杂度较低的着色器,在高级的显卡上运行复杂度较高的着色器。

SubShader语义块的定义如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SubShader{
    // 可选的
    [Tags]
    // 可选的
    [RenderSetup]
    
    Pass{
    
    }
    // 其他Pass
}

SubShader中定义了一系列的Pass以及[RenderSetup]状态和[Tags]标签。

每个Pass定义了一个完整的渲染流程,过多的Pass会导致性能的下降。标签和状态同样也可以在Pass中定义,但是SubShader的标签与Pass中使用的标签是不一样的,SubShader中的一些标签是特定的;状态两者使用的语法相同,但如果在SubShader中设置了状态,那么会用于全部的Pass

状态设置

SubShader提供了一系列的指令,这些指令用于设置显卡的各种状态。

一些常见的状态设置

就像之前提到的,SubShader中设置的状态会应用到全部的Pass,要想不同Pass使用不同的设置,需要在每个Pass中单独进行状态设置。

SubShader标签

SubShader的标签是一个键值对,键和值都是字符串。

结构如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Tags { "TagName1" = "Value1" "TagName2" = "Value2" }

Pass标签

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Pass {
    [Name]
    [Tags]
    [RenderSetup]
    // other
}

可以在Pass中定义该Pass的名称:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Name "MyPassName"

这样,我们可以在其他Unity Shader中调用ShaderLab的UsePass命令使用Pass

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
UsePass "MyShader/MYPASSNAME"

Unity内部会将所有Pass的名称转换为大写字母,所以使用UsePass时要使用大写形式

Pass中的标签不同于SubShader的标签

RequireOptions现在有很多选项,例如Shadows, Directional, Point等等,使用时查阅相关文档即可。

Unity Shader中还支持一些特殊的Pass:

  1. UsePass:复用其他Shader的Pass
  2. GrabPass:该Pass的作用是抓取屏幕并将结果存储在一张纹理中,用于后续Pass处理

Others

Unity Shader以及ShaderLab还能实现很多功能,比如自定义材质面板等等,但不太常用。

Unity Shader的形式

上面讲解了这么多,但基本没有涉及到Unity Shader是如何处理传统的像是顶点着色器或者片元着色器。这些着色器代码可以写在SubShader语义块中(表面着色器),也可以写在Pass语义块中(顶点/片元着色器和固定函数着色器)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Shader "ShaderName" {
    Properties {
    }
    SubShader {
        // shader code
    }
    SubShader {
    }
}

Surface Shader

这是Unity自创的一种shader类型,它需要的代码量很少,这就意味着Unity在背后为它做了很多工作(一般这种需要软件背后做工作的,性能都不会太好)。它本质上还是一个vs或fs,Unity会对其进行转换。

它的意义在于处理了很多光照细节,不需要开发者自己编写。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Shader "Custom/Simple Surface Shader" {
    SubShader {
        Tags { "RenderType" = "Opaque" }
        CGPROGRAM
        #pragma surface surf Lambert

        struct Input {
            float4 color : COLOR;
        };

        void surf(Input IN, inout SurfaceOutput o) {
            o.Albedo = IN.color.rgb;
        }
        ENDCG
    }
}

需要注意的点有:

  1. Surface Shader的代码没有定义在Pass语义块中,表面着色器不需要开发者关心Pass的问题,Unity会为我们处理好
  2. CGPROGRAMENDCG之间的代码是使用Unity封装后的CG/HLSL编写,与原生的CG/HLSL仅有细微的不同。

Vertex/Fragment Shader

同样是使用CG/HLSL语言来编写,定义在CGPROGRAMENDCG,但需要写在Pass语义块内,我们需要自己定义每个Pass使用的Shader代码。

如果想要使用GLSL编写Unity shader,需要将GLSL代码嵌套在GLSLPROGRAMENDGLSL之间。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
《Unity Shader入门精要》笔记:初级篇(1)
本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载。 本篇博客会补充一些扩展内容(例如其他博客链接)。 本篇博客还会提供一些边读边做的效果截图。文章内所有数学公式都由Latex在线编辑器生成。 本篇博客主要提供一个“glance”,知识点的总结。如有需要请到书店购买正版。 博客提及所有官方文档基于2022.2版本,博客会更新一些书中的旧的知识点到2022.2版本。 如有不对之处欢迎指正。 我创建了一个游戏制作交流群:637959304 进群密码:(CSGO的拆包密
[Sugar]
2022/09/21
7960
Unity3D学习笔记3——Unity Shader的初步使用
在上一篇文章《Unity3D学习笔记2——绘制一个带纹理的面》中介绍了如何绘制一个带纹理材质的面,并且通过调整光照,使得材质生效(变亮)。不过,上篇文章隐藏了一个很重要的细节——Unity Shader。Shader(着色器)是渲染管线中可被用户编程的阶段,依靠着色器可以控制渲染管线的细节。现代图像渲染技术,都把Shader封装成与Material(材质)相关的组件。所以这篇文章,我们就初步学习下在Unity中使用Shader。
charlee44
2021/08/06
4.3K0
Unity3D学习笔记3——Unity Shader的初步使用
Unity Shader入门
b.Shader分类。Shader中文翻译为“着色器”,含义是:可编程图形管线。主要分为:Vertex Shader和fragment Shader,即定点Shader和片段Shader。上面有一个概念是“图形管线”,简单解释就是:计算机处理图形显示的处理流水线。
全栈程序员站长
2022/09/20
8030
《Unity Shader入门精要》笔记(二)
Unity Shader定义了渲染所需的各种代码、属性和指令;材质则允许我们调整这些属性,并将其最终赋给相应的模型。 通俗讲就是:Shader制定了渲染的规则,材质是让这个物体在这个规则下调整渲染效果。
代码咖啡
2021/12/06
1.8K0
《Unity Shader入门精要》笔记(二)
【Shader】Shader官方示例[通俗易懂]
官方示例原文地址:https://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html
全栈程序员站长
2022/07/31
1.1K0
【Shader】Shader官方示例[通俗易懂]
Unity高级开发-Shader开发(3)-Shader编程
着色器:本身就是一段代码,专业性非常强的代码。就是指着色器有哪些输入。这些子着色器由运行的平台选择。它包含:1.属性定义、2.多个或者至少一个子着色器、3.还有一个处理后的结果即回滚。而回滚就是计算着色时,用来处理所有的子着色器不能运行的情况。
孙寅
2020/06/02
1.9K0
Unity高级开发-Shader开发(3)-Shader编程
Shader实例:高级纹理应用
第一种方法:就是提供一张具有特殊布局的纹理(如:立方体展开贴图交叉布局,全景布局等)用的时候把Texture Type设置成Cubemap(优点:这种方法可以对纹理数据进行压缩,而且可以支持边缘修正,光滑反射和HDR等功能);
bering
2019/12/03
5490
《Unity Shader入门精要》笔记:中级篇(1)
本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载。 本篇博客会补充一些扩展内容(例如其他博客链接)。 本篇博客还会提供一些边读边做的效果截图。文章内所有数学公式都由Latex在线编辑器生成。 本篇博客主要提供一个“glance”,知识点的总结。如有需要请到书店购买正版。 博客提及所有官方文档基于2022.2版本,博客会更新一些书中的旧的知识点到2022.2版本。 如有不对之处欢迎指正。 我创建了一个游戏制作交流群:637959304 进群密码:(CSGO的拆包密
[Sugar]
2022/09/21
7750
《Unity Shader入门精要》笔记:基础篇(1)
小插曲:看到具体数学冷汗直冒,细一看,嗷不是那本书呀。《具体数学》:别听《Unity Shader入门精要》里面说什么程序员的三大浪漫,真程序员就该手撕《具体数学》!
[Sugar]
2022/09/21
1.1K0
Unity Shader-描边效果[通俗易懂]
描边效果是游戏里面非常常用的一种效果,一般是为了凸显游戏中的某个对象,会给对象增加一个描边效果。最近又跑回去玩了玩《剑灵》,虽然出了三年了,感觉在现在的网游里面画面仍然算很好的了,剑灵里面走近或者选中NPC的一瞬间,NPC就会出现描边效果,不过这个描边效果是渐变的,会很快减弱最后消失(抓了好久才抓住一张图….)
全栈程序员站长
2022/07/26
2.2K0
Unity Shader-描边效果[通俗易懂]
Shader-基础光照-高光反射光照模型
高光反射计算公式: 我们需要4个参数,光源的颜色和强度,材质的高光反射系数,视角方向和反射方向. 在高光反射中我们要取得反射光线和视线的夹角. Cg提供了反射光线的函数reflect(i,n)
祝你万事顺利
2019/05/28
1K0
Unity通用渲染管线(URP)系列(二)——Draw Calls(Shaders and Batches)
要绘制物体,CPU需要告诉GPU应该绘制什么和如何绘制。通常我们用Mesh来决定绘制什么。而如何绘制是由着色器控制的,着色器实际上就是一组GPU的指令。除了Mesh之外,着色器还需要很多其他的信息来协同完成它的工作,比如对象的transform矩阵和材质属性等。
放牛的星星
2020/12/11
6.6K0
Unity通用渲染管线(URP)系列(二)——Draw Calls(Shaders and Batches)
Unity Shader 基础溶解效果
Dissolve Threshold阈值,用于控制溶解的进度,声明在Properties中,即可在Inspector面板进行控制:
CoderZ
2022/08/29
9210
Unity Shader 基础溶解效果
【unity shaders】:Unity中的Shader及其基本框架
Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组合作用,然后输出。绘图单元可以依据这个输出来将图像绘制到屏幕上。输入的贴图或者颜色等,加上对应的Shader,以及对Shader的特定的参数设置,将这些内容(Shader及输入参数)打包存储在一起,得到的就是一个Material(材质)。之后,我们便可以将材质赋予合适的renderer(渲染器)来进行渲染(输出)了。 所以说Shader并没有什么特别神奇的,它只是一段规定好输入(颜色,贴图等)和输出(渲染器能够读懂的点和颜色的对应关系)的程序。而Shader开发者要做的就是根据输入,进行计算变换,产生输出而已。
Tencent JCoder
2022/05/06
2K0
【unity shaders】:Unity中的Shader及其基本框架
Unity Shader
对于透明物体的处理,是游戏引擎的一个重要能力,通常通过模型的 透明通道 alpha 来控制物体的透明情况,alpha取值范围为
ruochen
2021/11/26
3.4K0
Unity高级开发-Shader开发(1)-渲染管线
学习Shader(着色器)必须先要了解渲染管线。如果不了解,那么就不能说你了解Shader
孙寅
2020/06/02
1.2K0
unity3d:Shader知识点,矩阵,函数,坐标转换,Tags,半透明,阴影,深度,亮度,优化
这些代码不需要包含在任何Pass语义块中,在使用时,我们只需要在Pass中直接指定需要使用的顶点着色器和片元着色器函数名即可。CGINCLUDE类似于C++中头文件的功能。由于高斯模糊需要定义两个Pass,但它们使用的片元着色器代码是完全相同的,使用CGINCLUDE可以避免我们编写两个完全一样的frag函数。
立羽
2024/07/08
6710
unity3d:Shader知识点,矩阵,函数,坐标转换,Tags,半透明,阴影,深度,亮度,优化
Unity3D学习笔记8——GPU实例化(3)
在前两篇文章《Unity3D学习笔记6——GPU实例化(1)》《Unity3D学习笔记6——GPU实例化(2)》分别介绍了通过简单的顶点着色器+片元着色器,以及通过表面着色器实现GPU实例化的过程。而在Unity的官方文档Creating shaders that support GPU instancing里,也提供了一个GPU实例化的案例,这里就详细论述一下。
charlee44
2022/07/12
1.4K0
Unity3D学习笔记8——GPU实例化(3)
Unity Shader 一 激光特效Shader[通俗易懂]
学习Shader已经有几个月的时间了,Shader作为一门GPU编程语言来说确实比较的难学。主要原因经过我的思考还是本人自己的计算机图形学和美术基础不扎实。好无奈,作为一个之前单纯手写代码的程序员真的是感觉好蛋疼。
全栈程序员站长
2022/07/27
1.6K0
Unity Shader 一 激光特效Shader[通俗易懂]
Shader-基础光照-漫反射光照模型
当光线从光源照射到模型表面,该表面回向每个方向散射多少辐射量 漫反射符合兰伯特定律:反射光线的强度与表面法线与光源方向之间的夹角的余弦值成正比. 漫反射的计算:
祝你万事顺利
2019/05/28
1K0
相关推荐
《Unity Shader入门精要》笔记:初级篇(1)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验