Babylon.js 第17章 阴影

发布于:2022-12-25 ⋅ 阅读:(422) ⋅ 点赞:(0)

一、创建阴影

    //参数:阴影贴图的大小和光源
    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:在应用模糊后处理之前定义用于缩小阴影贴图的比例。默认情况下,值为 2
  • shadowGenerator.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

 


网站公告

今日签到

点亮在社区的每一天
去签到