体绘制(Volume Rendering)概述之4:光线投射算法(Ray Casting)实现流程和代码(基于CPU的实现)
转自: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的实现)的更多相关文章
- 39. Volume Rendering Techniques
Milan Ikits University of Utah Joe Kniss University of Utah Aaron Lefohn University of California, D ...
- 体绘制(Volume Rendering)概述之3:光线投射算法(Ray Casting)原理和注意要点(强烈推荐呀,讲的很好)
转自:http://blog.csdn.net/liu_lin_xm/article/details/4850609 摘抄“GPU Programming And Cg Language Primer ...
- 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 ...
- CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探
CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码 ...
- Volume rendering
Volume rendering Reconstruction filter UCDAVIS
- 【优化算法】Greedy Randomized Adaptive Search算法 超详细解析,附代码实现TSP问题求解
01 概述 Greedy Randomized Adaptive Search,贪婪随机自适应搜索(GRAS),是组合优化问题中的多起点元启发式算法,在算法的每次迭代中,主要由两个阶段组成:构造(co ...
- 第2章 rsync算法原理和工作流程分析
本文通过示例详细分析rsync算法原理和rsync的工作流程,是对rsync官方技术报告和官方推荐文章的解释. 以下是本文的姊妹篇: 1.rsync(一):基本命令和用法 2.rsync(二):ino ...
- C++算法之大数加法计算的代码
如下代码段是关于C++算法之大数加法计算的代码,希望对大家有用. { int length; int index; int smaller; int prefix = 0; if(NULL == sr ...
- rsync算法原理和工作流程分析
本文通过示例详细分析rsync算法原理和rsync的工作流程,是对rsync官方技术报告和官方推荐文章的解释.本文不会介绍如何使用rsync命令(见rsync基本用法),而是详细解释它如何实现高效的增 ...
随机推荐
- ARM 中必须明白的几个概念
文章具体介绍了关于ARM的22个常用概念. 1.ARM中一些常见英文缩写解释 MSB:最高有效位: LSB:最低有效位: AHB:先进的高性能总线: VPB:连接片内外设功能的VLSI外设总线: EM ...
- C# 复制、粘贴文本信息到系统剪贴板
复制: Clipboard.SetDataObject(textBox1.SelectedText); 粘贴: IDataObject iData = Clipboard.GetDataObject( ...
- luogu NOIp热身赛(2018-11-07)题解
为什么前面的人都跑得那么快啊? QAQ T1:区间方差 题目大意:询问区间方差,支持单点修改 首先把方差的式子展开,得到 $$d = \frac{a_1 + ... a_n}{n} - \frac{a ...
- 【原创】自己动手写的一个查看函数API地址的小工具
C开源代码如下: #include <stdio.h> #include <windows.h> #include <winbase.h> typedef void ...
- 【BZOJ】2730: [HNOI2012]矿场搭建【Tarjan找割点】【分联通块割点个数】
2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3230 Solved: 1540[Submit][Stat ...
- 机器学习(2):Softmax回归原理及其实现
Softmax回归用于处理多分类问题,是Logistic回归的一种推广.这两种回归都是用回归的思想处理分类问题.这样做的一个优点就是输出的判断为概率值,便于直观理解和决策.下面我们介绍它的原理和实现. ...
- flash从数据流判断图片格式防止xss攻击
前段时间测试人员报了一个flash的xss bug,经分析用了Loader.loadBytes且没做数据流格式校验的程序都会中招,自测方法只需一行代码: ExternalInterface.call( ...
- Node.js学习笔记(1) - Node.js简介
近期在看一些Node.js的知识,看完后觉得,一些前面的东西忘记了,于是整理一下,方便自己查阅,也希望对学习Node.js的朋友有些帮助: 当然以下只是我个人的观点和理解,不喜勿喷,也望大神指教. 一 ...
- [JAVA] JAVA 文档注释
Java 程序设计环境 文档注释 javadoc JDK中包含的javadoc工具可以由源文件生成一个HTML文档. javadoc从以下几个特性中抽取信息 包 公有类与接口 公有的和受保护的构造器及 ...
- css3实现卷页效果http://jingyan.baidu.com/article/73c3ce2806aef9e50343d93a.html
css3实现卷页效果 | 浏览:31 | 更新:2015-01-08 13:30 1 2 3 4 5 6 7 分步阅读 百度经验:jingyan.baidu.com 页面上经常会看到鼠标移动上去,对象 ...