使用opencl进行快速光栅化

问题描述 投票:-1回答:1

我正在使用opencl编写用于实时3d渲染的光栅化器。

我当前的体系结构:

  • 顶点着色器:每个顶点1个线程
  • 光栅化器:每个面有1个线程,遍历该面覆盖的所有像素
  • 片段着色器:每个像素1个线程

这在面部占据较小的屏幕空间时很好用,但是当我有一个覆盖大部分屏幕时,由于光栅化线程必须同步遍历该面部覆盖的所有像素,因此帧速率降低。

我认为可以通过平铺方法解决。屏幕将被划分为多个小块(图块),并且每个图块将启动一个线程。仅边界框与图块重叠的面将被处理。

尽管我对此方法有一些疑问:

  • 我应该找到图块的重叠面是CPU还是GPU?
  • 应该使用什么数据结构存储面孔列表?它们的长度是可变的,但是我相信OpenCL缓冲区是固定长度的。

当前实现的宿主代码示例:

// set up vertex shader args
queue.enqueueNDRangeKernel(vertexShader, cl::NullRange, numVerts, cl::NullRange);

// set up rasterizer args
queue.enqueueNDRangeKernel(rasterizer, cl::NullRange, numFaces, cl::NullRange);

// set up fragment shader args
queue.enqueueNDRangeKernel(fragmentShader, cl::NullRange, numPixels, cl::NullRange);

// read frame buffer to draw to screen
queue.enqueueReadBuffer(buffer_screen, CL_TRUE, 0, width * height * 3 * sizeof(unsigned char), screen);

光栅化器内核示例:

float2 bboxmin = (float2)(INFINITY,INFINITY);
float2 bboxmax = (float2)(-INFINITY,-INFINITY);

float2 clampCoords = (float2)(width-1, height-1);

// get bounding box
for (int i=0; i<3; i++) {
    for (int j=0; j<2; j++) {
        bboxmin[j] = max(0.f, min(bboxmin[j], vs[i][j]));
        bboxmax[j] = min(clampCoords[j], max(bboxmax[j], vs[i][j]));
    }
}

// loop over all pixels in bounding box
// this is the part that needs to be improved
int2 pix;
for (pix.x=bboxmin.x; pix.x<=bboxmax.x; pix.x++) {
    for (pix.y=bboxmin.y; pix.y<=bboxmax.y; pix.y++) {
        float3 bc_screen  = barycentric(vs[0].xy, vs[1].xy, vs[2].xy, (float2)(pix.x,pix.y), offset);
        float3 bc_clip    = (float3)(bc_screen.x/vsVP[0][3], bc_screen.y/vsVP[1][3], bc_screen.z/vsVP[2][3]);

        bc_clip = bc_clip/(bc_clip.x+bc_clip.y+bc_clip.z);

        float frag_depth = dot(homoZs, bc_clip);
        int pixInd = pix.x+pix.y*width;

        if (bc_screen.x<0 || bc_screen.y<0 || bc_screen.z<0 || zbuffer[pixInd]>frag_depth) continue;

        zbuffer[pixInd] = frag_depth;

    }
}
opengl graphics opencl rasterizing
1个回答
0
投票

一种解决方法是,如果脸部过大而返回,则取消栅格化。这将导致一些视觉失真,但至少不会影响帧频。

© www.soinside.com 2019 - 2024. All rights reserved.