先来看一段我们项目常见的Shader代码,这个是Vertex&Fragment shader,目前已经不常用了,不过还是适合我们理解一些基础知识和理解一些比较老的shader 代码。下次我们再讲unity主推的surface shader

 Shader "Custom/test"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
} SubShader
{
Pass
{
Tags { "RenderType"="Opaque" } CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex; struct VertexOutput
{
float4 pos:SV_POSITION;
float2 uv_MainTex:TEXCOORD0;
}; VertexOutput vert(appdata_base input)
{
VertexOutput o;
o.pos = mul(UNITY_MATRIX_MVP,input.vertex);
o.uv_MainTex = input.texcoord.xy;
return o;
} float4 frag(VertexOutput i):COLOR
{
float4 col = tex2D(_MainTex,i.uv_MainTex);
return col;
} ENDCG
}
}
FallBack "Diffuse"
}

第1行代码的 Shader "Custom/test" 声明了目录结构,test是这个shader的名字。之后就可以在材质上中找到对应的shader

第3-6行声明了shader的可以调节参数的地方。设置了之后,就可以在Inspector面板中找到对应的变量。具体内容查看这里.

第8行的SubShader比较重要。一个Shader中可以包含任意多个SubShader,但是只有一个SubShader被显卡选中并最终执行。显卡会自动选择一个最适合它自身性能的SubShader去执行。如果我们写的SubShader最后都没有被选中,那么就执行第25行的fallback 指定的shader。

第10行的Pass也很重要,在一个SubShader中我们可以定义多个Pass,而Pass与SubShader不同,你写的每一个Pass都会按照顺序全部执行一遍.我们要在Pass中写具体的着色器代码,还有一点要提一下,在Unity主推的Surface Shader中是不能写Pass的,因为在Unity的光照模型中他会自动定义一些Pass,所以也就不再允许你额外写了。

第12行的 Tags { "RenderType"="Opaque" } 他是一种ShaderLab(UnityShader中除了CG以外的语法),给我们提供好的可配置的一些选项,这些选项你可以每个Pass都写一个,也可以直接写在SubShader下面让所有Pass公共用一个配置。这里面的RenderType = "Opaque"是告诉渲染设备,这个使用这个Shader的材质是一个不透明的物体,对应的还有Transparent透明物体等,这个标签的功能需要跟ztest配合使用。比较重要的还有Queue标签,它会改变物体被渲染的顺序。具体看这里,常用标签的顺序为 Background is 1000, Geometry is 2000, AlphaTest is 2450,Transparent is 3000 and Overlay is 4000.

第14~40行被CGPROGRAM 和 ENDCG包含的部分才是真正的CG代码

第15~16行的两句话是告诉渲染设备顶点着色器(vertex)和片段着色器(fragment)的名字是什么,这是为了让显卡在渲染的时候能够准确找到他们而必须声明的.而我们后面具体些着色器的时候也要用这个名字

第17行#include "UnityCG.cginc"是因为Unity为我们提供大量的可用变量和常量,比如说一些空间变换矩阵,这样子可以提高我们的开发效率,为了使用他们你需要把这句话加上。在Unity4.0之后你可以省略这句话了,他会被默认包含进来,不过为了向下兼容还是建议加上。

第18行的uniform sampler2D _MainTex;我们声明了一个叫_MainTex变量,他的类型是sampler2D(也就是指可采样的2D贴图),前面的uniform意思是说这个变量是由外部赋值进来的,你会发现这里的_MainTex和我们的Properties中的_MainTex名字一致,前面说过了,通过这种方式我们就可以在着色器中使用在Properties中声明的变量了。

第20行~24行是声明一个顶点着色器的输出结构,它同时也是片段着色器的输入结构.每个变量声明最后都跟了一个像:SV_POSITION这样的语法,这在CG中称为语义(semantic),简单的理解就是显卡设定了一些特定的寄存器,用来存放一些指定的特殊变量,在渲染时候如果需要用到的话就直接来取,这样子可能处理起来更快。其中SV_POSITION是专门用来存放模型顶点在投影空间的坐标的。TEXCOORD0可以用来存放任何你想存放的变量,在光栅化的时候这个变量会被插值 。类似于TEXCOORD0还有TEXCOORD1,TEXCOORD2等,具体个数看显卡的性能.我们在这个结构里添加了两个变量一个是顶点投影坐标,这个是必须有的,另外一个是顶点的纹理坐标,用来贴图用的。

第26~32行 是顶点着色器的代码部分,着色器(理解成函数就行了)的返回类型为我们刚才声明的返回结构,着色器名字就用我们在CG代码一开始通过#pragma 关联的名字。

而参数这里要注意一下了,顶点着色器接受的参数都是模型最原始的参数,也就是美术同学指定的模型本身的一些参数,包括顶点的位置,法线,纹理坐标,颜色等等.unity通过MeshRenderer等render组件把顶点信息传递给了Shader,但是在Shader中是通过语义(semantic)来关联这些参数.

这个appdata_base是一个Unity为我们定义好的结构,就在我们上面写过的#include"UnityCG.cginc"包含进来.你可以在Unity安装目录的/Editor/Data/CGIncludes文件夹里面找打他看一看源代码。

所以在顶点着色其中我们可以通过appdata_base.XXX这种方式来直接获取模型的顶点信息了。具体官方解释查看这里。Unity_Matrix_MVP是unity提供好的模型空间转投影空间的矩阵,mul(UNITY_MATRIX_MVP,input.vertex)就能取到投影空间的坐标。

o.uv_MainTex = input.texcoord.xy;就是将uv信息传递进去。texcoord.xy就是uv信息。

第34~38行是片段着色器的代码,由于片段着色器的任务就是最后计算出一个颜色提供给渲染设备进行最后的处理,所以它的返回值为float4(存的是rgba).

函数的名字与前面#pragma约定好的一致.参数的话就是刚刚顶点着色器输出结构.

而最后面还跟了个:COLOR,这是为了把返回结果提供给:COLOR语义关联的寄存器,到时候渲染设备最后进行处理的时候去这里取片段着色器计算出来的结果就可以了.

tex2D函数,这是一个根据纹理坐标查询2D贴图颜色的函数,第一个参数是贴图,就是我们在上面声明的_MainTex,而后面是我们要查询的坐标,纹理坐标填上去就可以了,最终将为我们返回一个贴图上的颜色。

Unity的shader学习1的更多相关文章

  1. Unity的shader学习2

    下面继续看基于surface的shader代码,基本与Vertex&Fragment shader差不多,只是不能写pass,然后只需要声明surface函数,就能处理所有的事情. Shade ...

  2. 【Unity Shaders】Shader学习资源和Surface Shader概述

    写在前面 写这篇文章的时候,我断断续续学习Unity Shader半年了,其实还是个门外汉.我也能体会很多童鞋那种想要学好Shader却无从下手的感觉.在这个期间,我找到一些学习Shader的教程以及 ...

  3. Unity Shader 学习之旅

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

  4. Unity Shader 学习之旅之SurfaceShader

    Unity Shader 学习之旅之SurfaceShader unity shader 图形图像  如果大地的每个角落都充满了光明 谁还需要星星,谁还会 在夜里凝望 寻找遥远的安慰——江河 官方文档 ...

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

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

  6. [转]Unity Shader 学习总结

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

  7. 【Unity Shaders】学习笔记——SurfaceShader(十一)光照模型

    [Unity Shaders]学习笔记——SurfaceShader(十一)光照模型 转载请注明出处:http://www.cnblogs.com/-867259206/p/5664792.html ...

  8. 【Unity Shaders】学习笔记——SurfaceShader(十)镜面反射

    [Unity Shaders]学习笔记——SurfaceShader(十)镜面反射 如果你想从零开始学习Unity Shader,那么你可以看看本系列的文章入门,你只需要稍微有点编程的概念就可以. 水 ...

  9. 【Unity Shaders】学习笔记——SurfaceShader(九)Cubemap

    [Unity Shaders]学习笔记——SurfaceShader(九)Cubemap 如果你想从零开始学习Unity Shader,那么你可以看看本系列的文章入门,你只需要稍微有点编程的概念就可以 ...

随机推荐

  1. Yii2使用驼峰命名的形式访问控制器

    yii2在使用的时候,访问控制器的时候,如果控制器的名称是驼峰命名法,那访问的url中要改成横线的形式.例如: public function actionRoomUpdate() { // }//访 ...

  2. day4装饰器

    Python装饰器 1.必备 def foo(): print(foo) <function foo at 0x7f62db093f28> >>> foo <fun ...

  3. Templated Helper Methods

    1.Model 2.HomeController 3.CreatePerson.cshtml 禁用了客户端验证 4.Using Templated Helper Methods Editor 和 Ed ...

  4. Asp.net MVC CSS/Javascript Bundle 配置文件

    Asp.net mvc 中使用 Web Optimization 可以合并.压缩JS和CSS文件,但是每次修改都要改代码 ~/App_Start/BundleConfig.cs ,遂有了将它挪到配置文 ...

  5. [实战]MVC5+EF6+MySql企业网盘实战(18)——文件上传,下载,修改

    写在前面 经过一段时间的秀秀改改,终于把文件上传下载,修改文件夹文件名称的功能实现了. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企 ...

  6. Loadrunner报错“Too many local variablesAction.c”解决方法

    问题描述,在Action.c里定义数组时如果数组长度过长,如char a[1024*1024]运行时即会报错: 意思为:太多的局部变量 问题原因及解决方法如下: 1. VuGen对于局部变量可以分配的 ...

  7. 在 github 中新建仓库后,如何上传文件到这个仓库里面。

    在 github 中新建仓库后,如何上传文件到这个仓库里面. libin@hglibin MINGW64 /e/github.io (master) $ git remote libin@hglibi ...

  8. Django Rest Framework(版本、解析器、序列化、数据验证)

    一.版本 程序也来越大时,可能通过版本不同做不同的处理 没用rest_framework之前,我们可以通过以下这样的方式去获取. class UserView(APIView): def get(se ...

  9. Unity 2D游戏开发教程之游戏精灵的开火状态

    Unity 2D游戏开发教程之游戏精灵的开火状态 精灵的开火状态 “开火”就是发射子弹的意思,在战争类型的电影或者电视剧中,主角们就爱这么说!本节打算为精灵添加发射子弹的能力.因为本游戏在后面会引入敌 ...

  10. Codeforces 650 D. Zip-line

    $ >Codeforces \space 650 D. Zip-line<$ 题目大意 : 有一个长度为 \(n\) 的序列 \(h\) ,\(m\) 次询问,每一次询问求如果把序列中第 ...