关于Unity中GrabPass截屏的使用和Shader的组织优化
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" }
第三步:使用截屏通道
Shader "Custom/GrabShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Overlay" }//把渲染队列拉到最高overlay
LOD //
GrabPass {} // 截图通道, 后面使用_GrabTexture访问截屏纹理
// end
Pass
{
name "ONE" CGPROGRAM
#pragma vertex vert
#pragma fragment frag #include "UnityCG.cginc" struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
}; struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS()
float4 vertex : SV_POSITION;
}; sampler2D _MainTex;
float4 _MainTex_ST; sampler2D _GrabTexture;//使用前重新声明一下
float4 _GrabTexture_ST; v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _GrabTexture);//使用
return o;
} fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_GrabTexture, i.uv);//使用
return col;
}
ENDCG
}
}
}
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
第二步:
Shader "Custom/MultiShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag // 定义这个的两个开关,告诉有两个版本的shader
#pragma multi_compile MY_multi_1 MY_multi_2 #include "UnityCG.cginc" struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
}; struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS()
float4 vertex : SV_POSITION;
}; sampler2D _MainTex;
float4 _MainTex_ST; v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
} fixed4 frag (v2f i) : SV_Target
{
fixed4 col;
// sample the texture
#ifdef MY_multi_1//版本1
col = fixed4(1.0, 0.0, 0.0, 1.0);
#endif #ifdef MY_multi_2//版本2
col = fixed4(0.0, 0.0, 1.0, 1.0);
#endif return col;
}
ENDCG
}
}
}
3.创建一个材质MultiShader,设置它的shader属性为Custom/MultiShader
4.创建一个立方体cube,把材质MultiShader拖进cube
5.创建一个脚本MultiShader,挂载在立方体cube下面
打开MultiShader.cs
using UnityEngine;
using System.Collections; public class MulShader : MonoBehaviour { // Use this for initialization
void Start () {
Shader.EnableKeyword("MY_multi_2");//打开版本2
Shader.DisableKeyword("MY_multi_1");//关闭版本1
} // Update is called once per frame
void Update () { }
}
移动平台优化
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的组织优化的更多相关文章
- iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏)
iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏) 2017.03.16 12:18* 字数 52 阅读 563评论 4喜欢 2 1. 截取屏幕尺寸大小的图片并保存至相册 ...
- js利用clipboardData在网页中实现截屏粘贴的功能
目前仅有高版本的 Chrome 浏览器支持这样直接粘贴,其他浏览器目前为止还无法粘贴,不过火狐和ie11浏览器在可编辑的div中能够粘贴截图的图片也是base64位和Chrome利用clipboard ...
- Unity中Oculus分屏相机和普通相机一键切换
Unity中Oculus分屏相机和普通相机一键切换 一.OCulus 分屏相机介绍 在VR开发工程中,总会觉得OC分屏的处理太慢,严重浪费时间啊! 但是不使用有不好调试,来回切换相机就成为了一个必须. ...
- 利用 clipboardData 在网页中实现截屏粘贴的功能
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- iOS 中捕获截屏操作
转自:iOS知识小集 在iOS 7后,苹果提供了UIApplicationUserDidTakeScreenshotNotification通知来告诉App用户做了截屏操作.苹果的描述如下: // T ...
- Unity三种截屏方法(非自带API)
者利用了三种表现形式: 1,选择截图路径的方法 2,直接截取截屏的方法 3,截取鼠标圈选区域. 上代码,: 第一种是调用.net的类库,需要引用System.Windows.Forms.dll,在As ...
- react-native项目中禁止截屏与录屏
在android/app/src/main/java/com/projname/MainActivity.java文件中的onCreate方法添加一下代码即可 import android.view. ...
- Unity中调用Windows窗口句柄以及根据需求设置并且解决扩展屏窗体显示错乱/位置错误的Bug
问题背景: 现在在搞PC端应用开发,我们开发中需要调用系统的窗口以及需要最大化最小化,缩放窗口拖拽窗口,以及设置窗口位置,去边框等功能 解决根据: 使用user32.dll解决 具体功能: Unity ...
- 纯C#实现屏幕指定区域截屏
以前在别的地方见过一个通过调用系统API实现屏幕截图的例子,从内心来说我不太喜欢在C#代码中出现这种情况,现在什么都讲“和谐”,我觉得这种做法就是破坏了我们的“和谐”代码,呵呵,开玩笑,有的时候,不通 ...
随机推荐
- Atitit 切入一个领域的方法总结 attilax这里,机器学习为例子
Atitit 切入一个领域的方法总结 attilax这里,机器学习为例子 1.1. 何为机器学习?1 1.2. 两类机器学习算法 :监督式学习(Supervised Learning)和非监督式学习( ...
- spring(三) spring事务操作
前面一篇博文讲解了什么是AOP.学会了写AOP的实现,但是并没有实际运用起来,这一篇博文就算是对AOP技术应用的进阶把,重点是事务的处理. --wh 一.jdbcTemplate 什么是JdbcTem ...
- 真机提示Undefinedsymbolsforarchitecturearm64
转自:http://www.haodaima.net/art/2830860 iOS程序模拟器手机运行都正常,archiving出错:Undefined symbols for architectur ...
- bug ,improvements, features jira等信息
https://issues.apache.org/jira/secure/ReleaseNote.jspa?version=12341764&projectId=12315522 https ...
- Python 3.6 安装pip
1.首先python3.4以后,pip内嵌,不过使用方法是: python -m pip install django 2.如果你觉得上面的指令太长,想用旧方法使用pip,那用以下指令安装pip即可 ...
- App store 应用审核由于 IPv6 网络问题被拒的一点分析
App store 应用审核由于 IPv6 网络问题被拒的一点分析 六月以后陆续有一些软件提交市场的时候被拒了,症状基本就是无法登陆啥的.我们公司的应用也未能幸免. 很多同学也想了不少办法,申诉. ...
- 【C/C++】一道试题,深入理解数组和指针
在x86平台下分析下面的代码输出结果 int main(void) { ] = {, , , }; ); ); printf(], *ptr2); ; } &a+1 首先明确,a是一个具有4个 ...
- Netty高性能之Reactor线程模型
Netty是一个高性能.异步事件驱动的NIO框架,它提供了对TCP.UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用 ...
- Python写入连接mysql失败
执行如下连接数据库的语句: engine = create_engine('mysql://root:root@127.0.0.1/stock?charset=utf8') 报错如下: ImportE ...
- 初步理解Python进程的信号通讯
Reference: http://www.jb51.net/article/63787.htm 信号的概念 信号(signal)-- 进程之间通讯的方式,是一种软件中断.一个进程一旦接收到信 ...