2014-02-20 91 views
-4

所以这个RT代码通过原始代码创建一个带有模糊的3D图像。如何在没有任何建模工具的情况下实际完成?如何理解这个RayTracer代码

我目前的工作,了解RT的工作,不同的方式如何实现它们,所以这是一种冷静地看到的产生相当可观的3D图像代码这么小的量。

#include <stdlib.h> // card > aek.ppm 
#include <stdio.h> 
#include <math.h> 
#include <fstream> 

typedef int i; 
typedef float f; 

struct v { 
f x, y, z; 
v operator+(v r) { 
    return v(x + r.x, y + r.y, z + r.z); 
} 
v operator*(f r) { 
    return v(x * r, y * r, z * r); 
} 
f operator%(v r) { 
    return x * r.x + y * r.y + z * r.z; 
} 
v() {} 
v operator^(v r) { 
    return v(y * r.z - z * r.y, z * r.x - x * r.z, x * r.y - y * r.x); 
} 
v(f a, f b, f c) {x = a; y = b; z = c;} 
v operator!() { 
    return*this * (1/sqrt(*this % *this)); 
} 
}; 
i G[] = {247570, 280596, 280600, 249748, 18578, 18577, 231184, 16, 16}; 
f R() 
{ 
return(f)rand()/RAND_MAX; 
} 
i T(v o, v d, f&t, v&n) 
{ 
t = 1e9; i m = 0; 
f p = -o.z/d.z; 

if(.01 < p)t = p, n = v(0, 0, 1), m = 1; 

for(i k = 19; k--;) 
    for(i j = 9; j--;)if(G[j] & 1 << k) { 
      v p = o + v(-k, 0, -j - 4); 
      f b = p % d, c = p % p - 1, q = b * b - c; 

      if(q > 0) { 
       f s = -b - sqrt(q); 

       if(s < t && s > .01) 
        t = s, n = !(p + d * t), m = 2; 
      } 
     } 

return m; 
} v S(v o, v d) 
{ 
f t; 
v n; 
i m = T(o, d, t, n); 

if(!m)return v(.7, .6, 1) * pow(1 - d.z, 4); 

v h = o + d * t, l = !(v(9 + R(), 9 + R(), 16) + h * -1), r = d + n * (n % d * -2); 

f b = l % n; if(b < 0 || T(h, l, t, n))b = 0; 

f p = pow(l % r * (b > 0), 99); 

if(m & 1) { 
    h = h * .2; 
    return((i)(ceil(h.x) + ceil(h.y)) & 1 ? v(3, 1, 1) : v(3, 3, 3)) * (b * .2 + .1); 
} return v(p, p, p) + S(h, r) * .5; 
} i 

main() 
{ 

FILE * pFile; 
pFile = fopen("d:\\myfile3.ppm", "w"); 
fprintf(pFile,"P6 512 512 255 "); 
v g = !v(-6, -16, 0), a = !(v(0, 0, 1)^g) * .002, b = !(g^a) * .002, c = (a + b) * -256 + g; 

for(i y = 512; y--;) 
    for(i x = 512; x--;) { 
     v p(13, 13, 13); 

     for(i r = 64; r--;) { 
      v t = a * (R() - .5) * 99 + b * (R() - .5) * 99; 
      p = S(v(17, 16, 8) + t, !(t * -1 + (a * (R() + x) + b * (y + R()) + c) *  16)) * 3.5 + p; 
     } 

     fprintf(pFile, "%c%c%c", (i)p.x, (i)p.y, (i)p.z); 

    } 
} 
+0

如果我没有看到包括'',我会说这是C代码。而那非常丑陋。有小写字母,单个字符'结构'名称看起来确实是错误的。 – crashmstr

+0

@crashmstr从什么时候C有运算符超载? :) – 2014-02-20 14:30:48

+0

@ user3333072你期望我们做什么?一行一行地解释这段代码?你能否缩小这个话题的范围,告诉我们你不明白的部分? – Hulk

回答

2

我亲爱的朋友,那是Paul Heckbert的代码的权利?

你至少可以提到它。

对于人的思维这段代码是不可读的,这是为什么:

这家伙提出,可以容纳一张信用卡上的代码,这是目标:)

他的网站:http://www.cs.cmu.edu/~ph/

编辑:了解此代码的来源可能会帮助您理解它。即使it'snot您的主要动机......

如果你在光线追踪真正的兴趣,开始与其他来源。 看看这个网站http://www.scratchapixel.com/lessons/3d-basic-lessons/lesson-1-writing-a-simple-raytracer/source-code/(加上它说说你的代码)

+1

我同意他应该提到它,但是你的帖子不是答案:( –

+1

@phresnel只是想帮助记住Paul Heckbert。 我认为你不能真正回答他的问题,但你可以通过以下方式了解此代码:知道是什么激发了设计 – 2014-02-20 14:41:26

+0

@phresnel编辑的答案,给出了我在几年前制作我的第一个光线追踪器的路径 – 2014-02-20 14:46:37

2

这段代码并不是特别的。它基本上是一个光线跟踪器,被模糊成一张可以放在名片上的形式(请参阅https://www.cs.cmu.edu/~ph/)。

如何,实际上没有任何建模工具呢?

你并不需要工具来渲染什么。你甚至可以在没有任何建模工具的情况下创建一个完整的WoW游戏(或者现在的髋关节)。建模工具让你的生活变得更轻松w.r.t.某些种类的场景(阅读:非常复杂的场景)。

您可以随时对这些数据进行硬编码,或将它们手动编入某些外部文件。

你也可以使用参数发生器;佩林噪音是其中比较受欢迎的例子之一。

在射线追踪器中,碰巧没有建模工具就很容易开始,因为计算渲染基元“射线”和任何有限几何基元之间的几何相交非常简单。例如,非近似的“完美”球体的交点只是几行代码。

TL; DR:数据仅仅是数据。你如何创建和紧缩它完全取决于你。

+0

TL; DR,这段代码只是写入一个bmp。 :p – 2014-02-20 15:19:24

+0

@Mayerz:哦,你的意思是提问者和我的意思是建模工具的不同环境?就像,我假设“我如何获得我的射线追踪模型”,与“如何在嵌入建模工具的情况下工作”? –