- 2007/03/31 02:57
- uncategorized
ずーっとほったらかしにしてた、レイトレ球レンダリングを、
ハッと思い立って書いてみました。
で、その結果↓

交差判定だのなんだのってところが、どうやってんの!?ってずーっと思ってて、
一旦判明したんだけどプログラムにするやり方がわかんなくて、
で、なんとなく思いついたから仕事終わってから会社で書いてみた。
前に失敗した時の経験なども生かし、交差判定するところまではほぼ問題なくクリア。
するするっと、数十分程度、かな。厳密にはわからんけどサクッとイケた。
イヤッホーーーゥ!!
そんで上の画像は、それにディフューズ計算を簡単に入れてみたもの。
なんか、端がもっと黒くなってもいいような気がするんだけど、
まぁそこは僕のコーディングミスかもしれないのでスルー。
今回もまたppmで画像を出す方式で書きました。
使用した言語はpython。
プログラムの行数は100行もないくらい。80行前後。
きゃー短い。
この調子で、一般的なレンダリング技術ぐらいはなんとなく理解しておきたいなぁ。
そうそう、ライトも追加してみようと思って、視点ベクトルと法線で計算していたdiffuseを
ライトと法線で計算しようと思ったら、
ValueError: math domain error
というエラーが出て計算できないので諦めた。
原因不明。人為的なものじゃないと思うんだけどなぁ、、
まぁ、仕方ないので要調査です。
以下、一応ソースコード載せておきます。
恥ずかしながら。。
間違いなどあれば是非ご指摘くださいませーーー。
————————————————————————–
from math import *
class Vector:
def __init__( self, x, y, z ):
self.x = x
self.y = y
self.z = z
def sub( self, other ):
self.x -= other.x
self.y -= other.y
self.z -= other.z
return Vector( self.x, self.y, self.z )
def mult( self, other ):
return self.x*other.x+self.y*other.y+self.z*other.z
def square( self ):
return self.x*self.x+self.y*self.y+self.z*self.z
def dot( self, other ):
length = sqrt( self.x*self.x+self.y*self.y+self.z*self.z )
n1x = self.x / length
n1y = self.y / length
n1z = self.z / length
length = sqrt( other.x*other.x+other.y*other.y+other.z*other.z )
n2x = other.x / length
n2y = other.y / length
n2z = other.z / length
return sqrt( n1x*n2x+n1y*n2y+n1z*n2z )
class Sphere:
def __init__( self, r ):
self.r = r
def intersect( self, ray, eye ):
a = ray.square()
b = ray.mult( eye )*2
c = eye.square()-self.r
return b*b-4*a*c
def distance( self, ray, eye ):
a = ray.square()
b = ray.mult( eye )*2
c = eye.square()-self.r
return ( -b + sqrt( b*b -4*a*c ) ) / 2*a
# main routine
filename = “E:\\raytest.ppm”
file = open( filename, ‘w’, -1 )
width = 200
height = 200
radius = 10.0
max = 5.0
i = j = 0
x = y = -max
z = -10.0
screenY = -max
perStep = max*2/width
sphere = Sphere( radius )
file.write( “P3\n”+str(width)+” “+str(height)+”\n255\n” )
for i in range( height ):
x += perStep
y = screenY
for j in range( width ):
y += perStep
eye = Vector( x, y, z )
ray = Vector( x, y, z+1.0 )
ray = ray.sub( eye )
d = sphere.intersect( ray, eye )
if d >= 0:
t = sphere.distance( ray, eye )
px = eye.x + t*ray.x
py = eye.y + t*ray.y
pz = eye.z + t*ray.z
p = Vector( px, py, pz )
p.dot( ray )
diffuse = p.dot( ray )
result = int( 255*diffuse )
file.write( str(result)+” “+str(result)+” “+str(result)+” ” )
else:
file.write( “255 255 255 ” )
file.write( “\n” )
print( ” – - – - – rendering finished – - – - – ” )
Comments:0
Trackbacks:0
- Trackback URL for this entry
- http://blog.taikomatsu.com/2007/03/31/ray-%e8%b6%85%e7%b0%a1%e5%8d%98%e3%83%ac%e3%82%a4%e3%83%88%e3%83%ac%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%a0/trackback/
- Listed below are links to weblogs that reference
- [ ray ] 超簡単レイトレプログラム from memlog