cocoscreator,RenderTexture实现残影效果

效果图如下:

cocoscreator,RenderTexture实现残影效果_第1张图片

实现方法:

1.将需要产生残影的物体单独设置为一个Group;

2.新建两个sprite,设置为和残影物体相同Group,一个用于显示当前帧的残影,一个保存上一帧的残影用于摄像机渲染,修改sprite的透明度用于产生渐隐效果;

3.新建一个摄像机,摄像机位置需要与两个sprite一致(至少在渲染残影的那个时刻保持一致);

4.代码中新建两个RenderTexture,分别表示上一帧的渲染纹理(用于渲染当前帧的残影)和当前帧的渲染纹理(显示到屏幕);

5.两个RenderTexture交替作为摄像机的渲染目标。在当前帧渲染以前,把不是本次渲染目标的RenderTexture作为保存上一帧纹理的sprite的spriteFrame,然后摄像机执行渲染操作, 更新当前帧的RenderTexture;

实现思路:

保存上一帧的图像并与本帧的图像进行混合,自然就产生了残影效果。优势在于:不用修改透明度,不用动态添加节点,不关心屏幕外的物体是否产生了残影(因为只会渲染当前摄像机范围内的残影), 相当于做了屏幕后处理。缺点在于做了两次渲染,但可以通过设置group来显著减少drawcall。实测,产生残影仅使得drawcall增加了1。

代码:

const { ccclass, property } = cc._decorator;

@ccclass
export default class AfterImage extends cc.Component {
    @property(cc.Camera)
    camera: cc.Camera = null;

    //表示当前帧的RenderTexture
    @property(cc.Sprite)
    spriteNew: cc.Sprite = null;

    //表示上一帧的RenderTexture
    @property(cc.Sprite)
    spriteOld: cc.Sprite = null;

    texture1: cc.RenderTexture;
    texture2: cc.RenderTexture;

    flag: boolean = true;
    public showAfterImage = false;

    public oldX: number = 0;
    public oldY: number = 0;

    onLoad() {
        //初始化渲染纹理
        this.texture1 = new cc.RenderTexture();
        this.texture1.initWithSize(cc.winSize.width, cc.winSize.height);
        this.texture2 = new cc.RenderTexture();
        this.texture2.initWithSize(cc.winSize.width, cc.winSize.height);
    }

    addShadow() {
        //设置相机的渲染目标
        if (this.flag) {
            this.camera.targetTexture = this.texture1;
        } else {
            this.camera.targetTexture = this.texture2;
        }
        if (this.flag) {
            //当前渲染目标为t1,则上一帧的缓冲为t2
            let spriteFrame = new cc.SpriteFrame();
            spriteFrame.setTexture(this.texture2);
            //更新残影图片
            this.spriteOld.spriteFrame = spriteFrame;
        } else {
            let spriteFrame = new cc.SpriteFrame();
            spriteFrame.setTexture(this.texture1);
            this.spriteOld.spriteFrame = spriteFrame;
        }
        //如果不涉及MainCamera移动的话,下面这句可以不要。需注意spriteNew是camera的子节点
        this.spriteOld.node.setPosition(this.camera.node.getPosition());
        //将摄像机拍摄的图像渲染到渲染纹理内
        this.camera.render(this.node.parent);

        if (this.flag) {
            //当前渲染目标为t1,则将t1显示到屏幕上
            let spriteFrame = new cc.SpriteFrame();
            spriteFrame.setTexture(this.texture1);
            //更新残影图片
            this.spriteNew.spriteFrame = spriteFrame;
        } else {
            let spriteFrame = new cc.SpriteFrame();
            spriteFrame.setTexture(this.texture2);
            this.spriteNew.spriteFrame = spriteFrame;
        }
        this.flag = !this.flag;
    }

    start() {
        this.schedule(this.addShadow, 0.1, cc.macro.REPEAT_FOREVER, 0);
    }
}

打了个包

cocos版本2.0.x(2.0.1)

链接:https://pan.baidu.com/s/1rGq41knUNyOvvyISpQPYag 
提取码:wkkh 

你可能感兴趣的:(cocos,creator)