问题十三:怎么用ray tracing画个球
当然这个球是画在之前的背景图上。
通过画第一张图,已经直到画图有两个步骤:其一,确定位置(范围、大小);其二,设置颜色。
画球也不例外。
第一步:确定球的位置。球上每个像素点的位置即为光线与球的交点,所有这些交点就组成了球。所以,问题转化为找光线和球的交点。
第二步:设置球的颜色。即设置光线和球交点的颜色。
(图都是一个像素点一个像素点画出来的,一个光线代表着一个像素点。此处和球有交点的光线对应的像素点就设置成球的颜色)
13.1 光线撞上球
先抄相关源代码:(红色字体为新增代码)
boolhit_sphere(const vec3& center, float radius, const ray& r)
{
vec3oc = r.orgin() - center;
float a = oc.dot(r.direction(), r.direction());
float b = 2.0 * oc.dot(oc, r.direction());
float c = oc.dot(oc, oc) - radius*radius;
float discriminant = b*b - 4*a*c;
return (discriminant > 0);
}
vec3 color(const ray&r)
{
if(hit_sphere(vec3(0,0,-1), 0.5, r))
return vec3(1, 0, 0);
vec3 unit_direction =unit_vector(r.direction());
float t =0.5*(unit_direction.y() + 1.0);
return(1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0);//white, light blue
// return(1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(1.0, 0, 0.7);//white, pink
}
先解释“光线撞上球”的情况:
球上任一点的坐标(向量)为P,球心坐标(向量)为C,球的半径为R,则球的方程为
|P-C|2=R2即(P-C)( P-C)= R2,注意这里的P,C都是向量,所以,
方程等价于:dot((P-C),( P-C))=R2
光线的方程:R(t)=A+t*B (参考“问题十二”)
“光线撞上球”意味着光线和球在“撞点”上相交,将光线方程代入球方程,得到:
dot((A+t*B-C),( A+t*B -C))= R2
(B*t +(A-C))·(B*t + (A-C)) = R2
(B·B)*t2 + 2*(B·(A-C))*t +(A-C)·(A-C) - R2=0
所以,
a = (B·B)=dot(B,B),
b=2*(B·(A-C))=2*dot(B,(A-C)),
c= (A-C)·(A-C) - R2=dot((A-C),(A-C))- R2,
当方程有实根时,说明光线和球有交点,也就是说这条光线撞上了球。至于方程在什么情况下有实根,哦也,请初中数学老师!!!
b2-4ac= ……
对照源代码:
boolhit_sphere(const vec3& center, float radius, const ray& r)
{
vec3oc = r.orgin() - center;
//得到向量A-C=oc
float a = oc.dot(r.direction(), r.direction());
//B即为光线的方向向量。a = (B·B)=dot(B,B),
float b = 2.0 * oc.dot(oc, r.direction());
// b=2*(B·(A-C))=2*dot(B,(A-C)),
float c = oc.dot(oc, oc) - radius*radius;
//c= (A-C)·(A-C) - R2=dot((A-C),(A-C)) - R2,
float discriminant = b*b - 4*a*c;
return (discriminant > 0);
//判别式>0,有实根,光线撞上球,返回1;
//判别式<0,没有实根,光线没有撞上球,返回0;
}
13.2 给球上每个像素点设置颜色
vec3 color(const ray&r)
{
if(hit_sphere(vec3(0,0,-1), 0.5, r))
return vec3(1, 0, 0);
//此处判断这条光线是否撞上球。
//如果撞上,则执行return vec3(1, 0, 0),将这个像素点设置为红色。
//如果没有撞上,则不执行returnvec3(1, 0, 0),程序向下运行,将这个像素点设置为背景色。
vec3 unit_direction =unit_vector(r.direction());
float t =0.5*(unit_direction.y() + 1.0);
return(1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0);//white, light blue
// return(1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(1.0, 0, 0.7);//white, pink
}
结果图片:
问题十三:怎么用ray tracing画个球相关推荐
- 问题五十三:怎么用ray tracing画参数方程表示的曲面(1)
首先,以球面为例学习怎么用ray tracing画参数方程表示的曲面:然后,再画一个牛角面. 特别说明:这一章节所画的曲面只是示意性的,所以先不care图片上的瑕疵. 53.1 数学推导 球面的参数方 ...
- 问题三十三:怎么用ray tracing画特殊长方体(box)
33.1 怎么用ray tracing画特殊长方体 在光线追踪中被用到的一种常见形态是长方体盒子.这种基本物体被用于可见物体和包围盒,包围盒被用于加速复杂物体的相交测试. 吐槽:单词都认识,就是不知道 ...
- 问题五十四:怎么用ray tracing画参数方程表示的曲面(2)—— bezier surface
首先,需要说明的是: 这一章节可以看作"问题五十三"的另一个例子--bicubic bezier surface: 之前已经用"球面"和"牛角面&qu ...
- 问题六十六:怎么用ray tracing画CSG(Constructive Solid Geometry 构造实体几何)图形
66.1 概述 什么是CSG图形? 若干简单图形通过集合运算后得到的复杂图形,被称为"CSG图形". 其中"简单图形",包括:sphere, box, cyli ...
- Q77:怎么用Ray Tracing画仿射变换之后的图形
77.1 理论说明 如上图所示,椭球面是球面通过仿射变换T得到的. 现在我们的问题是:怎么ray trace变换后的椭球面? (先重申一点:经过仿射变换之后,直线还是直线,光线还是光线) 我们应该这么 ...
- 问题十七:怎么用ray tracing画多个球?
回忆一下,一个球是怎么画的呢? 第一步:光线撞上球.找"撞点" 第二步:将"撞点"的像素位置设置为球的颜色.之前采用过两种方式设置颜色:1,简单粗暴,将整个球的 ...
- 问题六十三:怎么用ray tracing画sphere sweeping图形
63.1 概述 Translational sweeping.conic sweeping.rotational sweeping都是任意曲线以某种固定方式移动后形成的图形. 接下来,我们要画的sph ...
- 问题六十三:怎么用ray tracing画sphere sweeping图形(2)——teapot
63.5 组合rotational sweeping和sphere sweeping画一个teapot ----------------------------------------------ma ...
- 问题五十:怎么用ray tracing画blobs
这一节,画这个: 参考文献: Blinn, J.F., A generalization of algebraic surfacedrawing. ACM Trans. Graph. 1(3) , 2 ...
最新文章
- 小米miui系统怎么关闭文件管理里的热门视频和表情?
- CTR模型越来越深,如何让它变轻?
- 代理模式coding-动态代理
- Python协程(真才实学,想学的进来)
- python 创建文件_Python入学首次项目,新手必看,简单易操作
- Entity Framework Core Lolita
- 异或!!不占用额外空间!!
- 支付宝app支付java后台流程、原理分析(含nei wang chuan tou)
- Entity Framework 4.1 DbContext使用记之三——如何玩转实体的属性值?
- linux下php安装
- rand(m,n) 续行
- vue2饿了吗之路第一篇:开发环境准备
- 方舟编译器编译linux,方舟编译器环境配置
- 图书管理系统(个人)
- 一个本科生的毕业设计和论文
- 微信小黄鸡php,微信表情包小黄鸡含义
- 国外计算机论文范文精选,国外计算机论文参考范文.doc
- Linux shell复习
- js汉字转拼音包——pinyin-pro
- python提取微信聊天语音_利用Python进行微信,QQ的语音识别!内部技术的延伸版!...