5 圖片貼圖映射

  咱們以前使用撞點P來索引一個固體紋理,好比大理石。咱們還能夠讀取圖像,並使用2D紋理座標索引到圖像上。web

  在圖像中縮放(u,v)的直接方法是將u和v四捨五入爲整數,並將其用做(i,j)像素。可是這很尷尬,由於當咱們改變圖像分辨率時,咱們不想改變代碼。所以,最廣泛的非官方標準之一是使用紋理座標而不是圖像像素座標。這些只是圖像中分數位置的一種形式。例如,對於nx中的像素(i,j),圖像紋理的位置爲:數組

    u = i/(nx-1)
    v = j/(nx-1)函數

  這只是一個分數位置。對於一個真正的撞擊物體,咱們還須要返回一個u和v在命中記錄。對於球體,這一般是基於某種形式的經度和緯度,即。球座標。若是咱們有一個(theta,phi)在球座標系中咱們只須要縮放和分數。若是是從極點向下的角度,是繞軸穿過極點的角度,那麼歸一化到[0,1]的歸一化就是:工具

    u = phi / (2*Pi)
    v = theta / Pispa

  爲了計算θ和π,對於給定的擊中點,單位半徑球在原點上的球面座標公式爲:  blog

    x = cos(phi) cos(theta)
    y = sin(phi) cos(theta)
    z = sin(theta)索引

  咱們須要反轉過來。 因爲可愛的math.h的函數atan2()--- 取任意數字與正弦和餘弦成比例並返回角度,咱們能夠傳入x和y (cos(theta)取消):get

    phi = atan2(y, x)it

  atan2在-Pi到Pi的範圍內返回,因此咱們須要在那裏稍加註意。 theta更直截了當:class

    theta = asin(z)

  它返回-Pi / 2到Pi / 2範圍內的數字。

  所以,對於球體,u,v coord計算由效用函數完成,該函數指望單位球體上的物體以原點爲中心。 sphere :: hit中的調用應該是:

  get_sphere_uv((rec.p-center)/radius, rec.u, rec.v);

  效用函數是:

    

  如今咱們還須要建立一個包含圖像的紋理類。我將使用我最喜歡的圖像工具stb_image。它將圖像讀入一個大的無符號字符數組。這些就是每一個範圍爲0的RGBs。255爲黑色至全亮。

    

  按這個順序排列的填充數組的表示是至關標準的。值得慶幸的是,stb_image包使這變得很是簡單——只需在main中用#define包含header的定義:  

    #define STB_IMAGE_IMPLEMENTATION
    #include "stb_image.h"

  爲了從一個文件eathmap.jpg中讀取一個圖像(我剛剛從web上抓取了一個隨機的地球地圖——任何標準的投影均可以實現咱們的目的),而後將其分配給一個漫反射的材料,代碼是:

    int nx, ny, nn;
    unsigned char *tex_data = stbi_load("earthmap.jpg", &nx, &ny, &nn, 0);
    material *mat = new lambertian(new image_texture(tex_data, nx, ny));

  咱們開始看到全部顏色的一些能量都是紋理 - 咱們能夠爲朗伯物質分配任何類型的紋理,理想散射不須要意識到它。

相關文章
相關標籤/搜索