Unity Surface Shader 示例分析

【Unity Shaders】初探Surface Shader背后的机制 转载请注明出处!写在前面一直以来,Unity Surface Shader背后的机制一直是初学者为之困惑的地方。Unity Surface Shader在Unity 3.0的时候被开放给公众使用,其宣传手段也是号称让所有人都可以轻松地写shader。但由于资料缺乏,很多人知其然不知其所以然,无法理解Unity Surface Shader在背后为我们做了哪些事情。前几天一直被问到一个问题,为什么我 阅读详情
Unity Surface Shader 示例分析

     对于Unity中的表面着色器(Surface Shader),它的代码整体结构如下所示:

     Shader "name" {
         Properties {
              // 第一部分
         }

         SubShader {
              // 第二部分
         }

         Fallback "Diffuse" // 第三部分
     }

     第一部分 Properties 数据块
       
     它的作用是充当数据的接口,将外部的数据(资源)引入进来,以供着色器内部使用。在这里,我们可以定义的数据类型如下所示:

     (1) _MainTex ( "Base (RGB)", 2D ) = "white" {}
          2D类型,主要指我们所使用的纹理贴图。
          _MainTex是自定义的变量名称,我们在编写shader的代码时将使用它,它会显示在shader的属性面板上,下同;
          "Base (RGB)"也是一个名称,它会在绑定该shader的材质属性面板上显示。

     (2) _CubeTex ( "3D Map", Cube ) = "white" {}
          Cube类型,表示三维纹理。三维纹理具有宽度、高度以及深度三个维度的信息。

     (3) _Color ( "Main Color", Color ) = (1,1,1,1)
          Color类型,表示一种颜色,包含( R, G, B, A )4个颜色值成分。
          _Color是自定义的变量名称,在编写shader的代码时使用。

     (4) _Float ( "Float Value", float ) = 0.0
          float类型,表示一个浮点数值。
          _Float是自定义的变量名称,在编写shader的代码时使用。

     (5) _RimPower ( "Rim Power", Range( 0.5, 1.0 ) ) = 1.0
          float类型,数值取自[min, max]这段范围。
          _RimPower是自定义的变量名称,在编写shader的代码时使用。

     (6) _Vector( "Vector4", Vector ) = ( 1, 1, 1, 1 )
          Vector类型,表示4个元素的向量,包含( X, Y, Z, W )4个值。
          _Vector是自定义的变量名称,在编写shader的代码时使用。

     第二部分 SubShader 子着色器代码块

     这一部分是着色器的代码主体,是我们编写代码的主阵地,在下面的示例分析中会着重写到。

     第三部分 Fallback "Diffuse" 回滚块

     回滚作为一种替代方案,当我们的图形卡没有找到合适的SubShader时将被调用,具备较为简单的着色效果。

     接下来,我们从示例入手,来分析一下着色器的代码。我们的示例程序是Unity Surface Examples 中的Normal mapping,实现了法线贴图的基础着色器(链接地址http://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html),完整代码如下所示:
     
     
      Shader "Example/Diffuse Bump" { 

          Properties { 
               _MainTex ("Texture", 2D) = "white" {} 
               _BumpMap ("Bumpmap", 2D) = "bump" {} 
          } 

          SubShader {
               Tags { "RenderType" = "Opaque" } 
               LOD 200

               CGPROGRAM#pragma surface surf Lambert 
               sampler2D _MainTex; 
               sampler2D _BumpMap;
               struct Input {
                    float2 uv_MainTex; 
                    float2 uv_BumpMap; 
               }; 
               void surf (Input IN, inout SurfaceOutput o) { 
                    o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; 
                    o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap)); 
               } 
               ENDCG 
          }

          Fallback "Diffuse"
      }

     首先,我们在Properties块中定义了两个2D类型的变量:_MainTex和_BumpMap。_MainTex作为纹理贴图数据,_BumpMap作为法线贴图数据。
     进入到我们的SubShader内部,首先看到的是一个Tags(标签)。Tags用来对表面着色器进行修饰,我们的硬件通过判断这些Tags,来决定何时应该调用该子着色器。常用的一些Tags如下所示:

     "RenderType" = "Opaque"      // 在绘制不透明图形时调用
     "RenderType" = "Transparent" // 在绘制透明图形时调用
     "IgnoreProjector" = "True"   // 不受投影的影响
     "Queue" = "XXX"              // 指定渲染队列

     LOD 200
     LOD是Level of Detail 的缩写,这个数值的大小决定了我们的SubShader是否可以被调用。当系统设定的最大LOD小于该SubShader所指定的LOD时,该SubShader将不可用。

     接下来的部分,CGPROGRAM - ENDCG 表示这是一段CG程序。#pragma surface surf Lambert 是一个编译指令,surface表明这是一个表面着色器,surf是着色器调用的方法名字,Lambert则是使用的光照模型,这也是一个Unity自带的光照模型。需要特别注意的是,想要在CG程序中访问在Properties中所定义的变量的话,必须在CG程序中对这些变量使用相同的名字再次进行声明。只不过这时,变量的类型要使用CG程序中相对应的类型。Input是一个需要我们自定义的结构体,它的对象作为输入(IN)参数,以供我们在surf方法中使用。在上述示例中,我们定义了uv_MainTex和uv_BumpMap,它们分别表示了纹理贴图和法线贴图的uv坐标。最后的surf函数部分,是着色器的方法主体。在这里我们完成了着色和法线的处理。最终效果如下所示:

     
【Unity Shaders】Diffuse Shading——创建一个基本的Surface Shader 这一次的工作非常简单,我们主要是为了了解Unity Shaders的基本工作原理。 准备工作 创建一个新的Unity Project在Assets目录下新建一个文件夹:Shaders在Assets目录下新建一个文件夹:Materials 实现 在Shaders文件夹下,点击右键新建一个Shader,命名为BasicDiffuse,并打开它 阅读详情

相关推荐

【猫猫的Unity Shader之旅】之一个完整的Shader示例

Unity Shader结构介绍  上回我们创建了一个用自己的材质和Shader的立方体,并且举例说了模型、材质、Shader三者的关系,想必大家已经很了解了。还不了解的同学请请戳这里。对于我们创建的Shader,虽然我们自己没有写代码,但是Unity为我们生成了一个简单的Shader:Shader "Custom/CubeShader" { Properties { _Ma

dbtxdxy的专栏 4105

Unity---表面着色器

【千锋合集】史上最全Unity3D全套教程|匠心之作_哔哩哔哩_bilibili Shader "MyShader/Surface/Surface001" { Properties { float number=10; float2 pos=float2(0.3,0.5);//相当于unity中vector2 float3 vector3=float3(1,1,1);//相当于unity中vector3 float4 vect...

renwen1579的博客 1239

【Unity Shaders】Diffuse Shading——向Surface Shader添加properties

这次是在上一篇的基础上,进一步学习Unity Shaders的Properties。 准备工作 我们假设你已经进行了上一篇里的工作:创建了一个BasicDiffuse.shader,并且看到了Unity自动为你创建的代码: Shader "Custom/BasicDiffuse" { Properties { _MainTex ("Base (RGB)", 2D) =

candycat 1万+

Shader学习Day03 表面着色器、CG语言

1. 7.凹凸纹理 法线渲染:只是告诉这个像素的法线 主纹理和法线贴图

Gyp郭小帅的博客 273

【Unity Shaders】Diffuse Shading——在Surface Shader中使用properties

在上一篇中,我们已经向Surface Shader中添加了一些properties。在这篇教程里,我们将学习如何在Shader中访问和使用它们,以便通过调整Inspector中的变量来改变渲染效果。 准备工作 在上一篇结束后,我们的shader代码如下:Shader "Custom/BasicDiffuse" { Properties { _EmissiveCol

candycat 1万+

【Unity Shader实战】卡通风格的Shader(一)

呜,其实很早就看到了这类Shader,

candycat 7万+

Shader编程学习笔记(八)—— Surface Shader 2

目录1、引言2、surface函数3、SurfaceOutput”和“SurfaceOutputStandard”两种结构体的对比 1、引言   上一篇我们主要了解了Surface Shader使用了“#pragma surface surf Standard fullforwardshadows”指令的意义,这里我们主要了解“surf”surface函数。 void surf (Input I...

对酒当歌﹏✍ 513

Unity笔记 Surface Shader

学习《unity shaders and effects book》的tips。

fjl2007的博客 2922

UnityShader官方案例讲解——SurfaceShader(4)

“Without purpose, the days would have ended, as such days always end, in disintegration.”– , Explorerstep1 经世界坐标空间位置的切片Shader"Example / AutisticPatient SurfaceShader8" { Properties { _

AutisticPatient的博客 1486

Unity_Shader基础篇_Unity Shader入门精要

1基础篇 2-4基础篇 为初学者普及基本的理论知识以及必要的数学基础 5-8初级篇 从最简单的shader开始,讲解Shader中基础的光照模型、纹理和透明效果等初级渲染效果。 9-16中极篇 讲解Unity中的渲染路径、如何计算光照衰减和阴影、如何使用高级纹理和动画等一系列内容。 17-22扩展篇 进一步扩展读者的视野。 2渲染流水线 渲染流水线的最终目的在于生成或者说是渲染一张...

wy小骑士 6197

【Unity Shader实战】卡通风格的Shader(二)

写在前面好久没写博客了,一定是因为课程作业比较多,一定不是因为我懒,恩恩。三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Shader中实现描边效果的弊端,也就是只对表面平缓的模型有效。这是因为我们是依赖法线和视角的点乘结果来进行描边判断的,因此,对于那些平整的表面,它们的法线通常是一个常量或者会发生突变(例如立方体的每个面),这样就会导致最后的效果并非如我们所愿。如下

candycat 3万+

入门图形学:光照模型(五)

        紧接上一篇:https://blog.youkuaiyun.com/yinhun2012/article/details/81061129         之前我们详细的学习了怎么使用unity buildin的标准光照模型,给我们的shader指定这个标准光照模型,然后观察呈现出什么样的效果。         具体做法就是添加一个预编译指令:         #pragma surfa...

羊羊的博客 1967

【Unity5.x Shaders】最基本的Surface Shader-Diffuse shader以及Surface中的三种输出结构

某些物体可能具有均匀的颜色和光滑的表面,但光滑程度不足以照射反射光。 这些哑光材料最好用Diffuse Shader。 在现实世界中,不存在纯diffuse materials Diffuse shader经常出现在游戏中,下面就是一个简单的Diffuse shader代码Shader "Custom/DiffuseShader" { Properties {

森系少女的游戏梦 3052

Unity Shader (三)Surface Shader机制

一直以来,Unity Surface Shader背后的机制一直是初学者为之困惑的地方。Unity Surface Shader在Unity 3.0的时候被开放给公众使用,其宣传手段也是号称让所有人都可以轻松地写shader。但由于资料缺乏,很多人知其然不知其所以然,无法理解Unity Surface Shader在背后为我们做了哪些事情。   前几天一直被问到一个问题,为什么我的场景里没有灯...

居安思危,游戏人生。 1675

【rk3566/3568】Android 11移植gms

【rk3566/3568】Android 11移植gms 1、前言 测试功能时,想去Google play store去下个应用测试,发现通过网页搜索总是下载不到正确的谷歌服务框架;于是就不得不去搞一个内置的gms。 2、移植 1、需要下载Android 11对应的gms的包 opengapps 2、看下文件目录 直接移植core里面的文件,GAPPs Optional按需添加 3、在vendor下创建google目录 ...

lin_ff的博客 7647

TekTronix 高速信号完整性基础以及测试方法分析

如果信号速率比较高,则CTLE与FFE都无法满足要求,尤其是大于10G,比如USB3.1Gen2 10Gbps,PCIe4.0 16Gbps,这些场合都会采用DFE均衡,DFE的优点是,它既可以识别当前比特,并且可以判决前面的n个比特(Tap的阶数越高,看到的前面的比特数越多),根据前面比特的变化来计算出要处理当前比特所要变化的幅度,来补偿由于前面比特变化所引起的信号幅度的变化。10G以下,一般都不太关心这个串扰,高于10G的信号,会发现相互之间的串扰越来越明显,已经成为引起误码的重要的原因之一。

weixin_45365488的博客 4143

Unity Shader 表面着色器(Surface Shader)

Unity Shader分为表面着色器(Surface Shader),顶点着色器(Vertex Shader),片段着色器(Fragment Shader) 我们先来看个简单的Surface Shader,看看它都能做什么。 首先我们通过"Create->3D Object ->Plane"创建一个面板 然后通过"Create->Shader->Standard Surface S

jk823394954的专栏 1万+

当Kmer遇到多倍体:复杂基因组Survey分析中的避坑指南

本文针对小麦、棉花等多倍体及高杂合复杂基因组的Survey分析,深入解析了Kmer分布图解读中的常见陷阱。文章重点探讨了如何超越理想二倍体模型,利用Smudgeplot等工具准确判断基因组倍性,并提供了从参数优化、污染判断到结果验证的全流程实战指南,帮助研究者规避错误,获得更准确的基因组大小、杂合度等关键信息。

yhn45678901的博客 1010

unity Shader 入门精要 EX

1、shader概念 Shader,中文名为着色器。 Shader其实就是专门用来渲染图形的一种技术,通过shader,我们可以自定义显卡渲染画面的算法,使画面达到我们想要的效果。 2、shader分类 Shader分为两类 : 顶点Shader(3D图形都是由一个个三角面片组成的,顶点Shader就是计算每个三角面片上的顶点,并为最终像素渲染做准备)。 像素Shader,顾名思义,就是以像素为单位,计算光照、颜色的一系列算法。 几个不同的图形API都有各自的Shader语言 在DirectX中,顶点sha

xinghaikongmeng的博客 5136

RAP 语义键:让 UUID 世界变得可读、可导航、可校验

RAP 语义键的核心价值与实现要点 语义键(Semantic Key)是 ABAP RAP 模型中连接技术实现与业务体验的关键设计:通过为实体指定一组业务可读的标识字段(如订单号、物料编码等),在保持技术主键(如UUID)不变的同时,显著提升用户界面的可读性和导航体验。 主要优势: 提升UI可读性:Fiori元素会突出显示语义键字段,帮助用户快速识别关键业务数据 改善导航体验:OData URL会使用可读的语义键而非技术ID,便于分享和排查问题 降低沟通成本:业务人员能准确引用有意义的业务标识而非技术ID

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 156

ESP32S3 TLS 握手WIFI可用但是在蜂窝热点下卡死:排查方法与根因

设备卡在等。

摸鱼专家 87

(三)unity Shader之——————surface shader转变为自己写的vertex&fragment Shader不受unity的动态实时点光源的影响解决方案

在写环境、植物的Shader时,原来使用的是Surface shader,出于性能的考虑要转变成效果一致的vertex&fragment Shader,转变中遇到了一个问题。 首先我加了一个unity的标准点光源,如果都换成unity的standard shader,或者其他的surface shader(包括现在使用的环境和植物的surface shader),你会发现环境都是受点光源...

cgy56191948的博客 1450

USB_TYPE-C 母座电路设计

本文详细介绍了USB Type-C接口(C2765186)的电路设计要点,重点解析了电源、识别和数据三部分的关键连接方案。电源部分需并联VBUS和GND引脚并加宽走线以承载3A电流;识别部分必须为CC1/CC2引脚配置5.1kΩ±1%精度的下拉电阻,这是触发PD充电的核心条件;数据部分通过短接正反插引脚实现盲插功能。文档还提供了完整的引脚对照表,并强调PCB布局需注意ESD防护、差分走线阻抗控制等要点,为Type-C接口设计提供了实用指导。

在读研究生,FPGA电路设计与功能开发。 588
上一篇: OpenGL中的多重采样
下一篇: 图形系统总结
杜晓萌
博客等级 码龄16年 221粉丝 70原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值