三渲二 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

浏览 64
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报