Chapter 5:Image Texture Mapping

先看效果:

我们之前的纹理是利用的是撞击点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。对于球体,我们采用球面坐标。即:

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

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

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

则:

x = cosφ· cosθ

z = sinφ· cosθ
y = sinθ

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

u = φ/(2π)

v = θ/π

过程:

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

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

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

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

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

获取纹理坐标

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

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

下面是图片纹理类

/// 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 = ( - v)*_sizeY - 0.001;
if (i < )i = ;
if (j < )j = ;
if (i > _sizeX - )i = _sizeX - ;
if (j > _sizeY - )j = _sizeY - ;
rtvar r = int(_image[ * i + * _sizeX*j]) / 255.0;
rtvar g = int(_image[ * i + * _sizeX*j + ]) / 255.0;
rtvar b = int(_image[ * i + * _sizeX*j + ]) / 255.0;
return rtvec(r, g, b);
} }

image_texture.hpp

因为图片信息是有一维数组存储的,每个元素的rgb是顺序存储的,所以每个像素点有三个值,所以求取对应位置索引的时候要用3乘

现在我们需要的是读取并存储图像文件

我们采用stb图片读取处理库,我们就用一个函数

我们要在库引用之前先定义一个宏

#define STB_IMAGE_IMPLEMENTATION

然后#include “stb_image.h”

如果你们找不到地球图,就去我相册中下载一下吧

或者随便找一个也行

然后就可以得到第一张图

第二章图的话,就是下面那个是金属材质的球,可以采用下面函数

如果有什么代码不完整的可以在下面留言

我们的代码,一般情况下会在每本书的后面做统一的整理公布

感谢您的阅读,生活愉快~

【Ray Tracing The Next Week 超详解】 光线追踪2-5的更多相关文章

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

    我们来整理一下项目的代码 目录 ----include --hit --texture --material ----RTdef.hpp ----ray.hpp ----camera.hpp ---- ...

  2. 【Ray Tracing The Next Week 超详解】 光线追踪2-6 Cornell box

    Chapter 6:Rectangles and Lights 今天,我们来学习长方形区域光照  先看效果 light 首先我们需要设计一个发光的材质 /// light.hpp // ------- ...

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

    我们上一篇写了Chapter5 的第一个部分表面法线,那么我们来学剩下的部分,以及Chapter6. Chapter5:Surface normals and multiple objects. 我们 ...

  4. 【Ray Tracing The Next Week 超详解】 光线追踪2-7 任意长方体 && 场景案例

    上一篇比较简单,很久才发是因为做了一些好玩的场景,后来发现这一章是专门写场景例子的,所以就安排到了这一篇 Preface 这一篇要介绍的内容有: 1. 自己做的光照例子 2. Cornell box画 ...

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

     Preface 今天有两个东东,一个是体积烟雾,一个是封面图 下一篇我们总结项目代码 Chapter 8:Volumes 我们需要为我们的光线追踪器添加新的物体——烟.雾,也称为participat ...

  6. 【Ray Tracing in One Weekend 超详解】 光线追踪1-8 自定义相机设计

    今天,我们来学习如何设计自定义位置的相机 ready 我们只需要了解我们之前的坐标体系,或者说是相机位置 先看效果   Chapter10:Positionable camera 这一章我们直接用概念 ...

  7. 【Ray Tracing The Next Week 超详解】 光线追踪2-4 Perlin noise

     Preface 为了得到更好的纹理,很多人采用各种形式的柏林噪声(该命名来自于发明人 Ken Perlin) 柏林噪声是一种比较模糊的白噪声的东西:(引用书中一张图) 柏林噪声是用来生成一些看似杂乱 ...

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

     Preface 终于到了激动人心的纹理章节了 然鹅,看了下,并不激动 因为我们之前就接触过 当初有一个 attenuation 吗? 对了,这就是我们的rgb分量过滤器,我们画出的红色.蓝色.绿色等 ...

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

    Chapter 2:Bounding Volume Hierarchies 今天我们来讲层次包围盒,乍一看比较难,篇幅也多,但是咱们一步一步来,相信大家应该都能听懂 BVH 和 Perlin text ...

随机推荐

  1. Android:(本地、可通信的、前台、远程)Service使用全面介绍

    2.具体使用解析 2.1 本地Service 这是最普通.最常用的后台服务Service. 2.1.1 使用步骤 步骤1:新建子类继承Service类 需重写父类的onCreate().onStart ...

  2. Shiro会话管理器与验证码实现(十四)

    和shiro整合后,使用shiro的session管理,shiro提供sessionDao操作 会话数据. 配置sessionManager

  3. linux 网卡

    查看网卡UUID:nmcli con show    或    nmcli con list 查看网卡mac地址:nmcli dev show    或    nmcli dev list 注:sho ...

  4. 【Mysql sql inject】【入门篇】SQLi-Labs使用 part 1【01-11】

    人员流动性过大一直是乙方公司痛点.虽然试用期间都有岗前学习,但老员工忙于项目无暇带新人成长,入职新人的学习基本靠自己不断摸索.期望看相关文档就可以一蹴而是不现实的.而按部就班的学习又很难短期内将知识有 ...

  5. redis拾趣(客户端连接,keys命令,数据备份,缓存有效期等)

    1.客户端连接 为了安全保护,redis支持绑定IP跟端口,这个通过conf配置文件中的bind跟port来设置. 绑定后登录client控制台时就需要写明ip(或者hostname)跟端口了,如: ...

  6. android手机访问app网页报错:net::ERR_PROXY_CONNECTION_FAILED

    手机访问网页报错:net::ERR_PROXY_CONNECTION_FAILED 手机访问app中嵌入的html网页报错: net::ERR_PROXY_CONNECTION_FAILED 原来是手 ...

  7. jdbc驱动加载

    使用sqlserver数据库时,加载驱动: Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); Strin ...

  8. Ex 3_25 图中每个顶点有一个相关价格..._十一次作业

    (a)首先对有向无环图进行拓扑排序,再按拓扑排序的逆序依次计算每个顶点的cost值,每个顶点的cost值为自身的price值与相邻顶点间的cost值得最小值 (b)求出图中的每一个强连通分量,并把所有 ...

  9. Appium+Java(一) Windows环境搭建篇

    准备: Android版本 :4.2.2 nodejs版本:5.6.0 appium版本:v1.4.16 1. 安卓SDK及配置环境变量 1.1.先下载sdk安装包:installer_r24.4.1 ...

  10. JavaScript 使用 mediaDevices API 选择摄像头

    大多数智能手机都有前置和后置摄像头,当你在创建视频应用时你可能想要选择或者切换前置.后置摄像头. 如果你开发的是一款聊天应用,你很可能会想调用前置摄像头,但如果你开发的是一款拍照软件,那么你会更倾向于 ...