Unity Shader 学习之旅之SurfaceShader

unity shader 图形图像 

如果大地的每个角落都充满了光明 谁还需要星星,谁还会 在夜里凝望 寻找遥远的安慰——江河

官方文档

一、工作原理

sureface表面着色器相当于unity在顶点片元着色器的基础上进一步的封装。当我们定义一个“surface function”后,可以通过unity已经封装好的的结构体“SurfaceOutput”等直接获取需要的数据,如纹理,法线,光滑度等

二、结构体

2.1标准output结构体

  1. struct SurfaceOutput 



  2. fixed3 Albedo; // 漫反射颜色 

  3. fixed3 Normal; // 切线空间法线 

  4. fixed3 Emission; 

  5. half Specular; // 高光系数 

  6. fixed Gloss; // 高光强度 

  7. fixed Alpha; // alpha 通道 

  8. }; 

2.2Unity5 output结构体

unity5中表面着色器使用基于物理的光照模型。内建Standard和StantardSpecular光照模型使用如下两种结构体:

  1. struct SurfaceOutputStandard 



  2. fixed3 Albedo; // base (diffuse or specular) color 

  3. fixed3 Normal; // tangent space normal, if written 

  4. half3 Emission; 

  5. half Metallic; // 0=non-metal, 1=metal 

  6. half Smoothness; // 0=rough, 1=smooth 

  7. half Occlusion; // occlusion (default 1) 

  8. fixed Alpha; // alpha for transparencies 

  9. }; 

  10. struct SurfaceOutputStandardSpecular 



  11. fixed3 Albedo; // diffuse color 

  12. fixed3 Specular; // specular color 

  13. fixed3 Normal; // tangent space normal, if written 

  14. half3 Emission; 

  15. half Smoothness; // 0=rough, 1=smooth 

  16. half Occlusion; // occlusion (default 1) 

  17. fixed Alpha; // alpha for transparencies 

  18. }; 

三、SurfaceShader编译指令

SurfaceShader被放置在 CGPROGRAM---ENDCG语块之间,需要注意以下两点:

  • 必须放置在SubShader语块中,不能在Pass语块中,SurfaceShader会自主编译成多个Pass
  • 通过使用 #pragma surface ... 来表明这是一个SurfaceShader
  1. #pragma surface surfaceFunction lightModel [optionalparams] 

3.1必要参数

  • surfaceFuncton:这就是我们在编译指令中指定的表面着色器Cg函数。可以通过 void surf (Input IN, inout SurfaceOutput o) 这种形式定义。其中input是我们定义的结构体,包含该函数需要的数据信息。
  • lightMode:光照模型可以使用内建的基于物理的 Standard 和StandardSpecular。也可以使用非物理的Lambert BlinnPhong。这几种类型可以直接通过在编译指令中指定,无需在自己实现。
    • Standard 光照模型使用SurfaceOutputStandard output结构体
    • StandardSpecular 光照模型使用SurfaceOutputStandardSpecular output结构体
    • Lambert和BlinnPhong 光照模型使用 SurfaceOutput output结构体

3.2可选参数

通过指定可选参数[optionalparams],可以让surfaceshader表现出更丰富的效果,如雾效,半透明,阴影等。可选参数具体类型可参考文首给出的 官方文档 查阅。

3.3示例

示例1:使用内置Lambert光照模型的表面着色器

  1. Shader "Example/Rim" { 

  2. Properties { 

  3. _MainTex ("Texture", 2D) = "white" {} 

  4. _BumpMap ("Bumpmap", 2D) = "bump" {} 

  5. _RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0) 

  6. _RimPower ("Rim Power", Range(0.5,8.0)) = 3.0 



  7. SubShader { 

  8. Tags { "RenderType" = "Opaque" } 

  9. CGPROGRAM 

  10. #pragma surface surf Lambert 

  11. struct Input { 

  12. float2 uv_MainTex; 

  13. float2 uv_BumpMap; 

  14. float3 viewDir; 

  15. }; 

  16. sampler2D _MainTex; 

  17. sampler2D _BumpMap; 

  18. float4 _RimColor; 

  19. float _RimPower; 

  20. void surf (Input IN, inout SurfaceOutput o) { 

  21. o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; 

  22. o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap)); 

  23. half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal)); 

  24. o.Emission = _RimColor.rgb * pow (rim, _RimPower); 



  25. ENDCG 

  26. }  

  27. Fallback "Diffuse" 



示例2:使用可选参数的表面着色器,通过指定decal:blend,该shader会表现出半透明贴画的效果。

  1. Shader "Example/Decal" { 

  2. Properties { 

  3. _MainTex ("Base (RGB)", 2D) = "white" {} 



  4. SubShader { 

  5. Tags { "RenderType"="Opaque" "Queue"="Geometry+1" "ForceNoShadowCasting"="True" } 

  6. LOD 200 

  7. Offset -1, -1 


  8. CGPROGRAM 

  9. #pragma surface surf Lambert decal:blend 


  10. sampler2D _MainTex; 


  11. struct Input { 

  12. float2 uv_MainTex; 

  13. }; 


  14. void surf (Input IN, inout SurfaceOutput o) { 

  15. half4 c = tex2D (_MainTex, IN.uv_MainTex); 

  16. o.Albedo = c.rgb; 

  17. o.Alpha = c.a; 



  18. ENDCG 





Unity Shader 学习之旅之SurfaceShader的更多相关文章

  1. Unity Shader 学习之旅

    Unity Shader 学习之旅 unityshader图形图像 纸上学来终觉浅,绝知此事要躬行 美丽的梦和美丽的诗一样 都是可遇而不可求的——席慕蓉 一.渲染流水线 示例图 Tips:什么是 GP ...

  2. 第四章 开始Unity Shader学习之旅(2)

    目录 1. 强大的援手:Unity提供的内置文件和变量 1.1 内置的包含文件 1.2 内置的变量 2. Unity提供的Cg/HLSL语义 2.1 什么是语义 2.2 Unity支持的语义 2.3 ...

  3. 第四章 开始Unity Shader学习之旅(1)

    1. 一个最简单的顶点/片元着色器 现在,我们正式开始学习如何编写Unity Shader,更准确的说是,学习如何编写顶点/片元着色器 2.顶点/片元着色器的基本结构 我们在以前已经讲过了Unity ...

  4. Unity Shader入门精要学习笔记 - 第5章 开始 Unity Shader 学习之旅

    一个顶点/片元 着色器的结构大概如下: Shader "MyShaderName" { Properties { //属性 } SubShader { //针对显卡A的SubSha ...

  5. 第四章 开始Unity Shader学习之旅(3)

    1. 程序员的烦恼:Debug 调试(debug),大概是所有程序员的噩梦.而不幸的是,对一个Shader进行调试更是噩梦中的噩梦.这也是造成Shader难写的原因之一--如果发现得到的效果不对,我们 ...

  6. [转]Unity Shader 学习总结

    1.先来一段单张纹理贴图的shader示例代码: // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClip ...

  7. Unity Shader学习笔记-1

    本篇文章是对Unity Shader入门精要的学习笔记,插图大部分来自冯乐乐女神的github 如果有什么说的不正确的请批评指正 目录 渲染流水线 流程图 Shader作用 屏幕映射 三角形遍历 两大 ...

  8. 【Unity Shader学习笔记】Unity基础纹理-单张纹理

    1 单张纹理 1.1 纹理 使用纹理映射(Texture Mapping)技术,我们把一张图片逐纹素(Texel)地控制模型的颜色. 美术人员建模时,会在建模软件中利用纹理展开技术把纹理映射坐标(Te ...

  9. Unity shader学习之屏幕后期处理效果之高斯模糊

    高斯模糊,见 百度百科. 也使用卷积来实现,每个卷积元素的公式为: 其中б是标准方差,一般取值为1. x和y分别对应当前位置到卷积中心的整数距离. 由于需要对高斯核中的权重进行归一化,即使所有权重相加 ...

随机推荐

  1. debian 7上安装svn

    1.在终端中直接输入  sudo apt-get install subversion,选择安装即可 2.查看版本命令 svnserve --version(更多命令直接键入svnserve --he ...

  2. BZOJ1001: [BeiJing2006]狼抓兔子【最短路+对偶图】

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1001 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Se ...

  3. Java并发编程--2.synchronized

    前言 synchronized关键字是互斥锁,也称为内部锁 每个对象都有自己的monitor(锁标记),它是为了分配给线程,最多一个线程可以拥有对象的锁 使用 synchronized修饰成员方法,锁 ...

  4. Day17 多线程编程

    基本概念 进程:内存中正则运行的一个应用程序.一个进程包含多个线程. 线程:进程中的一个执行流程. 多线程:有两个或两个以上的并发执行流程. 线程的声明周期 说明: 1. 新建状态(New)      ...

  5. [luogu1600] 天天爱跑步

    题面 ​ 直接写正解吧, 不想再写部分分了, 对于\(u\)和\(v\), 我们可以将它拆成两条路径, \(u\)到\(lca(u, v)\)和\(lca(u, v)\)到v, 在这里只分析从\(u\ ...

  6. 20155314 2016-2017-2 《Java程序设计》第10周学习总结

    20155314 2016-2017-2 <Java程序设计>第10周学习总结 教材学习内容总结 了解计算机网络基础 掌握Java Socket编程 理解混合密码系统 掌握Java 密码技 ...

  7. Java泛型学习一

    Java泛型 所谓泛型,就是变量类型的参数化.泛型是java1.5中引入的一个重要特征,通过引入泛型,可以使编译时类型安全,运行时更少抛出ClassCastException的可能.一提到参数化,最熟 ...

  8. Spring事务(三)事务增强器

    摘要: 本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 目录 一.创建事务 1. 获取事务 2. 处理已经存在的事务 3. 准 ...

  9. 网络流$1$·简单的$EK$与$Dinic~of~Net-work ~ Flow$学习笔记

    \(2333\)这是好久之前学的了,不过一直在咕咕咕咕. 一般来讲,正常的网络流笔记一开始都是要给网络流图下定义的.那么我们不妨也来先进行一波这种操作. 那么网络流图,类似于有向图,边上带权,但是这个 ...

  10. HDU 2141 Can you find it? (二分)

    题目链接: Can you find it? Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/10000 K (Java/ ...