134 lines
5.1 KiB
C#
134 lines
5.1 KiB
C#
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|