三渲二 Cocos Creator

共 4069字,需浏览 9分钟

 ·

2023-02-14 01:35

分享把3D动画输出成序列帧图片的一种方法,希望对大家有所帮助,代码工程将整理到 Cocos 论坛。

实现效果

6729bbd0b3518c09c881461e9b5a385d.webp

d7c2df73f00a1f365554d01c347f2fc2.webp

e3fdd54a5038603637f27d2e2705d10c.webp

配置环境
  • Cocos Creator 3.6.2 编辑器

  • Chrome 浏览器

实现

原理

  • 相机渲染成一张纹理

  • 读取纹理数据传给 Canvas 绘制

  • Canvas 生成纹理数据传给 HTML <a> 标签

608f0373d6e2a8fd7f0008e2fc714f34.webp

步骤

  • 将动画的模型放入场景中

  • 调整相机视角,修改相机参数
    616be64d6517749df8a34c3f51b87d81.webp

  • 引入脚本组件,填充参数
    875eb3375c080bb455e49439d06b02b2.webp

讲解视频

https://www.bilibili.com/video/BV1g8411u7Pp

工程代码

ScreenCapture.ts

面向网络编程,拼凑起来的代码,在此感谢各路神仙

    import {
_decorator, Component, log, Camera
, math, view, RenderTexture, Animation
} from 'cc';
const { ccclass, property } = _decorator;

@ccclass('ScreenCapture')
export class ScreenCapture extends Component {
@property(Camera)
camera: Camera = null!

@property(Animation)
animation: Animation = null!

@property
count = 3

start() {
log('欢迎关注微信公众号【白玉无冰】 https://mp.weixin.qq.com/s/4WwCjWBtZNnONh8hZ7JVDA')
const defaultState = this.animation.getState(this.animation.defaultClip!.name)
let count = this.count;
if (count < 2) count = 2;
defaultState.stop();
const stepTime = defaultState.duration / count;
const doAfterCap = () => {
count--;
if (count > 0) {
defaultState.update(stepTime);
this.doCapture(doAfterCap)
}
}
defaultState.update(0);
this.doCapture(doAfterCap);
}

private doCapture(doAfterCap = () => {

}) {
let vSize = new math.Size
vSize.width = view.getVisibleSize().width
vSize.height = view.getVisibleSize().height
let texture = new RenderTexture();
texture.reset(vSize);
this.camera.targetTexture = texture;
this.scheduleOnce(() => {
this.saveCapture(texture)
this.camera.targetTexture = null;
doAfterCap()
}, 0)
}

private index = 0
private timestamp = Date.now()
private saveCapture(rt: RenderTexture) {
let data: string = this.getImgBase(rt)
this.saveAs(`${this.timestamp}_${++this.index}`, data)
}

private getImgBase(texture: RenderTexture) {
const rtW = Math.floor(texture.width);
const rtH = Math.floor(texture.height);
const texPixels = new Uint8Array(rtW * rtH * 4);
let data = texture.readPixels(0, 0, rtW, rtH, texPixels)!

let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')!

canvas.width = texture.width
canvas.height = texture.height

let width = texture.width
let height = texture.height

let rowBytes = width * 4
for (let row = 0; row < height; row++) {
let srow = height - 1 - row
let imgData = ctx.createImageData(width, 1)
let start = srow * width * 4
for (let i = 0; i < rowBytes; i++) {
imgData.data[i] = data[start + i]
}
ctx.putImageData(imgData, 0, row)
}
let dataUrl = canvas.toDataURL('image/png')
console.log(dataUrl)
return dataUrl
}

private saveAs(fileName: string, data: any | string) {
var element = document.createElement('a');
if (typeof data === "string") {
element.setAttribute('href', data);
}
else {
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(data));
}

element.setAttribute('download', fileName);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
}



示例工程

capture-ccc3.6.2.zip (488.2 KB)

https://forum.cocos.org/uploads/short-url/9Q24VrBnMKyybOaKQM8SwRYtZkw.zip

文末阅读原文可下载

参考资料

  • https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement

  • https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement

  • https://developer.mozilla.org/en-US/docs/web/api/htmlelement/click

更多精彩 零代码实现面片效果(UV滚动,帧动画)  Cocos Creator
如何快速升级 Cocos Shader 版本,以简易水shader为例
游戏开发资料合集,2022年版
【3D游戏基础】蒙皮骨骼动画与骨架
让编辑器显示场景内的相机视角



点击 阅读原文”下载完整工程

“点赞“ ”在看” 鼓励一下12bd4fe310211e8129b2afa34f9f429e.webp

浏览 77
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐