#define LOAD_NOISE3D_ON_STARTUP // prevent loading spike from happening when the 1st beam is instantiated using UnityEngine; #pragma warning disable 0429, 0162 // Unreachable expression code detected (because of Noise3D.isSupported on mobile) namespace VLB { public static class Noise3D { /// /// Returns if the 3D Noise feature is supported on the current platform or not. /// 3D Noise feature requires a graphicsShaderLevel 35 or higher (which is basically Shader Model 3.5 / OpenGL ES 3.0 or above) /// If not supported, the beams will look like the 3D Noise has been disabled. /// public static bool isSupported { get { if (!ms_IsSupportedChecked) { ms_IsSupported = SystemInfo.graphicsShaderLevel >= kMinShaderLevel; if (!ms_IsSupported) Debug.LogWarning(isNotSupportedString); ms_IsSupportedChecked = true; } return ms_IsSupported; } } /// /// Returns if the 3D Noise Texture has been successfully loaded or not. /// If the feature is not supported (isSupported == false), isProperlyLoaded is also false. /// public static bool isProperlyLoaded { get { return ms_NoiseTexture != null; } } public static string isNotSupportedString { get { var str = string.Format("3D Noise requires higher shader capabilities (Shader Model 3.5 / OpenGL ES 3.0), which are not available on the current platform: graphicsShaderLevel (current/required) = {0} / {1}", SystemInfo.graphicsShaderLevel, kMinShaderLevel); #if UNITY_EDITOR str += "\nPlease change the editor's graphics emulation for a more capable one via \"Edit/Graphics Emulation\" and press Play to force the light beams to be recomputed."; #endif return str; } } static bool ms_IsSupportedChecked = false; static bool ms_IsSupported = false; static Texture3D ms_NoiseTexture = null; const HideFlags kHideFlags = HideFlags.HideAndDontSave; // hide the noise texture const int kMinShaderLevel = 35; // Shader Model 3.5 / OpenGL ES 3.0 to handle sampler3D -> https://docs.unity3d.com/ScriptReference/SystemInfo-graphicsShaderLevel.html #if LOAD_NOISE3D_ON_STARTUP [RuntimeInitializeOnLoadMethod] static void OnStartUp() { LoadIfNeeded(); } #endif #if UNITY_EDITOR public static void _EditorForceReloadData() { if (ms_NoiseTexture) { Object.DestroyImmediate(ms_NoiseTexture); ms_NoiseTexture = null; } LoadIfNeeded(); } #endif public static void LoadIfNeeded() { if (!isSupported) return; if (ms_NoiseTexture == null) { ms_NoiseTexture = LoadTexture3D(Config.Instance.noise3DData, Config.Instance.noise3DSize); if(ms_NoiseTexture) ms_NoiseTexture.hideFlags = kHideFlags; Shader.SetGlobalTexture(ShaderProperties.GlobalNoiseTex3D, ms_NoiseTexture); Shader.SetGlobalFloat(ShaderProperties.GlobalNoiseCustomTime, -1.0f); } } static Texture3D LoadTexture3D(TextAsset textData, int size) { if (textData == null) { // Debug.LogError("Fail to open Noise 3D Data"); return null; } var bytes = textData.bytes; Debug.Assert(bytes != null); int dataLen = Mathf.Max(0, size * size * size); if (bytes.Length != dataLen) { Debug.LogErrorFormat("Noise 3D Data file has not the proper size {0}x{0}x{0}", size); return null; } var tex = new Texture3D(size, size, size, TextureFormat.Alpha8, false); var colors = new Color[dataLen]; for (int i = 0; i < dataLen; ++i) colors[i] = new Color32(0, 0, 0, bytes[i]); tex.SetPixels(colors); tex.Apply(); return tex; } } }