精华内容
下载资源
问答
  • 光线投射Raycaster

    2019-05-21 22:31:18
    光线投射Raycaster Three.js 中文文档链接 这个类用于进行raycasting(光线投射)。 光线投射用于进行鼠标拾取(在三维空间中计算出鼠标移过了什么物体)。 示例 var raycaster = new THREE.Raycaster(); var mouse ...

    光线投射Raycaster

    Three.js 中文文档链接

    这个类用于进行raycasting(光线投射)。 光线投射用于进行鼠标拾取(在三维空间中计算出鼠标移过了什么物体)。
    示例

    var raycaster = new THREE.Raycaster();
    var mouse = new THREE.Vector2();
    
    function onMouseMove( event ) {
    
    	// 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
    
    	mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    	mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
    
    }
    
    function render() {
    
    	// 通过摄像机和鼠标位置更新射线
    	raycaster.setFromCamera( mouse, camera );
    
    	// 计算物体和射线的焦点
    	var intersects = raycaster.intersectObjects( scene.children );
    
    	for ( var i = 0; i < intersects.length; i++ ) {
    
    		intersects[ i ].object.material.color.set( 0xff0000 );
    
    	}
    
    	renderer.render( scene, camera );
    
    }
    
    window.addEventListener( 'mousemove', onMouseMove, false );
    
    window.requestAnimationFrame(render);
    

    构造函数

    Raycaster( origin : Vector3, direction : Vector3, near : Float, far : Float ) {

    origin —— 光线投射的原点向量。
    direction —— 向射线提供方向的方向向量,应当被标准化。
    near —— 返回的所有结果比near远。near不能为负值,其默认值为0。
    far —— 返回的所有结果都比far近。far不能小于near,其默认值为Infinity(正无穷。)

    这将创建一个新的raycaster对象。

    属性

    .far : float

    raycaster的远距离因数(投射远点)。这个值表明哪些对象可以基于该距离而被raycaster所丢弃。 这个值不应当为负,并且应当比near### 属性大。

    .linePrecision : float

    raycaster与Line(线)物体相交时的精度因数。

    .near : float

    raycaster的近距离因数(投射近点)。这个值表明哪些对象可以基于该距离而被raycaster所丢弃。 这个值不应当为负,并且应当比near### 属性小。

    .params : Object

    具有以下属性的物体:
    {
    Mesh: {},
    Line: {},
    LOD: {},
    Points: { threshold: 1 },
    Sprite: {}
    }

    .ray : Ray

    用于进行光线投射的Ray(射线)。

    方法

    .set ( origin : Vector3, direction : Vector3 ) : null

    origin —— 光线投射的原点向量。
    direction —— 为光线提供方向的标准化方向向量。

    使用一个新的原点和方向来更新射线。

    .setFromCamera ( coords : Vector2, camera : Camera ) : null

    coords —— 在标准化设备坐标中鼠标的二维坐标 —— X分量与Y分量应当在-1到1之间。
    camera —— 射线所来源的摄像机。

    使用一个新的原点和方向来更新射线。

    .intersectObject ( object : Object3D, recursive : Boolean, optionalTarget : Array ) : Array

    object —— 检查与射线相交的物体。
    recursive —— 若为true,则同时也会检查所有的后代。否则将只会检查对象本身。默认值为false。
    optionalTarget — (可选)设置结果的目标数组。如果不设置这个值,则一个新的Array会被实例化;如果设置了这个值,则在每次调用之前必须清空这个数组(例如:array.length = 0;)。

    检测所有在射线与物体之间,包括或不包括后代的相交部分。返回结果时,相交部分将按距离进行排序,最近的位于第一个)。
    该### 方法返回一个包含有交叉部分的数组:
    [ { distance, point, face, faceIndex, object }, … ]

    distance —— 射线投射原点和相交部分之间的距离。
    point —— 相交部分的点(世界坐标)
    face —— 相交的面
    faceIndex —— 相交的面的索引
    object —— 相交的物体
    uv —— 相交部分的点的UV坐标。

    当计算这条射线是否和物体相交的时候,Raycaster将传入的对象委托给raycast### 方法。 这将可以让mesh对于光线投射的响应不同于lines和pointclouds。

    请注意:对于网格来说,面必须朝向射线的原点,以便其能够被检测到。 用于交互的射线穿过面的背侧时,将不会被检测到。如果需要对物体中面的两侧进行光线投射, 你需要将material中的side### 属性设置为THREE.DoubleSide。

    .intersectObjects ( objects : Array, recursive : Boolean, optionalTarget : Array ) : Array

    objects —— 检测和射线相交的一组物体。
    recursive —— 若为true,则同时也会检测所有物体的后代。否则将只会检测对象本身的相交部分。默认值为false。
    optionalTarget —— (可选)(可选)设置结果的目标数组。如果不设置这个值,则一个新的Array会被实例化;如果设置了这个值,则在每次调用之前必须清空这个数组(例如:array.length = 0;)。

    检测所有在射线与这些物体之间,包括或不包括后代的相交部分。返回结果时,相交部分将按距离进行排序,最近的位于第一个),相交部分和.intersectObject所返回的格式是相同的。

    展开全文
  • 光线投射与光线跟踪算法归纳

    万次阅读 2017-04-14 14:48:56
    为了生成在三维计算机图形环境中的可见图像,光线跟踪是一个比光线投射或者扫描线渲染更加逼真的实现方法。这种方法通过逆向跟踪与假象的照相机镜头相交的光路进行工作,由于大量的类似光线横穿场景,所以从照相机...

    目录

    1. 前言
    2. 三维可视化与体绘制
    3. Ray Tracing vs. Ray Casting
    4. 体绘制的加速技术
    5. 基于CUDA实现Ray-Casting
    6. 后话
    7. 参考文献

     

    1.       前言

    在读了大牛们的很多深入浅出的科普文章和教程系列并受益匪浅后,不免有自己尝试写写的冲动。本文将尽量平白地阐述一些基本概念和算法流程,同时尽可能多地给出进一步学习所需要的有用资料,一些关键链接就省去了,感兴趣者可以google之。

    向乐于分享的大牛们致敬!

     

    2.       三维可视化与体绘制

    大家应该对可视化(visualization)这个词并不陌生了。这里限于3D数据场的可视化。譬如,一组CT\MRI切片是人体某个部位(也不限于人体,如客运站的行李安全检查也是CT扫描)的剖面图,逐张切片图像的2D观察不够形象,医学可视化技术就是实现了3D观察­。当然也可以漫游这个3D数据场,只要变换观察点和观察角度就可以了。

    图1 医学可视化

    图2 流体力学模拟

    也就是说,我们对现实世界进行采样而得到的一组数据,标识了这个3D空间里的采样点的某些属性;现在,把这个3D模型放在舞台上,用一台虚拟摄像机对它拍照,照片就是我们所需的可视化结果。这里的3D模型,是体模型、体数据,而传统图形学的是网格模型——我们看到的游戏人物,其实就是在建立好的3D网格模型上贴上纹理加入光照,是为“空壳”也!

    3D模型不一样,那么渲染技术也不一样吗?两者的确差异很大。现在暂且不说,先讲讲其他几个概念。

    3D数据场的可视化技术,可以分为面绘制(surface rendering)和体绘制(volume rendering)。

    面绘制,是先抽取出3D数据场里的某个等值面,这个等值面的表示形式,是一个元素为三角面片的数组。这样,接下来用OpenGL/D3D的API函数就可以画出结果了。面绘制常用的方法有MC、MT和dividing cubes等。所以,可以说,面绘制是从原始的3D模型中抽取出我们感兴趣的某个网格模型,而忽略了其他数据。

    体绘制,或者叫直接体绘制(DVR, Direct Volume Rendering),就是直接对原始的3D模型进行处理,利用了整个数据场信息。体绘制结果,不单单可以看到表面,还可以透过表面(赋予一定的透明度)看到里面。体绘制的自由度大得多,绘制结果也丰富得多,但是需要处理海量的体数据,不能直接使用图形学API,速度慢得多。其算法族有光线投射法(ray casting)、溅射法(splatting)、错切—变形法(shear-warp)、体元投射法(cell projection)和基于纹理映射(texture mapping)的方法。这样说,对于外行来说,可能还不够清楚,且看下文吧。

    有书名为“Real-Time Volume Graphics”,可译为“实时体图形学”。这本书非常经典!记得年初我通过馆际互借从上海图书馆借来捧在手上时,如获至宝!——寻书的过程,也使得我对“诺大一个中国,却无书可读”深有感触。我忘记了“体图形学”是自己的译法还是在哪里见过,我们姑且用这个名称吧。看书中第一章开头:

    “This book covers two seemingly very different applications of volume graphics: on the one hand, ‘special effects’ and realistic rendering of clouds, smoke, fire, and similar effects for computer games, movie production, and so forth; on the other hand, the scientific visualization of volumetric data.”

    “…both fields rely on the same underlying physical models and therefore use identical, or at least very similar, rendering techniques.”

    “Therefore, volume graphics targets the same goal as computer graphics in general: the simulation of light propagation in order to produce images as recorded by a virtual camera.”

    到这里,你大概知道“3D模型不一样,那么渲染技术也不一样吗?”的答案了吧。如果还有疑问,又不想花太多时间,可以到“Real-Time Volume Graphics”这本书的主页上下载chapter 2的PPT看看。

     

    3.       Ray Tracing vs. Ray Casting

    说到“ray tracing”,先回顾一下我的计算机图形学(CG)学习过程。

    开始时,因由做MC算法,把徐波译的《OpenGL超级宝典》翻了一遍,之后也看过OpenGL红宝书——感觉翻译水平有限,还不如看原版,另外推荐NeHe的OpenGL教程——其实学习CG就要做好足够的心理准备要看大量的外文资料。

    之后做体绘制时,发觉有必要较为系统地看看CG。看书评,知国人写得较好的图形学教材有唐荣锡的《计算机图形学教程》和彭群生的《计算机真实感图形的算法基础》,浙大的CAD&CG国家key lab不乏牛人。国外有一大堆经典就不说了。

    着色语言(shading language)的学习是看《OpenGL着色语言》、NVIDIA的“The Cg Tutorial”和康玉之大牛的《GPU编程与Cg语言之阳春白雪下里巴人》——向康大牛致敬!——不知他近况如何。

    还有是随手翻翻了一些经典,如“GPU Gems”系列,也对OpenGPU论坛热衷过一段时间,现在也偶尔去逛逛。这样到现在,算是对CG不再陌生了,但水平很一般。

    言归正传!

    Ray tracing通常译作“光线跟踪”,而ray casting通常译作“光线投射”。个人觉得两者区别不是很大。Ray tracing是逆向跟踪射入virtual camera的光线,在光线与场景物体的交点处累积来自光源的直接辐照量和反射、折射而来的间接辐照量;而ray casting是向三维数据场投射出光线,然后沿着光线方向积分,数值化方法为由前往后或由后向前合成。

     

    图3 ray casting

    图4 ray tracing

     

    4.       体绘制的加速技术

    体绘制处理的是海量的数据,如何提高效率是难题。体绘制的加速技术可以分为:软件加速和硬件加速。

    软件加速技术有提前光线终止(early ray termination)、空间跳跃(empty space leaping)和延迟渲染(deferred shading)等。这里,空间跳跃的实现,需要对三维数据场进行数据结构管理,如八叉树、二叉树和k-d树,类似于场景管理技术。

    硬件加速技术有并行实现、专用硬件实现和GPU加速。其实说GPU加速也欠妥,因为这个概念是NVIDIA在1999年才提出来的。先概述GPU加速的过去与现状吧。——了解科技史,也是学习中必不可少的一环,如:学习编程就应该去了解Unix/C的历史。

    最开始是基于二维纹理映射的方法:在虚拟的三维画布上设定好一个组正方形的坐标,然后把切片图像当作纹理贴上去,最后就可以按照一定的规则得到合成图像。

     

    图5 基于二维纹理映射的方法

    然后是基于三维纹理映射的方法:也是先设定代理几何体,不过这时代理几何体可以垂直于观察方向。

     

    图6 基于三维纹理映射的方法

    随着GPU的渲染管线由固定到可编程的转变,基于纹理映射的方法可以有更多的自由度,能够实现一些复杂的光照效果,而把ray casting由CPU移植到GPU也成为可能。

    这几年出现GPGPU:GPU里的众核(就是众多的计算核心)可以用作并行计算。NVIDIA适时地推出CUDA,使得基于CUDA加速体绘制一时成为热点。

     

    5.       基于CUDA实现Ray-Casting

    在CUDA SDK里有这样的例程。Heresy大牛写的“CUDA Volume Rendering”对此作了详细的介绍。下面我多此一举,加个流程图吧。

     

    图7 CUDA-based ray-casting算法流程图

    传递函数:input为表征3D数据场中重采样点的属性值,如灰度值、梯度值和曲率等;output为重采样点处的光照属性值,如不透明度、颜色等。传递函数实质上是对3D数据场的分类,是可视化技术中的十大难题之一。1D传递函数(灰度—不透明度,和灰度—颜色值)效果有限,增加维度(如梯度值)设计高维传递函数可以更好地区分开各种物质,而当前的研究热点是先用模式分类的方法识别出3D数据场中的感兴趣部分。

     

    图8 一维传递函数

     

    图9 二维传递函数

    【注】重采样:对离散3D数据场的采样,常用三线性插值,而为了更精确复原重采样点处的信息,可以使用复杂度更高的算法,如B样条插值。

     

    6.       后话

    Ray casting的最后一步是由前往后或由后向前。这可以理解成简单的融合——可以参照“Jim Blinn’s Corner”中的“compositing”两篇文章,也可以理解成光线吸收—发射模型中光照积分的离散方法。这个问题在接下来探讨预积分(pre-integration)的文章会有更详细的讲述。

    上文对光照模型说得很少。这可以参照“Real-Time Volume Graphics”。Joe Kniss曾经在体绘制领域活跃过几年,也做了不少重量级的贡献。他用基于三维纹理映射的方法,实现了阴影和多重散射效果。在一系列的关于“Advanced Illumination Techniques for GPU Raycasting”的conference tutorials中,Christof Rezk Salama具体阐述了他在raycasting中添加多重散射效果的方法。他是渲染多个等值面,在等值面之间计算多重散射,分为多个pass,并在“first hit pass”中计算local illumination和ambient occlusion。Christof Rezk Salama的想法源于Joe Kniss。

    我想,这两种实现做了很有意义的探索,而未来将会——现在大概也有了——是先用模式识别分类好物质,然后实现各种各样的光照效果。

    【注】统称为“Advanced Illumination Techniques for GPU Raycasting”的tutorials其实都一样,只是在不同的conference中有不同的名字。这个tutorials还讲述了体数据结构的组织、多分辨率绘制和多规模数据处理等。

    【注】听说Joe Kniss跑去做模式识别了,不知真否。

     

    图10 Joe Kniss's

     

    图11 Christof Rezk Salama's

     

    7.       参考文献

    在上面已经提及了不少,这里就略去了



    光线跟踪计算机算法的一般描述

    为了生成在三维计算机图形环境中的可见图像,光线跟踪是一个比光线投射或者扫描线渲染更加逼真的实现方法。这种方法通过逆向跟踪与假象的照相机镜头相交的光路进行工作,由于大量的类似光线横穿场景,所以从照相机角度看到的场景可见信息以及软件特定的光照条件,就可以构建起来。当光线与场景中的物体或者媒介相交的时候计算光线的反射、折射以及吸收。

    光线跟踪的场景经常是由程序员用数学工具进行描述,也可以由视觉艺术家使用中间工具描述,也可以使用从数码相机等不同技术方法捕捉到的图像或者模型数据。

    由于一个光源发射出的光线的绝大部分不会在观察者看到的光线中占很大比例,这些光线大部分经过多次反射逐渐消失或者至无限小,所以对于构建可见信息来说,逆向跟踪光线要比真实地模拟光线相互作用的效率要高很多倍。计算机模拟程序从光源发出的光线开始查询与观察点相交的光线从执行与获得正确的图像来说是不现实的。

    这种方法的一个明显缺点就是需要假设光线在观察点处终止,然后进行逆向跟踪。在一定数量的最大反射之后,最后交点处的光线强度使用多种算法进行估计,这些算法可能包括经典的渲染算法,也可能包括如辐射着色这样的技术。

    光线跟踪计算机算法及其起源的详细描述

    自然现象

    在自然界中,光源发出的光线向前传播,最后到达一个妨碍它继续传播的物体表面,我们可以将“光线”看作在同样的路径传输的光子流,在完全真空中,这条光线将是一条直线。但是在现实中,在光路上会受到三个因素的影响:吸收反射折射。物体表面可能在一个或者多个方向反射全部或者部分光线,它也可能吸收部分光线,使得反射或者折射的光线强度减弱。如果物体表面是透明的或者半透明的,那么它就会将一部分光线按照不同的方向折射到物体内部,同时吸收部分或者全部光谱并发出辐射。吸收、反射以及折射的光线都来自于入射光线,而不会超出入射光线的强度。例如,一个物体表面不可能反射 66% 的输入光线,然后再折射 50% 的输入光线,因为这二者相加将会达到 116%。这样,反射或者折射的光线可以到达其它的物体表面,同样,吸收、反射、折射的光线重新根据入射光线进行计算。其中一部分光线通过这样的途径传播到我们的眼睛,我们就能够看到最终的渲染图像及场景。

    光线投射算法

    Arthur Appel 于 1968 年首次提出用于渲染的光线投射算法。光线投射的基础就是从眼睛投射光线到物体上的每个点,查找阻挡光线的最近物体,也就是将图像当作一个屏风,每个点就是屏风上的一个正方形。通常这就是眼睛看到的那个点的物体。根据材料的特性以及场景中的光线效果,这个算法可以确定物体的浓淡效果。其中一个简单假设就是如果表面面向光线,那么这个表面就会被照亮而不会处于阴影中。表面的浓淡效果根据传统的三维计算机图形学的浓淡模型进行计算。光线投射超出扫描线渲染的一个重要优点是它能够很容易地处理非平面的表面以及实体,如圆锥球体等。如果一个数学表面与光线相交,那么就可以用光线投射进行渲染。复杂的物体可以用实体造型技术构建,并且可以很容易地进行渲染。

    位于纽约 Elmsford, New York Mathematical Applications Group, Inc.(MAGI)的科学家首次将光线投射技术用于生成计算机图形。1966 年,为了替美国国防部计算放射性污染创立了这个公司。MAGI 不仅计算了伽马射线如何从表面进行反射(辐射的光线投射自从二十世纪四十年代就已经开始计算了),也计算了它们如何穿透以及折射。这些研究工作帮助政府确定一些特定的军事应用;建造能够保护军队避免辐射的军用车辆,设计可以重入的太空探索交通工具。在Philip Mittelman 博士的指导下,科学家们开发了一种使用同样基本软件生成图像的方法。1972 年,MAGI 转变成了一个商业动画工作室,这个工作室使用光线投射技术为商业电视、教育电影以及最后为故事片制作三维计算机动画,他们全部使用光线投射制作了Tron 电影中的绝大部分动画。MAGI 于 1985 年破产。

    光线跟踪算法

    下一个重要的研究突破是 Turner Whitted 于 1979 年做出的。以前的算法从眼睛到场景投射光线,但是并不跟踪这些光线。当光线碰到一个物体表面的时候,可能产生三种新的类型的光线:反射、折射与阴影。光滑的物体表面将光线按照镜像反射的方向反射出去,然后这个光线与场景中的物体相交,最近的相交物体就是反射中看到的物体。在透明物质中传输的光线以类似的方式传播,但是在进入或者离开一种物质的时候会发生折射。为了避免跟踪场景中的所有光线,人们使用阴影光线来测试光线是否可以照射到物体表面。光线照射到物体表面上的某些点上,如果这些点面向光线,那么就跟踪这段交点与光源之间的光线。如果在表面与光源之间是不透明的物体,那么这个表面就位于阴影之中,光线无法照射。这种新层次的光线计算使得光线跟踪图像更加真实。

    光线跟踪的优点

    光线跟踪的流行来源于它比其它渲染方法如扫描线渲染或者光线投射更加能够现实地模拟光线,象反射和阴影这样一些对于其它的算法来说都很难实现的效果,却是光线跟踪算法的一种自然结果。光线跟踪易于实现并且视觉效果很好,所以它通常是图形编程中首次尝试的领域。

    光线跟踪的缺点

    光线跟踪的一个最大的缺点就是性能,扫描线算法以及其它算法利用了数据的一致性从而在像素之间共享计算,但是光线跟踪通常是将每条光线当作独立的光线,每次都要重新计算。但是,这种独立的做法也有一些其它的优点,例如可以使用更多的光线以抗混叠现象,并且在需要的时候可以提高图像质量。尽管它正确地处理了相互反射的现象以及折射等光学效果,但是传统的光线跟踪并不一定是真实效果图像,只有在非常近似或者完全实现渲染方程的时候才能实现真正的真实效果图像。由于渲染方程描述了每个光束的物理效果,所以实现渲染方程可以得到真正的真实效果,但是,考虑到所需要的计算资源,这通常是无法实现的。于是,所有可以实现的渲染模型都必须是渲染方程的近似,而光线跟踪就不一定是最为可行的方法。包括光子映射在内的一些方法,都是依据光线跟踪实现一部分算法,但是可以得到更好的效果。

    光线穿过场景的反方向

    从眼睛发出光线到达光源从而渲染图像的过程有时也称为后向光线跟踪,这是因为它是实际光线传播方向的反方向。但是,对于这个术语来说还有一些混淆的地方。早期的光线跟踪经常是从眼睛开始,James Arvo 等早期研究人员用后向光线跟踪表示从光源发出光线然后收集得到的结果。因为如此,将它们分成基于眼睛或者基于光源的光线跟踪将会更加清楚。在过去的几十年中,研究人员已经开发了许多组合了这两种方向的计算方法与机制以生成投降或者偏离交叉表面的或多或少的光线。例如,辐射着色算法通常根据光源对于表面的影响进行计算并且存储这些结果,然后一个标准的递归光线跟踪器可以使用这些数据生成场景的真实、物理正确的图像。在全局照明算法如光子映射以及Metropolis light transport 中,光线跟踪只是一个用来计算光线在表面之间传输的简单工具。

    上面的内容转载自:http://zh.wikipedia.org/wiki/%E5%85%89%E7%BA%BF%E8%B7%9F%E8%B8%AA#.E5.85.89.E7.BA.BF.E6.8A.95.E5.B0.84.E7.AE.97.E6.B3.95

    =====================================================================================

    光线投射算法:

     

     

    光线追踪:

     

    光线投射法用于非真实感渲染;光线跟踪法用于真实感渲染。

     //

     //


    一个使用CUDA来计算光线追踪的演示,改实现采用了KDTree算法,在GTX280下可以实现14MRays/second的速度,此Demo包含了源代码 近日Nvidia公司也在I3D 2009上展示了一个名为NVIRT的光线追踪引擎,同样是基于CUDA实现的

    一个使用CUDA来计算光线追踪的演示,改实现采用了KDTree算法,在GTX280下可以实现14MRays/second的速度,此Demo包含了源代码

    近日Nvidia公司也在I3D 2009上展示了一个名为NVIRT的光线追踪引擎,同样是基于CUDA实现的

     

    Source code (2.2 MBytes)
    Executable and data (41.2 MBytes)

    点击查看原文



    展开全文
  • 为了生成在三维计算机图形环境中的可见图像,光线跟踪是一个比光线投射或者扫描线渲染更加逼真的实现方法。这种方法通过逆向跟踪与假象的照相机镜头相交的光路进行工作,由于大量的类似光线横穿场景,所以从照相机...

    原文:http://blog.csdn.net/changbaolong/article/details/8461704

    光线跟踪计算机算法的一般描述

    为了生成在三维计算机图形环境中的可见图像,光线跟踪是一个比光线投射或者扫描线渲染更加逼真的实现方法。这种方法通过逆向跟踪与假象的照相机镜头相交的光路进行工作,由于大量的类似光线横穿场景,所以从照相机角度看到的场景可见信息以及软件特定的光照条件,就可以构建起来。当光线与场景中的物体或者媒介相交的时候计算光线的反射、折射以及吸收。

    光线跟踪的场景经常是由程序员用数学工具进行描述,也可以由视觉艺术家使用中间工具描述,也可以使用从数码相机等不同技术方法捕捉到的图像或者模型数据。

    由于一个光源发射出的光线的绝大部分不会在观察者看到的光线中占很大比例,这些光线大部分经过多次反射逐渐消失或者至无限小,所以对于构建可见信息来说,逆向跟踪光线要比真实地模拟光线相互作用的效率要高很多倍。计算机模拟程序从光源发出的光线开始查询与观察点相交的光线从执行与获得正确的图像来说是不现实的。

    这种方法的一个明显缺点就是需要假设光线在观察点处终止,然后进行逆向跟踪。在一定数量的最大反射之后,最后交点处的光线强度使用多种算法进行估计,这些算法可能包括经典的渲染算法,也可能包括如辐射着色这样的技术。

    光线跟踪计算机算法及其起源的详细描述

    自然现象

    在自然界中,光源发出的光线向前传播,最后到达一个妨碍它继续传播的物体表面,我们可以将“光线”看作在同样的路径传输的光子流,在完全真空中,这条光线将是一条直线。但是在现实中,在光路上会受到三个因素的影响:吸收反射折射。物体表面可能在一个或者多个方向反射全部或者部分光线,它也可能吸收部分光线,使得反射或者折射的光线强度减弱。如果物体表面是透明的或者半透明的,那么它就会将一部分光线按照不同的方向折射到物体内部,同时吸收部分或者全部光谱并发出辐射。吸收、反射以及折射的光线都来自于入射光线,而不会超出入射光线的强度。例如,一个物体表面不可能反射 66% 的输入光线,然后再折射 50% 的输入光线,因为这二者相加将会达到 116%。这样,反射或者折射的光线可以到达其它的物体表面,同样,吸收、反射、折射的光线重新根据入射光线进行计算。其中一部分光线通过这样的途径传播到我们的眼睛,我们就能够看到最终的渲染图像及场景。

    光线投射算法

    Arthur Appel 于 1968 年首次提出用于渲染的光线投射算法。光线投射的基础就是从眼睛投射光线到物体上的每个点,查找阻挡光线的最近物体,也就是将图像当作一个屏风,每个点就是屏风上的一个正方形。通常这就是眼睛看到的那个点的物体。根据材料的特性以及场景中的光线效果,这个算法可以确定物体的浓淡效果。其中一个简单假设就是如果表面面向光线,那么这个表面就会被照亮而不会处于阴影中。表面的浓淡效果根据传统的三维计算机图形学的浓淡模型进行计算。光线投射超出扫描线渲染的一个重要优点是它能够很容易地处理非平面的表面以及实体,如圆锥球体等。如果一个数学表面与光线相交,那么就可以用光线投射进行渲染。复杂的物体可以用实体造型技术构建,并且可以很容易地进行渲染。

    位于纽约 Elmsford, New York Mathematical Applications Group, Inc.(MAGI)的科学家首次将光线投射技术用于生成计算机图形。1966 年,为了替美国国防部计算放射性污染创立了这个公司。MAGI 不仅计算了伽马射线如何从表面进行反射(辐射的光线投射自从二十世纪四十年代就已经开始计算了),也计算了它们如何穿透以及折射。这些研究工作帮助政府确定一些特定的军事应用;建造能够保护军队避免辐射的军用车辆,设计可以重入的太空探索交通工具。在Philip Mittelman 博士的指导下,科学家们开发了一种使用同样基本软件生成图像的方法。1972 年,MAGI 转变成了一个商业动画工作室,这个工作室使用光线投射技术为商业电视、教育电影以及最后为故事片制作三维计算机动画,他们全部使用光线投射制作了Tron 电影中的绝大部分动画。MAGI 于 1985 年破产。

    光线跟踪算法

    下一个重要的研究突破是 Turner Whitted 于 1979 年做出的。以前的算法从眼睛到场景投射光线,但是并不跟踪这些光线。当光线碰到一个物体表面的时候,可能产生三种新的类型的光线:反射、折射与阴影。光滑的物体表面将光线按照镜像反射的方向反射出去,然后这个光线与场景中的物体相交,最近的相交物体就是反射中看到的物体。在透明物质中传输的光线以类似的方式传播,但是在进入或者离开一种物质的时候会发生折射。为了避免跟踪场景中的所有光线,人们使用阴影光线来测试光线是否可以照射到物体表面。光线照射到物体表面上的某些点上,如果这些点面向光线,那么就跟踪这段交点与光源之间的光线。如果在表面与光源之间是不透明的物体,那么这个表面就位于阴影之中,光线无法照射。这种新层次的光线计算使得光线跟踪图像更加真实。

    光线跟踪的优点

    光线跟踪的流行来源于它比其它渲染方法如扫描线渲染或者光线投射更加能够现实地模拟光线,象反射和阴影这样一些对于其它的算法来说都很难实现的效果,却是光线跟踪算法的一种自然结果。光线跟踪易于实现并且视觉效果很好,所以它通常是图形编程中首次尝试的领域。

    光线跟踪的缺点

    光线跟踪的一个最大的缺点就是性能,扫描线算法以及其它算法利用了数据的一致性从而在像素之间共享计算,但是光线跟踪通常是将每条光线当作独立的光线,每次都要重新计算。但是,这种独立的做法也有一些其它的优点,例如可以使用更多的光线以抗混叠现象,并且在需要的时候可以提高图像质量。尽管它正确地处理了相互反射的现象以及折射等光学效果,但是传统的光线跟踪并不一定是真实效果图像,只有在非常近似或者完全实现渲染方程的时候才能实现真正的真实效果图像。由于渲染方程描述了每个光束的物理效果,所以实现渲染方程可以得到真正的真实效果,但是,考虑到所需要的计算资源,这通常是无法实现的。于是,所有可以实现的渲染模型都必须是渲染方程的近似,而光线跟踪就不一定是最为可行的方法。包括光子映射在内的一些方法,都是依据光线跟踪实现一部分算法,但是可以得到更好的效果。

    光线穿过场景的反方向

    从眼睛发出光线到达光源从而渲染图像的过程有时也称为后向光线跟踪,这是因为它是实际光线传播方向的反方向。但是,对于这个术语来说还有一些混淆的地方。早期的光线跟踪经常是从眼睛开始,James Arvo 等早期研究人员用后向光线跟踪表示从光源发出光线然后收集得到的结果。因为如此,将它们分成基于眼睛或者基于光源的光线跟踪将会更加清楚。在过去的几十年中,研究人员已经开发了许多组合了这两种方向的计算方法与机制以生成投降或者偏离交叉表面的或多或少的光线。例如,辐射着色算法通常根据光源对于表面的影响进行计算并且存储这些结果,然后一个标准的递归光线跟踪器可以使用这些数据生成场景的真实、物理正确的图像。在全局照明算法如光子映射以及Metropolis light transport 中,光线跟踪只是一个用来计算光线在表面之间传输的简单工具。

    上面的内容转载自:http://zh.wikipedia.org/wiki/%E5%85%89%E7%BA%BF%E8%B7%9F%E8%B8%AA#.E5.85.89.E7.BA.BF.E6.8A.95.E5.B0.84.E7.AE.97.E6.B3.95

    =====================================================================================

    光线投射算法:

     

     

    光线追踪:

     

    光线投射法用于非真实感渲染;光线跟踪法用于真实感渲染。

    转载于:https://www.cnblogs.com/zhizhan/p/3971767.html

    展开全文
  • 体绘制-光线投射算法

    2021-05-20 15:49:39
    本文通过光线投射法原理、详述其流水线、列举其不足与改进。实验中,通过与面绘制技术Marching Cube 算法对比,阐述体绘制算法的优点与不足。 引言 作为直观显示和分析复杂 3D体数据的重要工具,体绘制在医学成像、...

    体绘制-光线投射算法

    介绍

    光线投射算法作为一种直接体绘制技术,其已被广泛应用于医学成像等众多领域。本文通过光线投射法原理、详述其流水线、列举其不足与改进。实验中,通过与面绘制技术Marching Cube 算法对比,阐述体绘制算法的优点与不足。

    引言

    作为直观显示和分析复杂 3D体数据的重要工具,体绘制在医学成像、计算流体动力学、有限元模型、地球物理学、遥感技术等领域起着至关重要的作用。一般地,这些大型的体数据来由磁共振成像(MRI)、计算机断层扫描(CT)、卫星成像和声纳等设备采样或通过数值模拟获得。体绘制旨在将三维体数据投影在二维图像平面上,一个体数据集通常组织为由体素(Voxel)组成的3D 数组 。
    在这里插入图片描述
    一个体素可以表示各种物理特性(如密度、温度、速度和压力)或其它测量(如面积和体积)。大型体数据可能包含数以亿计的体素,因此需要大量的存储空间。在图

    光线投射算法

    光线投射法是一种基于图像序列的直接体绘制技术,由Levoy 于 1988 年提出。
    原理图一
    在这里插入图片描述

    算法原理

    光线投射算法的计算不会停留在物体的表面,而会沿着射线穿过物体内部进行采样,且不会产生二次射线。如图2所示,它通过跟踪从视点到物体的射线将 3D标量数据场中的体数据通过科学计算绘制成 2D 图像。其基本步骤如图3所示,即从屏幕上每一个像素点出发,沿着视线方向发射出一条光线,当这条光线穿过体数据时,沿着光线方向等距离采样,利用插值计算出采样点的光学属性(如颜色值和不透明度);接着按照从前到后(Front-to-back)或从后到前(Back-to-front)的顺序对光线上的采样点进行合成,计算出这条光线对应的屏幕上像素点的颜色值。
    在这里插入图片描述
    光线投射合成公式如下:
    在这里插入图片描述

    其中,As表示透明物体的透明度,Cs表示透明物体的原本颜色,Cd表示目标物体的原本颜色,C0则是通过透明物体观察目标物体所得到的颜色值。
    如果有多个透明物体,通常需要对物体进行排序,除非所有物体的透明度都是一样的。在图形硬件中实现多个透明物体的绘制是依赖于Z缓冲区(Z-Buffer)。在光线投射算法中,射线穿越体纹理的同时也就是透明度的排序过程。所以这里存在一个合成的顺序问题。可以将射线穿越纹理的过程作为采样合成过程,这是从前面到背面进行排序,也可以反过来从背面到前面排序,毫无疑问这两种方式得到的效果是不太一样的。
    如果从前面到背面进行采样合成,则合成公式为:
    在这里插入图片描述

    其中, Ci和 Ai分别是在体纹理上采样所得到的颜色值和不透明度,其实也就是体素中蕴含的数据;deta Ci和 deta Ai表示累加的颜色值和不透明度。
    如果从背面到前面进行采样合成,则合成公式为:
    在这里插入图片描述

    其中,Ci和Ai分别是在体纹理上采样所得到的颜色值和不透明度,其实也就是体素中蕴含的数据;deta Ci和 deta Ai表示累加的颜色值和不透明度。
    在这里插入图片描述

    展开全文
  • 体绘制之光线投射算法(附源码)

    千次阅读 2016-01-29 19:56:21
    Levoy在1988年提出了光线投射(ray-casting)算法[1],其基本原理是:从屏幕上每一个像素点出发,沿着视线方向发射出一条光线,当这条光线穿过体数据时,沿着光线方向等距离采样,利用插值计算出采样点的颜色值和不...
  • 这是一个用于 OPCODE 的 Matlab 包装器,它是一个碰撞检测或用于三角形 3D 网格的光线投射库。 OPCODE 使用几个不同的 aabb 树来存储网格,这是其中一棵树的一个非常简单的包装器。 操作码的好处在于它允许变形网格...
  • ThreeJS 两点间投射线

    2018-08-03 14:46:08
    // 创建射线 Raycaster( origin : Vector3, direction : Vector3, near : Float, far : Float ) // origin: 起始点 // direction: vectorEnd.sub(vectorStr).normalize()为根据两点形成的方向单位向量 // near: ...
  • 可以这么想像:点击屏幕时,就会从视线方向发出一条射线,这条射线可能穿过场景中的多个模型,利用该类提供的方法能够拾取到这些模型。 (1)初始化 this.raycaster = new THREE.Raycaster(); this.mouse = new ...
  • Raycast光线投射,Linecast,RaycastAll

    千次阅读 2016-11-24 10:52:50
    RaycastHit 光线投射碰撞 Struct Structure used to get information back from a raycast. 用来获取从raycast函数中得到的信息反馈的结构。 参见:Physics.Raycast, Physics.Linecast, Physics....
  • 本篇介绍光线投射的第二个个制Pass,光线合成的参数,对应于第一篇总的流程介绍中的Processor SingleVolumeRaycaster.可设置的参数如下: 1,Sampling Rate 采样率 采样率越大,所需要的绘制时间越久,一般来说图像...
  • 光线投射Raycaster 这个类用于进行raycasting(光线投射)。 光线投射用于进行鼠标拾取(在三维空间中计算出鼠标移过了什么物体)。 Raycaster构造器: Raycaster( origin : Vector3, direction : Vector3, near : ...
  •  光线投射方法是基于图像序列的直接体会之算法,从图像的每一个像素,沿固定方向(通常是视线方向)发射一条光线,光线穿越整个图像序列,并在这个过程中,对图像序列进行采样获取颜色信息,同时根据光线吸收模型将...
  • 本文通过光线投射法原理、详述其流水线、列举其不足与改进。实验中,通过与面绘制技术 Marching Cube 算法对比,阐述体绘制算法的优点与不足。 关键词: 体绘制;面绘制;光线投射算法; Marching Cube 算法 引言 ...
  • 第二种光线投射算法的实现,基于光线起点(相机位置)。...每个fragment的坐标作为光线的入射点,由变换后的相机位置与光线入射点确定光线的方向,在沿着光线方向从入射点前进时,每到达一个新的点,判断其是否在长...
  • 下一代3d渲染技术,体素光线投射

    千次阅读 2017-05-16 12:31:45
    下一代3D渲染技术:体素光线投射  在我们回顾一下光线跟踪之后,让我们继续概述可以取代的渲染技术,至少可以补充我们今天所知道的三角形光栅化。 阅读我们以前的文章的人已经知道了,我们并不真正相信实时光线...
  • MonoGame中内置的3D光线投射引擎。 控制项 W / S:前进/后退A / D:向左/向右移动空格/左移:向上/向下移动方向键:向上/向下/向左/向右 安装/运行 确保已安装和 。 通过运行git clone ...
  • Physics2D.Raycast 光线投射

    千次阅读 2015-01-30 17:34:17
    光线投射有助于确定视线(瞄准线),目标被枪击中并有助于实现在游戏中的许多其他目的。 Additionally, this will also detect Collider(s) at the start of the ray. In this case the ray is starting inside...
  • 确定点是在简单多边形内部还是外部的一种简单方法是测试从该点开始并沿任何固定方向行进的射线与多边形边缘相交的次数。 如果所讨论的点不在多边形的边界上,则该点在外部时为偶数,在内部时为奇数。 该算法基于一...
  • 这里球被我命名为po,并且作为camera子对象raycast光线投射碰撞 17.8.5" title="【unity5学习记录】 raycast光线投射碰撞 17.8.5" style="margin:0px; padding:0px; border:0px; list-style:none"> 将这...
  • 摘抄“GPU Programming And Cg ...从图像的每一个像素,沿固定方向(通常是视线方向)发射一条光线,光线穿越整个图像序列,并在这个过程中,对图像序列进行采样获取颜色信息,同时依据光线吸收模型将颜色值进行累...
  • VTK中光线投射法实现体绘制 1、体绘制函数VTK 为使用者提供了三种用于光线投射法的函数分别是:等值面绘制函数(vtkVolumeRayCastIsosurfaceFunction);最大密度投影函数(vtkVolumeRayCastMIPFunction);...
  • 光线投射 static function Raycast (origin : Vector3, direction : Vector3, distance : float = Mathf.Infinity, layerMask : int = kDefaultRaycastLayers) : bool Parameters参数

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,029
精华内容 3,611
关键字:

投射方向线