Advertisement
Zgragselus

Mess of a kernel

Jun 12th, 2024
487
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.71 KB | None | 0 0
  1. extern "C" __global__ void otrace_kernel(void)
  2. {
  3.     // Get information from constant memory
  4.     const OtraceInput& in = c_OtraceInput;
  5.     int numRays = in.numRays;
  6.     bool anyHit = in.anyHit;
  7.     float4* rays = (float4*)in.rays;
  8.     int4* results = (int4*)in.results;
  9.     float4* nodesA = (float4*)in.nodesA;
  10.     float4* nodesB = (float4*)in.nodesB;
  11.     float4* nodesC = (float4*)in.nodesC;
  12.     float4* nodesD = (float4*)in.nodesD;
  13.     float4* trisA = (float4*)in.trisA;
  14.     float4* trisB = (float4*)in.trisB;
  15.     float4* trisC = (float4*)in.trisC;
  16.     int* triIndices = (int*)in.triIndices;
  17.     float2* texCoords = (float2*)in.texCoords;
  18.     float3* normals = (float3*)in.normals;
  19.     int3* vertIdx = (int3*)in.triVertIndex;
  20.     float4* atlasInfo = (float4*)in.atlasInfo;
  21.     int* matId = (int*)in.matId;
  22.     float4* matInfo = (float4*)in.matInfo;
  23.     int emissiveCount = in.emissiveNum;
  24.     int3* emissive = (int3*)in.emissive;
  25.     int trisCount = in.trisCount;
  26.     int3* tris = (int3*)in.tris;
  27.     int vertsCount = in.vertsCount;
  28.     float3* verts = (float3*)in.verts;
  29.     int randomSeed = in.randomSeed;
  30.     unsigned int* triMaterialColor    = (unsigned int*)in.matColor;
  31.  
  32.     int rayidx = threadIdx.x + blockDim.x * (threadIdx.y + blockDim.y * (blockIdx.x + gridDim.x * blockIdx.y));
  33.     if (rayidx >= numRays)
  34.         return;
  35.  
  36.     // Cast primary ray
  37.     int hitIndex;
  38.     float hitU;
  39.     float hitV;
  40.     float hitT;
  41.     float4 result = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
  42.     float4 primO = rays[rayidx * 2 + 0];
  43.     float4 primD = rays[rayidx * 2 + 1];
  44.     float4 tempDir;
  45.     float mult_val = 1.0f;
  46.  
  47.     /*result = make_float4(-random(in.randomSeed, rayidx),
  48.         -random(in.randomSeed, rayidx),
  49.         -random(in.randomSeed, rayidx),
  50.         1.0f);
  51.     STORE_RESULT(rayidx, hitIndex, result.x, result.y, result.z);
  52.     return;*/
  53.  
  54.     // For each sample per pixel
  55.     for (int spp = 0; spp < SAMPLES_PER_PIXEL; spp++)
  56.     {
  57.         // Grab primitive origin and direction
  58.         rays[rayidx * 2 + 0] = primO;
  59.         rays[rayidx * 2 + 1] = primD;
  60.  
  61.         int depth = 0;
  62.         float4 color = make_float4(0.0f, 0.0f, 0.0f, 1.0f);             // Accumulated color
  63.         float4 reflectance = make_float4(1.0f, 1.0f, 1.0f, 1.0f);       // Accumulated reflectance
  64.         while(true)
  65.         {
  66.             // If we miss, return black
  67.             bool hit = traversal(rayidx, numRays, rays, nodesA, anyHit, results, &hitIndex, &hitT, &hitU, &hitV);
  68.             if (hit == false || hitIndex == -1)
  69.             {
  70.                 break;
  71.             }
  72.            
  73.             // Get hit triangle index, compute barycentric coordinates, texture coordinates, hitpoint and normal; break on hitting light
  74.             int tri = hitIndex;
  75.             if (matInfo[matId[tri]].x > 0.0f)
  76.             {
  77.                 color = color + reflectance * make_float4(matInfo[matId[tri]].x, matInfo[matId[tri]].x, matInfo[matId[tri]].x, 1.0f);
  78.                 break;
  79.             }
  80.             float3 bary = make_float3(hitU, hitV, 1.0f - hitU - hitV);
  81.             float4 hitPoint = rays[rayidx * 2 + 0] + rays[rayidx * 2 + 1] * hitT * 0.99f;
  82.             float4 hitPointBehind = rays[rayidx * 2 + 0] + rays[rayidx * 2 + 1] * hitT * 1.01f;
  83.             float3 normal = interpolateAttribute3f(bary, normals[vertIdx[tri].x], normals[vertIdx[tri].y], normals[vertIdx[tri].z]);
  84.             float2 tc = interpolateAttribute2f(bary, texCoords[vertIdx[tri].x], texCoords[vertIdx[tri].y], texCoords[vertIdx[tri].z]);
  85.             // Calculate normal (always directing towards ray origin)
  86.             float3 normalDir = dot(normal, make_float3(rays[rayidx * 2 + 1])) < 0.0f ? normal : normal * -1;
  87.             // Sample color
  88.             float4 f = matInfo[matId[tri]].x > 0.0f ? make_float4(matInfo[matId[tri]].x, matInfo[matId[tri]].x, matInfo[matId[tri]].x, 1.0f) :
  89.                 matInfo[matId[tri]].w == 0.0f ? fromABGR(triMaterialColor[tri]) : sample2D(bary, tc, atlasInfo[tri], t_textureAtlas);
  90.             f.x = powf(f.x, 2.2f);
  91.             f.y = powf(f.y, 2.2f);
  92.             f.z = powf(f.z, 2.2f);
  93.             // Calculate maximum reflectance
  94.             float p = f.x > f.y && f.x > f.z ? f.x : f.y > f.z ? f.y : f.z;
  95.            
  96.             // Store previous ray dir
  97.             float4 raydir = rays[rayidx * 2 + 1];
  98.  
  99.             // Explicit step
  100.             if (matInfo[matId[tri]].y == 0.0f && matInfo[matId[tri]].z == 0.0f)
  101.             {
  102.                 int emiId = (uint)randomInt(in.randomSeed, rayidx + (spp + 127) * (rayidx + (depth + 334) * (rayidx + 72))) % emissiveCount;
  103.                 float3 baryRand = make_float3(random(in.randomSeed, rayidx + (spp + 17) * (rayidx + (depth + 68) * (rayidx + 62))),
  104.                     random(in.randomSeed, rayidx + (spp + 63) * (rayidx + (depth + 68) * (rayidx + 628))),
  105.                     0.0f);
  106.                 if(baryRand.x + baryRand.y > 1.0f)
  107.                 {
  108.                     baryRand.x = 1.0f - baryRand.x;
  109.                     baryRand.y = 1.0f - baryRand.y;
  110.                 }
  111.                 baryRand.z = 1.0f - baryRand.x - baryRand.y;
  112.                 float3 sp = interpolateAttribute3f(baryRand, verts[emissive[emiId].x], verts[emissive[emiId].y], verts[emissive[emiId].z]);
  113.                 float3 l = sp - make_float3(hitPoint);
  114.                 float atten = sqrtf(1.0f / (length(l) + 1.0f));
  115.                 l = normalize(l);
  116.                 rays[rayidx * 2 + 0] = hitPoint;
  117.                 rays[rayidx * 2 + 0].w = 0.01f;
  118.                 rays[rayidx * 2 + 1] = make_float4(l, 10000.0f);
  119.                 hit = traversal(rayidx, numRays, rays, nodesA, anyHit, results, &hitIndex, &hitT, &hitU, &hitV);
  120.                 float4 expl = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
  121.                 if (hit && matInfo[matId[hitIndex]].x > 0.0f)
  122.                 {
  123.                     expl = matInfo[matId[hitIndex]].x * f * dot(normalDir, l) * atten;
  124.                 }
  125.  
  126.                 color = color + reflectance * (matInfo[matId[tri]].x > 0.0f ? matInfo[matId[tri]].x : 0.0f) + reflectance * expl;
  127.             }
  128.             else
  129.             {
  130.                 color = color + reflectance * (matInfo[matId[tri]].x > 0.0f ? matInfo[matId[tri]].x : 0.0f);
  131.             }
  132.  
  133.             // Russian roulette
  134.             if (++depth > 3)
  135.             {
  136.                 if (random(in.randomSeed, rayidx + spp * (rayidx + depth * (rayidx + 256))) < p)
  137.                 {
  138.                     f = f * (1.0f / p);
  139.  
  140.                     if (depth > MAX_PATH_LENGTH)
  141.                     {
  142.                         break;
  143.                     }
  144.                 }
  145.                 else
  146.                 {
  147.                     break;
  148.                 }
  149.             }
  150.            
  151.             reflectance = reflectance * f;
  152.             // Diffuse
  153.             if (matInfo[matId[tri]].y == 0.0f && matInfo[matId[tri]].z == 0.0f)
  154.             {
  155.                 float r1 = 2.0f * 3.141592654f * random(in.randomSeed, rayidx + (spp + 37) * (rayidx + (depth + 17) * (rayidx + 171)));
  156.                 float r2 = random(in.randomSeed, rayidx + (spp + 63) * (rayidx + (depth + 94) * (rayidx + 317)));
  157.                 float r2s = sqrtf(r2);
  158.                 float3 w = normalDir;
  159.                 float3 u = normalize(cross((fabsf(w.x) > 0.1f ? make_float3(0.0f, 1.0f, 0.0f) : make_float3(1.0f, 0.0f, 0.0f)), w));
  160.                 float3 v = cross(w, u);
  161.                 float3 d = normalize(u * cosf(r1) * r2s + v * sinf(r1) * r2s + w * sqrtf(1.0f - r2));
  162.                 rays[rayidx * 2 + 0] = hitPoint;
  163.                 rays[rayidx * 2 + 0].w = 0.01f;
  164.                 rays[rayidx * 2 + 1] = make_float4(d, 10000.0f);
  165.             }
  166.             // Ideal dielectric reflection
  167.             else if (matInfo[matId[tri]].z == 0.0f)
  168.             {
  169.                 rays[rayidx * 2 + 0] = hitPoint;
  170.                 rays[rayidx * 2 + 0].w = 0.01f;
  171.                 rays[rayidx * 2 + 1] = raydir - 2.0f * make_float4(normal, 0.0f) * dot(make_float4(normal, 0.0f), raydir);
  172.             }
  173.             // Ideal dielectric refraction
  174.             else if (matInfo[matId[tri]].y == 0.0f)
  175.             {
  176.                 rays[rayidx * 2 + 0] = hitPoint;
  177.                 rays[rayidx * 2 + 0].w = 0.01f;
  178.                 rays[rayidx * 2 + 1] = raydir - 2.0f * make_float4(normal, 0.0f) * dot(make_float4(normal, 0.0f), raydir);
  179.  
  180.                 bool into = dot(normal, normalDir) > 0.0f;
  181.                 float nc = 1.0f;
  182.                 float nt = 1.5f;
  183.                 float nnt = into ? nc / nt : nt / nc;
  184.                 float ddn = dot(make_float3(raydir), normalDir);
  185.                 float cos2t = 1.0f - nnt * nnt * (1.0f - ddn * ddn);
  186.                 if (cos2t < 0.0f)
  187.                 {
  188.                     continue;
  189.                 }
  190.                 float3 tdir = normalize(make_float3(raydir) * nnt - normal * ((into ? 1.0f : -1.f) * (ddn * nnt + sqrtf(cos2t))));
  191.                 //float3 tdir = normalize(make_float3(raydir));
  192.                 float a = nt - nc;
  193.                 float b = nt + nc;
  194.                 float c = 1.0f - (into ? -ddn : dot(tdir, normal));
  195.                 float Re = matInfo[matId[tri]].y + (1.0f - matInfo[matId[tri]].y) * c * c * c * c * c;
  196.                 float Tr = 1.0f - Re;
  197.                 float P = 0.25f + 0.5f * Re;
  198.                 float RP = Re / P;
  199.                 float TP = Tr / (1.0f - P);
  200.  
  201.                 if (random(in.randomSeed, rayidx + (spp + 63) * (rayidx + (depth + 94) * (rayidx + 317))) < P)
  202.                 {
  203.                     reflectance = reflectance * RP;
  204.                 }
  205.                 else
  206.                 {
  207.                     reflectance = reflectance * TP;
  208.                     rays[rayidx * 2 + 0] = hitPointBehind;
  209.                     rays[rayidx * 2 + 0].w = 0.01f;
  210.                     rays[rayidx * 2 + 1] = make_float4(tdir, 10000.0f);
  211.                 }
  212.             }
  213.         }
  214.        
  215.         result = result + color;
  216.  
  217.         // Until path is terminated or path maximum length is reached
  218.         /*for (int path = 0; path < MAX_PATH_LENGTH; path++)
  219.         {
  220.             float4 color = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
  221.             float3 normal = make_float3(0.0f, 0.0f, 0.0f);
  222.             float len;
  223.             bool hit;
  224.        
  225.             tempDir = rays[rayidx * 2 + 1];
  226.  
  227.             // Check hit
  228.             hit = traversal(rayidx, numRays, rays, nodesA, anyHit, results, &hitIndex, &hitT, &hitU, &hitV);
  229.             if(hit)
  230.             {
  231.                 int tri = hitIndex;
  232.                 if (tri == -1)
  233.                 {
  234.                     // Invalid triangle hit - return black
  235.                     color = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
  236.                 }
  237.                 else
  238.                 {
  239.                     if(matInfo[matId[tri]].w == 0.0f)
  240.                     {
  241.                         // We hit a light
  242.                         color = make_float4(1.0f, 1.0f, 1.0f, 1.0f);
  243.                         normal = make_float3(rays[rayidx * 2 + 1]);
  244.                     }
  245.                     else
  246.                     {
  247.                         // We hit a triangle
  248.                         float3 bary = make_float3(hitU, hitV, 1.0f - hitU - hitV);
  249.  
  250.                         // Sample diffuse texture for color
  251.                         float2 tc = interpolateAttribute2f(bary, texCoords[vertIdx[tri].x], texCoords[vertIdx[tri].y], texCoords[vertIdx[tri].z]);
  252.                         color = sample2D(bary, tc, atlasInfo[tri], t_textureAtlas);
  253.  
  254.                         // Interpolate normal
  255.                         normal = interpolateAttribute3f(bary, normals[vertIdx[tri].x], normals[vertIdx[tri].y], normals[vertIdx[tri].z]);
  256.                
  257.                         // Generate random value for emissive triangle ID
  258.                         int hashA = in.randomSeed + path * spp + spp + path + rayidx * (path + threadIdx.x + 17);
  259.                         int hashB = 0x9e3779b9u;
  260.                         int hashC = 0x9e3779b9u;
  261.                         jenkinsMix(hashA, hashB, hashC);
  262.                         int emiId = (uint)hashC % emissiveCount;
  263.  
  264.                         // Generate random barycentric coordinate
  265.                         float3 baryRand = make_float3((float)hashA * exp2f(-32), (float)hashB * exp2f(-32), 0.0f);
  266.                         if(baryRand.x + baryRand.y > 1.0f)
  267.                         {
  268.                             baryRand.x = 1.0f - baryRand.x;
  269.                             baryRand.y = 1.0f - baryRand.y;
  270.                         }
  271.                         baryRand.z = 1.0f - baryRand.x - baryRand.y;
  272.  
  273.                         // Calculate new origin and direction to light
  274.                         rays[rayidx * 2 + 0] = rays[rayidx * 2 + 0] + rays[rayidx * 2 + 1] * hitT * 0.99f;
  275.                         rays[rayidx * 2 + 0].w = 0.01f;
  276.                         float3 pos = interpolateAttribute3f(baryRand, verts[emissive[emiId].x], verts[emissive[emiId].y], verts[emissive[emiId].z]);
  277.                         float3 dir = pos - make_float3(rays[rayidx * 2 + 0]);
  278.                         len = length(dir);
  279.                         dir = normalize(dir);
  280.                         rays[rayidx * 2 + 1] = make_float4(dir, 10000.0f);
  281.  
  282.                         // Calculate BRDF
  283.                        
  284.                         color = color * max(dot(dir, normal), 0.0f);
  285.                     }
  286.                 }
  287.             }
  288.  
  289.             // Cast a ray against random light source position
  290.             int hitIdx;
  291.             hit = traversal(rayidx, numRays, rays, nodesA, anyHit, results, &hitIdx, &hitT, &hitU, &hitV);
  292.             if (hit)
  293.             {
  294.                 // Hit means shadow, unless emissive material
  295.                 if (hitIdx != -1)
  296.                 {
  297.                     if(matInfo[matId[hitIdx]].w != 0.0f)
  298.                     {
  299.                         color *= 0.0f;
  300.                     }
  301.                 }
  302.             }
  303.        
  304.             // Generate random value for next step
  305.             int hashA = in.randomSeed + path * spp + spp + path * 4 + 27 + rayidx * (path + threadIdx.x + 34);
  306.             int hashB = 0x9e3779b9u;
  307.             int hashC = 0x9e3779b9u;
  308.             jenkinsMix(hashA, hashB, hashC);
  309.             rays[rayidx * 2 + 0].w = 0.01f;
  310.             rays[rayidx * 2 + 1] = normalize(make_float4((float)hashA * exp2f(-32), (float)hashB * exp2f(-32), (float)hashC * exp2f(-32), 0.0f));
  311.             rays[rayidx * 2 + 1].w = 10000.0f;
  312.        
  313.             mult_val = dot(tempDir, make_float4(-normal, 0.0f));
  314.             color.x = max(color.x, 0.0f);
  315.             color.y = max(color.y, 0.0f);
  316.             color.z = max(color.z, 0.0f);
  317.             result += color * mult_val;
  318.         }*/
  319.     }
  320.     result /= SAMPLES_PER_PIXEL;
  321.  
  322.     STORE_RESULT(rayidx, hitIndex, result.x, result.y, result.z);
  323. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement