屏幕快照渲染纹理 && 高斯处理

渲染纹理资源(Render Texture)

渲染纹理是一张在 GPU 上的纹理。通常会把它设置到相机的 目标纹理 上,使相机照射的内容通过离屏的 frambuffer 绘制到该纹理上。一般用于制作汽车后视镜、动态阴影、屏幕截图(快照)、投屏(分屏)、3渲2、2渲3等功能。

案例实现

这里的案例实现是一个屏幕虚化(模糊)的效果。
实现原理/流程:
通过设置相机1的targettexture,把相机渲染的内容通过帧缓冲区保存在用于存储中间结果的texture2d中,然后创建一个输出纹理(相机2的Group)读取中间的texture2d。把输出的纹理做高斯模糊处理。

  1. 准备好相机1的内容
  2. 编写输入纹理的代码实现
import { _decorator, Camera, Component, Node, RenderTexture, Sprite, SpriteFrame, v3, view } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('TestRender')
export class TestRender extends Component {
    @property(Camera)
    main_camera:Camera = null;
    @property(Sprite)
    outSprite: Sprite = null;
    start() {
        //创建一个渲染纹理
        let rendTex = new RenderTexture();
        //读取视图尺寸并设置为渲染纹理大小
        rendTex.reset({
            width:view.getVisibleSize().width,
            height:view.getVisibleSize().height,
        });
    
        //rendTex.setWrapMode(1,1)
        //设置相机的目标纹理(把相机渲染的内容绘制到渲染纹理上)
        this.main_camera.targetTexture = rendTex;
        //创建中间纹理保存数据(一定要,否则写入和输入会陷入循环)
        let spriteFrame = new SpriteFrame();
        spriteFrame.texture = rendTex;
        //绘制到输出纹理上
        this.outSprite.spriteFrame = spriteFrame;
        //不同平台的原点不一样,根据需要决定是否反转
        this.outSprite.node.scale = v3(1,-1,1);
    }


    /**
     * 隐藏输出渲染纹理
     */
    hideOutTex(){
        this.main_camera.targetTexture = null;
        this.node.active = false;
        this.outSprite.node.active = false;
    }

    updateCapto(){
        //创建一个渲染纹理
        let rendTex = new RenderTexture();
        //读取视图尺寸并设置为渲染纹理大小
        rendTex.reset({
            width:view.getVisibleSize().width,
            height:view.getVisibleSize().height,
        });
    
        //rendTex.setWrapMode(1,1)
        //设置相机的目标纹理(把相机渲染的内容绘制到渲染纹理上)
        this.main_camera.targetTexture = rendTex;
        //创建中间纹理保存数据(一定要,否则写入和输入会陷入循环)
        let spriteFrame = new SpriteFrame();
        spriteFrame.texture = rendTex;
        //绘制到输出纹理上
        this.outSprite.spriteFrame = spriteFrame;
        //不同平台的原点不一样,根据需要决定是否反转
        this.outSprite.node.scale = v3(1,-1,1);
    }
}


  1. 创建相机2
    创建相机2的目的是把输入纹理和渲染纹理分开,如果不分开同一个相机分组下,渲染纹理在帧缓冲区的写入和输出纹理的读取循环冲突,并报一个非常经典的错误:
  [.WebGL-0000026CBBD48AA0] GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture 

创建相机2后把渲染层级放在相机1的后面,添加新的分组比如“top”
把相机2的渲染掩码设置为top,并在帧缓冲区选择只清除深度
4. 创建输出精灵
在场景中创建输出精灵,并把其渲染层级设置“top”分组
5. 添加相机和输出纹理的引用
把相机1和刚创建的输出精灵拖拽到之前创建的脚本的属性上
6. 输出纹理高斯模糊
把之间编写的高斯模糊shader挂载到输出精灵的材质上
7. 取消勾选WebGL2.0渲染
基于3.7.4的WebGL2.0渲染,编写的脚本会编译报错。
在功能裁剪中取消勾选即可。
8. 运行预览
image

链接:高斯模糊Shader

posted @ 2024-11-26 12:50  EricShx  阅读(33)  评论(0)    收藏  举报