【Ray Tracing The Next Week 超详解】 光线追踪2-5

Chapter 5:Image Texture Mapping

先看效果:

【Ray Tracing The Next Week 超详解】 光线追踪2-5

【Ray Tracing The Next Week 超详解】 光线追踪2-5

 

我们之前的纹理是利用的是撞击点p处的位置信息,比如大理石纹理

而我们今天的图片映射纹理采用2D(u,v)纹理坐标来进行。

在图像中使用缩放(u,v)的直接方法是将u和v四舍五入为整数,并将其作用于(i,j)像素。而,我们的纹理和物体的尺寸并不一致,所以我们需要将其规格化,然后再放大适应至物体尺寸。即,我们采用某个点在当前图像中的比例,而不是具体的位置,例如,对于nx乘ny图像中的像素(i,j),图像纹理位置为:

u = i / (nx - 1)

v = j / (ny - 1)

对于intersect,我们还需要在相交碰撞记录中返回u和v。对于球体,我们采用球面坐标。即:

 

【Ray Tracing The Next Week 超详解】 光线追踪2-5

如上坐标系采用光线追踪惯用坐标系,设P点为单位球上一点

∠θ 为xOz平面与线段OP之间的夹角,θ∈0~π

∠φ 为线段OP在xOz平面的映射线与x轴正方向之间的夹角,φ∈0~2π

则:

x = cosφ· cosθ

z = sinφ· cosθ
y = sinθ

 

将θ和φ规格化到【0,1】,则如下:

u = φ/(2π)

v = θ/π

 

 过程:

我们先将撞击点的坐标映射到单位球面上(规格化),得到纹理坐标

然后材质纹理反射的时候将此规格化坐标带入

根据图片的规格展开得到图片对应的位置,返回图片对应处的rgb

 

可见,撞击点处应该存储关于图片纹理坐标的信息

所以,我们先将撞击点信息更新:

【Ray Tracing The Next Week 超详解】 光线追踪2-5

 

获取纹理坐标

【Ray Tracing The Next Week 超详解】 光线追踪2-5

【Ray Tracing The Next Week 超详解】 光线追踪2-5

 

反射求取图片对应出的像素值

【Ray Tracing The Next Week 超详解】 光线追踪2-5

 

我们来解决图片纹理对应的value函数

下面是图片纹理类

 

【Ray Tracing The Next Week 超详解】 光线追踪2-5

【Ray Tracing The Next Week 超详解】 光线追踪2-5

/// image_tex.hpp // ----------------------------------------------------- // [author] lv // [begin ] 2019.1 // [brief ] the image_texture-class for the ray-tracing project // from the 《ray tracing the next week》 // ----------------------------------------------------- #pragma once namespace rt { class image_texture: public texture { public: image_texture() { } image_texture(unsigned char* image, size_t a, size_t b); inline unsigned char* image()const { return _image; } inline size_t sizeX()const { return _sizeX; } inline size_t sizeY()const { return _sizeY; } public: virtual rtvec value(rtvar u, rtvar v, const rtvec& p)const override; private: unsigned char* _image; size_t _sizeX; size_t _sizeY; }; image_texture::image_texture(unsigned char* image, size_t a, size_t b) :_image(image) ,_sizeX(a) ,_sizeY(b) { } rtvec image_texture::value(rtvar u, rtvar v, const rtvec& p)const { int i = u*_sizeX; int j = (1 - v)*_sizeY - 0.001; if (i < 0)i = 0; if (j < 0)j = 0; if (i > _sizeX - 1)i = _sizeX - 1; if (j > _sizeY - 1)j = _sizeY - 1; rtvar r = int(_image[3 * i + 3 * _sizeX*j]) / 255.0; rtvar g = int(_image[3 * i + 3 * _sizeX*j + 1]) / 255.0; rtvar b = int(_image[3 * i + 3 * _sizeX*j + 2]) / 255.0; return rtvec(r, g, b); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjwsp.html