Singularity/Library/PackageCache/com.unity.render-pipelines..../Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs

134 lines
5.1 KiB
C#
Raw Normal View History

2024-05-06 14:45:45 -04:00
using System;
using UnityEngine.Profiling;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEditor;
namespace UnityEngine.Experimental.Rendering
{
partial class ProbeGIBaking
{
static List<MeshRenderer> addedOccluders;
private static void AddOccluders()
{
addedOccluders = new List<MeshRenderer>();
for (int sceneIndex = 0; sceneIndex < UnityEngine.SceneManagement.SceneManager.sceneCount; ++sceneIndex)
{
UnityEngine.SceneManagement.Scene scene = UnityEngine.SceneManagement.SceneManager.GetSceneAt(sceneIndex);
if (!scene.isLoaded)
continue;
GameObject[] gameObjects = scene.GetRootGameObjects();
foreach (GameObject gameObject in gameObjects)
{
MeshRenderer[] renderComponents = gameObject.GetComponentsInChildren<MeshRenderer>();
foreach (MeshRenderer mr in renderComponents)
{
if (!mr.gameObject.GetComponent<MeshCollider>() && (GameObjectUtility.GetStaticEditorFlags(mr.gameObject).HasFlag(StaticEditorFlags.ContributeGI)))
{
var meshCollider = mr.gameObject.AddComponent<MeshCollider>();
meshCollider.hideFlags |= (HideFlags.DontSaveInEditor | HideFlags.DontSaveInBuild);
addedOccluders.Add(mr);
}
}
}
}
var autoSimState = Physics.autoSimulation;
Physics.autoSimulation = false;
Physics.Simulate(0.1f);
Physics.autoSimulation = autoSimState;
}
private static void CleanupOccluders()
{
foreach (MeshRenderer meshRenderer in addedOccluders)
{
MeshCollider collider = meshRenderer.gameObject.GetComponent<MeshCollider>();
UnityEngine.Object.DestroyImmediate(collider);
}
}
private static bool HasMeshColliderHits(RaycastHit[] outBoundHits, RaycastHit[] inBoundHits, Vector3 outRay, Vector3 inRay, float rayEnd, out float distance)
{
distance = float.MaxValue;
bool hasHit = false;
foreach (var hit in outBoundHits)
{
if (hit.collider is MeshCollider && Vector3.Dot(outRay, hit.normal) > 0)
{
if (hit.distance < distance)
{
distance = hit.distance;
hasHit = true;
}
}
}
foreach (var hit in inBoundHits)
{
if (hit.collider is MeshCollider && Vector3.Dot(inRay, hit.normal) > 0)
{
if ((rayEnd - hit.distance) < distance)
{
distance = hit.distance;
hasHit = true;
}
}
}
return hasHit;
}
private static Vector3 PushPositionOutOfGeometry(Vector3 worldPosition, float distanceSearch, float biasOutGeo)
{
bool queriesHitBackBefore = Physics.queriesHitBackfaces;
Physics.queriesHitBackfaces = true;
float minDist = float.MaxValue;
bool hitFound = false;
Vector3 outDirection = Vector3.zero;
for (int x = -1; x <= 1; ++x)
{
for (int y = -1; y <= 1; ++y)
{
for (int z = -1; z <= 1; ++z)
{
Vector3 searchDir = new Vector3(x, y, z);
Vector3 normDir = searchDir.normalized;
Vector3 ray = normDir * distanceSearch;
var collisionLayerMask = ~0;
RaycastHit[] outBoundHits = Physics.RaycastAll(worldPosition, normDir, distanceSearch, collisionLayerMask);
RaycastHit[] inBoundHits = Physics.RaycastAll(worldPosition + ray, -1.0f * normDir, distanceSearch, collisionLayerMask);
float distanceForDir = 0;
bool hasMeshColliderHits = HasMeshColliderHits(outBoundHits, inBoundHits, normDir, -normDir, distanceSearch, out distanceForDir);
if (hasMeshColliderHits)
{
hitFound = true;
if (distanceForDir < minDist)
{
outDirection = searchDir;
minDist = distanceForDir;
}
}
}
}
}
if (hitFound)
{
worldPosition = worldPosition + outDirection.normalized * (minDist * 1.05f + biasOutGeo);
}
Physics.queriesHitBackfaces = queriesHitBackBefore;
return worldPosition;
}
}
}