当前位置: 首页 > 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
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • Angular数据绑定机制
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • Javascript设计模式学习之Observer(观察者)模式
  • JS笔记四:作用域、变量(函数)提升
  • mac修复ab及siege安装
  • MySQL用户中的%到底包不包括localhost?
  • php ci框架整合银盛支付
  • Python学习之路13-记分
  • Redash本地开发环境搭建
  • socket.io+express实现聊天室的思考(三)
  • vue.js框架原理浅析
  • win10下安装mysql5.7
  • 初识 beanstalkd
  • - 概述 - 《设计模式(极简c++版)》
  • 观察者模式实现非直接耦合
  • 力扣(LeetCode)357
  • 嵌入式文件系统
  • 设计模式 开闭原则
  • 协程
  • 一个SAP顾问在美国的这些年
  • 硬币翻转问题,区间操作
  • 在weex里面使用chart图表
  • python最赚钱的4个方向,你最心动的是哪个?
  • 交换综合实验一
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (floyd+补集) poj 3275
  • (全注解开发)学习Spring-MVC的第三天
  • (一) storm的集群安装与配置
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • .libPaths()设置包加载目录
  • .NET CF命令行调试器MDbg入门(一)
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET 发展历程
  • .NET 命令行参数包含应用程序路径吗?
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池