射线追踪闪亮的球体


15

我下载了POV-ray,并渲染了这种有光泽的90年代金属球体样式:

在此处输入图片说明

您的任务是做同样的事情,但要通过自己以尽可能少的字节实现渲染引擎来实现。您不必复制此精确图像-只要符合以下条件,无穷棋盘上方反射球的任何图像都可以。

规则:

  • 该图像必须描绘出一个悬在无限棋盘上方的反射球体。图像本身必须同时显示棋盘本身及其在球体中的反射。必须在视觉上清楚地知道这就是我们所看到的。除此之外,几何形状,颜色,材料属性等的详细信息取决于您。

  • 场景中必须有一些照明:球体的某些部分应该比其他部分更暗,并且在视觉上应该可以大致分辨出光线的来源。除此之外,照明模型的细节由您决定。(如果愿意,可以发明自己的简化照明模型。)球体不必投射阴影。

  • 以上两个标准-是否真的看起来像是被光源照亮的棋盘上方的发光球-将由社区使用投票进行判断。因此,答案必须有一个积极的分数,才有资格获胜。

  • 输出必须至少为300x300像素。可以将其显示在屏幕上或写入文件,也可以。

  • 您的代码应该在一台合理的现代计算机上运行不到一个小时。(这很慷慨-POV射线实际上是在瞬间渲染上述场景。)

  • 不能使用内置的光线跟踪功能-您必须自己实现渲染器。

  • 这是,因此具有最短代码(以字节为单位)的正得分条目将获胜。但是,也欢迎您玩一幅通过画一幅漂亮的图画来获得最多选票的元游戏(同时当然要使代码尽量简短)。

这个挑战看似很难,但由于几何形状是固定的,因此通过光线跟踪渲染这种场景的算法非常简单。这实际上只是在输出图像中的每个像素上进行迭代并评估数学表达式以查看其应为哪种颜色的情况,因此,我很乐意看到一些好的答案。


我个人不喜欢照明要求。我认为这增加了很多额外的复杂性,但收益却很小。不过,只是我的意见。
stokastic 2014年

您说颜色取决于我们。这包括灰度图像吗?
Martin Ender 2014年

@MartinBüttner是的,灰度图像很好。
纳撒尼尔(Nathaniel)2014年

@stokastic,我希望这将是创造力的来源,因为人们想出了根本上简化的方法,但只是说服了可以用少量代码指定的照明模型。我在问题中添加了注释,即简化的照明模型还可以。
纳撒尼尔(Nathaniel)2014年

它已经完成:fabiensanglard.net/rayTracing_back_of_business_card/index.php当然这是可以做短一点把它简化成一个球,除抗锯齿等
Shujal

Answers:


28

Python 2中,484个 468 467字节

在此处输入图片说明

i=int;u=249.3
def Q(A,B):
 a=A*A+B*B+9e4;b=B*u+36e4;I=b*b-a*128e4
 if I>0:
    t=(-b+I**.5)/(5e2*a);F,G,H=A*t,B*t,u*t;J,K,M=F,G+.6,H+2.4;L=a**-.5;k=2*(A*J+B*K+u*M)*L;C,D,E=A*L-k*J,B*L-k*K,u*L-k*M;L=(C*C+D*D+E*E)**-.5;t=(-4e2-G)/D;return(D*D*L*L*u,((i(F+t*C)/200+i(H+t*E)/200)&1)*(u*D*L))[D>0]
 else:return(u*B*B/a,((i(-2e2/B*A)/200+i(-6e4/B)/100)&1)*u*B/a**.5)[B>0]
open("s.pgm","wb").write("P5 800 600 255 "+"".join(chr(i(Q(j%800-4e2,j/800-u)))for j in range(480000)))

注:后if I>0:有一个换行符后跟一个标签之前字符t=...

运行程序将创建一个名为s.pgm的800x600图像

从“真实的”光线追踪器公式开始(对高尔夫进行了一些调整)。

在旧的旧PC上渲染大约需要3秒(使用pypy需要0.7秒)。


4
漂亮的图像!
纳撒尼尔(Nathaniel)2014年

您可以通过替换0000为来节省一些字节,而无需执行zlib技巧e4
纳撒尼尔(Nathaniel)2014年

@Nathaniel:Doh ...一个代码高尔夫球很大的错误:-)已修复。我还删除了zlib打包技巧,因为我必须研究其合法性(例如,最新版本(例如,当zipped适用于标准python却不适用于pypy时,这很奇怪))。
4502年

另一个代码的高尔夫技巧,你可以替换a if b else c使用(c,a)[b],只要你不靠短路通过零个错误,以避免如师。也if A:code;return B\nelse:return C可以将其替换code;return(C,B)[A]
克劳迪(Claudiu)2014年

@Claudiu:谢谢你的建议。我不得不稍微更改参数以避免被零除。我还对图像使用了一个循环,这节省了很多。
4502年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.