volumeRender_kernel.cu
资源名称:CUDAseg.zip [点击查看]
上传用户:liuping58
上传日期:2022-06-05
资源大小:105k
文件大小:5k
源码类别:
3D图形编程
开发平台:
Visual C++
- /*
- * Copyright 1993-2006 NVIDIA Corporation. All rights reserved.
- *
- * NOTICE TO USER:
- *
- * This source code is subject to NVIDIA ownership rights under U.S. and
- * international Copyright laws.
- *
- * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
- * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
- * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
- * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
- * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
- * OR PERFORMANCE OF THIS SOURCE CODE.
- *
- * U.S. Government End Users. This source code is a "commercial item" as
- * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of
- * "commercial computer software" and "commercial computer software
- * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995)
- * and is provided to the U.S. Government only as a commercial end item.
- * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through
- * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
- * source code with only those rights set forth herein.
- */
- #ifndef _TEXTURE3D_KERNEL_H_
- #define _TEXTURE3D_KERNEL_H_
- #include "cutil_math.h"
- texture<uchar, 3, cudaReadModeNormalizedFloat> tex; // 3D texture
- texture<float4, 1, cudaReadModeElementType> transferTex; // 1D transfer function texture
- typedef struct {
- float4 m[3];
- } float3x4;
- __constant__ float3x4 c_invViewMatrix; // inverse view matrix
- struct Ray {
- float3 o; // origin
- float3 d; // direction
- };
- // intersect ray with a box
- // http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm
- __device__
- int intersectBox(Ray r, float3 boxmin, float3 boxmax, float *tnear, float *tfar)
- {
- // compute intersection of ray with all six bbox planes
- float3 invR = make_float3(1.0f) / r.d;
- float3 tbot = invR * (boxmin - r.o);
- float3 ttop = invR * (boxmax - r.o);
- // re-order intersections to find smallest and largest on each axis
- float3 tmin = fminf(ttop, tbot);
- float3 tmax = fmaxf(ttop, tbot);
- // find the largest tmin and the smallest tmax
- float largest_tmin = fmaxf(fmaxf(tmin.x, tmin.y), fmaxf(tmin.x, tmin.z));
- float smallest_tmax = fminf(fminf(tmax.x, tmax.y), fminf(tmax.x, tmax.z));
- *tnear = largest_tmin;
- *tfar = smallest_tmax;
- return smallest_tmax > largest_tmin;
- }
- // transform vector by matrix (no translation)
- __device__
- float3 mul(const float3x4 &M, const float3 &v)
- {
- float3 r;
- r.x = dot(v, make_float3(M.m[0]));
- r.y = dot(v, make_float3(M.m[1]));
- r.z = dot(v, make_float3(M.m[2]));
- return r;
- }
- // transform vector by matrix with translation
- __device__
- float4 mul(const float3x4 &M, const float4 &v)
- {
- float4 r;
- r.x = dot(v, M.m[0]);
- r.y = dot(v, M.m[1]);
- r.z = dot(v, M.m[2]);
- r.w = 1.0f;
- return r;
- }
- __device__ uint rgbaFloatToInt(float4 rgba)
- {
- rgba.x = __saturatef(rgba.x); // clamp to [0.0, 1.0]
- rgba.y = __saturatef(rgba.y);
- rgba.z = __saturatef(rgba.z);
- rgba.w = __saturatef(rgba.w);
- return (uint(rgba.w*255)<<24) | (uint(rgba.z*255)<<16) | (uint(rgba.y*255)<<8) | uint(rgba.x*255);
- }
- __global__ void
- d_render(uint *d_output, uint imageW, uint imageH,
- float density, float brightness,
- float transferOffset, float transferScale)
- {
- int maxSteps = 500;
- float tstep = 0.01f;
- float3 boxMin = make_float3(-1.0f, -1.0f, -1.0f);
- float3 boxMax = make_float3(1.0f, 1.0f, 1.0f);
- uint x = __umul24(blockIdx.x, blockDim.x) + threadIdx.x;
- uint y = __umul24(blockIdx.y, blockDim.y) + threadIdx.y;
- float u = (x / (float) imageW)*2.0f-1.0f;
- float v = (y / (float) imageH)*2.0f-1.0f;
- // calculate eye ray in world space
- Ray eyeRay;
- eyeRay.o = make_float3(mul(c_invViewMatrix, make_float4(0.0f, 0.0f, 0.0f, 1.0f)));
- eyeRay.d = normalize(make_float3(u, v, -2.0f));
- eyeRay.d = mul(c_invViewMatrix, eyeRay.d);
- // find intersection with box
- float tnear, tfar;
- int hit = intersectBox(eyeRay, boxMin, boxMax, &tnear, &tfar);
- if (!hit) return;
- if (tnear < 0.0f) tnear = 0.0f; // clamp to near plane
- // march along ray from back to front, accumulating color
- float4 sum = make_float4(0.0f);;
- float t = tfar;
- for(int i=0; i<maxSteps; i++) {
- float3 pos = eyeRay.o + eyeRay.d*t;
- pos = pos*0.5f+0.5f; // map position to [0, 1] coordinates
- // read from 3D texture
- float sample = tex3D(tex, pos.x, pos.y, pos.z);
- // lookup in transfer function texture
- float4 col = tex1D(transferTex, (sample-transferOffset)*transferScale);
- // accumulate result
- sum = lerp(sum, col, col.w*density);
- t -= tstep;
- if (t < tnear) break;
- }
- sum *= brightness;
- if ((x < imageW) && (y < imageH)) {
- // write output color
- uint i = __umul24(y, imageW) + x;
- d_output[i] = rgbaFloatToInt(sum);
- }
- }
- #endif // #ifndef _TEXTURE3D_KERNEL_H_