volumeRender_kernel.cu
上传用户:liuping58
上传日期:2022-06-05
资源大小:105k
文件大小:5k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright 1993-2006 NVIDIA Corporation.  All rights reserved.
  3.  *
  4.  * NOTICE TO USER:   
  5.  *
  6.  * This source code is subject to NVIDIA ownership rights under U.S. and 
  7.  * international Copyright laws.  
  8.  *
  9.  * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE 
  10.  * CODE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR 
  11.  * IMPLIED WARRANTY OF ANY KIND.  NVIDIA DISCLAIMS ALL WARRANTIES WITH 
  12.  * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF 
  13.  * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.   
  14.  * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, 
  15.  * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 
  16.  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
  17.  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE 
  18.  * OR PERFORMANCE OF THIS SOURCE CODE.  
  19.  *
  20.  * U.S. Government End Users.  This source code is a "commercial item" as 
  21.  * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting  of 
  22.  * "commercial computer software" and "commercial computer software 
  23.  * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) 
  24.  * and is provided to the U.S. Government only as a commercial end item.  
  25.  * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through 
  26.  * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the 
  27.  * source code with only those rights set forth herein.
  28.  */
  29. #ifndef _TEXTURE3D_KERNEL_H_
  30. #define _TEXTURE3D_KERNEL_H_
  31. #include "cutil_math.h"
  32. texture<uchar, 3, cudaReadModeNormalizedFloat> tex;         // 3D texture
  33. texture<float4, 1, cudaReadModeElementType> transferTex;    // 1D transfer function texture
  34. typedef struct {
  35.     float4 m[3];
  36. } float3x4;
  37. __constant__ float3x4 c_invViewMatrix;  // inverse view matrix
  38. struct Ray {
  39. float3 o; // origin
  40. float3 d; // direction
  41. };
  42. // intersect ray with a box
  43. // http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm
  44. __device__
  45. int intersectBox(Ray r, float3 boxmin, float3 boxmax, float *tnear, float *tfar)
  46. {
  47.     // compute intersection of ray with all six bbox planes
  48.     float3 invR = make_float3(1.0f) / r.d;
  49.     float3 tbot = invR * (boxmin - r.o);
  50.     float3 ttop = invR * (boxmax - r.o);
  51.     // re-order intersections to find smallest and largest on each axis
  52.     float3 tmin = fminf(ttop, tbot);
  53.     float3 tmax = fmaxf(ttop, tbot);
  54.     // find the largest tmin and the smallest tmax
  55.     float largest_tmin = fmaxf(fmaxf(tmin.x, tmin.y), fmaxf(tmin.x, tmin.z));
  56.     float smallest_tmax = fminf(fminf(tmax.x, tmax.y), fminf(tmax.x, tmax.z));
  57. *tnear = largest_tmin;
  58. *tfar = smallest_tmax;
  59. return smallest_tmax > largest_tmin;
  60. }
  61. // transform vector by matrix (no translation)
  62. __device__
  63. float3 mul(const float3x4 &M, const float3 &v)
  64. {
  65.     float3 r;
  66.     r.x = dot(v, make_float3(M.m[0]));
  67.     r.y = dot(v, make_float3(M.m[1]));
  68.     r.z = dot(v, make_float3(M.m[2]));
  69.     return r;
  70. }
  71. // transform vector by matrix with translation
  72. __device__
  73. float4 mul(const float3x4 &M, const float4 &v)
  74. {
  75.     float4 r;
  76.     r.x = dot(v, M.m[0]);
  77.     r.y = dot(v, M.m[1]);
  78.     r.z = dot(v, M.m[2]);
  79.     r.w = 1.0f;
  80.     return r;
  81. }
  82. __device__ uint rgbaFloatToInt(float4 rgba)
  83. {
  84.     rgba.x = __saturatef(rgba.x);   // clamp to [0.0, 1.0]
  85.     rgba.y = __saturatef(rgba.y);
  86.     rgba.z = __saturatef(rgba.z);
  87.     rgba.w = __saturatef(rgba.w);
  88.     return (uint(rgba.w*255)<<24) | (uint(rgba.z*255)<<16) | (uint(rgba.y*255)<<8) | uint(rgba.x*255);
  89. }
  90. __global__ void
  91. d_render(uint *d_output, uint imageW, uint imageH,
  92.          float density, float brightness,
  93.          float transferOffset, float transferScale)
  94. {
  95.     int maxSteps = 500;
  96.     float tstep = 0.01f;
  97.     float3 boxMin = make_float3(-1.0f, -1.0f, -1.0f);
  98.     float3 boxMax = make_float3(1.0f, 1.0f, 1.0f);
  99. uint x = __umul24(blockIdx.x, blockDim.x) + threadIdx.x;
  100.     uint y = __umul24(blockIdx.y, blockDim.y) + threadIdx.y;
  101.     float u = (x / (float) imageW)*2.0f-1.0f;
  102.     float v = (y / (float) imageH)*2.0f-1.0f;
  103.     // calculate eye ray in world space
  104.     Ray eyeRay;
  105.     eyeRay.o = make_float3(mul(c_invViewMatrix, make_float4(0.0f, 0.0f, 0.0f, 1.0f)));
  106.     eyeRay.d = normalize(make_float3(u, v, -2.0f));
  107.     eyeRay.d = mul(c_invViewMatrix, eyeRay.d);
  108.     // find intersection with box
  109. float tnear, tfar;
  110. int hit = intersectBox(eyeRay, boxMin, boxMax, &tnear, &tfar);
  111.     if (!hit) return;
  112. if (tnear < 0.0f) tnear = 0.0f;     // clamp to near plane
  113.     // march along ray from back to front, accumulating color
  114.     float4 sum = make_float4(0.0f);;
  115.     float t = tfar;
  116. for(int i=0; i<maxSteps; i++) {
  117.         float3 pos = eyeRay.o + eyeRay.d*t;
  118.         pos = pos*0.5f+0.5f;    // map position to [0, 1] coordinates
  119.         // read from 3D texture
  120.         float sample = tex3D(tex, pos.x, pos.y, pos.z);
  121.         // lookup in transfer function texture
  122.         float4 col = tex1D(transferTex, (sample-transferOffset)*transferScale);
  123.         // accumulate result
  124.         sum = lerp(sum, col, col.w*density);
  125.         t -= tstep;
  126.         if (t < tnear) break;
  127.     }
  128.     sum *= brightness;
  129.     if ((x < imageW) && (y < imageH)) {
  130.         // write output color
  131.         uint i = __umul24(y, imageW) + x;
  132.         d_output[i] = rgbaFloatToInt(sum);
  133.     }
  134. }
  135. #endif // #ifndef _TEXTURE3D_KERNEL_H_