首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >奇数或高级语言中的射线追踪器

奇数或高级语言中的射线追踪器
EN

Code Golf用户
提问于 2014-01-03 03:51:04
回答 1查看 567关注 0票数 -3

射线追踪器很容易写。在屏幕上的每个像素,你拍摄一条光线到现场,看看它击中了什么。对于最基本的射线追踪器,光线获取它击中的物体的颜色。

如果你正在做阴影,那么你不会立即给像素着色,而是尝试将光线追溯到光源。然后,阴影颜色是光线对光源的角度余弦(点积)*(表面的颜色)。如果无法到达光源,那么物体就处于阴影中。

这个挑战是用你能用的任何语言写射线追踪器。赢家是最简洁的代码,同时仍然保持可读性(有关更多的优雅的定义,请参见这里)。

需求

  • 射线示踪球
  • 明暗处理
  • 影影
  • 至少1次反射。
  • 必须使用像素显示结果或写入图像文件。不要进入控制台。

奖金

  • 包括射线追踪一般多边形的能力
  • 半透明

超级奖金

  • 一般BRDF
  • 地下散射(BSSRDF)

坏例子

  • 别这么做:http://www.teamten.com/lawrence/projects/shortest_射线_示踪剂/
  • 别这么做:http://www.kevinbeason.com/smallpt/

第一个是不可读的。第二个只是一个非常紧凑的C++程序。

这是一个困难的项目,所以您可能想要书签,然后再回来。我会把这个打开大约一个月,然后再颁发支票。

资源:

  • http://www.cs.utah.edu/~shirley/irt/

(稍后将添加更多内容)

EN

回答 1

Code Golf用户

发布于 2014-01-03 04:32:34

这需要更多的工作来满足需求(阴影,交互反射),但大部分工作。它在回调过程中向image操作符逐行生成像素.可读性的代价是浪费内存,任意创建和丢弃临时数组。

Postscript 90行

使用外部矩阵库

代码语言:javascript
运行
复制
(mat.ps) run  % load matrix library
/div { dup 0 eq { pop 10000 }{ div } ifelse } bind def  % make divide-by-zero safe
/tan { dup sin exch cos div } def 

%[vector] scalar {op}  .  [vector']
%create a new vector and fill with the scalar,
%call matrix library's vector-op
/sop {
    exch % [] {} s
    [ exch % [] {} [ s 
    3 index length 1 sub{dup}repeat % [] {} [ s*n-1
    ] exch % [] [] {}  
    vop 
} def 

/normalize { dup mag {div} sop } def 

<< % parameters
    /Cam    [ 0 0 0 ]   % camera location
    /Lookat [ 0 0 -1 ]  % camera lookat point
    /Up     [ 0 1 0 ]   % up vector
    /fovx   45          % horizontal field of view
    /W      320         % image width
    /H      200         % image height
    /Sc     [ 1 1 -5 ]  % sphere center
    /Sr     2           % sphere radius
>> begin

<< % dependent constants
    /Left Lookat Cam {sub} vop Up cross
    /buf W string
    /fovy H W div fovx mul 
    /ang 0
    /pos 3
>> {def} forall  % add these values to existing dictionary

% place the light in the scene according to the /ang parameter
/setLight { /Light [ ang cos pos mul 3 ang sin pos mul ] def } def 

0 10 360 { /ang exch def   % for-loop sets /ang, calls image and showpage
setLight                   % place the light
150 200 translate          % position lower left corner of image on page
/y 0 def                   % initial y-value
W H 8                      % put width height depth on stack  for `image` call
[ 1 0 0 1 0 0 ]            % 1-to-1 matrix, so width*height points is the image size
{                          % image procedure yields a string with one image row 
    0 1 W 1 sub { /x exch def                   % for-loop iterates over x-values
        Left   x 2 mul W sub W div fovx tan mul  {mul} sop  % construct vector from eye through center of pixel
        Up     y 2 mul H sub H div fovy tan mul  {mul} sop 
        Lookat {add} vop {add} vop 
        Cam {sub} vop 
        normalize /R exch def 

        Cam Sc {sub} vop   % use the quadratic formula to check for real intersection
        dup R dot 2 mul /B exch def 
        dup dot Sr dup mul sub /C exch def 

        B dup mul C 4 mul sub /disc exch def  % discriminant, the part under the radical-sign

        % ray hits sphere? no:0 yes:calculate
        disc 0 lt { 0 }{
            disc sqrt /sdisc exch def  % complete the quadratic formula to yield t value
            B neg sdisc sub .5 mul /t exch def
            t 0 le { B neg sdisc add .5 mul /t exch def } if
            R t {mul} sop
            Cam {add} vop /ri exch def  %intersection point
            ri Sc {sub} vop
            1 Sr div {mul} sop %normalize
            /rn exch def  %surface normal
            Light
            ri
            {sub} vop %normalize
            rn dot  % normal .dot. light-ray
            1 add .3 mul
            %.3 mul
            dup 0 lt {pop 0} if  % clip value into 8-bit range
            dup 1 gt {pop 1} if
            255 mul truncate cvi
        } ifelse   % pixel_color = 0..255

        buf x 3 2 roll put  % put pixel value in string
    } for
    /y y 1 add def  % increase y for next row
    buf  % yield string buffer to image
}
%exec  % image doesn't report internal errors, debug the procedure with `exec`
image
showpage

} bind for

可以使用幽灵脚本生成一系列编号的图像。ImageMagick的convert可以将它们编译成动画gif。

票数 7
EN
页面原文内容由Code Golf提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codegolf.stackexchange.com/questions/17270

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档