有光则有影,即时渲染的阴影可以使场景看上去更加真实。
算法描述:
ShadowMap是一种基于阴影图的阴影生成方法,阴影图是一张2D贴图。阴影图中的每个像素都记录了从光源到遮挡物(遮挡物就是阴影生成物体)的每个“可见”像素的距离。这里的“可见”像素是指,以光源为观察点,光的方向为观察方向,设置观察矩阵并渲染所有遮挡物,最终出现在渲染表面上的像素。使用ShadowMap渲染阴影主要分两个过程:生成阴影图和使用阴影图渲染。下面的代码取自生成阴影图的PS代码
float distance=distance(lightpos,input.PWorld); ①
distance*=distancescale; ②
distance-=depthbais; ③
return distance; ④
① distance是HLSL的内置函数用于计算两点距离,这里获得了光源到当前像素的距离。
② disancescaler用于对距离值进行缩放,这个值可以通过应用程序设置,使用它就可以对阴影进行即时可见的调整。
③ depthbais同样用于阴影图调整。
④ 返回距离值,实际上此时的渲染目标已经被设置成阴影图,阴影图的设置方法和上节的立方体环境贴图类似,不过这里只需要将遮挡物渲染一次。
下图显示了一个场景和其使用到的阴影图。
需要在阴影图中保存从光源到“可见”点的距离是因为:利用这个距离就可以直接判
断一个像素是否在阴影中。如果一个世界空间的“点”到光源的距离大于阴影图中对
应像素的值,那么这个点肯定已经被另一个离光源更近的点遮挡住了,所以它肯定在
阴影中。基于这个原理就可以很容易的编写渲染阴影的代码了。
下面的代码取自渲染阴影的PS代码
float CurrentPixelDistance=distance(lightpos,input.PWorld)*distancescale+depthbais;①
Shadow = (CurrentPixelDistance > tex2Dproj(shadowmap,input.ShadowMapCord))②
Shadow*=ShadowDensity;③
Return Shadow;
|
① 这里获得当前像素到光源的距离。
② 首先对阴影图采样,再用当前像素的值和采样所得的值进行比较。大于则当前像素在阴影中,Shadow=1;否则Shadow=0;
③ 这里ShadowDensity同样由应用程序调整,用于设置阴影浓度。
该PS返回了阴影值,该数值越大表示阴影越浓。但是直接将其输出是不行的,因为这里只有阴影,而场景必须将场景本身的颜色和阴影“混合”输出。这里的解决方案是AlphaBlend,简单的说就是首先按照指定的方式渲染场景,这里可以使用前面说的任何渲染方式;接着渲染阴影,在渲染阴影的时候启用AlphaBlend,这样前后两次渲染的结果就可以通过AlphaBlend“混合”在一起了。
另外,由于阴影图是一种基于贴图采样的技术。渲染效果和阴影图的分辨率有着极大的关系,当提高分辨率无法满足渲染效果的需要时,有必要采用一些图象处理的方法。例如,对阴影图进行多次采样使得阴影的边缘更加平滑。下面的Shader使用2×2PCF(Percentage Closer Filter)方法对阴影图进行过滤。
float ShadowDepth=tex2Dproj(shadowmap,input.ShadowMapCord);①
float ShadowDepth1=tex2Dproj(shadowmap,input.ShadowMapCord+float4(-SampleOffset,0,0,0));
float ShadowDepth2=tex2Dproj(shadowmap,input.ShadowMapCord+float4(0,-SampleOffset,0,0));
float ShadowDepth3=tex2Dproj(shadowmap,input.ShadowMapCord+float4(-SampleOffset,0,0,0));
float Shadow = (CurrentPixelDistance > ShadowDepth);②
float Shadow1=CurrentPixelDistance> ShadowDepth1;
float Shadow2=CurrentPixelDistance> ShadowDepth2;
float Shadow3=CurrentPixelDistance> ShadowDepth3;
……………………………………….
finalshadow=(Shadow+Shadow1+Shadow2+Shadow3)/4;③
|
① 这四行代码对阴影图执行了4次采样,每次采样以Sample Offset为偏移量,获得阴影图中对应像素周围4个像素所保存的光源距离。
② 这四行代码用每一个距离值和当前像素距离值比较得到4个阴影值。
③ 平均四个阴影值,得到最终的阴影值。
很显然,当一个像素处于阴影边缘的时候,4次采样中可能会有部分结果为0,部分为1。平均以后就可以得到一个
0,1之间的值,这个值将会表现在阴影的浓度上,这样就可以形成平滑的阴影边缘。但是,提升效果的代价也是明
显的,使用多次采样会明显的降低速度。由于PS2.0最多可用64条指令,编写3×3PCF刚好够用,效果更好,但也
更慢。
下图对各种采样方式做了一个比较。从左到右逐渐提高了PCF(百分比渐进过滤)的采样次数:
结论,本文给出了一个ShadowMap的实现方式。需要注意的是,文中所提到的PCF实现方式并不是最佳的,因为现在的很多图形硬件已经从硬件上支持多次采样的PCF技术,这种技术能够获得更好的执行效率并且能够免除ps指令条数的限制。
分享到:
相关推荐
5. **MainFrame.cpp, BaseDraw.cpp, MyGLSL.cpp, shadowmap.cpp, Camera.cpp, StdAfx.cpp, shadowmap.dsp, shadowmap.dsw**: 这些文件是项目的主要组成部分,它们分别包含了项目框架、基本绘制操作、GLSL相关的...
OpenGL Shadow Map阴影实现 在3D图形编程中,阴影效果是增强场景真实感的重要手段。...在提供的文件列表中,`shadowmap.cpp`很可能是实现Shadow Map的核心部分,而其他文件则提供了支持性的框架和功能。
《D3D11_ShadowMap1:深度阴影贴图技术在Direct3D11中的应用》 在3D图形编程领域,为了实现更逼真的光照效果,阴影的模拟是必不可少的一部分。本项目“D3D11_ShadowMap1”专注于在Direct3D11环境下,利用深度阴影...
"Shadow Map"技术就是一种常用的实现实时阴影的方法,特别是在3D游戏和虚拟现实应用中。本话题将深入探讨如何利用OpenGL和GLSL(OpenGL着色语言)来创建基本的纹理阴影。 一、阴影贴图(Shadow Map)原理 阴影贴图...
在3D图形渲染领域,"ShadowMap + Phong"是一个重要的技术组合,它结合了阴影映射(ShadowMap)和菲涅尔(Pong)光照模型,以提高场景的真实感和视觉质量。这两种技术都是现代实时渲染中的核心组件,主要用于创建更逼真的...
Shadowmap是实现软阴影和硬阴影的一种常见技术,而Phong光照模型则为物体提供了真实感的反射和高光效果。在"改进后的GLSL+Shadowmap"项目中,我们将会探讨如何利用这些技术来提升场景的真实感。 首先,让我们深入...
《深度阴影贴图(Shadow Map)在DirectX9.0 SDK Sample中的实现解析》 深度阴影贴图(Shadow Map),也称为Shadow Mapping,是计算机图形学中一种常用的实时光照技术,用于模拟真实世界中物体投射的阴影效果。在...
- Shadow Map是一个从光源视角看场景的深度纹理,记录了场景中每个点到光源的距离。 - 这个深度纹理在渲染时被用来判断物体表面是否在光源的阴影中。 2. **光源和摄像机视角**: - 在OpenGL中,我们需要两个不同...
在提供的"ShadowMap"压缩包中,可能包含有Unity项目文件,用于展示如何创建和配置Shadow Map,以及相关的脚本示例。你可以通过导入这些文件到Unity编辑器中,实际操作并观察效果,加深理解。 通过查阅链接的博客...
"Shadow Map" 技术是一种常用的实时光照计算方法,它通过将光源视角下的场景深度信息编码到一张纹理中,然后在接收光照的物体上进行采样,判断物体是否处于阴影中。而"Percentage-Closer Filtering (PCF)"则是一种...
unity shader实现自定义shadowmap,shadowmask原理学习用
5. **硬件加速**:现代GPU提供了硬件支持的阴影映射功能,如OpenGL的Shadow Volumes和Direct3D的Shadow Map纹理采样,大大提升了阴影映射的效率。 6. **高级阴影技术**:除了基本的阴影映射,还有许多高级技术,如...
在OpenSceneGraph (osg) 中实现ShadowMap是一种增强3D场景真实感的重要技术。ShadowMap是将光源的位置作为观察者,记录下场景中物体在光源视角下的投影,然后在渲染时使用这些投影来确定哪些区域应该被遮蔽,从而...
### 阴影渲染 Shadowmap 知识点详解 #### 一、阴影渲染与 Shadow Mapping 概述 阴影渲染在计算机图形学中是一项至关重要的技术,它能够显著提高三维场景的真实感。随着计算机图形学的发展,多种阴影生成算法...
Shadow Map,也称为深度贴图,是一种计算和投射阴影的技术,它广泛应用于游戏开发和实时渲染领域。本篇文章将深入探讨Shadow Map的概念、工作原理以及如何在Unity引擎中实现动态阴影。 一、Shadow Map简介 Shadow ...
《GL_ShadowMap与Phong光照在图形渲染中的应用》 在计算机图形学领域,真实感渲染是追求的目标之一,而阴影是增加场景真实感的关键因素。GL_ShadowMap技术结合Phong光照模型,能够有效地在3D场景中实现高质量的阴影...
# Shadow Map 技术在三维图形中的应用及发展 ## 摘要 在现代三维图形渲染技术中,阴影效果是提升场景真实感的关键因素之一。本文主要探讨了阴影映射(Shadow Maps)这一技术的基本原理及其在当前图形渲染领域的...
【标题】:“最初级的Shadow Map” 在3D图形编程中,阴影映射(Shadow Mapping)是一种常用的技术,用于在场景中实现逼真的光照效果,尤其是动态光源产生的影子。这个话题涉及到Direct3D,一个由微软开发的API,...
透视阴影贴图(Perspective Shadow Map,PSM)是计算机图形学中用于渲染真实感阴影的一种高级技术。在3D游戏中或复杂的可视化应用中,阴影的逼真度对整体视觉效果有着重大影响。传统的阴影贴图方法,如正交阴影贴图...
**Variance Shadow Map的工作原理** 1. **存储阴影信息:**在传统Shadow Mapping中,我们直接存储每个像素是否被遮挡(1或0)。而在VSM中,我们存储两个值——阴影像素的平均深度(Mean)和深度方差(Variance)。...