Объявление
public static void CalculateInterpolatedLightAndOcclusionProbes(Vector3[] positions, SphericalHarmonicsL2[] lightProbes, Vector4[] occlusionProbes);public static void CalculateInterpolatedLightAndOcclusionProbes(List
Параметры
positions | Массив позиций в мировом пространстве, используемый для оценки зондов.. |
lightProbes | Массив, в который записываются результирующие световые зонды. |
occlusionProbes | Массив, в который записываются результирующие зонды окклюзии.. |
Описание
Рассчитать датчики света и датчики окклюзии в заданных положениях в мировом пространстве.
Если в сцене нет запеченных зондов, фоновый зонд будет записан в массив lightProbes
и Vector4
( 1,1,1,1) будут записаны в массив occlusionProbes
.
ArgumentNullException возникает, если positions
равно null
.
Вы можете опустить массив lightProbes
или occlusionProbes
, передав в функцию null
, но вы не можете опустить оба одновременно. Если оба массива опущены, создается исключение ArgumentException. lightProbes
и occlusionProbes
должны рассчитываться вместе для повышения производительности.
Для перегрузки, которая принимает массивы в качестве аргументов, lightProbes
и occlusionProbes
должны иметь не менее того же количества элементов, что и positions
.
Для перегрузки, которая принимает списки в качестве аргументов, размер выходных списков будет изменен, чтобы соответствовать размеру массива positions
, если в заданных списках недостаточно места.
Возвращенные зонды можно в дальнейшем использовать для инстансного рендеринга, скопировав их в объект MaterialPropertyBlock через MaterialPropertyBlock.CopySHCoefficientArraysFrom и MaterialPropertyBlock.CopyProbeOcclusionArrayFrom.
using UnityEngine;
// Этот скрипт использует OnPreCull для рендеринга. Обязательно поместите скрипт в объект Camera.
// Убедитесь, что световые зонды размещены и запечены в Scene.
// Используйте режим Shadowmask и смешанное освещение, чтобы увидеть датчики окклюзии, приближающиеся к тени.
[RequireComponent(typeof(Camera))]
public class Simple : MonoBehaviour
{
public Material material;
private Matrix4x4[] transforms;
private MaterialPropertyBlock properties;
private Mesh cubeMesh;
void Start()
{
const int kCount = 100;
// Generate 100 random positions
var positions = new Vector3[kCount];
for (int i = 0; i < kCount; ++i)
positions[i] = new Vector3(Random.Range(-20.0f, 20.0f), Random.Range(-20.0f, 20.0f), Random.Range(-20.0f, 20.0f));
// Calculate probes at these positions
var lightprobes = new UnityEngine.Rendering.SphericalHarmonicsL2[kCount];
var occlusionprobes = new Vector4[kCount];
LightProbes.CalculateInterpolatedLightAndOcclusionProbes(positions, lightprobes, occlusionprobes);
// Put them into the MPB
properties = new MaterialPropertyBlock();
properties.CopySHCoefficientArraysFrom(lightprobes);
properties.CopyProbeOcclusionArrayFrom(occlusionprobes);
// Compute the transforms list
transforms = new Matrix4x4[kCount];
for (int i = 0; i < kCount; ++i)
transforms[i] = Matrix4x4.Translate(positions[i]);
// Create the cube mesh
cubeMesh = GameObject.CreatePrimitive(PrimitiveType.Cube).GetComponent<MeshFilter>().sharedMesh;
// Make sure the material property is assigned
if (material == null || !material.enableInstancing)
Debug.LogError("material must be assigned with one with instancing enabled.");
}
// OnPreCull happens before every culling, which is the perfect timing to inject DrawMesh* function calls.
void OnPreCull()
{
if (material != null && material.enableInstancing)
{
var lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.CustomProvided; // enable instancing for probes
Graphics.DrawMeshInstanced(cubeMesh, 0, material, transforms, transforms.Length, properties, UnityEngine.Rendering.ShadowCastingMode.On, true, 0, null, lightProbeUsage);
}
}
}
В этом примере показано, как использовать датчики запеченного света для улучшения визуального качества инстансного рендеринга.