当前位置: 首页 > news >正文

(转)3D模板阴影原理

3D模板阴影原理

1:先从3dsMax中导出一个简单的场景,一个园环,球,平面。

2:园环直接面向光源,园环对球体来说是一个光线的阻挡物,园环在它上面形成阴影,同时,园环和球体对平面来说是光线的阻挡物,所以,同时在其上面形成阴影。


3: 要产生模板阴影,先要找出在园环和球体上面面向光线的面,去除背向光线的面,通过测试光线同园环和球体上面每一个所组成的小角形的法线的夹角是否小于90度,即光线矢量同法线矢量的点积要大于零。

4:在余下的所有面向光线的面中,把每个面的每条边可以保存到一个Vector中,不过在保存之前,先把该条边同已保存在Vector中的每条边先进行逐一比较,如果,找到的这条边同它的两个顶点相同,但顺序相反,则取走在Vector中的这条边。
如找不到,则把该条边加入到Vector中,最后将得到一条(或两条)轮廓线(见图红色线)。

5: 把轮廓线上的每个点延着光线方向延长一定的长度(见黄线),黄线所构成的面(所谓的阴影体)同场景去作比较,即模板测试(stencil)
最后画出阴影部分和非阴影部分,这就是基本的原理。

 

 

 

 

以下摘自《pro ogre 3D programing 》

模板阴影

       模板阴影的概念很简单,影子的形状是根据对象的轮廓和给定的灯光位置计算产生。图11-3中很清晰地展示了相应的原理。在这里需要注意一下,Ogre为阴影提供了一个调试模式,当打开这个功能的时候我们可以看到阴影的空间体积。

 

11-3在Demo_Shadows演示程序中使用调制模板阴影并且启用阴影调试模式

 

阴影体积

       阴影体积是物体轮廓边缘所围成的空间,其中的一端以模型作为封口,另一端的封口通过以下规则得到:

 

       ·如果可编程图形硬件管线可用,顶点程序将使用无穷远来产生空间包围体积。

 

       ·当顶点程序无法使用的时候,阴影体积的另外一端通过对灯光衰弱(点光和聚光)的计算来得到,也可以直接通过SceneManager::setShadowDirectionalLightExtrusionDistance()方法来构造。

 

警告:如果在使用的环境中无法开启对顶点程序的使用,Ogre将不得不使用有限的阴影体积。在这时候需要避免物体太靠近光源,否则就会面临广阔的阴影体积无法在内部产生物体阴影的风险。

 

       阴影体积会在场景空间中形成一个所谓的模板(Stencil)。所有在这个模板内部物体的像素都会被绘制上阴影,而外面的像素则不会。当阴影体积与某一个物体(例如在图11-4中的地面)相交的时候,模板缓存会被更新(在GPU中的一种缓存,类似深度缓存),这个更新将会让相应的像素被渲染成为在“阴影内部”或者“阴影外部”。

11-4Demo_Shadows演示程序中启用阴影调试,表现了阴影体积与地面物体的相交

 

       在图11-4中,通过地板和阴影体积相交而产生的模板,在其中的像素被渲染成暗色调,而外部的其他部分仍然进行普通的渲染。

 

      因为模板阴影技术天生的性质,导致了模板阴影技术实现的影子边缘锐利的结果,在影子内部和外部之间形成了一个明显的边缘。这种类型阴影的好处是即使拉得很长也不会失真(例如黄昏或者黎明时候所产生的物体阴影),但同时意味着阴影的边缘会显得过分明显(特别是当影子被拉长的时候)。Ogre没有提供“让我的阴影变得软化”的开关,而事实上,对于模型板阴影技术来说也不可能有“软”的实现方式。在演示程序Demo_Shadows中使用了这一章节的相应阴影技术。


 

 

相关文章:

  • 使用idea创建一个简单的Spring-boot(一)
  • 创业公司感悟录之十个提醒—作者李天平
  • Zookeeper安装和部署
  • [AAuto]给百宝箱增加娱乐功能
  • centos7防火墙常用命令
  • ExtJs 根据屏幕设置组件的width属性
  • 基于Docker容器运行环境下的全手动安装WordPress
  • 外贸企业建站需慎重 虚拟主机选择是关键
  • Spark Streaming:性能调优
  • [转载] 闻一多——七子之歌
  • 推荐系统中的常用算法
  • 存储类说明符
  • win10 U盘安装ubuntu16.04双系统
  • createQuery is not valid without active transaction
  • hello
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • C++入门教程(10):for 语句
  • ES6核心特性
  • JavaScript-Array类型
  • javascript面向对象之创建对象
  • Webpack 4 学习01(基础配置)
  • 当SetTimeout遇到了字符串
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 原生JS动态加载JS、CSS文件及代码脚本
  • #define、const、typedef的差别
  • #pragma data_seg 共享数据区(转)
  • #单片机(TB6600驱动42步进电机)
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (八十八)VFL语言初步 - 实现布局
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (转)Scala的“=”符号简介
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .NET Core WebAPI中封装Swagger配置
  • .Net IOC框架入门之一 Unity
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • .Net中wcf服务生成及调用
  • .pop ----remove 删除
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理
  • [ 英语 ] 马斯克抱水槽“入主”推特总部中那句 Let that sink in 到底是什么梗?
  • [4.9福建四校联考]
  • [CLR via C#]11. 事件
  • [C语言][PTA基础C基础题目集] strtok 函数的理解与应用
  • [element-ui] el-dialog 中的内容没有预先加载,因此无法获得内部元素的ref 的解决方案
  • [EMWIN]FRAMEWIN 与 WINDOW 的使用注意
  • [HDU 3555] Bomb [数位DP]
  • [IE 技巧] 显示/隐藏IE 的菜单/工具栏
  • [Java][Android][Process] 暴力的服务能够解决一切,暴力的方式运行命令行语句
  • [office] excel如何计算毛重和皮重的时间间隔 excel计算毛重和皮重时间间隔方法 #笔记#学习方法