详解cuda by example中第六章光线追踪代码

最近在学习cuda by example第六章时发现代码看不太懂(本人小菜鸡勿喷),经过学习(chatgpt的帮助)后对这段代码有了比较清晰的理解,于是打算对这段代码进行一个注解,仅供学习,如果大家有发现不对的地方欢迎指正

定义线程块与线程一个线程块包含一个16*16的线程

int dim=1024
//dim3 是 CUDA 中定义三维向量的类型,用于指定网格的维度。网格是由多个线程块组成的。grids 定义了网格的尺寸为 64x64,这意味着在网格中会有 64 行和 64 列,总共 4096 个线程块
dim3    grids(DIM / 16, DIM / 16);
//这行代码定义了每个线程块的尺寸,也使用 dim3 这种三维向量类型。threads(16, 16) 表示每个线程块由 16x16 个线程组成,总共 256 个线程。
dim3    threads(16, 16);

以下是结构体注释

#include "cuda.h"
#include "../common/book.h"
#include "../common/cpu_bitmap.h"

#define DIM 1024//相当于设定了一个1024*1024的像素分布

#define rnd( x ) (x * rand() / RAND_MAX)
#define INF     2e10f
//定义一个球形结构体
struct Sphere {
    float   r, b, g; //定义球体颜色
    float   radius; //半径
    float   x, y, z; //原点坐标
    __device__ float hit(float ox, float oy, float* n) {//ox,oy为平面上的一点可以理解为书中所说的像素,float* n用来返回一个比例系数
        float dx = ox - x;//计算某一像素x坐标与球体x坐标的差值
        float dy = oy - y;//计算某一像素y坐标与球体y坐标的差值
        if (dx * dx + dy * dy < radius * radius) {//在xOy平面上判断是否在球面内
            float dz = sqrtf(radius * radius - dx * dx - dy * dy);//通过勾股定理算以球中心点的xOy平面上这个像素到球体表面的距离
            *n = dz / sqrtf(radius * radius);//计算一个比例系数(用来模拟光线减弱)
            return dz + z;//返回实际上的像素点到球体表面的距离
        }
        return -INF;
    }
}; 
#define SPHERES 20 

以下是核函数的解释

__constant__ Sphere s[SPHERES];

__global__ void kernel(unsigned char* ptr) {
    // map from threadIdx/BlockIdx to pixel position
    //x 和 y:当前线程所负责的像素的 x 和 y 坐标。
    /*blockIdx.x表示线程块的x方向(第一维)上的序号,
    blockDim.x表示线程块x方向(第一维)上有几个线程*/
    int x = threadIdx.x + blockIdx.x * blockDim.x;
    /*blockIdx.y表示线程块的y方向(第二维)上的序号,
    blockDim.y表示线程块y方向(第二维)上有几个线程*/
    int y = threadIdx.y + blockIdx.y * blockDim.y;

    //offset:计算每个像素在图像数据数组中的位置。offset 是 ptr 数组的索引,用于定位像素在内存中的位置。
    int offset = x + y * blockDim.x * gridDim.x;//这里以一个二维数组去联想,x相当于列的序号,y相当于行的序号
    //将 (x, y) 从图像的左上角为原点的坐标系转换到图像中心为原点的坐标系
    float   ox = (x - DIM / 2);
    float   oy = (y - DIM / 2);
    //给一个默认r,g,b参数,即背景参数(注意下面代码*255,这几个参数相当于系数)
    float   r = 1, g = 1, b = 1;
    float   maxz = -INF;

    
    for (int i = 0; i < SPHERES; i++) {
        float   n;//比例系数用来模拟光线减弱
        float   t = s[i].hit(ox, oy, &n);
        if (t > maxz) {
            float fscale = n;//之前所说的比例系数,用来模拟光线减弱
            r = s[i].r * fscale;
            g = s[i].g * fscale;
            b = s[i].b * fscale;
            maxz = t;
        }
    }
    //一个像素有四个属性r,g,b,透明度
    ptr[offset * 4 + 0] = (int)(r * 255);
    ptr[offset * 4 + 1] = (int)(g * 255);
    ptr[offset * 4 + 2] = (int)(b * 255);
    ptr[offset * 4 + 3] = 255;
}


计算时间的代码就不注释了,主要就解释一下核函数以及结构体,如果有错误还请大家指正

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值