zoukankan      html  css  js  c++  java
  • 5 图片贴图映射

      我们之前使用撞点P来索引一个固体纹理,比如大理石。我们还可以读取图像,并使用2D纹理坐标索引到图像上。

      在图像中缩放(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 / Pi

      为了计算θ和π,对于给定的击中点,单位半径球在原点上的球面坐标公式为:  

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

      我们需要反转过来。 由于可爱的math.h的函数atan2()--- 取任意数字与正弦和余弦成比例并返回角度,我们可以传入x和y (cos(theta)取消):

        phi = atan2(y, x)

      atan2在-Pi到Pi的范围内返回,所以我们需要在那里稍加注意。 theta更直截了当:

        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));

      我们开始看到所有颜色的一些能量都是纹理 - 我们可以为朗伯物质分配任何类型的纹理,理想散射不需要意识到它。

      

  • 相关阅读:
    有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
    C编程实现2的1000次方(使程序中的n=1000即可)
    有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面m个数。
    有一个字符串,内有若干字符,输入一个字符,要求程序将字符串中该字符删去。
    使用静态变量的方法求n!
    数组排序:冒泡法和选择法
    使用函数的递归调用来解决Hanoi(汉诺)塔问题。
    VC5509的通用GEL代码
    字、字节和位的关系
    安装JDK后环境变量的配置
  • 原文地址:https://www.cnblogs.com/TooYoungTsukasa/p/9342501.html
Copyright © 2011-2022 走看看