游戏开发论坛

 找回密码
 立即注册
搜索
查看: 7829|回复: 11

VB中应用光线跟踪渲染

[复制链接]

42

主题

140

帖子

203

积分

中级会员

Rank: 3Rank: 3

积分
203
发表于 2003-10-16 16:50:00 | 显示全部楼层 |阅读模式
VB中应用光线跟踪渲染

                             ——zh1110,原程序由Almar Joling提供

这里演示一个最简单的光线跟踪算法的程序

如图,这是我为程序绘制的示意图,兰色假想为眼睛位置(0,0-600),黄色假想为灯光位置(100,100,-400),红色假想为球体位置(10,100,00),为了简单,只绘制零号球且未表达出Z坐标,但绘制比例是精确的

 
sf_20031016165055.gif

42

主题

140

帖子

203

积分

中级会员

Rank: 3Rank: 3

积分
203
 楼主| 发表于 2003-10-16 16:52:00 | 显示全部楼层

Re: VB中应用光线跟踪渲染

主要变量:

Private backBuffer(640& * 480&) As Long  '定义了存放图片数据的数组

Private Type Ray
  Origin As Vector
  Direction As Vector
End Type

Private primaryRay As Ray  '定义了观察者的位置及观察方向

Private directionTable() As Vector  '定义了射线方向(数组)

Public LightLoc As Vector  '定义了灯光的位置
 

主要函数:

Sub Main  '主函数

Rotate  '球体位置旋转的函数

GenerateRayDirectionTable()  '定义了开始的射线方向(数组)

TraceScene  '场景跟踪,球体的遮挡关系也在此进行

IntersectSphere  '射线与球体相交的长度计算

VectorDot    '向量点积(计算向量间的夹角或长度)

VectorNormalize   '单位化向量

待续

42

主题

140

帖子

203

积分

中级会员

Rank: 3Rank: 3

积分
203
 楼主| 发表于 2003-10-16 16:52:00 | 显示全部楼层

Re: Re: VB中应用光线跟踪渲染

Public Sub TraceScene(ByRef Spheres() As Sphere, ByRef numSpheres As Integer, ByRef LightLoc As Vector)
'// 开始计算射线
Dim X As Long, Y As Long, Z As Long
Dim closestIntersectionDistance As Single
Dim closestIntersectedSphereNum As Integer
Dim currResult As TraceResult
Dim lngBuffer As Long
'//改变loop大小让FPS 显示更快
'//尤其是外部的 loop 影响最大!!!
'//缩方, 这会改变窗口
For Y = 150 To 350
For X = 250 To 400
'//单一的数值会快很多...
primaryRay.Direction = directionTable(X + (Y * 640))
closestIntersectionDistance = 1000000
closestIntersectedSphereNum = -1
'//循环所有的球体找出最靠近眼睛的球体号

For Z = 0 To numSpheres
currResult = IntersectSphere(primaryRay, Spheres(Z))
If currResult.Hit Then
If currResult.Distance < closestIntersectionDistance Then
closestIntersectionDistance = currResult.Distance
closestIntersectedSphereNum = Z
Exit For
End If
End If
Next Z
'//仅计算相交最靠近眼睛的球体
If (closestIntersectedSphereNum > -1) Then
'//bits数组赋值
Bits(X, Y) = ShadeSphere(Spheres(closestIntersectedSphereNum), primaryRay, closestIntersectionDistance, LightLoc)
Else
With Bits(X, Y)
.rgbRed = 0
.rgbBlue = 0
.rgbGreen = 0
End With
End If
Next X
Next Y
With frmMain.picRay
'//复制 bits 数据到图片
SetDIBits lngHDC, lngImageHandle, 0, BInfo.bmiHeader.biHeight, Bits(0, 0), BInfo, DIB_RGB_COLORS
'图片刷新
.Refresh
End With
End Sub

 

Public Function IntersectSphere(ByRef myRay As Ray, ByRef mySphere As Sphere) As TraceResult
Dim rayToSphereCenter As Vector  '眼睛到球体中心的向量
Dim lengthRTSC2 As Single
Dim closestApproach As Single
Dim halfCord2 As Single
With IntersectSphere
.Hit = False
'// 眼睛到球体中心的向量并归到单一的原点

Call VectorSub(mySphere.Center, myRay.Origin, rayToSphereCenter)
'// lengthRTSC2 ='眼睛到球体中心距离的平方
lengthRTSC2 = VectorDot(rayToSphereCenter, rayToSphereCenter)
closestApproach = VectorDot(rayToSphereCenter, myRay.Direction)
'//如果是在背面,就返回失败(背面照不到光线)
If closestApproach < 0 Then Exit Function
'//halfCord2 = 球体中心到射线的垂直点与射线与球体交点的距离平方。
halfCord2 = (mySphere.Radius * mySphere.Radius) - lengthRTSC2 + (closestApproach * closestApproach) ' // sphere.radius 的平方可以在循环前先计算出来

42

主题

140

帖子

203

积分

中级会员

Rank: 3Rank: 3

积分
203
 楼主| 发表于 2003-10-16 16:52:00 | 显示全部楼层

Re: Re: Re: VB中应用光线跟踪渲染

  [em6] [em5] [em4]

42

主题

140

帖子

203

积分

中级会员

Rank: 3Rank: 3

积分
203
 楼主| 发表于 2003-10-16 16:55:00 | 显示全部楼层

Re: Re: Re: Re: VB中应用光线跟踪渲染

文件

sf_20031016165531.rar

37.86 KB, 下载次数:

42

主题

140

帖子

203

积分

中级会员

Rank: 3Rank: 3

积分
203
 楼主| 发表于 2003-10-17 11:36:00 | 显示全部楼层

Re: Re: Re: Re: Re: VB中应用光线跟踪渲染

sf_20031017113647.gif

42

主题

140

帖子

203

积分

中级会员

Rank: 3Rank: 3

积分
203
 楼主| 发表于 2003-10-17 11:37:00 | 显示全部楼层

Re:VB中应用光线跟踪渲染

'射线未与球体相交(光线未照到球体)
If (halfCord2 < 0) Then Exit Function
.Hit = True
.Distance = closestApproach - Sqr(halfCord2)
End With
End Function

 

Public Function ShadeSphere(ByRef mySphere As Sphere, ByRef myRay As Ray, ByRef Distance As Single, ByRef LightLoc As Vector) As RGBQUAD
Dim Intersection As Vector
Dim Normal As Vector
Dim LightDir As Vector
Dim LightCoef As Single
Dim OneOverRadius As Single
'//射线与球体交点的坐标位置计算 。
With myRay
Intersection.X = .Origin.X + Distance * .Direction.X
Intersection.Y = .Origin.Y + Distance * .Direction.Y
Intersection.Z = .Origin.Z + Distance * .Direction.Z
End With
'//计算交点处的法线
OneOverRadius = 1 / mySphere.Radius '预先计算数据会快一些,但也可能更慢,因为结果是32位数
With mySphere
'//相当于( intersection.x - sphere.center.x ) / sphere.radius
Normal.X = (Intersection.X - .Center.X) * OneOverRadius
Normal.Y = (Intersection.Y - .Center.Y) * OneOverRadius
Normal.Z = (Intersection.Z - .Center.Z) * OneOverRadius
'//计算灯光到交点的单位向量
Call VectorSub(LightLoc, Intersection, LightDir)
Call VectorNormalize(LightDir)
'计算灯光系数—它会与球体颜色相乘
LightCoef = VectorDot(Normal, LightDir)
If (LightCoef < 0) Then LightCoef = 0
'计算颜色并返回
ShadeSphere.rgbRed = .Color.R * LightCoef
ShadeSphere.rgbGreen = .Color.G * LightCoef
ShadeSphere.rgbBlue = .Color.B * LightCoef
End With
End Function

可见算法的基本过程是先计算眼睛与球体相交的射线,交点,再反过来计算灯光发出的光线。最后通过通过灯光与法线的夹角计算出颜色


25

主题

234

帖子

262

积分

中级会员

Rank: 3Rank: 3

积分
262
发表于 2003-10-17 14:34:00 | 显示全部楼层

Re:VB中应用光线跟踪渲染

看看先。favorites

3

主题

67

帖子

67

积分

注册会员

Rank: 2

积分
67
发表于 2008-7-6 22:22:00 | 显示全部楼层

Re:VB中应用光线跟踪渲染

试试,此贴会不会被删除

1

主题

103

帖子

119

积分

注册会员

Rank: 2

积分
119
发表于 2008-7-6 22:26:00 | 显示全部楼层

Re:VB中应用光线跟踪渲染

楼主明显不知趣,现在是教主布道的时候,你发这种低劣,丑陋的光线追踪技术干什么?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-22 01:40

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表