HLSL
高阶着色器语言(High Level Shader Language,简称HLSL),由微软拥有及开发的一种语言,HLSL 独立的工作在 Windows 平台上,只能供微软的Direct3D使用。 HLSL是微软抗衡GLSL的产品,同时不能与OpenGL标准兼容。
GLSL
OpenGL着色语言(OpenGL Shading Language)是用来在OpenGL中着色编程的语言,也即开发人员写的短小的自定义程序,他们是在图形卡的GPU (Graphic Processor Unit图形处理单元)上执行的,代替了固定的渲染管线的一部分,使渲染管线中不同层次具有可编程性。
CG
Paste_Image.pngGPU语言
由于GPU采用不同于CPU的运行运算结构,因此需要一种适用于GPU的编程语言。
1、微软基于Direct3D图形库的HLSL(High Level Shading Language)
2、OpenGL ARB定义基于OpenGL图形库的GLSL(OpenGL Shading Language)
3、NVIDIA(英伟达)与微软合作研发的Cg(C for Graphics).
Cg能够同时兼容Direct3D和OpenGL图形接口。
Unity所有的渲染都需要shader来完成,内置的着色器超过80个,可以轻松利用其内置的着色器来完成各种画面效果,并且还提供了自定义shader,方便扩展。Unity使用shaderLab开发语言来组织shader内容,并会针对不同的平台进行编译,类似微软的FX文件或者NAIDIA的CgFX.
Shader,可以分为VertexShader 和PixelShader/FragmentShader两部分,简称VS,PS。学名顶点着色器和像素着色器。一旦你使用了VS和PS,则渲染过程会将VB(顶点缓冲)的数据按照IB索引(顶点索引缓冲)将每个顶点结构值分量传入VS,VS进行相应的计算和顶点变化,并将VS返回的结果再交由PS进行像素着色,输出相应的图像。概念上来说 FragmentShader会比PixelShader大很多..
这两个东西由于DX用PixelShader的缘故,其实是一个东西
Unity中可以编写3种不同的着色器:表面着色器(Surface Shader)、顶点和片段着色器(Vertex and Fragment Shaders)和固定功能管线着色器(Fixed Function Shaders).
Unity5.0,内建了基于物理渲染的StandardShader,同时还引入了完全延迟着色(FullDeferredRendering)和烘焙反射探头(Baked Reflection Probes)用于以真实环境为基础的镜面高光
物理着色:PBS (physically Based Shading):新的工业标准,用于电影产品
遵从了Conservation of Energy(能量守恒定律),只有这样才能够正真让场景里面的光源依据能量传递的方式,产生一种自然和谐的光照效果。
Paste_Image.png
Standard Surface Shader (Instanced):标准表面材质(实例化)
Unlit Shader:未点燃的材质
Image Effect Shader:图像效果材质
Compute Shader:计算着色器
Shader Variant Collection:着色器变量集合
内建Shader介绍
4.X版本提供超过80个内建Shader、包括顶点光照效果到高光、发现、反射等游戏常用的材质效果。
内建Shader分类:
普通(Normal):用于不透明对象
透明(Transparent):用于半透明和全透明对象
透明镂空效果(TransparentCutOut):用于完全透明和完全不透明部分组成(不含半透明部分)的对象,像栅栏一样。
自发光(Self-llluminated shader Family):用于能反射环境立方体贴图的不透明对象
反射(Reflective Shader Family):用于能反射环境立方体贴图的不透明对象
每个类别下包含若干复杂性各异的shader
Paste_Image.png
以光照效果计算开销从低到高排序:
Unlit : 仅使用纹理,不受光照影响
VertexLit:顶点光照
Diffuse:漫发射
Specular: 在漫反射基础上增加高光计算
Nomal Mapped : 法线贴图,增加了一张法线贴图和几个着色器指令。
Nomal Mapped Specular : 带高光法线贴图
Parallax Nomal Mapped : 视差法线贴图,增加了视差贴图计算开销
Parallax Nomal Mapped :带高光视差法线贴图
5.X版本新增加了一种基于物理着色的内建着色器,即StandardShader(标准着色器)
物理着色:PBS (physically Based Shading):新的工业标准,用于电影产品
遵从了Conservation of Energy(能量守恒定律),只有这样才能够正真让场景里面的光源依据能量传递的方式,产生一种自然和谐的光照效果。
Paste_Image.png
Paste_Image.png
StandardShader是基于物理的着色器,也就是说不管你选择什么样的贴图都会与光照产生反应,这些贴图可以是同一张图片,Unity会使用必要的资源进行计算。
原理:
遵从了Conservation of Energy(能量守恒定律),只有这样才能够正真让场景里面的光源依据能量传递的方式,产生一种自然和谐的光照效果。
表面反射的光线不会比它们收到的更多
光滑的表面会有更强的反射
醋糟的表面反射会更弱一些
高光强度会随着漫反射的强度而改变
所有的表面从某一特定角度看上去会有或多或少的高光
所有的表面在掠射角会有更多的反射
编写自己的Shader(详细解答Shader的各种属性及用法)
Shader "Custom/firstsharder" {//这里是Shader的名字
Properties {//着色器属性
_Color ("Color", Color) = (1,1,1,1)
//在输入贴图时候,必须要写一个什么都不含的{}
//需要打开特定选项时可以把其写在这对花括号内.
//如果需要同时打开多个选项,可以使用空白分隔
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader {
//表面着色器可以被若干的标签(tags)所修饰
//硬件将通过判定这些标签来决定什么时候调用该着色器
Tags { "RenderType"="Opaque" }//标签内部就是告诉系统渲染非透明的物体调用我们
//Tags { "RenderType"="Transparent" }//渲染透明物体调用
//Tags { "IgnoreProjector"="True" }//不被Projectors影响
//Tags{ "ForceNoShadowCasting"="True" }//不产生阴影
//指定渲染队列(下面有系统预设的队列)
//Tags{ "Queue"="Geometry" }
//Background--最早被调用的渲染,用来渲染天空盒或者背景
//Geometry--默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
//AlphaTest--用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑
//Overlay--用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)
//Transparent--以从后往前的顺序渲染透明物体
//预设的队列本质就是定义的整数(有点像枚举值)
//Background=1000,Geometry=2000,AlphaTest=2450
//Transparent=3000,最后Overlay=4000
//如何自定义列表
Tags{ "Queue"="Transparent+100" }//通过调用Queue值,确保渲染的先后顺序
//Unity的内建Diffuse着色器的设定值,这个数值决定了我们能用什么样的Shader
//这个数值可以在unity中的质量设定中设定
LOD 200//着色器的设定值
//关于VertexLit及其系列 = 100
//Decal, Reflective VertexLit = 150
//Diffuse = 200
//Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
//Bumped, Specular = 300
//Bumped Specular = 400
//Parallax = 500
//Parallax Specular = 600
//Shader字体:也就是将输入转变成输出的代码部分
CGPROGRAM//开始CG语言的编写
// Physically based Standard lighting model, and enable shadows on all light types
//surface:申明的是一个表面着色器
//surf:着色器代码的方法的名字,下方的代码有这个函数
//Standard:标准
//fullforwardshadows:光照模型
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
//在CG中,sampler2D就是和texture所绑定的一个数据容器接口
//其实就是内存存储的RGB通道,sampler2D:就是GLSL中的2D贴图的类型
//其他类型:sampler1D,sampler3D,samplerCube
// 图片
sampler2D _MainTex;
// 用来获取MainTex的UV信息
struct Input {
float2 uv_MainTex;//float2:浮点数的float后面紧跟一个数字2
vec2 coordinate;//float和vec都可以在之后加入一个2到4的数字,来表示被打包在一起的2到4个同类型数
float4 color;
};
half _Glossiness;//half指的是半精度浮点数,精度最低,运算性能相对比高精度浮点数高一些
half _Metallic;
// 颜色属性
fixed4 _Color;
// SurfaceOutputStandard 表面着色器输出一个标准的结构体
//着色器的工作核心,着色器就是给定了输入,然后给出输出进行着色的代码,第一个参数是Input结果,第二个参数是一个inout的SurfaceOutput结构
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
// 获取图片 * 我们选定的颜色
//fixed4:定点书:整形数据类型,作用就是把所有数进行转换,得到相应类型的整形表达
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
// 输出的像素的颜色 = 图像的颜色(RGB)
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
// 输出的颜色效果(金属方面) = 设定的金属值
o.Metallic = _Metallic;
// 输出的光滑粗糙程度 = 设置的光滑粗燥程度
o.Smoothness = _Glossiness;
// 输出的透明通道 = 图像的透明通道
o.Alpha = c.a;
}
ENDCG//结束CG语言的编写
}
FallBack "Diffuse"
}
642887-57f1485a1e706ea0.png
参考
https://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html
https://onevcat.com/2013/08/shader-tutorial-2/
http://www.tuicool.com/articles/JvYJ3em
http://www.itnose.net/detail/6143450.html
CG语言基础知识:
内置元类型
Float : 32bit浮点类型
Half: 16bit浮点
Int : 32bit整形
Fixed : 12bit定点
Bool : 布尔值
Sampler:纹理对象的句柄
String:不是每个都支持
cg提供内置的向量数据类型(build-in vector data types)
float1、float4,
bool2, bool3,
float1x1
float2x3
类型转换跟C是一样的,用强制转化。
类型定义的时候可以在常量后跟后缀,如2.0f,1.0h,3x。目前值有f,h,x(fixed)三种。
支持类型
1、数组
float a[10];
float4 b[10];
int length = a.length; //获取长度,上面两个返回都是10
float b[2][3] = { { }, { } };
int length1 = b.length; // length1 = 2;
int length2 = b[0].length; // length = 3;
2、结构
以struct开始,紧跟名字,内容用{};包住。不要忘记最后的分号。
结构中可以带function,是C++中的用法。
结构不支持继承。
3、特定关键字
in , out , inout,
uniform (被修饰的变量从外部传入), const ,
4、输入语义关键字
Vertex Shader的输入:
POSITION, NORMAL, BINORMAL, BLENDINDICES, BLENDWEIGHT, TANGENT, PSIZE, TEXCOORD0 ~ TEXCOORD7
如:in float4 modelPos: POSITION
Vertex Shader的输出, 也就是Pixel Shader的输入
POSITION, PSIZE, FOG,COLOR0 ~ COLOR1, TEXCOORD1 ~ TEXCOORD7
Pixel Shader的输出:
COLOR
5、入口函数
通过观察程序的输入输出语义绑定,就可以区分入口函数对应到顶点程序还是片段程序。
6、内置函数库
reflect 求发射向量
refract 求折射向量
mul 矩阵相乘
normalize 归一化
CG语言的学习资料:
http://blog.csdn.net/liu_lin_xm?viewmode=contents
https://developer.nvidia.com/cg-toolkit
网友评论