文章目录

  • 先尝试GL类来制作
    • Shader
    • CSharp
      • 画个三角型
      • 画个全屏的Quad
      • 发现GL没有RenderTarget之类的
  • 使用CommandBuffer来绘制全屏的Quad
  • GL渲染到目标
  • 另外优化
  • Project
  • References

先尝试GL类来制作

Shader

// jave.lin 2020.04.12 - 绘制一个全屏的Quad
Shader "Custom/DrawFullScreenQuad" {SubShader {Pass {ZTest Always ZWrite Off Cull OffCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata {float4 vertex : POSITION;fixed4 color : COLOR;};struct v2f {float4 vertex : SV_POSITION;fixed4 color : COLOR;};v2f vert (appdata v) {v2f o;o.vertex = v.vertex;o.color = v.color;return o;}fixed4 frag (v2f i) : SV_Target { return i.color; }ENDCG}}
}

CSharp

画个三角型

        GL.PushMatrix();mat.SetPass(0);GL.LoadOrtho();GL.Begin(GL.TRIANGLE_STRIP);// 注意顶点顺序,组合为:顺时针即可,Unity 逆时针为正面GL.Color(new Color(1, 0, 0, 1));//redGL.Vertex3(0, 0, 1);GL.Color(new Color(0, 1, 0, 1));//greenGL.Vertex3(1, 0, 1);GL.Color(new Color(0, 0, 1, 1));//blueGL.Vertex3(0.5f, 0.5f, 1);GL.End();GL.Flush();

运行效果

借用我之前写的一篇:

里面有个图片要注意的是,Unity的三角面正面判定

画个全屏的Quad

    private void DrawFullScreenQuadTesting(){//var camWPos = cam.transform.position;mat.SetPass(0);GL.Begin(GL.TRIANGLE_STRIP);// 注意顶点顺序,组合为:顺时针即可,Unity 逆时针为正面GL.Color(new Color(1, 0, 0, 1));//redGL.Vertex3(-1, -1, 0);GL.Color(new Color(0, 1, 0, 1));//greenGL.Vertex3(1, -1, 0);GL.Color(new Color(0, 0, 1, 1));//blueGL.Vertex3(-1, 1, 0);GL.Color(new Color(1, 1, 0, 1));//yellowGL.Vertex3(1, 1, 0);GL.End();}

运行效果:

发现GL没有RenderTarget之类的

全屏的效果算是弄出来的,但是向要GL调用底层绘制的内容想指定一下渲染目标,结果发现没有。。。哈哈,白忙活了。。。连RenderTarget都没有。
这么说Unity GL貌似没啥用了,除了可以话一些Line来调试用。
看来要实现RT功能只能CommandBuffer或是Camera来设置RenderTarget并绘制了。
使用姿势不对,其实可以使用RenderTexture.active来设置当前渲染目标

使用CommandBuffer来绘制全屏的Quad

为何需要全屏Quad并Render到RT的功能,因为后面制作SSSM(Screen Space Shadow Map)做准备的。

CommandBuffer 相关的内容,我写过4篇,可以查看我References的。

CSharp

using UnityEngine;
using UnityEngine.Rendering;
// jave.lin 2020.04.13 - 绘制全屏Quad
public class CmdBuffDrawFullScreen : MonoBehaviour
{public Camera cam;public Material mat;[SerializeField] private RenderTexture sssmRT;private Mesh mesh;private CommandBuffer cmdBuff;private void Start(){cam.depthTextureMode |= DepthTextureMode.Depth;mesh = new Mesh();mesh.vertices = new Vector3[] {// 这里的第三个z分量最好不要在这里设置,最好在shader中判断是GL还是DX平台来设置为近截面的z值就好new Vector3(-1,1,0),    // blnew Vector3(-1,-1,0),   // tlnew Vector3(1,-1,0),    // trnew Vector3(1,1,0),     // br};mesh.uv = new Vector2[]{new Vector2(0,0),       // blnew Vector2(0,1),       // tlnew Vector2(1,1),       // trnew Vector2(1,0),       // br};mesh.triangles = new int[] {0, 1, 2,0, 2, 3};}private void OnPreRender(){if (sssmRT == null || sssmRT.width != Screen.width || sssmRT.height != Screen.height){if (sssmRT) RenderTexture.ReleaseTemporary(sssmRT);sssmRT = RenderTexture.GetTemporary(Screen.width, Screen.height, 0);//, RenderTextureFormat.R8);sssmRT.name = "sssmRT";if (cmdBuff == null){cmdBuff = new CommandBuffer();cmdBuff.name = "After Depth TEX";}cmdBuff.Clear();cmdBuff.SetRenderTarget(sssmRT);cmdBuff.ClearRenderTarget(true, true, Color.white);cmdBuff.DrawMesh(mesh, Matrix4x4.identity, mat);cam.RemoveCommandBuffer(CameraEvent.AfterDepthTexture, cmdBuff);cam.AddCommandBuffer(CameraEvent.AfterDepthTexture, cmdBuff);}}private void OnDestroy(){if (sssmRT) RenderTexture.ReleaseTemporary(sssmRT);if (cam != null && cmdBuff != null){cam.RemoveCommandBuffer(CameraEvent.AfterDepthTexture, cmdBuff);cmdBuff.Release();}}private void OnRenderImage(RenderTexture source, RenderTexture destination){Graphics.Blit(sssmRT, (RenderTexture)null);}
}

其中需要注意的地方

        mesh.vertices = new Vector3[] {// 这里的第三个z分量最好不要在这里设置,最好在shader中判断是GL还是DX平台来设置为近截面的z值就好new Vector3(-1,1,0),    // blnew Vector3(-1,-1,0),   // tlnew Vector3(1,-1,0),    // trnew Vector3(1,1,0),     // br};

留意注意:这里的第三个z分量最好不要在这里设置,最好在shader中判断是GL还是DX平台来设置为近截面的z值就好

Shader

// jave.lin
Shader "Custom/CmdBuffDrawFullScreenQuadMat" {SubShader {ZTest Always ZWrite Off Cull OffPass {CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata {float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f {float4 vertex : SV_POSITION;float2 uv : TEXCOORD0;};sampler2D _CameraDepthTexture;v2f vert (appdata v) {v2f o;// jave.lin : 在这里我们处理GL与DX的差异// GL的Z:-1~1,DX的Z:0~1#if defined (SHADER_TARGET_GLSL)v.vertex.z = -1;#elsev.vertex.z = 0;#endifo.vertex = v.vertex;o.uv = v.uv;return o;}fixed4 frag (v2f i) : SV_Target {float depth = tex2D(_CameraDepthTexture, i.uv).r;#if defined (UNITY_REVERSED_Z)depth = 1 - depth;#endifreturn depth;}ENDCG}}
}

shader的vert函数中注意这么一段:

             // CSharp层脚本的第三个z分量最好不要在这里设置// 最好在shader中判断是GL还是DX平台来设置为近截面的z值就好// jave.lin : 在这里我们处理GL与DX的差异// GL的Z:-1~1,DX的Z:0~1#if defined (SHADER_TARGET_GLSL)v.vertex.z = -1;#elsev.vertex.z = 0;#endif

运行效果

GL渲染到目标

CSharp,主要调用的是:RenderTexture.active = RT;

using UnityEngine;
// jave.lin 2020.04.22 - 绘制一个全屏的Quad
public class DrawFullScreenQuadGL_Correct : MonoBehaviour
{private static int _TestFullscreenTex_hash = Shader.PropertyToID("_TestFullscreenTex");public enum TransformType{None,       // 无,就是VS不处理任何变化,a2v的坐标当做clip space的坐标用Generic     // 一般化}public Camera cam;public TransformType transType;public Material noneTransformMat;public Material genericTransformMat;public bool drawMergeColor = true;public Material depthMergeFullscreenColorMat;private RenderTexture rt;private void Start(){cam.depthTextureMode |= DepthTextureMode.DepthNormals;}private void OnRenderObject(){if (rt == null || rt.width != Screen.width || rt.height != Screen.height){if (rt != null) RenderTexture.ReleaseTemporary(rt);rt = RenderTexture.GetTemporary(Screen.width, Screen.height, 0);}RenderTexture src = RenderTexture.active;if (drawMergeColor){RenderTexture.active = rt;}if (transType == TransformType.None) NoneTransformDraw();else GenericTransformDraw();if (drawMergeColor){RenderTexture.active = src;}}private void OnRenderImage(RenderTexture source, RenderTexture destination){if (drawMergeColor){depthMergeFullscreenColorMat.SetTexture(_TestFullscreenTex_hash, rt);Graphics.Blit(source, destination, depthMergeFullscreenColorMat);}else{Graphics.Blit(source, destination);}}private void OnDestroy(){if (rt != null) {RenderTexture.ReleaseTemporary(rt);rt = null;}}private void NoneTransformDraw(){noneTransformMat.SetPass(0);GL.Begin(GL.TRIANGLE_STRIP);// 注意顶点顺序,组合为:顺时针即可,Unity 逆时针为正面GL.Color(new Color(1, 0, 0, 1));//redGL.Vertex3(-1, -1, 0);GL.Color(new Color(0, 1, 0, 1));//greenGL.Vertex3(1, -1, 0);GL.Color(new Color(0, 0, 1, 1));//blueGL.Vertex3(-1, 1, 0);GL.Color(new Color(1, 1, 0, 1));//yellowGL.Vertex3(1, 1, 0);GL.End();}private void GenericTransformDraw(){genericTransformMat.SetPass(0);GL.PushMatrix();GL.LoadOrtho();GL.Begin(GL.QUADS);// 注意顶点顺序,组合为:顺时针即可,Unity 逆时针为正面GL.Color(new Color(1, 0, 0, 1));//redGL.Vertex3(0, 0, 0); // blGL.Color(new Color(0, 1, 0, 1));//greenGL.Vertex3(0, 1, 0); // tlGL.Color(new Color(0, 0, 1, 1));//blueGL.Vertex3(1, 1, 0); // trGL.Color(new Color(1, 1, 0, 1));//yellowGL.Vertex3(1, 0, 0); // brGL.End();GL.PopMatrix();}
}

另外优化

后期渲染我们一般的会使用4个顶点,两个三角形来绘制全屏图像。

但后来发现这部分竟然还可以优化,说是因为tile-based渲染相关。

所以可以使用一个三角形来替代一个Quad(两个三角形)的方式来优化。

引用一张图:

在 Unity Shader URP 中,可以看到:Common.hlsl 中的 GetFullScreenTriangleTexCoordGetFullScreenTriangleVertexPosition

也有类似的优化处理

// Generates a triangle in homogeneous clip space, s.t.
// v0 = (-1, -1, 1), v1 = (3, -1, 1), v2 = (-1, 3, 1).
float2 GetFullScreenTriangleTexCoord(uint vertexID)
{#if UNITY_UV_STARTS_AT_TOPreturn float2((vertexID << 1) & 2, 1.0 - (vertexID & 2));
#elsereturn float2((vertexID << 1) & 2, vertexID & 2);
#endif
}float4 GetFullScreenTriangleVertexPosition(uint vertexID, float z = UNITY_NEAR_CLIP_VALUE)
{float2 uv = float2((vertexID << 1) & 2, vertexID & 2);return float4(uv * 2.0 - 1.0, z, 1.0);
}

具体查看:用三角形代替四边形-后处理优化

Project

backup : UnityShader_RenderImageLikeTesting_2018.3.0f2

References

GL

  • GL
  • GL.Begin
  • GL.Vertex3
  • Material.SetPass

CommandBuffer相关的之前几篇:

  • Unity Graphics Command Buffers 图形指令缓存
  • Unity Shader PostProcessing - 6 - GaussianBlur 高斯模糊+CommandBuffer使用做一些其他的特效
  • Unity CommandBuffer或是Camera重定向RenderTarget的ColorBuffer & DepthBuffer
  • Unity Shader - 实现武器热扭曲拖尾效果(不需要GrabPass)

Unity Shader - 模仿RenderImage制作全屏Quad,可以制作自定义后处理的流程相关推荐

  1. uniapp 判断页面是否是横竖屏,解决微信小程序video组件全屏播放视频遮盖自定义播放控件问题

    如果res.deviceOrientation 等于landscape 的话是竖屏,portrait则是横屏.因为用户每旋转一次屏幕就会触发里面的onShow钩子,因此在页面显示或横竖屏变化都会触发这 ...

  2. Unity Shader GrabPass 抓屏幕 截屏

    Shader 抓屏 截屏 常用途径: 1.截取全屏作为截图储存 (常用). 2.截取全屏,模糊处理当作背景. 3.接入屏幕中某些指定的画面. 抓屏命令: GradPass{"Name&quo ...

  3. VB.NET在WinForm中嵌入谷歌浏览器_制作全屏显示网页程序_并读取INI配置文件_根据配置文件显示不同的网页---VB.NET工作笔记016

    我们做了个项目,科技馆的,需要把绚丽的网页,全屏放到浏览器上显示,但是....他们做的这个网页...我去,只支持谷歌这样的浏览器,在IE这样的浏览器模式下,显示有问题... 不知道是不是因为,没有使用 ...

  4. QT制作全屏播放器以及出现的问题

    使用QT做播放器使用widget::winid可以获取播放器组件的windows句柄并以命令行的方式调起另一个程序使用D3D将内存缓冲区的图像打在上面.但是在做全屏是出现了问题,如果让播放器组件自己独 ...

  5. HTML5七夕情人节表白网页制作 (全屏爱心相册) HTML+CSS+JS

    ❤ 精彩专栏推荐

  6. Unity Shader - Custom SSSM(Screen Space Shadow Map) 自定义屏幕空间阴影图

    文章目录 思路 实践 获取光源空间ShadowMap[A] 获取屏幕空间的深度图[B] 获取SSSM(Screen Space Shadow Map) 绘制一个全屏的Quad[C] 输出SSSM RT ...

  7. 一款全屏展示的流量卡官网单页模板源码

    介绍: 一款fullpage.js制作全屏展示的流量卡官网单页模板 这个是一个单页源码没有后台的,下载之后自行通过源码修改文字图片即可 具体的就不多介绍了,用的上的伙伴就下载拿走吧! 网盘下载地址: ...

  8. 全屏自适应游戏开始界面

    功能效果展示 运行环境 Win7,Win8,Win10 Reworld版本 体验版 vc_redist.x64 运行环境 针对零基础读者的补充 下载安装 Reworld对应版本 Reworld官网链接 ...

  9. 阿里巴巴卖家如何修改html,阿里巴巴店铺装修之全屏广告轮换特效代码分享及说明...

    原标题:阿里巴巴店铺装修之全屏广告轮换特效代码分享及说明 阿里巴巴店铺装修中离不开全屏轮换广告,由于阿里店铺装修原配的轮换图有点呆板,所以通过自己编写的特效代码来制作全屏轮换广告还是很有必要的. (源 ...

最新文章

  1. 关于创建zeromq消息队列,设置和更改IP地址,远程可以访问,不只是本地链接。python代码。
  2. 如何删除输入文本元素上的边框突出显示
  3. apache开启 gzip 压缩
  4. python opengl 入门
  5. python 练习题-去重排序与字符串分割
  6. 同一条sql insert 有时快有时慢 引发的血案
  7. idea 不打开文件提示错误_IDEA无法正常启动(打不开报错)
  8. 产品经理如何洞察人性?
  9. springmvc图片文件上传接口
  10. Activity生命周期方法的调用顺序project与測试日志
  11. beta阶段——项目复审
  12. pytorch梯度累积
  13. dotNET中创建自定义的配置节
  14. catia重心主惯量矩 m1_CATIA_Knowledge_Advisor_help
  15. 如何用idftp遍历整个目录----下载、删除_delphi教程
  16. RIP总结(转自鸿鹄论坛)
  17. 音频基础 - Linein和Micin的区别及使用
  18. Hive | 用sort_array函数解决collet_list列表排序混乱问题
  19. 数千 npm 账号使用域名过期的邮箱,涉及 8494 个包
  20. Android TextView带背景图片和自定义边框

热门文章

  1. 怎么爱护眼睛保护视力?补充光照的护眼台灯
  2. 使用python获取股票“净利润同比增长率”等“上市公司成长能力”数据
  3. 抓住机会,敢于尝试——第一次讲解ppt
  4. el-form表单验证身份证合法性和手机号格式
  5. P1325 雷达安装
  6. 盲人如何学计算机编程,全盲男孩自学编程,一句话打动无数网友…
  7. [转载]CodeGear RAD 2007 SP4 最新下载及破解
  8. 锐捷网络,无边光景一时新
  9. Ubuntu 20.04.3 LTS安装rabbitvcs svn图形化客户端和简单实用
  10. 天空之门手游怎么用电脑玩 天空之门手游模拟器教程