Skip to content

Latest commit

 

History

History
424 lines (331 loc) · 11.7 KB

656-2705095-输出当前帧号_当前时间_关键帧_初始化场景.sy.md

File metadata and controls

424 lines (331 loc) · 11.7 KB
show version enable_checker
step
1.0
true

python_blender

开始

  • 上次 我们
    • 设置了 关键帧
    • 制作了 动画
    • 并且渲染出了 动画序列
  • 我们可以设置变化的灯光吗?🤔

图片描述

深入关键帧变化

  • 执行代码后
    • 在场景中播放
import bpy
import datetime

def handler(scene):
    print(datetime.datetime.now())

bpy.ops.object.select_all(action="SELECT") 
bpy.ops.object.delete() 
bpy.app.handlers.frame_change_pre.clear()
bpy.app.handlers.frame_change_pre.append(handler)
  • 选中Layout工作区

    • 将时间轴播放头选中第6帧
    • 观察终端里面的变化
  • 每次 在进入 新帧之前

    • 会在console中
    • 输出当前时间

图片描述

  • 可以输出当前帧号吗?

输出帧号

import bpy

def handler(scene):
    current_frame = bpy.context.scene.frame_current
    print("frame:", current_frame)

bpy.app.handlers.frame_change_pre.clear()
bpy.app.handlers.frame_change_pre.append(handler)
print(bpy.app.handlers.frame_change_pre)
  • 运行脚本
    • 播放场景

图片描述

  • 可以把帧号放到场景里吗?

从场景输出帧号

import bpy

def handler(scene):
    current = bpy.context.scene.frame_current
    bpy.data.objects["Text"].data.body = "Frame:" + str(current)

bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
bpy.ops.object.text_add()
bpy.app.handlers.frame_change_pre.clear()
bpy.app.handlers.frame_change_pre.append(handler)
print(bpy.app.handlers.frame_change_pre)
  • 播放场景后
    • 每一帧都可以输出到场景中

图片描述

  • 想要根据这个帧号
    • 移动方块 有可能吗?

按帧号移动

import bpy

def handler(scene):
    current = bpy.context.scene.frame_current
    bpy.data.objects["Icosphere"].location[1] = -0.2*current
    bpy.data.objects["Text"].data.body = "Frame:" + str(current)

bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
bpy.ops.object.text_add()
bpy.ops.mesh.primitive_ico_sphere_add()
bpy.app.handlers.frame_change_pre.clear()
bpy.app.handlers.frame_change_pre.append(handler)
  • 效果
    • 一去不复返

图片描述

  • 可以 来回 移动 吗?

来回移动

import bpy

def frame_handler(scene):
    current = bpy.context.scene.frame_current
    temp = current % 20
    if temp < 10:
        distance = -0.2 * temp
        bpy.data.objects["Icosphere"].location[1] = -0.2*temp
    else:
        distance = 0.2 * (temp - 10) - 2
        bpy.data.objects["Icosphere"].location[1] = distance
    str_dis = "{:.1f}".format(distance)
    bpy.data.objects["Text"].data.body = "Frame:" + str(current) + "\n"\
                                       + "Dis:" + str_dis

def init():
    bpy.ops.object.select_all(action="SELECT")
    bpy.ops.object.delete()
    bpy.ops.object.text_add()
    bpy.context.object.location[1] = 2
    bpy.ops.mesh.primitive_ico_sphere_add()
    bpy.app.handlers.frame_change_pre.clear()
    bpy.app.handlers.frame_change_pre.append(frame_handler)

init()
  • 切到layout工作区
    • 播放观察效果

图片描述

  • 可以直接渲染出来吗?

直接渲染

import bpy

def frame_handler(scene):
    current = bpy.context.scene.frame_current
    temp = current % 20
    if temp < 10:
        distance = -0.2 * temp
        bpy.data.objects["Icosphere"].location[1] = -0.2*temp
    else:
        distance = 0.2 * (temp - 10) - 2
        bpy.data.objects["Icosphere"].location[1] = distance
    str_dis = "{:.1f}".format(distance)
    bpy.data.objects["Text"].data.body = "Frame:" + str(current) + "\n"\
                                       + "Dis:" + str_dis

def init():
    bpy.ops.object.select_all(action="SELECT")
    bpy.ops.object.delete()
    bpy.ops.object.text_add()
    bpy.context.object.location[1] = 2
    bpy.ops.mesh.primitive_ico_sphere_add()
    camera = bpy.data.cameras.new('Camera')
    camera_obj = bpy.data.objects.new('Camera', camera)
    bpy.data.collections["Collection"].objects.link(camera_obj)
    camera.lens = 50  # Focal length in millimeters
    camera.sensor_width = 36  # Sensor width in millimeters
    camera.sensor_height = 24  # Sensor height in millimeters
    camera_obj.location = (0,-5,40)  # X, Y, Z coordinates
    camera_obj.rotation_euler = (0,0,0)
    bpy.context.scene.camera = camera_obj
    bpy.app.handlers.frame_change_pre.clear()
    bpy.app.handlers.frame_change_pre.append(frame_handler)

def render():
    bpy.context.scene.frame_end = 20
    bpy.context.scene.render.resolution_x = 200
    bpy.context.scene.render.resolution_y = 150
    bpy.context.scene.render.engine = 'CYCLES'
    bpy.context.scene.render.filepath = "/home/shiyanlou/Code/o"
    bpy.ops.render.render(animation=True)

init()
render()
  • 用feh观察动画效果

图片描述

  • 准备加
    • 一盏灯
    • 摄影机
    • 背景板

代码


def frame_handler(scene):
    current = bpy.context.scene.frame_current
    temp = current % 20
    if temp < 10:
        distance = -0.2 * temp
        bpy.data.objects["Icosphere"].location[1] = -0.2*temp
    else:
        distance = 0.2 * (temp - 10) - 2
        bpy.data.objects["Icosphere"].location[1] = distance
    str_dis = "{:.1f}".format(distance)
    bpy.data.objects["Text"].data.body = "Frame:" + str(current) + "\n"\
                                       + "Dis:" + str_dis

def init():
    bpy.ops.object.select_all(action="SELECT")
    bpy.ops.object.delete()

    bpy.ops.object.text_add()
    bpy.context.object.data.size = 4
    mat = bpy.data.materials.new('mat_text')
    color = (0, 0, 0, 1)
    mat.diffuse_color = color
    bpy.context.object.data.materials.append(mat)

    bpy.ops.mesh.primitive_plane_add(size=20)
    mat = bpy.data.materials.new('mat_plane')
    color = (0, 1, 0, 1)
    mat.diffuse_color = color
    bpy.context.object.data.materials.append(mat)
    bpy.context.object.location = (0,0,-0.5)
    bpy.context.object.scale = (10,10,1)

    bpy.ops.mesh.primitive_ico_sphere_add()
    mat = bpy.data.materials.new('mat_text')
    color = (1, 0, 0, 1)
    mat.diffuse_color = color
    bpy.context.object.data.materials.append(mat)
    bpy.context.object.location = (0,10,0)

    bpy.ops.object.light_add(type='SPOT', radius=1)
    bpy.context.object.data.energy = 20000
    bpy.context.object.location = (0,0,35)

    camera = bpy.data.cameras.new('Camera')
    camera_obj = bpy.data.objects.new('Camera', camera)
    bpy.data.collections["Collection"].objects.link(camera_obj)
    camera.lens = 50  # Focal length in millimeters
    camera.sensor_width = 36  # Sensor width in millimeters
    camera.sensor_height = 24  # Sensor height in millimeters
    camera_obj.location = (0,-5,40)  # X, Y, Z coordinates
    camera_obj.rotation_euler = (0,0,0)
    bpy.context.scene.camera = camera_obj
    bpy.app.handlers.frame_change_pre.clear()
    bpy.app.handlers.frame_change_pre.append(frame_handler)

def render():
    bpy.context.scene.frame_end = 20
    bpy.context.scene.render.resolution_x = 200
    bpy.context.scene.render.resolution_y = 150
    bpy.context.scene.render.engine = 'CYCLES'
    bpy.context.scene.render.filepath = "/tmp/o"
    bpy.ops.render.render(animation=True)

init()
render()
  • 播放效果

图片描述

  • 这种每帧设置具体参数的方式
  • 和设置开始、结束关键帧的方式
  • 有什么区别吗?

对比参照

import bpy

def frame_handler(scene):
    current = bpy.context.scene.frame_current
    distance = - current
    bpy.data.objects["red_ball"].location[1] = distance
    str_dis = "{:.2f}".format(distance)
    bpy.data.objects["red_text"].data.body = "Frm:" + str(current) + "\n"\
                                       + "Dis:" + str_dis
    str_dis = "{:.2f}".format(bpy.data.objects["blue_ball"].location[1])
    bpy.data.objects["blue_text"].data.body = "Frm:" + str(current) + "\n"\
                                       + "Dis:" + str_dis

def init():
    bpy.ops.object.select_all(action="SELECT")
    bpy.ops.object.delete()

    bpy.ops.object.text_add()
    bpy.context.object.data.size = 3
    bpy.context.object.name = "red_text"
    mat = bpy.data.materials.new('red_text')
    color = (0.5, 0, 0, 1)
    mat.diffuse_color = color
    bpy.context.object.data.materials.append(mat)

    bpy.ops.mesh.primitive_plane_add(size=20)
    mat = bpy.data.materials.new('mat_plane')
    color = (0, 1, 0, 1)
    mat.diffuse_color = color
    bpy.context.object.data.materials.append(mat)
    bpy.context.object.location = (0,0,-0.5)
    bpy.context.object.scale = (10,10,1)

    bpy.ops.mesh.primitive_ico_sphere_add()
    bpy.context.object.name = "red_ball"
    mat = bpy.data.materials.new('mat_red')
    color = (1, 0, 0, 1)
    mat.diffuse_color = color
    bpy.context.object.data.materials.append(mat)
    bpy.context.object.location = (3,10,0)

    bpy.ops.object.light_add(type='SPOT', radius=1)
    bpy.context.object.data.energy = 20000
    bpy.context.object.location = (0,0,35)

    camera = bpy.data.cameras.new('Camera')
    camera_obj = bpy.data.objects.new('Camera', camera)
    bpy.data.collections["Collection"].objects.link(camera_obj)
    camera.lens = 50  # Focal length in millimeters
    camera.sensor_width = 36  # Sensor width in millimeters
    camera.sensor_height = 24  # Sensor height in millimeters
    camera_obj.location = (0,-5,40)  # X, Y, Z coordinates
    camera_obj.rotation_euler = (0,0,0)
    bpy.context.scene.camera = camera_obj
    bpy.app.handlers.frame_change_pre.clear()
    bpy.app.handlers.frame_change_pre.append(frame_handler)
    
    bpy.ops.mesh.primitive_ico_sphere_add()
    mat = bpy.data.materials.new('mat_text')
    color = (0, 0, 1, 1)
    mat.diffuse_color = color
    obj = bpy.context.object
    obj.data.materials.append(mat)
    obj.location = (-3,-1,0)
    obj.keyframe_insert('location',frame=1)
    obj.location =  (-3,-10,0)
    obj.name = "blue_ball"
    obj.keyframe_insert(data_path="location",frame=10)
    
    bpy.ops.object.text_add()
    bpy.context.object.data.size = 3
    bpy.context.object.name = "blue_text"
    bpy.context.object.location = (-15,0,0)
    mat = bpy.data.materials.new('blue_text')
    color = (0, 0, 0.5, 1)
    mat.diffuse_color = color
    bpy.context.object.data.materials.append(mat)

def render():
    bpy.context.scene.frame_end = 10
    bpy.context.scene.render.resolution_x = 200
    bpy.context.scene.render.resolution_y = 150
    bpy.context.scene.render.engine = 'CYCLES'
    bpy.context.scene.render.filepath = "/tmp/o"
    bpy.ops.render.render(animation=True)

init()
render()

比较首尾

  • 第一帧
    • 两球y位置相同

图片描述

  • 最后一帧
    • 第十帧
    • 两球 y位置也相同

图片描述

  • 但是中间过程如何呢?

中间过程

  • 从第2帧 到 第9帧
    • 两球的y坐标都不相同

图片描述

  • 为什么会这样呢?

总结 🤔

  • 这次我们用代码
    • 实现了动画
  • 代码动画有两种
    1. 每次进入帧的时候 计算数值
    2. 在时间轴上插入关键帧
  • 我们实践了两种动画
    • 都能用
    • 但是具体帧上数值不同
  • 这是为什么呢?🤔
  • 我们下次再说!👋