一、创建阴影
//参数:阴影贴图的大小和光源
let shadow=new BABYLON.ShadowGenerator(1024,light)
//定义要渲染的网格,添加阴影投射
//shadow.addShadowCaster(sphere)
shadow.getShadowMap().renderList.push(sphere)
//地面接收阴影
ground.receiveShadows=true
//1.泊松抽样.禁用方差阴影贴图,此滤镜使用泊松采样来柔化阴影。结果更好,但速度更慢。
shadow.usePoissonSampling=true
/*
*2.指数阴影贴图
*默认情况下为true,因为减少阴影的锯齿很有用。但是,如果您想减少计算时间
*请随时将其关闭。您还可以通过更改shadowGenerator.depthScale.
*默认情况下,该值为 50.0,但如果您的世界的深度比例(MinZ 和 MaxZ 之间的距离
*很小,您可能需要更改它。
*/
shadow.useExponentialShadowMap = true
/*
*3.模糊指数阴影贴图
*这是更好的柔化阴影滤镜,但也更慢。它使用模糊指数阴影贴图。
*/
shadow.useBlurExponentialShadowMap = true ;
shadow.useKernelBlur = true;
shadow.blurKernel = 20;
shadow.addShadowCaster(sphere)和shadow.getShadowMap().renderList.push(sphere)都能创建阴影。
模糊的质量由以下属性定义:
shadowGenerator.blurScale
:在应用模糊后处理之前定义用于缩小阴影贴图的比例。默认情况下,值为 2shadowGenerator.blurBoxOffset
:定义用于应用模糊的框边缘的偏移量。默认情况下,该值为 1(这意味着框将在两个方向上从 -1 变为 1,从而导致模糊后处理读取 9 个值)。shadowGenerator.useKernelBlur
:您可以决定使用内核模糊而不是框模糊。虽然有点贵,但使用内核模糊的阴影质量要好得多。您可以使用 来控制内核大小shadowGenerator.blurKernel
,默认值为 1。
二、关闭指数阴影贴图
从 Babylon.js 3.0 开始,我们引入了一种新的指数阴影贴图方法来处理自阴影问题:闭合指数阴影贴图 (CESM)。使用 CESM,您可以获得准确的自阴影,但您需要定义其他参数:
- 您必须通过设置
light.shadowMinZ
和来提供来自灯光的最小深度值范围light.shadowMaxZ
。范围越小,阴影就越好。 - 您必须确保光线尽可能靠近阴影投射器。
//启用CESM
//shadow.useCloseExponentialShadowMap=true
//使用模糊的阴影
shadow.useBlurCloseExponentialShadowMap = true
三、PFC阴影
PCF 阴影受益于 Webgl2 中可用的新硬件过滤功能,并产生更平滑的泊松采样版本。当 Webgl2 在目标设备上不可用时,它们会回退到标准泊松采样。
//启用PFC阴影,
shadow.usePercentageCloserFiltering = true
由于 PCF 需要的资源比小型平台上可用的资源多,因此您可以使用该filteringQuality
属性根据您的经验选择质量和性能之间的最佳折衷(质量越低,性能越好)。
shadow.filteringQuality = BABYLON.ShadowGenerator.QUALITY_LOW
四、PCSS 阴影的接触硬化阴影
PCSS 可以被视为 PCF 的改进版本,但尽管看起来更好,但它们的处理器成本也更高,应该保留给桌面应用程序。与 PCF 一样,如果代码在 WebGL 1 平台上运行,它们将自动回退到泊松采样。
在 PCSS 中,阴影在远离投射它们的对象时会变得更柔和,模拟现实生活中发生的情况。
为了获得准确的结果,您需要定义其他参数:
- 您必须通过设置
light.shadowMinZ
和来提供来自灯光的最小深度值范围light.shadowMaxZ
。范围越小,阴影就越好。 - 您还可以使用以下参数
contactHardeningLightSizeUVRatio
来更改阴影柔化的速度(在 0 和 1 之间)。
shadow.useContactHardeningShadow = true
shadowGenerator.filteringQuality = BABYLON.ShadowGenerator.QUALITY_LOW;
由于 PCSS 需要的资源比小型平台上可用的资源多,您可以使用该filteringQuality
属性根据您的经验选择质量和性能之间的最佳折衷。(质量越低性能越好)。
五、透明物体投射阴影
要使透明对象投射阴影,您必须在阴影生成器上将transparencyShadow
属性设置为:true
可以为透明对象模拟柔和的透明阴影。为此,您需要将enableSoftTransparentShadow
属性设置true
为阴影生成器
六、使用偏差
//定义偏差
shadow.bias=0.0001
七、边缘衰减
shadow.frustumEdgeFalloff =1
当对象靠近地面时需要对其阴影的衰减进行处理。
八、冻结阴影
//冻结阴影
shadowGenerator.getShadowMap().refreshRate =
BABYLON.RenderTargetTexture.REFRESHRATE_RENDER_ONCE;
//要求灯光不要重新计算阴影位置
light.autoUpdateExtends = false;
九、清洁骨基质
动画网格的错误或不精确的骨骼权重可能会导致负面或奇怪的阴影。在这种情况下,您可以在使用以下代码加载时自动清理权重
BABYLON.SceneLoader.CleanBoneMatrixWeights = true;
十、一种较好的阴影示例
var light = new BABYLON.SpotLight("spotLight",
new BABYLON.Vector3(-40, 40, -40),
new BABYLON.Vector3(1, -1, 1), Math.PI / 5, 30, scene);
//参数:阴影贴图的大小和光源
let shadow=new BABYLON.ShadowGenerator(1024,light)
//定义要渲染的网格,添加阴影投射
//偏差
shadow.bias = 0.001;
shadow.normalBias = 0.02;
light.shadowMaxZ = 100;
light.shadowMinZ = 10;
//启用PCSS阴影
shadow.useContactHardeningShadow = true;
shadow.contactHardeningLightSizeUVRatio = 0.05;
shadow.setDarkness(0.5);
shadow.addShadowCaster(sphere)
//shadow.getShadowMap().renderList.push(sphere)
//地面接收阴影
ground.receiveShadows=true
shadow.addShadowCaster(sphere)
sphere.receiveShadows=true