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: