管线渲染

定义:图形数据在GPU上经过运算处理,最后输出到屏幕的过程

1. 顶点处理: 接收模型顶点数据、坐标系装换

2. 图元装配: 组装面、连接相邻的顶点,绘制为三角面

3. 光栅化 :计算三角面上的像素,并为后面着色阶段提供合理的插值参数(以及深度值)

4. 像素处理: 对每个像素区域进行着色、写入到缓存

5.  缓存:一个存储像素数据的内存块,最重要的缓存是帧缓存与深度缓存

帧缓存:存储每个像素的色彩(缓冲)

深度缓存Z-buffer:前后排序(深度信息,物体到摄像机的距离)

6. Draw Call  绘制调用:每帧调用显卡渲染物体的次数

什么是缓冲?

一个像素有如下缓冲

颜色缓冲Color buffer/prixel buffer: 储存该点即将显示的颜色,RGBA值

深度缓存 depth buffer/Z buffer: 储存该点的深度Z

模板缓存stencil buffer  : 通常作用限制渲染区域。更高级用法需结合深度缓存,例如某像素的模板缓冲值会随着其是否通过深度缓冲测试而改变

什么是图元装配(Primitive Assembly)

经过变换的顶点 被装配成几何(三角形等)图集

什么是光栅化(栅格化)(Rasterization)

栅格化这个术语:可以用于任何将矢量图形转化成栅格图像的过程

在3D渲染中主要是指,三角形等图元(矢量)转化成像素碎片的过程。或者说决定哪些像素几何图元覆盖的过程。栅格化的结果是像素位置的集合和片段的集合

什么是光栅操作(Raster Operation)

指在碎片fragment处理后,在更新帧缓存前最后执行的一系列操作。通过包括裁剪,深度测试,alpha测试,alpha混合等。

Shader常见术语

Alpha 透明的(黑透白不透、灰色半透半不透)

Bump凹凸 (法线贴图)

Specular (高光)

Shader主要看Game视窗

Shader显示名称与Shader名不冲突

什么是GPU?

GPU:Graphic Processing Unit,中文翻译为“图形处理器”。显卡包括(GPU,显存,显卡BLOS,显卡PCB板)

什么是Shader?

Shader程序:GPU执行的,针对3D对象进行操作的程序

Shader编程有那几种?

CG:与DirectX 9.0 以上以及OpenGL 完全兼容。运行时或事先编译成GPU汇编代码

HLSL: 主要用于Direct3D。平台:Windows

GLSL: 主要用于OPenGL。 平台:移动平台(IOS,Android),Mac(only use when you target Mac OS X or OpenGL ES 2.0)

为什么Shader中选择CG?

因为CG/HLSL 比GLSL支持更多的平台。

Unity3d 里CG输出什么?

Windows平台:Direct3D,GPU汇编代码

Mac: OpenGL GPU汇编代码

Flash: Flash GPU 汇编代码

IOS/Android : unity 会将CG转换成GLSL代码。

总结:也就是除了移动平台会把CG转换成GLSL代码,其余平台都是转化成汇编代码。

Unity 中的三种自定义Shade:

1.surface shaders, 表面着色器(最常用,比固定功能管线高级)(之前默认创建的shader类型)它是 Vertex and fragment shaders 的包装,让我们可以不用关心这些顶点和片段程序的细节,可以直接得到我们想要的着色器。

2.Vertex and fragment shaders 顶点和片元着色器(细节处理,偏底层)

3.fixed function shaders.  固定功能管线着色器(更简单),在可编程渲染管线硬件出现之前,很多光照都会放在硬件级处理(可以理解为对固定管线硬件的操作),一般放在项目前绝大多数硬件都可支持,应用就可以使用,比如光照、纹理采样

//Shader中没有注明是前两种shader,即为第三种shader

先从ShaderLab基本语法开始入手,再去阅读surface shader,或者vertex and fragment shaders

ShaderLab 基本结构

Unity中的Shader 都是要通过ShaderLab的基本语法进行编写,unity就是想通过Shaderlab的方案进行Shader的编写。将三种定义的Shader通过同一种格式进行编写,避免不同Shader使用不同的方法。

Shader "name"
{//[Properties] 属性 查看ShaderLab:Properties //作用:在可视化面板提供美工可使用的属性Properties  {}//[Subshader] 算法用于执行给定的数据SubShader{}//[FallBack] 后退 一般会填写所有硬件都支持的渲染方式FallBack "Diffuse"
}

关于SubShaders (处理ShaderLab中的语言片段) 在ShaderLab中至少有一个SubShader,当然也可多个。但是,显卡每次渲染处理的时候只能选择一个SubShaders执行。那多个SubShader的作用是为了不同的硬件的渲染支持,为了Shader能在比较老的图形显卡中也能支持。一般比较往下的Subshader要简化,运算指令要简单。

Fixed function shader固定功能管线

所有硬件平台都可支持,针对硬件能够执行的基本命令的Shader,当然有,但是,速度最快

Properties 属性

Material 材质

Lighting 光照

Settexture  设置纹理

Pass通道(存储图像的色彩RGB)(只有Surface 可以不写)

Surface shaders

surfaceOutPut输出

Input 输入

Lighting 光照

常用公式

环境反射

Ambient= Ka*globalAmbient;

Ka是材质的环境反射系数

globalAmbient是入射环境光的颜色

漫反射

Diffuse=Kd*lightColor*max(N*L,0);

Kd 是材质的漫反射颜色

lightColor是入射漫反射光的颜色

N 是规范化的表面法向量

L 是规范化的纸箱光源对的向量;

镜面反射

Specular=Ks * lightColor *facing*max((N*H),0) shininess

Ks 是材质的镜面反射颜色;

lightColor是入射镜面反射光的颜色

N是规范化的表面法向量

V是指向视点的规范化的向量

L是指向光源的规范化的向量

H是V和L的中间向量的规范化向量

P是要被着色的点

Faceing是1如果N*L是大于0的,否者为0

写Shader不区分大小写

和灯光有呼应的  ------ 漫反射  高光   背光    阴影   环境光

固定着色器格式

hader "Unlit/Test2"//不区分大小写
{//声明属性Properties{//默认颜色颜色//变量名    在监视面板显示的名称    类型=值_Color("MyColor",Color)=(1,0,0,1)//环境光_Ambient("Ambient",Color)=(1,0,0,1)//高光_Specular("Specular",Color)=(1,0,0,1)_Shininess("Shininess",Range(0,1))=0.5 //range 0-8的值//自发光_Emission("Emission",Color)=(1,0,0,1)//_MainTexture("Main Texture",2D)="white"{}//默认颜色}SubShader{pass{Color[_Color]   //使用默认颜色进行颜色的写入Material{//漫反射Diffuse[_Color]//环境光Ambient[_Ambient]//亮度Shininess[_Shininess]//高光反射系数Specular[_Specular]//自发光Emission[_Emission]}//启动光照Lighting On //启动高光反射SeparateSpecular OnSetTexture[_MainTexture]{Combine Texture*primary double}}}FallBack "Diffuse"
}

表面着色器格式

Shader "Custom/Test1" {//属性 //属性变量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 { "RenderType"="Opaque" } //描述渲染类型,当前是不透明的物体//Tags{"RenderType"="Opaque" "queue"="transparent"}//透明的物体LOD 200  //层级细节CGPROGRAM  //CG代码块 CG开始// Physically based Standard lighting model, and enable shadows on all light types//如果是Standard fullforwardshadows光照模型,则对应用SurfaceOutputStandard,//如果是Lambert光照模型(其他版本Unity默认的光照模型),则对应SurfaceOutput。//对应的SurfaceOutputStandard/SurfaceOutput结构体不用写出来#pragma surface surf Standard fullforwardshadows//编译指令//surface表面着色器 surf调用的方法 Standard基于物理的光照模型(原来是漫反射 Lambert)//fullforwardshadows 阴影表现(平行光、点光、聚光都是有阴影的)// Use shader model 3.0 target, to get nicer looking lighting#pragma target 3.0  //GPU硬件支持3.0 (不写默认是2.0)sampler2D _MainTex; //CG中图片的类型struct Input {float2 uv_MainTex; //记录uv纹理坐标};half _Glossiness; //CG中的浮点型half _Metallic;   fixed4 _Color;    //CG中的四阶向量(0,0,0,0)rgb// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.// #pragma instancing_options assumeuniformscalingUNITY_INSTANCING_CBUFFER_START(Props)// put more per-instance properties hereUNITY_INSTANCING_CBUFFER_END//Input 传入值    inout 传出值(基于物理的要加Standard)void surf (Input IN, inout SurfaceOutputStandard o) {// Albedo comes from a texture tinted by colorfixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;o.Albedo = c.rgb;// Metallic and smoothness come from slider variableso.Metallic = _Metallic;  //金属光泽表现o.Smoothness = _Glossiness; //高光光泽度o.Alpha = c.a;}ENDCG //CG结束}FallBack "Diffuse"
}

表面着色器示例练习

Shader "Custom/Test5" {Properties {//2D ---图片    white----默认格式  “”内也可以不写//大括号也可以不写(大括号内可以给值)_MainTex("Texture",2D)="white"{}_BumpMap("Bumpmap",2D)="bump"{}//cube 立方体贴图_Cube("Cubemap",CUBE)=""{}}SubShader {//不透明Tags { "RenderType"="Opaque" }LOD 200CGPROGRAM// Physically based Standard lighting model, and enable shadows on all light types//如果是Standard fullforwardshadows光照模型,则对应用SurfaceOutputStandard,//如果是Lambert光照模型(其他版本Unity默认的光照模型),则对应SurfaceOutput。//对应的SurfaceOutputStandard/SurfaceOutput结构体不用写出来#pragma surface surf Lambert// Use shader model 3.0 target, to get nicer looking lighting#pragma target 3.0struct Input {//只要是纹理相关都需要UVfloat2 uv_MainTex;float2 uv_BumpMap;float3 worldRef1;INTERNAL_DATA  //反射与法线效果配合};//再次声明变量sampler2D _MainTex;sampler2D _BumpMap;samplerCUBE _Cube;// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.// #pragma instancing_options assumeuniformscalingUNITY_INSTANCING_CBUFFER_START(Props)// put more per-instance properties hereUNITY_INSTANCING_CBUFFER_ENDvoid surf (Input IN, inout SurfaceOutput o) {o.Albedo=tex2D(_MainTex,IN.uv_MainTex).rgb;//不需要法线的反射效果//o.Emission=texCUBE(_Cube,IN.worldRefl).rgb;//法线与反射效果配合//需要将INTERNAL_DATA添加到Input结构中o.Normal=UnpackNormal(tex2D(_BumpMap,IN.uv_BumpMap));//反射o.Emission=texCUBE(_Cube,WorldReflectionVector(IN,o.Normal)).rgb;}ENDCG}FallBack "Diffuse"
}

CG之基本光照模型计算公式

在一个基本模型里,一个物体表面的颜色是由放射(emissive)、环境反射(ambient)、漫反射(diffuse)和镜面反射(specular)等光照作用的总和。每种光照作用取决于表面材质的性质(如亮度和材质颜色)和光源的性质(如光的颜色和位置)的共同作用。

从数学上描述基本模型的高级公式如下所示:

surfaceColor = emissive +ambient + diffuse + specular

一、放射项

emissive = Ke

其中:

Ke代表材质的放射光颜色。

二、环境反射项

ambient = Ka * globalAmbient

其中:

Ka是材质的环境反射系数。

globalAmbient是入射环境光的颜色。

三、漫反射项

diffuse = Kd * lightColor * max(dot(N, L), 0)

其中:

Kd是材质的漫反射颜色。

lightColor是入射漫反射光的颜色。

N是规范化的表面法向量。

L是规范化的从顶点到光源的向量。

四、镜面反射项

specular = Ks * lightColor * facing * pow(max(dot(N, H), 0), shininess)

其中:

Ks 是材质的镜面反射颜色。

lightColor是入射镜面反射光的颜色。

N是规范化的表面法向量。

H是规范化的,顶点到光源的向量与顶点到眼睛的向量的中间向量。

facing是,如果dot(N,L)大于0则为1,否则为0。其中L是顶点到光源位置的向量。

shinniess是表面光泽度。

1 Shader "Custom/Test"
 2 {
 3     Properties
 4     {
 5         _Ke("Ke", Color) = (1,1,1,1)
 6         _Ka("Ka", Color) = (1,1,1,1)
 7         _GlobalAmbient("Global ambient", Color) = (1,1,1,1)
 8         _Kd("Kd", Color) = (1,1,1,1)
 9         _Ks("Ks", Color) = (1,1,1,1)
10         _Shininess("", float) = 1
11     }
12
13     SubShader
14     {
15         Pass
16         {
17             Tags
18             {
19                 "RenderType" = "Opaque"
20             }
21
22             CGPROGRAM
23             #pragma vertex Vert
24             #pragma fragment Frag
25
26             #include "UnityCG.cginc"
27             #include "Lighting.cginc"
28
29             uniform float4 _Ke;
30             uniform float4 _Ka;
31             uniform float4 _GlobalAmbient;
32             uniform float4 _Kd;
33             uniform float4 _Ks;
34             uniform float _Shininess;
35             
36             struct VertexInput
37             {
38                 float4 pos : POSITION;
39                 float2 uv : TEXCOORD0;
40                 float3 nor : NORMAL;
41                 float4 col : COLOR;
42             };
43
44             struct FragmentInput
45             {
46                 float4 pos : SV_POSITION;
47                 float2 uv : TEXCOORD0;
48                 float4 col : COLOR;
49             };
50
51             FragmentInput Vert(VertexInput vi)
52             {
53                 FragmentInput fi;
54                 fi.pos = mul(UNITY_MATRIX_MVP, vi.pos);
55                 fi.uv = vi.uv;
56
57                 // compute emissive
58                 float3 emissiveC = _Ke.rgb;
59
60                 // compute ambient
61                 float3 ambientC = _Ka.rgb * _GlobalAmbient.rgb;
62
63                 // compute diffuse
64                 float3 nor = mul(vi.nor, (float3x3)_World2Object);
65                 float3 dir2Light = normalize(WorldSpaceLightDir(vi.pos));
66                 float nl = max(0, dot(nor, dir2Light));
67                 float3 diffuseC = _Kd.rgb * _LightColor0.rgb * nl;
68
69                 // compute specular
70                 float3 dir2Cam = normalize(WorldSpaceViewDir(vi.pos));
71                 float nh = max(0, dot(nor, dir2Cam + dir2Light));
72                 float specLight = nl > 0 ? pow(nh, _Shininess) : 0;
73                 float3 specC = _Ks * _LightColor0.rgb * specLight;
74
75                 fi.col.rgb = emissiveC + ambientC + diffuseC + specC;
76                 fi.col.a = 1;
77
78                 return fi;
79             }
80
81             float4 Frag(FragmentInput fi) : Color
82             {
83                 return fi.col;
84             }
85
86             ENDCG
87         }
88     }
89 }

【Unity5.x Shaders】最基本的Surface Shader-Diffuse shader以及Surface中的三种输出结构

某些物体可能具有均匀的颜色和光滑的表面,但光滑程度不足以照射反射光。
这些哑光材料最好用Diffuse Shader。 在现实世界中,不存在纯diffuse materials
Diffuse shader经常出现在游戏中,下面就是一个简单的Diffuse shader代码

Shader "Custom/DiffuseShader" {Properties {_Color ("Color", Color) = (1,1,1,1)                     }SubShader {Tags { "RenderType"="Opaque" }LOD 200CGPROGRAM// Physically based Standard lighting model, and enable shadows on all light types#pragma surface surf Standard fullforwardshadows// Use shader model 3.0 target, to get nicer looking lighting#pragma target 3.0struct Input {float2 uv_MainTex;};fixed4 _Color;void surf (Input IN, inout SurfaceOutputStandard o){           o.Albedo = _Color.rgb;          }ENDCG}FallBack "Diffuse"
}

这是一个从Standard Shader改装的的Shader,它将使用基于物理的渲染去模仿灯光在模型上的行为。
如果你想实现一个非真实感(non-photorealistic)的外观,可以改变第一个预处理指令使用Lambert光照模型。
#pragma surface surf Lambert
如果使用了这个模型,surf函数中的输出结构SurfaceOutputStandard需要改成SurfaceOutput

Surface输出结构

Shader允许你通过Surface的输出结构将材质的渲染属性传递给光照模型。
不同的Surface光照模型需要不同的Surface输出结构

在Unity5中,有三种主要的输出结构:

SurfaceOutput

一般的光照模型例如Lambert光照模型

struct SurfaceOutput {  fixed3 Albedo;   //对光源的反射率fixed3 Normal;   //对应切线空间法线方向fixed3 Emission; //自发光half Specular;   //高光反射中的指数部分的系数。fixed Gloss;     //高光反射中的强度系数half Alpha;      //透明通道

SurfaceOutputStandard

标准光照模型 使用此结构输出

struct SurfaceOutputStandard {  fixed3 Albedo;  //材质的基础颜色(无论是漫反射还是高光)fixed3 Normal;   half3 Emission; //类型被声明为half3,注意在SurfaceOutput中被定义为fixed3half Alpha;      half Occlusion; //遮挡(默认为1)  half Smoothness;//光滑程度(0=粗糙, 1=光滑)half Metallic;  //0=非金属, 1=金属

SurfaceOutputStandardSpecular

标准镜面光照模型 使用此结构输出

struct SurfaceOutputStandardSpecular
{fixed3 Albedo;      fixed3 Specular;    // 镜面反射颜色fixed3 Normal;     half3 Emission;half Smoothness;    half Occlusion;     fixed Alpha;
};

注意:这里的Specular完全不同于SurfaceOutput中的Specular
它允许指定一个颜色而不是一个单值。

正确使用Surface Shader,是使Surface输出结构输出正确的值

参考资料 https://blog.csdn.net/leonardo_davinci/article/details/78869587

Shader的基础知识相关推荐

  1. 【西川善司的3D图形技术连载】GPU和Shader技术的基础知识(1~8回)

    本连载的主要目的,是介绍最新的PC和GAME所使用的最新3D图形技术的发展趋势. 暂时的方针是,首先是考虑介绍比较新的PC Game和PS3,XBOX360等新时代游戏机的游戏所采用的技术. 那么首先 ...

  2. 【西川善司】GPU和Shader技术的基础知识(全8回)

    本文取自西川善司的3D图形技术连载,全99回 本贴为1~8回,争取每1~2天更新一回吧.半年更新完. 也希望大家能支持. 翻译 Trace 校对&注解 千里马肝 http://www.open ...

  3. Unity3d基础知识之Texture纹理、Shader着色器、Material材质、Rendering Mode

    Unity3d基础知识之Texture纹理.Shader着色器.Material材质.Rendering Mode 一.纹理.着色器与材质 Texture(纹理):应用于网格表面上的标准位图图像.Un ...

  4. HLSL 的基础知识

    基础知识很重要,一定要抓牢! 一.数据类型: HLSL中的数据类型主要有:标准类型.向量.矩阵.和复杂数据类型几大类. 标准数据类型: 标准的数据类型有:bool ,int,half ,float,d ...

  5. Unity3D基础知识之Camera摄像机及其属性

    Unity3D基础知识之摄像机Camera 一.简介 Camera:附加了摄像机Camera组件的游戏对象,向玩家捕获和显示世界的设备,同时在一个场景中摄像机的数量不限. 组件:Transform:变 ...

  6. 计算机图形渲染基础知识(个人笔记)

    一,什么是计算机图形学 对于我个人来说,计算机图形学是用计算机来表示图形,并且运用复杂的数学运算来生成图形的一门科学. 二,计算机图形学能干什么? 计算机图形学能制作粒子特效,动画,渲染,虚拟显示,增 ...

  7. Android基础知识——完善

    首页 下载App × Android基础知识--完善 布鲁马 2016.05.17 10:29* 字数 5478 阅读 2672评论 1喜欢 38 疯狂Android摘要,Android基础知识好乱好 ...

  8. Android基础知识梳理

    文章目录 系统架构 应用层 应用框架层 系统运行库层 硬件抽象层(HAL) Linux内核层 补充 通信方式 Binder IPC原理 Binder原理 Socket handler 主线程中 子线程 ...

  9. 《Unity 3D 游戏开发技术详解与典型案例》——1.1节Unity 3D基础知识概览

    本节书摘来自异步社区<Unity 3D 游戏开发技术详解与典型案例>一书中的第1章,第1.1节Unity 3D基础知识概览,作者 吴亚峰 , 于复兴,更多章节内容可以访问云栖社区" ...

最新文章

  1. 你了解欧拉回路吗?(附Java实现代码)
  2. python3.6环境变量设置win10_python——python3.6环境搭建(Windows10,64位)
  3. MySQL数据库MVCC多版本并发控制简介
  4. SetConsoleCursorPosition光标的位置控制
  5. (转)Arcgis for JS之Cluster聚类分析的实现
  6. html数字自动滚动代码怎么写,你可能需要这样的大屏数字滚动效果
  7. Delphi的MessageBox对话框使用
  8. static与线程安全 -摘自网络
  9. unity, 取消ugui button响应键盘
  10. linux脚本定义量,Linux上增加自定义脚本的展现量
  11. SPSS——相关分析——偏相关(Partial)分析
  12. 黑帽SEO研究之js快照劫持代码分析
  13. 【S-CMS企业建站系统 v5.0 】闪灵CMS+含小程序+响应式布局+支持手机版网站+支持QQ旺旺客服
  14. 11月小报|读小报,涨知识
  15. linux下使用命令行将informix数据库表导出.unl文件
  16. 数学建模:整数规划示例模型 (Python 求解)
  17. 卫生间智能取纸机选型知识合集
  18. 一文看懂计算机网络五层协议+各层网络协议大全
  19. 二 、C语言程序的基本语句和基本结构
  20. 计算机公式乘以百分之十五,EXCEL表格数据乘以15的公式【EXCEL表格中可以套用公式来实现输入数据后自动乘以某个数据的计算吗?】...

热门文章

  1. Qt的基本控件——列表控件
  2. 计算机网络各层协议说明及常见协议
  3. 正则表达式中,表示匹配非数字字符的字符
  4. 基址寻址和变址寻址的不同
  5. Muli3D 4 Calculate vertex tangent
  6. jxTMS--web界面定义
  7. MacBook电池使用策略
  8. android手机屏幕共享神器踩坑指南
  9. h5 底部按钮兼容 iPhone X(解决底部横杠遮挡问题)
  10. 这又是一则招聘贴——招聘区块链系统开发的同学