日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

Blender渲染App最佳實踐

說明

本篇主要是介紹如何將渲染軟件 Blender 創建成 BatchCompute 的 App,并通過此 App 提交 Blender 渲染作業。 Blender 是目前最流行的一款開源的跨平臺全能三維動畫制作軟件,提供從建模、動畫、材質、渲染、到音頻處理、視頻剪輯等一系列動畫短片制作解決方案。 具體介紹可以看這里:https://www.blender.org/features/。

1. 準備工作

(1) 開通服務

如果已經開通,請忽略此步驟。

(2) 地域的選擇

本篇例子所有阿里云服務都需要使用相同的地域。 

本篇例子使用地域: 華南1(深圳)

(3) 準備OSS Bucket

本篇例子假設創建的 bucket 名稱為:blender-demo,  地域在華南1(深圳)。 

說明

注意:使用批量計算時,地域需要和 OSS bucket 的地域相同。 注意:實際操作時,需要將例子中的bucket 名稱修改為您自己創建的真實的bucket名稱。

2. 制作 Blender Docker 鏡像

(1) 創建一個Dockerfile文件

文件名:Dockerfile, 內容如下:

FROM ubuntu:latest

MAINTAINER your-name<your-email>

# 更新源
RUN apt update

# 清除緩存
RUN apt autoclean

# 安裝
RUN apt install python python-pip curl pulseaudio blender -y

# 啟動時運行這個命令
CMD ["/bin/bash"]

(2) build

docker build -t ubuntu-blender ./

等待完成,然后使用下面的命令查看是否有 ubuntu-blender

docker images

(3) check

docker run -t ubuntu-blender blender -v

顯示:

Blender 2.79 (sub 0)

記住此版本信息,下面要用到。

3. Docker鏡像上傳

您需要將 ubuntu-blender 上傳到 BatchCompute 支持Registry。

BatchCompute支持2種Registry:阿里云的 CR(Container Registry)和阿里云的OSS。

選擇一種即可,推薦第一種: CR。

如何上傳,請參考以下文檔:

Docker鏡像上傳到CR

Docker鏡像上傳到OSS

假設已經上傳到CR(地域:華南1-深圳),名稱為:registry.cn-shenzhen.aliyuncs.com/batchcompute_test/blender:1.0

4. 創建 App

說明

BatchCompute 提交作業,需要配置很多參數。BatchCompute 提供的 App 模板機制,讓用戶很方便預設參數默認值,提交作業時,只需填寫少量參數即可。

下面我們來創建一個 Blender 渲染 App。

(1) 開始創建 App

打開批量計算控制臺:https://batchcompute.console.aliyun.com

1

填寫基本信息

Docker 鏡像名稱,填寫您已經上傳到CR的鏡像名稱,如:registry.cn-shenzhen.aliyuncs.com/batchcompute_test/blender:1.0

2

運行時參數

只需修改實例類型為8核16GB規格,其他的默認即可。

3

(2) 命令行和參數配置

4

命令行填寫:

python -c "import os;import sys;sys.path.append('/home/scripts/'); from framer import parseFrames; frames=parseFrames('${frames}'); framestr=','.join(map(lambda x:str(x), frames)); s='blender -b /home/input/${scene_file_path} -o /home/output/result/${output_name_format} -F ${format} -f %s' % framestr; print('exec: %s' % s); os.system(s);"
  • ${..} 都是變量,可以作為輸入和輸出參數。在使用此App提交作業的時候,傳入的參數將替換掉這些變量。

  • 參考文檔 Blender 2.79 命令行參數

輸入參數

說明

注意:實際操作時,需要將例子中的bucket 名稱修改為您自己創建的真實的bucket名稱。

名稱

默認值

允許覆蓋

本地目錄絕對路徑

備注

scripts_oss_folder

oss://blender-demo/scripts/

/home/scripts/

輸入OSS目錄路徑,該路徑將掛載到虛擬機的/home/scripts/,應該包含要渲染的 framer.py 文件, 如:oss://bucket/scripts/

input_oss_folder

/home/input/

輸入OSS目錄路徑,該路徑將掛載到虛擬機的/home/input/,應該包含要渲染的.blend文件,如:oss://bucket/input/

scene_file_path

渲染場景文件的路徑,相對于input_oss_folder的目錄路徑, 如:a.blend或者 folder_name/a.blend

frames

支持連續幀:”1-10”, 支持多幀(逗號隔開,無空格):”1,3,5-10”

format

PNG

渲染輸出格式,支持:TGA,RAWTGA,JPEG,IRIS,IRIZ,AVIRAW,AVIJPEG,PNG,BMP

output_name_format

####.png

輸出文件名,#會被替代為幀序號,不足位補零。舉例:test_###.png變成 test_001.png,可以在前面加目錄名:test/test_###.png

輸出參數

名稱

默認值

允許覆蓋

本地目錄絕對路徑

備注

output_oss_folder

/home/output/

輸出OSS目錄路徑, 如:oss://bucket/output/

環境變量

環境變量可以不用配置, 直接提交即可。

4. 提交渲染作業

在App列表中可以看到已經創建好的 ubuntu-blender, 點擊”提交作業”。

5

(1) 準備工作

在提交作業前,還有一些準備工作。

手動上傳分幀器

分幀器python代碼(見附錄),上傳到您的OSS目錄下,比如:oss://blender-demo/scripts/framer.py

手動上傳blender場景文件

Blender 官網提供了好多 demo 文件: https://www.blender.org/download/demo-files/

本例子需要下載 2.79 版本(注意:要和鏡像中安裝的Blender版本相同。不同版本的可能渲染不出來)

6

素材下載后,解壓得到目錄: splash279/將整個目錄上傳到 oss://blender-demo/input/下面,即:oss://blender-demo/input/splash279/

(2) 開始提交作業

7

  • 實例類型要選大一點的,比如: 8核16GB。

  • 實例數量本例子填 2 個。

(3) 參數配置

說明

注意:實際操作時,需要將例子中的 bucket 名稱修改為您自己創建的真實的bucket名稱。

image

輸入:

參數

說明

input_oss_folder

oss://blender-demo/input/

場景文件所在OSS目錄

scene_file_path

splash279/splash279.blend

場景文件名

frames

1-4

渲染1到4幀

format

PNG

渲染輸出格式,默認即可

output_name_format

####.png

渲染輸出文件名,默認即可

  • scripts_oss_folder 設置了默認值,且不允許覆蓋,可以不用填。

輸出:

參數

說明

input_oss_folder

oss://blender-demo/output/

輸出OSS目錄, 渲染結果圖片將保存到此目錄的 result/子目錄下

Loggin(日志目錄配置):

參數

說明

StdoutPath

oss://blender-demo/log/

stdout日志輸出到此

StderrPath

oss://blender-demo/log/

stderr日志輸出到此

填好后點擊提交即可。

5. 查看作業狀態和結果

(1) 查看作業狀態

image

(2) 查看結果

oss://blender-demo/output/result/

image

(3) 渲染時長和實例規格參考

實例規格

節點數

渲染幀數

時長

ecs.sn1ne.2xlarge(8核16GB)

2

1-4

9-12分鐘

ecs.sn1ne.4xlarge (16核/32GB)

2

1-4

4-6分鐘

6. 附錄

分幀器代碼(python):

framer.py:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os
import math
import sys
import re

NOTHING_TO_DO = 'Nothing to do, exit'

def _calcRange(a,b, id, step):
  start = min(id * step + a, b)
  end  = min((id+1) * step + a-1, b)
  return (start, end)

def _parseContinuedFrames(render_frames, total_nodes, id=None, return_type='list'):
  '''
  解析連續幀, 如:1-10
  '''
  [a,b]=render_frames.split('-')
  a=int(a)
  b=int(b)
  #print(a,b)
  step = int(math.ceil((b-a+1)*1.0/total_nodes))

  #print('step:', step) 
  mod =  (b-a+1) % total_nodes
  #print('mod:', mod)

  if mod==0 or id < mod:
    (start, end) = _calcRange(a,b, id, step)
    #print('--->',start, end)
    return (start, end) if return_type!='list' else range(start, end+1)
  else:
    a1 =  step * mod + a
    #print('less', a1, b, id)
    (start, end) = _calcRange(a1 ,b, id-mod, step-1)

    #print('--->',start, end)
    return (start, end)  if return_type!='list' else range(start, end+1)

def _parseIntermittentFrames(render_frames, total_nodes, id=None):
  '''
  解析不連續幀, 如:1,3,8-10,21
  '''
  a1=render_frames.split(',')
  a2=[]
  for n in a1:
    a=n.split('-')
    a2.append(range(int(a[0]),int(a[1])+1) if len(a)==2 else [int(a[0])])

  a3=[]
  for n in a2: 
    a3=a3+n
  #print('a3',a3)

  step = int(math.ceil(len(a3)*1.0/total_nodes))
  #print('step',step)

  mod =  len(a3) % total_nodes
  #print('mod:', mod)

  if mod==0 or id < mod:
    (start, end) = _calcRange(0, len(a3)-1, id, step) 
    #print(start, end)
    a4= a3[start: end+1] 
    #print('--->', a4)
    return a4
  else:
    #print('less',  step * mod  , len(a3)-1, id)
    (start, end) = _calcRange( step * mod   ,len(a3)-1, id-mod, step-1)
    if start > len(a3)-1:
      print(NOTHING_TO_DO)
      sys.exit(0)
    #print(start, end)
    a4= a3[start: end+1] 
    #print('--->', a4)
    return a4


def parseFrames(render_frames, return_type='list', id=None, total_nodes=None):
  '''
  @param render_frames {string}:  需要渲染的總幀數列表范圍,可以用"-"表示范圍,不連續的幀可以使用","隔開, 如: 1,3,5-10 
  @param return_type {string}:  取值范圍[list,range]。 list樣例: [1,2,3], range樣例: (1,3)。 
         注意: render_frames包含","時有效,強制為list。
  @param id, 節點ID,從0開始。 正式環境不要填寫,將從環境變量 BATCH_COMPUTE_DAG_INSTANCE_ID 中取得。
  @param total_nodes, 總共的節點個數。正式環境不要填寫,將從環境變量 BATCH_COMPUTE_DAG_INSTANCE_COUNT 中取得。
  '''

  if id==None:
    id=os.environ['BATCH_COMPUTE_DAG_INSTANCE_ID']
  if type(id)==str:
    id = int(id)

  if total_nodes==None:
    total_nodes = os.environ['BATCH_COMPUTE_DAG_INSTANCE_COUNT']
  if type(total_nodes)==str:
    total_nodes = int(total_nodes)

  if re.match(r'^(\d+)\-(\d+)$',render_frames):
    # 1-2
    # continued frames
    return _parseContinuedFrames(render_frames, total_nodes, id, return_type)

  else:
    # intermittent frames
    return _parseIntermittentFrames(render_frames, total_nodes, id)