Skip to content

Latest commit

 

History

History
730 lines (487 loc) · 15.5 KB

651-2731673-函数封装_静态建模总结.sy.md

File metadata and controls

730 lines (487 loc) · 15.5 KB
show version enable_checker
step
1.0
true

python_blender

开始

  • 上次通过python设置了舞台基本要素
    • 灯光
    • 物体
    • 摄像机
  • 并且将结果渲染为一张png
  • 可以把流程总结一下吗?

启动环境

  • 从终端运行blender启动环境

图片描述

  • 这样可以
    • 收到 更多报错信息

清屏

  • 切换到 script视图
    • 并新建文本

图片描述

  • 把清屏操作封装成函数
    • 然后再调用函数
import bpy

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

clear_scene()

执行代码

  • 写好代码后
    • 观察3d视图里面状态
    • 点击运行按钮

图片描述

  • 执行之后
    • 清空场景中所有对象
  • 信息调板
    • 有相关信息

图片描述

  • 如何将这个脚本文件保存呢?

保存脚本

  • 点击Text
    • Save As

图片描述

  • 进入Code文件夹

图片描述

  • 并将文本保存为
    • 1_clear_scene.py

图片描述

观察文件

  • 在终端中
    • 新开标签页

图片描述

  • 在新标签页中打开文件
cd Code
vi 1_clear_scene.py
  • 查看到Code中确实有文件

图片描述

  • 为什么要把文件存在Code中呢?

下载文件

  • Code文件夹中的文件可以下载

图片描述

  • 点击侧面的边栏
    • 找到下载代码

图片描述

  • 这样就可以将py文件
    • 下载到本地硬盘了

创建球体

  • 在3d视图
    • 新建一个球体

图片描述

  • 在左下角信息调板
    • 选中信息
    • 然后复制

图片描述

  • 将信息粘贴到文本调板中

创建球体并封装

  • 将代码 封装到 函数create_man
    • 并且调用函数
import bpy

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

def create_man():
    bpy.ops.mesh.primitive_uv_sphere_add()


clear_scene()
create_man()
  • 执行脚本会有两个功能function
    • 清屏
    • 创建球体

创建圆锥并调整位置

  • 用同样方式创建圆锥
    • 在信息调板中找到代码

图片描述

  • 并将代码
    • 封装到 create_man函数

创建平面

图片描述

  • 创建平面
    • 并将代码封装到
    • create_plane函数
import bpy

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

def create_man():
    bpy.ops.mesh.primitive_uv_sphere_add()
    bpy.ops.mesh.primitive_cone_add()

def create_plane():
    bpy.ops.mesh.primitive_plane_add()

clear_scene()
create_man()
create_plane()
  • 执行代码

图片描述

调整平面

图片描述

  • 将平面的缩放调整为
    • (10,10,1)

图片描述

  • 需要将操作落实到代码

落实代码

  • 修改create_plane函数

图片描述

  • 执行结果
    • 同手动操作

图片描述

  • 现在 要把
    • 球和锥
    • 拔起来

拔萝卜

  • 选中球体
    • shift + 空格
    • G
    • 使用移动工具
    • 把球拔起来
  • 然后
    • 选中圆锥
    • 也拔起来
  • 调整位置

图片描述

  • 合适 后
    • 观察数值

图片描述

  • 将球体和圆锥的数值
    • 调整进程序中

调整代码

  • 设置圆锥和球体的
    • 位置location
import bpy

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

def create_man():
    bpy.ops.mesh.primitive_uv_sphere_add()
    head = bpy.context.object
    head.location = (0,0,2.5)
    bpy.ops.mesh.primitive_cone_add()
    body = bpy.context.object
    body.location = (0,0,1)

def create_plane():
    bpy.ops.mesh.primitive_plane_add()
    plane = bpy.context.object
    plane.scale = (10,10,1)

clear_scene()
create_man()
create_plane()
  • 执行后
    • 可以复原场景

图片描述

  • 但是 目前场景中的名字
    • 比较尬
    • 需要改成可以理解的

修改名字

  • 在脚本中
    • 设定相关对象的name
  • 执行后
    • 得到新的名字

图片描述

  • 还需要将头和身体
    • 封装进
    • man对象

封装对象

  • 新建控对象man

    • 并且把head、body封装进去
  • 运行结果

    • 可以看到封装成功

图片描述

  • 下面需要设置颜色

设置并应用材质

  • 设置蓝色材质
    • 并应用到
      • head
      • body

图片描述

  • 然后将函数名修改为
    • create_blue_man
  • 然后修改调用函数

再存文件

import bpy

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

def create_blue_man():
    mat = bpy.data.materials.new('blue')
    color = (0, 0, 1, 1)
    mat.diffuse_color = color
    man  = bpy.data.objects.new("man", None)
    bpy.data.collections["Collection"].objects.link(man)
    bpy.ops.mesh.primitive_uv_sphere_add()
    head = bpy.context.object
    head.location = (0,0,2.5)
    head.data.materials.append(mat)
    head.parent = man
    head.name = "head"
    bpy.ops.mesh.primitive_cone_add()
    body = bpy.context.object
    body.location = (0,0,1)
    body.parent = man
    body.data.materials.append(mat)
    body.name = "body"

def create_plane():
    bpy.ops.mesh.primitive_plane_add()
    plane = bpy.context.object
    plane.scale = (10,10,1)


clear_scene()
create_blue_man()
create_plane()
  • 这次将文件存储在Code中
    • 名叫create_blue.py

图片描述

  • 下面准备摄影机

手动添加摄影机

图片描述

  • 添加摄影机后
    • 复制代码

图片描述

  • 准备粘贴到
    • 脚本区

摄影机代码

  • 新建摄影机函数
    • 并调用

图片描述

  • 当前摄影机能拍摄到什么画面呢?

摄影机画面

  • 选中摄影机
    • 在3d视图
    • 将其设置为 默认摄影机

图片描述

  • 由于摄影机默认位于(0,0,0)
    • 属于圆锥内部
    • 画框内 只能看到漆黑一片

图片描述

设置摄影机

图片描述

  • 选择view
    • 框选所有 Frame All
  • 然后调整 摄影机位置和角度

图片描述

  • 将小蓝设置为画面主体

对齐摄影机

  • 将摄影机
    • 对齐到当前视图

图片描述

  • 从画框中观察最终画面

图片描述

  • 此时摄影机
    • 位置和角度如何呢?

观察摄影机

  • 选中Camera观察
    • 对象属性
    • object properties

图片描述

  • 能否快速得到这些数据呢?

获取摄影机数据

  • 将大纲调板中的摄影机
    • 拖动到游乐场

图片描述

  • 在游乐场获得
    • 摄影机基础空间属性

图片描述

  • 如何将这些属性
    • 代码化呢?

代码化

  • 将数据设置为代码

图片描述

  • 准备渲染输出

渲染输出

  • 添加渲染输出函数
import bpy

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

def create_man():
    mat = bpy.data.materials.new('blue')
    color = (0, 0, 1, 1)
    mat.diffuse_color = color
    man  = bpy.data.objects.new("man", None)
    bpy.data.collections["Collection"].objects.link(man)
    bpy.ops.mesh.primitive_uv_sphere_add()
    head = bpy.context.object
    head.location = (0,0,2.5)
    head.data.materials.append(mat)
    head.parent = man
    bpy.ops.mesh.primitive_cone_add()
    body = bpy.context.object
    body.location = (0,0,1)
    body.parent = man
    body.data.materials.append(mat)

def create_plane():
    bpy.ops.mesh.primitive_plane_add()
    plane = bpy.context.object
    plane.scale = (10,10,1)

def create_camera():
    bpy.ops.object.camera_add()
    camera = bpy.context.object
    camera.location = (3.059990406036377, -9.885231018066406, 12.905241966247559)
    camera.rotation_euler = (0.7260572910308838, -6.679311326251991e-09, 0.30019673705101013)
    bpy.context.scene.camera = camera

def render():
    bpy.context.scene.render.resolution_x = 320
    bpy.context.scene.render.resolution_y = 240
    bpy.context.scene.render.resolution_percentage = 50
    bpy.context.scene.render.engine = 'CYCLES'
    bpy.context.scene.render.filepath = '/tmp/o.png'
    bpy.ops.render.render(write_still=True)

clear_scene()
create_man()
create_plane()
create_camera()
render()

观察输出结果

firefox /tmp/o.png
  • 观察效果

图片描述

  • 缺一盏灯

手动添灯

图片描述

  • 在信息调板中
    • 找到相关代码
    • 并复制 进 剪贴板

代码添灯

  • 添加聚光灯函数

图片描述

  • 执行成功
    • 但是如何让聚光灯
    • 照射小蓝

设置聚光灯

  • 选中聚光灯
    • 在3d视图中 设置为
    • 当前 摄影机

图片描述

  • 聚光灯位置是(0,0,0)
    • 相当于圆锥内部

图片描述

  • 如何调整聚光灯位置?

调整聚光灯位置

  • 视图
    • 框选所有
    • Frame all

图片描述

  • 可以 框选到
    • 场景中所有的对象

图片描述

调整聚光灯

  • 调整 当前摄影机(聚光灯)
    • 位置和角度
    • 使其正好照射小蓝

图片描述

设置聚光灯

  • 对齐视图
    • 将当前摄影机(聚光灯)
    • 对齐到 当前视图

图片描述

  • 聚光灯
    • 位置和角度变了吗?

观察数值变化

  • 选中摄影机
    • 观察聚光灯属性

图片描述

  • 如何将这些属性代码化?

获得聚光灯属性

  • 将 大纲调板中的 聚光灯
    • 拖动到 游乐场

图片描述

  • 获得具体属性

聚光灯 代码定位

  • 将相关数值粘贴到
    • 聚光灯相关的代码处

图片描述

  • 尝试执行

再观察

  • 渲染成功

图片描述

  • 效果不明显

图片描述

  • 加大功率

上强度

  • 功率怎么用代码表示?

图片描述

  • 找到
    • 预设
    • preferences

图片描述

  • 勾选python-tips

找到功率

  • 进行修改

图片描述

  • 信息调板里观察

图片描述

  • 复制代码
    • 准备粘贴

功率代码

图片描述

  • 最终效果
    • 完整代码
import bpy

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

def create_man():
    mat = bpy.data.materials.new('blue')
    color = (0, 0, 1, 1)
    mat.diffuse_color = color
    man  = bpy.data.objects.new("man", None)
    bpy.data.collections["Collection"].objects.link(man)
    bpy.ops.mesh.primitive_uv_sphere_add()
    head = bpy.context.object
    head.location = (0,0,2.5)
    head.data.materials.append(mat)
    head.parent = man
    bpy.ops.mesh.primitive_cone_add()
    body = bpy.context.object
    body.location = (0,0,1)
    body.parent = man
    body.data.materials.append(mat)

def create_plane():
    bpy.ops.mesh.primitive_plane_add()
    plane = bpy.context.object
    plane.scale = (10,10,1)

def create_camera():
    bpy.ops.object.camera_add()
    camera = bpy.context.object
    camera.location = (3.059990406036377, -9.885231018066406, 12.905241966247559)
    camera.rotation_euler = (0.7260572910308838, -6.679311326251991e-09, 0.30019673705101013)
    bpy.context.scene.camera = camera

def create_spot():
    bpy.ops.object.light_add(type='SPOT')
    spot = bpy.context.object
    spot.location = (-1.2811667919158936, -3.316868543624878, 12.282358169555664)
    spot.rotation_euler = (0.34208473563194275, 1.8850268901360323e-08, -0.3071775436401367)
    spot.data.energy = 1000

def render():
    bpy.context.scene.render.resolution_x = 320
    bpy.context.scene.render.resolution_y = 240
    bpy.context.scene.render.resolution_percentage = 50
    bpy.context.scene.render.engine = 'CYCLES'
    bpy.context.scene.render.filepath = '/tmp/render2.png'
    bpy.ops.render.render(write_still=True)

clear_scene()
create_man()
create_plane()
create_camera()
create_spot()
render()

总结 🤔

  • 这次将静态图渲染做了总结
  • 可以让画面动起来吗?🤔
  • 我们下次再说!👋