1 前言

上文介绍了渲染管线、固定管线着色器和表面着色器,如下:

  • 渲染管线

  • 固定管线着色器一

  • 固定管线着色器二

  • 表面着色器

固定管线着色器通过命令方式实现光照和贴图等效果,表面着色器通过给 SurfaceOutput 赋值实现光照、贴图和法线贴图等效果,它们都不用关注光照算法是如何实现的,只需要传值就行。

顶点和片元着色器给用户提供了更灵活的用法,但使用也更困难。另外,顶点着色器可以通过控制 MVP 矩阵变换实现对模型位置和姿态的控制。

2 固定颜色

在 Assets 窗口右键,依次选择【Create→Shader→Standard Surface Shader】创建 Shader 脚本,实现固定颜色 Shader 代码如下:

VFShader.shader

Shader "MyShader/VFShaderTest" {Properties{// 属性名 ("面板显示名称", 类型) = 默认值_MainColor ("显示颜色", Color) = (1, 0, 0, 1)}SubShader{Pass{CGPROGRAM // CG语言的开始// 编译指令 着色器名称 函数名称#pragma vertex vert // 顶点着色器, 每个顶点执行一次#pragma fragment frag // 片段着色器, 每个像素执行一次// 导入头文件#include "UnityCG.cginc"// 声明属性变量, 必须与外部属性变量名称一致fixed4 _MainColor;// 顶点着色器half4 vert(half4 vertexPos: POSITION) : SV_POSITION{// 将局部坐标系下坐标转换为裁剪坐标系下坐标return UnityObjectToClipPos(vertexPos); // 等价于: mul(UNITY_MATRIX_MVP, vertexPos)}// 片元着色器fixed4 frag(): COLOR{return _MainColor;}ENDCG // CG语言的结束}}FallBack "Diffuse"
}

创建一个 Material,并将 ShaderTest 绑定到该 Material 上,如下:

将该 Material 拖拽到一个 Cube 和 Sphere 游戏对象上。选中绑定的 Material,在 Inspector 窗口调整 Shader 中固定颜色,显示效果如下:

3 光照

1)光照原理

Phong 光照模型和 Blinn Phong 光照模型是应用比较广泛的光照模型,两者区别在与镜面反射光的计算,Phong 光照模型根据反向量和观察向量计算镜面反射光,Blinn Phong 光照模型根据半向量和法向量计算镜面反射光。

光照计算如下:

// 模型自身颜色
fixed4 albedo = tex2D(_MainTex, i.uv) * _ModelColor;
// 环境光
fixed4 ambient = UNITY_LIGHTMODEL_AMBIENT * albedo;
// 漫反射光
fixed4 diffuse = _LightColor0 * albedo * max(0, dot(normal, lightDir));
// 镜面反射光(Phong光照模型)
// fixed4 specular = _LightColor0 * _Specular * pow(max(0, dot(reflectDir, viewDir)), _Gloss);
// 镜面反射光(Blinn Phong光照模型)
fixed4 specular = _LightColor0 * _Specular * pow(max(0, dot(normal, halfDir)), _Gloss);
// 合成颜色
fixed4 finalColor = fixed4(ambient + diffuse + specular, 1.0);

2)代码实现

VFShader.shader

Shader "MyShader/VFShaderTest" {Properties {_ModelColor ("Model Color", Color) = (1, 1, 1, 1) // 模型颜色_Specular ("Specular Color", Color) = (1, 1, 1, 1) // 镜面反射颜色_Gloss ("Gloss", Range(8.0, 256)) = 20 // 镜面反射光泽度}SubShader {Tags { "RenderType"="Opaque" }Pass { Tags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"fixed4 _ModelColor; // 模型颜色fixed4 _Specular; // 镜面反射颜色float _Gloss; // 镜面反射光泽度struct a2v {float4 vertex : POSITION; // 模型空间顶点坐标half3 normal : NORMAL; // 模型空间顶点法线向量};struct v2f {float4 pos : SV_POSITION; // 裁剪空间顶点坐标float3 normal : Normal; // 世界空间顶点法线向量float3 worldPos : TEXCOORD0; // 世界空间顶点坐标};v2f vert(a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex); // 模型空间顶点坐标变换到裁剪空间, 等价于: mul(UNITY_MATRIX_MVP, v.vertex)o.normal = UnityObjectToWorldNormal(v.normal); // 将模型空间法线向量变换到世界空间o.worldPos = mul(unity_ObjectToWorld, v.vertex); // 将模型空间顶点坐标变换到世界空间return o;}fixed4 frag(v2f i) : SV_Target {fixed3 normal = normalize(i.normal); // 世界空间法线向量fixed3 lightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); // 世界空间灯光向量fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); // 世界空间观察向量fixed3 halfDir = normalize(lightDir + viewDir); // 半向量fixed3 albedo = _ModelColor; // 模型自身颜色fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT * albedo; // 环境光fixed3 diffuse = _LightColor0 * albedo * max(0, dot(normal, lightDir)); // 漫反射光fixed3 specular = _LightColor0 * _Specular * pow(max(0, dot(normal, halfDir)), _Gloss); // 镜面反射光(Blinn Phong光照模型)return fixed4(ambient + diffuse + specular, 1);}ENDCG}}FallBack "Specular"
}

选中绑定的 Material,在 Inspector 窗口调整 Shader 中光照颜色,显示效果如下:

4 贴图

VFShader.shader

Shader "MyShader/VFShaderTest" {Properties{// 属性名 ("面板显示名称", 类型) = 默认值_MainTex ("2阶贴图", 2D) = "white" {}}SubShader{Pass{Tags {"LightMode"="ForwardBase"}CGPROGRAM // CG语言的开始// 编译指令 着色器名称 函数名称#pragma vertex vert // 顶点着色器, 每个顶点执行一次#pragma fragment frag // 片段着色器, 每个像素执行一次// 导入头文件#include "UnityCG.cginc"// 声明属性变量, 必须与外部属性变量名称一致sampler2D _MainTex;struct appdata // 顶点着色器输入结构体{half4 vertexPos : POSITION; // 顶点坐标half2 uv_MainTex : TEXCOORD0; // 纹理uv坐标};struct v2f // 顶点着色器输出结构体{half4 clipPos : SV_POSITION; // 屏幕坐标half2 uv_MainTex : TEXCOORD0; // 纹理uv坐标};// 顶点着色器v2f vert(appdata data){v2f o;o.clipPos = UnityObjectToClipPos(data.vertexPos); // 等价于: mul(UNITY_MATRIX_MVP, data.vertexPos)o.uv_MainTex = data.uv_MainTex;return o;}// 片元着色器fixed4 frag(v2f input) : SV_Target{return tex2D(_MainTex, input.uv_MainTex);}ENDCG // CG语言的结束}}FallBack "Diffuse"
}

选中绑定的 Material,在 Inspector 窗口选择贴图图片,显示效果如下:

【Unity3D】顶点和片元着色器相关推荐

  1. unity 表面着色器、顶点、片元着色器

    1.表面着色器:表面着色器是Unity特有的一种着色器代码类型,表面着色器定义在SubShader中.表面着色器需要编写的代码量很少,Unity会自动处理一些细节.但是表面着色器的本质和顶点.片元着色 ...

  2. [从零构建光栅渲染器] 6. 顶点和片元着色器的工作原理

    [从零构建光栅渲染器] 6. 顶点和片元着色器的工作原理 非常感谢和推荐Sokolov的教程,Sokolov使用500行C++代码实现一个光栅渲染器.教程学习过程非常平滑,从画点.线和三角形开始教学, ...

  3. java 顶点着色_Shader笔记_002简单顶点/片元着色器扩展

    参考<>第五章 一.如何获取其他模型数据 在001里介绍了通过POSITION获取顶点位置坐标,如果想的到更多的模型数据,比如我们想要得到模型上每个顶点的纹理坐标和法线方向 PS:我们可以 ...

  4. 【Unity Shader】学习顶点/片元着色器

    上一篇博客重点放在了Unity Shader的基本结构,分别介绍了它包含的三个语义块,最后简单介绍了Unity Shader的形式:表面着色器.顶点/片元着色器和固定函数着色器. 趁热打铁,今天接着上 ...

  5. opengl顶点数据传送和着色器处理(vao,vbo)

    OpenGL学习脚印: 顶点数据传送和着色器处理1 写在前面 本节内容翻译和整理自<Learning Modern 3D Graphics Programming>Chapter1内容.作 ...

  6. WebGL入门(四)-在JavaScript程序通过uniform变量向片元着色器传值

    在JavaScript程序通过uniform变量向片元着色器传值 1.demo效果 2.相关知识点 2.1 片元着色器中的uniform变量 2.2 gl.getUniformLocation()方法 ...

  7. UnityShader6:最简单的顶点/片元着色器

    一.顶点/片元着色器基本结构 直接上代码: 这个着色器可以得到蓝色的纯色输出,如果顶点着色器得出了错误的裁剪空间坐标,那么会出现很明显表现错误 Shader "Jaihk662/NewSur ...

  8. 初识顶点/片元着色器

    5.2 一个最简单的顶点/片元着色器 5.2.1 顶点/片元着色器的基本结构 一个 Unity Shader 的基本结构.它包含了 Shader.Properties.SubShader.Fallba ...

  9. 【Unity Shaders】最简单的顶点/片元着色器3

    微信号:ITComputerGraph 更多精彩内容,关注公众号<IT木子李> Shader "Unity Shaders/Simple Shader3" {SubSh ...

最新文章

  1. MySQL如何判别InnoDB表是独立表空间还是共享表空间
  2. 技术人生:与其鸟宿檐下,不如击翅风雨
  3. 翻译:FireBug 1.10 新特性
  4. 客户端与服务器持续同步解析(轮询,comet,WebSocket)
  5. STL源码剖析---deque
  6. 使用Spring Roo进行快速云开发–第1部分:Google App Engine(GAE)
  7. 理科本科,无考试,读诗《宣州谢脁楼饯别校书叔云》李白
  8. 饭店计算机软件系统FIDlLIL,【万迅千里马餐饮管理系统_饭店餐厅管理软件】免费试用_餐饮软件_选软件网...
  9. C语言文件操作(文件读写)
  10. 中山医06年考研初试复试全攻略!( 完整版)
  11. 神秘美女接机刘谦 网友见证奇迹时刻:女子像舒淇
  12. python 实时监控日志文件_Python动态监控日志的内容
  13. 搞死SAP系统系列 让PO系统宕机
  14. QTP/UFT能捕捉到对象但是点击不了,录制点击也没反应
  15. 【模型分享】全网质量最高最全《王者荣耀》角色3D模型独立角色
  16. 微信分享与支付开发详解
  17. 【性能测试】Loadrunner12.55(二)-飞机订票系统-脚本录制
  18. 极路由 刷linux,极路由 刷uboot + openwrt , 以及连接校园网(netkeeper)
  19. ffmpeg mp4 mp3 wav flac webm aac ac3 ogg格式转换
  20. 中国石油大学 个人训练赛第五场C:所罗门王的宝藏(高斯消元)

热门文章

  1. BZOJ 2547(匈牙利算法-任意边的处理)
  2. Python爬虫—猫眼电影排行TOP100
  3. Qt Creator用法详解
  4. aav-php,脑洞大开 ——还在用立体定位手术操作? 新型AAV帮您跨越血脑屏障 !颤抖吧,神经外科!...
  5. Excel生成不重复id或者相同的列
  6. Funnel Activation for Visual Recognition(FReLU)
  7. Android Studio调试华为mate9 pro时Logcat不显示
  8. 9 08 | 目标客户和用户画像
  9. Filter过滤器的拦截路径配置
  10. Delphi与C++Builder代码共享的实现