UnityShader官方案例讲解——SurfaceShader(1)
来源:互联网 发布:淘宝买家信誉等级查询 编辑:程序博客网 时间:2024/06/18 00:09
Living without an aim is like sailing without a compass.(John Ruskin)
接下来要做的就是对官方的着色器案例进行讲解,本着学习的态度,我会尽量解释每一行代码,因为还没有毕业,剩下的时间比较多,我会写的比较详细(慢&懒)
因为我也是新手,所以我很理解新手的痛处吗,在一开始我不会一下子列出好多好多的语法,或者是好多 好多的关键字,咱们一起从例子中不断的学习,虽然很慢,但是shader这条路是没有捷径的
若有不足之处 还望路过的前辈们不吝赐教(拱手状 O(∩_∩)O)
突然发现自己学和写出来一步一步进行讲解真的很不一样,应该是技术水平过于拙劣吧
step1
从最基础讲SurfaceShader,需要介绍其常用的标准的表面着色器输出结构(SurfaceOutput)
struct SurfaceOutput{ half3 Albedo; //表面着色器当中常于做漫反射的颜色值,也就是SurfaceShader常用来进行输出的颜色值 half3 Normal; //游戏物体(mesh)的表面法线坐标 half3 Emission; //自发光颜色 half Specular; //镜面高光 half Gloss; //光泽系数 half Alpha; //透明度系数};
看完很蒙?
那就对了。。。说明我不是一个人O(∩_∩)O哈哈~(狂笑)
没关系,大家先放一放,紧接着会在案例中对这些属性及其作用进行讲解,先有个印象好了
step2
表面着色器的编译指令
我们在写vertex&*fragment shader 时 经常会为其指定一个通道进行渲染,但是SurfaceShader不可以放在通道(pass)内,因为表面着色器会自身编译为多个通道。
Shader"Example / AutisticPatient SurfaceShader1"{ SubShader { CGPROGRAM //表面着色器编译指令, #pragma + surface + surfaceFunction + LightModle //这里指定了unity3D的内建光照模型:Lambert #pragma surface surf Lambert //其中“Input”是自定义的结构。Input 结构应包含表面函数所需的任何纹理坐标和额外自动变量。 //SurfaceOutput刚才说了 是表面着色器标准输出结构体,这里Input将作为输入结构体,SurfaceOutput将用于输出 void surf(Input IN, SurfaceOutput o) { } ENDCG }}
step3
表面着色器的输入结构体
下面是一部分可以放在输入结构体当中的值
struct Input { float2 uv_MainTex; //主纹理UV坐标值 float2 uv2_MainTex; //使用第二纹理坐标值 float3 viewDir; //包含视线方向 float4 screenPos; //屏幕空间位置 float3 worldPos; // 将包含世界坐标空间位置。 };
剩下的不管有没有提到 都会在接下来的shader实例中进行讲解
表面着色器实例
(1)
因为是对官方案例的讲解,所以就按照官方的顺序来,我会逐句进行解释
并配上效果图供大家参考(图片是Down的)
从一个简单的SurfaceShader开始
Shader"Example / AutisticPatient SurfaceShader2"{ //刚开始官方给的是一个不需要纹理的shader,所以这里并没有大家常见的Properties //开始一个子shader SubShader { //Tags 用来指示渲染引擎如何渲染,以及何时渲染。+ 标签有多种,灯光标签,队列标签等 //这行代码的意思是此shader渲染不透明对象 //RenderType tag 是渲染标签,它常用的有: //Opaque //Transparent //TransparentCutout //Background //Overlay Tags{"RenderType" = "Opaque"} //开始CG CGPROGRAM //定义表面着色器,并指定了unity内置的光照模式lambert(漫反射光照模式) #pragma surface surf Lambert //表面着色器输入结构体 //为什么里面能写颜色值上边已经说过了 struct Input { float4 color : COLOR; }; //这个函数便是我们上面定义好的表面着色器 名称一定要完全相同. //然后将我们定义好的输入结构体放进去 //想要使得表面着色器能够输出我们想要的颜色值,还必须将标准的表面着色器结构体作为输出放进形参内. //这里使用了inout关键字,意思是 SurfaceOutput结构体中传进来的参数既作输入也做输出. void surf(Input IN,inout SurfaceOutput o) { //相当于o.Albedo = (1,1,1)不要问为啥了吧(痛哭状) o.Albedo = 1; //所以最后整个表面着色函数输出的便是SurfaceOutput下的Albedo值了. } ENDCG } //这里需要设置一个备胎着色器,如果以上着色器不能被设备支持 //便会使用下面的Diffuse着色器 fallback"Diffuse"}
这个shader就不上效果图了,实在是没啥可看的,咳咳~
(2)
接下来是有纹理贴图的shader
Shader"Example / AutisticPatient SurfaceShader3"{ //属性块,这一代码块中定义的属性是对整个shader的定义(这句话可能不太恰当) //比如说,我们想要一个融化效果,那么在shader中肯定会有融化纹理以及主纹理的定义 //还有包括融化速度,融化边缘效果等等,这些属性都是要在Properties中进行定义的 Properties { //_MainTex的作用是关联整个shader代码,下面我们会在CG中进行关联,只有关联上,我们才能对这个纹理进行修改等操作 //"MainTex" 的作用是在Inspector面板中创建一个可视化操作台,方便开发者在外部进行修改贴图,不需要修改shader. //2D的作用的指定我们所定义的对象的类型,这里是指2D纹理类型,如果你想定义一个贴图,那么就要用到它了 //等号后面,不说了,就是初始化而已 _MainTex("MainTex",2D) = "white"{} } SubShader { Tags{"RenderType" = "Opaque"} CGPROGRAM #pragma surface surf Lambert //输入结构体用于描述贴图的uv坐标,只有得到了uv坐标,才能对纹理进行采样等操作 struct Input { //命名格式 uv + _MainTex float2 uv_MainTex; }; //properties里已经说过了,想要对纹理贴图进行操作,就必须关联上 //而为什么用sampler2D呢 //如果在Properties使用2D,CG里要用sampler2D,代表使用的是2维纹理 //这是王八的屁股,规定(龟腚) sampler2D _MainTex; void surf(Input IN,inout SurfaceOutput o) { //tex2D是CG程序中用来对一张贴图(这里是_MainTex)中对一个点(IN.uv_MainTex)进行采样的方法 //返回一个float4类型,并将其颜色的rgb值赋给了输出的像素颜色 //总的来说,着色器会找到贴图上对应的UV坐标点,直接使用这个点的颜色信息rgb来进行着色. o.Albedo = tex2D(_MainTex,IN.uv_MainTex).rgb; } ENDCG } FallBack"Diffuse"}
ok 上个效果图先
本节就到这里吧
刚开始有很多细节是不能跳过的,所以注释会显得过于冗长(其实就是表达能力弱(。・・)ノ)
- UnityShader官方案例讲解——SurfaceShader(1)
- UnityShader官方案例讲解——SurfaceShader(2)
- UnityShader官方案例讲解——SurfaceShader(3)
- UnityShader官方案例讲解——SurfaceShader(4)
- unityshader之surfaceshader
- UnityShader案例(八)——透明效果(1)
- UnityShader案例(一)——漫反射
- UnityShader案例(二)——Phong高光反射
- UnityShader案例(三)——BlinnPhong高光反射
- UnityShader案例(四)——单张纹理
- UnityShader案例(五)——法线纹理
- UnityShader案例(六)——渐变纹理
- UnityShader案例(七)——遮罩纹理
- UnityShader案例(九)——透明效果(2)
- UnityShader官方案例之表面着色器光照示例
- UnityShader官方案例之编写顶点和片段着色器
- UnityShader——Wireframe
- SurfaceShader
- 基础——算法
- C++知识文档九_多态和虚函数
- Problem-467A-Codeforces-George and Accommodation
- Pandas 文本数据方法 startswith( ) endwith( )
- Glide_三级缓冲
- UnityShader官方案例讲解——SurfaceShader(1)
- 蓝桥杯 乘积最大(dfs)
- Ehome:智能家居之嵌入式软件项目发布
- 关于Tomcat端口被占用的解决办法
- 如何做事儿? 分而治之!!!
- uoj 279: [清华集训2016]温暖会指引我们前行
- Python 字符串方法汇总
- Android更新UI的几种方式
- windows下python2.7 pip的安装