转自:http://blog.csdn.net/liu_lin_xm/article/details/4850630

摘抄“GPU Programming And Cg Language Primer 1rd Edition” 中文 名“GPU编程与CG语言之阳春白雪下里巴人”    

算法流程

图 47 展示了使用光线投射算法进行体绘制的实现流程。

首先要渲染出正向面深度图和背向面深度图,这是为了计算射线穿越的最大距离,做为循环采样控制的结束依据;然后在顶点着色程序中计算顶点位置和射线方向,射线方向由视线方向和点的世界坐标决定,其实射线方向也可以放在片段着色程序中进行计算。然后到了最关键的地方,就是循环纹理采样、合成。

每一次循环都要计算新的采样纹理坐标和采样距离,然后进行颜色合成和透明度累加,如果采样距离超过了最大穿越距离,或者透明度累加到 1 ,则循环结束。将合成得到的颜色值输出即可。

图 48 给出了使用光线投射算法进行体绘制的效果图:

15.4 光线投射算法实现

本节给出光线投射算法的着色程序实现代码。依然是分为三个部分:结构体、顶点着色程序和片段着色程序。

代码 22 光线投射算法结构体

struct VertexIn

{

float4 position : POSITION;

float4 texCoord:  TEXCOORD;

};

struct VertexScreen

{

float4 position   : POSITION;

float4 worldPos   : TEXCOORD0;

float4 projPos    : TEXCOORD1;

float4 texCoord   : TEXCOORD2;

};

代码 23 光线投射算法顶点着色程序

VertexScreen main_v(VertexIn posIn,

uniform float4x4 world,

uniform float4x4 worldViewProj,

uniform float4x4 texViewProj)

{

VertexScreen posOut;

posOut.position = mul(worldViewProj, posIn.position);

posOut.worldPos = mul(world,posIn.position);

posOut.projPos = mul(texViewProj, posOut.worldPos);

posOut.texCoord = posIn.texCoord;

return posOut;

}

代码 24 光线投射算法片段着色程序

void main_f(VertexScreen posIn,

uniform float3 eyePosition,

uniform sampler3D volumeTex: register(s0),

uniform sampler2D frontDepthTex: register(s1) ,

uniform sampler2D backDepthTex: register(s2) ,

out float4 result        : COLOR)

{

// 根据视点和当前顶点世界坐标计算方向

float3 dir = posIn.worldPos.xyz-eyePosition;

dir = normalize(dir);

float3 deltaDir = float3(0.0, 0.0, 0.0);

// 获取当前顶点的三维纹理坐标

float3 tex = posIn.texCoord.xyz;

float2 uvDelta;

uvDelta.x = 0.0;//ddx( tex ).x;

uvDelta.y = 0.0;//ddy( tex ).y;

// 取出深度间隔值 , 并设置采样间隔

float2 uv= posIn.projPos.xy/posIn.projPos.w;

float frontDis = tex2D(frontDepthTex,uv).x;

float backDis = tex2D(backDepthTex,uv).x;

float len = backDis-frontDis;

// 初始化颜色值、采样值、透明度

float3 norm_dir = normalize(dir);

float stepsize = 0.01;

float delta = stepsize;

float3 delta_dir = norm_dir * delta;

float delta_dir_len = length(delta_dir);

float3 vec = posIn.texCoord.xyz;

float4 col_acc = float4(0,0,0,0);

float alpha_acc = 0;

float length_acc = 0;

float4 color_sample;

float alpha_sample;

for(int i = 0; i < 800; i++){

color_sample = tex3D(volumeTex,vec);

alpha_sample = color_sample.a * stepsize;

col_acc   += (1.0 - alpha_acc) * color_sample * alpha_sample * 3;

alpha_acc += alpha_sample;

vec += delta_dir;

length_acc += delta_dir_len;

if(length_acc >= len || alpha_acc > 1.0) break; // 采样循环控制条件

}

result.xyz = col_acc.xyz*2.0+float3(0.2,0.2,0.2);

result.w = col_acc.w;

}

15.5 本章小结

本书的第14 、15 章阐述了体绘制中光线投射算法的基本原理和实现流程。实际上,在此基础上可以对光线投射算法加以扩展,例如将光线投射算法和阴影绘制算法相结合,可以渲染出真实感更强的图像。

此外,有些体数据是中间是空的,在射线方向上进行采样时需要跳过空区域,这其中也需要额外的算法处理,在英文中称为“Object-Order Empty Space Skipping ”。

目前我所发现关于体绘制以及光线投射算法最好的教材是Markus Hadwiger 等人所写的“Advanced Illumination Techniques for GPU-Based Volume Raycasting ”。此书发表在SIGGRAPH ASIA2008 上,是目前所能找到最新也是非常权威的教材,共166 页。英文阅读能力比较好的同学可以尝试着看一下。

本章已经是此书的最后一章,最后希望中国的计算机科学可以真正上升到科学研究的层次,而不是一直在混沌中热衷做泥瓦匠的工作。

体绘制(Volume Rendering)概述之4:光线投射算法(Ray Casting)实现流程和代码(基于CPU的实现)的更多相关文章

  1. 39. Volume Rendering Techniques

    Milan Ikits University of Utah Joe Kniss University of Utah Aaron Lefohn University of California, D ...

  2. 体绘制(Volume Rendering)概述之3:光线投射算法(Ray Casting)原理和注意要点(强烈推荐呀,讲的很好)

    转自:http://blog.csdn.net/liu_lin_xm/article/details/4850609 摘抄“GPU Programming And Cg Language Primer ...

  3. PaperRead - A Shader Framework for Rapid Prototyping of GPU-Based Volume Rendering

    PaperRead - A Shader Framework for Rapid Prototyping of GPU-Based Volume Rendering 目录 PaperRead - A ...

  4. CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探

    CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码 ...

  5. Volume rendering

    Volume rendering Reconstruction filter UCDAVIS

  6. 【优化算法】Greedy Randomized Adaptive Search算法 超详细解析,附代码实现TSP问题求解

    01 概述 Greedy Randomized Adaptive Search,贪婪随机自适应搜索(GRAS),是组合优化问题中的多起点元启发式算法,在算法的每次迭代中,主要由两个阶段组成:构造(co ...

  7. 第2章 rsync算法原理和工作流程分析

    本文通过示例详细分析rsync算法原理和rsync的工作流程,是对rsync官方技术报告和官方推荐文章的解释. 以下是本文的姊妹篇: 1.rsync(一):基本命令和用法 2.rsync(二):ino ...

  8. C++算法之大数加法计算的代码

    如下代码段是关于C++算法之大数加法计算的代码,希望对大家有用. { int length; int index; int smaller; int prefix = 0; if(NULL == sr ...

  9. rsync算法原理和工作流程分析

    本文通过示例详细分析rsync算法原理和rsync的工作流程,是对rsync官方技术报告和官方推荐文章的解释.本文不会介绍如何使用rsync命令(见rsync基本用法),而是详细解释它如何实现高效的增 ...

随机推荐

  1. python opencv3 检测人

    git:https://github.com/linyi0604/Computer-Vision # coding:utf-8 import cv2 # 检测i方框 包含o方框 def is_insi ...

  2. python可变数据和不可变数据

    可变数据类型:列表list和字典dict: 不可变数据类型:整型int.浮点型float.字符串型string和元组tuple 可变与不可变是相对“引用地址”来说的.python中的不可变数据类型,不 ...

  3. 【10.17校内测试】【二进制数位DP】【博弈论/预处理】【玄学(?)DP】

    Solution 几乎是秒想到的水题叻! 异或很容易想到每一位单独做贡献,所以我们需要统计的是区间内每一位上做的贡献,就是统计区间内每一位是1的数的数量. 所以就写数位dp辣!(昨天才做了数字统计不要 ...

  4. Codeforces Round #222 (Div. 1) D. Developing Game 扫描线

    D. Developing Game 题目连接: http://www.codeforces.com/contest/377/problem/D Description Pavel is going ...

  5. Linux性能监控分析命令(三)—iostat命令介绍

    性能监控分析的命令包括如下: 1.vmstat 2.sar 3.iostat 4.top 5.free 6.uptime 7.netstat 8.ps 9.strace 10.lsof 命令介绍: i ...

  6. 文件上传demo

    前端代码: <form action="upload.php" enctype="multipart/form-data" method="po ...

  7. Redis系列之(一):10分钟玩转Redis

    1. Redis介绍 Redis是一个开源的使用ANSI C语言编写.基于内存的Key-Value数据库. 它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集 ...

  8. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2843  Solved: 1519[Submi ...

  9. Java工程师成神之路 转

      一.基础篇 1.1 JVM 1.1.1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 http://www.jcp.org/en/jsr/detail?id=133 http:/ ...

  10. IT程序猿们,我该做什么选择呢

    这个时刻,我想我遇到人生小拐点了,程序猿到了30岁,到达了一个分界线了,现在的我该何去何从呢? 先谈下简单的情况吧: 来这个公司2年了,之前因为身体的原因,不想那么累,于是选择了一份维护的工作,就来了 ...