Unity的三种shader形式
自己做个总结先。当然文中很多内容都是从各位大神的文档当中看的。我只是站在巨人的肩膀上。
首先什么是shader?其实就是一个在显示屏当中的显示程序,俗称着色器。它可以定义物体在硬件显示屏当中的显示方式,例如物体颜色和表面贴图,光泽等。貌似3Dmax和maya都有相关的shader程序。本篇基于unity内部的shader总结。
shader在unity的编程当中有3种,1.固定管式shader ;2.VF-shader; 3.surface shader 。
1.固定功能着色器(Fixed Function Shader)
固定功能着色器是传统的Shader语法,用于非常简单的效果。建议编写可编程着色器,因为这样可以提供更大的灵活性。固定函数着色器完全用一种称为ShaderLab,在Unity内部,固定功能着色器最后会转换为顶点和片段着色器。
-
Properties
{
_Color ("Main Color", Color) = (1,0.5,0.5,1)
}
SubShader {
Pass {
Material {
Diffuse [_Color] }
Lighting On
}
}
}
可以看到它有固定的函数块Diffuse [_Color] } ,所以它是由基本的固定的渲染函数组成的,下面是Unity的VertexLit shader的示例
Shader "VertexLit" { Properties { _Color ("Main Color", Color) = (1,1,1,0.5) _SpecColor ("Spec Color", Color) = (1,1,1,1) _Emission ("Emmisive Color", Color) = (0,0,0,0) _Shininess ("Shininess", Range (0.01, 1)) = 0.7 _MainTex ("Base (RGB)", 2D) = "white" { } } SubShader { Pass { Material { Diffuse [_Color] Ambient [_Color] Shininess [_Shininess] Specular [_SpecColor] Emission [_Emission] } Lighting On SeparateSpecular On SetTexture [_MainTex] { constantColor [_Color] Combine texture * primary DOUBLE, texture * constant } } } }
所有这些命令都非常直接映射到固定功能OpenGL / Direct3D硬件模型。更多的详细信息,请参阅OpenGL红皮书。
2.表面着色器(Surface Shader)-
需要受到灯光和阴影的影响。Surface Shaders使得以复杂的方式编写复杂的着色器变得容易 - 这是与Unity的照明管道交互的更高层次的抽象。大多数表面着色器自动支持前向和延迟照明。您可以在几行Cg / HLSL中编写Surface Shaders 。
如果您的着色器没有对灯光做任何事情,请不要使用Surface Shaders。对于后期处理效果或许多特殊效果着色器并不建议使用表面着色器,因为它们无缘无故地进行了大量的光照计算。建议初学者从这块学起。与灯光互动非常复杂。有不同的灯光类型,不同的阴影选项,不同的渲染路径(前向和延迟渲染),着色器应以某种方式处理所有复杂性。而surface shader简化了这些东西,你只要控制输出
struct SurfaceOutput { fixed3 Albedo; // diffuse color fixed3 Normal; // tangent space normal, if written fixed3 Emission; half Specular; // specular power in 0..1 range fixed Gloss; // specular intensity fixed Alpha; // alpha for transparencies };
Unity5新出的物理材质表面的输出结构体
struct SurfaceOutputStandard { fixed3 Albedo; // base (diffuse or specular) color fixed3 Normal; // tangent space normal, if written half3 Emission; half Metallic; // 0=non-metal, 1=metal half Smoothness; // 0=rough, 1=smooth half Occlusion; // occlusion (default 1) fixed Alpha; // alpha for transparencies }; struct SurfaceOutputStandardSpecular { fixed3 Albedo; // diffuse color fixed3 Specular; // specular color fixed3 Normal; // tangent space normal, if written half3 Emission; half Smoothness; // 0=rough, 1=smooth half Occlusion; // occlusion (default 1) fixed Alpha; // alpha for transparencies };
Surface Shader代码结构: Properties {} SubShader { //渲染类型为Opaque,不透明 Tags { "RenderType" = "Opaque" } //-------------------开始CG着色器编程语言段----------------- CGPROGRAM //使用兰伯特光照模式 #pragma surface surf Lambert //输入结构 struct Input { }; void surf (Input IN, inout SurfaceOutput o) { }
3.顶点着色器&片段着色器 (Vertex Shader & Fragment Shader)
如果您的着色器不需要与光照交互,或者如果您需要Surface Shaders无法处理的非常奇特的效果,则需要使用顶点和片段着色器。以这种方式编写的着色器程序是创建所需效果的最灵活方式(甚至表面着色器也会自动转换为一堆顶点和碎片着色器),但这需要付出代价:你必须编写更多的代码让它与照明互动。这些着色器也是用Cg / HLSL编写的。
编写顶点/片段程序需要全面了解3D变换,光照和坐标空间 - 因为必须自己重写内置于OpenGL的API的固定功能。!
基本结构: Properties{ } Pass{ Tags{ "LightMode" = "" } CGPROGRAM #pragma vertex vert //#pragma vertex name告诉代码包含给定函数中的顶点程序(此处为vert)。 #pragma fragment frag //#pragma片段名称告诉代码包含给定函数中的片段程序(此处为frag)。
#include "UnityCG.cginc" struct appdata_t { }; struct v2f { }; v2f vert(appdata_t v) { } half4 frag(v2f i) : COLOR { }
本文只是初略研究shader,如有错误之处,欢迎大神指点。
如果您觉得本文对你有用,不妨帮忙点个赞,或者在评论里给我一句赞美,小小成就都是今后继续为大家编写优质文章的动力,carson拜谢! 欢迎您持续关注我的博客:)
作者:carsonche
出处:https://home.cnblogs.com/u/carsonche/
版权所有,欢迎保留原文链接进行转载:)