From ee5b330904a05c47458d570db1c9c4c623aa23be Mon Sep 17 00:00:00 2001 From: Thomas Woischnig Date: Thu, 6 Feb 2025 20:09:35 +0100 Subject: [PATCH] folder structure --- BillboardDrawCall.cs | 128 ---- BillboardDrawCall.cs.meta | 11 - CameraRenderSettings.cs | 161 ----- CameraRenderSettings.cs.meta | 11 - CameraRenderer.cs | 676 ------------------ CameraRenderer.cs.meta | 11 - CellLayout.cs | 179 ----- CellLayout.cs.meta | 11 - CellLayoutPool.cs | 85 --- CellLayoutPool.cs.meta | 11 - DrawCall.cs | 97 --- DrawCall.cs.meta | 11 - DrawGroup.cs | 65 -- DrawGroup.cs.meta | 11 - FrameRenderer.cs | 90 --- FrameRenderer.cs.meta | 11 - GrassRenderer.cs | 196 ----- GrassRenderer.cs.meta | 11 - GrassStreamer.cs | 301 -------- GrassStreamer.cs.meta | 11 - InstanceBuffer.cs | 26 - InstanceBuffer.cs.meta | 11 - InstanceMatrix.cs | 174 ----- InstanceMatrix.cs.meta | 11 - InstanceRenderSettings.cs | 60 -- InstanceRenderSettings.cs.meta | 11 - InstanceStreamer.cs | 89 --- InstanceStreamer.cs.meta | 11 - ObjectData.cs | 266 ------- ObjectData.cs.meta | 11 - RendererPool.cs | 541 -------------- RendererPool.cs.meta | 11 - RendererUtility.cs | 55 -- RendererUtility.cs.meta | 11 - Resources.meta | 8 - ...ThoMagic Instanced Position.shadersubgraph | 438 ------------ ...gic Instanced Position.shadersubgraph.meta | 10 - .../ThoMagic Renderer Instancing.compute | 418 ----------- .../ThoMagic Renderer Instancing.compute.meta | 7 - Resources/ThoMagicRenderer.cginc | 136 ---- Resources/ThoMagicRenderer.cginc.meta | 7 - Resources/ThoMagicRenderer.hlsl | 9 - Resources/ThoMagicRenderer.hlsl.meta | 7 - SceneRenderSettings.cs | 11 - SceneRenderSettings.cs.meta | 11 - TerrainDetailRenderer.cs | 299 -------- TerrainDetailRenderer.cs.meta | 11 - ThoMagicRendererObjectSettings.cs | 145 ---- ThoMagicRendererObjectSettings.cs.meta | 11 - TileObjectRenderer.cs | 133 ---- TileObjectRenderer.cs.meta | 11 - TileObjectStreamer.cs | 246 ------- TileObjectStreamer.cs.meta | 11 - TreeRenderer.cs | 272 ------- TreeRenderer.cs.meta | 11 - TreeStreamer.cs | 36 - TreeStreamer.cs.meta | 11 - 57 files changed, 5635 deletions(-) delete mode 100644 BillboardDrawCall.cs delete mode 100644 BillboardDrawCall.cs.meta delete mode 100644 CameraRenderSettings.cs delete mode 100644 CameraRenderSettings.cs.meta delete mode 100644 CameraRenderer.cs delete mode 100644 CameraRenderer.cs.meta delete mode 100644 CellLayout.cs delete mode 100644 CellLayout.cs.meta delete mode 100644 CellLayoutPool.cs delete mode 100644 CellLayoutPool.cs.meta delete mode 100644 DrawCall.cs delete mode 100644 DrawCall.cs.meta delete mode 100644 DrawGroup.cs delete mode 100644 DrawGroup.cs.meta delete mode 100644 FrameRenderer.cs delete mode 100644 FrameRenderer.cs.meta delete mode 100644 GrassRenderer.cs delete mode 100644 GrassRenderer.cs.meta delete mode 100644 GrassStreamer.cs delete mode 100644 GrassStreamer.cs.meta delete mode 100644 InstanceBuffer.cs delete mode 100644 InstanceBuffer.cs.meta delete mode 100644 InstanceMatrix.cs delete mode 100644 InstanceMatrix.cs.meta delete mode 100644 InstanceRenderSettings.cs delete mode 100644 InstanceRenderSettings.cs.meta delete mode 100644 InstanceStreamer.cs delete mode 100644 InstanceStreamer.cs.meta delete mode 100644 ObjectData.cs delete mode 100644 ObjectData.cs.meta delete mode 100644 RendererPool.cs delete mode 100644 RendererPool.cs.meta delete mode 100644 RendererUtility.cs delete mode 100644 RendererUtility.cs.meta delete mode 100644 Resources.meta delete mode 100644 Resources/ThoMagic Instanced Position.shadersubgraph delete mode 100644 Resources/ThoMagic Instanced Position.shadersubgraph.meta delete mode 100644 Resources/ThoMagic Renderer Instancing.compute delete mode 100644 Resources/ThoMagic Renderer Instancing.compute.meta delete mode 100644 Resources/ThoMagicRenderer.cginc delete mode 100644 Resources/ThoMagicRenderer.cginc.meta delete mode 100644 Resources/ThoMagicRenderer.hlsl delete mode 100644 Resources/ThoMagicRenderer.hlsl.meta delete mode 100644 SceneRenderSettings.cs delete mode 100644 SceneRenderSettings.cs.meta delete mode 100644 TerrainDetailRenderer.cs delete mode 100644 TerrainDetailRenderer.cs.meta delete mode 100644 ThoMagicRendererObjectSettings.cs delete mode 100644 ThoMagicRendererObjectSettings.cs.meta delete mode 100644 TileObjectRenderer.cs delete mode 100644 TileObjectRenderer.cs.meta delete mode 100644 TileObjectStreamer.cs delete mode 100644 TileObjectStreamer.cs.meta delete mode 100644 TreeRenderer.cs delete mode 100644 TreeRenderer.cs.meta delete mode 100644 TreeStreamer.cs delete mode 100644 TreeStreamer.cs.meta diff --git a/BillboardDrawCall.cs b/BillboardDrawCall.cs deleted file mode 100644 index 53ea2cb..0000000 --- a/BillboardDrawCall.cs +++ /dev/null @@ -1,128 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public class BillboardDrawCall : DrawCall - { - private static Mesh _billboardMesh; - - private static Mesh GetBillboardMesh() - { - if (_billboardMesh == null) - { - _billboardMesh = new Mesh(); - _billboardMesh.name = "Billboard Mesh"; - _billboardMesh.vertices = new Vector3[6]; - _billboardMesh.triangles = new int[6] { - 0, - 1, - 2, - 3, - 4, - 5 - }; - - _billboardMesh.SetUVs(0,new Vector2[6] - { - new Vector2(0.0f, 0.0f), - new Vector2(0.0f, 1f), - new Vector2(1f, 1f), - new Vector2(0.0f, 0.0f), - new Vector2(1f, 1f), - new Vector2(1f, 0.0f) - }); - - _billboardMesh.SetUVs(1, new Vector4[6] - { - new Vector4(1f, 1f, 0.0f, 0.0f), - new Vector4(1f, 1f, 0.0f, 0.0f), - new Vector4(1f, 1f, 0.0f, 0.0f), - new Vector4(1f, 1f, 0.0f, 0.0f), - new Vector4(1f, 1f, 0.0f, 0.0f), - new Vector4(1f, 1f, 0.0f, 0.0f) - }); - - _billboardMesh.UploadMeshData(true); - } - - return _billboardMesh; - } - - public BillboardDrawCall( - int lodNr, - BillboardAsset billboardAsset, - Material material, - Matrix4x4 localToWorldMatrix, - uint baseIndirectArgsIndex, - List indirectDrawIndexedArgs, - in RenderParams renderParams) - : base(lodNr, - GetBillboardMesh(), - new Material[1]{ material }, - localToWorldMatrix, - baseIndirectArgsIndex, - indirectDrawIndexedArgs, - in renderParams) - { - if (billboardAsset == null) - throw new ArgumentNullException(nameof(billboardAsset)); - - SetBillboardPerBatch(billboardAsset); - } - - internal override void Dispose() { - UnityEngine.Object.Destroy(_billboardMesh); - base.Dispose(); - } - - public override void Draw(Camera camera, ObjectData obj, GraphicsBuffer indirectDrawIndexedArgs) - { - SetBillboardPerCamera(camera); - base.Draw(camera, obj, indirectDrawIndexedArgs); - } - - private void SetBillboardPerCamera(Camera camera) - { - Vector3 position = camera.transform.position; - Vector3 vector3_1 = camera.transform.forward * -1f; - vector3_1.y = 0.0f; - vector3_1.Normalize(); - Vector3 vector3_2 = camera.transform.right * -1f; - vector3_2.y = 0.0f; - vector3_2.Normalize(); - float num1 = Mathf.Atan2(vector3_1.z, vector3_1.x); - float num2 = num1 + (num1 < 0.0f ? 6.283185f : 0.0f); - Vector4 vector4; - vector4.x = position.x; - vector4.y = position.y; - vector4.z = position.z; - vector4.w = num2; - for (int index = 0; index < RenderParams.Length; ++index) - { - RenderParams[index].matProps.SetVector("unity_BillboardNormal", vector3_1); - RenderParams[index].matProps.SetVector("unity_BillboardTangent", vector3_2); - RenderParams[index].matProps.SetVector("unity_BillboardCameraParams", vector4); - } - } - - private void SetBillboardPerBatch(BillboardAsset asset) - { - Vector4 vector4_1 = Vector4.zero; - vector4_1.x = asset.imageCount; - vector4_1.y = 1.0f / (6.28318548202515f / asset.imageCount); - Vector4 vector4_2 = Vector4.zero; - vector4_2.x = asset.width; - vector4_2.y = asset.height; - vector4_2.z = asset.bottom; - Vector4[] imageTexCoords = asset.GetImageTexCoords(); - for (int index = 0; index < RenderParams.Length; ++index) - { - RenderParams[index].matProps.SetVector("unity_BillboardInfo", vector4_1); - RenderParams[index].matProps.SetVector("unity_BillboardSize", vector4_2); - RenderParams[index].matProps.SetVectorArray("unity_BillboardImageTexCoords", imageTexCoords); - } - } - } -} diff --git a/BillboardDrawCall.cs.meta b/BillboardDrawCall.cs.meta deleted file mode 100644 index 88e477a..0000000 --- a/BillboardDrawCall.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 462b041640bdab24f87e7de6f8a16fb3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/CameraRenderSettings.cs b/CameraRenderSettings.cs deleted file mode 100644 index 7c401a7..0000000 --- a/CameraRenderSettings.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - [DisallowMultipleComponent] - [ExecuteAlways] - public class ThoMagicRendererCameraSettings : MonoBehaviour, IInstanceRenderSettings - { - [SerializeField] - private bool _supported; - [SerializeField] - private bool _overrideSupported; - [SerializeField] - private bool _render; - [SerializeField] - private bool _overrideRendering; - [Min(0.0f)] - [SerializeField] - private float _renderDistance; - [SerializeField] - private bool _overrideRenderDistance; - [SerializeField] - private bool _renderShadows; - [SerializeField] - private bool _overrideRenderShadows; - [Min(0.0f)] - [SerializeField] - private float _shadowDistance; - [SerializeField] - private bool _overrideShadowDistance; - [Range(0.01f, 1f)] - [SerializeField] - private float _densityInDistance; - [SerializeField] - private bool _overrideDensityInDistance; - [SerializeField] - private Vector2 _densityInDistanceFalloff; - [SerializeField] - private bool _overrideDensityInDistanceFalloff; - private ReflectionProbe _reflectionProbe; - - public InstanceRenderSettings Settings => new InstanceRenderSettings() - { - Supported = !_overrideSupported || _supported, - Render = !_overrideRendering || _render, - RenderDistance = _overrideRenderDistance ? _renderDistance : -1f, - ShadowDistance = _overrideShadowDistance ? _shadowDistance : -1f, - Shadows = !_overrideRenderShadows || _renderShadows, - DensityInDistance = _overrideDensityInDistance ? _densityInDistance : 1f, - DensityInDistanceFalloff = _overrideDensityInDistanceFalloff ? _densityInDistanceFalloff : Vector2.zero - }; - - public bool? Supported - { - get => !_overrideSupported ? new bool?() : new bool?(_supported); - set - { - _overrideSupported = value.HasValue; - if (!value.HasValue) - return; - _supported = value.Value; - } - } - - public bool? Render - { - get => !_overrideRendering ? new bool?() : new bool?(_render); - set - { - _overrideRendering = value.HasValue; - if (!value.HasValue) - return; - _render = value.Value; - } - } - - public float? RenderDistance - { - get => !_overrideRenderDistance ? new float?() : new float?(_renderDistance); - set - { - _overrideRenderDistance = value.HasValue; - if (!value.HasValue) - return; - _renderDistance = value.Value; - } - } - - public bool? RenderShadows - { - get => !_overrideRenderShadows ? new bool?() : new bool?(_renderShadows); - set - { - _overrideRenderShadows = value.HasValue; - if (!value.HasValue) - return; - _renderShadows = value.Value; - } - } - - public float? ShadowDistance - { - get => !_overrideShadowDistance ? new float?() : new float?(_shadowDistance); - set - { - _overrideShadowDistance = value.HasValue; - if (!value.HasValue) - return; - _shadowDistance = value.Value; - } - } - - public float? DensityInDistance - { - get => !_overrideDensityInDistance ? new float?() : new float?(_densityInDistance); - set - { - _overrideDensityInDistance = value.HasValue; - if (!value.HasValue) - return; - _densityInDistance = value.Value; - } - } - - public Vector2? DensityInDistanceFalloff - { - get => !_overrideDensityInDistanceFalloff ? new Vector2?() : new Vector2?(_densityInDistanceFalloff); - set - { - _overrideDensityInDistanceFalloff = value.HasValue; - if (!value.HasValue) - return; - _densityInDistanceFalloff = value.Value; - } - } - - private void OnEnable() - { - _reflectionProbe = GetComponent(); - if (_reflectionProbe == null) - return; - CameraRenderer.ReflectionProbeSettings = this; - } - - private void OnDisable() - { - if (_reflectionProbe == null || CameraRenderer.ReflectionProbeSettings as ThoMagicRendererCameraSettings == this) - return; - - CameraRenderer.ReflectionProbeSettings = null; - } - - private void OnValidate() - { - if (_reflectionProbe == null || !Application.isEditor) - return; - _reflectionProbe.RenderProbe(); - } - } -} diff --git a/CameraRenderSettings.cs.meta b/CameraRenderSettings.cs.meta deleted file mode 100644 index 940980c..0000000 --- a/CameraRenderSettings.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 937c543b6caf2384898a535da09c337d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/CameraRenderer.cs b/CameraRenderer.cs deleted file mode 100644 index 05c6bc6..0000000 --- a/CameraRenderer.cs +++ /dev/null @@ -1,676 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Threading; -using UnityEngine; -using UnityEngine.Rendering; -using UnityEngine.XR; - -namespace Assets.ThoMagic.Renderer -{ - public class CameraRenderer : IDisposable - { - internal static int nextCameraRendererId = 0; - int cameraRendererId; - public static IInstanceRenderSettings ReflectionProbeSettings; - public readonly Camera Camera; - public IInstanceRenderSettings cameraSettings; - - private readonly bool _singlePassInstanced = false; - - private int cachedBufferHash; - - private Vector3 _origin; - private Light _mainLight; - - List visibleStreams = new List(); - - List prefabData = new List(); - List indirectDrawIndexedArgs = new List(); - Dictionary objRenderDistanceCache = new Dictionary(); - Dictionary appliedSettings = new Dictionary(); - List cullableIndexes = new List(); - - public Camera ReferenceCamera { get; private set; } - - private CommandBuffer commandBuffer; - private ComputeShader instancingShader; - private ComputeBuffer prefabBuffer; - - private GraphicsBuffer indirectDrawIndexedArgsBuffer; - private ComputeBuffer metaBuffer; - private ComputeBuffer cullableIndexesBuffer; - private ComputeBuffer visibleIndexesBuffer; - private ComputeBuffer visibleShadowIndexesBuffer; - - private float cachedFov; - private float cachedBias; - private bool lodInvalid; - - SceneRenderSettings sceneSettings = new SceneRenderSettings(); - private Plane[] _cachedFrustumPlanes; - private Vector4[] _cachedShaderFrustumPlanes; - internal bool instanceCountChanged = true; - internal bool rebuildPrefabs = true; - - private int cullShaderId = 0, clearShaderId = 0; - - private uint maxInstancesCount = 0; - private uint indexBufferOffset = 0; - - private int lastCamSettingsHash = 0; - - public CameraRenderer(Camera camera) - { - commandBuffer = new CommandBuffer(); - cameraRendererId = Interlocked.Increment(ref nextCameraRendererId); - - instancingShader = UnityEngine.Object.Instantiate(Resources.Load("ThoMagic Renderer Instancing")); - instancingShader.hideFlags = HideFlags.HideAndDontSave; - cullShaderId = instancingShader.FindKernel("Cull_64"); - clearShaderId = instancingShader.FindKernel("Clear_64"); - - instancingShader.name = $"ThoMagic Renderer Instancing - {camera.name}"; - Camera = camera != null ? camera : throw new ArgumentNullException(nameof(camera)); - cameraSettings = camera.GetComponent(); - ReferenceCamera = camera; - if (camera.cameraType == CameraType.Game || camera.cameraType == CameraType.VR) - { - _singlePassInstanced = XRSettings.enabled && (XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePassInstanced || XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePassMultiview); - if (Application.isEditor && XRSettings.enabled && !_singlePassInstanced && XRSettings.loadedDeviceName == "MockHMD Display" && this.LoadMockHmdSetting() == "SinglePassInstanced") - _singlePassInstanced = true; - } - } - - public void SetFloatingOrigin(in Vector3 origin) - { - _origin = origin; - } - - public void SetReferenceCamera(Camera camera) - { - ReferenceCamera = camera != null ? camera : Camera; - cameraSettings = ReferenceCamera.GetComponent(); - } - - public void SetMainLight(Light light) => _mainLight = light; - - private void CalculateFrustumPlanes() - { - if (_cachedFrustumPlanes == null) - _cachedFrustumPlanes = new Plane[6]; - GeometryUtility.CalculateFrustumPlanes(ReferenceCamera, _cachedFrustumPlanes); - - if (_cachedShaderFrustumPlanes == null) - _cachedShaderFrustumPlanes = new Vector4[6]; - - for (int index = 0; index < 6; ++index) - _cachedShaderFrustumPlanes[index] = new Vector4(_cachedFrustumPlanes[index].normal.x, _cachedFrustumPlanes[index].normal.y, _cachedFrustumPlanes[index].normal.z, _cachedFrustumPlanes[index].distance); - } - - public void Render() - { - //Used in editor if selected camera is not editor scene camera. Then only the culled instances of the selected camera is rendered. - if (ReferenceCamera == null) - SetReferenceCamera(Camera); - - if (_mainLight == null) - _mainLight = FindMainLight(); - - if (_mainLight != null) - { - sceneSettings.HasMainLight = true; - sceneSettings.HasMainLightShadows = _mainLight.shadows > 0; - sceneSettings.MainLightDirection = _mainLight.transform.forward; - } - else - { - sceneSettings.HasMainLight = false; - sceneSettings.HasMainLightShadows = false; - } - - var finalSettings = InstanceRenderSettings.Default(ReferenceCamera); - - if (ReferenceCamera.cameraType == CameraType.Reflection && ReflectionProbeSettings != null) - finalSettings.Merge(ReflectionProbeSettings.Settings); - - if (cameraSettings == null && Application.isEditor && !Application.isPlaying) - cameraSettings = ReferenceCamera.GetComponent(); - - if (cameraSettings != null) - finalSettings.Merge(cameraSettings.Settings); - - if(finalSettings.GetHashCode() != lastCamSettingsHash) - { - lastCamSettingsHash = finalSettings.GetHashCode(); - rebuildPrefabs = true; - } - - if (!rebuildPrefabs && Application.isEditor && !Application.isPlaying) - { - foreach (var renderObject in RendererPool.objectsList) - { - - var settingsEditor = finalSettings; - var renderObjectSettingsNew = renderObject.GameObject.GetComponent(); - - if (renderObjectSettingsNew != null) - settingsEditor.Merge(renderObjectSettingsNew.Settings); - - if(!appliedSettings.ContainsKey(renderObject.prefabId) || settingsEditor.GetHashCode() != appliedSettings[renderObject.prefabId].GetHashCode()) - { - renderObject.Settings = renderObjectSettingsNew; - rebuildPrefabs = true; - } - } - } - - CalculateFrustumPlanes(); - //Find visible streams for this frame - visibleStreams.Clear(); - - foreach (var streamer in RendererPool.streamers.Values) - if (streamer.IsInRange(ReferenceCamera, _cachedFrustumPlanes)) - { - streamer.UpdateForCamera(ReferenceCamera, _cachedFrustumPlanes); - visibleStreams.Add(streamer); - } - - bool prefabDataChanged = false; - bool noNeedToUpdateIndirectIndexOffsets = false; - //A prefab (object) has been added, removed or changed - if (rebuildPrefabs) - { - noNeedToUpdateIndirectIndexOffsets = true; - rebuildPrefabs = false; - - lodInvalid = false; - cachedFov = ReferenceCamera.fieldOfView; - cachedBias = QualitySettings.lodBias; - - appliedSettings.Clear(); - indirectDrawIndexedArgs.Clear(); - - prefabData.Clear(); - prefabData.AddRange(RendererPool.prefabData); - - maxInstancesCount = 0; - indexBufferOffset = 0; - - uint batchIndex = 0; - uint prefabCount = 0; - uint indexArgsSize = 0; - int totalIndirectArgsIndex = 0; - - foreach (var renderObject in RendererPool.objectsList) - { - var localPrefabData = prefabData[(int)renderObject.prefabId]; - - var finalObjSettings = finalSettings; - - if (renderObject.Settings != null) - { - finalObjSettings.Merge(renderObject.Settings.Settings); - ValidateSettings(ref finalObjSettings); - } - - CalculateCullingDistances(renderObject, finalObjSettings, cachedFov, cachedBias, renderObject.LodTransitions, renderObject.LodSizes, renderObject.lods); - - float distance1 = RelativeHeightToDistance(finalObjSettings.DensityInDistanceFalloff.x, renderObject.LodSizes[0], cachedFov); - float distance2 = RelativeHeightToDistance(finalObjSettings.DensityInDistanceFalloff.y, renderObject.LodSizes[0], cachedFov); - - var densityInDistance = new Vector4(finalObjSettings.DensityInDistance, - distance1, - distance2 - distance1, - finalObjSettings.ShadowDistance); - - localPrefabData.lodCount = renderObject.lodCount; - localPrefabData.fadeLods = renderObject.fadeLods; - localPrefabData.batchIndex = batchIndex; - localPrefabData.indexBufferStartOffset = indexBufferOffset; - localPrefabData.maxCount = renderObject.count; - localPrefabData.densityInDistance = densityInDistance; - - renderObject.indirectArgsPerSubmeshOffsets.Clear(); - - indirectDrawIndexedArgs.AddRange(renderObject.indirectDrawIndexedArgs); - - for (int i = 0; i < renderObject.lodCount; i++) - { - renderObject.indirectArgsPerLodOffsets[i] = indexArgsSize; - - //All indirect arguments for this lod including shadows - for (int z = 0; z < renderObject.indirectArgsPerLodWithShadowsCounts[i]; z++) - { - //Set batchoffset - var idia = indirectDrawIndexedArgs[totalIndirectArgsIndex]; - idia.startInstance = indexBufferOffset + (uint)(i * renderObject.count); - indirectDrawIndexedArgs[totalIndirectArgsIndex] = idia; - //** - - renderObject.indirectArgsPerSubmeshOffsets.Add(totalIndirectArgsIndex); - totalIndirectArgsIndex++; - indexArgsSize += 5; - } - } - - localPrefabData.SetLods(renderObject.lods, renderObject.indirectArgsPerLodOffsets, renderObject.indirectArgsPerLodCounts); - prefabData[(int)renderObject.prefabId] = localPrefabData; - appliedSettings[renderObject.prefabId] = finalObjSettings; - - batchIndex += renderObject.lodCount; - indexBufferOffset += renderObject.count * renderObject.lodCount; - maxInstancesCount += renderObject.count; - prefabCount++; - } - - //Nothing to draw yet - if (maxInstancesCount == 0) - { - rebuildPrefabs = true; - return; - } - - if (metaBuffer == null || metaBuffer.count < maxInstancesCount) - { - metaBuffer?.Dispose(); - int nextCount = RendererPool.RESIZE_COUNT * (((int)maxInstancesCount - 1) / RendererPool.RESIZE_COUNT + 1); - metaBuffer = new ComputeBuffer(nextCount, sizeof(uint) * 4, ComputeBufferType.Structured); - metaBuffer.name = $"ThoMagic metaBuffer ({Camera.name})"; - - cullableIndexesBuffer?.Dispose(); - cullableIndexesBuffer = new ComputeBuffer(nextCount, sizeof(uint), ComputeBufferType.Structured); - cullableIndexesBuffer.name = $"ThoMagic cullingIndexesBuffer ({Camera.name})"; - } - - if (indirectDrawIndexedArgsBuffer == null || indirectDrawIndexedArgsBuffer.count < indirectDrawIndexedArgs.Count) - { - indirectDrawIndexedArgsBuffer?.Dispose(); - int nextCount = RendererPool.RESIZE_COUNT * (((int)indirectDrawIndexedArgs.Count - 1) / RendererPool.RESIZE_COUNT + 1); - indirectDrawIndexedArgsBuffer = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, nextCount, GraphicsBuffer.IndirectDrawIndexedArgs.size); - indirectDrawIndexedArgsBuffer.name = $"ThoMagic indirectDrawIndexedArgsBuffer ({Camera.name})"; - } - - indirectDrawIndexedArgsBuffer.SetData(indirectDrawIndexedArgs); - - if (prefabBuffer == null || prefabBuffer.count < prefabCount) - { - prefabBuffer?.Dispose(); - int nextCount = RendererPool.RESIZE_COUNT * (((int)prefabCount - 1) / RendererPool.RESIZE_COUNT + 1); - prefabBuffer = new ComputeBuffer(nextCount, PrefabData.Stride, ComputeBufferType.Structured); - prefabBuffer.name = $"ThoMagic prefabBuffer ({Camera.name})"; - } - - if (visibleIndexesBuffer == null || visibleIndexesBuffer.count < indexBufferOffset) - { - visibleIndexesBuffer?.Dispose(); - int nextCount = RendererPool.RESIZE_COUNT * (((int)indexBufferOffset - 1) / RendererPool.RESIZE_COUNT + 1); - visibleIndexesBuffer = new ComputeBuffer(nextCount, sizeof(uint), ComputeBufferType.Structured); - visibleIndexesBuffer.name = $"ThoMagic visibleIndexesBuffer ({Camera.name})"; - - visibleShadowIndexesBuffer?.Dispose(); - visibleShadowIndexesBuffer = new ComputeBuffer(nextCount, sizeof(uint), ComputeBufferType.Structured); - visibleShadowIndexesBuffer.name = $"ThoMagic visibleShadowIndexesBuffer ({Camera.name})"; - }; - - prefabDataChanged = true; - instanceCountChanged = true; - } - - //Nothing to draw yet - if (maxInstancesCount == 0) - return; - - //Either instances have been added/removed or the visible streams have changed. - //We need to rebuild the visible instances index buffer - if (instanceCountChanged || BuffersChanged(visibleStreams, ref cachedBufferHash)) - { - if (instanceCountChanged) - { - if (!noNeedToUpdateIndirectIndexOffsets)//If already rebuild by prefab update, this is not needed - { - maxInstancesCount = 0; - indexBufferOffset = 0; - uint indexArgsSize = 0; - int totalIndirectArgsIndex = 0; - - foreach (var renderObject in RendererPool.objectsList) - { - for (int i = 0; i < renderObject.lodCount; i++) - { - //All indirect arguments for this lod including shadows - for (int z = 0; z < renderObject.indirectArgsPerLodWithShadowsCounts[i]; z++) - { - //Set batchoffset - var idia = indirectDrawIndexedArgs[totalIndirectArgsIndex]; - idia.startInstance = indexBufferOffset + (uint)(i * renderObject.count); - indirectDrawIndexedArgs[totalIndirectArgsIndex] = idia; - //** - - totalIndirectArgsIndex++; - indexArgsSize += 5; - } - } - - var pd = prefabData[(int)renderObject.prefabId]; - if (pd.maxCount != renderObject.count) - prefabDataChanged = true; - pd.indexBufferStartOffset = indexBufferOffset; - pd.maxCount = renderObject.count; - prefabData[(int)renderObject.prefabId] = pd; - - indexBufferOffset += renderObject.count * renderObject.lodCount; - maxInstancesCount += renderObject.count; - } - - if (metaBuffer == null || metaBuffer.count < maxInstancesCount) - { - metaBuffer?.Dispose(); - int nextCount = RendererPool.RESIZE_COUNT * (((int)maxInstancesCount - 1) / RendererPool.RESIZE_COUNT + 1); - metaBuffer = new ComputeBuffer(nextCount, sizeof(uint) * 4, ComputeBufferType.Structured); - metaBuffer.name = $"ThoMagic metaBuffer ({Camera.name})"; - - cullableIndexesBuffer?.Dispose(); - cullableIndexesBuffer = new ComputeBuffer(nextCount, sizeof(uint), ComputeBufferType.Structured); - cullableIndexesBuffer.name = $"ThoMagic cullingIndexesBuffer ({Camera.name})"; - } - - if (visibleIndexesBuffer == null || visibleIndexesBuffer.count < indexBufferOffset) - { - visibleIndexesBuffer?.Dispose(); - int nextCount = RendererPool.RESIZE_COUNT * (((int)indexBufferOffset - 1) / RendererPool.RESIZE_COUNT + 1); - visibleIndexesBuffer = new ComputeBuffer(nextCount, sizeof(uint), ComputeBufferType.Structured); - visibleIndexesBuffer.name = $"ThoMagic visibleIndexesBuffer ({Camera.name})"; - - visibleShadowIndexesBuffer?.Dispose(); - visibleShadowIndexesBuffer = new ComputeBuffer(nextCount, sizeof(uint), ComputeBufferType.Structured); - visibleShadowIndexesBuffer.name = $"ThoMagic visibleShadowIndexesBuffer ({Camera.name})"; - }; - - indirectDrawIndexedArgsBuffer.SetData(indirectDrawIndexedArgs); - } - } - - instanceCountChanged = false; - - cullableIndexes.Clear(); - - foreach (var stream in visibleStreams) - { - foreach (var objectInstanceIds in stream.objectInstanceIds.Values) - { - cullableIndexes.AddRange(objectInstanceIds); - } - } - - cullableIndexesBuffer.SetData(cullableIndexes); - } - - //Nothing to render - if (cullableIndexes.Count == 0 || RendererPool.globalInstanceBuffer == null) - return; - - //Lod settings changed, update prefab lod data - if (cachedFov != ReferenceCamera.fieldOfView || cachedBias != QualitySettings.lodBias || lodInvalid) - { - lodInvalid = false; - cachedFov = ReferenceCamera.fieldOfView; - cachedBias = QualitySettings.lodBias; - - foreach (var renderObject in RendererPool.objectsList) - { - CalculateCullingDistances(renderObject, appliedSettings[renderObject.prefabId], cachedFov, cachedBias, renderObject.LodTransitions, renderObject.LodSizes, renderObject.lods); - - float distance1 = RelativeHeightToDistance(appliedSettings[renderObject.prefabId].DensityInDistanceFalloff.x, renderObject.LodSizes[0], cachedFov); - float distance2 = RelativeHeightToDistance(appliedSettings[renderObject.prefabId].DensityInDistanceFalloff.y, renderObject.LodSizes[0], cachedFov); - - var densityInDistance = new Vector4(appliedSettings[renderObject.prefabId].DensityInDistance, - distance1, - distance2 - distance1, - appliedSettings[renderObject.prefabId].ShadowDistance); - - var pd = prefabData[(int)renderObject.prefabId]; - pd.SetLods(renderObject.lods, renderObject.indirectArgsPerLodOffsets, renderObject.indirectArgsPerLodCounts); - pd.densityInDistance = densityInDistance; - prefabData[(int)renderObject.prefabId] = pd; - } - - prefabDataChanged = true; - } - - if(prefabDataChanged) - prefabBuffer.SetData(prefabData); - - //Compute culling - - //Reset visible count of instances to zero - /*instancingShader.SetInt("_Count", indirectDrawIndexedArgs.Count); - instancingShader.SetBuffer(clearShaderId, "perCamIndirectArgumentsBuffer", indirectDrawIndexedArgsBuffer); - instancingShader.Dispatch(clearShaderId, Mathf.CeilToInt(indirectDrawIndexedArgs.Count / 64.0f), 1, 1); - - //Cull - instancingShader.SetBuffer(cullShaderId, "globalInstances", RendererPool.globalInstanceBuffer); - instancingShader.SetBuffer(cullShaderId, "perCamPrefabs", prefabBuffer); - instancingShader.SetBuffer(cullShaderId, "perCamMeta", metaBuffer); - instancingShader.SetBuffer(cullShaderId, "perCamIndirectArgumentsBuffer", indirectDrawIndexedArgsBuffer); - instancingShader.SetBuffer(cullShaderId, "perCamCullableIndexesBuffer", cullableIndexesBuffer); - instancingShader.SetBuffer(cullShaderId, "perCamVisibleIndexesBuffer", visibleIndexesBuffer); - instancingShader.SetBuffer(cullShaderId, "perCamShadowVisibleIndexesBuffer", visibleShadowIndexesBuffer); - - instancingShader.SetVector("_CameraPosition", ReferenceCamera.transform.position); - instancingShader.SetVectorArray("_FrustumPlanes", _cachedShaderFrustumPlanes); - instancingShader.SetVector("_ShadowDirection", sceneSettings.MainLightDirection); - instancingShader.SetInt("_Count", cullableIndexes.Count); - - instancingShader.Dispatch(cullShaderId, Mathf.CeilToInt(cullableIndexes.Count / 64.0f), 1, 1);*/ - - commandBuffer.Clear(); - - commandBuffer.SetComputeIntParam(instancingShader, "_CountClear", indirectDrawIndexedArgs.Count); - commandBuffer.SetComputeBufferParam(instancingShader, clearShaderId, "perCamIndirectArgumentsBuffer", indirectDrawIndexedArgsBuffer); - commandBuffer.DispatchCompute(instancingShader, clearShaderId, Mathf.CeilToInt(indirectDrawIndexedArgs.Count / 64.0f), 1, 1); - - commandBuffer.SetComputeBufferParam(instancingShader, cullShaderId, "globalInstances", RendererPool.globalInstanceBuffer); - commandBuffer.SetComputeBufferParam(instancingShader, cullShaderId, "perCamPrefabs", prefabBuffer); - commandBuffer.SetComputeBufferParam(instancingShader, cullShaderId, "perCamMeta", metaBuffer); - commandBuffer.SetComputeBufferParam(instancingShader, cullShaderId, "perCamIndirectArgumentsBuffer", indirectDrawIndexedArgsBuffer); - commandBuffer.SetComputeBufferParam(instancingShader, cullShaderId, "perCamCullableIndexesBuffer", cullableIndexesBuffer); - commandBuffer.SetComputeBufferParam(instancingShader, cullShaderId, "perCamVisibleIndexesBuffer", visibleIndexesBuffer); - commandBuffer.SetComputeBufferParam(instancingShader, cullShaderId, "perCamShadowVisibleIndexesBuffer", visibleShadowIndexesBuffer); - commandBuffer.SetComputeVectorParam(instancingShader, "_CameraPosition", ReferenceCamera.transform.position); - commandBuffer.SetComputeVectorArrayParam(instancingShader, "_FrustumPlanes", _cachedShaderFrustumPlanes); - commandBuffer.SetComputeVectorParam(instancingShader, "_ShadowDirection", sceneSettings.MainLightDirection); - commandBuffer.SetComputeIntParam(instancingShader, "_CountCull", cullableIndexes.Count); - commandBuffer.DispatchCompute(instancingShader, cullShaderId, Mathf.CeilToInt(cullableIndexes.Count / 64.0f), 1, 1); - - Graphics.ExecuteCommandBuffer(commandBuffer); - - var fence = Graphics.CreateGraphicsFence(GraphicsFenceType.AsyncQueueSynchronisation, SynchronisationStageFlags.ComputeProcessing); - Graphics.WaitOnAsyncGraphicsFence(fence); - - //Render all prefabs (objects) - foreach (var renderObject in RendererPool.objectsList) - if (renderObject.count > 0)//Ignore if no instance is registered - RenderObject(renderObject, appliedSettings[renderObject.prefabId]); - } - - private void CalculateCullingDistances( - ObjectData renderObject, - InstanceRenderSettings finalSettings, - float fieldOfView, - float bias, - float[] relativeTransitionHeight, - float[] detailSize, - Vector4[] lodData) - { - for (int index = 0; index < relativeTransitionHeight.Length; ++index) - lodData[index] = new Vector4(index > 0 ? lodData[index - 1].y : 0.0f, RelativeHeightToDistance(relativeTransitionHeight[index], detailSize[index], fieldOfView) * bias, detailSize[index], 0.0f); - - var renderDistance = Mathf.Min(finalSettings.RenderDistance, RelativeHeightToDistance(renderObject.LodTransitions[renderObject.LodTransitions.Length - 1], renderObject.LodSizes[renderObject.LodTransitions.Length - 1], this.ReferenceCamera.fieldOfView, QualitySettings.lodBias)); - objRenderDistanceCache[renderObject.GetHashCode()] = renderDistance; - - for (int index = 0; index < renderObject.LodSizes.Length; ++index) - { - renderObject.lods[index].x = Mathf.Min(renderObject.lods[index].x, renderDistance); - renderObject.lods[index].y = Mathf.Min(renderObject.lods[index].y, renderDistance); - } - } - - public static float RelativeHeightToDistance( - float relativeHeight, - float size, - float fieldOfView) - { - if (relativeHeight <= 0.0f || relativeHeight == float.MaxValue) - return float.MaxValue; - - float num = Mathf.Tan((float)(Math.PI / 180.0 * (double)fieldOfView * 0.5)); - return size * 0.5f / relativeHeight / num; - } - - private void RenderObject( - ObjectData obj, - InstanceRenderSettings renderSettings) - { - if (LayerIsCulled(ReferenceCamera, obj.GameObject.layer) || (/*(!Application.isEditor || Application.isPlaying) &&*/ SceneIsCulled(ReferenceCamera, obj.GameObject))) - return; - - if (!renderSettings.Render) - return; - - foreach(var drawGroup in obj.drawGroups) - { - if (drawGroup == null) continue; - drawGroup.SetInstances(RendererPool.globalInstanceBuffer, visibleIndexesBuffer, metaBuffer); - drawGroup.Draw(Camera, obj, indirectDrawIndexedArgsBuffer); - } - - if (!renderSettings.Shadows) - return; - - foreach (var drawGroup in obj.drawShadowGroups) - { - if (drawGroup == null) continue; - drawGroup.SetInstances(RendererPool.globalInstanceBuffer, visibleShadowIndexesBuffer, metaBuffer); - drawGroup.Draw(Camera, obj, indirectDrawIndexedArgsBuffer); - } - } - - private void ValidateSettings(ref InstanceRenderSettings settings) - { - if (settings.RenderDistance <= 0.0f) - settings.RenderDistance = this.ReferenceCamera.farClipPlane; - if (settings.ShadowDistance > 0.0f) - return; - settings.ShadowDistance = settings.RenderDistance; - } - - private bool LayerIsCulled(Camera camera, int layer) - { - if (camera.cullingMask != -1) - { - int num = layer; - if ((camera.cullingMask & 1 << num) == 0) - return true; - } - return false; - } - - private bool SceneIsCulled(Camera camera, GameObject gameObject) - { - if (camera.scene != null && camera.scene.handle != 0 && camera.scene != gameObject.scene) - return true; - else - return false; - } - - private string LoadMockHmdSetting() - { - try - { - foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) - { - Type type = assembly.GetType("Unity.XR.MockHMD.MockHMDBuildSettings", false); - if (!(type == (Type)null)) - { - object obj = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue((object)null); - return type.GetField("renderMode").GetValue(obj).ToString(); - } - } - } - catch - { - } - return null; - } - - private Light FindMainLight() - { - Light currentLight = null; - foreach (Light otherLight in UnityEngine.Object.FindObjectsOfType()) - { - if (otherLight.type == LightType.Directional) - { - if (otherLight.shadows > 0) - { - currentLight = otherLight; - break; - } - if (currentLight == null) - currentLight = otherLight; - else if (otherLight.intensity > currentLight.intensity) - currentLight = otherLight; - } - } - return currentLight; - } - - private float RelativeHeightToDistance( - float relativeHeight, - float size, - float fieldOfView, - float bias) - { - if ((double)relativeHeight <= 0.0 || (double)relativeHeight == 3.40282346638529E+38) - return float.MaxValue; - float num = Mathf.Tan((float)(Math.PI / 180.0 * (double)fieldOfView * 0.5)); - return size * 0.5f / relativeHeight / num * bias; - } - - private bool BuffersChanged(List buffers, ref int cachedHash) - { - int hash = ComputeHash(buffers); - if (hash == cachedHash) - return false; - cachedHash = hash; - return true; - } - - private int ComputeHash(List buffers) - { - if (buffers == null || buffers.Count == 0) - return 0; - int num = buffers[0].GetHashCode(); - for (int index = 1; index < buffers.Count; ++index) - num = HashCode.Combine(num, buffers[index].GetHashCode()); - return num; - } - - public void Dispose() - { - UnityEngine.Object.DestroyImmediate(instancingShader); - prefabBuffer?.Dispose(); - indirectDrawIndexedArgsBuffer?.Dispose(); - metaBuffer?.Dispose(); - cullableIndexesBuffer?.Dispose(); - visibleIndexesBuffer?.Dispose(); - visibleShadowIndexesBuffer?.Dispose(); - commandBuffer?.Dispose(); - prefabBuffer = null; - indirectDrawIndexedArgsBuffer = null; - metaBuffer = null; - visibleIndexesBuffer = null; - visibleShadowIndexesBuffer = null; - } - } -} diff --git a/CameraRenderer.cs.meta b/CameraRenderer.cs.meta deleted file mode 100644 index 6e82e1a..0000000 --- a/CameraRenderer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f2218c3942cfa8745866f4503b313216 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/CellLayout.cs b/CellLayout.cs deleted file mode 100644 index 8909a94..0000000 --- a/CellLayout.cs +++ /dev/null @@ -1,179 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public class CellLayout - { - public Vector3 Origin; - private readonly int _cellsX; - private readonly int _cellsZ; - private readonly float _cellSizeX; - private readonly float _cellSizeZ; - private readonly Cell[] _cells; - private readonly Dictionary _cameraPlanes = new Dictionary(); - private const int _planeCount = 6; - private int _cachedFrameId; - private Camera _cachedCamera; - private Plane[] _planes = new Plane[6]; - private Double3[] _absNormals = new Double3[6]; - private Double3[] _planeNormal = new Double3[6]; - private double[] _planeDistance = new double[6]; - - public CellLayout(float cellSizeX, float cellSizeZ, Bounds worldBounds) - { - Origin = worldBounds.min; - _cellSizeX = cellSizeX; - _cellSizeZ = cellSizeZ; - _cellsX = Mathf.CeilToInt(worldBounds.size.x / _cellSizeX); - _cellsZ = Mathf.CeilToInt(worldBounds.size.z / _cellSizeZ); - _cells = new Cell[_cellsX * _cellsZ]; - float num1 = _cellSizeX * 0.5f; - float num2 = _cellSizeZ * 0.5f; - for (int index1 = 0; index1 < _cellsZ; ++index1) - { - for (int index2 = 0; index2 < _cellsX; ++index2) - { - int index3 = index1 * _cellsX + index2; - float num3 = (float)index2 * _cellSizeX + num1; - float num4 = (float)index1 * _cellSizeZ + num2; - _cells[index3].HeightMin = double.MaxValue; - _cells[index3].HeightMax = double.MinValue; - _cells[index3].Center = new Double3((double)num3, 0.0, (double)num4); - _cells[index3].Extends = new Double3((double)num1, double.NaN, (double)num2); - } - } - } - - public Cell[] GetCells() => _cells; - - public int GetCellCount() => _cells.Length; - - public void OverwriteCellHeightBounds() - { - int length = _cells.Length; - for (int index = 0; index < length; ++index) - _cells[index].HeightOverwrite = true; - } - - public void SetCellHeightBounds(int cellIndex, double min, double max) - { - ref Cell local = ref _cells[cellIndex]; - if (local.HeightOverwrite) - { - local.HeightOverwrite = false; - local.HeightMax = max; - local.HeightMin = min; - } - else - { - local.HeightMax = Math.Max(local.HeightMax, max); - local.HeightMin = Math.Min(local.HeightMin, min); - } - local.Center = new Double3(local.Center.x, (local.HeightMax + local.HeightMin) * 0.5, local.Center.z); - local.Extends = new Double3(local.Extends.x, (local.HeightMax + local.HeightMin) * 0.5, local.Extends.z); - } - - public void Update(Camera camera, int frameId, bool frustumCulling) - { - if (camera == _cachedCamera && frameId == _cachedFrameId) - return; - _cachedCamera = camera; - _cachedFrameId = frameId; - Plane[] planes; - if (!_cameraPlanes.TryGetValue(((object)camera).GetHashCode(), out planes)) - _cameraPlanes[((object)camera).GetHashCode()] = planes = new Plane[6]; - GeometryUtility.CalculateFrustumPlanes(camera, planes); - SetPlanes(planes); - double x1 = camera.transform.position.x; - double z1 = camera.transform.position.z; - Double3 absNormal1 = _absNormals[0]; - Double3 absNormal2 = _absNormals[1]; - Double3 absNormal3 = _absNormals[2]; - Double3 absNormal4 = _absNormals[3]; - Double3 absNormal5 = _absNormals[4]; - Double3 absNormal6 = _absNormals[5]; - Double3 double3_1 = _planeNormal[0]; - Double3 double3_2 = _planeNormal[1]; - Double3 double3_3 = _planeNormal[2]; - Double3 double3_4 = _planeNormal[3]; - Double3 double3_5 = _planeNormal[4]; - Double3 double3_6 = _planeNormal[5]; - double num1 = _planeDistance[0]; - double num2 = _planeDistance[1]; - double num3 = _planeDistance[2]; - double num4 = _planeDistance[3]; - double num5 = _planeDistance[4]; - double num6 = _planeDistance[5]; - double x2 = (double)Origin.x; - double y = (double)Origin.y; - double z2 = (double)Origin.z; - int length = _cells.Length; - for (int index = 0; index < length; ++index) - { - ref Cell local = ref _cells[index]; - double num7 = local.Center.x + x2; - double num8 = local.Center.y + y; - double num9 = local.Center.z + z2; - Double3 extends = local.Extends; - local.DistanceX = Math.Abs(x1 - num7); - local.DistanceZ = Math.Abs(z1 - num9); - if (frustumCulling && !double.IsNaN(extends.y)) - { - bool flag = extends.x * absNormal1.x + extends.y * absNormal1.y + extends.z * absNormal1.z + (double3_1.x * num7 + double3_1.y * num8 + double3_1.z * num9) < -num1 || extends.x * absNormal2.x + extends.y * absNormal2.y + extends.z * absNormal2.z + (double3_2.x * num7 + double3_2.y * num8 + double3_2.z * num9) < -num2 || extends.x * absNormal3.x + extends.y * absNormal3.y + extends.z * absNormal3.z + (double3_3.x * num7 + double3_3.y * num8 + double3_3.z * num9) < -num3 || extends.x * absNormal4.x + extends.y * absNormal4.y + extends.z * absNormal4.z + (double3_4.x * num7 + double3_4.y * num8 + double3_4.z * num9) < -num4 || extends.x * absNormal5.x + extends.y * absNormal5.y + extends.z * absNormal5.z + (double3_5.x * num7 + double3_5.y * num8 + double3_5.z * num9) < -num5 || extends.x * absNormal6.x + extends.y * absNormal6.y + extends.z * absNormal6.z + (double3_6.x * num7 + double3_6.y * num8 + double3_6.z * num9) < -num6; - local.InFrustum = !flag; - } - else - local.InFrustum = true; - } - } - - private void SetPlanes(Plane[] planes) - { - _planes = planes; - for (int index = 0; index < 6; ++index) - { - Plane plane = _planes[index]; - Vector3 vector = plane.normal; - Double3 double3 = new Double3(in vector); - _absNormals[index] = new Double3(Math.Abs(double3.x), Math.Abs(double3.y), Math.Abs(double3.z)); - _planeNormal[index] = double3; - _planeDistance[index] = plane.distance; - } - } - - public struct Cell - { - public double DistanceX; - public double DistanceZ; - public bool InFrustum; - public Double3 Center; - public Double3 Extends; - public double HeightMin; - public double HeightMax; - public bool HeightOverwrite; - } - - public readonly struct Double3 - { - public readonly double x; - public readonly double y; - public readonly double z; - - public Double3(in Vector3 vector) - { - x = (double)vector.x; - y = (double)vector.y; - z = (double)vector.z; - } - - public Double3(double x, double y, double z) - { - this.x = x; - this.y = y; - this.z = z; - } - } - } -} diff --git a/CellLayout.cs.meta b/CellLayout.cs.meta deleted file mode 100644 index 4193062..0000000 --- a/CellLayout.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4cf46f5589518ec4f9ea40aaf072cfbf -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/CellLayoutPool.cs b/CellLayoutPool.cs deleted file mode 100644 index f4a9da2..0000000 --- a/CellLayoutPool.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - internal class CellLayoutPool - { - private static readonly Dictionary _hashLookup = new Dictionary(); - private static readonly Dictionary _sharedCells = new Dictionary(); - private static readonly Dictionary> _usageTracker = new Dictionary>(); - - public static int Count => CellLayoutPool._sharedCells.Count; - - internal static bool Validate() => CellLayoutPool._hashLookup.Count == CellLayoutPool._sharedCells.Count && CellLayoutPool._hashLookup.Count == CellLayoutPool._usageTracker.Count; - - public static CellLayout Get( - object owner, - float cellSizeX, - float cellSizeZ, - int cellsX, - int cellsZ, - Bounds bounds) - { - if (owner == null) - throw new ArgumentNullException(nameof(owner)); - int hashCode = CellLayoutPool.GetHashCode(cellSizeX, cellSizeZ, cellsX, cellsZ, bounds.min); - CellLayout key; - if (!CellLayoutPool._sharedCells.TryGetValue(hashCode, out key)) - { - CellLayoutPool._sharedCells[hashCode] = key = new CellLayout(cellSizeX, cellSizeZ, bounds); - CellLayoutPool._hashLookup[key] = hashCode; - } - CellLayoutPool.IncreaseUsage(hashCode, owner); - return key; - } - - public static void Return(object owner, CellLayout layout) - { - if (owner == null) - throw new ArgumentNullException(nameof(owner)); - int hash = layout != null ? CellLayoutPool.GetHashCode(layout) : throw new ArgumentNullException(nameof(layout)); - if (CellLayoutPool.DecreaseUsage(hash, owner) != 0) - return; - CellLayoutPool.Dispose(hash, layout); - } - - private static void Dispose(int hash, CellLayout layout) - { - CellLayoutPool._usageTracker.Remove(hash); - CellLayoutPool._sharedCells.Remove(hash); - CellLayoutPool._hashLookup.Remove(layout); - } - - private static int GetHashCode(CellLayout layout) => CellLayoutPool._hashLookup[layout]; - - private static void IncreaseUsage(int hash, object owner) - { - HashSet intSet; - if (!CellLayoutPool._usageTracker.TryGetValue(hash, out intSet) || intSet == null) - CellLayoutPool._usageTracker[hash] = intSet = new HashSet(); - int hashCode = owner.GetHashCode(); - if (intSet.Contains(hashCode)) - return; - intSet.Add(hashCode); - } - - private static int DecreaseUsage(int hash, object owner) - { - HashSet intSet = CellLayoutPool._usageTracker[hash]; - intSet.Remove(owner.GetHashCode()); - return intSet.Count; - } - - private static int GetHashCode( - float cellSizeX, - float cellSizeZ, - int cellsX, - int cellsZ, - Vector3 initialOrigin) - { - return HashCode.Combine(cellSizeX, cellSizeZ, cellsX, cellsZ, initialOrigin); - } - } -} diff --git a/CellLayoutPool.cs.meta b/CellLayoutPool.cs.meta deleted file mode 100644 index 81db81a..0000000 --- a/CellLayoutPool.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d431ea020bbd81c42b897bd3afc640cb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/DrawCall.cs b/DrawCall.cs deleted file mode 100644 index c1b7dda..0000000 --- a/DrawCall.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public class DrawCall - { - public readonly Mesh Mesh; - public readonly Material[] Materials; - public readonly RenderParams[] RenderParams; - private readonly Matrix4x4 _localToWorldMatrix; - private readonly uint baseIndirectArgsIndex; - private readonly int lodNr; - public DrawCall( - int lodNr, - Mesh mesh, - Material[] materials, - Matrix4x4 localToWorldMatrix, - uint baseIndirectArgsIndex, - List indirectDrawIndexedArgs, - in RenderParams renderParams) - { - if (mesh == null) - throw new ArgumentNullException(nameof(mesh)); - if (materials == null) - throw new ArgumentNullException(nameof(materials)); - if (materials.Length != mesh.subMeshCount) - throw new IndexOutOfRangeException(nameof(materials)); - - this.baseIndirectArgsIndex = baseIndirectArgsIndex; - _localToWorldMatrix = localToWorldMatrix; - Mesh = mesh; - Materials = materials; - RenderParams = new RenderParams[mesh.subMeshCount]; - - this.lodNr = lodNr; - - for (int index = 0; index < mesh.subMeshCount; ++index) - { - RenderParams[index] = renderParams; - RenderParams[index].material = materials[index]; - RenderParams[index].matProps = new MaterialPropertyBlock(); - RenderParams[index].matProps.SetMatrix("trInstanceMatrix", _localToWorldMatrix); - RenderParams[index].matProps.SetInteger("trLodNr", lodNr + 1); - - RenderParams[index].worldBounds = new Bounds(Vector3.zero, 1000f * Vector3.one); - - indirectDrawIndexedArgs.Add(new GraphicsBuffer.IndirectDrawIndexedArgs - { - indexCountPerInstance = mesh.GetIndexCount(index), - baseVertexIndex = mesh.GetBaseVertex(index), - startIndex = mesh.GetIndexStart(index), - startInstance = 0, - instanceCount = 0 - }); - } - } - - public virtual void SetInstances(ComputeBuffer instances, ComputeBuffer visibleIndexBuffer, ComputeBuffer metaBuffer) - { - for (int index = 0; index < this.RenderParams.Length; ++index) - { - RenderParams[index].matProps.SetBuffer("trInstances", instances); - RenderParams[index].matProps.SetBuffer("trPerCamVisibleIndexesBuffer", visibleIndexBuffer); - RenderParams[index].matProps.SetBuffer("trPerCamMeta", metaBuffer); - } - } - - public virtual void Draw(Camera camera, ObjectData obj, GraphicsBuffer indirectDrawIndexedArgs) - { - if (Materials == null) - throw new ObjectDisposedException("Materials"); - - if (Mesh == null) - throw new ObjectDisposedException("Mesh"); - - var bounds = new Bounds(camera.transform.position, Vector3.one * 1000f); - - for (int index = 0; index < RenderParams.Length; ++index) - { - var renderParam = RenderParams[index]; - if (renderParam.material != null) - { - renderParam.camera = camera; - renderParam.worldBounds = bounds; - Graphics.RenderMeshIndirect(in renderParam, Mesh, indirectDrawIndexedArgs, 1, obj.indirectArgsPerSubmeshOffsets[(int)baseIndirectArgsIndex + index]); - } - } - } - - internal virtual void Dispose() - { - - } - } -} diff --git a/DrawCall.cs.meta b/DrawCall.cs.meta deleted file mode 100644 index f706731..0000000 --- a/DrawCall.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0345ca3ff11f4114a9cb20dfdeee77a5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/DrawGroup.cs b/DrawGroup.cs deleted file mode 100644 index 27fb676..0000000 --- a/DrawGroup.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public class DrawGroup - { - private List _drawCalls = new List(); - - public void Add(DrawCall drawCall) => _drawCalls.Add(drawCall); - - private int lodNr; - - public DrawGroup(int lodNr) - { - this.lodNr = lodNr; - } - - public uint Add( - Mesh mesh, - Material[] materials, - Matrix4x4 matrix, - uint indirectArgsCount, - List indirectDrawIndexedArgs, - in RenderParams renderParams) - { - var drawCall = new DrawCall(lodNr, mesh, materials, matrix, indirectArgsCount, indirectDrawIndexedArgs, in renderParams); - _drawCalls.Add(drawCall); - return (uint)drawCall.Mesh.subMeshCount; - } - - public uint Add( - BillboardAsset mesh, - Material material, - Matrix4x4 matrix, - uint indirectArgsCount, - List indirectDrawIndexedArgs, - in RenderParams renderParams) - { - var drawCall = new BillboardDrawCall(lodNr, mesh, material, matrix, indirectArgsCount, indirectDrawIndexedArgs, in renderParams); - _drawCalls.Add(drawCall); - return (uint)drawCall.Mesh.subMeshCount; - } - - public void Draw(Camera camera, ObjectData obj, GraphicsBuffer indirectDrawIndexedArgs) - { - foreach (var drawCall in _drawCalls) - drawCall?.Draw(camera, obj, indirectDrawIndexedArgs); - } - - public virtual void SetInstances(ComputeBuffer instances, ComputeBuffer visibleIndexBuffer, ComputeBuffer metaBuffer) - { - foreach (var drawCall in _drawCalls) - drawCall?.SetInstances(instances, visibleIndexBuffer, metaBuffer); - } - - internal void Dispose() - { - foreach (var drawCall in _drawCalls) - drawCall?.Dispose(); - - _drawCalls.Clear(); - } - } -} diff --git a/DrawGroup.cs.meta b/DrawGroup.cs.meta deleted file mode 100644 index 4ddfb14..0000000 --- a/DrawGroup.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 14eaba28b1cfbac43acbf8a698ee5dbe -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/FrameRenderer.cs b/FrameRenderer.cs deleted file mode 100644 index 0d1fd57..0000000 --- a/FrameRenderer.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Collections.Generic; -#if UNITY_EDITOR -using UnityEditor; -#endif -using UnityEngine; -using UnityEngine.Rendering; - -namespace Assets.ThoMagic.Renderer -{ - public class FrameRenderer - { - [RuntimeInitializeOnLoadMethod] - public static void Initialize() - { -#if UNITY_EDITOR - AssemblyReloadEvents.beforeAssemblyReload += AssemblyReloadEvents_beforeAssemblyReload; -#endif - RendererPool.RemoveDestroyedCameras(); - RendererPool.Initialize(); - Camera.onPreCull -= RenderCamera; - Camera.onPreCull += RenderCamera; - RenderPipelineManager.beginContextRendering -= OnBeginContextRendering; - RenderPipelineManager.beginContextRendering += OnBeginContextRendering; - } - - private static void AssemblyReloadEvents_beforeAssemblyReload() - { - RendererPool.Destroy(); - } - - private static void OnBeginContextRendering( - ScriptableRenderContext context, - List cameras) - { - RendererPool.BuildBuffers(); - RendererPool.RemoveDestroyedCameras(); - foreach(var camera in cameras) - { - if (!CameraIsSupported(camera)) - { - RendererPool.RemoveCamera(camera.GetHashCode()); - } - else - { - CameraRenderer cameraRenderer = RendererPool.GetCamera(RendererPool.RegisterCamera(camera)); - try - { - cameraRenderer.Render(); - } - catch (Exception ex) - { - Debug.LogException(ex); - } - } - } - } - - private static void RenderCamera(Camera camera) - { - if (camera == null) - throw new NullReferenceException(nameof(camera)); - - if (!CameraIsSupported(camera)) - { - RendererPool.RemoveCamera(camera.GetHashCode()); - } - else - { - RendererPool.BuildBuffers(); - RendererPool.RemoveDestroyedCameras(); - int cameraId = RendererPool.RegisterCamera(camera); - try - { - RendererPool.GetCamera(cameraId)?.Render(); - } - catch (Exception ex) - { - Debug.LogException(ex); - } - } - } - - private static bool CameraIsSupported(Camera camera) - { - IInstanceRenderSettings instanceRenderSettings; - return (Application.isPlaying || camera.cameraType != CameraType.Preview) && (!camera.TryGetComponent(out instanceRenderSettings) || instanceRenderSettings.Settings.Supported); - } - } -} diff --git a/FrameRenderer.cs.meta b/FrameRenderer.cs.meta deleted file mode 100644 index 6f87a9b..0000000 --- a/FrameRenderer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e9b14e1d6d523834db575b4973d22c0e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/GrassRenderer.cs b/GrassRenderer.cs deleted file mode 100644 index 630d3b1..0000000 --- a/GrassRenderer.cs +++ /dev/null @@ -1,196 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public class GrassRenderer : GrassStreamer - { - - private readonly Terrain terrain; - private readonly TerrainData terrainData; - private bool isDirty; - - public GrassRenderer(Terrain terrain) - : base(terrain) - { - this.terrain = terrain; - terrainData = terrain.terrainData; - } - - public void OnTerrainChanged(TerrainChangedFlags flags) - { - if (flags.HasFlag(TerrainChangedFlags.DelayedHeightmapUpdate)) - isDirty = true; - else if (flags.HasFlag(TerrainChangedFlags.Heightmap)) - isDirty = true; - else if (flags.HasFlag(TerrainChangedFlags.HeightmapResolution)) - isDirty = true; - else if (flags.HasFlag(TerrainChangedFlags.Holes)) - isDirty = true; - else if (flags.HasFlag(TerrainChangedFlags.DelayedHolesUpdate)) - isDirty = true; - else if (flags.HasFlag(TerrainChangedFlags.FlushEverythingImmediately)) - isDirty = true; - } - - public void Destroy() - { - Recycle(); - } - - public void LateUpdate() - { - if (isDirty) - { - isDirty = false; - Load(); - } - - if (Application.isEditor && !Application.isPlaying) - RebuildChangedPrototypes(); - - Update(); - } - - public void Load() - { - DetailPrototype[] detailPrototypes = terrainData.detailPrototypes; - - Recycle(); - - int ownerHash = GetHashCode(); - - if (grassPrefabs == null) - { - grassPrefabs = new List(); - grassPrefabSet = new List(); - } - - float maxDetailDistance = float.MinValue; - - for (int index = 0; index < detailPrototypes.Length; ++index) - { - if (!detailPrototypes[index].usePrototypeMesh || detailPrototypes[index].prototype == null) - { - AddDummy(index); - } - else - { - GameObject prototypeToRender = RendererUtility.GetPrototypeToRender(detailPrototypes[index]); - if (!RendererUtility.SupportsProceduralInstancing(prototypeToRender)) - { - AddDummy(index); - } - else - { - var settings = GetSettingsOrDefault(prototypeToRender); - maxDetailDistance = Mathf.Max(maxDetailDistance, settings.Settings.RenderDistance); - grassPrefabs.Add(RendererPool.RegisterObject(prototypeToRender, settings, this, ownerHash)); - grassPrefabSet.Add(true); - } - } - } - - Build(maxDetailDistance, detailPrototypes.Length); - } - - private void AddDummy(int i) - { - grassPrefabs.Add(-1); - grassPrefabSet.Add(false); - } - - public override void Recycle() - { - if (grassPrefabs == null) - return; - - base.Recycle(); - - int ownerHash = GetHashCode(); - for (int index = 0; index < grassPrefabs.Count; ++index) - { - if (grassPrefabSet[index]) - { - RendererPool.RemoveObject(grassPrefabs[index], ownerHash); - } - } - - grassPrefabs.Clear(); - grassPrefabSet.Clear(); - } - - private void RebuildChangedPrototypes() - { - DetailPrototype[] detailPrototypes = terrainData.detailPrototypes; - if (detailPrototypes.Length != grassPrefabs.Count) - { - Load(); - } - else - { - int ownerHash = GetHashCode(); - - for (int index = 0; index < grassPrefabs.Count; ++index) - { - if (grassPrefabSet[index]) - { - GameObject prototypeToRender = RendererUtility.GetPrototypeToRender(detailPrototypes[index]); - GameObject gameObject = RendererPool.GetObject(grassPrefabs[index]); - if (prototypeToRender != gameObject) - { - RendererPool.RemoveObject(grassPrefabs[index], ownerHash); - - if (prototypeToRender != null) - { - grassPrefabs[index] = RendererPool.RegisterObject(prototypeToRender, GetSettingsOrDefault(prototypeToRender), this, ownerHash); - grassPrefabSet[index] = true; - } - else - { - grassPrefabs[index] = -1; - grassPrefabSet[index] = false; - } - } - else if (RendererPool.ContentHashChanged(grassPrefabs[index])) - { - RendererPool.RemoveObject(grassPrefabs[index], GetHashCode()); - if (prototypeToRender != null) - { - grassPrefabs[index] = RendererPool.RegisterObject(prototypeToRender, GetSettingsOrDefault(prototypeToRender), this, ownerHash); - grassPrefabSet[index] = true; - } - else - { - grassPrefabs[index] = -1; - grassPrefabSet[index] = false; - } - } - else if (prototypeToRender != null) - RendererPool.SetObjectSettings(prototypeToRender, GetSettingsOrDefault(prototypeToRender)); - } - } - } - } - - private IInstanceRenderSettings GetSettingsOrDefault(GameObject gameObject) - { - IInstanceRenderSettings instanceRenderSettings; - return gameObject.TryGetComponent(out instanceRenderSettings) ? instanceRenderSettings : new DefaultRenderSettings(); - } - - private class DefaultRenderSettings : IInstanceRenderSettings - { - public InstanceRenderSettings Settings => new InstanceRenderSettings() - { - Render = true, - DensityInDistance = 0.125f, - DensityInDistanceFalloff = new Vector2(0.08f, 0.0075f), - RenderDistance = 150f, - ShadowDistance = 50f, - Shadows = true, - Supported = true - }; - } - } -} diff --git a/GrassRenderer.cs.meta b/GrassRenderer.cs.meta deleted file mode 100644 index 8ffedca..0000000 --- a/GrassRenderer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cdb66824e49e1344faf75691d1c8788d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/GrassStreamer.cs b/GrassStreamer.cs deleted file mode 100644 index 006162f..0000000 --- a/GrassStreamer.cs +++ /dev/null @@ -1,301 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - /// - /// Subdivides a terrain into smaller 2d-cells in the xz-plane based on terrain settings. Only cells in range 'maxDetailDistance' of the camera - /// are alive. - /// - public class GrassStreamer : InstanceStreamer - { - /// - /// The limit of how many instances are created per frame. - /// TODO: While the setting is global, the budget is per streamer and each - /// terrain has it's own streamer. This should be a real global budget. - /// - static int globalStreamingBudget = 10000; - - protected List grassPrefabs; - protected List grassPrefabSet; - - private readonly Terrain terrain; - private readonly TerrainData terrainData; - - /// - /// Used to find cells in range of the camera. - /// - private float maxDetailDistance; - private Bounds worldBounds; - private int layerCount; - - private Cell[] Cells; - private float cellSizeX, cellSizeZ; - private int cellsX, cellsZ; - - /// - /// A queue with a list of cells to load. Cells are loaded per frame - /// til the streaming budget is spent. - /// - private Queue cellsToLoad = new Queue(); - /// - /// List of cells unloaded in a frame, only temporary list used to remove from loadedCells. - /// - private List cellsToUnloaded = new List(); - //A map of loaded cells. The cell index is z * cellCountX + x. - private Dictionary loadedCells = new Dictionary(); - - public static void SetStreamingBudget(int budget) => globalStreamingBudget = budget; - - private static float CalculatePatchSizeX(TerrainData terrainData) => (float)((double)terrainData.detailResolutionPerPatch / (double)terrainData.detailResolution * terrainData.size.x); - - private static float CalculatePatchSizeZ(TerrainData terrainData) => (float)((double)terrainData.detailResolutionPerPatch / (double)terrainData.detailResolution * terrainData.size.z); - - public GrassStreamer( - Terrain terrain) - : base() - { - this.terrain = terrain; - terrainData = terrain.terrainData; - } - - /// - /// Update loaded cells. Called by renderer. The renderer calls this once each frame. - /// - public void Update() - { - //Load cells until either all cells are loaded or budget is spent. - //Returns the budget left. - int streamingBudget = UpdateLoadCellsAsync(); - - //Go through all loaded cells and reduce 'inRangeOfAnyCamera'. - //If 'inRangeOfAnyCamera' is equal or below zero unload the cell. - //'inRangeOfAnyCamera' is reset to x if a camera renders and this - //cell is in range. - foreach (var cellIndex in loadedCells.Keys) - { - var cell = loadedCells[cellIndex]; - - //If cell is out of range and budget exist, unload. - if (cell.inRangeOfAnyCamera <= 0 && streamingBudget > 0) - { - streamingBudget -= UnloadCell(cellIndex); - cellsToUnloaded.Add(cellIndex); - } - - --cell.inRangeOfAnyCamera; - } - - //Remove all cells unloaded from 'loadedCells'. - if (cellsToUnloaded.Count > 0) - { - foreach (var id in cellsToUnloaded) - loadedCells.Remove(id); - cellsToUnloaded.Clear(); - } - } - - /// - /// Rebuild the cell layout. Called on initialize and on certain terrain changes. - /// - /// Max distance where a cell is in range - /// Count of detail layers - public void Build(float maxDistance, int layerCount) - { - maxDetailDistance = maxDistance; - this.layerCount = layerCount; - - cellSizeX = CalculatePatchSizeX(terrainData); - cellSizeZ = CalculatePatchSizeZ(terrainData); - - Vector3 position = terrain.GetPosition(); - worldBounds = new Bounds(terrainData.bounds.center + position, terrainData.bounds.size); - - cellsX = Mathf.CeilToInt(worldBounds.size.x / cellSizeX); - cellsZ = Mathf.CeilToInt(worldBounds.size.z / cellSizeZ); - Cells = new Cell[cellsX * cellsZ]; - - float cellSizeX_2 = cellSizeX * 0.5f; - float cellSizeZ_2 = cellSizeZ * 0.5f; - for (int indexZ = 0; indexZ < cellsZ; ++indexZ) - { - for (int indexX = 0; indexX < cellsX; ++indexX) - { - int cellIndex = indexZ * cellsX + indexX; - Cells[cellIndex] = new Cell(); - float cellCenterX = indexX * cellSizeX + cellSizeX_2; - float cellCenterZ = indexZ * cellSizeZ + cellSizeZ_2; - Cells[cellIndex].CenterX = cellCenterX; - Cells[cellIndex].CenterZ = cellCenterZ; - } - } - } - - /// - /// Is this streamer within range? - /// - /// The camera to check for - /// Planes of the camera frustum - /// - public override bool IsInRange(Camera camera, Plane[] planes) - { - if (layerCount == 0) - return false; - - if (!terrain.editorRenderFlags.HasFlag(TerrainRenderFlags.Details)) - return false; - - var eyePos = camera.transform.position; - - if ((eyePos - worldBounds.ClosestPoint(eyePos)).magnitude <= Mathf.Min(camera.farClipPlane, maxDetailDistance)) - return true; - - return false; - } - - /// - /// Load cells until either all cells are loaded from the cellsToLoad list - /// or the budget is spent. - /// - /// Unspent budget - private int UpdateLoadCellsAsync() - { - int streamingBudget = globalStreamingBudget; - - if (globalStreamingBudget <= 0 || Cells == null || Cells.Length == 0) - return streamingBudget; - - while(streamingBudget > 0 && cellsToLoad.TryDequeue(out var cellIndex)) - { - streamingBudget -= LoadCell(cellIndex); - } - - return streamingBudget; - } - - public virtual void Recycle() - { - UnloadAll(); - } - - private void UnloadAll() - { - if (Cells == null || Cells.Length == 0) - return; - - for (int cellIndex = 0; cellIndex < Cells.Length; ++cellIndex) - { - UnloadCell(cellIndex); - } - - loadedCells.Clear(); - } - - /// - /// Remove all instances of a cell. - /// - /// - /// The amount of deleted instances - private int UnloadCell(int cellIndex) - { - if (cellIndex < 0 || cellIndex >= Cells.Length || !Cells[cellIndex].IsLoaded) - return 0; - - var cell = Cells[cellIndex]; - cell.IsLoaded = false; - cell.IsLoading = false; - - int deletedInstances = cell.loadedInstances.Count; - - foreach (var instanceInfo in cell.loadedInstances) - RemoveInstance(instanceInfo.objectId, instanceInfo.instanceId); - - cell.loadedInstances.Clear(); - - return deletedInstances; - } - - /// - /// Load all instances for a cell. - /// - /// - /// The amount of loaded instances - private int LoadCell(int cellIndex) - { - if (cellIndex < 0 || cellIndex >= Cells.Length || Cells[cellIndex].IsLoaded) - return 0; - - var cell = Cells[cellIndex]; - cell.IsLoaded = true; - cell.IsLoading = false; - - loadedCells.Add(cellIndex, cell); - int x = Mathf.FloorToInt(cell.CenterX / cellSizeX); - int z = Mathf.FloorToInt(cell.CenterZ / cellSizeZ); - Vector3 size = terrainData.size; - Vector3 terrainOffset = terrain.transform.position; - Quaternion terrainRotation = terrain.transform.rotation; - float detailObjectDensity = terrain.detailObjectDensity; - - for (int layer = 0; layer < layerCount; layer++) - { - var instanceTransforms = terrainData.ComputeDetailInstanceTransforms(x, z, layer, detailObjectDensity, out var _); - - for (int index = 0; index < instanceTransforms.Length; ++index) - { - var local = instanceTransforms[index]; - - Vector3 interpolatedNormal = terrainData.GetInterpolatedNormal((local.posX / size.x), (local.posZ / size.z)); - Quaternion rotation = terrainRotation * Quaternion.FromToRotation(Vector3.up, interpolatedNormal) * Quaternion.AngleAxis((local.rotationY * 57.2957801818848f), Vector3.up); - - var instanceId = AddInstance(grassPrefabs[layer], new Vector3(local.posX, local.posY, local.posZ) + terrainOffset, rotation, local.scaleXZ, local.scaleY); - cell.loadedInstances.Add(new InstanceInfo { instanceId = instanceId, objectId = grassPrefabs[layer] }); - } - } - - return cell.loadedInstances.Count; - } - - /// - /// Called by each camera at the start of a frame. - /// Finds all cells visible in range of a camera. Either - /// resets the 'inRangeOfAnyCamera' counter or adds the cell - /// to the load list. - /// - /// - /// - public override void UpdateForCamera(Camera camera, Plane[] planes) - { - if (Cells == null || Cells.Length == 0) - return; - - var range = Mathf.Min(camera.farClipPlane, maxDetailDistance); - var rangeX = Mathf.CeilToInt((range + cellSizeX * 0.5f) / cellSizeX); - var rangeZ = Mathf.CeilToInt((range + cellSizeZ * 0.5f) / cellSizeZ); - - var eyePos = camera.transform.position - worldBounds.min; - var eyeCellX = Mathf.FloorToInt(eyePos.x / cellSizeX); - var eyeCellZ = Mathf.FloorToInt(eyePos.z / cellSizeZ); - - for(int indexZ = eyeCellZ - rangeZ; indexZ < eyeCellZ + rangeZ; indexZ++) - for (int indexX = eyeCellX - rangeX; indexX < eyeCellX + rangeX; indexX++) - { - if(indexZ >= 0 && indexZ < cellsZ && - indexX >= 0 && indexX < cellsX) - { - int cellIndex = indexZ * cellsX + indexX; - if (Cells[cellIndex].IsLoaded || Cells[cellIndex].IsLoading) - { - Cells[cellIndex].inRangeOfAnyCamera = 2; - } - else - { - Cells[cellIndex].IsLoading = true; - Cells[cellIndex].inRangeOfAnyCamera = 2; - cellsToLoad.Enqueue(cellIndex); - } - } - } - } - } -} diff --git a/GrassStreamer.cs.meta b/GrassStreamer.cs.meta deleted file mode 100644 index ab6d341..0000000 --- a/GrassStreamer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a9909a9557ba0b94e9de512444a0629e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/InstanceBuffer.cs b/InstanceBuffer.cs deleted file mode 100644 index 090659f..0000000 --- a/InstanceBuffer.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Collections.Generic; -using System.Threading; - -namespace Assets.ThoMagic.Renderer -{ - public class InstanceBuffer - { - private static int nextInstanceBufferId = 1; - private readonly int instanceBufferId; - - public readonly ObjectData objectData; - public readonly Dictionary instanceData; - - public InstanceBuffer(ObjectData objectData) - { - this.objectData = objectData; - instanceData = new Dictionary(); - instanceBufferId = Interlocked.Increment(ref InstanceBuffer.nextInstanceBufferId); - } - - public override int GetHashCode() - { - return instanceBufferId; - } - } -} \ No newline at end of file diff --git a/InstanceBuffer.cs.meta b/InstanceBuffer.cs.meta deleted file mode 100644 index 20b1044..0000000 --- a/InstanceBuffer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1d85f6533dc1bb84bb236fd27ab68b38 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/InstanceMatrix.cs b/InstanceMatrix.cs deleted file mode 100644 index 0d9e6da..0000000 --- a/InstanceMatrix.cs +++ /dev/null @@ -1,174 +0,0 @@ -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public struct InstanceData - { - public const int Add = 1; - public const int Delete = 2; - public static readonly int Stride = 48; - public readonly Vector4 Packed1; - public readonly Vector4 Packed2; - public readonly uint prefabId; - //Used to stream out new instances - public readonly int uploadAction; - public readonly int uploadId; - public readonly int padding; - - public InstanceData( - int uploadAction, - int uploadId, - uint prefabId, - float x, - float y, - float z, - in Quaternion rotation, - float scaleXZ, - float scaleY) - { - float num = rotation.w > 0.0 ? 1f : -1f; - Packed1.x = x; - Packed1.y = y; - Packed1.z = z; - Packed1.w = (rotation.x * num); - Packed2.x = scaleXZ; - Packed2.y = scaleY; - Packed2.z = (rotation.y * num); - Packed2.w = (rotation.z * num); - this.prefabId = prefabId; - this.uploadAction = uploadAction; - this.uploadId = uploadId; - padding = 0; - } - - public InstanceData( - int uploadAction, - int uploadId) - { - Packed1.x = 0; - Packed1.y = 0; - Packed1.z = 0; - Packed1.w = 0; - Packed2.x = 0; - Packed2.y = 0; - Packed2.z = 0; - Packed2.w = 0; - this.prefabId = 0; - this.uploadAction = uploadAction; - this.uploadId = uploadId; - padding = 0; - } - } - - public struct PrefabData - { - public static readonly int Stride = 228; - public uint batchIndex; - public uint indexBufferStartOffset; - public uint maxCount; - public uint lodCount; - public uint fadeLods; - public Vector4 densityInDistance; - public Vector4 lodData0; - public Vector4 lodData1; - public Vector4 lodData2; - public Vector4 lodData3; - public Vector4 lodData4; - public Vector4 lodData5; - public Vector4 lodData6; - public Vector4 lodData7; - public uint indirectArgsOffset0; - public uint indirectArgsCount0; - public uint indirectArgsOffset1; - public uint indirectArgsCount1; - public uint indirectArgsOffset2; - public uint indirectArgsCount2; - public uint indirectArgsOffset3; - public uint indirectArgsCount3; - public uint indirectArgsOffset4; - public uint indirectArgsCount4; - public uint indirectArgsOffset5; - public uint indirectArgsCount5; - public uint indirectArgsOffset6; - public uint indirectArgsCount6; - public uint indirectArgsOffset7; - public uint indirectArgsCount7; - - public void SetLods(Vector4[] lodData, uint[] indirectArgsPerLodOffset, uint[] indirectArgsPerLodCount) - { - this.lodData0 = lodCount > 0 ? lodData[0] : Vector4.zero; - this.lodData1 = lodCount > 1 ? lodData[1] : Vector4.zero; - this.lodData2 = lodCount > 2 ? lodData[2] : Vector4.zero; - this.lodData3 = lodCount > 3 ? lodData[3] : Vector4.zero; - this.lodData4 = lodCount > 4 ? lodData[4] : Vector4.zero; - this.lodData5 = lodCount > 5 ? lodData[5] : Vector4.zero; - this.lodData6 = lodCount > 6 ? lodData[6] : Vector4.zero; - this.lodData7 = lodCount > 7 ? lodData[7] : Vector4.zero; - - this.indirectArgsOffset0 = lodCount > 0 ? indirectArgsPerLodOffset[0] : 0; - this.indirectArgsOffset1 = lodCount > 1 ? indirectArgsPerLodOffset[1] : 0; - this.indirectArgsOffset2 = lodCount > 2 ? indirectArgsPerLodOffset[2] : 0; - this.indirectArgsOffset3 = lodCount > 3 ? indirectArgsPerLodOffset[3] : 0; - this.indirectArgsOffset4 = lodCount > 4 ? indirectArgsPerLodOffset[4] : 0; - this.indirectArgsOffset5 = lodCount > 5 ? indirectArgsPerLodOffset[5] : 0; - this.indirectArgsOffset6 = lodCount > 6 ? indirectArgsPerLodOffset[6] : 0; - this.indirectArgsOffset7 = lodCount > 7 ? indirectArgsPerLodOffset[7] : 0; - - this.indirectArgsCount0 = lodCount > 0 ? indirectArgsPerLodCount[0] : 0; - this.indirectArgsCount1 = lodCount > 1 ? indirectArgsPerLodCount[1] : 0; - this.indirectArgsCount2 = lodCount > 2 ? indirectArgsPerLodCount[2] : 0; - this.indirectArgsCount3 = lodCount > 3 ? indirectArgsPerLodCount[3] : 0; - this.indirectArgsCount4 = lodCount > 4 ? indirectArgsPerLodCount[4] : 0; - this.indirectArgsCount5 = lodCount > 5 ? indirectArgsPerLodCount[5] : 0; - this.indirectArgsCount6 = lodCount > 6 ? indirectArgsPerLodCount[6] : 0; - this.indirectArgsCount7 = lodCount > 7 ? indirectArgsPerLodCount[7] : 0; - } - - public PrefabData( - uint batchIndex, - uint indexBufferStartOffset, - uint maxCount, - uint lodCount, - uint fadeLods, - Vector4 densityInDistance, - Vector4[] lodData, - uint[] indirectArgsPerLodOffset, - uint[] indirectArgsPerLodCount - ) - { - this.batchIndex = batchIndex; - this.indexBufferStartOffset = indexBufferStartOffset; - this.maxCount = maxCount; - this.lodCount = lodCount; - this.fadeLods = fadeLods; - this.densityInDistance = densityInDistance; - - this.lodData0 = lodCount > 0 ? lodData[0] : Vector4.zero; - this.lodData1 = lodCount > 1 ? lodData[1] : Vector4.zero; - this.lodData2 = lodCount > 2 ? lodData[2] : Vector4.zero; - this.lodData3 = lodCount > 3 ? lodData[3] : Vector4.zero; - this.lodData4 = lodCount > 4 ? lodData[4] : Vector4.zero; - this.lodData5 = lodCount > 5 ? lodData[5] : Vector4.zero; - this.lodData6 = lodCount > 6 ? lodData[6] : Vector4.zero; - this.lodData7 = lodCount > 7 ? lodData[7] : Vector4.zero; - - this.indirectArgsOffset0 = lodCount > 0 ? indirectArgsPerLodOffset[0] : 0; - this.indirectArgsOffset1 = lodCount > 1 ? indirectArgsPerLodOffset[1] : 0; - this.indirectArgsOffset2 = lodCount > 2 ? indirectArgsPerLodOffset[2] : 0; - this.indirectArgsOffset3 = lodCount > 3 ? indirectArgsPerLodOffset[3] : 0; - this.indirectArgsOffset4 = lodCount > 4 ? indirectArgsPerLodOffset[4] : 0; - this.indirectArgsOffset5 = lodCount > 5 ? indirectArgsPerLodOffset[5] : 0; - this.indirectArgsOffset6 = lodCount > 6 ? indirectArgsPerLodOffset[6] : 0; - this.indirectArgsOffset7 = lodCount > 7 ? indirectArgsPerLodOffset[7] : 0; - - this.indirectArgsCount0 = lodCount > 0 ? indirectArgsPerLodCount[0] : 0; - this.indirectArgsCount1 = lodCount > 1 ? indirectArgsPerLodCount[1] : 0; - this.indirectArgsCount2 = lodCount > 2 ? indirectArgsPerLodCount[2] : 0; - this.indirectArgsCount3 = lodCount > 3 ? indirectArgsPerLodCount[3] : 0; - this.indirectArgsCount4 = lodCount > 4 ? indirectArgsPerLodCount[4] : 0; - this.indirectArgsCount5 = lodCount > 5 ? indirectArgsPerLodCount[5] : 0; - this.indirectArgsCount6 = lodCount > 6 ? indirectArgsPerLodCount[6] : 0; - this.indirectArgsCount7 = lodCount > 7 ? indirectArgsPerLodCount[7] : 0; - } - } -} diff --git a/InstanceMatrix.cs.meta b/InstanceMatrix.cs.meta deleted file mode 100644 index 9ad60f0..0000000 --- a/InstanceMatrix.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 80369a8a9c9a0e64daddf39789fa0f66 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/InstanceRenderSettings.cs b/InstanceRenderSettings.cs deleted file mode 100644 index 4d45fc3..0000000 --- a/InstanceRenderSettings.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public interface IInstanceRenderSettings - { - InstanceRenderSettings Settings { get; } - } - - public struct InstanceRenderSettings - { - int hashCodeCache; - public bool Supported; - public bool Render; - public float RenderDistance; - public float ShadowDistance; - public bool Shadows; - public float DensityInDistance; - public Vector2 DensityInDistanceFalloff; - public static InstanceRenderSettings Default(Camera camera) => new InstanceRenderSettings() - { - Supported = true, - Render = true, - Shadows = true, - RenderDistance = camera.farClipPlane, - ShadowDistance = camera.farClipPlane, - DensityInDistance = 1f, - DensityInDistanceFalloff = Vector2.zero, - }; - - public void Merge(InstanceRenderSettings other) - { - Supported = Supported && other.Supported; - Render = Render && other.Render; - Shadows = Shadows && other.Shadows; - if (RenderDistance > 0.0f && other.RenderDistance > 0.0f) - RenderDistance = Mathf.Min(RenderDistance, other.RenderDistance); - else if (other.RenderDistance > 0.0f) - RenderDistance = other.RenderDistance; - if (ShadowDistance > 0.0f && other.ShadowDistance > 0.0f) - ShadowDistance = Mathf.Min(ShadowDistance, other.ShadowDistance); - else if (other.ShadowDistance > 0.0f) - ShadowDistance = other.ShadowDistance; - DensityInDistance = Mathf.Min(DensityInDistance, other.DensityInDistance); - DensityInDistanceFalloff.x = Mathf.Max(DensityInDistanceFalloff.x, other.DensityInDistanceFalloff.x); - DensityInDistanceFalloff.y = Mathf.Max(DensityInDistanceFalloff.y, other.DensityInDistanceFalloff.y); - - hashCodeCache = HashCode.Combine(Render, Shadows, RenderDistance, ShadowDistance, DensityInDistance, DensityInDistanceFalloff.x, DensityInDistanceFalloff.y); - } - - public override int GetHashCode() - { - if(hashCodeCache == 0 || (Application.isEditor && !Application.isPlaying)) - hashCodeCache = HashCode.Combine(Render, Shadows, RenderDistance, ShadowDistance, DensityInDistance, DensityInDistanceFalloff.x, DensityInDistanceFalloff.y); - - return hashCodeCache; - } - } -} diff --git a/InstanceRenderSettings.cs.meta b/InstanceRenderSettings.cs.meta deleted file mode 100644 index 1e32039..0000000 --- a/InstanceRenderSettings.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ada01dd02c566634092d55b23558e707 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/InstanceStreamer.cs b/InstanceStreamer.cs deleted file mode 100644 index 2ba7f05..0000000 --- a/InstanceStreamer.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System.Collections.Generic; -using System.Threading; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public class InstanceStreamer - { - public struct InstanceInfo - { - public int instanceId; - public int objectId; - } - - public class Cell - { - public float CenterX; - public float CenterZ; - public bool IsLoaded; - public bool IsLoading; - public int inRangeOfAnyCamera; - public List loadedInstances = new List(); - } - - internal static int nextStreamerId = 1; - protected readonly int streamerInstanceId = Interlocked.Increment(ref nextStreamerId); - - public readonly HashSet owners = new HashSet(); - public Dictionary> objectInstanceIds = new Dictionary>(); - public virtual int AddInstance(int objectId, Vector3 pos, Quaternion orientation, float scaleXZ, float scaleY) - { - var instanceId = RendererPool.AddInstance(objectId, pos, orientation, scaleXZ, scaleY); - - if (!objectInstanceIds.ContainsKey(objectId)) - objectInstanceIds.Add(objectId, new HashSet()); - - objectInstanceIds[objectId].Add((uint)instanceId); - - return instanceId; - } - - public virtual void RemoveInstance(int objectId, int instanceId, bool noRemove = false) - { - if (noRemove) - { - RendererPool.RemoveInstance(objectId, instanceId); - } - else - { - if (!objectInstanceIds.ContainsKey(objectId)) - return; - - if (objectInstanceIds[objectId].Remove((uint)instanceId)) - RendererPool.RemoveInstance(objectId, instanceId); - } - } - - public void Clear() - { - foreach (var obj in objectInstanceIds) - { - if (!objectInstanceIds.ContainsKey(obj.Key)) - continue; - - foreach (var id in obj.Value) - { - RemoveInstance(obj.Key, (int)id, true); - } - } - - objectInstanceIds.Clear(); - } - - public virtual void UpdateForCamera(Camera camera, Plane[] planes) - { - - } - - public virtual bool IsInRange(Camera camera, Plane[] planes) - { - return true; - } - - public override int GetHashCode() - { - return streamerInstanceId.GetHashCode();//HashCode.Combine(streamerInstanceId, objectInstanceIds.Count); - } - } -} diff --git a/InstanceStreamer.cs.meta b/InstanceStreamer.cs.meta deleted file mode 100644 index 48e76d1..0000000 --- a/InstanceStreamer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e591f7bae0131d548ab936dcae307d64 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/ObjectData.cs b/ObjectData.cs deleted file mode 100644 index 9974787..0000000 --- a/ObjectData.cs +++ /dev/null @@ -1,266 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.Rendering; - -namespace Assets.ThoMagic.Renderer -{ - public class ObjectData - { - public readonly GameObject GameObject; - public readonly HashSet Owners = new HashSet(); - public readonly uint prefabId; - public float[] LodSizes; - public float[] LodTransitions; - public LOD[] LODs; - public Vector4[] lods = new Vector4[8]; - public uint[] indirectArgsPerLodOffsets = new uint[8]; - public uint[] indirectArgsPerLodCounts = new uint[8]; - public uint[] indirectArgsPerLodWithShadowsCounts = new uint[8]; - public List indirectArgsPerSubmeshOffsets = new List(); - public uint lodCount = 1; - public uint fadeLods = 0; - public uint indirectArgsCount = 1; - public uint count = 0; - public IInstanceRenderSettings Settings; - - public List indirectDrawIndexedArgs = new List(); - - public DrawGroup[] drawGroups; - public DrawGroup[] drawShadowGroups; - - public int contentHashCache; - private bool _isDisposed; - - public ObjectData(GameObject gameObject, IInstanceRenderSettings settings) - { - GameObject = gameObject; - Settings = settings; - - var lodGroup = GameObject.GetComponent(); - - LOD[] lodArray; - - if (lodGroup == null) - lodArray = new LOD[1] - { - new LOD(0.0001f, GameObject.GetComponentsInChildren()) - }; - else - lodArray = lodGroup.GetLODs(); - - LODs = lodArray; - - LodSizes = new float[lodArray.Length]; - LodTransitions = new float[lodArray.Length]; - lodCount = (uint)lodArray.Length; - - if (lodGroup != null && lodGroup.fadeMode == LODFadeMode.CrossFade) - fadeLods = 1; - - for (int index = 0; index < lodArray.Length; ++index) - { - LodSizes[index] = CalculateBoundsForRenderers(lodArray[index].renderers); - LodTransitions[index] = lodArray[index].screenRelativeTransitionHeight; - } - - if (RendererPool.prefabDataFreeSlot.Count > 0) - { - prefabId = RendererPool.prefabDataFreeSlot.Dequeue(); - RendererPool.prefabData[(int)prefabId] = new PrefabData(); - } - else - { - prefabId = (uint)RendererPool.prefabData.Count; - RendererPool.prefabData.Add(new PrefabData()); - } - - RendererPool.rebuildPrefabs = true; - - indirectArgsCount = BuildRenderer(indirectDrawIndexedArgs); - } - - public void Dispose() - { - if (this._isDisposed) - return; - - foreach (var drawGroup in drawGroups) - { - drawGroup?.Dispose(); - } - - foreach (var drawGroup in drawShadowGroups) - { - drawGroup?.Dispose(); - } - - this._isDisposed = true; - } - - private uint BuildRenderer(List indirectDrawIndexedArgs) - { - uint indirectArgsCount = 0; - - drawGroups = new DrawGroup[lodCount]; - drawShadowGroups = new DrawGroup[lodCount]; - - for (int index = 0; index < lodCount; ++index) - { - uint indirectArgsPerLodCount = 0; - - foreach (var renderer in LODs[index].renderers) - { - if (renderer != null) - { - if (renderer is MeshRenderer) - { - var meshFilter = renderer.GetComponent(); - if (meshFilter != null) - { - var sharedMesh = meshFilter.sharedMesh; - var sharedMaterials = renderer.sharedMaterials; - - if (sharedMesh != null && sharedMaterials != null && sharedMaterials.Length == sharedMesh.subMeshCount) - { - if (drawGroups[index] == null) - drawGroups[index] = new DrawGroup(index); - - RenderParams renderParams1 = new RenderParams(); - renderParams1.layer = renderer.gameObject.layer; - renderParams1.receiveShadows = renderer.receiveShadows; - renderParams1.rendererPriority = renderer.rendererPriority; - renderParams1.renderingLayerMask = renderer.renderingLayerMask; - renderParams1.shadowCastingMode = ShadowCastingMode.Off; - renderParams1.reflectionProbeUsage = renderer.reflectionProbeUsage; - renderParams1.motionVectorMode = renderer.motionVectorGenerationMode; - - var count = drawGroups[index].Add(sharedMesh, sharedMaterials, Matrix4x4.identity, //renderer.transform.localToWorldMatrix, - indirectArgsCount, indirectDrawIndexedArgs, in renderParams1); - indirectArgsPerLodCount += count; - - } - } - } - else if (renderer is BillboardRenderer billboardRenderer) - { - if (billboardRenderer.billboard != null && billboardRenderer.billboard.material != null) - { - if (drawGroups[index] == null) - drawGroups[index] = new DrawGroup(index); - - RenderParams renderParams1 = new RenderParams(); - renderParams1.layer = renderer.gameObject.layer; - renderParams1.receiveShadows = renderer.receiveShadows; - renderParams1.rendererPriority = renderer.rendererPriority; - renderParams1.renderingLayerMask = renderer.renderingLayerMask; - renderParams1.shadowCastingMode = ShadowCastingMode.Off; - renderParams1.reflectionProbeUsage = renderer.reflectionProbeUsage; - renderParams1.motionVectorMode = renderer.motionVectorGenerationMode; - - var count = drawGroups[index].Add(billboardRenderer.billboard, billboardRenderer.material, renderer.transform.localToWorldMatrix, - indirectArgsCount, indirectDrawIndexedArgs, in renderParams1); - - indirectArgsPerLodCount += count; - } - } - } - } - - indirectArgsPerLodCounts[index] = indirectArgsPerLodCount; - uint indirectArgsPerLodCountShadowOffset = indirectArgsPerLodCount; - - foreach (var renderer in LODs[index].renderers) - { - if (renderer != null) - { - if (renderer is MeshRenderer) - { - var meshFilter = renderer.GetComponent(); - if (meshFilter != null) - { - var sharedMesh = meshFilter.sharedMesh; - var sharedMaterials = renderer.sharedMaterials; - - if (sharedMesh != null && sharedMaterials != null && sharedMaterials.Length == sharedMesh.subMeshCount) - { - if (renderer.shadowCastingMode > 0) - { - if (drawShadowGroups[index] == null) - drawShadowGroups[index] = new DrawGroup(index); - - var renderParams1 = new RenderParams(); - renderParams1.layer = renderer.gameObject.layer; - renderParams1.shadowCastingMode = ShadowCastingMode.ShadowsOnly; - renderParams1.renderingLayerMask = renderer.renderingLayerMask; - renderParams1.rendererPriority = renderer.rendererPriority; - - indirectArgsPerLodCount += drawShadowGroups[index].Add(sharedMesh, sharedMaterials, Matrix4x4.identity, //renderer.transform.localToWorldMatrix, - indirectArgsPerLodCountShadowOffset + indirectArgsCount, indirectDrawIndexedArgs, in renderParams1); - } - else - { - //indirectArgsPerLodCount += (uint)sharedMesh.subMeshCount; - } - } - } - } - else if (renderer is BillboardRenderer billboardRenderer) - { - if (renderer.shadowCastingMode > 0) - { - if (billboardRenderer.billboard != null && billboardRenderer.billboard.material != null) - { - if (drawShadowGroups[index] == null) - drawShadowGroups[index] = new DrawGroup(index); - - var renderParams1 = new RenderParams(); - renderParams1.layer = renderer.gameObject.layer; - renderParams1.shadowCastingMode = ShadowCastingMode.ShadowsOnly; - renderParams1.renderingLayerMask = renderer.renderingLayerMask; - renderParams1.rendererPriority = renderer.rendererPriority; - - indirectArgsPerLodCount += drawShadowGroups[index].Add(billboardRenderer.billboard, billboardRenderer.material, renderer.transform.localToWorldMatrix, - indirectArgsPerLodCountShadowOffset + indirectArgsCount, indirectDrawIndexedArgs, in renderParams1); - } - else - { - //indirectArgsPerLodCount += 1; - } - } - } - } - } - - indirectArgsPerLodWithShadowsCounts[index] = indirectArgsPerLodCount; - indirectArgsCount += indirectArgsPerLodCount; - } - - return indirectArgsCount; - } - - private static float CalculateBoundsForRenderers(UnityEngine.Renderer[] renderers) - { - Bounds bounds = new Bounds(); - bool first = true; - foreach (var renderer in renderers) - { - if (renderer != null) - { - if (first) - { - bounds = renderer.bounds; - first = false; - } - else - bounds.Encapsulate(renderer.bounds); - } - } - return Mathf.Max(Mathf.Max(bounds.size.x, bounds.size.y), bounds.size.z); - } - - public override int GetHashCode() - { - return GameObject.GetHashCode(); - } - } -} diff --git a/ObjectData.cs.meta b/ObjectData.cs.meta deleted file mode 100644 index 06d6036..0000000 --- a/ObjectData.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 38c29b0618523cb44971f341d53349bf -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/RendererPool.cs b/RendererPool.cs deleted file mode 100644 index e2eb2fd..0000000 --- a/RendererPool.cs +++ /dev/null @@ -1,541 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using Unity.Collections; -using UnityEngine; -using UnityEngine.Rendering; - -namespace Assets.ThoMagic.Renderer -{ - public static class RendererPool - { - public const int RESIZE_COUNT = 100000; - public const int STREAMOUT_SIZE = 10000; - - public static bool isDisposed = true; - private static ComputeShader instancingShader = null; - private static CommandBuffer commandBuffer = null; - private static int uploadInstancesShaderId = 0, resizeInstanceBufferShaderId = 0; - - private static object threadSecurity = new object(); - private static int maxInstanceCount = 0; - private static int instanceUploadCount = 0; - private static readonly Dictionary cameras = new Dictionary(); - public static readonly Dictionary objects = new Dictionary(); - public static readonly Dictionary streamers = new Dictionary(); - public static readonly List objectsList = new List(); - public static readonly List prefabData = new List(); - - public static NativeArray uploadInstancesArray; - - public static readonly Queue uploadInstancesArrayQueue = new Queue(); - - public static readonly Queue prefabDataFreeSlot = new Queue(); - public static readonly Queue instanceBufferFreeSlot = new Queue(); - - public static ComputeBuffer globalUpdateInstanceBuffer = null; - public static ComputeBuffer globalInstanceBuffer = null; - public static ComputeBuffer tempGlobalInstanceBuffer = null; - - private static Vector3 _origin; - private static List _keysToRemove = new List(); - - private static bool _instanceCountChanged; - - public static bool externInstanceCountChanged - { - set - { - if (value == true) - { - foreach (var camera in cameras.Values) - { - camera.instanceCountChanged = value; - } - } - } - } - - public static bool instanceCountChanged - { - set - { - if (value == true && !_instanceCountChanged) - { - _instanceCountChanged = true; - foreach (var camera in cameras.Values) - { - camera.instanceCountChanged = value; - } - } - } - } - - public static bool rebuildPrefabs - { - set - { - if (value == true) - { - foreach (var camera in cameras.Values) - { - camera.rebuildPrefabs = value; - } - } - } - } - - public static void Destroy() - { - if (isDisposed) - return; - - isDisposed = true; - - _keysToRemove.Clear(); - - foreach (KeyValuePair camera in cameras) - { - _keysToRemove.Add(camera.Key); - } - - foreach (int id in _keysToRemove) - RemoveCamera(id); - - maxInstanceCount = 0; - instanceUploadCount = 0; - - uploadInstancesArrayQueue.Clear(); - - globalInstanceBuffer?.Dispose(); - globalInstanceBuffer = null; - globalUpdateInstanceBuffer?.Dispose(); - globalUpdateInstanceBuffer = null; - tempGlobalInstanceBuffer?.Dispose(); - tempGlobalInstanceBuffer = null; - commandBuffer?.Dispose(); - commandBuffer = null; - - prefabDataFreeSlot.Clear(); - instanceBufferFreeSlot.Clear(); - _keysToRemove.Clear(); - InstanceStreamer.nextStreamerId = 1; - CameraRenderer.nextCameraRendererId = 1; - - uploadInstancesArray.Dispose(); - } - - internal static void BuildBuffers() - { - Monitor.Enter(threadSecurity); - bool deleteOldBuffer = false; - //Load shader TODO: (Move this to init?) - if(instancingShader == null) - { - uploadInstancesArray = new NativeArray(STREAMOUT_SIZE, Allocator.Persistent); - - instancingShader = UnityEngine.Object.Instantiate(Resources.Load("ThoMagic Renderer Instancing")); - instancingShader.hideFlags = HideFlags.HideAndDontSave; - uploadInstancesShaderId = instancingShader.FindKernel("Upload_64"); - resizeInstanceBufferShaderId = instancingShader.FindKernel("Resize_64"); - - instancingShader.name = $"ThoMagic Renderer Instancing - RendererPool"; - commandBuffer = new CommandBuffer(); - } - - commandBuffer.Clear(); - - //Are there queued instances ready for upload no current upload is planned? - if (instanceUploadCount == 0 && uploadInstancesArrayQueue.Count > 0) - { - int take = Math.Min(STREAMOUT_SIZE, uploadInstancesArrayQueue.Count); - for (int i = 0; i < take; i++) - { - uploadInstancesArray[instanceUploadCount++] = uploadInstancesArrayQueue.Dequeue(); - } - - instanceCountChanged = true; - } - - //Upload instances - if (_instanceCountChanged && maxInstanceCount > 0) - { - //Create update buffer if null. TODO: Move to init? - if(globalUpdateInstanceBuffer == null) - { - globalUpdateInstanceBuffer = new ComputeBuffer(STREAMOUT_SIZE, InstanceData.Stride, ComputeBufferType.Structured);//, ComputeBufferMode.SubUpdates); - } - - //Resize and copy global instance buffer in gpu - if (globalInstanceBuffer == null || globalInstanceBuffer.count < maxInstanceCount) - { - int nextCount = RESIZE_COUNT * ((maxInstanceCount - 1) / RESIZE_COUNT + 1); - - tempGlobalInstanceBuffer = new ComputeBuffer(nextCount, InstanceData.Stride, ComputeBufferType.Structured); - - tempGlobalInstanceBuffer.name = $"ThoMagic global instance buffer"; - Debug.Log($"Upsized globalInstanceBuffer {nextCount.ToString("N")} / {(nextCount * InstanceData.Stride / 1024 / 1024)}mb"); - - if (globalInstanceBuffer != null) - { - deleteOldBuffer = true; - commandBuffer.SetComputeBufferParam(instancingShader, resizeInstanceBufferShaderId, "tempGlobalInstances", tempGlobalInstanceBuffer); - commandBuffer.SetComputeBufferParam(instancingShader, resizeInstanceBufferShaderId, "globalInstances", globalInstanceBuffer); - commandBuffer.SetComputeIntParam(instancingShader, "_CountResize", globalInstanceBuffer.count); - commandBuffer.DispatchCompute(instancingShader, resizeInstanceBufferShaderId, Mathf.CeilToInt(globalInstanceBuffer.count / 64.0f), 1, 1); - - /*instancingShader.SetBuffer(resizeInstanceBufferShaderId, "tempGlobalInstances", tempGlobalInstanceBuffer); - instancingShader.SetBuffer(resizeInstanceBufferShaderId, "globalInstances", globalInstanceBuffer); - instancingShader.SetInt("_Count", globalInstanceBuffer.count); - instancingShader.Dispatch(resizeInstanceBufferShaderId, Mathf.CeilToInt(globalInstanceBuffer.count / 64.0f), 1, 1); - - globalInstanceBuffer.Dispose(); - globalInstanceBuffer = tempGlobalInstanceBuffer; - tempGlobalInstanceBuffer = null;*/ - } - else - { - globalInstanceBuffer = tempGlobalInstanceBuffer; - //tempGlobalInstanceBuffer = null; - } - } - else - { - tempGlobalInstanceBuffer = globalInstanceBuffer; - } - - //Upload - globalUpdateInstanceBuffer.SetData(uploadInstancesArray); - /*var updateTarget = globalUpdateInstanceBuffer.BeginWrite(0, instanceUploadCount); - NativeArray.Copy(uploadInstancesArray, updateTarget, instanceUploadCount); - globalUpdateInstanceBuffer.EndWrite(instanceUploadCount);*/ - - /*instancingShader.SetBuffer(uploadInstancesShaderId, "globalUploadInstances", globalUpdateInstanceBuffer); - instancingShader.SetBuffer(uploadInstancesShaderId, "globalInstances", globalInstanceBuffer); - instancingShader.SetInt("_Count", instanceUploadCount); - instancingShader.Dispatch(uploadInstancesShaderId, Mathf.CeilToInt(instanceUploadCount / 64.0f), 1, 1);*/ - - commandBuffer.SetComputeBufferParam(instancingShader, uploadInstancesShaderId, "globalUploadInstances", globalUpdateInstanceBuffer); - commandBuffer.SetComputeBufferParam(instancingShader, uploadInstancesShaderId, "globalInstances", tempGlobalInstanceBuffer); - commandBuffer.SetComputeIntParam(instancingShader, "_CountUpload", instanceUploadCount); - commandBuffer.DispatchCompute(instancingShader, uploadInstancesShaderId, Mathf.CeilToInt(instanceUploadCount / 64.0f), 1, 1); - - Graphics.ExecuteCommandBuffer(commandBuffer); - - var fence = Graphics.CreateGraphicsFence(GraphicsFenceType.AsyncQueueSynchronisation, SynchronisationStageFlags.ComputeProcessing); - Graphics.WaitOnAsyncGraphicsFence(fence); - - if(deleteOldBuffer) - { - globalInstanceBuffer.Dispose(); - globalInstanceBuffer = tempGlobalInstanceBuffer; - tempGlobalInstanceBuffer = null; - } - - instanceUploadCount = 0; - _instanceCountChanged = false; - } - - Monitor.Exit(threadSecurity); - } - - #region Instance handling - internal static int AddInstance(int objectId, Vector3 pos, Quaternion orientation, float scaleXZ, float scaleY) - { - if (isDisposed) - return -1; - - Monitor.Enter(threadSecurity); - - var myId = maxInstanceCount; - var objectData = GetObjectData(objectId); - objectData.count++; - - //Take free slot in instance buffer - if (instanceBufferFreeSlot.Count > 0) - { - myId = instanceBufferFreeSlot.Dequeue(); - } - else - { - maxInstanceCount++; - } - - //Directly upload if STREAMOUT_SIZE not reached, otherwise queue for upload - if (instanceUploadCount < STREAMOUT_SIZE && uploadInstancesArrayQueue.Count == 0) - uploadInstancesArray[instanceUploadCount++] = new InstanceData(InstanceData.Add, myId, objectData.prefabId, pos.x, pos.y, pos.z, orientation, scaleXZ, scaleY); - else - uploadInstancesArrayQueue.Enqueue(new InstanceData(InstanceData.Add, myId, objectData.prefabId, pos.x, pos.y, pos.z, orientation, scaleXZ, scaleY)); - - instanceCountChanged = true; - - Monitor.Exit(threadSecurity); - - return myId; - } - - internal static void RemoveInstance(int objectId, int instanceId) - { - if (isDisposed) - return; - - Monitor.Enter(threadSecurity); - - var objectData = GetObjectData(objectId); - objectData.count--; - - //No need to reset instance data because the cullable index is removed, instance data will be reset on reuse. - /*if (instanceUploadCount < STREAMOUT_SIZE && uploadInstancesArrayQueue.Count == 0) - uploadInstancesArray[instanceUploadCount++] = new InstanceData(InstanceData.Delete, instanceId); - else - uploadInstancesArrayQueue.Enqueue(new InstanceData(InstanceData.Delete, instanceId));*/ - - externInstanceCountChanged = true; - //Remember free slot in instance buffer - instanceBufferFreeSlot.Enqueue(instanceId); - - Monitor.Exit(threadSecurity); - } - #endregion - - #region Camera handling - public static IEnumerable GetCameras() - { - return cameras.Values; - } - - public static int RegisterCamera(Camera camera) - { - int num = camera != null ? camera.GetHashCode() : throw new ArgumentNullException(nameof(camera)); - if (!cameras.ContainsKey(num)) - { - CameraRenderer cameraRenderer = new CameraRenderer(camera); - cameraRenderer.SetFloatingOrigin(in _origin); - cameras.Add(num, cameraRenderer); - } - return num; - } - - public static CameraRenderer GetCamera(int cameraId) - { - CameraRenderer cameraRenderer; - return cameras.TryGetValue(cameraId, out cameraRenderer) ? cameraRenderer : null; - } - - public static bool RemoveCamera(int cameraId) - { - CameraRenderer cameraRenderer; - if (!cameras.TryGetValue(cameraId, out cameraRenderer)) - return false; - cameraRenderer?.Dispose(); - return cameras.Remove(cameraId); - } - - public static void RemoveDestroyedCameras() - { - _keysToRemove.Clear(); - - foreach (KeyValuePair camera in cameras) - { - if (camera.Value.Camera == null) - _keysToRemove.Add(camera.Key); - } - - foreach (int id in _keysToRemove) - RemoveCamera(id); - } - #endregion - - #region Object handling - public static int RegisterObject(GameObject gameObject, IInstanceRenderSettings settings, InstanceStreamer source, int ownerHash) - { - int num = gameObject != null ? /*gameObject.GetHashCode()*/ CalculateContentHash(gameObject) : throw new ArgumentNullException(nameof(gameObject)); - - if(!streamers.ContainsKey(ownerHash)) - streamers.Add(ownerHash, source); - - if (!objects.ContainsKey(num)) - { - var obj = new ObjectData(gameObject, settings); - objects.Add(num, obj); - objectsList.Add(obj); - obj.contentHashCache = CalculateContentHash(num, false); - } - else - SetObjectSettings(gameObject, settings); - - if (!objects[num].Owners.Contains(ownerHash)) - objects[num].Owners.Add(ownerHash); - - streamers[ownerHash].owners.Add(num); - - return num; - } - - public static void RemoveObject(int objectId, int ownerHash) - { - if (objects.TryGetValue(objectId, out var objectData)) - { - objectData.Owners.Remove(ownerHash); - if (objectData.Owners.Count == 0) - { - objects.Remove(objectId); - objectsList.Remove(objectData); - prefabDataFreeSlot.Enqueue(objectData.prefabId); - } - } - - if (streamers.TryGetValue(ownerHash, out var streamer)) - { - streamer.owners.Remove(objectId); - - if (streamer.owners.Count == 0) - streamers.Remove(ownerHash); - } - - rebuildPrefabs = true; - } - - public static GameObject GetObject(int objectId) - { - return objects.TryGetValue(objectId, out var objectData) ? objectData.GameObject : null; - } - - public static ObjectData GetObjectData(int objectId) - { - return objects[objectId]; - } - - public static void SetObjectSettings(GameObject prefab, IInstanceRenderSettings instanceRenderSettings) - { - int hashCode = prefab.GetHashCode(); - ObjectData objectData; - if (!objects.TryGetValue(hashCode, out objectData)) - return; - - if ((objectData.Settings == null && instanceRenderSettings != null) - || (objectData.Settings != null && instanceRenderSettings == null) - || instanceRenderSettings.Settings.GetHashCode() != objectData.Settings.Settings.GetHashCode()) - { - objectData.Settings = instanceRenderSettings; - rebuildPrefabs = true; - } - } - - private static int CalculateContentHash(GameObject gameObject) - { - int num = 13; - if (gameObject == null) - return num; - - var lodGroup = gameObject.GetComponent(); - - LOD[] lodArray; - - if (lodGroup == null) - lodArray = new LOD[1] - { - new LOD(0.0001f, gameObject.GetComponentsInChildren()) - }; - else - lodArray = lodGroup.GetLODs(); - - - foreach (LOD loD in lodArray) - num = HashCode.Combine(num, CalculateContentHash(loD)); - - return num; - } - - public static int CalculateContentHash(int objectId, bool reload = false) - { - var obj = objects[objectId]; - - int num = 13; - if (obj.GameObject == null) - return num; - - if (reload) - { - var lodGroup = obj.GameObject.GetComponent(); - - LOD[] lodArray; - - if (lodGroup == null) - lodArray = new LOD[1] - { - new LOD(0.0001f, obj.GameObject.GetComponentsInChildren()) - }; - else - lodArray = lodGroup.GetLODs(); - - obj.LODs = lodArray; - } - - foreach (LOD loD in obj.LODs) - num = HashCode.Combine(num, CalculateContentHash(loD)); - - return num; - } - - private static int CalculateContentHash(LOD lod) - { - int num = 13; - if (lod.renderers != null) - { - foreach (var renderer in lod.renderers) - { - if (renderer == null) - { - num = HashCode.Combine(num, 13); - } - else - { - MeshFilter component = renderer.GetComponent(); - - num = HashCode.Combine(HashCode.Combine( - num, - component == null || component.sharedMesh == null ? 13 : component.sharedMesh.GetHashCode(), - renderer.shadowCastingMode.GetHashCode(), - CalculateContentHash(renderer.sharedMaterials), - renderer.motionVectorGenerationMode.GetHashCode(), - renderer.receiveShadows.GetHashCode(), - renderer.rendererPriority.GetHashCode(), - renderer.renderingLayerMask.GetHashCode()), - renderer.gameObject.layer.GetHashCode(), - renderer.gameObject.transform.localPosition.GetHashCode(), - lod.screenRelativeTransitionHeight.GetHashCode()); - } - } - } - return num; - } - - private static int CalculateContentHash(Material[] materials) - { - int num = 13; - if (materials != null) - { - foreach (Material material in materials) - num = HashCode.Combine(num, - material != null ? material.GetHashCode() : 13); - } - return num; - } - - public static bool ContentHashChanged(int objectId) - { - if (!objects.ContainsKey(objectId)) - return false; - - return objects[objectId].contentHashCache != CalculateContentHash(objectId, true); - } - - internal static void Initialize() - { - isDisposed = false; - BuildBuffers(); - } - #endregion - } -} diff --git a/RendererPool.cs.meta b/RendererPool.cs.meta deleted file mode 100644 index bbdf6c6..0000000 --- a/RendererPool.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 76aaa879e050ed44ba26642123a3d6fe -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/RendererUtility.cs b/RendererUtility.cs deleted file mode 100644 index a023180..0000000 --- a/RendererUtility.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public class RendererUtility - { - public static GameObject GetPrototypeToRender(DetailPrototype prototype) => prototype.prototype == null ? null : - prototype.prototype.transform.root.gameObject; - - public static bool SupportsProceduralInstancing(GameObject gameObject) - { - foreach (var componentsInChild in gameObject.GetComponentsInChildren()) - { - foreach (var sharedMaterial in componentsInChild.sharedMaterials) - { - if (sharedMaterial != null && sharedMaterial.shader != null && !RendererUtility.SupportsProceduralInstancing(sharedMaterial)) - return false; - } - } - return true; - } - - public static bool SupportsProceduralInstancing(Material material) - { - if (material == null) - throw new ArgumentNullException(nameof(material)); - if (material.shader == null) - throw new ArgumentNullException("material.shader"); - return true; - } - - public static bool IsSupportedByUnity(DetailPrototype prototype) => !prototype.usePrototypeMesh || prototype.prototype == null || prototype.prototype.GetComponent() == null; - - public static GameObject GetSupportedPlaceholder(DetailPrototype prototype) => IsSupportedByUnity(prototype) ? prototype.prototype : GetSupportedPlaceholder(prototype.prototype); - - public static GameObject GetSupportedPlaceholder(GameObject prototype) - { - if (prototype == null) - return prototype; - LODGroup component = prototype.GetComponent(); - if (component == null) - return prototype; - foreach (LOD loD in component.GetLODs()) - { - foreach (UnityEngine.Renderer renderer in loD.renderers) - { - if (renderer != null) - return renderer.gameObject; - } - } - return null; - } - } -} diff --git a/RendererUtility.cs.meta b/RendererUtility.cs.meta deleted file mode 100644 index b2311b0..0000000 --- a/RendererUtility.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8948a91a0e0980f428ba7d5418d8dc6f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Resources.meta b/Resources.meta deleted file mode 100644 index fe08a86..0000000 --- a/Resources.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 66cad6ae64c1463448771e8e1325a51c -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Resources/ThoMagic Instanced Position.shadersubgraph b/Resources/ThoMagic Instanced Position.shadersubgraph deleted file mode 100644 index e7cb95b..0000000 --- a/Resources/ThoMagic Instanced Position.shadersubgraph +++ /dev/null @@ -1,438 +0,0 @@ -{ - "m_SGVersion": 3, - "m_Type": "UnityEditor.ShaderGraph.GraphData", - "m_ObjectId": "4ea35b44b3fe4b25a7cb4e39a4b9b407", - "m_Properties": [], - "m_Keywords": [ - { - "m_Id": "9ba4f485275c4fc9b2f1ce82a79369c4" - } - ], - "m_Dropdowns": [], - "m_CategoryData": [ - { - "m_Id": "480708220ad2491387a14ef84b7fe431" - } - ], - "m_Nodes": [ - { - "m_Id": "281b26d889224fc487a79fa8214bd0b1" - }, - { - "m_Id": "c5119037ba0c48fbba1bb84ead9a5adb" - }, - { - "m_Id": "4e57f58cc3d24bf1b53cde5e846cbd31" - }, - { - "m_Id": "304803996acc4ca999953697d05a2515" - } - ], - "m_GroupDatas": [], - "m_StickyNoteDatas": [], - "m_Edges": [ - { - "m_OutputSlot": { - "m_Node": { - "m_Id": "304803996acc4ca999953697d05a2515" - }, - "m_SlotId": 1 - }, - "m_InputSlot": { - "m_Node": { - "m_Id": "281b26d889224fc487a79fa8214bd0b1" - }, - "m_SlotId": 1 - } - }, - { - "m_OutputSlot": { - "m_Node": { - "m_Id": "4e57f58cc3d24bf1b53cde5e846cbd31" - }, - "m_SlotId": 1 - }, - "m_InputSlot": { - "m_Node": { - "m_Id": "304803996acc4ca999953697d05a2515" - }, - "m_SlotId": 0 - } - }, - { - "m_OutputSlot": { - "m_Node": { - "m_Id": "c5119037ba0c48fbba1bb84ead9a5adb" - }, - "m_SlotId": 0 - }, - "m_InputSlot": { - "m_Node": { - "m_Id": "4e57f58cc3d24bf1b53cde5e846cbd31" - }, - "m_SlotId": 0 - } - } - ], - "m_VertexContext": { - "m_Position": { - "x": 0.0, - "y": 0.0 - }, - "m_Blocks": [] - }, - "m_FragmentContext": { - "m_Position": { - "x": 0.0, - "y": 0.0 - }, - "m_Blocks": [] - }, - "m_PreviewData": { - "serializedMesh": { - "m_SerializedMesh": "{\"mesh\":{\"instanceID\":0}}", - "m_Guid": "" - }, - "preventRotation": false - }, - "m_Path": "Sub Graphs", - "m_GraphPrecision": 1, - "m_PreviewMode": 2, - "m_OutputNode": { - "m_Id": "281b26d889224fc487a79fa8214bd0b1" - }, - "m_ActiveTargets": [] -} - -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", - "m_ObjectId": "13e38f92c90c4e709dc150f29929c84a", - "m_Id": 0, - "m_DisplayName": "Out", - "m_SlotType": 1, - "m_Hidden": false, - "m_ShaderOutputName": "Out", - "m_StageCapability": 3, - "m_Value": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "m_DefaultValue": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "m_Labels": [] -} - -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.SubGraphOutputNode", - "m_ObjectId": "281b26d889224fc487a79fa8214bd0b1", - "m_Group": { - "m_Id": "" - }, - "m_Name": "Output", - "m_DrawState": { - "m_Expanded": true, - "m_Position": { - "serializedVersion": "2", - "x": 25.00006866455078, - "y": -310.0, - "width": 96.99996185302735, - "height": 77.00001525878906 - } - }, - "m_Slots": [ - { - "m_Id": "aca287a71573483789d5dcb380daa40c" - } - ], - "synonyms": [], - "m_Precision": 0, - "m_PreviewExpanded": true, - "m_DismissedVersion": 0, - "m_PreviewMode": 0, - "m_CustomColors": { - "m_SerializableColors": [] - }, - "IsFirstSlotValid": true -} - -{ - "m_SGVersion": 1, - "m_Type": "UnityEditor.ShaderGraph.CustomFunctionNode", - "m_ObjectId": "304803996acc4ca999953697d05a2515", - "m_Group": { - "m_Id": "" - }, - "m_Name": "IncludeThoMagicRenderer (Custom Function)", - "m_DrawState": { - "m_Expanded": true, - "m_Position": { - "serializedVersion": "2", - "x": -330.0, - "y": -310.0, - "width": 304.0, - "height": 94.0 - } - }, - "m_Slots": [ - { - "m_Id": "59dd7ed4b8b14695ab4443b7b89ab9df" - }, - { - "m_Id": "79b2dd99d8ea4726856c03ea82ede95b" - } - ], - "synonyms": [ - "code", - "HLSL" - ], - "m_Precision": 0, - "m_PreviewExpanded": false, - "m_DismissedVersion": 0, - "m_PreviewMode": 0, - "m_CustomColors": { - "m_SerializableColors": [] - }, - "m_SourceType": 0, - "m_FunctionName": "IncludeThoMagicRenderer", - "m_FunctionSource": "678dff042fe9c004cb7522c2233af44d", - "m_FunctionBody": "Enter function body here..." -} - -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", - "m_ObjectId": "45a92477b6a7449c9c4d29eac6f7f4c1", - "m_Id": 0, - "m_DisplayName": "In", - "m_SlotType": 0, - "m_Hidden": false, - "m_ShaderOutputName": "In", - "m_StageCapability": 3, - "m_Value": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "m_DefaultValue": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "m_Labels": [] -} - -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.CategoryData", - "m_ObjectId": "480708220ad2491387a14ef84b7fe431", - "m_Name": "", - "m_ChildObjectList": [ - { - "m_Id": "9ba4f485275c4fc9b2f1ce82a79369c4" - } - ] -} - -{ - "m_SGVersion": 1, - "m_Type": "UnityEditor.ShaderGraph.CustomFunctionNode", - "m_ObjectId": "4e57f58cc3d24bf1b53cde5e846cbd31", - "m_Group": { - "m_Id": "" - }, - "m_Name": "SetupThoMagicRenderer (Custom Function)", - "m_DrawState": { - "m_Expanded": true, - "m_Position": { - "serializedVersion": "2", - "x": -694.0, - "y": -310.0000305175781, - "width": 296.9999694824219, - "height": 94.00001525878906 - } - }, - "m_Slots": [ - { - "m_Id": "45a92477b6a7449c9c4d29eac6f7f4c1" - }, - { - "m_Id": "ca8752373fc04409ae302adfc1808024" - } - ], - "synonyms": [ - "code", - "HLSL" - ], - "m_Precision": 0, - "m_PreviewExpanded": false, - "m_DismissedVersion": 0, - "m_PreviewMode": 0, - "m_CustomColors": { - "m_SerializableColors": [] - }, - "m_SourceType": 1, - "m_FunctionName": "SetupThoMagicRenderer", - "m_FunctionSource": "06018a56d442f704f82b130cdeaf74ef", - "m_FunctionBody": "Out = In;\n#pragma instancing_options procedural:SetupThoMagicRenderer\r\r\n" -} - -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", - "m_ObjectId": "59dd7ed4b8b14695ab4443b7b89ab9df", - "m_Id": 0, - "m_DisplayName": "In", - "m_SlotType": 0, - "m_Hidden": false, - "m_ShaderOutputName": "In", - "m_StageCapability": 3, - "m_Value": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "m_DefaultValue": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "m_Labels": [] -} - -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", - "m_ObjectId": "79b2dd99d8ea4726856c03ea82ede95b", - "m_Id": 1, - "m_DisplayName": "Out", - "m_SlotType": 1, - "m_Hidden": false, - "m_ShaderOutputName": "Out", - "m_StageCapability": 3, - "m_Value": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "m_DefaultValue": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "m_Labels": [] -} - -{ - "m_SGVersion": 1, - "m_Type": "UnityEditor.ShaderGraph.ShaderKeyword", - "m_ObjectId": "9ba4f485275c4fc9b2f1ce82a79369c4", - "m_Guid": { - "m_GuidSerialized": "019818f3-0f1b-49f3-8508-39d308ae3731" - }, - "m_Name": "PROCEDURAL_INSTANCING_ON", - "m_DefaultRefNameVersion": 1, - "m_RefNameGeneratedByDisplayName": "PROCEDURAL_INSTANCING_ON", - "m_DefaultReferenceName": "_PROCEDURAL_INSTANCING_ON", - "m_OverrideReferenceName": "", - "m_GeneratePropertyBlock": true, - "m_UseCustomSlotLabel": false, - "m_CustomSlotLabel": "", - "m_DismissedVersion": 0, - "m_KeywordType": 0, - "m_KeywordDefinition": 0, - "m_KeywordScope": 1, - "m_KeywordStages": 63, - "m_Entries": [], - "m_Value": 1, - "m_IsEditable": true -} - -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", - "m_ObjectId": "aca287a71573483789d5dcb380daa40c", - "m_Id": 1, - "m_DisplayName": "Position", - "m_SlotType": 0, - "m_Hidden": false, - "m_ShaderOutputName": "Position", - "m_StageCapability": 3, - "m_Value": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "m_DefaultValue": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "m_Labels": [] -} - -{ - "m_SGVersion": 1, - "m_Type": "UnityEditor.ShaderGraph.PositionNode", - "m_ObjectId": "c5119037ba0c48fbba1bb84ead9a5adb", - "m_Group": { - "m_Id": "" - }, - "m_Name": "Position", - "m_DrawState": { - "m_Expanded": true, - "m_Position": { - "serializedVersion": "2", - "x": -952.0, - "y": -310.0, - "width": 206.0, - "height": 131.00003051757813 - } - }, - "m_Slots": [ - { - "m_Id": "13e38f92c90c4e709dc150f29929c84a" - } - ], - "synonyms": [ - "location" - ], - "m_Precision": 1, - "m_PreviewExpanded": false, - "m_DismissedVersion": 0, - "m_PreviewMode": 2, - "m_CustomColors": { - "m_SerializableColors": [] - }, - "m_Space": 0, - "m_PositionSource": 0 -} - -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", - "m_ObjectId": "ca8752373fc04409ae302adfc1808024", - "m_Id": 1, - "m_DisplayName": "Out", - "m_SlotType": 1, - "m_Hidden": false, - "m_ShaderOutputName": "Out", - "m_StageCapability": 3, - "m_Value": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "m_DefaultValue": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "m_Labels": [] -} - diff --git a/Resources/ThoMagic Instanced Position.shadersubgraph.meta b/Resources/ThoMagic Instanced Position.shadersubgraph.meta deleted file mode 100644 index bffaa82..0000000 --- a/Resources/ThoMagic Instanced Position.shadersubgraph.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: 9ac8f6239a1b8d94a9aa0ba4ece1f714 -ScriptedImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 2 - userData: - assetBundleName: - assetBundleVariant: - script: {fileID: 11500000, guid: 60072b568d64c40a485e0fc55012dc9f, type: 3} diff --git a/Resources/ThoMagic Renderer Instancing.compute b/Resources/ThoMagic Renderer Instancing.compute deleted file mode 100644 index 6810df1..0000000 --- a/Resources/ThoMagic Renderer Instancing.compute +++ /dev/null @@ -1,418 +0,0 @@ -#pragma kernel Cull_32 GROUPS=32 -#pragma kernel Cull_64 GROUPS=64 -#pragma kernel Cull_128 GROUPS=128 -#pragma kernel Cull_256 GROUPS=256 -#pragma kernel Cull_512 GROUPS=512 -#pragma kernel Cull_1024 GROUPS=1024 - -#pragma kernel Clear_32 GROUPS=32 -#pragma kernel Clear_64 GROUPS=64 -#pragma kernel Clear_128 GROUPS=128 -#pragma kernel Clear_256 GROUPS=256 -#pragma kernel Clear_512 GROUPS=512 -#pragma kernel Clear_1024 GROUPS=1024 - -#pragma kernel Upload_32 GROUPS=32 -#pragma kernel Upload_64 GROUPS=64 -#pragma kernel Upload_128 GROUPS=128 -#pragma kernel Upload_256 GROUPS=256 -#pragma kernel Upload_512 GROUPS=512 -#pragma kernel Upload_1024 GROUPS=1024 - -#pragma kernel Resize_32 GROUPS=32 -#pragma kernel Resize_64 GROUPS=64 -#pragma kernel Resize_128 GROUPS=128 -#pragma kernel Resize_256 GROUPS=256 -#pragma kernel Resize_512 GROUPS=512 -#pragma kernel Resize_1024 GROUPS=1024 - -#include "UnityCG.cginc" - -struct InstanceData -{ - // position.xyz : position.xyz - // position.w : rotation.x - // scale.x : scale.xz - // scale.y : scale.y - // scale.zw : rotation.yz - float4 position; - float4 scale; - uint prefabId; - //Used to stream out new instances - int uploadAction; - int uploadId; - int age; -}; - -struct PrefabData -{ - uint batchIndex; - uint indexBufferStartOffset; - uint maxCount; - uint lodCount; - uint fadeLods;//Todo: Use Bitwise and save memory? - //x: density threshold, y: density range start, z: density range length, w: shadow distance - float4 densityInDistance; - float4 lodData[8]; - uint2 indirectArgsIndexAndCountPerLod[8]; -}; - -struct InstanceMeta -{ - uint visibleLod; - uint fadeOutLod; - float fadeAnim; - - // The scale of the instance can be adjusted - float Scale; -}; - -StructuredBuffer globalUploadInstances; -RWStructuredBuffer globalInstances; -RWStructuredBuffer tempGlobalInstances; -StructuredBuffer perCamPrefabs; -StructuredBuffer perCamCullableIndexesBuffer; -RWStructuredBuffer perCamMeta; -RWStructuredBuffer perCamIndirectArgumentsBuffer; -RWStructuredBuffer perCamVisibleIndexesBuffer; -RWStructuredBuffer perCamShadowVisibleIndexesBuffer; - -uint _CountClear; -uint _CountUpload; -uint _CountResize; -uint _CountCull; -float3 _CameraPosition; -float3 _ShadowDirection; -float4 _FrustumPlanes[6]; - -// Plane equation: {(a, b, c) = N, d = -dot(N, P)}. -// Returns the distance from the plane to the point 'p' along the normal. -// Positive -> in front (above), negative -> behind (below). -float DistanceFromPlane(float3 p, float4 plane) -{ - return dot(float4(p, 1.0), plane); -} - -// Returns 'true' if the object is outside of the frustum. -// 'size' is the (negative) size of the object's bounds. -bool CullFrustum(float3 center, float size, float4 frustumPlanes[6], int numPlanes) -{ - bool outside = false; - [unroll(6)] - for (int i = 0; i < numPlanes; i++) - outside = outside || DistanceFromPlane(center, frustumPlanes[i]) < size; - - return outside; -} - -// Returns 'true' if the shadow of the object is outside of the frustum. -// 'size' is the (negative) size of the object's bounds. -bool CullShadowFrustum(float3 center, float size, float3 lightDirection, float4 frustumPlanes[6], int numPlanes) -{ - bool outside = false; - [unroll(6)] - for (int i = 0; i < numPlanes; i++) - outside = outside || max(DistanceFromPlane(center, frustumPlanes[i]), DistanceFromPlane(center + lightDirection, frustumPlanes[i])) < size; - - return outside; -} - -// Calculates the adjusted scale of the instance based on the "Density in Distance" -// setting. Instances get scaled down if the density is reduced. -float ReduceDensityScale(inout InstanceData instance, float4 densityInDistance, float distance) -{ - float rangeStart = densityInDistance.y; - float rangeLength = densityInDistance.z; - - // Calculate a dither pattern with range [0..1] - float dither = frac(dot(float3((instance.position.xz) * 16.0f, 0), uint3(2, 7, 23) / 17.0f)); - - float densityThreshold = 1 - densityInDistance.x; - float distanceNormalized = (distance - rangeStart) / (rangeLength * dither + 0.001f); - - if(dither > densityInDistance.x && distanceNormalized > 0) - return 1 - distanceNormalized; - else - return 1; -} - -void ClearArgumentsBuffer(uint3 id : SV_DispatchThreadID) -{ - if (id.x >= _CountClear) - return; - - uint indirectArgsCountOffset = id.x * 5 + 1; - perCamIndirectArgumentsBuffer[indirectArgsCountOffset] = 0; -} - -void Upload (uint3 id : SV_DispatchThreadID) -{ - if (id.x >= _CountUpload) - return; - - InstanceData instance = globalUploadInstances[id.x]; - - if (instance.uploadAction == 1) - { - globalInstances[instance.uploadId] = instance; - } -} - -void Resize(uint3 id : SV_DispatchThreadID) -{ - if (id.x >= _CountResize) - return; - - tempGlobalInstances[id.x] = globalInstances[id.x]; -} - -void Cull (uint3 id : SV_DispatchThreadID) -{ - if(id.x >= _CountCull) - return; - - uint instanceIndex = perCamCullableIndexesBuffer[id.x]; - InstanceData instance = globalInstances[instanceIndex]; - InstanceMeta meta = perCamMeta[instanceIndex]; - PrefabData prefab = perCamPrefabs[instance.prefabId]; - - if (instance.age == 0) - { - meta = (InstanceMeta)0; - globalInstances[instanceIndex].age = 1; - } - - uint lodCount = prefab.lodCount; - - uint visibleLod = 0; - uint visibleShadowLod = 0; - uint batchOffset = 0; - uint indirectArgsCount = 0; - uint indirectArgsCountOffset = 0; - uint i = 0; - uint u = 0; - - // Calculate active LOD - float dist = distance(instance.position.xyz, _CameraPosition.xyz); - - [unroll(8)] - for(i=0; i < lodCount; i++) - { - float maxDist = - i < lodCount - 1 ? prefab.lodData[i].y * instance.scale.y : prefab.lodData[i].y; - - if(dist >= prefab.lodData[i].x * instance.scale.y && dist < maxDist) - { - visibleLod = i + 1; - if (dist < prefab.densityInDistance.w)//prefab.densityInDistance.w = max shadow distance - visibleShadowLod = i + 1; - } - } - - // Reduce density - if(prefab.densityInDistance.x < 1) - { - meta.Scale = ReduceDensityScale(instance, prefab.densityInDistance, dist); - if(meta.Scale < 0.3) - { - visibleLod = 0; - visibleShadowLod = 0; - } - } - else - { - meta.Scale = 1; - } - - // Frustum Culling - if(visibleLod > 0) - { - float size = -prefab.lodData[visibleLod - 1].z * length(instance.scale.xy); - const int planeCount = 5; // Do not test near/far planes - if (CullFrustum(instance.position.xyz, size, _FrustumPlanes, planeCount)) - { - // Setting active LOD to 0 culls the instance. The LODs start from 1. - visibleLod = 0; - - if (CullShadowFrustum( - instance.position.xyz, - size, - _ShadowDirection * 1000, - _FrustumPlanes, - planeCount)) - { - visibleShadowLod = 0; - } - } - } - - uint visibleCount = 0; - - if (visibleLod > 0) - { - batchOffset = prefab.indexBufferStartOffset + ((visibleLod - 1) * prefab.maxCount); - indirectArgsCount = prefab.indirectArgsIndexAndCountPerLod[visibleLod - 1].y; - indirectArgsCountOffset = prefab.indirectArgsIndexAndCountPerLod[visibleLod - 1].x + 1; - - InterlockedAdd(perCamIndirectArgumentsBuffer[indirectArgsCountOffset], 1, visibleCount); - - for (i = 1, u = 5; i < indirectArgsCount; i++, u += 5) - { - InterlockedAdd(perCamIndirectArgumentsBuffer[indirectArgsCountOffset + u], 1); - } - - perCamVisibleIndexesBuffer[batchOffset + visibleCount] = instanceIndex; - - if (meta.visibleLod != visibleLod && meta.visibleLod > 0 && prefab.fadeLods > 0) - { - meta.fadeOutLod = meta.visibleLod; - meta.fadeAnim = 1; - } - } - - if (visibleShadowLod > 0) - { - batchOffset = prefab.indexBufferStartOffset + ((visibleShadowLod - 1) * prefab.maxCount); - indirectArgsCount = prefab.indirectArgsIndexAndCountPerLod[visibleShadowLod - 1].y; - indirectArgsCountOffset = indirectArgsCount * 5 + prefab.indirectArgsIndexAndCountPerLod[visibleShadowLod - 1].x + 1; - - InterlockedAdd(perCamIndirectArgumentsBuffer[indirectArgsCountOffset], 1, visibleCount); - - for (i = 1, u = 5; i < indirectArgsCount; i++, u += 5) - { - InterlockedAdd(perCamIndirectArgumentsBuffer[indirectArgsCountOffset + u], 1); - } - - perCamShadowVisibleIndexesBuffer[batchOffset + visibleCount] = instanceIndex; - - if (meta.visibleLod != visibleShadowLod && meta.visibleLod > 0 && prefab.fadeLods > 0) - { - meta.fadeOutLod = meta.visibleLod; - meta.fadeAnim = 1; - } - } - - if (meta.fadeOutLod == 0) - meta.fadeAnim = 0; - - if (meta.fadeAnim == 0) - meta.fadeOutLod = 0; - - //Add lod cross fade - if (meta.fadeAnim > 0 && meta.fadeOutLod > 0) - { - meta.fadeAnim = max(0, meta.fadeAnim - unity_DeltaTime.z); - - //Normal - if (visibleLod > 0 && meta.fadeAnim > 0) - { - batchOffset = prefab.indexBufferStartOffset + ((meta.fadeOutLod - 1) * prefab.maxCount); - indirectArgsCount = prefab.indirectArgsIndexAndCountPerLod[meta.fadeOutLod - 1].y; - indirectArgsCountOffset = prefab.indirectArgsIndexAndCountPerLod[meta.fadeOutLod - 1].x + 1; - - InterlockedAdd(perCamIndirectArgumentsBuffer[indirectArgsCountOffset], 1, visibleCount); - - for (i = 1, u = 5; i < indirectArgsCount; i++, u += 5) - { - InterlockedAdd(perCamIndirectArgumentsBuffer[indirectArgsCountOffset + u], 1); - } - - perCamVisibleIndexesBuffer[batchOffset + visibleCount] = instanceIndex; - } - - //Shadow - if (visibleShadowLod > 0 && meta.fadeAnim > 0) - { - batchOffset = prefab.indexBufferStartOffset + ((meta.fadeOutLod - 1) * prefab.maxCount); - indirectArgsCount = prefab.indirectArgsIndexAndCountPerLod[meta.fadeOutLod - 1].y; - indirectArgsCountOffset = indirectArgsCount * 5 + prefab.indirectArgsIndexAndCountPerLod[meta.fadeOutLod - 1].x + 1; - - InterlockedAdd(perCamIndirectArgumentsBuffer[indirectArgsCountOffset], 1, visibleCount); - - for (i = 1, u = 5; i < indirectArgsCount; i++, u += 5) - { - InterlockedAdd(perCamIndirectArgumentsBuffer[indirectArgsCountOffset + u], 1); - } - - perCamShadowVisibleIndexesBuffer[batchOffset + visibleCount] = instanceIndex; - } - } - - meta.visibleLod = max(visibleLod, visibleShadowLod); - perCamMeta[instanceIndex] = meta; -} - -[numthreads(GROUPS,1,1)] -void Cull_32(uint3 id : SV_DispatchThreadID) { Cull(id); } - -[numthreads(GROUPS,1,1)] -void Cull_64(uint3 id : SV_DispatchThreadID) { Cull(id); } - -[numthreads(GROUPS,1,1)] -void Cull_128(uint3 id : SV_DispatchThreadID) { Cull(id); } - -[numthreads(GROUPS,1,1)] -void Cull_256(uint3 id : SV_DispatchThreadID) { Cull(id); } - -[numthreads(GROUPS,1,1)] -void Cull_512(uint3 id : SV_DispatchThreadID) { Cull(id); } - -[numthreads(GROUPS,1,1)] -void Cull_1024(uint3 id : SV_DispatchThreadID) { Cull(id); } - -[numthreads(GROUPS, 1, 1)] -void Clear_32(uint3 id : SV_DispatchThreadID) { ClearArgumentsBuffer(id); } - -[numthreads(GROUPS, 1, 1)] -void Clear_64(uint3 id : SV_DispatchThreadID) { ClearArgumentsBuffer(id); } - -[numthreads(GROUPS, 1, 1)] -void Clear_128(uint3 id : SV_DispatchThreadID) { ClearArgumentsBuffer(id); } - -[numthreads(GROUPS, 1, 1)] -void Clear_256(uint3 id : SV_DispatchThreadID) { ClearArgumentsBuffer(id); } - -[numthreads(GROUPS, 1, 1)] -void Clear_512(uint3 id : SV_DispatchThreadID) { ClearArgumentsBuffer(id); } - -[numthreads(GROUPS, 1, 1)] -void Clear_1024(uint3 id : SV_DispatchThreadID) { ClearArgumentsBuffer(id); } - -[numthreads(GROUPS, 1, 1)] -void Upload_32(uint3 id : SV_DispatchThreadID) { Upload(id); } - -[numthreads(GROUPS, 1, 1)] -void Upload_64(uint3 id : SV_DispatchThreadID) { Upload(id); } - -[numthreads(GROUPS, 1, 1)] -void Upload_128(uint3 id : SV_DispatchThreadID) { Upload(id); } - -[numthreads(GROUPS, 1, 1)] -void Upload_256(uint3 id : SV_DispatchThreadID) { Upload(id); } - -[numthreads(GROUPS, 1, 1)] -void Upload_512(uint3 id : SV_DispatchThreadID) { Upload(id); } - -[numthreads(GROUPS, 1, 1)] -void Upload_1024(uint3 id : SV_DispatchThreadID) { Upload(id); } - - -[numthreads(GROUPS, 1, 1)] -void Resize_32(uint3 id : SV_DispatchThreadID) { Resize(id); } - -[numthreads(GROUPS, 1, 1)] -void Resize_64(uint3 id : SV_DispatchThreadID) { Resize(id); } - -[numthreads(GROUPS, 1, 1)] -void Resize_128(uint3 id : SV_DispatchThreadID) { Resize(id); } - -[numthreads(GROUPS, 1, 1)] -void Resize_256(uint3 id : SV_DispatchThreadID) { Resize(id); } - -[numthreads(GROUPS, 1, 1)] -void Resize_512(uint3 id : SV_DispatchThreadID) { Resize(id); } - -[numthreads(GROUPS, 1, 1)] -void Resize_1024(uint3 id : SV_DispatchThreadID) { Resize(id); } - - diff --git a/Resources/ThoMagic Renderer Instancing.compute.meta b/Resources/ThoMagic Renderer Instancing.compute.meta deleted file mode 100644 index 10b3d3b..0000000 --- a/Resources/ThoMagic Renderer Instancing.compute.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 4a840c1c229294d4996e80608a899881 -ComputeShaderImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Resources/ThoMagicRenderer.cginc b/Resources/ThoMagicRenderer.cginc deleted file mode 100644 index 465a771..0000000 --- a/Resources/ThoMagicRenderer.cginc +++ /dev/null @@ -1,136 +0,0 @@ -#pragma multi_compile _LOD_FADE_CROSSFADE - -#ifndef NODE_THOMAGIC_RENDERER_INCLUDED -#define NODE_THOMAGIC_RENDERER_INCLUDED - -#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED - - -#define UNITY_INDIRECT_DRAW_ARGS IndirectDrawIndexedArgs -#include "UnityIndirect.cginc" - -#define Use_Macro_UNITY_MATRIX_M_instead_of_unity_ObjectToWorld unity_ObjectToWorld -#define Use_Macro_UNITY_MATRIX_I_M_instead_of_unity_WorldToObject unity_WorldToObject - -#define LOD_FADE_CROSSFADE - -struct InstanceData -{ - // position.xyz : position.xyz - // position.w : rotation.x - // scale.x : scale.xz - // scale.y : scale.y - // scale.zw : rotation.yz - float4 position; - float4 scale; - uint prefabId; - int3 padding; -}; - -struct InstanceMeta -{ - uint visibleLod; - uint fadeOutLod; - float fadeAnim; - - // The scale of the instance can be adjusted - float Scale; -}; - -StructuredBuffer trInstances; -StructuredBuffer trPerCamVisibleIndexesBuffer; -StructuredBuffer trPerCamMeta; - -float4x4 trInstanceMatrix; -int trLodNr; - -float4x4 TRS(float3 t, float4 r, float3 s) -{ - float4x4 result = (float4x4)0; - result[0][0] = (1.0f - 2.0f * (r.y * r.y + r.z * r.z)) * s.x; - result[1][0] = (r.x * r.y + r.z * r.w) * s.x * 2.0f; - result[2][0] = (r.x * r.z - r.y * r.w) * s.x * 2.0f; - result[3][0] = 0.0f; - result[0][1] = (r.x * r.y - r.z * r.w) * s.y * 2.0f; - result[1][1] = (1.0f - 2.0f * (r.x * r.x + r.z * r.z)) * s.y; - result[2][1] = (r.y * r.z + r.x * r.w) * s.y * 2.0f; - result[3][1] = 0.0f; - result[0][2] = (r.x * r.z + r.y * r.w) * s.z * 2.0f; - result[1][2] = (r.y * r.z - r.x * r.w) * s.z * 2.0f; - result[2][2] = (1.0f - 2.0f * (r.x * r.x + r.y * r.y)) * s.z; - result[3][2] = 0.0f; - result[0][3] = t.x; - result[1][3] = t.y; - result[2][3] = t.z; - result[3][3] = 1.0f; - return result; -} - -void DecompressInstanceMatrix(inout float4x4 m, InstanceData instanceData, InstanceMeta meta) -{ - float3 position = instanceData.position.xyz; - float4 rotation = float4(instanceData.position.w, instanceData.scale.zw, 0); - float3 scale = instanceData.scale.xyx * meta.Scale; - rotation.w = sqrt(1.0 - rotation.x * rotation.x - rotation.y * rotation.y - rotation.z * rotation.z); - m = TRS(position, rotation, scale); -} - -float4x4 inverse(float4x4 input) -{ -#define minor(a,b,c) determinant(float3x3(input.a, input.b, input.c)) - - float4x4 cofactors = float4x4( - minor(_22_23_24, _32_33_34, _42_43_44), - -minor(_21_23_24, _31_33_34, _41_43_44), - minor(_21_22_24, _31_32_34, _41_42_44), - -minor(_21_22_23, _31_32_33, _41_42_43), - - -minor(_12_13_14, _32_33_34, _42_43_44), - minor(_11_13_14, _31_33_34, _41_43_44), - -minor(_11_12_14, _31_32_34, _41_42_44), - minor(_11_12_13, _31_32_33, _41_42_43), - - minor(_12_13_14, _22_23_24, _42_43_44), - -minor(_11_13_14, _21_23_24, _41_43_44), - minor(_11_12_14, _21_22_24, _41_42_44), - -minor(_11_12_13, _21_22_23, _41_42_43), - - -minor(_12_13_14, _22_23_24, _32_33_34), - minor(_11_13_14, _21_23_24, _31_33_34), - -minor(_11_12_14, _21_22_24, _31_32_34), - minor(_11_12_13, _21_22_23, _31_32_33) - ); -#undef minor - return transpose(cofactors) / determinant(input); -} -#endif - -void SetupThoMagicRenderer() -{ -#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED - InitIndirectDrawArgs(0); - - uint instanceID = GetIndirectInstanceID_Base(unity_InstanceID); - uint instanceIndex = trPerCamVisibleIndexesBuffer[instanceID]; - InstanceMeta meta = trPerCamMeta[instanceIndex]; - DecompressInstanceMatrix(unity_ObjectToWorld, trInstances[instanceIndex], meta); - unity_ObjectToWorld = mul(unity_ObjectToWorld, trInstanceMatrix); - unity_WorldToObject = inverse(unity_ObjectToWorld); - - if (meta.visibleLod == trLodNr) - unity_LODFade.x = (1.0f - meta.fadeAnim); - else - unity_LODFade.x = -(1.0f - meta.fadeAnim); - - // {% hd %} - // Instances are static so the previous matrix is the same as the current one. - // These matrices are required for correct motion vectors in HDRP. -#if SHADERPASS == SHADERPASS_MOTION_VECTORS && defined(SHADERPASS_CS_HLSL) - unity_MatrixPreviousM = unity_ObjectToWorld; - unity_MatrixPreviousMI = unity_WorldToObject; -#endif - // {% endhd %} -#endif -} - -#endif \ No newline at end of file diff --git a/Resources/ThoMagicRenderer.cginc.meta b/Resources/ThoMagicRenderer.cginc.meta deleted file mode 100644 index c7c8a50..0000000 --- a/Resources/ThoMagicRenderer.cginc.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 7fe5ed120e85ccf499d429b359f89173 -ShaderIncludeImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Resources/ThoMagicRenderer.hlsl b/Resources/ThoMagicRenderer.hlsl deleted file mode 100644 index 3e0e6d6..0000000 --- a/Resources/ThoMagicRenderer.hlsl +++ /dev/null @@ -1,9 +0,0 @@ -#include "ThoMagicRenderer.cginc" - -#ifndef THOMAGICRENDERERSETUP_INClUDED -#define THOMAGICRENDERERSETUP_INClUDED -void IncludeThoMagicRenderer_float(float3 In, out float3 Out) -{ - Out = In; -} -#endif \ No newline at end of file diff --git a/Resources/ThoMagicRenderer.hlsl.meta b/Resources/ThoMagicRenderer.hlsl.meta deleted file mode 100644 index f0ab5f9..0000000 --- a/Resources/ThoMagicRenderer.hlsl.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 678dff042fe9c004cb7522c2233af44d -ShaderIncludeImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/SceneRenderSettings.cs b/SceneRenderSettings.cs deleted file mode 100644 index 50a0046..0000000 --- a/SceneRenderSettings.cs +++ /dev/null @@ -1,11 +0,0 @@ -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public struct SceneRenderSettings - { - public bool HasMainLight; - public bool HasMainLightShadows; - public Vector3 MainLightDirection; - } -} diff --git a/SceneRenderSettings.cs.meta b/SceneRenderSettings.cs.meta deleted file mode 100644 index c696fc0..0000000 --- a/SceneRenderSettings.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8c1bc4c6b611d9d439d0f03feecc4e71 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/TerrainDetailRenderer.cs b/TerrainDetailRenderer.cs deleted file mode 100644 index d1347bd..0000000 --- a/TerrainDetailRenderer.cs +++ /dev/null @@ -1,299 +0,0 @@ -using System; -using System.Collections.Generic; -#if UNITY_EDITOR -using UnityEditor; -#endif -using UnityEngine; -using UnityEngine.Rendering; - -namespace Assets.ThoMagic.Renderer -{ - /// - /// Adds a tree renderer and grass renderer to a terrain object. - /// - [AddComponentMenu("ThoMagic/Detail Renderer")] - [ExecuteAlways] - [DisallowMultipleComponent] - public class TerrainDetailRenderer : MonoBehaviour - { - /// - /// This event is called after this detail renderer is initialized. - /// - public event EventHandler Initialized; - - /// - /// The terrain object. - /// - public Terrain terrain; - /// - /// Cached terrain data. - /// - public TerrainData terrainData; - - [NonSerialized] - private bool isInitialized = false; - - [NonSerialized] - private TreeRenderer treeRenderer; - [NonSerialized] - private GrassRenderer grassRenderer; - - [NonSerialized] - private Vector3 lastPosition; - - [NonSerialized] - private Quaternion lastOrientation; - - [NonSerialized] - private Vector3 lastScale; - - - [Tooltip("Should ThoMagic Renderer automatically refresh the terrain data if the terrain was modified at runtime? If disabled, use Refresh() from a custom script to refresh the terrain data.")] - [SerializeField] - private bool _autoRefreshTerrainAtRuntime = true; - - [Tooltip("Should the default grass and tree rendering of Unity be enabled when ThoMagic Renderer is disabled?")] - [SerializeField] - private bool _enableUnityRendererWhenDisabled = true; - - [Tooltip("Delay the initialization of ThoMagic Renderer until the first LateUpdate event")] - [SerializeField] - private bool _delayInitialize = true; - - /// - /// If true and the terrain is changed at runtime the renderers are updated automaticly. - /// If needed you can also refresh them manually by calling Refresh(). - /// - public bool AutoRefreshTerrainAtRuntime - { - get => _autoRefreshTerrainAtRuntime; - set => _autoRefreshTerrainAtRuntime = value; - } - - /// - /// Enable the default unity renderer for trees and grass if this component gets disabled? - /// - public bool EnableUnityRendererWhenDisabled - { - get => _enableUnityRendererWhenDisabled; - set => _enableUnityRendererWhenDisabled = value; - } - - private bool HasValidTerrainData() - { - TerrainData terrainData = GetTerrainData(); - return terrainData != null && terrainData.detailResolution > 0 && terrainData.alphamapResolution > 0 && terrainData.heightmapResolution > 0 && terrainData.size != Vector3.zero; - } - - private bool CanInitialize() => isActiveAndEnabled && HasValidTerrainData(); - - private void Awake() - { - //Load resources - - } - - private void OnEnable() - { - if (_delayInitialize && Application.isPlaying || (isInitialized || !CanInitialize())) - return; - Initialize(); - } - - private void Start() - { - if (_delayInitialize && Application.isPlaying || (isInitialized || !CanInitialize())) - return; - Initialize(); - } - - private void OnDisable() - { - if (!isInitialized) - return; - Destroy(); - } - - private void OnDestroy() - { - if (!isInitialized) - return; - Destroy(); - } - - //Called by unity on terrain changes - public void OnTerrainChanged(TerrainChangedFlags flags) - { - if (!isInitialized || !AutoRefreshTerrainAtRuntime) - return; - Refresh(flags); - } - - /// - /// Used to refresh the renderers. - /// - /// The terrain changes - public void Refresh(TerrainChangedFlags flags) - { - //if a detail object has to be replaced by a placeholder return immediatly, as a second OnTerrainChanged will be called - //cause the detail protoypes where changed on the terrain. - if(flags.HasFlag(TerrainChangedFlags.FlushEverythingImmediately) && ReplaceUnsupportedDetails() && AutoRefreshTerrainAtRuntime) - return; - - treeRenderer?.OnTerrainChanged(flags); - grassRenderer?.OnTerrainChanged(flags); - } - - /// - /// Replace unsupported grass details with placeholders. - /// - /// True if a placeholder was created, otherwise false. - private bool ReplaceUnsupportedDetails() - { - bool flag = false; - DetailPrototype[] detailPrototypes = terrainData.detailPrototypes; - for (int index = 0; index < detailPrototypes.Length; ++index) - { - if (!RendererUtility.IsSupportedByUnity(detailPrototypes[index])) - { - GameObject supportedPlaceholder = RendererUtility.GetSupportedPlaceholder(detailPrototypes[index]); - if (supportedPlaceholder != detailPrototypes[index].prototype) - { - detailPrototypes[index].prototype = supportedPlaceholder; - flag = true; - } - } - } - if (flag) - terrainData.detailPrototypes = detailPrototypes; - return flag; - } - - private void DisableUnityRenderer() - { - if (terrain == null) - return; - terrain.drawTreesAndFoliage = false; - } - - private void RestoreUnityRenderer() - { - if (terrain == null || !EnableUnityRendererWhenDisabled) - return; - terrain.drawTreesAndFoliage = true; - } - - private void Initialize() - { - if (isInitialized) - return; - - DisableUnityRenderer(); - GetTerrainData(); - ReplaceUnsupportedDetails(); - - if (treeRenderer == null) - treeRenderer = new TreeRenderer(terrain); - - treeRenderer?.Load(); - - if (grassRenderer == null) - grassRenderer = new GrassRenderer(terrain); - - grassRenderer?.Load(); - - if (Initialized != null) - Initialized(this, this); - - isInitialized = true; - - lastPosition = terrain.transform.position; - lastOrientation = terrain.transform.rotation; - lastScale = terrain.transform.localScale; - -#if UNITY_EDITOR - SceneView.lastActiveSceneView?.Repaint(); - - RenderPipelineManager.endContextRendering -= OnBeginContextRendering; - RenderPipelineManager.endContextRendering += OnBeginContextRendering; -#endif - } - -#if UNITY_EDITOR - private void OnBeginContextRendering( - ScriptableRenderContext context, - List cameras) - { - LateUpdate(); - } -#endif - private void LateUpdate() - { - if (!isInitialized && CanInitialize()) - Initialize(); - - if (!isInitialized) - return; - - //TODO: We are currently not supporting a floating offset, - //so if the terrain moves we refresh/rebuild everything, - //which is expenisve. If possible we should switch to a - //floating offset. - if (terrain.transform.position != lastPosition || - terrain.transform.localScale != lastScale || - terrain.transform.rotation != lastOrientation) - { - lastPosition = terrain.transform.position; - lastOrientation = terrain.transform.rotation; - lastScale = terrain.transform.localScale; - Refresh(TerrainChangedFlags.FlushEverythingImmediately); - } - - treeRenderer?.LateUpdate(); - grassRenderer?.LateUpdate(); - } - - private void Destroy() - { - if (!isInitialized) - return; - - treeRenderer?.Destroy(); - treeRenderer = null; - grassRenderer?.Destroy(); - grassRenderer = null; - - RestoreUnityRenderer(); - isInitialized = false; - -#if UNITY_EDITOR - RenderPipelineManager.endContextRendering -= OnBeginContextRendering; -#endif - } - - private TerrainData GetTerrainData() - { - if (terrain == null) - terrain = GetComponent(); - terrainData = terrain != null ? terrain.terrainData : null; - return terrainData; - } - - private Bounds CalculateBounds(GameObject obj) - { - var meshRenderer = obj.GetComponentsInChildren(); - - Bounds b = new Bounds(); - if (meshRenderer.Length > 0) - { - b = new Bounds(meshRenderer[0].bounds.center, meshRenderer[0].bounds.size); - for (int r = 1; r < meshRenderer.Length; r++) - { - b.Encapsulate(meshRenderer[r].bounds); - } - } - - return b; - } - } -} diff --git a/TerrainDetailRenderer.cs.meta b/TerrainDetailRenderer.cs.meta deleted file mode 100644 index 004d510..0000000 --- a/TerrainDetailRenderer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 533ab6e6ebf6be745ae7f02dc1922e05 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/ThoMagicRendererObjectSettings.cs b/ThoMagicRendererObjectSettings.cs deleted file mode 100644 index b79c772..0000000 --- a/ThoMagicRendererObjectSettings.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - [AddComponentMenu("ThoMagic/Renderer Object Settings")] - [DisallowMultipleComponent] - [ExecuteAlways] - public class ThoMagicRendererObjectSettings : MonoBehaviour, IInstanceRenderSettings - { - [SerializeField] - private bool _render = true; - [SerializeField] - private bool _overrideRendering; - [Min(0.0f)] - [SerializeField] - private float _renderDistance = 150; - [SerializeField] - private bool _overrideRenderDistance; - [SerializeField] - private bool _renderShadows = true; - [SerializeField] - private bool _overrideRenderShadows; - [Min(0.0f)] - [SerializeField] - private float _shadowDistance = 80; - [SerializeField] - private bool _overrideShadowDistance; - [Range(0.01f, 1f)] - [SerializeField] - private float _densityInDistance = 0.125f; - [SerializeField] - private bool _overrideDensityInDistance; - [SerializeField] - private Vector2 _densityInDistanceFalloff = new Vector2(0.08f, 0.0075f); - [SerializeField] - private bool _overrideDensityInDistanceFalloff; - private ReflectionProbe _reflectionProbe; - - public InstanceRenderSettings Settings => new InstanceRenderSettings() - { - Supported = true, - Render = !this._overrideRendering || this._render, - RenderDistance = this._overrideRenderDistance ? this._renderDistance : -1f, - ShadowDistance = this._overrideShadowDistance ? this._shadowDistance : -1f, - Shadows = !this._overrideRenderShadows || this._renderShadows, - DensityInDistance = this._overrideDensityInDistance ? this._densityInDistance : 1f, - DensityInDistanceFalloff = this._overrideDensityInDistanceFalloff ? this._densityInDistanceFalloff : Vector2.zero - }; - - public bool? Render - { - get => !this._overrideRendering ? new bool?() : new bool?(this._render); - set - { - this._overrideRendering = value.HasValue; - if (!value.HasValue) - return; - this._render = value.Value; - } - } - - public float? RenderDistance - { - get => !this._overrideRenderDistance ? new float?() : new float?(this._renderDistance); - set - { - this._overrideRenderDistance = value.HasValue; - if (!value.HasValue) - return; - this._renderDistance = value.Value; - } - } - - public bool? RenderShadows - { - get => !this._overrideRenderShadows ? new bool?() : new bool?(this._renderShadows); - set - { - this._overrideRenderShadows = value.HasValue; - if (!value.HasValue) - return; - this._renderShadows = value.Value; - } - } - - public float? ShadowDistance - { - get => !this._overrideShadowDistance ? new float?() : new float?(this._shadowDistance); - set - { - this._overrideShadowDistance = value.HasValue; - if (!value.HasValue) - return; - this._shadowDistance = value.Value; - } - } - - public float? DensityInDistance - { - get => !this._overrideDensityInDistance ? new float?() : new float?(this._densityInDistance); - set - { - this._overrideDensityInDistance = value.HasValue; - if (!value.HasValue) - return; - this._densityInDistance = value.Value; - } - } - - public Vector2? DensityInDistanceFalloff - { - get => !this._overrideDensityInDistanceFalloff ? new Vector2?() : new Vector2?(this._densityInDistanceFalloff); - set - { - this._overrideDensityInDistanceFalloff = value.HasValue; - if (!value.HasValue) - return; - this._densityInDistanceFalloff = value.Value; - } - } - - private void OnEnable() - { - _reflectionProbe = GetComponent(); - if (_reflectionProbe == null) - return; - CameraRenderer.ReflectionProbeSettings = this; - } - - private void OnDisable() - { - if (_reflectionProbe == null || CameraRenderer.ReflectionProbeSettings as ThoMagicRendererObjectSettings != this) - return; - CameraRenderer.ReflectionProbeSettings = null; - } - - private void OnValidate() - { - if (_reflectionProbe == null || !Application.isEditor) - return; - this._reflectionProbe.RenderProbe(); - } - } -} diff --git a/ThoMagicRendererObjectSettings.cs.meta b/ThoMagicRendererObjectSettings.cs.meta deleted file mode 100644 index 44f96db..0000000 --- a/ThoMagicRendererObjectSettings.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c2a37bd5b745b59448b6bc6c1ff5f09c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/TileObjectRenderer.cs b/TileObjectRenderer.cs deleted file mode 100644 index 5fe2f59..0000000 --- a/TileObjectRenderer.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Collections.Generic; -#if UNITY_EDITOR -using UnityEditor; -#endif -using UnityEngine; -using UnityEngine.Rendering; - -namespace Assets.ThoMagic.Renderer -{ - [ExecuteAlways] - [DisallowMultipleComponent] - public class TileObjectRenderer : MonoBehaviour - { - /// - /// This event is called after this detail renderer is initialized. - /// - public event EventHandler Initialized; - - [NonSerialized] - private bool isInitialized = false; - - - [Tooltip("Delay the initialization of ThoMagic Renderer until the first LateUpdate event")] - [SerializeField] - private bool _delayInitialize = true; - - private bool CanInitialize() => isActiveAndEnabled; - - [NonSerialized] - private TileObjectStreamer tileObjectStreamer; - - private void Awake() - { - //Load resources - - } - - private void OnEnable() - { - if (_delayInitialize && Application.isPlaying || (isInitialized || !CanInitialize())) - return; - Initialize(); - } - - private void Start() - { - if (_delayInitialize && Application.isPlaying || (isInitialized || !CanInitialize())) - return; - Initialize(); - } - - private void OnDisable() - { - if (!isInitialized) - return; - Destroy(); - } - - private void OnDestroy() - { - if (!isInitialized) - return; - Destroy(); - } - - private void Initialize() - { - if (isInitialized) - return; - - if (tileObjectStreamer == null) - tileObjectStreamer = new TileObjectStreamer(gameObject); - - tileObjectStreamer?.Load(); - - if (Initialized != null) - Initialized(this, this); - - isInitialized = true; - -#if UNITY_EDITOR - SceneView.lastActiveSceneView?.Repaint(); - - RenderPipelineManager.endContextRendering -= OnBeginContextRendering; - RenderPipelineManager.endContextRendering += OnBeginContextRendering; -#endif - } - -#if UNITY_EDITOR - private void OnBeginContextRendering( - ScriptableRenderContext context, - List cameras) - { - //LateUpdate(); - } -#endif - private void LateUpdate() - { - if (!isInitialized && CanInitialize()) - Initialize(); - - if (!isInitialized) - return; - - tileObjectStreamer?.LateUpdate(); - } - - private void Destroy() - { - if (!isInitialized) - return; - - try - { - tileObjectStreamer?.Destroy(); - } - catch { } - tileObjectStreamer = null; - - isInitialized = false; - -#if UNITY_EDITOR - RenderPipelineManager.endContextRendering -= OnBeginContextRendering; -#endif - } - - private void OnTransformChildrenChanged() - { - tileObjectStreamer?.MarkDirty(); - } - } -} diff --git a/TileObjectRenderer.cs.meta b/TileObjectRenderer.cs.meta deleted file mode 100644 index 2b5fd3b..0000000 --- a/TileObjectRenderer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 365a0b5496e0c71438e4b4a0b232aca6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/TileObjectStreamer.cs b/TileObjectStreamer.cs deleted file mode 100644 index 382b1e5..0000000 --- a/TileObjectStreamer.cs +++ /dev/null @@ -1,246 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public class TileObjectStreamer : InstanceStreamer - { - private readonly GameObject objectContainer; - private Bounds worldBounds; - private float maxDistance; - - private Dictionary registeredPrefabs = new Dictionary(); - private Dictionary instanceToGameObject = new Dictionary(); - - private bool isDirty = true; - - public TileObjectStreamer(GameObject objectContainer) - : base() - { - this.objectContainer = objectContainer; - } - - public void Recycle() - { - Clear(); - - int ownerHash = GetHashCode(); - foreach (var item in registeredPrefabs) - { - RendererPool.RemoveObject(item.Value, ownerHash); - } - - foreach (var item in instanceToGameObject) - { - var mrs = item.Value.gameObject.GetComponentsInChildren(); - foreach(var mr in mrs) - mr.enabled = true; - - var lod = item.Value.gameObject.GetComponent(); - if (lod != null) - lod.enabled = true; - - } - - registeredPrefabs.Clear(); - instanceToGameObject.Clear(); - } - - public void Load() - { - isDirty = false; - - Recycle(); - - worldBounds.SetMinMax(Vector3.zero, Vector3.zero); - - registeredPrefabs.Clear(); - instanceToGameObject.Clear(); - - int ownerHash = GetHashCode(); - - foreach (Transform child in objectContainer.transform) - { - var hash = CalculateHash(child.gameObject); - - if(hash != 0) - { - int objectId; - - if (registeredPrefabs.ContainsKey(hash)) - { - objectId = registeredPrefabs[hash]; - } - else - { - var settings = GetSettingsOrDefault(child.gameObject); - objectId = RendererPool.RegisterObject(child.gameObject, settings, this, ownerHash); - registeredPrefabs.Add(hash, objectId); - if (settings.Settings.RenderDistance == 0) - maxDistance = float.MaxValue; - - maxDistance = Mathf.Max(maxDistance, settings.Settings.RenderDistance); - } - - var mrs = child.gameObject.GetComponentsInChildren(); - Bounds bounds = new Bounds(); - bool first = true; - foreach (var mr in mrs) - { - if (first) - { - bounds = mr.bounds; - } - else - { - bounds.Encapsulate(mr.bounds); - } - - mr.enabled = false; - } - - var lod = child.gameObject.GetComponent(); - if(lod != null) - lod.enabled = false; - - var instanceId = AddInstance(objectId, new Vector3(child.position.x, child.position.y, child.position.z), child.rotation, child.lossyScale.x, child.lossyScale.z); - - instanceToGameObject.Add(instanceId, child.gameObject); - if (instanceToGameObject.Count == 1) - worldBounds = bounds; - else - worldBounds.Encapsulate(bounds); - } - } - } - - private IInstanceRenderSettings GetSettingsOrDefault(GameObject gameObject) - { - IInstanceRenderSettings instanceRenderSettings; - return gameObject.TryGetComponent(out instanceRenderSettings) ? instanceRenderSettings : new DefaultRenderSettings(); - } - - private int CalculateHash(GameObject gameObject) - { - int num = 13; - - var lodGroup = gameObject.GetComponent(); - - LOD[] lodArray; - - if (lodGroup == null) - { - var mr = gameObject.GetComponentsInChildren(); - - if (mr == null) - return 0; - - lodArray = new LOD[1] - { - new LOD(0.0001f, mr) - }; - } - else - lodArray = lodGroup.GetLODs(); - - - foreach (var loD in lodArray) - num = HashCode.Combine(num, CalcualteContentHash(loD)); - - return num; - } - - private int CalcualteContentHash(LOD lod) - { - int num = 13; - if (lod.renderers != null) - { - foreach (var renderer in lod.renderers) - { - if (renderer == null) - { - num = HashCode.Combine(num, 13); - } - else - { - MeshFilter component = renderer.GetComponent(); - - num = HashCode.Combine(HashCode.Combine( - num, - component == null || component.sharedMesh == null ? 13 : component.sharedMesh.GetHashCode(), - renderer.shadowCastingMode.GetHashCode(), - CalculateContentHash(renderer.sharedMaterials), - renderer.motionVectorGenerationMode.GetHashCode(), - renderer.receiveShadows.GetHashCode(), - renderer.rendererPriority.GetHashCode(), - renderer.renderingLayerMask.GetHashCode()), - renderer.gameObject.layer.GetHashCode(), - lod.screenRelativeTransitionHeight.GetHashCode()); - } - } - } - - return num; - } - - private int CalculateContentHash(Material[] materials) - { - int num = 13; - if (materials != null) - { - foreach (Material material in materials) - num = HashCode.Combine(num, - material != null ? material.GetHashCode() : 13); - } - return num; - } - - public override bool IsInRange(Camera referenceCamera, Plane[] planes) - { - var eyePos = referenceCamera.transform.position; - - if ((eyePos - worldBounds.ClosestPoint(eyePos)).magnitude <= Mathf.Min(referenceCamera.farClipPlane, maxDistance)) - return true; - - return false; - } - - public override int GetHashCode() - { - return streamerInstanceId.GetHashCode();//HashCode.Combine(streamerInstanceId, objectInstanceIds.Count); - } - - public void Destroy() - { - Recycle(); - } - - public void LateUpdate() - { - if (isDirty) - { - Load(); - } - } - - public void MarkDirty() - { - isDirty = true; - } - - private class DefaultRenderSettings : IInstanceRenderSettings - { - public InstanceRenderSettings Settings => new InstanceRenderSettings() - { - Render = true, - DensityInDistance = 1f, - DensityInDistanceFalloff = Vector2.zero, - RenderDistance = 0.0f, - ShadowDistance = 0.0f, - Shadows = true, - Supported = true - }; - } - } -} diff --git a/TileObjectStreamer.cs.meta b/TileObjectStreamer.cs.meta deleted file mode 100644 index 74bddf7..0000000 --- a/TileObjectStreamer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 14d63a559cc9211479181fed32a2a5c0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/TreeRenderer.cs b/TreeRenderer.cs deleted file mode 100644 index 534f74f..0000000 --- a/TreeRenderer.cs +++ /dev/null @@ -1,272 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public class TreeRenderer : TreeStreamer - { - private Terrain terrain; - private TerrainData terrainData; - private List treePrototypesRegistered; - private Dictionary treeToInstances = new Dictionary(); - private HashSet touchedTrees = new HashSet(); - private bool isDirty; - private float maxTreeDistance = 0; - - class TreeInfo - { - internal int instanceId; - internal int objectId; - } - - public TreeRenderer(Terrain terrain) - : base(terrain) - { - this.terrain = terrain; - terrainData = terrain.terrainData; - } - - public void LateUpdate() - { - if (isDirty) - { - isDirty = false; - ApplyChanges(); - } - - if (Application.isEditor && !Application.isPlaying) - RebuildChangedPrototypes(); - } - - int GetTreeTerrainInstanceId(TreeInstance tree) - { - return HashCode.Combine(tree.position.x, tree.position.y, tree.position.z, tree.rotation, tree.widthScale, tree.heightScale, tree.prototypeIndex); - } - - public void ApplyChanges() - { - Vector3 size = terrainData.size; - Vector3 offset = terrain.transform.position; - - var treeInstances = terrainData.treeInstances; - touchedTrees.Clear(); - foreach (var treeInstance in treeInstances) - { - if (treeInstance.widthScale == 0) - continue; - - var treeTerrainInstanceId = GetTreeTerrainInstanceId(treeInstance); - if (!treeToInstances.ContainsKey(treeTerrainInstanceId)) - { - var treeId = treePrototypesRegistered[treeInstance.prototypeIndex]; - var prefab = RendererPool.GetObject(treeId); - var quaternion = Quaternion.Euler(0.0f, 57.2957801818848f * treeInstance.rotation, 0.0f); - var instanceId = AddInstance(treeId, new Vector3(treeInstance.position.x * size.x, - treeInstance.position.y * size.y, - treeInstance.position.z * size.z) + offset, quaternion, - treeInstance.widthScale * prefab.transform.localScale.x, - treeInstance.heightScale * prefab.transform.localScale.y - ); - treeToInstances[treeTerrainInstanceId] = new TreeInfo { instanceId = instanceId, objectId = treeId }; - touchedTrees.Add(treeTerrainInstanceId); - } - else - { - touchedTrees.Add(treeTerrainInstanceId); - } - } - - foreach(var treeTerrainInstanceId in treeToInstances.Keys.ToList()) - { - if(!touchedTrees.Contains(treeTerrainInstanceId)) - { - RemoveInstance(treeToInstances[treeTerrainInstanceId].objectId, treeToInstances[treeTerrainInstanceId].instanceId); - treeToInstances.Remove(treeTerrainInstanceId); - } - } - - Build(maxTreeDistance); - } - - public void Load() - { - maxTreeDistance = 0; - - Vector3 size = terrainData.size; - Vector3 offset = terrain.transform.position; - - Recycle(); - - int ownerHash = GetHashCode(); - - if (treePrototypesRegistered == null) - treePrototypesRegistered = new List(); - - var treePrototypes = terrainData.treePrototypes; - if(treePrototypes.Length > 0) - { - foreach(var treePrototype in treePrototypes) - { - if(treePrototype.prefab != null) - { - var settings = GetSettingsOrDefault(treePrototype.prefab); - treePrototypesRegistered.Add(RendererPool.RegisterObject(treePrototype.prefab, settings, this, ownerHash)); - - if (settings.Settings.RenderDistance == 0) - maxTreeDistance = float.MaxValue; - - if(settings.Settings.RenderDistance > maxTreeDistance) - maxTreeDistance = settings.Settings.RenderDistance; - } - } - - var treeInstances = terrainData.treeInstances; - foreach (var treeInstance in treeInstances) - { - var treeTerrainInstanceId = GetTreeTerrainInstanceId(treeInstance); - var treeId = treePrototypesRegistered[treeInstance.prototypeIndex]; - var prefab = RendererPool.GetObject(treeId); - var quaternion = Quaternion.Euler(0.0f, 57.2957801818848f * treeInstance.rotation, 0.0f); - var instanceId = AddInstance(treeId, new Vector3(treeInstance.position.x * size.x, - treeInstance.position.y * size.y, - treeInstance.position.z * size.z) + offset, quaternion, - treeInstance.widthScale * prefab.transform.localScale.x, - treeInstance.heightScale * prefab.transform.localScale.y); - treeToInstances[treeTerrainInstanceId] = new TreeInfo { instanceId = instanceId, objectId = treeId }; - } - } - - Build(maxTreeDistance); - } - - private void Recycle() - { - if (treePrototypesRegistered == null) - return; - - treeToInstances.Clear(); - - Clear(); - - var ownerHash = GetHashCode(); - - for (int index = 0; index < treePrototypesRegistered.Count; ++index) - { - var objectId = treePrototypesRegistered[index]; - RendererPool.RemoveObject(objectId, ownerHash); - } - - treePrototypesRegistered.Clear(); - } - - private void RebuildChangedPrototypes() - { - TreePrototype[] treePrototypes = terrainData.treePrototypes; - if (treePrototypes.Length != treePrototypesRegistered.Count) - { - Load(); - } - else - { - int ownerHash = GetHashCode(); - maxTreeDistance = 0; - for (int index = 0; index < treePrototypesRegistered.Count; ++index) - { - int treeId = treePrototypesRegistered[index]; - - GameObject prefab = treePrototypes[index].prefab; - GameObject gameObject = RendererPool.GetObject(treeId); - if (prefab != gameObject) - { - RendererPool.RemoveObject(treeId, ownerHash); - if (prefab != null) - { - var settings = GetSettingsOrDefault(prefab); - - if (settings.Settings.RenderDistance == 0) - maxTreeDistance = float.MaxValue; - - if (settings.Settings.RenderDistance > maxTreeDistance) - maxTreeDistance = settings.Settings.RenderDistance; - - treePrototypesRegistered[index] = RendererPool.RegisterObject(prefab, settings, this, ownerHash); - } - } - else if (RendererPool.ContentHashChanged(treeId)) - { - RendererPool.RemoveObject(treeId, ownerHash); - if (prefab != null) - { - var settings = GetSettingsOrDefault(prefab); - - if (settings.Settings.RenderDistance == 0) - maxTreeDistance = float.MaxValue; - - if (settings.Settings.RenderDistance > maxTreeDistance) - maxTreeDistance = settings.Settings.RenderDistance; - - treePrototypesRegistered[index] = RendererPool.RegisterObject(prefab, settings, this, ownerHash); - } - } - else if (prefab != null) - { - var settings = GetSettingsOrDefault(prefab); - - if (settings.Settings.RenderDistance == 0) - maxTreeDistance = float.MaxValue; - - if (settings.Settings.RenderDistance > maxTreeDistance) - maxTreeDistance = settings.Settings.RenderDistance; - - RendererPool.SetObjectSettings(prefab, settings); - } - } - } - } - - public void Destroy() - { - Recycle(); - } - - public void OnTerrainChanged(TerrainChangedFlags flags) - { - if(flags.HasFlag(TerrainChangedFlags.TreeInstances)) - isDirty = true; - else if (flags.HasFlag(TerrainChangedFlags.DelayedHeightmapUpdate)) - isDirty = true; - else if (flags.HasFlag(TerrainChangedFlags.Heightmap)) - isDirty = true; - else if (flags.HasFlag(TerrainChangedFlags.HeightmapResolution)) - isDirty = true; - else if (flags.HasFlag(TerrainChangedFlags.Holes)) - isDirty = true; - else if (flags.HasFlag(TerrainChangedFlags.DelayedHolesUpdate)) - isDirty = true; - else if (flags.HasFlag(TerrainChangedFlags.FlushEverythingImmediately)) - isDirty = true; - } - - private IInstanceRenderSettings GetSettingsOrDefault(GameObject gameObject) - { - IInstanceRenderSettings instanceRenderSettings; - return gameObject.TryGetComponent(out instanceRenderSettings) ? instanceRenderSettings : new DefaultRenderSettings(); - } - - private class DefaultRenderSettings : IInstanceRenderSettings - { - public InstanceRenderSettings Settings => new InstanceRenderSettings() - { - Render = true, - DensityInDistance = 1f, - DensityInDistanceFalloff = Vector2.zero, - RenderDistance = 0.0f, - ShadowDistance = 0.0f, - Shadows = true, - Supported = true - }; - } - } -} diff --git a/TreeRenderer.cs.meta b/TreeRenderer.cs.meta deleted file mode 100644 index 72b0adf..0000000 --- a/TreeRenderer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e0f78ad04f9bf164e81068b0dcffd13b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/TreeStreamer.cs b/TreeStreamer.cs deleted file mode 100644 index 2d9100c..0000000 --- a/TreeStreamer.cs +++ /dev/null @@ -1,36 +0,0 @@ -using UnityEngine; - -namespace Assets.ThoMagic.Renderer -{ - public class TreeStreamer : InstanceStreamer - { - private readonly Terrain _terrain; - private Bounds worldBounds; - private float maxTreeDistance; - - public TreeStreamer(Terrain terrain) - : base() - => _terrain = terrain; - - public void Build(float maxDistance) - { - maxTreeDistance = maxDistance; - - Vector3 position = _terrain.GetPosition(); - worldBounds = new Bounds(_terrain.terrainData.bounds.center + position, _terrain.terrainData.bounds.size); - } - - public override bool IsInRange(Camera referenceCamera, Plane[] planes) - { - if (!_terrain.editorRenderFlags.HasFlag(TerrainRenderFlags.Trees)) - return false; - - var eyePos = referenceCamera.transform.position; - - if ((eyePos - worldBounds.ClosestPoint(eyePos)).magnitude <= Mathf.Min(referenceCamera.farClipPlane, maxTreeDistance)) - return true; - - return false; - } - } -} diff --git a/TreeStreamer.cs.meta b/TreeStreamer.cs.meta deleted file mode 100644 index aab0238..0000000 --- a/TreeStreamer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 049083d3196ea1b429c2057a188c2bf2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: