0.简介

目前我们的程序能模拟一些反射和折射的效果,但是,目前物体可见主要还是由于物体自身发光,也就是材质的light属性不为0,从这里开始,要彻底的实现光源发光,其余物体依靠光源的光反射光线的方法显示。

注:贴出源码与最终源码可能有所不同,以最终源码为准。

1.光源

定义一个光源很简单,就是将光源材质的light设置一个大于0的数字,这就是光源,其余的等于0的都是非光源。

2.阴影

有了光源,就可以产生阴影效果,直接将每个物体与光源直接连接光线,也就是检测每个物体与光源之间是不是有其余物体格挡,有的话就不叠加光源的光强度,没有的话就接收光源的光强来显示物体表面颜色。在计算光源与物体之间关系的时候,要每个物体都遍历一遍,这样产生的效果就会有阴影效果了。

for (auto obj : s){vec3 color = vec3(0, 0, 0);float light = 0;int count = 0;//能发光的话,单个物体if (!obj->isSet && (obj->m->light > 0.0f)){//for (int i = 0; i < 5; i++){if (((Polygon*)(r.polygon))->m != nullptr && ((Polygon*)(r.polygon))->m->light > 0&&(r.polygon!=obj))break;//获取光源上随机一点vec3 point = obj->getLightCenter();//构造光线,光源与当前物体的直接连线lightRay = Ray(normalize(point - r.end.position), r.end.position, r.intensity, r.color, nullptr);//计算光碰撞的颜色,minDistance = FLT_MAX;for (int i = 0; i < s.size(); i++){Ray t = s[i]->intersect(lightRay);if (t.polygon != nullptr && t.distance < minDistance){minDistance = t.distance;lightRay = t;}}//如果物体是直接对着光源,获取光源的信息if (lightRay.polygon == obj){light += lightRay.intensity;color += lightRay.color;count++;}if (count == 0){color = vec3(0, 0, 0);light = 0;//continue;}else{light /= count;color /= (count * 1.0);}lightRay.intensity = light;lightRay.color = color;lightsRay.push_back(lightRay);}}

目前的光源是球形光源,球形光源的中,光发出中心就是球心,那么每个物体上表面的点与球形光源的球心直接连线形成光线,这样就可以实现光照效果。上述代码中,先从物体集合中找到光源,然后计算构造好的指向光源的光线中途有没有其余物体遮挡,由于场景中的光源不一定只有一个,所以将构造的指向不同光源的光线最后都存储到数组中。

3.光线颜色和强度计算


Ray Polygon::sample(Ray out, Ray reflect, Ray refract, vector<Ray> lightsRay)
{Ray res(out.direction, out.position, 0, vec3(0, 0, 0), out.polygon);if (m->light > 0){res.intensity = (m->light);res.color = m->getColor(out.end.textureUV);return res;}//out光线带的是对应物体的法向量值float cosa = abs(dot(out.normal,-out.direction));//光线入射角和面法向量的cos值for (auto lightRay : lightsRay){float cosl = abs(dot(out.normal, -lightRay.direction));//计算光源的发出中心//float cosl = abs(dot(out.normal, -normalize(((Polygon*)(lightRay.polygon))->getLightCenter()-lightRay.position)));res.color += (m->getColor(out.end.textureUV)*0.6f+lightRay.color*0.4f) * (m->light + std::fmaxf(cosl, 0) * lightRay.intensity * (1.0f - m->transparent)) * std::fmaxf(cosa, 0);res.intensity += std::fmaxf(cosl, 0) * lightRay.intensity * (1.0f - m->transparent)* std::fmaxf(cosa, 0);}res.intensity += reflect.intensity * m->getSpecular(out.end.textureUV);res.intensity += refract.intensity * m->transparent;if(reflect.polygon)res.color += reflect.color * m->getSpecular(out.end.textureUV);if (refract.polygon)res.color += refract.color * m->transparent;return res;
}

这里新添加了一个函数参数,就是光线,现在一个物体的一个点接受来自反射,折射,和光源的光线,这里把光线的强度添加了进来,还有光源的颜色也添加了进来。还要注意光线强度还要乘以光线与被照到表面的法向量的cos值,这样能体现出离光源近亮,离光源远就暗。

Ray Sphere::intersect(Ray & ray)
{Ray result(ray.direction,ray.position,ray.intensity, vec3(0,0,0), nullptr);//计算球和光线的向量vec3 v = ray.position - center;//如果光源在球体表面或者内部,要专门注意这种情况if (abs(length(v) - radius) < 0.001 && dot(normalize(v) , ray.direction) <= 0){result.polygon = this;    float cosa = glm::dot(normalize((center - ray.position)), normalize(ray.direction));//normalize(abs((center - ray.position))*normalize(ray.direction));result.distance = 2 * radius * abs(cosa);result.end = ray.getEndPoint(result.distance);result.normal = -normalize(result.end.position - center);result.intensity = m->light;result.color = m->getColor(result.end.position);return result;}float disSubR = dot(v , v) - (radius * radius);float ray_v_dot = dot(ray.direction , v);if (ray_v_dot <= 0){float discr = ray_v_dot * ray_v_dot - disSubR;if (discr >= 0){result.polygon = this;result.distance = -ray_v_dot - sqrt(discr);result.end = ray.getEndPoint(result.distance);result.normal = normalize(result.end.position - center);result.intensity = m->light;result.color = m->getColor(result.end.position);return result;}}return result;
}

在球形和平面的这个碰撞检测函数中,返回的光线结果带有光源信息,就是直接将是否有光强,和物体表面颜色返回,这样可以在与光线连接计算中直接获得光线信息。函数参数也变成了引用,因为我在程序性能检测中发现函数传参数占用了不少时间。

4.效果

光源和阴影效果

5.源码

由于这次和上次的源码差距比较多,所以最后给出源码。

学习光线追踪(19)---光源[1]相关推荐

  1. c语言图片透明度混合,【PS CC 2018 学习连载 19】如何让图层与图层之间融合的更好?不透明度和混合模式详细讲解...

    原标题:[PS CC 2018 学习连载 19]如何让图层与图层之间融合的更好?不透明度和混合模式详细讲解 说起图层,根据之前的连载,已经学习了不少内容,比如: 但以上内容,都只是对图层的理解以及对指 ...

  2. Ext.Net学习笔记19:Ext.Net FormPanel 简单用法

    Ext.Net学习笔记19:Ext.Net FormPanel 简单用法 FormPanel是一个常用的控件,Ext.Net中的FormPanel控件同样具有非常丰富的功能,在接下来的笔记中我们将一起 ...

  3. Caffe学习系列(19): 绘制loss和accuracy曲线

    转载自: Caffe学习系列(19): 绘制loss和accuracy曲线 - denny402 - 博客园 http://www.cnblogs.com/denny402/p/5110204.htm ...

  4. springmvc学习笔记(19)-RESTful支持

    springmvc学习笔记(19)-RESTful支持 标签: springmvc springmvc学习笔记19-RESTful支持 概念 REST的样例 controller REST方法的前端控 ...

  5. 深度学习(19)神经网络与全连接层二: 测试(张量)实战

    深度学习(19)神经网络与全连接层二: 测试(张量)实战 1. 传入测试集数据 2. 数据类型转换 3. 创建test_db 4. test/evluation 5. 创建神经网络 6. 输出 7. ...

  6. Android 8.0系统学习(19)--- SystemUI启动流程

    Android 8.0系统学习(19)--- SystemUI启动流程 systemui属于系统级应用,在开机过程中就会启动.具体来讲是在SystemServer进程中startOtherServic ...

  7. 区块链学习笔记19——ETH难度调整

    区块链学习笔记19--ETH难度调整 学习视频:北京大学肖臻老师<区块链技术与应用> 笔记参考:北京大学肖臻老师<区块链技术与应用>公开课系列笔记--目录导航页 前面学过,比特 ...

  8. 《用一周学习光线追踪》2.BVH树、AABB相交检测

    本项目上接<用两天学习光线追踪>,继续学习光线追踪. 项目链接:https://github.com/maijiaquan/ray-tracing-with-imgui 目录: <用 ...

  9. 《用两天学习光线追踪》1.项目介绍和ppm图片输出

    本项目参考自教程<Ray Tracing in One Weekend>,在跑通了所有例子之后,加上了自己的理解写成笔记,项目使用CPU多线程提速,并增加了GUI进度显示. 项目链接:ht ...

最新文章

  1. react native 网络请求 axios
  2. Android时间选择器对话框的使用
  3. 用JS实现发邮件的功能 完美解决
  4. 领域驱动设计(DDD)的精髓
  5. 社会管理网格化 源码_为什么说网格化管理是基层社会治理的有效武器
  6. django-演练-英雄的编辑
  7. Bitmap如何高效加载图片
  8. BP神经网络参数设置及实例
  9. 关于 Spring 注解和 XML 的选择问题
  10. MySQL数据库基础理论
  11. 云服务器安装KALI教程
  12. MYSQL 命令行大全
  13. 更改计算机复制快捷键,电脑复制粘贴快捷键,详细教您电脑怎么用键盘复制粘贴...
  14. js判断对象上是否含有某个属性
  15. Sunday算法特征码搜索C++(支持通配符)
  16. 测试经理必知必会-Kanban和Scrum区别
  17. neo4j :rel_Neo4j:足球转移图表
  18. Java中带有T Z格式(UTC是世界标准时间)的时间转换为date,string,long类型
  19. 《Dream it possible》【梦想能成真】——最具感人,激励,追梦的英文歌曲,华为主题曲。
  20. 我的 “地形” 我做主

热门文章

  1. 3D修复版《泰坦尼克》2012上映 纪念沉没百年
  2. 传说中的程序员的七种武器
  3. 镇江SEO顾问:讲述,怎么查百度收录!
  4. SEO优化网站教程4
  5. 刺激战场pc服务器没有响应,刺激战场PC端玩不了怎么办 PC端玩不了解决方法[多图]...
  6. Which前加逗号与不加逗号有什么区别
  7. apache zip解压,使用org.apache.tools.zip实现zip压缩和解压
  8. ChatGPT的朋友们:大语言模型经典论文一次读到吐
  9. 2021高考成绩排名查询怎么,2021年山东高考成绩排名查询系统,山东高考位次排名查询...
  10. 一加账号app_一加帐号手机服务全面升级,将由欢太 HeyTap 提供服务