前两天用 Python 语言写了个小工具 Hamal,可以将一些朴素的数据文件转化为 POV-Ray 场景文件,然后进行光线跟踪渲染,从而实现数据的可视化。有关 Hamal 的用法,详见 「Hamal 指南」。

昨晚想给娃做一个伪全息投影的玩具,就是 4 张三角形的透明塑料片拼接成一个金字塔,然后用手机播放网上下载来的初音未来的伪全息视频,将屏幕画面投射到这个金字塔的四个面上。

制作这种金字塔的教程,百度一下,铺天盖地。淘宝上也有成品,不过,自己制作起来并不困难,要点就是金字塔底边框是一个正方形,边长与手机屏幕相同,并且金字塔的每个面与底边框围成的平面之间的夹角为 45 度角。硬一些的塑料板会更方便制作。

难度稍微大一些的是伪全息视频的制作,应该有这方面的专业软件。不过,由于我刚写了 Hamal,踌躇满志,文风开始进入不严肃模式。我决定投身演艺界,拍摄一部伪全息舞台剧。我围观了最近的演艺圈新闻,看看谁有潜力拿小金人。斯坦福兔子以一幅傲视群雌的姿态出现在我的视野……

斯坦福兔子最近化名为 foo.asc,潜伏在 github.com 山里。不够,他把自己隐居的事告诉了不止一个娱记。这种事,我只知道李白干过。我不远万里前往 github 山,许以重金和美貌的母兔子,将它请了回来:

$ wget https://github.com/liyanrui/hamal/blob/master/data/foo.asc

然后我开始写剧本,规划舞台布置以及照明等问题:

$ hamal foo.asc

没办法,整个拍摄团队就老哥我一个。

剧本与拍摄草案很快就就出来了。剧本太长,这里就不显摆了,它就在我的硬盘里躺着,文件名叫 foo.inc。舞台布置与照明的草案 foo.pov 的内容如下:

#version 3.7;
#include "colors.inc"
background {color White}
global_settings {assumed_gamma 1.0}

#declare model_center = <8.315960, 8.015419, -6.846305>;
#declare model_radius = 12.512303;
#declare view_center = model_center;

camera {
  orthographic
  location <0, 0, -2 * model_radius> + model_center * z
  look_at <0, 0, 0>
  translate view_center
}

light_source {
  model_center + <0, 0, -10 * model_radius>
  color rgb <1.000000, 1.000000, 1.000000>
  shadowless
}

#declare point_size_of_foo = 0.031281;

#include "foo.inc"
object {
  foo
  pigment {
    color rgb <0.03, 0.2, 0.4>
  }
}

斯坦福兔子抓过 foo.pov 看了看,又扔到了一边,你傻啊,舞台背景怎么能是白色呢?

那我就改成黑色:

background {color Black}

兔子又看了看,鄙夷地说,我是着妆是白色的,而不是脏兮兮的灰蓝色!

那我就改成白色:

object {
  foo
  pigment {
    color White
  }
}

兔子又看了看,没再说话。

那我们就开始拍吧!兔子先生,请你在上台,转一圈!

兔子没有动。兔子先生……请你……它居然发火了,老哥,你业余的吧!转圈是随便转的吗?一切都要设计,精心设计!

好吧,我从 foo.pov 里删掉了

object {
  foo
  pigment {
    color rgb <0.03, 0.2, 0.4>
  }
}

然后又很耐心地用了 5 分钟的时间,给它设计了一套很精确很复杂很繁琐的转圈说明:

#declare offset_dist = 1.3 * model_radius;

// 正面
object {
  foo
  translate -model_center
  rotate clock * 360 * y
  translate model_center
  translate -offset_dist * y
  pigment {
    color White
  }
}

// 背面
object {
  foo
  translate -model_center
  rotate 180 * y
  rotate 180 * z
  rotate -clock * 360 * y
  translate model_center
  translate offset_dist * y
  pigment {
    color White
  }
}

// 右面
object {
  foo
  translate -model_center
  rotate -90 * y
  rotate -90 * z
  rotate clock * 360 * x
  translate model_center
  translate -offset_dist * x
  pigment {
    color White
  }
}

// 左面
object {
  foo
  translate -model_center
  rotate 90 * y
  rotate 90 * z
  rotate -clock * 360 * x
  translate model_center
  translate offset_dist * x
  pigment {
    color White
  }
}

兔子看了看 foo.pov,又一次没再说话。

好,那我们开拍!兔子没有动。我只好再说一遍,开拍!它还是没动。

对,还没有场记,不得不再客串一下。

在硬盘上,在 foo.inc 与 foo.pov 所在的目录里创建了场记单 foo.ini,让兔子转一圈需要拍 60 帧,于是我在 foo.ini 里写下了

Input_File_Name = foo.pov
Initial_Frame = 1
Final_Frame = 60

然后我说,开拍!

兔子说,你还没启动摄像机!

好吧,

$ povray foo.ini

刷唰唰唰,四台摄像机启动了起来,它们从舞台的四面同时拍摄。兔子走上台,按照 foo.pov 里的说明,开始漫不经心的转圈……

上面的是「视频」是我用 imagemagick 工具箱里的 convert 命令用 60 帧图片合成的动图:

$  convert -delay 10 -loop 0 foo*.png foo.gif

第一场,拍完后,把之前谈好的片酬给了兔子。它去找母兔子制造斐波那契数列了,而我只好与一个身无分文的我惺惺相惜。

看来,要拍下一场,要么靠打赏,要么找风投啊……

后记

由于我觉得伪全息投影比较好玩,所以我在 Hamal 中增加了这一功能,上述的繁琐过程(除了获取数据文件的步骤),现在可归结为三条命令:

$ hamal --holography foo.asc
$ povray foo.ini
$ convert -delay 10 -loop 0 foo*.png foo.gif

你可能感兴趣的文章

载入中...
garfileo garfileo

4.6k 声望

发布于专栏

while(1) { }

死循环……就是永动机!

126 人关注