GrabPass截屏

可以用来截屏,截屏后把纹理传给下一个通道使用。

1:使用抓屏通道, GrabPass {} 或 GrabPass { “ 纹理名称”}; 使用GrabPass {}后,可以用_GrabTexture访问截屏的纹理
2: 后续的Pass通道使用这个抓屏;
3: 编写案例
(1): 创建一个顶点片元着色器;
(2): 将这个着色器放到Overlay队列
(3): 使用GrabPass通道截屏,并定义好变量来接收
(3): 设置顶点的UV坐标;
(4): 着色使用截图的纹理

GrabPass截屏案例

1.创建好Unity工程目录

2.创建一个平面plane和一个立方体cube,给cube一个材质red,把red拖进cube的材质属性中

3.再创建一个平面show,竖起来放在旁边,等下用来显示截屏纹理

4.在resources文件夹下面创建shaders文件夹

5.打开shaders文件夹,创建一个用于顶点片元着色的shader,create---->shader---->unlit shader,重命名为GrabShader

6.打开GrabShader

第一步:先把第一行改成Shader "Custom/GrabShader",这样才能在编辑器里面显示这个shader

第二步:把渲染队列拉到最高overlay

Tags { "RenderType"="Opaque" "Queue"="Overlay" }

第三步:使用截屏通道

  1. Shader "Custom/GrabShader"
  2. {
  3. Properties
  4. {
  5. _MainTex ("Texture", 2D) = "white" {}
  6. }
  7. SubShader
  8. {
  9. Tags { "RenderType"="Opaque" "Queue"="Overlay" }//把渲染队列拉到最高overlay
  10. LOD
  11.  
  12. //
  13. GrabPass {} // 截图通道, 后面使用_GrabTexture访问截屏纹理
  14. // end
  15. Pass
  16. {
  17. name "ONE"
  18.  
  19. CGPROGRAM
  20. #pragma vertex vert
  21. #pragma fragment frag
  22.  
  23. #include "UnityCG.cginc"
  24.  
  25. struct appdata
  26. {
  27. float4 vertex : POSITION;
  28. float2 uv : TEXCOORD0;
  29. };
  30.  
  31. struct v2f
  32. {
  33. float2 uv : TEXCOORD0;
  34. UNITY_FOG_COORDS()
  35. float4 vertex : SV_POSITION;
  36. };
  37.  
  38. sampler2D _MainTex;
  39. float4 _MainTex_ST;
  40.  
  41. sampler2D _GrabTexture;//使用前重新声明一下
  42. float4 _GrabTexture_ST;
  43.  
  44. v2f vert (appdata v)
  45. {
  46. v2f o;
  47. o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
  48. o.uv = TRANSFORM_TEX(v.uv, _GrabTexture);//使用
  49. return o;
  50. }
  51.  
  52. fixed4 frag (v2f i) : SV_Target
  53. {
  54. // sample the texture
  55. fixed4 col = tex2D(_GrabTexture, i.uv);//使用
  56. return col;
  57. }
  58. ENDCG
  59. }
  60. }
  61. }

7.创建一个材质GrabShader,shader属性设置为Custom/GrabShader

8.show平面关联材质球GrabShader

9.运行起来,Game视图里面的plane视图上面显示出截屏纹理

常用的gcinc

系统自带的类似于语言里面的.h文件,是库函数,在Unity-->Edit-->Data-->CGIncludes;查看

1:cginc文件: 宏,帮助函数等,放在CGIncludes下面,开发人员可以开发自己的cginclude文件
2:常用的cginc文件:
HLSL.Support.cginc 协助多平台开发的一些宏等,自动包含
UnityShaderVarirables.cginc 全局变量,自动包含;
UnityCG.cginc 常用的帮助函数;
AutoLight.cginc 光照和阴影功能;
Lighting.cginc 表面着色器的光照模型;
TerrainEngine.cginc 地形植被的光照着色函数;

UnityCG.gcinc常用函数

1:UnityWorldSpaceViewDir: 给定对象空间的顶点位置朝向摄像机方向的世界坐标空间方向;
2: ObjSpaceViewDir: 给定对象空间的顶点位置朝向摄像机方向的对象空间方向;
3: ParallaxOffset: 计算用于视差法线贴图的UV偏移量;
4: Luminance: 将颜色转为亮度;
5: DecodeLightmap: 从光照贴图中解码颜色;
6: float EncodeFloatRGBA(float4 rgba): 将RGBA颜色编码为[0,1)的浮点数;
7: float4 DecodeFloatRGBA(float v): 将一个浮点数解码为RGBA的颜色;
8: UnityWorldSpaceLightDir 给定对象空间的顶点位置到光源的世界坐标空间方向;
9: ObjSpaceLightDir: 给定对象空间的顶点位置到光源的对象空间方向;

UsePass 复用

1:编写过的pass可以重复使用,借助UsePass “ShaderPath/PASS_NAME”
2:PASS名字要大写;
3: Pass {
name “ONE” //不要写到cgprogram里面
}
4: UsePass “Custom/ShaderName/ONE”

multi_compile多版本控制

1: 通过multi_compile编译多个版本的shader;
2: #pragma multi_compile MY_multi_1 MY_multi_2;
3: #ifdef MY_multi_1 #endif
4: Shader.EnableKeyword(“ MY_multi_1”);
5: Shader.DisableKeyword(“MY_multi_2”); 控制shader编译出不同的版本;

multi_compile多版本控制实例

1.打开shaders文件夹,创建一个用于顶点片元着色的shader,create---->shader---->unlit shader,重命名为MultiShader

2.打开MultiShader

第一步:先把第一行改成Shader "Custom/MultiShader",这样才能在编辑器里面显示这个shader

第二步:

  1. Shader "Custom/MultiShader"
  2. {
  3. Properties
  4. {
  5. _MainTex ("Texture", 2D) = "white" {}
  6. }
  7. SubShader
  8. {
  9. Tags { "RenderType"="Opaque" }
  10. LOD
  11.  
  12. Pass
  13. {
  14. CGPROGRAM
  15. #pragma vertex vert
  16. #pragma fragment frag
  17.  
  18. // 定义这个的两个开关,告诉有两个版本的shader
  19. #pragma multi_compile MY_multi_1 MY_multi_2
  20.  
  21. #include "UnityCG.cginc"
  22.  
  23. struct appdata
  24. {
  25. float4 vertex : POSITION;
  26. float2 uv : TEXCOORD0;
  27. };
  28.  
  29. struct v2f
  30. {
  31. float2 uv : TEXCOORD0;
  32. UNITY_FOG_COORDS()
  33. float4 vertex : SV_POSITION;
  34. };
  35.  
  36. sampler2D _MainTex;
  37. float4 _MainTex_ST;
  38.  
  39. v2f vert (appdata v)
  40. {
  41. v2f o;
  42. o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
  43. o.uv = TRANSFORM_TEX(v.uv, _MainTex);
  44. return o;
  45. }
  46.  
  47. fixed4 frag (v2f i) : SV_Target
  48. {
  49. fixed4 col;
  50. // sample the texture
  51. #ifdef MY_multi_1//版本1
  52. col = fixed4(1.0, 0.0, 0.0, 1.0);
  53. #endif
  54.  
  55. #ifdef MY_multi_2//版本2
  56. col = fixed4(0.0, 0.0, 1.0, 1.0);
  57. #endif
  58.  
  59. return col;
  60. }
  61. ENDCG
  62. }
  63. }
  64. }

3.创建一个材质MultiShader,设置它的shader属性为Custom/MultiShader

4.创建一个立方体cube,把材质MultiShader拖进cube

5.创建一个脚本MultiShader,挂载在立方体cube下面

打开MultiShader.cs

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class MulShader : MonoBehaviour {
  5.  
  6. // Use this for initialization
  7. void Start () {
  8. Shader.EnableKeyword("MY_multi_2");//打开版本2
  9. Shader.DisableKeyword("MY_multi_1");//关闭版本1
  10. }
  11.  
  12. // Update is called once per frame
  13. void Update () {
  14.  
  15. }
  16. }

移动平台优化

1: 代码优化:
预先计算好对应的值 sqrt(2) --> 根号2 --> 1.414..;
放心的使用向量相关操作,叉积,点击,基本都是硬件实现,很高效;
尽量减少函数调用减少开销;
2: 尽可能的计算放在顶点着色器中,顶点着色器的调用频率远低于片着色器;
3: 几何复杂度考量:在IOS平台视口内的顶点数不要超过100K个,IOS默认的缓冲区就是就是这么大,超过这个数字,底层会做一些操作消耗更多的资源;
4: 纹理大小为 2^n次方大小, 16, 64, 128, 256, 512, 1024;
5: 使用适当的数据类型float < half < fixed; 性能
6: 尽量慎用透明效果,透明效果GPU要逐像素渲染,而且没有了遮挡剔除的效果,会用到Blend SrcAlpha OneMinusSrcAlpha//SrcAlpha是源因子,OneMinusSrcAlpha是目标因子,产生的各个颜色和各个因子相乘,然后两个颜色相加

关于Unity中GrabPass截屏的使用和Shader的组织优化的更多相关文章

  1. iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏)

    iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏) 2017.03.16 12:18* 字数 52 阅读 563评论 4喜欢 2 1. 截取屏幕尺寸大小的图片并保存至相册 ...

  2. js利用clipboardData在网页中实现截屏粘贴的功能

    目前仅有高版本的 Chrome 浏览器支持这样直接粘贴,其他浏览器目前为止还无法粘贴,不过火狐和ie11浏览器在可编辑的div中能够粘贴截图的图片也是base64位和Chrome利用clipboard ...

  3. Unity中Oculus分屏相机和普通相机一键切换

    Unity中Oculus分屏相机和普通相机一键切换 一.OCulus 分屏相机介绍 在VR开发工程中,总会觉得OC分屏的处理太慢,严重浪费时间啊! 但是不使用有不好调试,来回切换相机就成为了一个必须. ...

  4. 利用 clipboardData 在网页中实现截屏粘贴的功能

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  5. iOS 中捕获截屏操作

    转自:iOS知识小集 在iOS 7后,苹果提供了UIApplicationUserDidTakeScreenshotNotification通知来告诉App用户做了截屏操作.苹果的描述如下: // T ...

  6. Unity三种截屏方法(非自带API)

    者利用了三种表现形式: 1,选择截图路径的方法 2,直接截取截屏的方法 3,截取鼠标圈选区域. 上代码,: 第一种是调用.net的类库,需要引用System.Windows.Forms.dll,在As ...

  7. react-native项目中禁止截屏与录屏

    在android/app/src/main/java/com/projname/MainActivity.java文件中的onCreate方法添加一下代码即可 import android.view. ...

  8. Unity中调用Windows窗口句柄以及根据需求设置并且解决扩展屏窗体显示错乱/位置错误的Bug

    问题背景: 现在在搞PC端应用开发,我们开发中需要调用系统的窗口以及需要最大化最小化,缩放窗口拖拽窗口,以及设置窗口位置,去边框等功能 解决根据: 使用user32.dll解决 具体功能: Unity ...

  9. 纯C#实现屏幕指定区域截屏

    以前在别的地方见过一个通过调用系统API实现屏幕截图的例子,从内心来说我不太喜欢在C#代码中出现这种情况,现在什么都讲“和谐”,我觉得这种做法就是破坏了我们的“和谐”代码,呵呵,开玩笑,有的时候,不通 ...

随机推荐

  1. 机器学习 之 SVM VC维度、样本数目与经验风险最小化的关系

    VC维在有限的训练样本情况下,当样本数 n 固定时.此时学习机器的 VC 维越高学习机器的复杂性越高. VC 维反映了函数集的学习能力,VC 维越大则学习机器越复杂(容量越大). 所谓的结构风险最小化 ...

  2. STL学习笔记— —无序容器(Unordered Container)

    简单介绍 在头文件<unordered_set>和<unordered_map> 中定义 namespace std { template <typename T, ty ...

  3. analysis-what-blockchain-technology-means-for-artificial-intelligence-cm888540

    http://m.nasdaq.com/article/analysis-what-blockchain-technology-means-for-artificial-intelligence-cm ...

  4. android 调用系统相机拍照 获取原图

      好吧,为了这个问题又折腾了一整天.之前在网上找来的方法,如果在onActivityResult中直接用data.getData()的方式来生成bitmap,其实获取的是拍照生成的缩略图!看看尺寸就 ...

  5. Ubuntu访问Windows共享目录

    你可以选择目录挂载的形式,也可以选择直接使用图形界面的形式. 下面直接在文件浏览器中打开windows共享目录. 1 安装samba sudo apt-get install samba 2 打开一个 ...

  6. FIS-PLUS百度前端框架使用过程

    1.如果后端开发语言是php,那么前端fis框架用FIS-PLUS,如果是java则用jello 2.FIS-PLUS使用步骤 1.安装nodejs 2.安装 fis npm install -g f ...

  7. js弹出层的插件

    1.jquery.fancybox.pack.js 2.artdialog 3.

  8. 一个有趣的python排序模块:bisect

    今天同事说到了一个python的排序模块bisect,觉得挺有趣的,跟大家分享分享. 先看看模块的结构: 前面五个属性大家感兴趣可以打出来看看数值,这里就不介绍了. 先说明的是,使用这个模块的函数前先 ...

  9. JAVA-JSP内置对象之request获得参数的参数值(一个值)

    相关资料:<21天学通Java Web开发> 获得参数的参数值(一个值) RequestForm3.jsp <%@ page language="java" co ...

  10. Sqlserver 2008 error 40出现连接错误的解决方法

    说明(2017-5-25 15:00:16): 核心:把端口号改成1433 Sqlserver 2008 error 40出现连接错误的解决方法