光线追踪

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

#include <osgViewer/Viewer>

#include <osgDB/WriteFile>

const
int GRID_WIDTH = 1024;

const
int GRID_HEIGHT = 800;

#pragma comment(lib, "osgd.lib")

#pragma comment(lib, "osgViewerd.lib")

#pragma comment(lib, "osgDBd.lib")

class
CRay

{

public:

    CRay(osg::Vec3 orgin, osg::Vec3 direction)

        :_orgin(orgin)

        ,_direction(direction)

    {

        

    }

    osg::Vec3 GetOrgin()

    {

        return
_orgin;

    }

    

    void
SetOrgin(osg::Vec3 orgin)

    {

        _orgin = orgin;

    }

    osg::Vec3 GetDirection()

    {

        return
_direction;

    }

    

    void
SetDirection(osg::Vec3 dir)

    {

        _direction = dir;

    }

    osg::Vec3 GetPoint(float
t)

    {

        return
_orgin + _direction * t;

    }

private:

    osg::Vec3 _orgin;

    osg::Vec3 _direction;

    float    
_t;

};

class
CIntersectResult

{

public:

    CIntersectResult()

        :_isHit(false)

    {

            

    }

    static
CIntersectResult NoHit()

    {

        return
CIntersectResult();

    }

public:

    bool       
_isHit;

    float      
_distance;

    osg::Vec3   _position;

    osg::Vec3   _normal;

};

class
CGeometry

{

public:

    CGeometry()

    {

    }

    virtual
CIntersectResult IsIntersect(CRay ray) = 0;

};

class
CSphere : public
CGeometry

{

public:

    CSphere()

        :CGeometry()

    {

    }

    CSphere(osg::Vec3 center, double
radius)

        :CGeometry()

        ,_center(center)

        ,_radius(radius)

    {

    }

    CSphere(CSphere & s)

    {

        _center = s.GetCenter();

        _radius = s.GetRadius();

    }

    void
SetCenter(osg::Vec3 & center)

    {

        _center = center;  

    }

    void
SetRadius(float
radius)

    {

        _radius = radius;

    }

    osg::Vec3 GetCenter()

    {

        return
_center;

    }

    float
GetRadius()

    {

        return
_radius;

    }

    osg::Vec3 GetNormal(osg::Vec3 p)

    {

        return
p - _center;

    }

    virtual
CIntersectResult IsIntersect(CRay ray)

    {

        CIntersectResult result = CIntersectResult::NoHit();

        osg::Vec3 v = ray.GetOrgin() - _center;

        float
a0 = v * v - _radius * _radius;

        float
dir_dot_v = ray.GetDirection() * v;

        if
(dir_dot_v < 0)

        {

            float
discr = dir_dot_v * dir_dot_v - a0;

            if
(discr >= 0)

            {

                result._isHit = true;

                result._distance = -dir_dot_v - std::sqrt(discr);

                result._position = ray.GetPoint(result._distance);

                result._normal = result._position - _center;

                result._normal.normalize();

            }

        }

        return
result;

    }

private:

    osg::Vec3 _center;

    float    
_radius;

};

class
CPerspectiveCamera

{

public:

    CPerspectiveCamera()

    {

        

    }

    ~CPerspectiveCamera()

    {

    }

    CPerspectiveCamera(const
osg::Vec3 & eye, const
osg::Vec3 & front, const
osg::Vec3 & refUp, float
fov)

    {

        _eye = eye;

        _front = front;

        _refUp = refUp;

        _fov = fov;

        _right = _front ^ _refUp;

        _up = _right ^ _front;

        _fovScale = std::tan(fov * osg::PI * 0.5 / 180.0) * 2.0;

    }

    CRay GenerateRay(float
x, float
y)

    {

        osg::Vec3 r = _right * ((x - 0.5f) * _fovScale);

        osg::Vec3 u = _up * ((y - 0.5f) * _fovScale);

        osg::Vec3 temp = _front + r + u;

        temp.normalize();

        return
CRay(_eye, temp);

    }

private:

    osg::Vec3 _eye;

    osg::Vec3 _front;

    osg::Vec3 _refUp;

    float    
_fov;

    osg::Vec3 _right;

    osg::Vec3 _up;

    float    
_fovScale;

};

osg::ref_ptr<osg::Image> CreateImage()

{

    osg::ref_ptr<osg::Image> image = new
osg::Image;

    image->allocateImage(1024, 800, 1, GL_RGBA, GL_UNSIGNED_BYTE);

    unsigned char
* data = image->data();

    CPerspectiveCamera camera(osg::Vec3(0.0, 10.0, 10), osg::Vec3(0.0, 0.0, -1.0), osg::Vec3(0.0, 1.0, 0.0), 90);

    float
depth = 7.0;

    float
maxDepth = 18.0;

    CSphere sphere(osg::Vec3(0.0, 10, -10.0), 10.0);

    float
dx = 1.0f/GRID_WIDTH;

    float
dy = 1.0f/GRID_HEIGHT;

    float
dDepth = 255.0f/maxDepth;

    int
i = 0;

    for
(int
y = 0; y < GRID_HEIGHT; ++y)

    {

        float
sy = 1 - dy * y;

        for
(int
x = 0; x < GRID_WIDTH; ++x)

        {

            float
sx = dx * x;

            CRay ray(camera.GenerateRay(sx, sy));

            CIntersectResult result = sphere.IsIntersect(ray);

            if
(result._isHit)

            {

                float
t = std::min(result._distance * dDepth, 255.0f);

                int
depth = (int)(255 - t);

                data[i] = depth;

                data[i+1] = depth;

                data[i+2] = depth;

                data[i+3] = 255;

            }

            i += 4;

        }

    }

    return
image.get();

}

int
main()

{

    osg::ref_ptr<osg::Image> image = CreateImage();

    osgDB::writeImageFile(*image.get(), "H:/1.png");

    return
0;

}

光线追踪

时间: 2024-11-07 19:08:40

光线追踪的相关文章

一个光线追踪demo

去年写的一个练手项目,完成了三维场景的光线追踪,基于Phong模型. 支持的基本类型为球和矩形,其中矩形支持函数纹理贴图. 直接上图: 图中只有一个球,左侧为一个镜子. 左侧为一个折射率为1.5的折射球,右侧为一个全反射球. http://files.cnblogs.com/files/PiedmontStream/trace.zip

光线追踪发射主光线

光线追踪是图形学领域里最为著名的一种技术,其中首要的一步是视点(相机,眼睛)穿过像素中心,发射一条射线,也就是主光线(次级光线指的是从物体表面反射或折射等发出的光线).这一步看起来比较简单,但仍然涉及到一些细节和概念需要厘清.我系统的学习这些东西是从renderman规范开始的,看的第一本书是advanced renderman,这本比较难,我更推荐看An Introduction to Ray Tracing (1989).开始正题.首先,要搞清楚fov角,advanced renderman

Unity编辑器中光照贴图背后的PowerVR光线追踪技术

今年八月,大量的游戏开发者走进Unite 2014,齐聚在西雅图中心参加Unite第八届年度会议.在一系列令人兴奋的会议以及主题演讲中,来自我们PowerVR光线追踪团队的Jens Fursund介绍了即将推出的Unity 5光照贴图编辑器,使用光线追踪技术以快速.准确地模拟光照. 我们非常高兴与Unity的合作,在最近的展示和活动中,我们已经从观看该工具演示的一些开发者中得到很多积极反馈. 让我们来快速浏览一下PowerVR光线追踪技术如何通过新光照贴图编辑器助力开发人员和艺术家加快作品开发.

实现一个光线追踪器

写一个光线追踪器是一个很有意思的事情,光线追踪器的原理很简单,但是却能生成真实感强的图片. 使用bart场景写了一个光线追踪器,使用多线程和BVH加速,源码:https://github.com/tuituji/bart. 生成的照片: cnblogs不能上传视频?

全局光照:光线追踪、路径追踪与GI技术进化编年史

全局光照(Global Illumination,简称 GI), 作为图形学中比较酷的概念之一,是指既考虑场景中来自光源的直接光照,又考虑经过场景中其他物体反射后的间接光照的一种渲染技术. 大家常听到的光线追踪,路径追踪等同样很酷的概念,都是全局光照中人气较高的算法流派. 而这篇文章将围绕全局光照技术,介绍的要点有: 全局光照的基本概念 全局光照的算法主要流派 全局光照技术进化编年史 光线追踪 Ray Tracing 路径追踪 Path Tracing 光线追踪.路径追踪.光线投射的区别 环境光

基本光线追踪软件的设计与实现

参考文章:http://www.cnblogs.com/miloyip/archive/2010/03/29/1698953.html 这篇文章做的是计算机图形学中传统的光线追踪渲染,用的递归,最大反射次数为3,phong材料. (上图 1024* 1024) 运行测速 = 0.09帧/秒 流程: 1.建立场景 2.相机发出射线 3.追踪该射线 4.根据光照模型和光照方向渲染 代码中的特点: 1.找到的这份代码,用的是结构体struct来定义的用于计算的数据,搜索了下C++里面的struct和c

2 必要的光线追踪算法=&gt;光线球体的相交和映射

球是光线追踪中最常用的图元之一,同时,由于计算相交最容易,也被用于包围盒算法中.因此,深入研究本节这个问题的解决方案.首先导出了简单的代数解.然后考察了问题的特殊条件,提出了一种更有效的几何解.分析结果的比较表明了两种算法的基本等价性. 对射线追踪中常见的缺陷进行了研究,并提出了一些解决方法. 球面最常见的逆映射算法总结了这一节. 原文地址:https://www.cnblogs.com/TooYoungTsukasa/p/9201671.html

光线追踪&lt;1-1&gt; 超详解《Ray Tracing in One Weekend》

Preface 从这一篇起,我们开始学光线追踪这门牛逼的技术.读了几天,一个字:强! 这一篇我们主要讲述技术入门和一些简单的案例. 我们先学这本: Ready 这本书需要ppmview这个软件帮忙看效果图,不过下载也非常快. 其次,需要你会C/C++读写文件 最后需要你具备三维空间想象能力以及我对书中公式的讲述 Chapter1: Output an image 先看一张图,秒懂一下它如何设置像素 话说,有这么一个文件,叫做.ppm文件.它以水平向右为x正方向,以垂直向下为y正方向. 它的文件存

【Ray Tracing in One Weekend 超详解】 光线追踪1-10

<Ray Tracing in One Weekend>完结篇 最近课程上机实验,封面图渲染时间也超长,所以写东西就落下了,见谅 这篇之后,我会继续<Ray Tracing The Next Week>,还请多多关注 这几天我在渲染这本书的封面图,封面图还没出,不算结束,刚好安排了10节 今天呢,有两件事: 1.阐述整个工程的文件组织即内容 2.阐述封面,完结 12.1工程文件组织 试过很多方法,问过很多老师,无奈,子类继承实现的父类纯虚函数实在无法和类声明分成两个文件(即声明放于