Repository: LGhassen/Scatterer
Branch: master
Commit: c2d0b0f2a879
Files: 3995
Total size: 21.3 MB
Directory structure:
gitextract_hn92p19d/
├── .gitignore
├── Readme.md
├── license.md
└── scatterer/
├── CelestialBodySortableByDistance.cs
├── DataSerialization/
│ ├── ConfigPoint.cs
│ ├── ConfigReader.cs
│ ├── MainSettingsReadWrite.cs
│ ├── PlanetshineSource.cs
│ ├── PluginDataReadWrite.cs
│ ├── QualityPresetsLoader.cs
│ └── ScattererCelestialBody.cs
├── Effects/
│ ├── AntiAliasing/
│ │ ├── GenericAntiAliasing.cs
│ │ ├── SubpixelMorphologicalAntialiasing.cs
│ │ ├── TemporalAntiAliasing.cs
│ │ └── Utils/
│ │ └── HaltonSeq.cs
│ ├── PlanetShine/
│ │ ├── PlanetShineLight.cs
│ │ └── PlanetshineManager.cs
│ ├── Proland/
│ │ ├── Atmosphere/
│ │ │ ├── Godrays/
│ │ │ │ └── LegacyGodraysRenderer.cs
│ │ │ ├── Preprocessing/
│ │ │ │ └── AtmoPreprocessor.cs
│ │ │ ├── SkyNode.cs
│ │ │ └── Utils/
│ │ │ ├── AtmospherePQS.cs
│ │ │ ├── AtmosphereProjectorContainer.cs
│ │ │ ├── AtmosphereUtils.cs
│ │ │ ├── GenericLocalAtmosphereContainer.cs
│ │ │ ├── ScaledScatteringContainer.cs
│ │ │ ├── ScreenSpaceScatteringContainer.cs
│ │ │ └── SkySphereContainer.cs
│ │ ├── Ocean/
│ │ │ ├── Caustics/
│ │ │ │ ├── CausticsLightRaysRenderer.cs
│ │ │ │ └── CausticsShadowMaskModulate.cs
│ │ │ ├── FourierCPU.cs
│ │ │ ├── FourierGPU.cs
│ │ │ ├── GPUWaveInteractionHandler.cs
│ │ │ ├── OceanCameraUpdateHook.cs
│ │ │ ├── OceanFFTcpu.cs
│ │ │ ├── OceanFFTgpu.cs
│ │ │ ├── OceanNode.cs
│ │ │ ├── OceanRenderingHook.cs
│ │ │ ├── OceanWhiteCaps.cs
│ │ │ ├── UnderwaterDimmingHook.cs
│ │ │ └── Utils/
│ │ │ ├── CBUtility.cs
│ │ │ ├── FakeOceanPQS.cs
│ │ │ ├── OceanUtils.cs
│ │ │ ├── RTUtility.cs
│ │ │ └── WriteFloat.cs
│ │ └── ProlandManager.cs
│ ├── ScattererCelestialBodiesManager.cs
│ ├── SunFlare/
│ │ ├── SunFlare.cs
│ │ ├── SunflareCameraHook.cs
│ │ ├── SunflareManager.cs
│ │ ├── SunflareSettingsV1.cs
│ │ └── SunflareSettingsV2.cs
│ ├── SunlightModulator/
│ │ ├── SunlightModulator.cs
│ │ ├── SunlightModulatorPostRenderHook.cs
│ │ └── SunlightModulatorPreRenderHook.cs
│ └── Tonemapping/
│ └── HableCurve.cs
├── GUI/
│ ├── AtmoGUI.cs
│ ├── ConfigPointGUI.cs
│ ├── GUIhandler.cs
│ ├── MainOptionsGUI.cs
│ ├── ModularGUI/
│ │ ├── AbstractGUIModule.cs
│ │ ├── GUIModuleBool.cs
│ │ ├── GUIModuleFloat.cs
│ │ ├── GUIModuleInt.cs
│ │ ├── GUIModuleLabel.cs
│ │ ├── GUIModuleString.cs
│ │ ├── GUIModuleVector2.cs
│ │ ├── GUIModuleVector3.cs
│ │ ├── GUIModuleVector4.cs
│ │ └── ModularGUI.cs
│ ├── OceanGUI.cs
│ ├── SunflareGUI.cs
│ └── ToolbarButton.cs
├── OldShaders/
│ ├── readme.md.txt
│ └── scattererShaders/
│ ├── .vs/
│ │ └── scattererShaders/
│ │ ├── DesignTimeBuild/
│ │ │ └── .dtbcache
│ │ ├── v14/
│ │ │ └── .suo
│ │ └── v15/
│ │ ├── .suo
│ │ └── Server/
│ │ └── sqlite3/
│ │ ├── storage.ide
│ │ ├── storage.ide-shm
│ │ └── storage.ide-wal
│ ├── Assembly-CSharp-Editor.csproj
│ ├── Assembly-CSharp-Editor.csproj.orig
│ ├── Assembly-CSharp.csproj
│ ├── Assembly-CSharp.csproj.orig
│ ├── Assembly-UnityScript.unityproj
│ ├── Assets/
│ │ ├── AssetBundles/
│ │ │ ├── AssetBundles
│ │ │ └── AssetBundles.meta
│ │ ├── AssetBundles.meta
│ │ ├── Editor/
│ │ │ ├── ExportAssetBundle.cs
│ │ │ ├── ExportAssetBundle.cs.meta
│ │ │ ├── KSPCurveEditor.cs
│ │ │ └── KSPCurveEditor.cs.meta
│ │ ├── Editor.meta
│ │ ├── Shaders/
│ │ │ ├── AA/
│ │ │ │ ├── AreaTex.tga
│ │ │ │ ├── AreaTex.tga.meta
│ │ │ │ ├── CustomTAA.shader
│ │ │ │ ├── CustomTAA.shader.meta
│ │ │ │ ├── SMAA.cginc
│ │ │ │ ├── SMAA.cginc.meta
│ │ │ │ ├── SMAA.shader
│ │ │ │ ├── SMAA.shader.meta
│ │ │ │ ├── SMAABridge.cginc
│ │ │ │ ├── SMAABridge.cginc.meta
│ │ │ │ ├── SearchTex.tga
│ │ │ │ └── SearchTex.tga.meta
│ │ │ ├── AA.meta
│ │ │ ├── Atmo/
│ │ │ │ ├── CompositeDownscaledScattering.shader
│ │ │ │ ├── CompositeDownscaledScattering.shader.meta
│ │ │ │ ├── DepthBufferScattering.shader
│ │ │ │ ├── DepthBufferScattering.shader.meta
│ │ │ │ ├── Godrays/
│ │ │ │ │ ├── ComputeInverseShadowMatrices.compute
│ │ │ │ │ ├── ComputeInverseShadowMatrices.compute.meta
│ │ │ │ │ ├── GodraysCommon.cginc
│ │ │ │ │ ├── GodraysCommon.cginc.meta
│ │ │ │ │ ├── ShadowVolumeUtils.cginc
│ │ │ │ │ ├── ShadowVolumeUtils.cginc.meta
│ │ │ │ │ ├── VolumeDepth - Copy.shader.BAK
│ │ │ │ │ ├── VolumeDepth - Copy.shader.BAK.meta
│ │ │ │ │ ├── VolumeDepth.shader
│ │ │ │ │ └── VolumeDepth.shader.meta
│ │ │ │ ├── Godrays.meta
│ │ │ │ ├── Preprocessing.meta
│ │ │ │ ├── ProjectorScattering.shader
│ │ │ │ ├── ProjectorScattering.shader.meta
│ │ │ │ ├── ScaledPlanetScattering.shader
│ │ │ │ ├── ScaledPlanetScattering.shader.meta
│ │ │ │ ├── SkySphere.shader
│ │ │ │ └── SkySphere.shader.meta
│ │ │ ├── Atmo.meta
│ │ │ ├── ClippingUtils.cginc
│ │ │ ├── ClippingUtils.cginc.meta
│ │ │ ├── CommonAtmosphere.cginc
│ │ │ ├── CommonAtmosphere.cginc.meta
│ │ │ ├── DecodeEncode/
│ │ │ │ ├── DecodedToFloat.shader
│ │ │ │ ├── DecodedToFloat.shader.meta
│ │ │ │ ├── WriteToFloat.shader
│ │ │ │ └── WriteToFloat.shader.meta
│ │ │ ├── DecodeEncode.meta
│ │ │ ├── Depth/
│ │ │ │ ├── CopyCameraDepth.shader
│ │ │ │ ├── CopyCameraDepth.shader.meta
│ │ │ │ ├── DepthToDistance.shader
│ │ │ │ ├── DepthToDistance.shader.meta
│ │ │ │ ├── DownscaleDepth.shader
│ │ │ │ └── DownscaleDepth.shader.meta
│ │ │ ├── Depth.meta
│ │ │ ├── DepthCommon.cginc
│ │ │ ├── DepthCommon.cginc.meta
│ │ │ ├── EVE/
│ │ │ │ ├── CloudVolumeParticle.shader
│ │ │ │ ├── CloudVolumeParticle.shader.meta
│ │ │ │ ├── EVEUtils.cginc
│ │ │ │ ├── EVEUtils.cginc.meta
│ │ │ │ ├── GeometryCloudVolumeParticle.shader
│ │ │ │ ├── GeometryCloudVolumeParticle.shader.meta
│ │ │ │ ├── GeometryCloudVolumeParticleToTexture.shader
│ │ │ │ ├── GeometryCloudVolumeParticleToTexture.shader.meta
│ │ │ │ ├── SphereCloud.shader
│ │ │ │ ├── SphereCloud.shader.meta
│ │ │ │ ├── SphereCloudShadowMap.shader
│ │ │ │ ├── SphereCloudShadowMap.shader.meta
│ │ │ │ ├── alphaMap.cginc
│ │ │ │ ├── alphaMap.cginc.meta
│ │ │ │ ├── cubeMap.cginc
│ │ │ │ ├── cubeMap.cginc.meta
│ │ │ │ ├── noiseSimplex.cginc
│ │ │ │ └── noiseSimplex.cginc.meta
│ │ │ ├── EVE.meta
│ │ │ ├── EclipseCommon.cginc
│ │ │ ├── EclipseCommon.cginc.meta
│ │ │ ├── IntersectCommon.cginc
│ │ │ ├── IntersectCommon.cginc.meta
│ │ │ ├── Misc.meta
│ │ │ ├── Ocean/
│ │ │ │ ├── Caustics/
│ │ │ │ │ ├── 0042-underwater-beach-sand-texture-seamless.jpg.meta
│ │ │ │ │ ├── CausticsFinal.png.meta
│ │ │ │ │ ├── CausticsGodrays.mat
│ │ │ │ │ ├── CausticsGodrays.mat.meta
│ │ │ │ │ ├── CausticsGodraysRaymarch.shader
│ │ │ │ │ ├── CausticsGodraysRaymarch.shader.meta
│ │ │ │ │ ├── CausticsOcclusion.shader
│ │ │ │ │ ├── CausticsOcclusion.shader.meta
│ │ │ │ │ ├── CausticsScene.unity
│ │ │ │ │ ├── CausticsScene.unity.meta
│ │ │ │ │ ├── CausticsShadowMask.mat
│ │ │ │ │ ├── CausticsShadowMask.mat.meta
│ │ │ │ │ ├── CompositeCausticsGodrays.shader
│ │ │ │ │ ├── CompositeCausticsGodrays.shader.meta
│ │ │ │ │ ├── ModulateShadowMask.cs
│ │ │ │ │ ├── ModulateShadowMask.cs.meta
│ │ │ │ │ ├── SeaFloor.mat
│ │ │ │ │ ├── SeaFloor.mat.meta
│ │ │ │ │ └── WhiteTexture.png.meta
│ │ │ │ ├── Caustics.meta
│ │ │ │ ├── FindHeights.compute
│ │ │ │ ├── FindHeights.compute.meta
│ │ │ │ ├── Fourier.shader
│ │ │ │ ├── Fourier.shader.meta
│ │ │ │ ├── InitDisplacement.shader
│ │ │ │ ├── InitDisplacement.shader.meta
│ │ │ │ ├── InitJacobians.shader
│ │ │ │ ├── InitJacobians.shader.meta
│ │ │ │ ├── InitSpectrum.shader
│ │ │ │ ├── InitSpectrum.shader.meta
│ │ │ │ ├── InvisibleOcean.shader
│ │ │ │ ├── InvisibleOcean.shader.meta
│ │ │ │ ├── OceanBRDF.cginc
│ │ │ │ ├── OceanBRDF.cginc.meta
│ │ │ │ ├── OceanDisplacement3.cginc
│ │ │ │ ├── OceanDisplacement3.cginc.meta
│ │ │ │ ├── OceanLight.cginc
│ │ │ │ ├── OceanLight.cginc.meta
│ │ │ │ ├── OceanShadows.cginc
│ │ │ │ ├── OceanShadows.cginc.meta
│ │ │ │ ├── OceanUtils.cginc
│ │ │ │ ├── OceanUtils.cginc.meta
│ │ │ │ ├── OceanWhiteCapsModProj3.shader
│ │ │ │ ├── OceanWhiteCapsModProj3.shader.meta
│ │ │ │ ├── OceanWhiteCapsModProj3PixelLights.shader
│ │ │ │ ├── OceanWhiteCapsModProj3PixelLights.shader.meta
│ │ │ │ ├── OceanWhiteCapsModProj3VertexSearch.shader
│ │ │ │ ├── OceanWhiteCapsModProj3VertexSearch.shader.meta
│ │ │ │ ├── ReadData.compute
│ │ │ │ ├── ReadData.compute.meta
│ │ │ │ ├── SlopeVariance.compute
│ │ │ │ ├── SlopeVariance.compute.meta
│ │ │ │ ├── UnderwaterDepthBuffer.shader
│ │ │ │ ├── UnderwaterDepthBuffer.shader.meta
│ │ │ │ ├── UnderwaterProjector.shader
│ │ │ │ ├── UnderwaterProjector.shader.meta
│ │ │ │ ├── WhiteCapsPrecompute0.shader
│ │ │ │ └── WhiteCapsPrecompute0.shader.meta
│ │ │ ├── Ocean.meta
│ │ │ ├── RingCommon.cginc
│ │ │ ├── RingCommon.cginc.meta
│ │ │ ├── RingCommon.cgincBAK
│ │ │ ├── RingCommon.cgincBAK.meta
│ │ │ ├── Shadows/
│ │ │ │ ├── DoublePrecisionEmulation.cginc
│ │ │ │ ├── DoublePrecisionEmulation.cginc.meta
│ │ │ │ ├── FixedScreenSpaceShadows.cginc
│ │ │ │ ├── FixedScreenSpaceShadows.cginc.meta
│ │ │ │ ├── FixedScreenSpaceShadows.shader
│ │ │ │ ├── FixedScreenSpaceShadows.shader.meta
│ │ │ │ ├── LongDistanceScreenSpaceShadows.shader
│ │ │ │ └── LongDistanceScreenSpaceShadows.shader.meta
│ │ │ ├── Shadows.meta
│ │ │ ├── ShadowsCommon.cginc
│ │ │ ├── ShadowsCommon.cginc.meta
│ │ │ ├── SunFlare/
│ │ │ │ ├── SunFlare.shader
│ │ │ │ ├── SunFlare.shader.meta
│ │ │ │ ├── SunFlareExtinction.shader
│ │ │ │ └── SunFlareExtinction.shader.meta
│ │ │ ├── SunFlare.meta
│ │ │ ├── Utility.cginc
│ │ │ └── Utility.cginc.meta
│ │ ├── TestScenes.meta
│ │ └── shaders.meta
│ ├── Library/
│ │ ├── APIUpdater/
│ │ │ └── project-dependencies.graph
│ │ ├── AnnotationManager
│ │ ├── AssetImportState
│ │ ├── AssetServerCacheV3
│ │ ├── BuildPlayer.prefs
│ │ ├── BuildSettings.asset
│ │ ├── CurrentLayout-default.dwlt
│ │ ├── CurrentLayout.dwlt
│ │ ├── CurrentMaximizeLayout.dwlt
│ │ ├── EditorOnlyScriptingSettings.json
│ │ ├── EditorOnlyScriptingUserSettings.json
│ │ ├── EditorSnapSettings.asset
│ │ ├── EditorUserBuildSettings.asset
│ │ ├── EditorUserSettings.asset
│ │ ├── InspectorExpandedItems.asset
│ │ ├── LastBuild.buildreport
│ │ ├── LastSceneManagerSetup.txt
│ │ ├── LibraryFormatVersion.txt
│ │ ├── MonoManager.asset
│ │ ├── PackageCache/
│ │ │ ├── com.unity.collab-proxy@1.2.16/
│ │ │ │ ├── .npmignore
│ │ │ │ ├── CHANGELOG.md
│ │ │ │ ├── CHANGELOG.md.meta
│ │ │ │ ├── DEPENDENCIES.md
│ │ │ │ ├── DEPENDENCIES.md.meta
│ │ │ │ ├── Documentation~/
│ │ │ │ │ └── collab-proxy.md
│ │ │ │ ├── Editor/
│ │ │ │ │ ├── AssemblyInfo.cs
│ │ │ │ │ ├── AssemblyInfo.cs.meta
│ │ │ │ │ ├── Collab/
│ │ │ │ │ │ ├── Bootstrap.cs
│ │ │ │ │ │ ├── Bootstrap.cs.meta
│ │ │ │ │ │ ├── CollabAnalytics.cs
│ │ │ │ │ │ ├── CollabAnalytics.cs.meta
│ │ │ │ │ │ ├── CollabHistoryWindow.cs
│ │ │ │ │ │ ├── CollabHistoryWindow.cs.meta
│ │ │ │ │ │ ├── CollabToolbarButton.cs
│ │ │ │ │ │ ├── CollabToolbarButton.cs.meta
│ │ │ │ │ │ ├── CollabToolbarWindow.cs
│ │ │ │ │ │ ├── CollabToolbarWindow.cs.meta
│ │ │ │ │ │ ├── Presenters/
│ │ │ │ │ │ │ ├── CollabHistoryPresenter.cs
│ │ │ │ │ │ │ └── CollabHistoryPresenter.cs.meta
│ │ │ │ │ │ ├── Presenters.meta
│ │ │ │ │ │ ├── Views/
│ │ │ │ │ │ │ ├── BuildStatusButton.cs
│ │ │ │ │ │ │ ├── BuildStatusButton.cs.meta
│ │ │ │ │ │ │ ├── CollabHistoryDropDown.cs
│ │ │ │ │ │ │ ├── CollabHistoryDropDown.cs.meta
│ │ │ │ │ │ │ ├── CollabHistoryDropDownItem.cs
│ │ │ │ │ │ │ ├── CollabHistoryDropDownItem.cs.meta
│ │ │ │ │ │ │ ├── CollabHistoryItem.cs
│ │ │ │ │ │ │ ├── CollabHistoryItem.cs.meta
│ │ │ │ │ │ │ ├── CollabHistoryItemFactory.cs
│ │ │ │ │ │ │ ├── CollabHistoryItemFactory.cs.meta
│ │ │ │ │ │ │ ├── CollabHistoryRevisionLine.cs
│ │ │ │ │ │ │ ├── CollabHistoryRevisionLine.cs.meta
│ │ │ │ │ │ │ ├── HistoryProgressSpinner.cs
│ │ │ │ │ │ │ ├── HistoryProgressSpinner.cs.meta
│ │ │ │ │ │ │ ├── ICollabHistoryItemFactory.cs
│ │ │ │ │ │ │ ├── ICollabHistoryItemFactory.cs.meta
│ │ │ │ │ │ │ ├── PagedListView.cs
│ │ │ │ │ │ │ ├── PagedListView.cs.meta
│ │ │ │ │ │ │ ├── StatusView.cs
│ │ │ │ │ │ │ └── StatusView.cs.meta
│ │ │ │ │ │ └── Views.meta
│ │ │ │ │ ├── Collab.meta
│ │ │ │ │ ├── Resources/
│ │ │ │ │ │ ├── Styles/
│ │ │ │ │ │ │ ├── CollabHistoryCommon.uss
│ │ │ │ │ │ │ ├── CollabHistoryCommon.uss.meta
│ │ │ │ │ │ │ ├── CollabHistoryDark.uss
│ │ │ │ │ │ │ ├── CollabHistoryDark.uss.meta
│ │ │ │ │ │ │ ├── CollabHistoryLight.uss
│ │ │ │ │ │ │ └── CollabHistoryLight.uss.meta
│ │ │ │ │ │ └── Styles.meta
│ │ │ │ │ ├── Resources.meta
│ │ │ │ │ ├── Unity.CollabProxy.Editor.asmdef
│ │ │ │ │ └── Unity.CollabProxy.Editor.asmdef.meta
│ │ │ │ ├── Editor.meta
│ │ │ │ ├── LICENSE.md
│ │ │ │ ├── LICENSE.md.meta
│ │ │ │ ├── README.md
│ │ │ │ ├── README.md.meta
│ │ │ │ ├── Tests/
│ │ │ │ │ ├── Editor/
│ │ │ │ │ │ ├── HistoryTests.cs
│ │ │ │ │ │ ├── HistoryTests.cs.meta
│ │ │ │ │ │ ├── Unity.CollabProxy.EditorTests.asmdef
│ │ │ │ │ │ └── Unity.CollabProxy.EditorTests.asmdef.meta
│ │ │ │ │ └── Editor.meta
│ │ │ │ ├── Tests.meta
│ │ │ │ ├── package.json
│ │ │ │ └── package.json.meta
│ │ │ ├── com.unity.ext.nunit@1.0.0/
│ │ │ │ ├── .gitlab-ci.yml
│ │ │ │ ├── CHANGELOG.md
│ │ │ │ ├── CHANGELOG.md.meta
│ │ │ │ ├── Documentation~/
│ │ │ │ │ └── ext.nunit.md
│ │ │ │ ├── LICENSE.md
│ │ │ │ ├── LICENSE.md.meta
│ │ │ │ ├── README.md
│ │ │ │ ├── README.md.meta
│ │ │ │ ├── net35/
│ │ │ │ │ ├── unity-custom/
│ │ │ │ │ │ ├── This is a custom build DONT include.txt
│ │ │ │ │ │ ├── This is a custom build DONT include.txt.meta
│ │ │ │ │ │ ├── nunit.framework.dll.mdb
│ │ │ │ │ │ ├── nunit.framework.dll.mdb.meta
│ │ │ │ │ │ ├── nunit.framework.dll.meta
│ │ │ │ │ │ ├── nunit.framework.pdb
│ │ │ │ │ │ ├── nunit.framework.pdb.meta
│ │ │ │ │ │ ├── nunit.framework.xml
│ │ │ │ │ │ └── nunit.framework.xml.meta
│ │ │ │ │ └── unity-custom.meta
│ │ │ │ ├── net35.meta
│ │ │ │ ├── package.json
│ │ │ │ └── package.json.meta
│ │ │ ├── com.unity.ide.rider@1.1.0/
│ │ │ │ ├── .editorconfig
│ │ │ │ ├── CHANGELOG.md
│ │ │ │ ├── CHANGELOG.md.meta
│ │ │ │ ├── CONTRIBUTING.md
│ │ │ │ ├── CONTRIBUTING.md.meta
│ │ │ │ ├── Documentation~/
│ │ │ │ │ └── README.md
│ │ │ │ ├── LICENSE.md
│ │ │ │ ├── LICENSE.md.meta
│ │ │ │ ├── Rider/
│ │ │ │ │ ├── Editor/
│ │ │ │ │ │ ├── Discovery.cs
│ │ │ │ │ │ ├── Discovery.cs.meta
│ │ │ │ │ │ ├── EditorPluginInterop.cs
│ │ │ │ │ │ ├── EditorPluginInterop.cs.meta
│ │ │ │ │ │ ├── LoggingLevel.cs
│ │ │ │ │ │ ├── LoggingLevel.cs.meta
│ │ │ │ │ │ ├── PluginSettings.cs
│ │ │ │ │ │ ├── PluginSettings.cs.meta
│ │ │ │ │ │ ├── ProjectGeneration.cs
│ │ │ │ │ │ ├── ProjectGeneration.cs.meta
│ │ │ │ │ │ ├── RiderInitializer.cs
│ │ │ │ │ │ ├── RiderInitializer.cs.meta
│ │ │ │ │ │ ├── RiderScriptEditor.cs
│ │ │ │ │ │ ├── RiderScriptEditor.cs.meta
│ │ │ │ │ │ ├── RiderScriptEditorData.cs
│ │ │ │ │ │ ├── RiderScriptEditorData.cs.meta
│ │ │ │ │ │ ├── Util/
│ │ │ │ │ │ │ ├── FileSystemUtil.cs
│ │ │ │ │ │ │ ├── FileSystemUtil.cs.meta
│ │ │ │ │ │ │ ├── LibcNativeInterop.cs
│ │ │ │ │ │ │ ├── LibcNativeInterop.cs.meta
│ │ │ │ │ │ │ ├── UnityUtils.cs
│ │ │ │ │ │ │ └── UnityUtils.cs.meta
│ │ │ │ │ │ ├── Util.meta
│ │ │ │ │ │ ├── com.unity.ide.rider.asmdef
│ │ │ │ │ │ └── com.unity.ide.rider.asmdef.meta
│ │ │ │ │ └── Editor.meta
│ │ │ │ ├── Rider.meta
│ │ │ │ ├── package.json
│ │ │ │ └── package.json.meta
│ │ │ ├── com.unity.ide.vscode@1.1.3/
│ │ │ │ ├── CHANGELOG.md
│ │ │ │ ├── CHANGELOG.md.meta
│ │ │ │ ├── CONTRIBUTING.md
│ │ │ │ ├── CONTRIBUTING.md.meta
│ │ │ │ ├── Documentation~/
│ │ │ │ │ └── README.md
│ │ │ │ ├── Editor/
│ │ │ │ │ ├── ProjectGeneration/
│ │ │ │ │ │ ├── AssemblyNameProvider.cs
│ │ │ │ │ │ ├── AssemblyNameProvider.cs.meta
│ │ │ │ │ │ ├── FileIO.cs
│ │ │ │ │ │ ├── FileIO.cs.meta
│ │ │ │ │ │ ├── GUIDGenerator.cs
│ │ │ │ │ │ ├── GUIDGenerator.cs.meta
│ │ │ │ │ │ ├── ProjectGeneration.cs
│ │ │ │ │ │ └── ProjectGeneration.cs.meta
│ │ │ │ │ ├── ProjectGeneration.meta
│ │ │ │ │ ├── Unity.com.unity.vscode.Editor.asmdef
│ │ │ │ │ ├── Unity.com.unity.vscode.Editor.asmdef.meta
│ │ │ │ │ ├── Utility.cs
│ │ │ │ │ ├── Utility.cs.meta
│ │ │ │ │ ├── VSCodeDiscovery.cs
│ │ │ │ │ ├── VSCodeDiscovery.cs.meta
│ │ │ │ │ ├── VSCodeScriptEditor.cs
│ │ │ │ │ └── VSCodeScriptEditor.cs.meta
│ │ │ │ ├── Editor.meta
│ │ │ │ ├── LICENSE.md
│ │ │ │ ├── LICENSE.md.meta
│ │ │ │ ├── package.json
│ │ │ │ └── package.json.meta
│ │ │ ├── com.unity.test-framework@1.0.13/
│ │ │ │ ├── CHANGELOG.md
│ │ │ │ ├── CHANGELOG.md.meta
│ │ │ │ ├── CONTRIBUTING.md
│ │ │ │ ├── CONTRIBUTING.md.meta
│ │ │ │ ├── Documentation~/
│ │ │ │ │ ├── PlaymodeTestFramework.md
│ │ │ │ │ └── com.unity.test-framework.md
│ │ │ │ ├── LICENSE.md
│ │ │ │ ├── LICENSE.md.meta
│ │ │ │ ├── UnityEditor.TestRunner/
│ │ │ │ │ ├── Api/
│ │ │ │ │ │ ├── CallbacksDelegator.cs
│ │ │ │ │ │ ├── CallbacksDelegator.cs.meta
│ │ │ │ │ │ ├── CallbacksDelegatorListener.cs
│ │ │ │ │ │ ├── CallbacksDelegatorListener.cs.meta
│ │ │ │ │ │ ├── CallbacksHolder.cs
│ │ │ │ │ │ ├── CallbacksHolder.cs.meta
│ │ │ │ │ │ ├── ExecutionSettings.cs
│ │ │ │ │ │ ├── ExecutionSettings.cs.meta
│ │ │ │ │ │ ├── Filter.cs
│ │ │ │ │ │ ├── Filter.cs.meta
│ │ │ │ │ │ ├── ICallbacks.cs
│ │ │ │ │ │ ├── ICallbacks.cs.meta
│ │ │ │ │ │ ├── ITestAdaptor.cs
│ │ │ │ │ │ ├── ITestAdaptor.cs.meta
│ │ │ │ │ │ ├── ITestAdaptorFactory.cs
│ │ │ │ │ │ ├── ITestAdaptorFactory.cs.meta
│ │ │ │ │ │ ├── ITestResultAdaptor.cs
│ │ │ │ │ │ ├── ITestResultAdaptor.cs.meta
│ │ │ │ │ │ ├── ITestRunSettings.cs
│ │ │ │ │ │ ├── ITestRunSettings.cs.meta
│ │ │ │ │ │ ├── ITestRunnerApi.cs
│ │ │ │ │ │ ├── ITestRunnerApi.cs.meta
│ │ │ │ │ │ ├── RunState.cs
│ │ │ │ │ │ ├── RunState.cs.meta
│ │ │ │ │ │ ├── TestAdaptor.cs
│ │ │ │ │ │ ├── TestAdaptor.cs.meta
│ │ │ │ │ │ ├── TestAdaptorFactory.cs
│ │ │ │ │ │ ├── TestAdaptorFactory.cs.meta
│ │ │ │ │ │ ├── TestLauncherFactory.cs
│ │ │ │ │ │ ├── TestLauncherFactory.cs.meta
│ │ │ │ │ │ ├── TestMode.cs
│ │ │ │ │ │ ├── TestMode.cs.meta
│ │ │ │ │ │ ├── TestResultAdaptor.cs
│ │ │ │ │ │ ├── TestResultAdaptor.cs.meta
│ │ │ │ │ │ ├── TestRunData.cs
│ │ │ │ │ │ ├── TestRunData.cs.meta
│ │ │ │ │ │ ├── TestRunnerApi.cs
│ │ │ │ │ │ ├── TestRunnerApi.cs.meta
│ │ │ │ │ │ ├── TestStatus.cs
│ │ │ │ │ │ └── TestStatus.cs.meta
│ │ │ │ │ ├── Api.meta
│ │ │ │ │ ├── AssemblyInfo.cs
│ │ │ │ │ ├── AssemblyInfo.cs.meta
│ │ │ │ │ ├── CommandLineParser/
│ │ │ │ │ │ ├── CommandLineOption.cs
│ │ │ │ │ │ ├── CommandLineOption.cs.meta
│ │ │ │ │ │ ├── CommandLineOptionSet.cs
│ │ │ │ │ │ ├── CommandLineOptionSet.cs.meta
│ │ │ │ │ │ ├── ICommandLineOption.cs
│ │ │ │ │ │ └── ICommandLineOption.cs.meta
│ │ │ │ │ ├── CommandLineParser.meta
│ │ │ │ │ ├── CommandLineTest/
│ │ │ │ │ │ ├── Executer.cs
│ │ │ │ │ │ ├── Executer.cs.meta
│ │ │ │ │ │ ├── ExecutionSettings.cs
│ │ │ │ │ │ ├── ExecutionSettings.cs.meta
│ │ │ │ │ │ ├── ExitCallbacks.cs
│ │ │ │ │ │ ├── ExitCallbacks.cs.meta
│ │ │ │ │ │ ├── ISettingsBuilder.cs
│ │ │ │ │ │ ├── ISettingsBuilder.cs.meta
│ │ │ │ │ │ ├── LogSavingCallbacks.cs
│ │ │ │ │ │ ├── LogSavingCallbacks.cs.meta
│ │ │ │ │ │ ├── LogWriter.cs
│ │ │ │ │ │ ├── LogWriter.cs.meta
│ │ │ │ │ │ ├── ResultsSavingCallbacks.cs
│ │ │ │ │ │ ├── ResultsSavingCallbacks.cs.meta
│ │ │ │ │ │ ├── ResultsWriter.cs
│ │ │ │ │ │ ├── ResultsWriter.cs.meta
│ │ │ │ │ │ ├── RunData.cs
│ │ │ │ │ │ ├── RunData.cs.meta
│ │ │ │ │ │ ├── RunSettings.cs
│ │ │ │ │ │ ├── RunSettings.cs.meta
│ │ │ │ │ │ ├── SettingsBuilder.cs
│ │ │ │ │ │ ├── SettingsBuilder.cs.meta
│ │ │ │ │ │ ├── SetupException.cs
│ │ │ │ │ │ ├── SetupException.cs.meta
│ │ │ │ │ │ ├── TestStarter.cs
│ │ │ │ │ │ ├── TestStarter.cs.meta
│ │ │ │ │ │ ├── TimeoutCallbacks.cs
│ │ │ │ │ │ └── TimeoutCallbacks.cs.meta
│ │ │ │ │ ├── CommandLineTest.meta
│ │ │ │ │ ├── GUI/
│ │ │ │ │ │ ├── AssetsDatabaseHelper.cs
│ │ │ │ │ │ ├── AssetsDatabaseHelper.cs.meta
│ │ │ │ │ │ ├── GuiHelper.cs
│ │ │ │ │ │ ├── GuiHelper.cs.meta
│ │ │ │ │ │ ├── IAssetsDatabaseHelper.cs
│ │ │ │ │ │ ├── IAssetsDatabaseHelper.cs.meta
│ │ │ │ │ │ ├── IGuiHelper.cs
│ │ │ │ │ │ ├── IGuiHelper.cs.meta
│ │ │ │ │ │ ├── TestListBuilder/
│ │ │ │ │ │ │ ├── RenderingOptions.cs
│ │ │ │ │ │ │ ├── RenderingOptions.cs.meta
│ │ │ │ │ │ │ ├── ResultSummarizer.cs
│ │ │ │ │ │ │ ├── ResultSummarizer.cs.meta
│ │ │ │ │ │ │ ├── TestFilterSettings.cs
│ │ │ │ │ │ │ ├── TestFilterSettings.cs.meta
│ │ │ │ │ │ │ ├── TestTreeViewBuilder.cs
│ │ │ │ │ │ │ └── TestTreeViewBuilder.cs.meta
│ │ │ │ │ │ ├── TestListBuilder.meta
│ │ │ │ │ │ ├── TestListGuiHelper.cs
│ │ │ │ │ │ ├── TestListGuiHelper.cs.meta
│ │ │ │ │ │ ├── TestListTreeView/
│ │ │ │ │ │ │ ├── Icons.cs
│ │ │ │ │ │ │ ├── Icons.cs.meta
│ │ │ │ │ │ │ ├── TestListTreeViewDataSource.cs
│ │ │ │ │ │ │ ├── TestListTreeViewDataSource.cs.meta
│ │ │ │ │ │ │ ├── TestListTreeViewGUI.cs
│ │ │ │ │ │ │ ├── TestListTreeViewGUI.cs.meta
│ │ │ │ │ │ │ ├── TestTreeViewItem.cs
│ │ │ │ │ │ │ └── TestTreeViewItem.cs.meta
│ │ │ │ │ │ ├── TestListTreeView.meta
│ │ │ │ │ │ ├── TestRunnerResult.cs
│ │ │ │ │ │ ├── TestRunnerResult.cs.meta
│ │ │ │ │ │ ├── TestRunnerUIFilter.cs
│ │ │ │ │ │ ├── TestRunnerUIFilter.cs.meta
│ │ │ │ │ │ ├── Views/
│ │ │ │ │ │ │ ├── EditModeTestListGUI.cs
│ │ │ │ │ │ │ ├── EditModeTestListGUI.cs.meta
│ │ │ │ │ │ │ ├── PlayModeTestListGUI.cs
│ │ │ │ │ │ │ ├── PlayModeTestListGUI.cs.meta
│ │ │ │ │ │ │ ├── TestListGUIBase.cs
│ │ │ │ │ │ │ └── TestListGUIBase.cs.meta
│ │ │ │ │ │ └── Views.meta
│ │ │ │ │ ├── GUI.meta
│ │ │ │ │ ├── NUnitExtension/
│ │ │ │ │ │ ├── Attributes/
│ │ │ │ │ │ │ ├── AssetPipelineIgnore.cs
│ │ │ │ │ │ │ └── AssetPipelineIgnore.cs.meta
│ │ │ │ │ │ ├── Attributes.meta
│ │ │ │ │ │ ├── TestRunnerStateSerializer.cs
│ │ │ │ │ │ └── TestRunnerStateSerializer.cs.meta
│ │ │ │ │ ├── NUnitExtension.meta
│ │ │ │ │ ├── RequireApiProfileAttribute.cs
│ │ │ │ │ ├── RequireApiProfileAttribute.cs.meta
│ │ │ │ │ ├── RequirePlatformSupportAttribute.cs
│ │ │ │ │ ├── RequirePlatformSupportAttribute.cs.meta
│ │ │ │ │ ├── TestBuildAssemblyFilter.cs
│ │ │ │ │ ├── TestBuildAssemblyFilter.cs.meta
│ │ │ │ │ ├── TestLaunchers/
│ │ │ │ │ │ ├── AttributeFinderBase.cs
│ │ │ │ │ │ ├── AttributeFinderBase.cs.meta
│ │ │ │ │ │ ├── EditModeLauncher.cs
│ │ │ │ │ │ ├── EditModeLauncher.cs.meta
│ │ │ │ │ │ ├── EditModeLauncherContextSettings.cs
│ │ │ │ │ │ ├── EditModeLauncherContextSettings.cs.meta
│ │ │ │ │ │ ├── PlatformSetup/
│ │ │ │ │ │ │ ├── AndroidPlatformSetup.cs
│ │ │ │ │ │ │ ├── AndroidPlatformSetup.cs.meta
│ │ │ │ │ │ │ ├── ApplePlatformSetup.cs
│ │ │ │ │ │ │ ├── ApplePlatformSetup.cs.meta
│ │ │ │ │ │ │ ├── IPlatformSetup.cs
│ │ │ │ │ │ │ ├── IPlatformSetup.cs.meta
│ │ │ │ │ │ │ ├── LuminPlatformSetup.cs
│ │ │ │ │ │ │ ├── LuminPlatformSetup.cs.meta
│ │ │ │ │ │ │ ├── PlatformSpecificSetup.cs
│ │ │ │ │ │ │ ├── PlatformSpecificSetup.cs.meta
│ │ │ │ │ │ │ ├── SwitchPlatformSetup.cs
│ │ │ │ │ │ │ ├── SwitchPlatformSetup.cs.meta
│ │ │ │ │ │ │ ├── UwpPlatformSetup.cs
│ │ │ │ │ │ │ ├── UwpPlatformSetup.cs.meta
│ │ │ │ │ │ │ ├── XboxOnePlatformSetup.cs
│ │ │ │ │ │ │ └── XboxOnePlatformSetup.cs.meta
│ │ │ │ │ │ ├── PlatformSetup.meta
│ │ │ │ │ │ ├── PlayerLauncher.cs
│ │ │ │ │ │ ├── PlayerLauncher.cs.meta
│ │ │ │ │ │ ├── PlayerLauncherBuildOptions.cs
│ │ │ │ │ │ ├── PlayerLauncherBuildOptions.cs.meta
│ │ │ │ │ │ ├── PlayerLauncherContextSettings.cs
│ │ │ │ │ │ ├── PlayerLauncherContextSettings.cs.meta
│ │ │ │ │ │ ├── PlaymodeLauncher.cs
│ │ │ │ │ │ ├── PlaymodeLauncher.cs.meta
│ │ │ │ │ │ ├── PostbuildCleanupAttributeFinder.cs
│ │ │ │ │ │ ├── PostbuildCleanupAttributeFinder.cs.meta
│ │ │ │ │ │ ├── PrebuildSetupAttributeFinder.cs
│ │ │ │ │ │ ├── PrebuildSetupAttributeFinder.cs.meta
│ │ │ │ │ │ ├── RemotePlayerLogController.cs
│ │ │ │ │ │ ├── RemotePlayerLogController.cs.meta
│ │ │ │ │ │ ├── RemotePlayerTestController.cs
│ │ │ │ │ │ ├── RemotePlayerTestController.cs.meta
│ │ │ │ │ │ ├── RemoteTestResultReciever.cs
│ │ │ │ │ │ ├── RemoteTestResultReciever.cs.meta
│ │ │ │ │ │ ├── RuntimeTestLauncherBase.cs
│ │ │ │ │ │ ├── RuntimeTestLauncherBase.cs.meta
│ │ │ │ │ │ ├── TestLauncherBase.cs
│ │ │ │ │ │ └── TestLauncherBase.cs.meta
│ │ │ │ │ ├── TestLaunchers.meta
│ │ │ │ │ ├── TestResultSerializer.cs
│ │ │ │ │ ├── TestResultSerializer.cs.meta
│ │ │ │ │ ├── TestRunner/
│ │ │ │ │ │ ├── Callbacks/
│ │ │ │ │ │ │ ├── EditModeRunnerCallback.cs
│ │ │ │ │ │ │ ├── EditModeRunnerCallback.cs.meta
│ │ │ │ │ │ │ ├── RerunCallback.cs
│ │ │ │ │ │ │ ├── RerunCallback.cs.meta
│ │ │ │ │ │ │ ├── RerunCallbackData.cs
│ │ │ │ │ │ │ ├── RerunCallbackData.cs.meta
│ │ │ │ │ │ │ ├── RerunCallbackInitializer.cs
│ │ │ │ │ │ │ ├── RerunCallbackInitializer.cs.meta
│ │ │ │ │ │ │ ├── TestRunnerCallback.cs
│ │ │ │ │ │ │ ├── TestRunnerCallback.cs.meta
│ │ │ │ │ │ │ ├── WindowResultUpdater.cs
│ │ │ │ │ │ │ └── WindowResultUpdater.cs.meta
│ │ │ │ │ │ ├── Callbacks.meta
│ │ │ │ │ │ ├── EditModePCHelper.cs
│ │ │ │ │ │ ├── EditModePCHelper.cs.meta
│ │ │ │ │ │ ├── EditModeRunner.cs
│ │ │ │ │ │ ├── EditModeRunner.cs.meta
│ │ │ │ │ │ ├── EditmodeWorkItemFactory.cs
│ │ │ │ │ │ ├── EditmodeWorkItemFactory.cs.meta
│ │ │ │ │ │ ├── EditorEnumeratorTestWorkItem.cs
│ │ │ │ │ │ ├── EditorEnumeratorTestWorkItem.cs.meta
│ │ │ │ │ │ ├── EnumeratorStepHelper.cs
│ │ │ │ │ │ ├── EnumeratorStepHelper.cs.meta
│ │ │ │ │ │ ├── Messages/
│ │ │ │ │ │ │ ├── EnterPlayMode.cs
│ │ │ │ │ │ │ ├── EnterPlayMode.cs.meta
│ │ │ │ │ │ │ ├── ExitPlayMode.cs
│ │ │ │ │ │ │ ├── ExitPlayMode.cs.meta
│ │ │ │ │ │ │ ├── RecompileScripts.cs
│ │ │ │ │ │ │ ├── RecompileScripts.cs.meta
│ │ │ │ │ │ │ ├── WaitForDomainReload.cs
│ │ │ │ │ │ │ └── WaitForDomainReload.cs.meta
│ │ │ │ │ │ ├── Messages.meta
│ │ │ │ │ │ ├── TestFileCleanupVerifier.cs
│ │ │ │ │ │ ├── TestFileCleanupVerifier.cs.meta
│ │ │ │ │ │ ├── Utils/
│ │ │ │ │ │ │ ├── CachingTestListProvider.cs
│ │ │ │ │ │ │ ├── CachingTestListProvider.cs.meta
│ │ │ │ │ │ │ ├── EditorAssembliesProxy.cs
│ │ │ │ │ │ │ ├── EditorAssembliesProxy.cs.meta
│ │ │ │ │ │ │ ├── EditorAssemblyWrapper.cs
│ │ │ │ │ │ │ ├── EditorAssemblyWrapper.cs.meta
│ │ │ │ │ │ │ ├── EditorCompilationInterfaceProxy.cs
│ │ │ │ │ │ │ ├── EditorCompilationInterfaceProxy.cs.meta
│ │ │ │ │ │ │ ├── EditorLoadedTestAssemblyProvider.cs
│ │ │ │ │ │ │ ├── EditorLoadedTestAssemblyProvider.cs.meta
│ │ │ │ │ │ │ ├── IEditorAssembliesProxy.cs
│ │ │ │ │ │ │ ├── IEditorAssembliesProxy.cs.meta
│ │ │ │ │ │ │ ├── IEditorCompilationInterfaceProxy.cs
│ │ │ │ │ │ │ ├── IEditorCompilationInterfaceProxy.cs.meta
│ │ │ │ │ │ │ ├── ITestListCache.cs
│ │ │ │ │ │ │ ├── ITestListCache.cs.meta
│ │ │ │ │ │ │ ├── ITestListCacheData.cs
│ │ │ │ │ │ │ ├── ITestListCacheData.cs.meta
│ │ │ │ │ │ │ ├── ITestListProvider.cs
│ │ │ │ │ │ │ ├── ITestListProvider.cs.meta
│ │ │ │ │ │ │ ├── TestListCache.cs
│ │ │ │ │ │ │ ├── TestListCache.cs.meta
│ │ │ │ │ │ │ ├── TestListCacheData.cs
│ │ │ │ │ │ │ ├── TestListCacheData.cs.meta
│ │ │ │ │ │ │ ├── TestListJob.cs
│ │ │ │ │ │ │ ├── TestListJob.cs.meta
│ │ │ │ │ │ │ ├── TestListProvider.cs
│ │ │ │ │ │ │ └── TestListProvider.cs.meta
│ │ │ │ │ │ └── Utils.meta
│ │ │ │ │ ├── TestRunner.meta
│ │ │ │ │ ├── TestRunnerWindow.cs
│ │ │ │ │ ├── TestRunnerWindow.cs.meta
│ │ │ │ │ ├── TestRunnerWindowSettings.cs
│ │ │ │ │ ├── TestRunnerWindowSettings.cs.meta
│ │ │ │ │ ├── TestSettings/
│ │ │ │ │ │ ├── ITestSettings.cs
│ │ │ │ │ │ ├── ITestSettings.cs.meta
│ │ │ │ │ │ ├── ITestSettingsDeserializer.cs
│ │ │ │ │ │ ├── ITestSettingsDeserializer.cs.meta
│ │ │ │ │ │ ├── TestSettings.cs
│ │ │ │ │ │ ├── TestSettings.cs.meta
│ │ │ │ │ │ ├── TestSettingsDeserializer.cs
│ │ │ │ │ │ └── TestSettingsDeserializer.cs.meta
│ │ │ │ │ ├── TestSettings.meta
│ │ │ │ │ ├── UnityEditor.TestRunner.asmdef
│ │ │ │ │ ├── UnityEditor.TestRunner.asmdef.meta
│ │ │ │ │ ├── UnityTestProtocol/
│ │ │ │ │ │ ├── AssemblyCompilationErrorsMessage.cs
│ │ │ │ │ │ ├── AssemblyCompilationErrorsMessage.cs.meta
│ │ │ │ │ │ ├── ITestRunnerApiMapper.cs
│ │ │ │ │ │ ├── ITestRunnerApiMapper.cs.meta
│ │ │ │ │ │ ├── IUtpLogger.cs
│ │ │ │ │ │ ├── IUtpLogger.cs.meta
│ │ │ │ │ │ ├── IUtpMessageReporter.cs
│ │ │ │ │ │ ├── IUtpMessageReporter.cs.meta
│ │ │ │ │ │ ├── Message.cs
│ │ │ │ │ │ ├── Message.cs.meta
│ │ │ │ │ │ ├── TestFinishedMessage.cs
│ │ │ │ │ │ ├── TestFinishedMessage.cs.meta
│ │ │ │ │ │ ├── TestPlanMessage.cs
│ │ │ │ │ │ ├── TestPlanMessage.cs.meta
│ │ │ │ │ │ ├── TestRunnerApiMapper.cs
│ │ │ │ │ │ ├── TestRunnerApiMapper.cs.meta
│ │ │ │ │ │ ├── TestStartedMessage.cs
│ │ │ │ │ │ ├── TestStartedMessage.cs.meta
│ │ │ │ │ │ ├── TestState.cs
│ │ │ │ │ │ ├── TestState.cs.meta
│ │ │ │ │ │ ├── UnityTestProtocolListener.cs
│ │ │ │ │ │ ├── UnityTestProtocolListener.cs.meta
│ │ │ │ │ │ ├── UnityTestProtocolStarter.cs
│ │ │ │ │ │ ├── UnityTestProtocolStarter.cs.meta
│ │ │ │ │ │ ├── UtpDebuglogger.cs
│ │ │ │ │ │ ├── UtpDebuglogger.cs.meta
│ │ │ │ │ │ ├── UtpMessageReporter.cs
│ │ │ │ │ │ └── UtpMessageReporter.cs.meta
│ │ │ │ │ └── UnityTestProtocol.meta
│ │ │ │ ├── UnityEditor.TestRunner.meta
│ │ │ │ ├── UnityEngine.TestRunner/
│ │ │ │ │ ├── AssemblyInfo.cs
│ │ │ │ │ ├── AssemblyInfo.cs.meta
│ │ │ │ │ ├── Assertions/
│ │ │ │ │ │ ├── AllocatingGCMemoryConstraint.cs
│ │ │ │ │ │ ├── AllocatingGCMemoryConstraint.cs.meta
│ │ │ │ │ │ ├── ConstraintsExtensions.cs
│ │ │ │ │ │ ├── ConstraintsExtensions.cs.meta
│ │ │ │ │ │ ├── InvalidSignatureException.cs
│ │ │ │ │ │ ├── InvalidSignatureException.cs.meta
│ │ │ │ │ │ ├── Is.cs
│ │ │ │ │ │ ├── Is.cs.meta
│ │ │ │ │ │ ├── LogAssert.cs
│ │ │ │ │ │ ├── LogAssert.cs.meta
│ │ │ │ │ │ ├── LogScope/
│ │ │ │ │ │ │ ├── ILogScope.cs
│ │ │ │ │ │ │ ├── ILogScope.cs.meta
│ │ │ │ │ │ │ ├── LogEvent.cs
│ │ │ │ │ │ │ ├── LogEvent.cs.meta
│ │ │ │ │ │ │ ├── LogMatch.cs
│ │ │ │ │ │ │ ├── LogMatch.cs.meta
│ │ │ │ │ │ │ ├── LogScope.cs
│ │ │ │ │ │ │ └── LogScope.cs.meta
│ │ │ │ │ │ ├── LogScope.meta
│ │ │ │ │ │ ├── UnexpectedLogMessageException.cs
│ │ │ │ │ │ ├── UnexpectedLogMessageException.cs.meta
│ │ │ │ │ │ ├── UnhandledLogMessageException.cs
│ │ │ │ │ │ ├── UnhandledLogMessageException.cs.meta
│ │ │ │ │ │ ├── UnityTestTimeoutException.cs
│ │ │ │ │ │ └── UnityTestTimeoutException.cs.meta
│ │ │ │ │ ├── Assertions.meta
│ │ │ │ │ ├── NUnitExtensions/
│ │ │ │ │ │ ├── ActionDelegator.cs
│ │ │ │ │ │ ├── ActionDelegator.cs.meta
│ │ │ │ │ │ ├── Attributes/
│ │ │ │ │ │ │ ├── TestEnumerator.cs
│ │ │ │ │ │ │ ├── TestEnumerator.cs.meta
│ │ │ │ │ │ │ ├── UnityCombinatorialStrategy.cs
│ │ │ │ │ │ │ ├── UnityCombinatorialStrategy.cs.meta
│ │ │ │ │ │ │ ├── UnityPlatformAttribute.cs
│ │ │ │ │ │ │ ├── UnityPlatformAttribute.cs.meta
│ │ │ │ │ │ │ ├── UnitySetUpAttribute.cs
│ │ │ │ │ │ │ ├── UnitySetUpAttribute.cs.meta
│ │ │ │ │ │ │ ├── UnityTearDownAttribute.cs
│ │ │ │ │ │ │ ├── UnityTearDownAttribute.cs.meta
│ │ │ │ │ │ │ ├── UnityTestAttribute.cs
│ │ │ │ │ │ │ └── UnityTestAttribute.cs.meta
│ │ │ │ │ │ ├── Attributes.meta
│ │ │ │ │ │ ├── BaseDelegator.cs
│ │ │ │ │ │ ├── BaseDelegator.cs.meta
│ │ │ │ │ │ ├── Commands/
│ │ │ │ │ │ │ ├── BeforeAfterTestCommandBase.cs
│ │ │ │ │ │ │ ├── BeforeAfterTestCommandBase.cs.meta
│ │ │ │ │ │ │ ├── BeforeAfterTestCommandState.cs
│ │ │ │ │ │ │ ├── BeforeAfterTestCommandState.cs.meta
│ │ │ │ │ │ │ ├── EnumerableApplyChangesToContextCommand.cs
│ │ │ │ │ │ │ ├── EnumerableApplyChangesToContextCommand.cs.meta
│ │ │ │ │ │ │ ├── EnumerableSetUpTearDownCommand.cs
│ │ │ │ │ │ │ ├── EnumerableSetUpTearDownCommand.cs.meta
│ │ │ │ │ │ │ ├── EnumerableTestMethodCommand.cs
│ │ │ │ │ │ │ ├── EnumerableTestMethodCommand.cs.meta
│ │ │ │ │ │ │ ├── ImmediateEnumerableCommand.cs
│ │ │ │ │ │ │ ├── ImmediateEnumerableCommand.cs.meta
│ │ │ │ │ │ │ ├── OuterUnityTestActionCommand.cs
│ │ │ │ │ │ │ ├── OuterUnityTestActionCommand.cs.meta
│ │ │ │ │ │ │ ├── SetUpTearDownCommand.cs
│ │ │ │ │ │ │ ├── SetUpTearDownCommand.cs.meta
│ │ │ │ │ │ │ ├── TestActionCommand.cs
│ │ │ │ │ │ │ ├── TestActionCommand.cs.meta
│ │ │ │ │ │ │ ├── TestCommandPcHelper.cs
│ │ │ │ │ │ │ └── TestCommandPcHelper.cs.meta
│ │ │ │ │ │ ├── Commands.meta
│ │ │ │ │ │ ├── ConstructDelegator.cs
│ │ │ │ │ │ ├── ConstructDelegator.cs.meta
│ │ │ │ │ │ ├── Filters/
│ │ │ │ │ │ │ ├── AssemblyNameFilter.cs
│ │ │ │ │ │ │ ├── AssemblyNameFilter.cs.meta
│ │ │ │ │ │ │ ├── CategoryFilterExtended.cs
│ │ │ │ │ │ │ └── CategoryFilterExtended.cs.meta
│ │ │ │ │ │ ├── Filters.meta
│ │ │ │ │ │ ├── IStateSerializer.cs
│ │ │ │ │ │ ├── IStateSerializer.cs.meta
│ │ │ │ │ │ ├── Runner/
│ │ │ │ │ │ │ ├── CompositeWorkItem.cs
│ │ │ │ │ │ │ ├── CompositeWorkItem.cs.meta
│ │ │ │ │ │ │ ├── CoroutineTestWorkItem.cs
│ │ │ │ │ │ │ ├── CoroutineTestWorkItem.cs.meta
│ │ │ │ │ │ │ ├── DefaultTestWorkItem.cs
│ │ │ │ │ │ │ ├── DefaultTestWorkItem.cs.meta
│ │ │ │ │ │ │ ├── FailCommand.cs
│ │ │ │ │ │ │ ├── FailCommand.cs.meta
│ │ │ │ │ │ │ ├── IEnumerableTestMethodCommand.cs
│ │ │ │ │ │ │ ├── IEnumerableTestMethodCommand.cs.meta
│ │ │ │ │ │ │ ├── PlaymodeWorkItemFactory.cs
│ │ │ │ │ │ │ ├── PlaymodeWorkItemFactory.cs.meta
│ │ │ │ │ │ │ ├── RestoreTestContextAfterDomainReload.cs
│ │ │ │ │ │ │ ├── RestoreTestContextAfterDomainReload.cs.meta
│ │ │ │ │ │ │ ├── UnityLogCheckDelegatingCommand.cs
│ │ │ │ │ │ │ ├── UnityLogCheckDelegatingCommand.cs.meta
│ │ │ │ │ │ │ ├── UnityTestAssemblyRunner.cs
│ │ │ │ │ │ │ ├── UnityTestAssemblyRunner.cs.meta
│ │ │ │ │ │ │ ├── UnityTestExecutionContext.cs
│ │ │ │ │ │ │ ├── UnityTestExecutionContext.cs.meta
│ │ │ │ │ │ │ ├── UnityWorkItem.cs
│ │ │ │ │ │ │ ├── UnityWorkItem.cs.meta
│ │ │ │ │ │ │ ├── UnityWorkItemDataHolder.cs
│ │ │ │ │ │ │ ├── UnityWorkItemDataHolder.cs.meta
│ │ │ │ │ │ │ ├── WorkItemFactory.cs
│ │ │ │ │ │ │ └── WorkItemFactory.cs.meta
│ │ │ │ │ │ ├── Runner.meta
│ │ │ │ │ │ ├── TestExtensions.cs
│ │ │ │ │ │ ├── TestExtensions.cs.meta
│ │ │ │ │ │ ├── TestResultExtensions.cs
│ │ │ │ │ │ ├── TestResultExtensions.cs.meta
│ │ │ │ │ │ ├── UnityTestAssemblyBuilder.cs
│ │ │ │ │ │ └── UnityTestAssemblyBuilder.cs.meta
│ │ │ │ │ ├── NUnitExtensions.meta
│ │ │ │ │ ├── TestRunner/
│ │ │ │ │ │ ├── Callbacks/
│ │ │ │ │ │ │ ├── PlayModeRunnerCallback.cs
│ │ │ │ │ │ │ ├── PlayModeRunnerCallback.cs.meta
│ │ │ │ │ │ │ ├── RemoteTestResultSender.cs
│ │ │ │ │ │ │ ├── RemoteTestResultSender.cs.meta
│ │ │ │ │ │ │ ├── TestResultRenderer.cs
│ │ │ │ │ │ │ ├── TestResultRenderer.cs.meta
│ │ │ │ │ │ │ ├── TestResultRendererCallback.cs
│ │ │ │ │ │ │ └── TestResultRendererCallback.cs.meta
│ │ │ │ │ │ ├── Callbacks.meta
│ │ │ │ │ │ ├── ITestRunnerListener.cs
│ │ │ │ │ │ ├── ITestRunnerListener.cs.meta
│ │ │ │ │ │ ├── Messages/
│ │ │ │ │ │ │ ├── IEditModeTestYieldInstruction.cs
│ │ │ │ │ │ │ └── IEditModeTestYieldInstruction.cs.meta
│ │ │ │ │ │ ├── Messages.meta
│ │ │ │ │ │ ├── PlaymodeTestsController.cs
│ │ │ │ │ │ ├── PlaymodeTestsController.cs.meta
│ │ │ │ │ │ ├── PlaymodeTestsControllerSettings.cs
│ │ │ │ │ │ ├── PlaymodeTestsControllerSettings.cs.meta
│ │ │ │ │ │ ├── RemoteHelpers/
│ │ │ │ │ │ │ ├── IRemoteTestResultDataFactory.cs
│ │ │ │ │ │ │ ├── IRemoteTestResultDataFactory.cs.meta
│ │ │ │ │ │ │ ├── PlayerConnectionMessageIds.cs
│ │ │ │ │ │ │ ├── PlayerConnectionMessageIds.cs.meta
│ │ │ │ │ │ │ ├── RemoteTestData.cs
│ │ │ │ │ │ │ ├── RemoteTestData.cs.meta
│ │ │ │ │ │ │ ├── RemoteTestResultData.cs
│ │ │ │ │ │ │ ├── RemoteTestResultData.cs.meta
│ │ │ │ │ │ │ ├── RemoteTestResultDataFactory.cs
│ │ │ │ │ │ │ ├── RemoteTestResultDataFactory.cs.meta
│ │ │ │ │ │ │ ├── RemoteTestResultDataWithTestData.cs
│ │ │ │ │ │ │ └── RemoteTestResultDataWithTestData.cs.meta
│ │ │ │ │ │ ├── RemoteHelpers.meta
│ │ │ │ │ │ ├── TestEnumeratorWrapper.cs
│ │ │ │ │ │ ├── TestEnumeratorWrapper.cs.meta
│ │ │ │ │ │ ├── TestListenerWrapper.cs
│ │ │ │ │ │ ├── TestListenerWrapper.cs.meta
│ │ │ │ │ │ ├── TestPlatform.cs
│ │ │ │ │ │ ├── TestPlatform.cs.meta
│ │ │ │ │ │ ├── TestRunnerFilter.cs
│ │ │ │ │ │ └── TestRunnerFilter.cs.meta
│ │ │ │ │ ├── TestRunner.meta
│ │ │ │ │ ├── UnityEngine.TestRunner.asmdef
│ │ │ │ │ ├── UnityEngine.TestRunner.asmdef.meta
│ │ │ │ │ ├── Utils/
│ │ │ │ │ │ ├── AssemblyProvider/
│ │ │ │ │ │ │ ├── AssemblyLoadProxy.cs
│ │ │ │ │ │ │ ├── AssemblyLoadProxy.cs.meta
│ │ │ │ │ │ │ ├── AssemblyWrapper.cs
│ │ │ │ │ │ │ ├── AssemblyWrapper.cs.meta
│ │ │ │ │ │ │ ├── IAssemblyLoadProxy.cs
│ │ │ │ │ │ │ ├── IAssemblyLoadProxy.cs.meta
│ │ │ │ │ │ │ ├── IAssemblyWrapper.cs
│ │ │ │ │ │ │ ├── IAssemblyWrapper.cs.meta
│ │ │ │ │ │ │ ├── IScriptingRuntimeProxy.cs
│ │ │ │ │ │ │ ├── IScriptingRuntimeProxy.cs.meta
│ │ │ │ │ │ │ ├── ITestAssemblyProvider.cs
│ │ │ │ │ │ │ ├── ITestAssemblyProvider.cs.meta
│ │ │ │ │ │ │ ├── PlayerTestAssemblyProvider.cs
│ │ │ │ │ │ │ ├── PlayerTestAssemblyProvider.cs.meta
│ │ │ │ │ │ │ ├── ScriptingRuntimeProxy.cs
│ │ │ │ │ │ │ └── ScriptingRuntimeProxy.cs.meta
│ │ │ │ │ │ ├── AssemblyProvider.meta
│ │ │ │ │ │ ├── AttributeHelper.cs
│ │ │ │ │ │ ├── AttributeHelper.cs.meta
│ │ │ │ │ │ ├── ColorEqualityComparer.cs
│ │ │ │ │ │ ├── ColorEqualityComparer.cs.meta
│ │ │ │ │ │ ├── CoroutineRunner.cs
│ │ │ │ │ │ ├── CoroutineRunner.cs.meta
│ │ │ │ │ │ ├── FloatEqualityComparer.cs
│ │ │ │ │ │ ├── FloatEqualityComparer.cs.meta
│ │ │ │ │ │ ├── IOuterUnityTestAction.cs
│ │ │ │ │ │ ├── IOuterUnityTestAction.cs.meta
│ │ │ │ │ │ ├── IPostBuildCleanup.cs
│ │ │ │ │ │ ├── IPostBuildCleanup.cs.meta
│ │ │ │ │ │ ├── IPrebuildSceneSetup.cs
│ │ │ │ │ │ ├── IPrebuildSceneSetup.cs.meta
│ │ │ │ │ │ ├── MonoBehaviourTest/
│ │ │ │ │ │ │ ├── IMonoBehaviourTest.cs
│ │ │ │ │ │ │ ├── IMonoBehaviourTest.cs.meta
│ │ │ │ │ │ │ ├── MonoBehaviourTest.cs
│ │ │ │ │ │ │ └── MonoBehaviourTest.cs.meta
│ │ │ │ │ │ ├── MonoBehaviourTest.meta
│ │ │ │ │ │ ├── PostBuildCleanupAttribute.cs
│ │ │ │ │ │ ├── PostBuildCleanupAttribute.cs.meta
│ │ │ │ │ │ ├── PrebuildSceneSetupAttribute.cs
│ │ │ │ │ │ ├── PrebuildSceneSetupAttribute.cs.meta
│ │ │ │ │ │ ├── QuaternionEqualityComparer.cs
│ │ │ │ │ │ ├── QuaternionEqualityComparer.cs.meta
│ │ │ │ │ │ ├── StacktraceFilter.cs
│ │ │ │ │ │ ├── StacktraceFilter.cs.meta
│ │ │ │ │ │ ├── Utils.cs
│ │ │ │ │ │ ├── Utils.cs.meta
│ │ │ │ │ │ ├── Vector2ComparerWithEqualsOperator.cs
│ │ │ │ │ │ ├── Vector2ComparerWithEqualsOperator.cs.meta
│ │ │ │ │ │ ├── Vector2EqualityComparer.cs
│ │ │ │ │ │ ├── Vector2EqualityComparer.cs.meta
│ │ │ │ │ │ ├── Vector3ComparerWithEqualsOperator.cs
│ │ │ │ │ │ ├── Vector3ComparerWithEqualsOperator.cs.meta
│ │ │ │ │ │ ├── Vector3EqualityComparer.cs
│ │ │ │ │ │ ├── Vector3EqualityComparer.cs.meta
│ │ │ │ │ │ ├── Vector4ComparerWithEqualsOperator.cs
│ │ │ │ │ │ ├── Vector4ComparerWithEqualsOperator.cs.meta
│ │ │ │ │ │ ├── Vector4EqualityComparer.cs
│ │ │ │ │ │ └── Vector4EqualityComparer.cs.meta
│ │ │ │ │ └── Utils.meta
│ │ │ │ ├── UnityEngine.TestRunner.meta
│ │ │ │ ├── package.json
│ │ │ │ └── package.json.meta
│ │ │ └── com.unity.textmeshpro@2.0.1/
│ │ │ ├── .gitlab-ci.yml
│ │ │ ├── CHANGELOG.md
│ │ │ ├── CHANGELOG.md.meta
│ │ │ ├── Documentation~/
│ │ │ │ ├── TextMeshPro.md
│ │ │ │ └── TextMeshPro.md.meta
│ │ │ ├── Editor Resources/
│ │ │ │ ├── Gizmos/
│ │ │ │ │ ├── TMP - Dropdown Icon.psd
│ │ │ │ │ ├── TMP - Dropdown Icon.psd.meta
│ │ │ │ │ ├── TMP - Font Asset Icon.psd
│ │ │ │ │ ├── TMP - Font Asset Icon.psd.meta
│ │ │ │ │ ├── TMP - Input Field Icon.psd
│ │ │ │ │ ├── TMP - Input Field Icon.psd.meta
│ │ │ │ │ ├── TMP - Sprite Asset Icon.psd
│ │ │ │ │ ├── TMP - Sprite Asset Icon.psd.meta
│ │ │ │ │ ├── TMP - Text Component Icon.psd
│ │ │ │ │ └── TMP - Text Component Icon.psd.meta
│ │ │ │ ├── Gizmos.meta
│ │ │ │ ├── Shaders/
│ │ │ │ │ ├── TMP_Properties.cginc
│ │ │ │ │ ├── TMP_Properties.cginc.meta
│ │ │ │ │ ├── TMP_SDF Internal SSD.shader
│ │ │ │ │ └── TMP_SDF Internal SSD.shader.meta
│ │ │ │ ├── Shaders.meta
│ │ │ │ ├── Textures/
│ │ │ │ │ ├── SectionHeader_Dark.psd
│ │ │ │ │ ├── SectionHeader_Dark.psd.meta
│ │ │ │ │ ├── SectionHeader_Light.psd
│ │ │ │ │ ├── SectionHeader_Light.psd.meta
│ │ │ │ │ ├── btn_AlignBaseLine.psd
│ │ │ │ │ ├── btn_AlignBaseLine.psd.meta
│ │ │ │ │ ├── btn_AlignBaseLine_Light.psd
│ │ │ │ │ ├── btn_AlignBaseLine_Light.psd.meta
│ │ │ │ │ ├── btn_AlignBottom.psd
│ │ │ │ │ ├── btn_AlignBottom.psd.meta
│ │ │ │ │ ├── btn_AlignBottom_Light.psd
│ │ │ │ │ ├── btn_AlignBottom_Light.psd.meta
│ │ │ │ │ ├── btn_AlignCapLine.psd
│ │ │ │ │ ├── btn_AlignCapLine.psd.meta
│ │ │ │ │ ├── btn_AlignCapLine_Light.psd
│ │ │ │ │ ├── btn_AlignCapLine_Light.psd.meta
│ │ │ │ │ ├── btn_AlignCenter.psd
│ │ │ │ │ ├── btn_AlignCenter.psd.meta
│ │ │ │ │ ├── btn_AlignCenterGeo.psd
│ │ │ │ │ ├── btn_AlignCenterGeo.psd.meta
│ │ │ │ │ ├── btn_AlignCenterGeo_Light.psd
│ │ │ │ │ ├── btn_AlignCenterGeo_Light.psd.meta
│ │ │ │ │ ├── btn_AlignCenter_Light.psd
│ │ │ │ │ ├── btn_AlignCenter_Light.psd.meta
│ │ │ │ │ ├── btn_AlignFlush.psd
│ │ │ │ │ ├── btn_AlignFlush.psd.meta
│ │ │ │ │ ├── btn_AlignFlush_Light.psd
│ │ │ │ │ ├── btn_AlignFlush_Light.psd.meta
│ │ │ │ │ ├── btn_AlignJustified.psd
│ │ │ │ │ ├── btn_AlignJustified.psd.meta
│ │ │ │ │ ├── btn_AlignJustified_Light.psd
│ │ │ │ │ ├── btn_AlignJustified_Light.psd.meta
│ │ │ │ │ ├── btn_AlignLeft.psd
│ │ │ │ │ ├── btn_AlignLeft.psd.meta
│ │ │ │ │ ├── btn_AlignLeft_Light.psd
│ │ │ │ │ ├── btn_AlignLeft_Light.psd.meta
│ │ │ │ │ ├── btn_AlignMidLine.psd
│ │ │ │ │ ├── btn_AlignMidLine.psd.meta
│ │ │ │ │ ├── btn_AlignMiddle.psd
│ │ │ │ │ ├── btn_AlignMiddle.psd.meta
│ │ │ │ │ ├── btn_AlignMiddle_Light.psd
│ │ │ │ │ ├── btn_AlignMiddle_Light.psd.meta
│ │ │ │ │ ├── btn_AlignMidline_Light.psd
│ │ │ │ │ ├── btn_AlignMidline_Light.psd.meta
│ │ │ │ │ ├── btn_AlignRight.psd
│ │ │ │ │ ├── btn_AlignRight.psd.meta
│ │ │ │ │ ├── btn_AlignRight_Light.psd
│ │ │ │ │ ├── btn_AlignRight_Light.psd.meta
│ │ │ │ │ ├── btn_AlignTop.psd
│ │ │ │ │ ├── btn_AlignTop.psd.meta
│ │ │ │ │ ├── btn_AlignTop_Light.psd
│ │ │ │ │ └── btn_AlignTop_Light.psd.meta
│ │ │ │ └── Textures.meta
│ │ │ ├── Editor Resources.meta
│ │ │ ├── LICENSE.md
│ │ │ ├── LICENSE.md.meta
│ │ │ ├── Package Resources/
│ │ │ │ ├── TMP Essential Resources.unitypackage
│ │ │ │ ├── TMP Essential Resources.unitypackage.meta
│ │ │ │ ├── TMP Examples & Extras.unitypackage
│ │ │ │ └── TMP Examples & Extras.unitypackage.meta
│ │ │ ├── Package Resources.meta
│ │ │ ├── PackageConversionData.json
│ │ │ ├── PackageConversionData.json.meta
│ │ │ ├── PackageConversionData_Assets.json
│ │ │ ├── PackageConversionData_Assets.json.meta
│ │ │ ├── Scripts/
│ │ │ │ ├── Editor/
│ │ │ │ │ ├── DropdownOptionListDrawer.cs
│ │ │ │ │ ├── DropdownOptionListDrawer.cs.meta
│ │ │ │ │ ├── GlyphInfoDrawer.cs
│ │ │ │ │ ├── GlyphInfoDrawer.cs.meta
│ │ │ │ │ ├── GlyphMetricsPropertyDrawer.cs
│ │ │ │ │ ├── GlyphMetricsPropertyDrawer.cs.meta
│ │ │ │ │ ├── GlyphRectPropertyDrawer.cs
│ │ │ │ │ ├── GlyphRectPropertyDrawer.cs.meta
│ │ │ │ │ ├── TMP_BaseEditorPanel.cs
│ │ │ │ │ ├── TMP_BaseEditorPanel.cs.meta
│ │ │ │ │ ├── TMP_BaseShaderGUI.cs
│ │ │ │ │ ├── TMP_BaseShaderGUI.cs.meta
│ │ │ │ │ ├── TMP_BitmapShaderGUI.cs
│ │ │ │ │ ├── TMP_BitmapShaderGUI.cs.meta
│ │ │ │ │ ├── TMP_CharacterPropertyDrawer.cs
│ │ │ │ │ ├── TMP_CharacterPropertyDrawer.cs.meta
│ │ │ │ │ ├── TMP_ColorGradientAssetMenu.cs
│ │ │ │ │ ├── TMP_ColorGradientAssetMenu.cs.meta
│ │ │ │ │ ├── TMP_ColorGradientEditor.cs
│ │ │ │ │ ├── TMP_ColorGradientEditor.cs.meta
│ │ │ │ │ ├── TMP_DropdownEditor.cs
│ │ │ │ │ ├── TMP_DropdownEditor.cs.meta
│ │ │ │ │ ├── TMP_EditorCoroutine.cs
│ │ │ │ │ ├── TMP_EditorCoroutine.cs.meta
│ │ │ │ │ ├── TMP_EditorPanel.cs
│ │ │ │ │ ├── TMP_EditorPanel.cs.meta
│ │ │ │ │ ├── TMP_EditorUtility.cs
│ │ │ │ │ ├── TMP_EditorUtility.cs.meta
│ │ │ │ │ ├── TMP_FontAssetEditor.cs
│ │ │ │ │ ├── TMP_FontAssetEditor.cs.meta
│ │ │ │ │ ├── TMP_FontAsset_CreationMenu.cs
│ │ │ │ │ ├── TMP_FontAsset_CreationMenu.cs.meta
│ │ │ │ │ ├── TMP_GlyphPairAdjustmentRecordPropertyDrawer.cs
│ │ │ │ │ ├── TMP_GlyphPairAdjustmentRecordPropertyDrawer.cs.meta
│ │ │ │ │ ├── TMP_GlyphPropertyDrawer.cs
│ │ │ │ │ ├── TMP_GlyphPropertyDrawer.cs.meta
│ │ │ │ │ ├── TMP_InputFieldEditor.cs
│ │ │ │ │ ├── TMP_InputFieldEditor.cs.meta
│ │ │ │ │ ├── TMP_MeshRendererEditor.cs
│ │ │ │ │ ├── TMP_MeshRendererEditor.cs.meta
│ │ │ │ │ ├── TMP_PackageUtilities.cs
│ │ │ │ │ ├── TMP_PackageUtilities.cs.meta
│ │ │ │ │ ├── TMP_PostBuildProcessHandler.cs
│ │ │ │ │ ├── TMP_PostBuildProcessHandler.cs.meta
│ │ │ │ │ ├── TMP_ProjectTextSettings.cs
│ │ │ │ │ ├── TMP_ProjectTextSettings.cs.meta
│ │ │ │ │ ├── TMP_ResourcesLoader.cs
│ │ │ │ │ ├── TMP_ResourcesLoader.cs.meta
│ │ │ │ │ ├── TMP_SDFShaderGUI.cs
│ │ │ │ │ ├── TMP_SDFShaderGUI.cs.meta
│ │ │ │ │ ├── TMP_SerializedPropertyHolder.cs
│ │ │ │ │ ├── TMP_SerializedPropertyHolder.cs.meta
│ │ │ │ │ ├── TMP_SettingsEditor.cs
│ │ │ │ │ ├── TMP_SettingsEditor.cs.meta
│ │ │ │ │ ├── TMP_SpriteAssetEditor.cs
│ │ │ │ │ ├── TMP_SpriteAssetEditor.cs.meta
│ │ │ │ │ ├── TMP_SpriteAssetImporter.cs
│ │ │ │ │ ├── TMP_SpriteAssetImporter.cs.meta
│ │ │ │ │ ├── TMP_SpriteAssetMenu.cs
│ │ │ │ │ ├── TMP_SpriteAssetMenu.cs.meta
│ │ │ │ │ ├── TMP_SpriteCharacterPropertyDrawer.cs
│ │ │ │ │ ├── TMP_SpriteCharacterPropertyDrawer.cs.meta
│ │ │ │ │ ├── TMP_SpriteGlyphPropertyDrawer.cs
│ │ │ │ │ ├── TMP_SpriteGlyphPropertyDrawer.cs.meta
│ │ │ │ │ ├── TMP_StyleAssetMenu.cs
│ │ │ │ │ ├── TMP_StyleAssetMenu.cs.meta
│ │ │ │ │ ├── TMP_StyleSheetEditor.cs
│ │ │ │ │ ├── TMP_StyleSheetEditor.cs.meta
│ │ │ │ │ ├── TMP_SubMeshUI_Editor.cs
│ │ │ │ │ ├── TMP_SubMeshUI_Editor.cs.meta
│ │ │ │ │ ├── TMP_SubMesh_Editor.cs
│ │ │ │ │ ├── TMP_SubMesh_Editor.cs.meta
│ │ │ │ │ ├── TMP_TextAlignmentDrawer.cs
│ │ │ │ │ ├── TMP_TextAlignmentDrawer.cs.meta
│ │ │ │ │ ├── TMP_UIStyleManager.cs
│ │ │ │ │ ├── TMP_UIStyleManager.cs.meta
│ │ │ │ │ ├── TMP_UiEditorPanel.cs
│ │ │ │ │ ├── TMP_UiEditorPanel.cs.meta
│ │ │ │ │ ├── TMPro_ContextMenus.cs
│ │ │ │ │ ├── TMPro_ContextMenus.cs.meta
│ │ │ │ │ ├── TMPro_CreateObjectMenu.cs
│ │ │ │ │ ├── TMPro_CreateObjectMenu.cs.meta
│ │ │ │ │ ├── TMPro_EditorShaderUtilities.cs
│ │ │ │ │ ├── TMPro_EditorShaderUtilities.cs.meta
│ │ │ │ │ ├── TMPro_FontAssetCreatorWindow.cs
│ │ │ │ │ ├── TMPro_FontAssetCreatorWindow.cs.meta
│ │ │ │ │ ├── TMPro_FontPlugin.cs
│ │ │ │ │ ├── TMPro_FontPlugin.cs.meta
│ │ │ │ │ ├── TMPro_SortingLayerHelper.cs
│ │ │ │ │ ├── TMPro_SortingLayerHelper.cs.meta
│ │ │ │ │ ├── TMPro_TextContainerEditor.cs
│ │ │ │ │ ├── TMPro_TextContainerEditor.cs.meta
│ │ │ │ │ ├── TMPro_TexturePostProcessor.cs
│ │ │ │ │ ├── TMPro_TexturePostProcessor.cs.meta
│ │ │ │ │ ├── Unity.TextMeshPro.Editor.asmdef
│ │ │ │ │ └── Unity.TextMeshPro.Editor.asmdef.meta
│ │ │ │ ├── Editor.meta
│ │ │ │ ├── Runtime/
│ │ │ │ │ ├── AssemblyInfo.cs.cs
│ │ │ │ │ ├── AssemblyInfo.cs.cs.meta
│ │ │ │ │ ├── FastAction.cs
│ │ │ │ │ ├── FastAction.cs.meta
│ │ │ │ │ ├── MaterialReferenceManager.cs
│ │ │ │ │ ├── MaterialReferenceManager.cs.meta
│ │ │ │ │ ├── TMP_Asset.cs
│ │ │ │ │ ├── TMP_Asset.cs.meta
│ │ │ │ │ ├── TMP_Character.cs
│ │ │ │ │ ├── TMP_Character.cs.meta
│ │ │ │ │ ├── TMP_CharacterInfo.cs
│ │ │ │ │ ├── TMP_CharacterInfo.cs.meta
│ │ │ │ │ ├── TMP_ColorGradient.cs
│ │ │ │ │ ├── TMP_ColorGradient.cs.meta
│ │ │ │ │ ├── TMP_CoroutineTween.cs
│ │ │ │ │ ├── TMP_CoroutineTween.cs.meta
│ │ │ │ │ ├── TMP_DefaultControls.cs
│ │ │ │ │ ├── TMP_DefaultControls.cs.meta
│ │ │ │ │ ├── TMP_Dropdown.cs
│ │ │ │ │ ├── TMP_Dropdown.cs.meta
│ │ │ │ │ ├── TMP_EditorResourceManager.cs
│ │ │ │ │ ├── TMP_EditorResourceManager.cs.meta
│ │ │ │ │ ├── TMP_FontAsset.cs
│ │ │ │ │ ├── TMP_FontAsset.cs.meta
│ │ │ │ │ ├── TMP_FontAssetCommon.cs
│ │ │ │ │ ├── TMP_FontAssetCommon.cs.meta
│ │ │ │ │ ├── TMP_FontAssetUtilities.cs
│ │ │ │ │ ├── TMP_FontAssetUtilities.cs.meta
│ │ │ │ │ ├── TMP_FontFeatureTable.cs
│ │ │ │ │ ├── TMP_FontFeatureTable.cs.meta
│ │ │ │ │ ├── TMP_FontFeaturesCommon.cs
│ │ │ │ │ ├── TMP_FontFeaturesCommon.cs.meta
│ │ │ │ │ ├── TMP_InputField.cs
│ │ │ │ │ ├── TMP_InputField.cs.meta
│ │ │ │ │ ├── TMP_InputValidator.cs
│ │ │ │ │ ├── TMP_InputValidator.cs.meta
│ │ │ │ │ ├── TMP_LineInfo.cs
│ │ │ │ │ ├── TMP_LineInfo.cs.meta
│ │ │ │ │ ├── TMP_ListPool.cs
│ │ │ │ │ ├── TMP_ListPool.cs.meta
│ │ │ │ │ ├── TMP_MaterialManager.cs
│ │ │ │ │ ├── TMP_MaterialManager.cs.meta
│ │ │ │ │ ├── TMP_MeshInfo.cs
│ │ │ │ │ ├── TMP_MeshInfo.cs.meta
│ │ │ │ │ ├── TMP_ObjectPool.cs
│ │ │ │ │ ├── TMP_ObjectPool.cs.meta
│ │ │ │ │ ├── TMP_PackageResourceImporter.cs
│ │ │ │ │ ├── TMP_PackageResourceImporter.cs.meta
│ │ │ │ │ ├── TMP_RichTextTagStack.cs
│ │ │ │ │ ├── TMP_RichTextTagStack.cs.meta
│ │ │ │ │ ├── TMP_RichTextTagsCommon.cs
│ │ │ │ │ ├── TMP_RichTextTagsCommon.cs.meta
│ │ │ │ │ ├── TMP_ScrollbarEventHandler.cs
│ │ │ │ │ ├── TMP_ScrollbarEventHandler.cs.meta
│ │ │ │ │ ├── TMP_SelectionCaret.cs
│ │ │ │ │ ├── TMP_SelectionCaret.cs.meta
│ │ │ │ │ ├── TMP_Settings.cs
│ │ │ │ │ ├── TMP_Settings.cs.meta
│ │ │ │ │ ├── TMP_ShaderUtilities.cs
│ │ │ │ │ ├── TMP_ShaderUtilities.cs.meta
│ │ │ │ │ ├── TMP_Sprite.cs
│ │ │ │ │ ├── TMP_Sprite.cs.meta
│ │ │ │ │ ├── TMP_SpriteAnimator.cs
│ │ │ │ │ ├── TMP_SpriteAnimator.cs.meta
│ │ │ │ │ ├── TMP_SpriteAsset.cs
│ │ │ │ │ ├── TMP_SpriteAsset.cs.meta
│ │ │ │ │ ├── TMP_SpriteAssetImportFormats.cs
│ │ │ │ │ ├── TMP_SpriteAssetImportFormats.cs.meta
│ │ │ │ │ ├── TMP_SpriteCharacter.cs
│ │ │ │ │ ├── TMP_SpriteCharacter.cs.meta
│ │ │ │ │ ├── TMP_SpriteGlyph.cs
│ │ │ │ │ ├── TMP_SpriteGlyph.cs.meta
│ │ │ │ │ ├── TMP_Style.cs
│ │ │ │ │ ├── TMP_Style.cs.meta
│ │ │ │ │ ├── TMP_StyleSheet.cs
│ │ │ │ │ ├── TMP_StyleSheet.cs.meta
│ │ │ │ │ ├── TMP_SubMesh.cs
│ │ │ │ │ ├── TMP_SubMesh.cs.meta
│ │ │ │ │ ├── TMP_SubMeshUI.cs
│ │ │ │ │ ├── TMP_SubMeshUI.cs.meta
│ │ │ │ │ ├── TMP_Text.cs
│ │ │ │ │ ├── TMP_Text.cs.meta
│ │ │ │ │ ├── TMP_TextElement.cs
│ │ │ │ │ ├── TMP_TextElement.cs.meta
│ │ │ │ │ ├── TMP_TextElement_Legacy.cs
│ │ │ │ │ ├── TMP_TextElement_Legacy.cs.meta
│ │ │ │ │ ├── TMP_TextInfo.cs
│ │ │ │ │ ├── TMP_TextInfo.cs.meta
│ │ │ │ │ ├── TMP_TextParsingUtilities.cs
│ │ │ │ │ ├── TMP_TextParsingUtilities.cs.meta
│ │ │ │ │ ├── TMP_TextUtilities.cs
│ │ │ │ │ ├── TMP_TextUtilities.cs.meta
│ │ │ │ │ ├── TMP_UpdateManager.cs
│ │ │ │ │ ├── TMP_UpdateManager.cs.meta
│ │ │ │ │ ├── TMP_UpdateRegistery.cs
│ │ │ │ │ ├── TMP_UpdateRegistery.cs.meta
│ │ │ │ │ ├── TMPro_EventManager.cs
│ │ │ │ │ ├── TMPro_EventManager.cs.meta
│ │ │ │ │ ├── TMPro_ExtensionMethods.cs
│ │ │ │ │ ├── TMPro_ExtensionMethods.cs.meta
│ │ │ │ │ ├── TMPro_MeshUtilities.cs
│ │ │ │ │ ├── TMPro_MeshUtilities.cs.meta
│ │ │ │ │ ├── TMPro_Private.cs
│ │ │ │ │ ├── TMPro_Private.cs.meta
│ │ │ │ │ ├── TMPro_UGUI_Private.cs
│ │ │ │ │ ├── TMPro_UGUI_Private.cs.meta
│ │ │ │ │ ├── TextContainer.cs
│ │ │ │ │ ├── TextContainer.cs.meta
│ │ │ │ │ ├── TextMeshPro.cs
│ │ │ │ │ ├── TextMeshPro.cs.meta
│ │ │ │ │ ├── TextMeshProUGUI.cs
│ │ │ │ │ ├── TextMeshProUGUI.cs.meta
│ │ │ │ │ ├── Unity.TextMeshPro.asmdef
│ │ │ │ │ └── Unity.TextMeshPro.asmdef.meta
│ │ │ │ └── Runtime.meta
│ │ │ ├── Scripts.meta
│ │ │ ├── Tests/
│ │ │ │ ├── Editor/
│ │ │ │ │ ├── TMP_EditorTests.cs
│ │ │ │ │ ├── TMP_EditorTests.cs.meta
│ │ │ │ │ ├── Unity.TextMeshPro.Editor.Tests.asmdef
│ │ │ │ │ └── Unity.TextMeshPro.Editor.Tests.asmdef.meta
│ │ │ │ ├── Editor.meta
│ │ │ │ ├── Runtime/
│ │ │ │ │ ├── TMP_RuntimeTests.cs
│ │ │ │ │ ├── TMP_RuntimeTests.cs.meta
│ │ │ │ │ ├── Unity.TextMeshPro.Tests.asmdef
│ │ │ │ │ └── Unity.TextMeshPro.Tests.asmdef.meta
│ │ │ │ └── Runtime.meta
│ │ │ ├── Tests.meta
│ │ │ ├── package.json
│ │ │ └── package.json.meta
│ │ ├── ProjectSettings.asset
│ │ ├── SceneVisibilityState.asset
│ │ ├── ScriptAssemblies/
│ │ │ ├── Assembly-CSharp-Editor.pdb
│ │ │ ├── Assembly-CSharp.pdb
│ │ │ ├── BuiltinAssemblies.stamp
│ │ │ ├── Unity.CollabProxy.Editor.pdb
│ │ │ ├── Unity.Rider.Editor.pdb
│ │ │ ├── Unity.TextMeshPro.Editor.pdb
│ │ │ ├── Unity.TextMeshPro.pdb
│ │ │ ├── Unity.Timeline.Editor.pdb
│ │ │ ├── Unity.Timeline.pdb
│ │ │ ├── Unity.VSCode.Editor.pdb
│ │ │ ├── UnityEditor.TestRunner.pdb
│ │ │ ├── UnityEditor.UI.pdb
│ │ │ ├── UnityEngine.TestRunner.pdb
│ │ │ └── UnityEngine.UI.pdb
│ │ ├── ScriptMapper
│ │ ├── SpriteAtlasDatabase.asset
│ │ ├── StateCache/
│ │ │ ├── Hierarchy/
│ │ │ │ └── d2da7c-mainStage.json
│ │ │ ├── LayerSettings/
│ │ │ │ └── LayerSettings.json
│ │ │ └── SceneView/
│ │ │ └── e16c04-mainStage.json
│ │ ├── Style.catalog
│ │ ├── assetDatabase3
│ │ ├── expandedItems
│ │ ├── metadata/
│ │ │ ├── 00/
│ │ │ │ ├── 00000000000000001000000000000000
│ │ │ │ ├── 00000000000000001000000000000000.info
│ │ │ │ ├── 00000000000000002000000000000000
│ │ │ │ ├── 00000000000000002000000000000000.info
│ │ │ │ ├── 00000000000000003000000000000000
│ │ │ │ ├── 00000000000000003000000000000000.info
│ │ │ │ ├── 00000000000000004000000000000000
│ │ │ │ ├── 00000000000000004000000000000000.info
│ │ │ │ ├── 00000000000000004100000000000000
│ │ │ │ ├── 00000000000000004100000000000000.info
│ │ │ │ ├── 00000000000000005000000000000000
│ │ │ │ ├── 00000000000000005000000000000000.info
│ │ │ │ ├── 00000000000000005100000000000000
│ │ │ │ ├── 00000000000000005100000000000000.info
│ │ │ │ ├── 00000000000000006000000000000000
│ │ │ │ ├── 00000000000000006000000000000000.info
│ │ │ │ ├── 00000000000000006100000000000000
│ │ │ │ ├── 00000000000000006100000000000000.info
│ │ │ │ ├── 00000000000000007000000000000000
│ │ │ │ ├── 00000000000000007000000000000000.info
│ │ │ │ ├── 00000000000000007100000000000000
│ │ │ │ ├── 00000000000000007100000000000000.info
│ │ │ │ ├── 00000000000000008000000000000000
│ │ │ │ ├── 00000000000000008000000000000000.info
│ │ │ │ ├── 00000000000000009000000000000000
│ │ │ │ ├── 00000000000000009000000000000000.info
│ │ │ │ ├── 0000000000000000a100000000000000
│ │ │ │ ├── 0000000000000000a100000000000000.info
│ │ │ │ ├── 0000000000000000b000000000000000
│ │ │ │ ├── 0000000000000000b000000000000000.info
│ │ │ │ ├── 0000000000000000b100000000000000
│ │ │ │ ├── 0000000000000000b100000000000000.info
│ │ │ │ ├── 0000000000000000c000000000000000
│ │ │ │ ├── 0000000000000000c000000000000000.info
│ │ │ │ ├── 0000000000000000c100000000000000
│ │ │ │ ├── 0000000000000000c100000000000000.info
│ │ │ │ ├── 00187582b67e7654b914b5a0d37daafb
│ │ │ │ ├── 00187582b67e7654b914b5a0d37daafb.info
│ │ │ │ ├── 006633c8a6f4ae94aa9babf72234e1a2
│ │ │ │ ├── 006633c8a6f4ae94aa9babf72234e1a2.info
│ │ │ │ ├── 00f9a68859b850648902e0c98c25b590
│ │ │ │ └── 00f9a68859b850648902e0c98c25b590.info
│ │ │ ├── 01/
│ │ │ │ ├── 01ada73c4792aba4c937ff5d92cce866
│ │ │ │ ├── 01ada73c4792aba4c937ff5d92cce866.info
│ │ │ │ ├── 01cd96d8687272f4898cfd1562079dd7
│ │ │ │ ├── 01cd96d8687272f4898cfd1562079dd7.info
│ │ │ │ ├── 01df650e1b86e9f4a8e2b5dc9782506f
│ │ │ │ └── 01df650e1b86e9f4a8e2b5dc9782506f.info
│ │ │ ├── 02/
│ │ │ │ ├── 020ee4c1798a3d243a4b8cbfee6cac2d
│ │ │ │ ├── 020ee4c1798a3d243a4b8cbfee6cac2d.info
│ │ │ │ ├── 0217a80286f79419daa202f69409f19b
│ │ │ │ ├── 0217a80286f79419daa202f69409f19b.info
│ │ │ │ ├── 0232a25926bfdf945abd3ccb4519aac3
│ │ │ │ ├── 0232a25926bfdf945abd3ccb4519aac3.info
│ │ │ │ ├── 02893ffb522b490a9fa28eedd2584309
│ │ │ │ ├── 02893ffb522b490a9fa28eedd2584309.info
│ │ │ │ ├── 02e1fe0a338b35545a5fed1345848332
│ │ │ │ ├── 02e1fe0a338b35545a5fed1345848332.info
│ │ │ │ ├── 02e622e7baa59ac449d2c5f5bc992795
│ │ │ │ ├── 02e622e7baa59ac449d2c5f5bc992795.info
│ │ │ │ ├── 02f771204943f4a40949438e873e3eff
│ │ │ │ └── 02f771204943f4a40949438e873e3eff.info
│ │ │ ├── 03/
│ │ │ │ ├── 030f85c3f73729f4f976f66ffb23b875
│ │ │ │ ├── 030f85c3f73729f4f976f66ffb23b875.info
│ │ │ │ ├── 0336a32a79bfaed43a3fd2d88b91e974
│ │ │ │ ├── 0336a32a79bfaed43a3fd2d88b91e974.info
│ │ │ │ ├── 033c884ba52437d49bc55935939ef1c6
│ │ │ │ ├── 033c884ba52437d49bc55935939ef1c6.info
│ │ │ │ ├── 0386b6eb838c47138cd51d1c1b879a35
│ │ │ │ ├── 0386b6eb838c47138cd51d1c1b879a35.info
│ │ │ │ ├── 03e4d63665d06f04c8a6cf68133c1592
│ │ │ │ └── 03e4d63665d06f04c8a6cf68133c1592.info
│ │ │ ├── 04/
│ │ │ │ ├── 046c3854296c5ec48bac50da6ca248ec
│ │ │ │ ├── 046c3854296c5ec48bac50da6ca248ec.info
│ │ │ │ ├── 04cc958f40f350044a432c012f320305
│ │ │ │ └── 04cc958f40f350044a432c012f320305.info
│ │ │ ├── 05/
│ │ │ │ ├── 056819c66570ca54cadb72330a354050
│ │ │ │ ├── 056819c66570ca54cadb72330a354050.info
│ │ │ │ ├── 05778dd1de4433d418793b6f3d3c18cf
│ │ │ │ ├── 05778dd1de4433d418793b6f3d3c18cf.info
│ │ │ │ ├── 058cba836c1846c3aa1c5fd2e28aea77
│ │ │ │ ├── 058cba836c1846c3aa1c5fd2e28aea77.info
│ │ │ │ ├── 05f582d4fbc8e0c40afccb76bbbe0935
│ │ │ │ ├── 05f582d4fbc8e0c40afccb76bbbe0935.info
│ │ │ │ ├── 05f5bfd584002f948982a1498890f9a9
│ │ │ │ ├── 05f5bfd584002f948982a1498890f9a9.info
│ │ │ │ ├── 05f7f519769978b79b31d063a7fc6fa1
│ │ │ │ ├── 05f7f519769978b79b31d063a7fc6fa1.info
│ │ │ │ ├── 05f92e4a2414cb144a92157752dfa324
│ │ │ │ └── 05f92e4a2414cb144a92157752dfa324.info
│ │ │ ├── 06/
│ │ │ │ ├── 066619c9c9c84f89acb1b48c11a7efe2
│ │ │ │ ├── 066619c9c9c84f89acb1b48c11a7efe2.info
│ │ │ │ ├── 06ae1baf5524b314fa65b173b9eca869
│ │ │ │ ├── 06ae1baf5524b314fa65b173b9eca869.info
│ │ │ │ ├── 06bfdc59aae5325499d5beef3aa3d013
│ │ │ │ └── 06bfdc59aae5325499d5beef3aa3d013.info
│ │ │ ├── 07/
│ │ │ │ ├── 071c17858dc6c47ada7b2a1f1ded5402
│ │ │ │ ├── 071c17858dc6c47ada7b2a1f1ded5402.info
│ │ │ │ ├── 077690d334440b044bdd51b26b3e9413
│ │ │ │ ├── 077690d334440b044bdd51b26b3e9413.info
│ │ │ │ ├── 07994bfe8b0e4adb97d706de5dea48d5
│ │ │ │ ├── 07994bfe8b0e4adb97d706de5dea48d5.info
│ │ │ │ ├── 07a967d2fca95324f8922df8394a5655
│ │ │ │ ├── 07a967d2fca95324f8922df8394a5655.info
│ │ │ │ ├── 07ea0326ed848fb4489187cb58f96113
│ │ │ │ └── 07ea0326ed848fb4489187cb58f96113.info
│ │ │ ├── 08/
│ │ │ │ ├── 083c6a3a5426382449369ddc12b691d8
│ │ │ │ ├── 083c6a3a5426382449369ddc12b691d8.info
│ │ │ │ ├── 087cba9fa6ac867479a0b0fdc0a5864b
│ │ │ │ ├── 087cba9fa6ac867479a0b0fdc0a5864b.info
│ │ │ │ ├── 08d23c0b73905c148b525c3c93fff580
│ │ │ │ ├── 08d23c0b73905c148b525c3c93fff580.info
│ │ │ │ ├── 08e9894bdf0834710b22d3c0aa245ac0
│ │ │ │ └── 08e9894bdf0834710b22d3c0aa245ac0.info
│ │ │ ├── 09/
│ │ │ │ ├── 09e28640d754a611467eebfb261ed749
│ │ │ │ ├── 09e28640d754a611467eebfb261ed749.info
│ │ │ │ ├── 09e68d8a529a36340b752b99a1b70f83
│ │ │ │ ├── 09e68d8a529a36340b752b99a1b70f83.info
│ │ │ │ ├── 09f4db536a377bc40a9ac110af702bfa
│ │ │ │ └── 09f4db536a377bc40a9ac110af702bfa.info
│ │ │ ├── 0a/
│ │ │ │ ├── 0a017569bfe174e4890797b4d64cbabc
│ │ │ │ ├── 0a017569bfe174e4890797b4d64cbabc.info
│ │ │ │ ├── 0aaa057ce5566e940b18a0ccd0344693
│ │ │ │ ├── 0aaa057ce5566e940b18a0ccd0344693.info
│ │ │ │ ├── 0acc523941302664db1f4e527237feb3
│ │ │ │ └── 0acc523941302664db1f4e527237feb3.info
│ │ │ ├── 0b/
│ │ │ │ ├── 0b2706df6fdff50448f84a3f6629b40f
│ │ │ │ ├── 0b2706df6fdff50448f84a3f6629b40f.info
│ │ │ │ ├── 0bb74b1c097396c49b1691e6a938f814
│ │ │ │ └── 0bb74b1c097396c49b1691e6a938f814.info
│ │ │ ├── 0c/
│ │ │ │ ├── 0c04c8cb23b78e04492e0f310cdee93e
│ │ │ │ ├── 0c04c8cb23b78e04492e0f310cdee93e.info
│ │ │ │ ├── 0c56471f08a0f6846afc792f0b4205b9
│ │ │ │ ├── 0c56471f08a0f6846afc792f0b4205b9.info
│ │ │ │ ├── 0ca2545d76d1fb34fa45a9f1e432d259
│ │ │ │ ├── 0ca2545d76d1fb34fa45a9f1e432d259.info
│ │ │ │ ├── 0ca81982e37e893498abf804c12a22c7
│ │ │ │ ├── 0ca81982e37e893498abf804c12a22c7.info
│ │ │ │ ├── 0cb14878543cf3d4f8472b15f7ecf0e3
│ │ │ │ ├── 0cb14878543cf3d4f8472b15f7ecf0e3.info
│ │ │ │ ├── 0cd44c1031e13a943bb63640046fad76
│ │ │ │ └── 0cd44c1031e13a943bb63640046fad76.info
│ │ │ ├── 0d/
│ │ │ │ ├── 0d0b652f32a2cc243917e4028fa0f046
│ │ │ │ ├── 0d0b652f32a2cc243917e4028fa0f046.info
│ │ │ │ ├── 0d2d0f36e67d4518a07df76235e91f9a
│ │ │ │ ├── 0d2d0f36e67d4518a07df76235e91f9a.info
│ │ │ │ ├── 0d4fc309a0784294c8ab658b53b12320
│ │ │ │ ├── 0d4fc309a0784294c8ab658b53b12320.info
│ │ │ │ ├── 0d60a406ab64c434e9d731914e11a51e
│ │ │ │ ├── 0d60a406ab64c434e9d731914e11a51e.info
│ │ │ │ ├── 0d9a36012a224080966c7b55896aa0f9
│ │ │ │ ├── 0d9a36012a224080966c7b55896aa0f9.info
│ │ │ │ ├── 0dc62a5955cf04ec298a2c3ca4b2edf2
│ │ │ │ ├── 0dc62a5955cf04ec298a2c3ca4b2edf2.info
│ │ │ │ ├── 0de03ebd74e2b474fa23d05ab42d0cd8
│ │ │ │ └── 0de03ebd74e2b474fa23d05ab42d0cd8.info
│ │ │ ├── 0e/
│ │ │ │ ├── 0e0afa652c0031c48896a97b424d027b
│ │ │ │ ├── 0e0afa652c0031c48896a97b424d027b.info
│ │ │ │ ├── 0e751e877ed14d71a6b8e63ac54949cf
│ │ │ │ ├── 0e751e877ed14d71a6b8e63ac54949cf.info
│ │ │ │ ├── 0efb23ecb373b6d4bbe5217485785138
│ │ │ │ └── 0efb23ecb373b6d4bbe5217485785138.info
│ │ │ ├── 0f/
│ │ │ │ ├── 0f71aeefaa877ae4787e8356f25ad1e5
│ │ │ │ └── 0f71aeefaa877ae4787e8356f25ad1e5.info
│ │ │ ├── 10/
│ │ │ │ ├── 102e512f651ee834f951a2516c1ea3b8
│ │ │ │ ├── 102e512f651ee834f951a2516c1ea3b8.info
│ │ │ │ ├── 1048a87135154606808bf2030da32d18
│ │ │ │ ├── 1048a87135154606808bf2030da32d18.info
│ │ │ │ ├── 105515c1653548242b4fe973c0f375f7
│ │ │ │ ├── 105515c1653548242b4fe973c0f375f7.info
│ │ │ │ ├── 1091bc2ad06e3234aac2b2fa2841c09d
│ │ │ │ ├── 1091bc2ad06e3234aac2b2fa2841c09d.info
│ │ │ │ ├── 10ba9bc9317e315439b0223674162c52
│ │ │ │ └── 10ba9bc9317e315439b0223674162c52.info
│ │ │ ├── 11/
│ │ │ │ ├── 110d5035a36a6a34580fb65bb40cd78f
│ │ │ │ ├── 110d5035a36a6a34580fb65bb40cd78f.info
│ │ │ │ ├── 1158e311a3101950348dcecb1bebc42d
│ │ │ │ ├── 1158e311a3101950348dcecb1bebc42d.info
│ │ │ │ ├── 11a6a034ab84493cbed6af5ae7aae78b
│ │ │ │ └── 11a6a034ab84493cbed6af5ae7aae78b.info
│ │ │ ├── 12/
│ │ │ │ ├── 124533853216377448d786fd7c725701
│ │ │ │ ├── 124533853216377448d786fd7c725701.info
│ │ │ │ ├── 127023922adddf744b59fa7b0b0c3030
│ │ │ │ ├── 127023922adddf744b59fa7b0b0c3030.info
│ │ │ │ ├── 12736c98af174f91827a26b66d2b01b9
│ │ │ │ ├── 12736c98af174f91827a26b66d2b01b9.info
│ │ │ │ ├── 12c42068351bb084abde965d725b9887
│ │ │ │ ├── 12c42068351bb084abde965d725b9887.info
│ │ │ │ ├── 12dfd4bdbb5c8e6419432fbc54ef25d9
│ │ │ │ └── 12dfd4bdbb5c8e6419432fbc54ef25d9.info
│ │ │ ├── 13/
│ │ │ │ ├── 1336690ece4db2740b4ba38873e00dfb
│ │ │ │ ├── 1336690ece4db2740b4ba38873e00dfb.info
│ │ │ │ ├── 1344c3c82d62a2a41a3576d8abb8e3ea
│ │ │ │ ├── 1344c3c82d62a2a41a3576d8abb8e3ea.info
│ │ │ │ ├── 1369382d2c5e64dc5b2ec0b6b0a94531
│ │ │ │ ├── 1369382d2c5e64dc5b2ec0b6b0a94531.info
│ │ │ │ ├── 1385bc74f3945c943be16ecbb1381063
│ │ │ │ ├── 1385bc74f3945c943be16ecbb1381063.info
│ │ │ │ ├── 1389c6be1c6e80b4eb8604aabdda8255
│ │ │ │ ├── 1389c6be1c6e80b4eb8604aabdda8255.info
│ │ │ │ ├── 138dbec4f8742654fbceb0a19d68b9c5
│ │ │ │ ├── 138dbec4f8742654fbceb0a19d68b9c5.info
│ │ │ │ ├── 139c5eac101a4dc4fb3098e30c29f15e
│ │ │ │ ├── 139c5eac101a4dc4fb3098e30c29f15e.info
│ │ │ │ ├── 13a9c1b4df2e489e8eb9cacca7429596
│ │ │ │ ├── 13a9c1b4df2e489e8eb9cacca7429596.info
│ │ │ │ ├── 13cd966480ec3354bb318ee1aeccff6f
│ │ │ │ ├── 13cd966480ec3354bb318ee1aeccff6f.info
│ │ │ │ ├── 13d161b14bb3ab74e8a9634e26fb7a5e
│ │ │ │ ├── 13d161b14bb3ab74e8a9634e26fb7a5e.info
│ │ │ │ ├── 13eb80ce50ac9c43cdbaf2109c0ec7db
│ │ │ │ └── 13eb80ce50ac9c43cdbaf2109c0ec7db.info
│ │ │ ├── 14/
│ │ │ │ ├── 14427eecd0bccea468addc3492aaef57
│ │ │ │ ├── 14427eecd0bccea468addc3492aaef57.info
│ │ │ │ ├── 1489c7cdbe26c444b86705280ebdff02
│ │ │ │ ├── 1489c7cdbe26c444b86705280ebdff02.info
│ │ │ │ ├── 14d748c963c7b3549bed45457cc92c4f
│ │ │ │ └── 14d748c963c7b3549bed45457cc92c4f.info
│ │ │ ├── 15/
│ │ │ │ ├── 1511ccae7919cfc46b603b9b337fdc94
│ │ │ │ ├── 1511ccae7919cfc46b603b9b337fdc94.info
│ │ │ │ ├── 15225778e2107e44bb700adf9df97a60
│ │ │ │ ├── 15225778e2107e44bb700adf9df97a60.info
│ │ │ │ ├── 15c38f6fa1940124db1ab7f6fe7268d1
│ │ │ │ ├── 15c38f6fa1940124db1ab7f6fe7268d1.info
│ │ │ │ ├── 15e0374501f39d54eb30235764636e0e
│ │ │ │ ├── 15e0374501f39d54eb30235764636e0e.info
│ │ │ │ ├── 15f870c6975ad6449b5b52514b90dc2b
│ │ │ │ └── 15f870c6975ad6449b5b52514b90dc2b.info
│ │ │ ├── 16/
│ │ │ │ ├── 16388ae022a89264b84107f0c1b44680
│ │ │ │ ├── 16388ae022a89264b84107f0c1b44680.info
│ │ │ │ ├── 164c9b1458eaab743a4b45c37a4d720d
│ │ │ │ ├── 164c9b1458eaab743a4b45c37a4d720d.info
│ │ │ │ ├── 16548db454f7a3344b41ca2e5cdb52b2
│ │ │ │ ├── 16548db454f7a3344b41ca2e5cdb52b2.info
│ │ │ │ ├── 167329c8289a3a14a9e342df49fc4104
│ │ │ │ ├── 167329c8289a3a14a9e342df49fc4104.info
│ │ │ │ ├── 16950289b516d6747868e0f7bf7b37a0
│ │ │ │ ├── 16950289b516d6747868e0f7bf7b37a0.info
│ │ │ │ ├── 16c6414b77a90ff4098767dce485c495
│ │ │ │ └── 16c6414b77a90ff4098767dce485c495.info
│ │ │ ├── 17/
│ │ │ │ ├── 178008567c08e6d84014fa87825d10bb
│ │ │ │ └── 178008567c08e6d84014fa87825d10bb.info
│ │ │ ├── 18/
│ │ │ │ ├── 1852920dca83b454c8e49493d9ead74c
│ │ │ │ ├── 1852920dca83b454c8e49493d9ead74c.info
│ │ │ │ ├── 18775b51e3bd42299fd30bd036ea982f
│ │ │ │ ├── 18775b51e3bd42299fd30bd036ea982f.info
│ │ │ │ ├── 18a4fadfef534684d5af39ca8dc48fe9
│ │ │ │ └── 18a4fadfef534684d5af39ca8dc48fe9.info
│ │ │ ├── 19/
│ │ │ │ ├── 197c1114eb793d24c8ef31120a134e88
│ │ │ │ ├── 197c1114eb793d24c8ef31120a134e88.info
│ │ │ │ ├── 1999349e7f492c947bb6eb70f624382e
│ │ │ │ ├── 1999349e7f492c947bb6eb70f624382e.info
│ │ │ │ ├── 19a6f000f81e24c4a826c1abd43e77c7
│ │ │ │ ├── 19a6f000f81e24c4a826c1abd43e77c7.info
│ │ │ │ ├── 19c6f364c1e81cb4f829a057824639ad
│ │ │ │ └── 19c6f364c1e81cb4f829a057824639ad.info
│ │ │ ├── 1a/
│ │ │ │ ├── 1a26e19d51cbfac42a02631ad1f9e39e
│ │ │ │ ├── 1a26e19d51cbfac42a02631ad1f9e39e.info
│ │ │ │ ├── 1a34c77a67cf21c4b8523a435293645b
│ │ │ │ ├── 1a34c77a67cf21c4b8523a435293645b.info
│ │ │ │ ├── 1a4266815e998967becf686f9c71f0a6
│ │ │ │ ├── 1a4266815e998967becf686f9c71f0a6.info
│ │ │ │ ├── 1a70a790a43cd0d4a96f75746841f764
│ │ │ │ ├── 1a70a790a43cd0d4a96f75746841f764.info
│ │ │ │ ├── 1a7a541ac0259ac4e8570ac8c3510dfe
│ │ │ │ ├── 1a7a541ac0259ac4e8570ac8c3510dfe.info
│ │ │ │ ├── 1aa08ab6e0800fa44ae55d278d1423e3
│ │ │ │ ├── 1aa08ab6e0800fa44ae55d278d1423e3.info
│ │ │ │ ├── 1ac58cb55fc8daf4abd3945a2bbbb0c5
│ │ │ │ ├── 1ac58cb55fc8daf4abd3945a2bbbb0c5.info
│ │ │ │ ├── 1ac677c5ece15b443b2aaf7fae5842f7
│ │ │ │ ├── 1ac677c5ece15b443b2aaf7fae5842f7.info
│ │ │ │ ├── 1ad55f5ad04d1d045a1f287409c650dd
│ │ │ │ ├── 1ad55f5ad04d1d045a1f287409c650dd.info
│ │ │ │ ├── 1adaa8dcc4fda3d4cb4d3c8e0cb65d12
│ │ │ │ ├── 1adaa8dcc4fda3d4cb4d3c8e0cb65d12.info
│ │ │ │ ├── 1adad61bfb44214ee3e887b5febc4396
│ │ │ │ └── 1adad61bfb44214ee3e887b5febc4396.info
│ │ │ ├── 1b/
│ │ │ │ ├── 1b0a41d64d4e9534481f804049080fbb
│ │ │ │ ├── 1b0a41d64d4e9534481f804049080fbb.info
│ │ │ │ ├── 1b199a26663a15b4db765ffb1df401f2
│ │ │ │ ├── 1b199a26663a15b4db765ffb1df401f2.info
│ │ │ │ ├── 1b393f6b29a9ee84c803af1ab4944b71
│ │ │ │ ├── 1b393f6b29a9ee84c803af1ab4944b71.info
│ │ │ │ ├── 1bbfba4363c8e1e4b8214b4004316ce5
│ │ │ │ ├── 1bbfba4363c8e1e4b8214b4004316ce5.info
│ │ │ │ ├── 1bfe12aa306c0c74db4f4f1a1a0ae5ce
│ │ │ │ └── 1bfe12aa306c0c74db4f4f1a1a0ae5ce.info
│ │ │ ├── 1c/
│ │ │ │ ├── 1c147d10db452eb4b854a35f84472017
│ │ │ │ ├── 1c147d10db452eb4b854a35f84472017.info
│ │ │ │ ├── 1c5afe945b715e149a70113a4be7b32a
│ │ │ │ ├── 1c5afe945b715e149a70113a4be7b32a.info
│ │ │ │ ├── 1c61a04a5b7737c4d16673d64be4194e
│ │ │ │ ├── 1c61a04a5b7737c4d16673d64be4194e.info
│ │ │ │ ├── 1cd98b0d17936ed43bed805e1a150a88
│ │ │ │ ├── 1cd98b0d17936ed43bed805e1a150a88.info
│ │ │ │ ├── 1cddf785b0d07434d8e0607c97b09135
│ │ │ │ ├── 1cddf785b0d07434d8e0607c97b09135.info
│ │ │ │ ├── 1cf2469083ffa484da4d78dd70d708e8
│ │ │ │ └── 1cf2469083ffa484da4d78dd70d708e8.info
│ │ │ ├── 1d/
│ │ │ │ ├── 1d446e57147ca9b4183edfbbfa9bf206
│ │ │ │ ├── 1d446e57147ca9b4183edfbbfa9bf206.info
│ │ │ │ ├── 1d93ffb668978f7488211a331977b73b
│ │ │ │ ├── 1d93ffb668978f7488211a331977b73b.info
│ │ │ │ ├── 1db879070d9a45f4c86cdf5e59616df5
│ │ │ │ ├── 1db879070d9a45f4c86cdf5e59616df5.info
│ │ │ │ ├── 1ddb9e1c877ea80479d1eab4ddaa5d0d
│ │ │ │ └── 1ddb9e1c877ea80479d1eab4ddaa5d0d.info
│ │ │ ├── 1e/
│ │ │ │ ├── 1e5ee557da46d59498c484308be5067e
│ │ │ │ ├── 1e5ee557da46d59498c484308be5067e.info
│ │ │ │ ├── 1ea10891dd782154ca0fb67bce9e6f72
│ │ │ │ ├── 1ea10891dd782154ca0fb67bce9e6f72.info
│ │ │ │ ├── 1ebc1994f9a3d5649a1201d3a84b38df
│ │ │ │ ├── 1ebc1994f9a3d5649a1201d3a84b38df.info
│ │ │ │ ├── 1ec4b8ec4b34f4344bac53c19288eaa2
│ │ │ │ ├── 1ec4b8ec4b34f4344bac53c19288eaa2.info
│ │ │ │ ├── 1ef2923b9c5521948a04299da53ae750
│ │ │ │ └── 1ef2923b9c5521948a04299da53ae750.info
│ │ │ ├── 1f/
│ │ │ │ ├── 1f2a7e0d1b6bbba408a41e206945c23c
│ │ │ │ ├── 1f2a7e0d1b6bbba408a41e206945c23c.info
│ │ │ │ ├── 1f3a562675833b4448299e4f627b0cec
│ │ │ │ ├── 1f3a562675833b4448299e4f627b0cec.info
│ │ │ │ ├── 1f5bbb88ca730434483440cbc0278ef6
│ │ │ │ ├── 1f5bbb88ca730434483440cbc0278ef6.info
│ │ │ │ ├── 1fe0f539450e54dbc85bfb2fa6b466fb
│ │ │ │ └── 1fe0f539450e54dbc85bfb2fa6b466fb.info
│ │ │ ├── 20/
│ │ │ │ ├── 200617708f5b36a4da2e2a3f1ceacedd
│ │ │ │ ├── 200617708f5b36a4da2e2a3f1ceacedd.info
│ │ │ │ ├── 2011a59d3f76b3d4a85cb53f945fceee
│ │ │ │ ├── 2011a59d3f76b3d4a85cb53f945fceee.info
│ │ │ │ ├── 202d758d102b6854a9710c8b93db742c
│ │ │ │ ├── 202d758d102b6854a9710c8b93db742c.info
│ │ │ │ ├── 20793418366caf14293b29c55df5e9ec
│ │ │ │ ├── 20793418366caf14293b29c55df5e9ec.info
│ │ │ │ ├── 208e46d59ff6e304db0318377d20f5a1
│ │ │ │ ├── 208e46d59ff6e304db0318377d20f5a1.info
│ │ │ │ ├── 20a9b557a46149dfbfa04a3a7080f5aa
│ │ │ │ ├── 20a9b557a46149dfbfa04a3a7080f5aa.info
│ │ │ │ ├── 20c8bb6b47a526c4c96ca73314fe2856
│ │ │ │ ├── 20c8bb6b47a526c4c96ca73314fe2856.info
│ │ │ │ ├── 20cdb37e6fea6d946bbb84d2c923db85
│ │ │ │ ├── 20cdb37e6fea6d946bbb84d2c923db85.info
│ │ │ │ ├── 20ff4283f687e044087714f82c4d6d3f
│ │ │ │ └── 20ff4283f687e044087714f82c4d6d3f.info
│ │ │ ├── 21/
│ │ │ │ ├── 212a65848ed53294788b2731538c9d66
│ │ │ │ ├── 212a65848ed53294788b2731538c9d66.info
│ │ │ │ ├── 218eacd3a7686dd4d875c191fdaa058c
│ │ │ │ ├── 218eacd3a7686dd4d875c191fdaa058c.info
│ │ │ │ ├── 21bf7f712d84d26478ebe6a299f21738
│ │ │ │ ├── 21bf7f712d84d26478ebe6a299f21738.info
│ │ │ │ ├── 21c0044a7f964773be90d197a78e4703
│ │ │ │ ├── 21c0044a7f964773be90d197a78e4703.info
│ │ │ │ ├── 21d2d5d6901f2ca43a8015c60ada4e2c
│ │ │ │ └── 21d2d5d6901f2ca43a8015c60ada4e2c.info
│ │ │ ├── 22/
│ │ │ │ ├── 220e9325710f4235a43492dd1ee4980d
│ │ │ │ ├── 220e9325710f4235a43492dd1ee4980d.info
│ │ │ │ ├── 22464cf7ab0243a6bf9c79851183b002
│ │ │ │ ├── 22464cf7ab0243a6bf9c79851183b002.info
│ │ │ │ ├── 22899211c24eeb248b22704499dd108f
│ │ │ │ └── 22899211c24eeb248b22704499dd108f.info
│ │ │ ├── 23/
│ │ │ │ ├── 2300e75732d74890b38a8ff257a3ae15
│ │ │ │ ├── 2300e75732d74890b38a8ff257a3ae15.info
│ │ │ │ ├── 230f3ac09b9ef234cba81ade9bd0e32a
│ │ │ │ ├── 230f3ac09b9ef234cba81ade9bd0e32a.info
│ │ │ │ ├── 2347243c7aa3e224f9282dc94e6fc3b2
│ │ │ │ ├── 2347243c7aa3e224f9282dc94e6fc3b2.info
│ │ │ │ ├── 2359c66dee10c454c97f6aea84e3fe22
│ │ │ │ ├── 2359c66dee10c454c97f6aea84e3fe22.info
│ │ │ │ ├── 23884ce4c1de32846adafea2d53a4cee
│ │ │ │ ├── 23884ce4c1de32846adafea2d53a4cee.info
│ │ │ │ ├── 239dd6edc8e5cd14585c03e09e86a747
│ │ │ │ ├── 239dd6edc8e5cd14585c03e09e86a747.info
│ │ │ │ ├── 23a562f2cac6401f9f91251c68a1a794
│ │ │ │ ├── 23a562f2cac6401f9f91251c68a1a794.info
│ │ │ │ ├── 23a56a19774ed42b6b65646af08a003c
│ │ │ │ └── 23a56a19774ed42b6b65646af08a003c.info
│ │ │ ├── 24/
│ │ │ │ ├── 24a158219395ebf44a60547b97784ddc
│ │ │ │ ├── 24a158219395ebf44a60547b97784ddc.info
│ │ │ │ ├── 24a7ce8b48db53747a4e8abbda77eac4
│ │ │ │ ├── 24a7ce8b48db53747a4e8abbda77eac4.info
│ │ │ │ ├── 24f430bcb0b5b8046adfc8065bffc5c9
│ │ │ │ └── 24f430bcb0b5b8046adfc8065bffc5c9.info
│ │ │ ├── 25/
│ │ │ │ ├── 2537ddddebaa455409dec422eb08fd7e
│ │ │ │ ├── 2537ddddebaa455409dec422eb08fd7e.info
│ │ │ │ ├── 255b0c6d400fd964dab3029c8abc53f4
│ │ │ │ ├── 255b0c6d400fd964dab3029c8abc53f4.info
│ │ │ │ ├── 256a0ca37fa972840bce7fca446e75e7
│ │ │ │ ├── 256a0ca37fa972840bce7fca446e75e7.info
│ │ │ │ ├── 25a477c2f24db8778a4179421a32cc21
│ │ │ │ ├── 25a477c2f24db8778a4179421a32cc21.info
│ │ │ │ ├── 25b01819c6e1649428db2a9b274cf364
│ │ │ │ └── 25b01819c6e1649428db2a9b274cf364.info
│ │ │ ├── 26/
│ │ │ │ ├── 260b531edc40677429c0198d6961e448
│ │ │ │ ├── 260b531edc40677429c0198d6961e448.info
│ │ │ │ ├── 26570be2af04195458e6f1ac1f5c48e0
│ │ │ │ ├── 26570be2af04195458e6f1ac1f5c48e0.info
│ │ │ │ ├── 26721f9940339264fb14bdbfe1290e21
│ │ │ │ ├── 26721f9940339264fb14bdbfe1290e21.info
│ │ │ │ ├── 26a4f29db434fd79025c91f6126382cc
│ │ │ │ ├── 26a4f29db434fd79025c91f6126382cc.info
│ │ │ │ ├── 26f3e7301af463c4ca72fa98d59b429e
│ │ │ │ └── 26f3e7301af463c4ca72fa98d59b429e.info
│ │ │ ├── 27/
│ │ │ │ ├── 2705215ac5b84b70bacc50632be6e391
│ │ │ │ ├── 2705215ac5b84b70bacc50632be6e391.info
│ │ │ │ ├── 27619889b8ba8c24980f49ee34dbb44a
│ │ │ │ ├── 27619889b8ba8c24980f49ee34dbb44a.info
│ │ │ │ ├── 27769e9b00b038d47aefe306a4d20bec
│ │ │ │ ├── 27769e9b00b038d47aefe306a4d20bec.info
│ │ │ │ ├── 2799eb4c84e72e54092a292cf626936b
│ │ │ │ ├── 2799eb4c84e72e54092a292cf626936b.info
│ │ │ │ ├── 27a0335dab59ec542aadd6636a5b4ebd
│ │ │ │ ├── 27a0335dab59ec542aadd6636a5b4ebd.info
│ │ │ │ ├── 27df3b12f30d0b74a9b10a3968c402ff
│ │ │ │ ├── 27df3b12f30d0b74a9b10a3968c402ff.info
│ │ │ │ ├── 27ed3e221887b3544bd9d6505d4a789f
│ │ │ │ └── 27ed3e221887b3544bd9d6505d4a789f.info
│ │ │ ├── 28/
│ │ │ │ ├── 2808ba6bccb2478ec9c7209d8bf1f3cc
│ │ │ │ ├── 2808ba6bccb2478ec9c7209d8bf1f3cc.info
│ │ │ │ ├── 281f7e519f1ddd14b96c09995386ec82
│ │ │ │ ├── 281f7e519f1ddd14b96c09995386ec82.info
│ │ │ │ ├── 28375447bcea455c9b51a6650b10c9d7
│ │ │ │ ├── 28375447bcea455c9b51a6650b10c9d7.info
│ │ │ │ ├── 28542eca5f1b4c64813acfbd512524b6
│ │ │ │ ├── 28542eca5f1b4c64813acfbd512524b6.info
│ │ │ │ ├── 28c8fcb831e6e734a9f564bc4f495eba
│ │ │ │ ├── 28c8fcb831e6e734a9f564bc4f495eba.info
│ │ │ │ ├── 28e8b16370ff78c4faca58757271619f
│ │ │ │ ├── 28e8b16370ff78c4faca58757271619f.info
│ │ │ │ ├── 28f79a0d7e64c2345bc46f8c4cf788f8
│ │ │ │ └── 28f79a0d7e64c2345bc46f8c4cf788f8.info
│ │ │ ├── 29/
│ │ │ │ ├── 29b7e99efaf64b949afd3d5b830c72aa
│ │ │ │ ├── 29b7e99efaf64b949afd3d5b830c72aa.info
│ │ │ │ ├── 29bf1d4ec1012bc45967ce95b729b8b3
│ │ │ │ ├── 29bf1d4ec1012bc45967ce95b729b8b3.info
│ │ │ │ ├── 29d603e0a726a9043b3503112271844a
│ │ │ │ └── 29d603e0a726a9043b3503112271844a.info
│ │ │ ├── 2a/
│ │ │ │ ├── 2a0bd678385f98e4d8eabdfc07d62b4f
│ │ │ │ ├── 2a0bd678385f98e4d8eabdfc07d62b4f.info
│ │ │ │ ├── 2a16748d9461eae46a725db9776d5390
│ │ │ │ ├── 2a16748d9461eae46a725db9776d5390.info
│ │ │ │ ├── 2a28c2fab6b1bb745a844ef6b908e7ee
│ │ │ │ ├── 2a28c2fab6b1bb745a844ef6b908e7ee.info
│ │ │ │ ├── 2a4db7a114972834c8e4117be1d82ba3
│ │ │ │ ├── 2a4db7a114972834c8e4117be1d82ba3.info
│ │ │ │ ├── 2ac6db96cd5bff048a79be0215503e16
│ │ │ │ ├── 2ac6db96cd5bff048a79be0215503e16.info
│ │ │ │ ├── 2ae2ce6274819484fa8747a28cebdf3a
│ │ │ │ ├── 2ae2ce6274819484fa8747a28cebdf3a.info
│ │ │ │ ├── 2aff4fada0516c64a8537a20bfe1b699
│ │ │ │ └── 2aff4fada0516c64a8537a20bfe1b699.info
│ │ │ ├── 2b/
│ │ │ │ ├── 2b301b727225f1941974d69e61a55620
│ │ │ │ ├── 2b301b727225f1941974d69e61a55620.info
│ │ │ │ ├── 2bafac87e7f4b9b418d9448d219b01ab
│ │ │ │ ├── 2bafac87e7f4b9b418d9448d219b01ab.info
│ │ │ │ ├── 2bc8a181dfd9de24388de89bb8db7713
│ │ │ │ ├── 2bc8a181dfd9de24388de89bb8db7713.info
│ │ │ │ ├── 2bd3ca1fde4b154448ef972b0f9d292e
│ │ │ │ ├── 2bd3ca1fde4b154448ef972b0f9d292e.info
│ │ │ │ ├── 2bf68308f6cdff141ab98cd34174e4f1
│ │ │ │ └── 2bf68308f6cdff141ab98cd34174e4f1.info
│ │ │ ├── 2c/
│ │ │ │ ├── 2c03ae9aa36a4fd44a983831f44654be
│ │ │ │ ├── 2c03ae9aa36a4fd44a983831f44654be.info
│ │ │ │ ├── 2c2dfcbbb77359547bcaa7cdabd47ebb
│ │ │ │ ├── 2c2dfcbbb77359547bcaa7cdabd47ebb.info
│ │ │ │ ├── 2c80ef0306e06ac4d8a4b0fe7e4536ac
│ │ │ │ ├── 2c80ef0306e06ac4d8a4b0fe7e4536ac.info
│ │ │ │ ├── 2c814623cb42764d304be0c5ddd03ceb
│ │ │ │ ├── 2c814623cb42764d304be0c5ddd03ceb.info
│ │ │ │ ├── 2c87ec8c97244cd47945ec90a99abe35
│ │ │ │ ├── 2c87ec8c97244cd47945ec90a99abe35.info
│ │ │ │ ├── 2cb24b5a5793c654e899a06bf08ec3ae
│ │ │ │ ├── 2cb24b5a5793c654e899a06bf08ec3ae.info
│ │ │ │ ├── 2ce4bbcc4722440890a03312706037fe
│ │ │ │ └── 2ce4bbcc4722440890a03312706037fe.info
│ │ │ ├── 2d/
│ │ │ │ ├── 2d142b475fbfb8cf12ba3a795194300a
│ │ │ │ ├── 2d142b475fbfb8cf12ba3a795194300a.info
│ │ │ │ ├── 2d49b7c1bcd2e07499844da127be038d
│ │ │ │ ├── 2d49b7c1bcd2e07499844da127be038d.info
│ │ │ │ ├── 2d6ba5cbe47e6ad3c87474c56174d4e0
│ │ │ │ ├── 2d6ba5cbe47e6ad3c87474c56174d4e0.info
│ │ │ │ ├── 2d8485e4e3a2bcb429fc32900ca26d9e
│ │ │ │ ├── 2d8485e4e3a2bcb429fc32900ca26d9e.info
│ │ │ │ ├── 2d9b6ff056b6f484ba6500aa8e06bcf3
│ │ │ │ ├── 2d9b6ff056b6f484ba6500aa8e06bcf3.info
│ │ │ │ ├── 2da0c512f12947e489f739169773d7ca
│ │ │ │ ├── 2da0c512f12947e489f739169773d7ca.info
│ │ │ │ ├── 2da27f5fe80a3a549ac7331d9f52f5f0
│ │ │ │ ├── 2da27f5fe80a3a549ac7331d9f52f5f0.info
│ │ │ │ ├── 2de8ba3b840049641897e0da7ce1d5cd
│ │ │ │ └── 2de8ba3b840049641897e0da7ce1d5cd.info
│ │ │ ├── 2e/
│ │ │ │ ├── 2e0de782b8e9e4e45baeb7bb5ef4907f
│ │ │ │ ├── 2e0de782b8e9e4e45baeb7bb5ef4907f.info
│ │ │ │ ├── 2e3b9bbf2c1a3cd4f88883ca32882ec6
│ │ │ │ └── 2e3b9bbf2c1a3cd4f88883ca32882ec6.info
│ │ │ ├── 2f/
│ │ │ │ ├── 2fa2cf7de51b0d34d9dce3747b72e49d
│ │ │ │ ├── 2fa2cf7de51b0d34d9dce3747b72e49d.info
│ │ │ │ ├── 2fafe2cfe61f6974895a912c3755e8f1
│ │ │ │ ├── 2fafe2cfe61f6974895a912c3755e8f1.info
│ │ │ │ ├── 2fd6421f253b4ef1a19526541f9ffc0c
│ │ │ │ └── 2fd6421f253b4ef1a19526541f9ffc0c.info
│ │ │ ├── 30/
│ │ │ │ ├── 305ca32be1aa5504aa182f583895dfe4
│ │ │ │ ├── 305ca32be1aa5504aa182f583895dfe4.info
│ │ │ │ ├── 30649d3a9faa99c48a7b1166b86bf2a0
│ │ │ │ ├── 30649d3a9faa99c48a7b1166b86bf2a0.info
│ │ │ │ ├── 3069a00b8c364df395994d7d379e0a99
│ │ │ │ ├── 3069a00b8c364df395994d7d379e0a99.info
│ │ │ │ ├── 306cc8c2b49d7114eaa3623786fc2126
│ │ │ │ ├── 306cc8c2b49d7114eaa3623786fc2126.info
│ │ │ │ ├── 309b0604924786544a3786ec4073c5a1
│ │ │ │ ├── 309b0604924786544a3786ec4073c5a1.info
│ │ │ │ ├── 30a939dce2fd4073955f2f20e659d506
│ │ │ │ ├── 30a939dce2fd4073955f2f20e659d506.info
│ │ │ │ ├── 30bed781e402439ab8ce4e3357708115
│ │ │ │ └── 30bed781e402439ab8ce4e3357708115.info
│ │ │ ├── 31/
│ │ │ │ ├── 3168bf9e060ff4b46be4bf08e308ce97
│ │ │ │ ├── 3168bf9e060ff4b46be4bf08e308ce97.info
│ │ │ │ ├── 3174898fbcdf12448963cdb5f5b60a33
│ │ │ │ ├── 3174898fbcdf12448963cdb5f5b60a33.info
│ │ │ │ ├── 319b8889f363f5947acf209c17a94149
│ │ │ │ ├── 319b8889f363f5947acf209c17a94149.info
│ │ │ │ ├── 31a19414c41e5ae4aae2af33fee712f6
│ │ │ │ └── 31a19414c41e5ae4aae2af33fee712f6.info
│ │ │ ├── 32/
│ │ │ │ ├── 321dc2c0720f8dd4f9396ecdc12b8746
│ │ │ │ ├── 321dc2c0720f8dd4f9396ecdc12b8746.info
│ │ │ │ ├── 322392995be44d23a3c86cfd972f838f
│ │ │ │ ├── 322392995be44d23a3c86cfd972f838f.info
│ │ │ │ ├── 3245ec927659c4140ac4f8d17403cc18
│ │ │ │ ├── 3245ec927659c4140ac4f8d17403cc18.info
│ │ │ │ ├── 32535dd294c621e4297fba34b15b1c52
│ │ │ │ ├── 32535dd294c621e4297fba34b15b1c52.info
│ │ │ │ ├── 32a4a0ea998dd6149937d2774781c436
│ │ │ │ ├── 32a4a0ea998dd6149937d2774781c436.info
│ │ │ │ ├── 32d40088a6124c578ad6b428df586e2e
│ │ │ │ ├── 32d40088a6124c578ad6b428df586e2e.info
│ │ │ │ ├── 32da81683c22faf458026716a2b821aa
│ │ │ │ ├── 32da81683c22faf458026716a2b821aa.info
│ │ │ │ ├── 32e2186f4598cff489784aae586f2215
│ │ │ │ └── 32e2186f4598cff489784aae586f2215.info
│ │ │ ├── 33/
│ │ │ │ ├── 3312d7739989d2b4e91e6319e9a96d76
│ │ │ │ ├── 3312d7739989d2b4e91e6319e9a96d76.info
│ │ │ │ ├── 335020228a0fe124897f51f25f6350ee
│ │ │ │ ├── 335020228a0fe124897f51f25f6350ee.info
│ │ │ │ ├── 3371106faf8d06f47a73979a3c8d82a1
│ │ │ │ ├── 3371106faf8d06f47a73979a3c8d82a1.info
│ │ │ │ ├── 3387717991705ce4e8ef033a0e543a06
│ │ │ │ ├── 3387717991705ce4e8ef033a0e543a06.info
│ │ │ │ ├── 33e6b78c96bb0694e96383e3c56b7b54
│ │ │ │ └── 33e6b78c96bb0694e96383e3c56b7b54.info
│ │ │ ├── 34/
│ │ │ │ ├── 3411e19edd44cfd46b548b058c3bc36c
│ │ │ │ ├── 3411e19edd44cfd46b548b058c3bc36c.info
│ │ │ │ ├── 342a0f8aca7f4f0691338912faec0494
│ │ │ │ ├── 342a0f8aca7f4f0691338912faec0494.info
│ │ │ │ ├── 343deaaf83e0cee4ca978e7df0b80d21
│ │ │ │ ├── 343deaaf83e0cee4ca978e7df0b80d21.info
│ │ │ │ ├── 3477d28057cb3e4469c7ea6b8dc23046
│ │ │ │ ├── 3477d28057cb3e4469c7ea6b8dc23046.info
│ │ │ │ ├── 34d6f60b171c1004e8335d52c65928a3
│ │ │ │ ├── 34d6f60b171c1004e8335d52c65928a3.info
│ │ │ │ ├── 34e150112c1c42ac83170b52d898e322
│ │ │ │ ├── 34e150112c1c42ac83170b52d898e322.info
│ │ │ │ ├── 34e2c9b9d9e44953933afe37461f44e6
│ │ │ │ ├── 34e2c9b9d9e44953933afe37461f44e6.info
│ │ │ │ ├── 34f6695d37a94370a3697f6b068f5d5e
│ │ │ │ ├── 34f6695d37a94370a3697f6b068f5d5e.info
│ │ │ │ ├── 34f9419ac53fdb44fa9676a451481931
│ │ │ │ ├── 34f9419ac53fdb44fa9676a451481931.info
│ │ │ │ ├── 34fc60e2fe0cbfa4a87375cdfff9dc86
│ │ │ │ └── 34fc60e2fe0cbfa4a87375cdfff9dc86.info
│ │ │ ├── 35/
│ │ │ │ ├── 3504aa04cda851b44a65973f9aead6f7
│ │ │ │ ├── 3504aa04cda851b44a65973f9aead6f7.info
│ │ │ │ ├── 3550d8ec6f29ab34d895ae9a43d560c2
│ │ │ │ ├── 3550d8ec6f29ab34d895ae9a43d560c2.info
│ │ │ │ ├── 357e9aeae0d19c148b2437b05c8b3361
│ │ │ │ ├── 357e9aeae0d19c148b2437b05c8b3361.info
│ │ │ │ ├── 358a618bc6bd9354d81cc206fd2ed80e
│ │ │ │ ├── 358a618bc6bd9354d81cc206fd2ed80e.info
│ │ │ │ ├── 35a0d10199de49f4db0128003bfd3bda
│ │ │ │ ├── 35a0d10199de49f4db0128003bfd3bda.info
│ │ │ │ ├── 35cb34351b19cf44ba78afbd58746610
│ │ │ │ ├── 35cb34351b19cf44ba78afbd58746610.info
│ │ │ │ ├── 35d143b352678294ab0f5feb97b67f88
│ │ │ │ ├── 35d143b352678294ab0f5feb97b67f88.info
│ │ │ │ ├── 35ff0937876540d3bd4b6a941df62a92
│ │ │ │ └── 35ff0937876540d3bd4b6a941df62a92.info
│ │ │ ├── 36/
│ │ │ │ ├── 3664a2ade19bb7848a4d2c96ac9148e3
│ │ │ │ ├── 3664a2ade19bb7848a4d2c96ac9148e3.info
│ │ │ │ ├── 368d3a0498e78014da578aa5f45e2797
│ │ │ │ └── 368d3a0498e78014da578aa5f45e2797.info
│ │ │ ├── 37/
│ │ │ │ ├── 371b6b9c8adc50745ace66a6fdf67481
│ │ │ │ ├── 371b6b9c8adc50745ace66a6fdf67481.info
│ │ │ │ ├── 373b4c78c0396334288fa5ff8e7b7350
│ │ │ │ ├── 373b4c78c0396334288fa5ff8e7b7350.info
│ │ │ │ ├── 37472f5179ca2004489ac901814cdbc3
│ │ │ │ ├── 37472f5179ca2004489ac901814cdbc3.info
│ │ │ │ ├── 376c84ea405e0f2b80562c23bb977216
│ │ │ │ ├── 376c84ea405e0f2b80562c23bb977216.info
│ │ │ │ ├── 37888acc09d9ee848bf9559f06645c45
│ │ │ │ ├── 37888acc09d9ee848bf9559f06645c45.info
│ │ │ │ ├── 37b164a494cd92a498526852ecceedef
│ │ │ │ ├── 37b164a494cd92a498526852ecceedef.info
│ │ │ │ ├── 37cea569bfefafe49a1513c4d7f0e9eb
│ │ │ │ ├── 37cea569bfefafe49a1513c4d7f0e9eb.info
│ │ │ │ ├── 37cff9f5a86ae494c8cb04423580480d
│ │ │ │ └── 37cff9f5a86ae494c8cb04423580480d.info
│ │ │ ├── 38/
│ │ │ │ ├── 380f7372e785c7d408552e2c760d269d
│ │ │ │ ├── 380f7372e785c7d408552e2c760d269d.info
│ │ │ │ ├── 383966e89d344865a36addd5d378ffd3
│ │ │ │ ├── 383966e89d344865a36addd5d378ffd3.info
│ │ │ │ ├── 38a6d0a81fcac8e4e851c921333f9803
│ │ │ │ ├── 38a6d0a81fcac8e4e851c921333f9803.info
│ │ │ │ ├── 38e3a8976f0b9c586b6dfbcef4e4066c
│ │ │ │ └── 38e3a8976f0b9c586b6dfbcef4e4066c.info
│ │ │ ├── 39/
│ │ │ │ ├── 393b15da08c88194dbbcacd6ee15a89c
│ │ │ │ ├── 393b15da08c88194dbbcacd6ee15a89c.info
│ │ │ │ ├── 39728903e57c60021f80449a8bbc0096
│ │ │ │ ├── 39728903e57c60021f80449a8bbc0096.info
│ │ │ │ ├── 39ab466162988eb4f83443f911bbf5c8
│ │ │ │ ├── 39ab466162988eb4f83443f911bbf5c8.info
│ │ │ │ ├── 39dcddcb5895328489c92214aa73e3bb
│ │ │ │ └── 39dcddcb5895328489c92214aa73e3bb.info
│ │ │ ├── 3a/
│ │ │ │ ├── 3a2d94c8977984b67984caeff9fa666e
│ │ │ │ ├── 3a2d94c8977984b67984caeff9fa666e.info
│ │ │ │ ├── 3a5038547af7c7f46bd90a015862e0b3
│ │ │ │ ├── 3a5038547af7c7f46bd90a015862e0b3.info
│ │ │ │ ├── 3a784fb721704576b3b4c3a7f3324264
│ │ │ │ ├── 3a784fb721704576b3b4c3a7f3324264.info
│ │ │ │ ├── 3ad53269c7421084ab67f804591994e0
│ │ │ │ └── 3ad53269c7421084ab67f804591994e0.info
│ │ │ ├── 3b/
│ │ │ │ ├── 3b0c53b13a1539949b3b212e049151d1
│ │ │ │ ├── 3b0c53b13a1539949b3b212e049151d1.info
│ │ │ │ ├── 3b28913f21577de429da928d6d05219f
│ │ │ │ ├── 3b28913f21577de429da928d6d05219f.info
│ │ │ │ ├── 3b4429eff9fcffb48b006e8edcc90338
│ │ │ │ ├── 3b4429eff9fcffb48b006e8edcc90338.info
│ │ │ │ ├── 3bce033ee26244e419b3bb3bba95a37d
│ │ │ │ ├── 3bce033ee26244e419b3bb3bba95a37d.info
│ │ │ │ ├── 3bda1886f58f4e0ab1139400b160c3ee
│ │ │ │ └── 3bda1886f58f4e0ab1139400b160c3ee.info
│ │ │ ├── 3c/
│ │ │ │ ├── 3c01b61b3a6887c49a15276fd38be918
│ │ │ │ ├── 3c01b61b3a6887c49a15276fd38be918.info
│ │ │ │ ├── 3c09dc5cd0a70cf40856b7d406106ee1
│ │ │ │ ├── 3c09dc5cd0a70cf40856b7d406106ee1.info
│ │ │ │ ├── 3c4ccfb0896bcf44da13e152b267aa49
│ │ │ │ ├── 3c4ccfb0896bcf44da13e152b267aa49.info
│ │ │ │ ├── 3c6c403084eacec478a1129ce20061ea
│ │ │ │ ├── 3c6c403084eacec478a1129ce20061ea.info
│ │ │ │ ├── 3c731404613599947b4b4559797a5168
│ │ │ │ ├── 3c731404613599947b4b4559797a5168.info
│ │ │ │ ├── 3c737f7a9d78541d1ab25f28f045dd32
│ │ │ │ ├── 3c737f7a9d78541d1ab25f28f045dd32.info
│ │ │ │ ├── 3cf5cb9e1ef590c48b1f919f2a7bd895
│ │ │ │ └── 3cf5cb9e1ef590c48b1f919f2a7bd895.info
│ │ │ ├── 3d/
│ │ │ │ ├── 3d42c4854f9093e409cd90c00ef26de0
│ │ │ │ ├── 3d42c4854f9093e409cd90c00ef26de0.info
│ │ │ │ ├── 3d67ccdf81bed8247ad0db2d5f47a7d1
│ │ │ │ ├── 3d67ccdf81bed8247ad0db2d5f47a7d1.info
│ │ │ │ ├── 3dde15f260b0dd1469e60d16eaa795dc
│ │ │ │ └── 3dde15f260b0dd1469e60d16eaa795dc.info
│ │ │ ├── 3e/
│ │ │ │ ├── 3e29cdd1646803545b8fb18908666ec4
│ │ │ │ ├── 3e29cdd1646803545b8fb18908666ec4.info
│ │ │ │ ├── 3e8d6af343b383544ba5743d119f4062
│ │ │ │ ├── 3e8d6af343b383544ba5743d119f4062.info
│ │ │ │ ├── 3e99141cd5dbef844a4338bb87930b89
│ │ │ │ ├── 3e99141cd5dbef844a4338bb87930b89.info
│ │ │ │ ├── 3ec7596410385054a9e0bc90377fbe63
│ │ │ │ ├── 3ec7596410385054a9e0bc90377fbe63.info
│ │ │ │ ├── 3ec9edad2de6c4df3a146b543a0fbc4c
│ │ │ │ ├── 3ec9edad2de6c4df3a146b543a0fbc4c.info
│ │ │ │ ├── 3edf75dd062cabf449c243d3c0da9464
│ │ │ │ ├── 3edf75dd062cabf449c243d3c0da9464.info
│ │ │ │ ├── 3ee40aa79cd242a5b53b0b0ca4f13f0f
│ │ │ │ └── 3ee40aa79cd242a5b53b0b0ca4f13f0f.info
│ │ │ ├── 3f/
│ │ │ │ ├── 3f8643c1f8dd449e85b548a14edbea2e
│ │ │ │ ├── 3f8643c1f8dd449e85b548a14edbea2e.info
│ │ │ │ ├── 3f8c1075884df0249b80e23a0598f9c1
│ │ │ │ ├── 3f8c1075884df0249b80e23a0598f9c1.info
│ │ │ │ ├── 3f9202a39620f51418046c7754f215f0
│ │ │ │ ├── 3f9202a39620f51418046c7754f215f0.info
│ │ │ │ ├── 3fa274f26b1574c40b949e114327022e
│ │ │ │ ├── 3fa274f26b1574c40b949e114327022e.info
│ │ │ │ ├── 3fdd83b151eb8d25c5e2f82fc39dcb04
│ │ │ │ ├── 3fdd83b151eb8d25c5e2f82fc39dcb04.info
│ │ │ │ ├── 3ff3d24ea34f9f74cb138e435f5f491e
│ │ │ │ └── 3ff3d24ea34f9f74cb138e435f5f491e.info
│ │ │ ├── 40/
│ │ │ │ ├── 4068e97704a16794ea218ba560cdc1e9
│ │ │ │ ├── 4068e97704a16794ea218ba560cdc1e9.info
│ │ │ │ ├── 408674d91d506a54aac9a7f07951c018
│ │ │ │ ├── 408674d91d506a54aac9a7f07951c018.info
│ │ │ │ ├── 40bf3cec17fa0b49fe04443c8332d638
│ │ │ │ ├── 40bf3cec17fa0b49fe04443c8332d638.info
│ │ │ │ ├── 40c83ba6a1a64cb4baac27028dd1acc1
│ │ │ │ ├── 40c83ba6a1a64cb4baac27028dd1acc1.info
│ │ │ │ ├── 40cb137d0e9816e48a4141ed13afedad
│ │ │ │ └── 40cb137d0e9816e48a4141ed13afedad.info
│ │ │ ├── 41/
│ │ │ │ ├── 411b7c7ffc0960249b35a2a247b66ff7
│ │ │ │ ├── 411b7c7ffc0960249b35a2a247b66ff7.info
│ │ │ │ ├── 41b96614b2e6494ba995ddcd252d11ae
│ │ │ │ ├── 41b96614b2e6494ba995ddcd252d11ae.info
│ │ │ │ ├── 41d60936b62cc6d4ca7fe628b22b0e40
│ │ │ │ ├── 41d60936b62cc6d4ca7fe628b22b0e40.info
│ │ │ │ ├── 41dcdc094b311464c8d6cb614548d89b
│ │ │ │ ├── 41dcdc094b311464c8d6cb614548d89b.info
│ │ │ │ ├── 41e14f40b915ca743a3dffd18ffc65ab
│ │ │ │ └── 41e14f40b915ca743a3dffd18ffc65ab.info
│ │ │ ├── 42/
│ │ │ │ ├── 423cd382a7804414d9bfdb2e7fb7bb62
│ │ │ │ ├── 423cd382a7804414d9bfdb2e7fb7bb62.info
│ │ │ │ ├── 423fe2ef878fa1140a7e1f7f9e365815
│ │ │ │ ├── 423fe2ef878fa1140a7e1f7f9e365815.info
│ │ │ │ ├── 426106349a0ff964fa4e7178c1d3a4f5
│ │ │ │ ├── 426106349a0ff964fa4e7178c1d3a4f5.info
│ │ │ │ ├── 42fe78c8fe682715a2cb531422e6ccb3
│ │ │ │ └── 42fe78c8fe682715a2cb531422e6ccb3.info
│ │ │ ├── 43/
│ │ │ │ ├── 4335a164bb763104c8805212c23d795f
│ │ │ │ ├── 4335a164bb763104c8805212c23d795f.info
│ │ │ │ ├── 438efd46088d408d8a53f707fa68d976
│ │ │ │ ├── 438efd46088d408d8a53f707fa68d976.info
│ │ │ │ ├── 439c018cf4619e94d9a92110ce0aa188
│ │ │ │ ├── 439c018cf4619e94d9a92110ce0aa188.info
│ │ │ │ ├── 43a3aec217baa9644a7cf34b5f93fed9
│ │ │ │ ├── 43a3aec217baa9644a7cf34b5f93fed9.info
│ │ │ │ ├── 43ad7f10b8cb01a4ca1b57eff53b024c
│ │ │ │ ├── 43ad7f10b8cb01a4ca1b57eff53b024c.info
│ │ │ │ ├── 43b1467da3d29ae4597a733828cdd84a
│ │ │ │ └── 43b1467da3d29ae4597a733828cdd84a.info
│ │ │ ├── 44/
│ │ │ │ ├── 4402dcee6e9969549bf5b33f11533208
│ │ │ │ ├── 4402dcee6e9969549bf5b33f11533208.info
│ │ │ │ ├── 44100f5f60f351348b9719b46d46cebe
│ │ │ │ ├── 44100f5f60f351348b9719b46d46cebe.info
│ │ │ │ ├── 44507a833d0ca8a42aaec1c3d752eb5f
│ │ │ │ ├── 44507a833d0ca8a42aaec1c3d752eb5f.info
│ │ │ │ ├── 445cdcfc747eba94288b97f5869aa2fb
│ │ │ │ ├── 445cdcfc747eba94288b97f5869aa2fb.info
│ │ │ │ ├── 44df73535c7a760458518e95391dbfdc
│ │ │ │ ├── 44df73535c7a760458518e95391dbfdc.info
│ │ │ │ ├── 44e1d646473a40178712cb2150f54cec
│ │ │ │ └── 44e1d646473a40178712cb2150f54cec.info
│ │ │ ├── 45/
│ │ │ │ ├── 4506ac79f5b274cb1b249ed7f4abfb9a
│ │ │ │ ├── 4506ac79f5b274cb1b249ed7f4abfb9a.info
│ │ │ │ ├── 452534715106564439d2240d82999d88
│ │ │ │ ├── 452534715106564439d2240d82999d88.info
│ │ │ │ ├── 45322b284be6baf43a273a61abba527d
│ │ │ │ ├── 45322b284be6baf43a273a61abba527d.info
│ │ │ │ ├── 4545bb65ccebf8040ac212d5792979b5
│ │ │ │ ├── 4545bb65ccebf8040ac212d5792979b5.info
│ │ │ │ ├── 4584db2acba045742a16942983e7fb96
│ │ │ │ ├── 4584db2acba045742a16942983e7fb96.info
│ │ │ │ ├── 4585b5feb801bdb44b0e5eafdd95a3be
│ │ │ │ ├── 4585b5feb801bdb44b0e5eafdd95a3be.info
│ │ │ │ ├── 459f6a07ee4a58b42ba2568b097c3ec4
│ │ │ │ └── 459f6a07ee4a58b42ba2568b097c3ec4.info
│ │ │ ├── 46/
│ │ │ │ ├── 46646a5562f14984690c85ee7b946bc9
│ │ │ │ ├── 46646a5562f14984690c85ee7b946bc9.info
│ │ │ │ ├── 468e1bfc887161e4196f33e942fc3199
│ │ │ │ └── 468e1bfc887161e4196f33e942fc3199.info
│ │ │ ├── 47/
│ │ │ │ ├── 470530e667ad4475786b28fa3187ce95
│ │ │ │ ├── 470530e667ad4475786b28fa3187ce95.info
│ │ │ │ ├── 470fdf3cd8176d94e8aadd242240fe3c
│ │ │ │ ├── 470fdf3cd8176d94e8aadd242240fe3c.info
│ │ │ │ ├── 4722a1362908a1843ab03a055c5c3fa0
│ │ │ │ ├── 4722a1362908a1843ab03a055c5c3fa0.info
│ │ │ │ ├── 472a6f18dd2f97c41af72271d22db869
│ │ │ │ ├── 472a6f18dd2f97c41af72271d22db869.info
│ │ │ │ ├── 475e3699f219c854f8581a9838135002
│ │ │ │ ├── 475e3699f219c854f8581a9838135002.info
│ │ │ │ ├── 47d9eecc3df4a854eaabab84609abb27
│ │ │ │ └── 47d9eecc3df4a854eaabab84609abb27.info
│ │ │ ├── 48/
│ │ │ │ ├── 48230e4e90fb4d14a9d56bddea898413
│ │ │ │ ├── 48230e4e90fb4d14a9d56bddea898413.info
│ │ │ │ ├── 4884ccc3528cb2e40a0e6f0a19a2b35b
│ │ │ │ ├── 4884ccc3528cb2e40a0e6f0a19a2b35b.info
│ │ │ │ ├── 48853ae485fa386428341ac1ea122570
│ │ │ │ ├── 48853ae485fa386428341ac1ea122570.info
│ │ │ │ ├── 48967a2d5427ac2489cc0ea61da5f1a0
│ │ │ │ ├── 48967a2d5427ac2489cc0ea61da5f1a0.info
│ │ │ │ ├── 48b10b41f58d5b49717f376cda59eeb8
│ │ │ │ ├── 48b10b41f58d5b49717f376cda59eeb8.info
│ │ │ │ ├── 48d034c499ee4697af9dd6e327110249
│ │ │ │ └── 48d034c499ee4697af9dd6e327110249.info
│ │ │ ├── 49/
│ │ │ │ ├── 495e2738ac7d88a41a158cd2e237d70b
│ │ │ │ ├── 495e2738ac7d88a41a158cd2e237d70b.info
│ │ │ │ ├── 49679f302ac6408697f6b9314a38985c
│ │ │ │ ├── 49679f302ac6408697f6b9314a38985c.info
│ │ │ │ ├── 49d4c2ab7ff0f4442af256bad7c9d57c
│ │ │ │ ├── 49d4c2ab7ff0f4442af256bad7c9d57c.info
│ │ │ │ ├── 49f1d2c7420db4444b011955726d0046
│ │ │ │ └── 49f1d2c7420db4444b011955726d0046.info
│ │ │ ├── 4a/
│ │ │ │ ├── 4a0757ee0236f39489520769ae710288
│ │ │ │ ├── 4a0757ee0236f39489520769ae710288.info
│ │ │ │ ├── 4ac5b6a65aaeb59478e3b78660e9f134
│ │ │ │ ├── 4ac5b6a65aaeb59478e3b78660e9f134.info
│ │ │ │ ├── 4acbfc0398bab674f922f693e58f4afc
│ │ │ │ ├── 4acbfc0398bab674f922f693e58f4afc.info
│ │ │ │ ├── 4ad09461bf994e54da846f726a23118e
│ │ │ │ ├── 4ad09461bf994e54da846f726a23118e.info
│ │ │ │ ├── 4ae64f3f72004807a9f919f9c27af0db
│ │ │ │ └── 4ae64f3f72004807a9f919f9c27af0db.info
│ │ │ ├── 4b/
│ │ │ │ ├── 4b518b37798c97b0f860962cbf615533
│ │ │ │ ├── 4b518b37798c97b0f860962cbf615533.info
│ │ │ │ ├── 4b57f909f22642d469a39e9628535312
│ │ │ │ ├── 4b57f909f22642d469a39e9628535312.info
│ │ │ │ ├── 4b721099b5d509d4093e516f59ad9ad6
│ │ │ │ ├── 4b721099b5d509d4093e516f59ad9ad6.info
│ │ │ │ ├── 4b8be68229770db4ea3c78ab0d854325
│ │ │ │ ├── 4b8be68229770db4ea3c78ab0d854325.info
│ │ │ │ ├── 4ba2329b63d54f0187bcaa12486b1b0f
│ │ │ │ ├── 4ba2329b63d54f0187bcaa12486b1b0f.info
│ │ │ │ ├── 4bbc17b35884fdf468e4b52ae4222882
│ │ │ │ ├── 4bbc17b35884fdf468e4b52ae4222882.info
│ │ │ │ ├── 4bd2bc28ff24d5c488844851cb785db0
│ │ │ │ └── 4bd2bc28ff24d5c488844851cb785db0.info
│ │ │ ├── 4c/
│ │ │ │ ├── 4c1821c1816c6fa44967b8ecb79ea7e4
│ │ │ │ ├── 4c1821c1816c6fa44967b8ecb79ea7e4.info
│ │ │ │ ├── 4c5eb52d37bb6714a98af73df7d9cf2c
│ │ │ │ ├── 4c5eb52d37bb6714a98af73df7d9cf2c.info
│ │ │ │ ├── 4c6f60d349ea37048af03504fc872f33
│ │ │ │ ├── 4c6f60d349ea37048af03504fc872f33.info
│ │ │ │ ├── 4cb169caa67eddf4d83b39fd0917a945
│ │ │ │ ├── 4cb169caa67eddf4d83b39fd0917a945.info
│ │ │ │ ├── 4cfe5ade9a1375e40aed87618b92bd12
│ │ │ │ └── 4cfe5ade9a1375e40aed87618b92bd12.info
│ │ │ ├── 4d/
│ │ │ │ ├── 4d2250412b81fe34abf39f246e274479
│ │ │ │ ├── 4d2250412b81fe34abf39f246e274479.info
│ │ │ │ ├── 4d31e19fd539ac54c8d9151da43683e9
│ │ │ │ ├── 4d31e19fd539ac54c8d9151da43683e9.info
│ │ │ │ ├── 4d3d51749e989f747b2674e0b4d9b3d7
│ │ │ │ ├── 4d3d51749e989f747b2674e0b4d9b3d7.info
│ │ │ │ ├── 4d616d1a494edd144b262cf6cd5e5fda
│ │ │ │ ├── 4d616d1a494edd144b262cf6cd5e5fda.info
│ │ │ │ ├── 4db13e1060deaae48b30246ed63b7c9b
│ │ │ │ ├── 4db13e1060deaae48b30246ed63b7c9b.info
│ │ │ │ ├── 4dc5887d05b52fd4fb5f52909d09ffe9
│ │ │ │ ├── 4dc5887d05b52fd4fb5f52909d09ffe9.info
│ │ │ │ ├── 4ddcdc3816429494a8bea67e973875f7
│ │ │ │ ├── 4ddcdc3816429494a8bea67e973875f7.info
│ │ │ │ ├── 4dfcd3a631f61d248b7cc0b845d40345
│ │ │ │ └── 4dfcd3a631f61d248b7cc0b845d40345.info
│ │ │ ├── 4e/
│ │ │ │ ├── 4e29b1a8efbd4b44bb3f3716e73f07ff
│ │ │ │ ├── 4e29b1a8efbd4b44bb3f3716e73f07ff.info
│ │ │ │ ├── 4e82512e02403f342aefc6129f4d04a4
│ │ │ │ └── 4e82512e02403f342aefc6129f4d04a4.info
│ │ │ ├── 4f/
│ │ │ │ ├── 4f07c137155b291429c0b3670c4defba
│ │ │ │ ├── 4f07c137155b291429c0b3670c4defba.info
│ │ │ │ ├── 4f0ca6874aa74540bb3d4fe5a0f86bcc
│ │ │ │ ├── 4f0ca6874aa74540bb3d4fe5a0f86bcc.info
│ │ │ │ ├── 4f0f9b9f3ed97ad2b9ba8f1a8e4666c2
│ │ │ │ ├── 4f0f9b9f3ed97ad2b9ba8f1a8e4666c2.info
│ │ │ │ ├── 4f10dd60657c6004587f237a7e90f8e4
│ │ │ │ ├── 4f10dd60657c6004587f237a7e90f8e4.info
│ │ │ │ ├── 4f231c4fb786f3946a6b90b886c48677
│ │ │ │ ├── 4f231c4fb786f3946a6b90b886c48677.info
│ │ │ │ ├── 4f5ed95515938d14189b094f8654d0bd
│ │ │ │ ├── 4f5ed95515938d14189b094f8654d0bd.info
│ │ │ │ ├── 4f809c227a3cfde4bbb9482dc1814105
│ │ │ │ ├── 4f809c227a3cfde4bbb9482dc1814105.info
│ │ │ │ ├── 4f90cfe4bf5cfb44f84a5b11387f2a42
│ │ │ │ ├── 4f90cfe4bf5cfb44f84a5b11387f2a42.info
│ │ │ │ ├── 4f939b9e23a0946439b812551e07ac81
│ │ │ │ ├── 4f939b9e23a0946439b812551e07ac81.info
│ │ │ │ ├── 4f9ac6e545d53f94b9f09c85b9576f36
│ │ │ │ ├── 4f9ac6e545d53f94b9f09c85b9576f36.info
│ │ │ │ ├── 4fbcc9b1f6ace8c4f8724a88dccca5f8
│ │ │ │ └── 4fbcc9b1f6ace8c4f8724a88dccca5f8.info
│ │ │ ├── 50/
│ │ │ │ ├── 505965fb9ab352b4d88882d7c8d822bf
│ │ │ │ ├── 505965fb9ab352b4d88882d7c8d822bf.info
│ │ │ │ ├── 5082cb99a8f99b84d84dd8b4c5233a9e
│ │ │ │ ├── 5082cb99a8f99b84d84dd8b4c5233a9e.info
│ │ │ │ ├── 50de529b6a28f4a7093045e08810a5df
│ │ │ │ └── 50de529b6a28f4a7093045e08810a5df.info
│ │ │ ├── 51/
│ │ │ │ ├── 511aa760b8728a940a41c29837945292
│ │ │ │ ├── 511aa760b8728a940a41c29837945292.info
│ │ │ │ ├── 5143f58107604835ab1a5efa2d8818fd
│ │ │ │ ├── 5143f58107604835ab1a5efa2d8818fd.info
│ │ │ │ ├── 5151708d47edd4344ba8e7bd469d966e
│ │ │ │ ├── 5151708d47edd4344ba8e7bd469d966e.info
│ │ │ │ ├── 51557afa652635743b264a309f0a5c60
│ │ │ │ ├── 51557afa652635743b264a309f0a5c60.info
│ │ │ │ ├── 515638b803bef8599dbd6d5c8bdaa53e
│ │ │ │ ├── 515638b803bef8599dbd6d5c8bdaa53e.info
│ │ │ │ ├── 51a7878f6c989394782db73339e90e46
│ │ │ │ └── 51a7878f6c989394782db73339e90e46.info
│ │ │ ├── 52/
│ │ │ │ ├── 526f285e8d4fb8140b4cdfeb9102d8cb
│ │ │ │ ├── 526f285e8d4fb8140b4cdfeb9102d8cb.info
│ │ │ │ ├── 529fde071171dfd4e99d45ca81a3ac7b
│ │ │ │ ├── 529fde071171dfd4e99d45ca81a3ac7b.info
│ │ │ │ ├── 52c907c81459f324497af504b84fd557
│ │ │ │ └── 52c907c81459f324497af504b84fd557.info
│ │ │ ├── 54/
│ │ │ │ ├── 5415c904c4fbc3e498253bc2866b37cd
│ │ │ │ ├── 5415c904c4fbc3e498253bc2866b37cd.info
│ │ │ │ ├── 543674eec776b1442a192c932e6cd9b3
│ │ │ │ ├── 543674eec776b1442a192c932e6cd9b3.info
│ │ │ │ ├── 5440c1153b397e14c9c7b1d6eb83b9f9
│ │ │ │ ├── 5440c1153b397e14c9c7b1d6eb83b9f9.info
│ │ │ │ ├── 5469ef0820152a4ae45d400fdc4626e4
│ │ │ │ ├── 5469ef0820152a4ae45d400fdc4626e4.info
│ │ │ │ ├── 5472815444de2ce45bf2053a4af04b9d
│ │ │ │ ├── 5472815444de2ce45bf2053a4af04b9d.info
│ │ │ │ ├── 54d21f6ece3b46479f0c328f8c6007e0
│ │ │ │ └── 54d21f6ece3b46479f0c328f8c6007e0.info
│ │ │ ├── 55/
│ │ │ │ ├── 5503f95d174761548a68a901beab13c2
│ │ │ │ ├── 5503f95d174761548a68a901beab13c2.info
│ │ │ │ ├── 559482fe33c79e44882d3a6cedc55fb5
│ │ │ │ ├── 559482fe33c79e44882d3a6cedc55fb5.info
│ │ │ │ ├── 5598b14661b5f4c43bed757f34b6d172
│ │ │ │ ├── 5598b14661b5f4c43bed757f34b6d172.info
│ │ │ │ ├── 55a8539917657b14baf6c6a051a7df22
│ │ │ │ └── 55a8539917657b14baf6c6a051a7df22.info
│ │ │ ├── 56/
│ │ │ │ ├── 5653477a5039f674da8f856adcf47172
│ │ │ │ ├── 5653477a5039f674da8f856adcf47172.info
│ │ │ │ ├── 56666c5a40171f54783dd416a44f42bf
│ │ │ │ ├── 56666c5a40171f54783dd416a44f42bf.info
│ │ │ │ ├── 5673d7b11cb9ad04eb2368068b720c17
│ │ │ │ ├── 5673d7b11cb9ad04eb2368068b720c17.info
│ │ │ │ ├── 56ba6cb160ebfc042b48224bd1a35614
│ │ │ │ └── 56ba6cb160ebfc042b48224bd1a35614.info
│ │ │ ├── 57/
│ │ │ │ ├── 57a39be2178cca94ab21e15c082e3ab6
│ │ │ │ ├── 57a39be2178cca94ab21e15c082e3ab6.info
│ │ │ │ ├── 57acdaad593b8d143b8fb5052a09d7d0
│ │ │ │ ├── 57acdaad593b8d143b8fb5052a09d7d0.info
│ │ │ │ ├── 57b0c806ba25b48aa8a6ecb3345a4a9b
│ │ │ │ ├── 57b0c806ba25b48aa8a6ecb3345a4a9b.info
│ │ │ │ ├── 57d2ac5c7d5786e499d4794973fe0d4e
│ │ │ │ ├── 57d2ac5c7d5786e499d4794973fe0d4e.info
│ │ │ │ ├── 57ff740bce4ab0c498ada374a8ca1dc0
│ │ │ │ └── 57ff740bce4ab0c498ada374a8ca1dc0.info
│ │ │ ├── 58/
│ │ │ │ ├── 58004290eb3aab44e9823d1f25c4ed73
│ │ │ │ ├── 58004290eb3aab44e9823d1f25c4ed73.info
│ │ │ │ ├── 585b70cb75dd43efbfead809c30a1731
│ │ │ │ ├── 585b70cb75dd43efbfead809c30a1731.info
│ │ │ │ ├── 58628227479c34542ac8c5193ccced84
│ │ │ │ ├── 58628227479c34542ac8c5193ccced84.info
│ │ │ │ ├── 5882d0e4313310143acb11d1a66c597f
│ │ │ │ ├── 5882d0e4313310143acb11d1a66c597f.info
│ │ │ │ ├── 589533fb2413e3e4fba7df13a6a75bf2
│ │ │ │ ├── 589533fb2413e3e4fba7df13a6a75bf2.info
│ │ │ │ ├── 58ad09607a0d62d458a78d7174665566
│ │ │ │ ├── 58ad09607a0d62d458a78d7174665566.info
│ │ │ │ ├── 58e7d991249847640b1534192721c5ea
│ │ │ │ └── 58e7d991249847640b1534192721c5ea.info
│ │ │ ├── 59/
│ │ │ │ ├── 592f7288ed0df2c4b884e2cd9baac023
│ │ │ │ ├── 592f7288ed0df2c4b884e2cd9baac023.info
│ │ │ │ ├── 59d3f5586b341a74c84c8f72144a4568
│ │ │ │ ├── 59d3f5586b341a74c84c8f72144a4568.info
│ │ │ │ ├── 59f8146938fff824cb5fd77236b75775
│ │ │ │ ├── 59f8146938fff824cb5fd77236b75775.info
│ │ │ │ ├── 59ff995fabb3bac45afa0f96f333e5dc
│ │ │ │ └── 59ff995fabb3bac45afa0f96f333e5dc.info
│ │ │ ├── 5a/
│ │ │ │ ├── 5a2e98b03511c6f43bc645238cd40857
│ │ │ │ ├── 5a2e98b03511c6f43bc645238cd40857.info
│ │ │ │ ├── 5a31542ccf4e8584ca4f60843e9d02d0
│ │ │ │ ├── 5a31542ccf4e8584ca4f60843e9d02d0.info
│ │ │ │ ├── 5a7f0d89a47f18c41b6ddf60dfae1bde
│ │ │ │ ├── 5a7f0d89a47f18c41b6ddf60dfae1bde.info
│ │ │ │ ├── 5a8c170a1ec28a148ab78df2460a3135
│ │ │ │ ├── 5a8c170a1ec28a148ab78df2460a3135.info
│ │ │ │ ├── 5aa8f57287fc17149bcd798be813180b
│ │ │ │ ├── 5aa8f57287fc17149bcd798be813180b.info
│ │ │ │ ├── 5af3322745e78aa488fca5a2090f8755
│ │ │ │ └── 5af3322745e78aa488fca5a2090f8755.info
│ │ │ ├── 5b/
│ │ │ │ ├── 5b00473355622524394628f7ec51808d
│ │ │ │ ├── 5b00473355622524394628f7ec51808d.info
│ │ │ │ ├── 5b24618beecc3bf41acadfcf2246d772
│ │ │ │ ├── 5b24618beecc3bf41acadfcf2246d772.info
│ │ │ │ ├── 5b2eeca598284bd4abb4a15c30df1576
│ │ │ │ ├── 5b2eeca598284bd4abb4a15c30df1576.info
│ │ │ │ ├── 5b3bd7a976306c9449ba84e0591e8a0f
│ │ │ │ ├── 5b3bd7a976306c9449ba84e0591e8a0f.info
│ │ │ │ ├── 5b3e90046c38f1d4dad2e0d5a79e871c
│ │ │ │ ├── 5b3e90046c38f1d4dad2e0d5a79e871c.info
│ │ │ │ ├── 5b5c6a576605b3c4aab7d27193785f27
│ │ │ │ ├── 5b5c6a576605b3c4aab7d27193785f27.info
│ │ │ │ ├── 5b60206b4b7ac1043ba19efe7ecfd5be
│ │ │ │ ├── 5b60206b4b7ac1043ba19efe7ecfd5be.info
│ │ │ │ ├── 5b6cac4a98010394791c66942a33caf4
│ │ │ │ ├── 5b6cac4a98010394791c66942a33caf4.info
│ │ │ │ ├── 5b994928117e3db418da69c821da7e19
│ │ │ │ ├── 5b994928117e3db418da69c821da7e19.info
│ │ │ │ ├── 5ba130fc1db953547a50bcf5c162a3e8
│ │ │ │ ├── 5ba130fc1db953547a50bcf5c162a3e8.info
│ │ │ │ ├── 5bcb408b7b5e4d346aeb4860ab1d9d9b
│ │ │ │ └── 5bcb408b7b5e4d346aeb4860ab1d9d9b.info
│ │ │ ├── 5c/
│ │ │ │ ├── 5c004b1354944164fb076276c289afc1
│ │ │ │ ├── 5c004b1354944164fb076276c289afc1.info
│ │ │ │ ├── 5c15bf0966eb95847a4260d830a30d30
│ │ │ │ ├── 5c15bf0966eb95847a4260d830a30d30.info
│ │ │ │ ├── 5c9c9f62af2efb948a1974650039e2db
│ │ │ │ └── 5c9c9f62af2efb948a1974650039e2db.info
│ │ │ ├── 5d/
│ │ │ │ ├── 5d4d7b45df12a6845beb7d6a034a41a2
│ │ │ │ ├── 5d4d7b45df12a6845beb7d6a034a41a2.info
│ │ │ │ ├── 5d4de3d4682a8d641907cc75e4fb950e
│ │ │ │ ├── 5d4de3d4682a8d641907cc75e4fb950e.info
│ │ │ │ ├── 5d7f0d6acfced954682a89e7002c04d9
│ │ │ │ ├── 5d7f0d6acfced954682a89e7002c04d9.info
│ │ │ │ ├── 5da62a0c1c5218c4aa16b74546a7822d
│ │ │ │ ├── 5da62a0c1c5218c4aa16b74546a7822d.info
│ │ │ │ ├── 5da77d4d078922b4c8466e9e35fb3f5e
│ │ │ │ ├── 5da77d4d078922b4c8466e9e35fb3f5e.info
│ │ │ │ ├── 5da88f348abcbd94585671a69c672781
│ │ │ │ ├── 5da88f348abcbd94585671a69c672781.info
│ │ │ │ ├── 5ddd9f7d3cce6724696a33752ab2f5a4
│ │ │ │ ├── 5ddd9f7d3cce6724696a33752ab2f5a4.info
│ │ │ │ ├── 5df3c21c5237c994db89660fbdfee07d
│ │ │ │ └── 5df3c21c5237c994db89660fbdfee07d.info
│ │ │ ├── 5e/
│ │ │ │ ├── 5e726086cd652f82087d59d67d2c24cd
│ │ │ │ ├── 5e726086cd652f82087d59d67d2c24cd.info
│ │ │ │ ├── 5e83f8baac96eaa47bdd9ca781cd2002
│ │ │ │ ├── 5e83f8baac96eaa47bdd9ca781cd2002.info
│ │ │ │ ├── 5ea6a8a826704f743b3b0ce3e9d3c9a9
│ │ │ │ ├── 5ea6a8a826704f743b3b0ce3e9d3c9a9.info
│ │ │ │ ├── 5ea9f573d4b800a49b9d83a1f61c0a88
│ │ │ │ ├── 5ea9f573d4b800a49b9d83a1f61c0a88.info
│ │ │ │ ├── 5ebb87899ca30b743bb4274bc00c02b4
│ │ │ │ ├── 5ebb87899ca30b743bb4274bc00c02b4.info
│ │ │ │ ├── 5ebeb75bd91642048bb3f6c1939fde66
│ │ │ │ ├── 5ebeb75bd91642048bb3f6c1939fde66.info
│ │ │ │ ├── 5ec95f4d5b2d1f14e9ff8682562553f9
│ │ │ │ ├── 5ec95f4d5b2d1f14e9ff8682562553f9.info
│ │ │ │ ├── 5ecec8cdc3ff99e4a9c65635d7e6b043
│ │ │ │ └── 5ecec8cdc3ff99e4a9c65635d7e6b043.info
│ │ │ ├── 5f/
│ │ │ │ ├── 5f31f28cc64c91042976555c016ffd5f
│ │ │ │ ├── 5f31f28cc64c91042976555c016ffd5f.info
│ │ │ │ ├── 5f603f10b9ec26841b2ecb6003dc1d0e
│ │ │ │ ├── 5f603f10b9ec26841b2ecb6003dc1d0e.info
│ │ │ │ ├── 5f7201a12d95ffc409449d95f23cf332
│ │ │ │ ├── 5f7201a12d95ffc409449d95f23cf332.info
│ │ │ │ ├── 5f875a14565308a40a5262d2504da705
│ │ │ │ ├── 5f875a14565308a40a5262d2504da705.info
│ │ │ │ ├── 5fc988a1d5b04aee9a5222502b201a45
│ │ │ │ └── 5fc988a1d5b04aee9a5222502b201a45.info
│ │ │ ├── 60/
│ │ │ │ ├── 600f4b74746dbf944901257f81a8af6d
│ │ │ │ ├── 600f4b74746dbf944901257f81a8af6d.info
│ │ │ │ ├── 6023f2b823fc19b4e4a90875281ff117
│ │ │ │ ├── 6023f2b823fc19b4e4a90875281ff117.info
│ │ │ │ ├── 6055be8ebefd69e48b49212b09b47b2f
│ │ │ │ └── 6055be8ebefd69e48b49212b09b47b2f.info
│ │ │ ├── 61/
│ │ │ │ ├── 6124ad3c57404c3429a93ca37df030e9
│ │ │ │ ├── 6124ad3c57404c3429a93ca37df030e9.info
│ │ │ │ ├── 61a20120cddc53849bbc10fc805ffe3e
│ │ │ │ ├── 61a20120cddc53849bbc10fc805ffe3e.info
│ │ │ │ ├── 61d491d99e9292c4a81d7d01a74781ea
│ │ │ │ ├── 61d491d99e9292c4a81d7d01a74781ea.info
│ │ │ │ ├── 61e236e8570a95e4eb754fb291e102e0
│ │ │ │ └── 61e236e8570a95e4eb754fb291e102e0.info
│ │ │ ├── 62/
│ │ │ │ ├── 621a76c0c3927aa45aba7d2ad0c8e1c8
│ │ │ │ ├── 621a76c0c3927aa45aba7d2ad0c8e1c8.info
│ │ │ │ ├── 621fd19bcb071b64aa1d68f0271aa780
│ │ │ │ ├── 621fd19bcb071b64aa1d68f0271aa780.info
│ │ │ │ ├── 623c79a1e113b4941afdbfc88d19e8fd
│ │ │ │ └── 623c79a1e113b4941afdbfc88d19e8fd.info
│ │ │ ├── 63/
│ │ │ │ ├── 63118a0c9ee42ac46b7f30e793177a76
│ │ │ │ ├── 63118a0c9ee42ac46b7f30e793177a76.info
│ │ │ │ ├── 63572993f2104574099a48392460b211
│ │ │ │ ├── 63572993f2104574099a48392460b211.info
│ │ │ │ ├── 6366ee97f6b541449155028b9487355a
│ │ │ │ ├── 6366ee97f6b541449155028b9487355a.info
│ │ │ │ ├── 63cd91d36b6b0e4479ef6e61ad4f6f9a
│ │ │ │ ├── 63cd91d36b6b0e4479ef6e61ad4f6f9a.info
│ │ │ │ ├── 63f2caa33e79582448112b2e286d576d
│ │ │ │ └── 63f2caa33e79582448112b2e286d576d.info
│ │ │ ├── 64/
│ │ │ │ ├── 640125adae259fe47a36be84e510a46e
│ │ │ │ ├── 640125adae259fe47a36be84e510a46e.info
│ │ │ │ ├── 645165c8169474bfbbeb8fb0bcfd26f5
│ │ │ │ ├── 645165c8169474bfbbeb8fb0bcfd26f5.info
│ │ │ │ ├── 64689f8b25eadac4da519e96f514b653
│ │ │ │ ├── 64689f8b25eadac4da519e96f514b653.info
│ │ │ │ ├── 647e1bbd3809b30459d946b4a1ddf22b
│ │ │ │ ├── 647e1bbd3809b30459d946b4a1ddf22b.info
│ │ │ │ ├── 64b9fad609434c489c32b1cdf2004a1c
│ │ │ │ └── 64b9fad609434c489c32b1cdf2004a1c.info
│ │ │ ├── 65/
│ │ │ │ ├── 6546d7765b4165b40850b3667f981c26
│ │ │ │ ├── 6546d7765b4165b40850b3667f981c26.info
│ │ │ │ ├── 656e461844099ae43a609ff6109b0877
│ │ │ │ ├── 656e461844099ae43a609ff6109b0877.info
│ │ │ │ ├── 65701ebe8bada6b4785e9c7afe7f5bee
│ │ │ │ ├── 65701ebe8bada6b4785e9c7afe7f5bee.info
│ │ │ │ ├── 658c1fb149e7498aa072b0c0f3bf13f0
│ │ │ │ ├── 658c1fb149e7498aa072b0c0f3bf13f0.info
│ │ │ │ ├── 65b045927b3948f43afb31234936c6aa
│ │ │ │ ├── 65b045927b3948f43afb31234936c6aa.info
│ │ │ │ ├── 65f3a4c67e4927a478b7036bae1da0e3
│ │ │ │ ├── 65f3a4c67e4927a478b7036bae1da0e3.info
│ │ │ │ ├── 65fb6da362a78334ab360a125cfafdaf
│ │ │ │ └── 65fb6da362a78334ab360a125cfafdaf.info
│ │ │ ├── 66/
│ │ │ │ ├── 661266b8a30572e4fb9365bba3866896
│ │ │ │ ├── 661266b8a30572e4fb9365bba3866896.info
│ │ │ │ ├── 667a99762bdf5484fbaa02573fd396e2
│ │ │ │ ├── 667a99762bdf5484fbaa02573fd396e2.info
│ │ │ │ ├── 667c6ad86a0b7a548aaa5c287f2c2861
│ │ │ │ ├── 667c6ad86a0b7a548aaa5c287f2c2861.info
│ │ │ │ ├── 66b2b8fd1d9b4bc4c96b07335ad822f3
│ │ │ │ ├── 66b2b8fd1d9b4bc4c96b07335ad822f3.info
│ │ │ │ ├── 66c95bb3c74257f41bae2622511dc02d
│ │ │ │ └── 66c95bb3c74257f41bae2622511dc02d.info
│ │ │ ├── 67/
│ │ │ │ ├── 6773203120b27984d9a8572fa3564f03
│ │ │ │ ├── 6773203120b27984d9a8572fa3564f03.info
│ │ │ │ ├── 67db9e8f0e2ae9c40bc1e2b64352a6b4
│ │ │ │ ├── 67db9e8f0e2ae9c40bc1e2b64352a6b4.info
│ │ │ │ ├── 67e3583b91179094094c6a188b232262
│ │ │ │ ├── 67e3583b91179094094c6a188b232262.info
│ │ │ │ ├── 67e9c6cf60c57a54f9f4db1bc33fd2e3
│ │ │ │ ├── 67e9c6cf60c57a54f9f4db1bc33fd2e3.info
│ │ │ │ ├── 67ee43b2f6148de40861b289b0e00591
│ │ │ │ └── 67ee43b2f6148de40861b289b0e00591.info
│ │ │ ├── 68/
│ │ │ │ ├── 685f63932bebd0c4db02ee14845191e2
│ │ │ │ ├── 685f63932bebd0c4db02ee14845191e2.info
│ │ │ │ ├── 68993ba529ae04440916cb7c23bf3279
│ │ │ │ ├── 68993ba529ae04440916cb7c23bf3279.info
│ │ │ │ ├── 68a48d1900320ed458e118415857faf6
│ │ │ │ ├── 68a48d1900320ed458e118415857faf6.info
│ │ │ │ ├── 68cb547af0187634aad591a09c01cd5b
│ │ │ │ ├── 68cb547af0187634aad591a09c01cd5b.info
│ │ │ │ ├── 68e5dc8bfd5d72647a93b7f2e1da831a
│ │ │ │ ├── 68e5dc8bfd5d72647a93b7f2e1da831a.info
│ │ │ │ ├── 68eedd4e5b33b37429c02c4add0036fe
│ │ │ │ └── 68eedd4e5b33b37429c02c4add0036fe.info
│ │ │ ├── 69/
│ │ │ │ ├── 6901fab4d5157ac48b9f263730387c03
│ │ │ │ ├── 6901fab4d5157ac48b9f263730387c03.info
│ │ │ │ ├── 691475c57a824010be0c6f474caeb7e1
│ │ │ │ ├── 691475c57a824010be0c6f474caeb7e1.info
│ │ │ │ ├── 691db8cb70c4426a8ae718465c21345f
│ │ │ │ ├── 691db8cb70c4426a8ae718465c21345f.info
│ │ │ │ ├── 6965880f76f40194593cb53a88f74005
│ │ │ │ ├── 6965880f76f40194593cb53a88f74005.info
│ │ │ │ ├── 698b660e9477f4f16abad03ec00ce38c
│ │ │ │ ├── 698b660e9477f4f16abad03ec00ce38c.info
│ │ │ │ ├── 69ae55f76840b2849ba56cfb53a17df0
│ │ │ │ ├── 69ae55f76840b2849ba56cfb53a17df0.info
│ │ │ │ ├── 69e3979b7029e8a4da2d96b714ba5c3a
│ │ │ │ └── 69e3979b7029e8a4da2d96b714ba5c3a.info
│ │ │ ├── 6a/
│ │ │ │ ├── 6a022d21eb285c143ae29fc2aca21e11
│ │ │ │ ├── 6a022d21eb285c143ae29fc2aca21e11.info
│ │ │ │ ├── 6a44d0f20e3f6cd45881a44134574169
│ │ │ │ ├── 6a44d0f20e3f6cd45881a44134574169.info
│ │ │ │ ├── 6a4f0c91a28ece04198b200dd55145d0
│ │ │ │ ├── 6a4f0c91a28ece04198b200dd55145d0.info
│ │ │ │ ├── 6a981cd1456bec84b86e1c66773f57f5
│ │ │ │ ├── 6a981cd1456bec84b86e1c66773f57f5.info
│ │ │ │ ├── 6ace62d30f494c948b71d5594afce11d
│ │ │ │ ├── 6ace62d30f494c948b71d5594afce11d.info
│ │ │ │ ├── 6ad632cbcc87f634d9b86006cdffdaf5
│ │ │ │ ├── 6ad632cbcc87f634d9b86006cdffdaf5.info
│ │ │ │ ├── 6afb166a156df2d20433d981f4bb2832
│ │ │ │ └── 6afb166a156df2d20433d981f4bb2832.info
│ │ │ ├── 6b/
│ │ │ │ ├── 6b01141ed8f74d198965c86f25eb7040
│ │ │ │ ├── 6b01141ed8f74d198965c86f25eb7040.info
│ │ │ │ ├── 6b152d671c864bf41bbcc096f5a7567c
│ │ │ │ ├── 6b152d671c864bf41bbcc096f5a7567c.info
│ │ │ │ ├── 6b1ae1e78552c459d9ce27048ff51c7f
│ │ │ │ ├── 6b1ae1e78552c459d9ce27048ff51c7f.info
│ │ │ │ ├── 6b259c4003a802847b9ada90744e34c5
│ │ │ │ ├── 6b259c4003a802847b9ada90744e34c5.info
│ │ │ │ ├── 6b32b6725087a0d4bb1670818d26996e
│ │ │ │ ├── 6b32b6725087a0d4bb1670818d26996e.info
│ │ │ │ ├── 6b72875690e0f7343911e06af3145bd5
│ │ │ │ ├── 6b72875690e0f7343911e06af3145bd5.info
│ │ │ │ ├── 6ba7805325c426c43b8e85b5be4eae36
│ │ │ │ ├── 6ba7805325c426c43b8e85b5be4eae36.info
│ │ │ │ ├── 6bfec54ce89b0b642a65d44def023b99
│ │ │ │ └── 6bfec54ce89b0b642a65d44def023b99.info
│ │ │ ├── 6c/
│ │ │ │ ├── 6c3d52cc5c46d7946a920e21901ff38e
│ │ │ │ ├── 6c3d52cc5c46d7946a920e21901ff38e.info
│ │ │ │ ├── 6c61ba0c209bcc74f83e3650039ebdf9
│ │ │ │ ├── 6c61ba0c209bcc74f83e3650039ebdf9.info
│ │ │ │ ├── 6ca745fb561cbf640b6e603f95662fa0
│ │ │ │ ├── 6ca745fb561cbf640b6e603f95662fa0.info
│ │ │ │ ├── 6cccd50ebf7384242bda4d7bcb282ebf
│ │ │ │ └── 6cccd50ebf7384242bda4d7bcb282ebf.info
│ │ │ ├── 6d/
│ │ │ │ ├── 6d16f2e78a356d34c9a32108929de932
│ │ │ │ ├── 6d16f2e78a356d34c9a32108929de932.info
│ │ │ │ ├── 6d437b997e074079b4b2f6e395394f4b
│ │ │ │ ├── 6d437b997e074079b4b2f6e395394f4b.info
│ │ │ │ ├── 6d468ee3657be7a43a2ef2178ec14239
│ │ │ │ ├── 6d468ee3657be7a43a2ef2178ec14239.info
│ │ │ │ ├── 6d56244f8c39a851975d3c0bd432c66f
│ │ │ │ ├── 6d56244f8c39a851975d3c0bd432c66f.info
│ │ │ │ ├── 6d5833966abeadb429de247e4316eef4
│ │ │ │ ├── 6d5833966abeadb429de247e4316eef4.info
│ │ │ │ ├── 6d6f82a762acb4417b895d3babc790f9
│ │ │ │ ├── 6d6f82a762acb4417b895d3babc790f9.info
│ │ │ │ ├── 6d768b1bb52e2c64ba818933dbdd8452
│ │ │ │ ├── 6d768b1bb52e2c64ba818933dbdd8452.info
│ │ │ │ ├── 6d9df2bc198c417db00037803568139c
│ │ │ │ ├── 6d9df2bc198c417db00037803568139c.info
│ │ │ │ ├── 6dbcf248c987476181a37f01a1814975
│ │ │ │ ├── 6dbcf248c987476181a37f01a1814975.info
│ │ │ │ ├── 6de79ae237e51554da96fd28f68b66a6
│ │ │ │ └── 6de79ae237e51554da96fd28f68b66a6.info
│ │ │ ├── 6e/
│ │ │ │ ├── 6e0e62db88935c74288c97c907243bd0
│ │ │ │ ├── 6e0e62db88935c74288c97c907243bd0.info
│ │ │ │ ├── 6e1c8b97ec8aa0464e92506ffe099558
│ │ │ │ ├── 6e1c8b97ec8aa0464e92506ffe099558.info
│ │ │ │ ├── 6e7c80eefe2def5459e0b486b3ab96e2
│ │ │ │ ├── 6e7c80eefe2def5459e0b486b3ab96e2.info
│ │ │ │ ├── 6ecb9e17e44feb84cb80451fa27b09fe
│ │ │ │ └── 6ecb9e17e44feb84cb80451fa27b09fe.info
│ │ │ ├── 6f/
│ │ │ │ ├── 6f1c7ebc8ac78cb951be24c238cbd3ba
│ │ │ │ ├── 6f1c7ebc8ac78cb951be24c238cbd3ba.info
│ │ │ │ ├── 6f25fb081e85cb743b272c2f7fbc2f6b
│ │ │ │ ├── 6f25fb081e85cb743b272c2f7fbc2f6b.info
│ │ │ │ ├── 6f515f8ecd3b6a546b90abaae2553f99
│ │ │ │ ├── 6f515f8ecd3b6a546b90abaae2553f99.info
│ │ │ │ ├── 6f516f1ec21a54a59a92bf99db2d9535
│ │ │ │ ├── 6f516f1ec21a54a59a92bf99db2d9535.info
│ │ │ │ ├── 6f72aa6eab9392548b9e9d92eb6b2ef8
│ │ │ │ ├── 6f72aa6eab9392548b9e9d92eb6b2ef8.info
│ │ │ │ ├── 6f768c3714a34a549960ea903fbadcc2
│ │ │ │ ├── 6f768c3714a34a549960ea903fbadcc2.info
│ │ │ │ ├── 6fdea2af3daa40fe8f88e5e9cfc17abb
│ │ │ │ └── 6fdea2af3daa40fe8f88e5e9cfc17abb.info
│ │ │ ├── 70/
│ │ │ │ ├── 7004c8cc6d477784e8d85fbad56de5f8
│ │ │ │ ├── 7004c8cc6d477784e8d85fbad56de5f8.info
│ │ │ │ ├── 7043e9a330ac2d84a80a965ada4589ad
│ │ │ │ ├── 7043e9a330ac2d84a80a965ada4589ad.info
│ │ │ │ ├── 7065397ff8184621aa3ca4f854491259
│ │ │ │ ├── 7065397ff8184621aa3ca4f854491259.info
│ │ │ │ ├── 7071adaea60f6124d9ab426b002d5afa
│ │ │ │ ├── 7071adaea60f6124d9ab426b002d5afa.info
│ │ │ │ ├── 70a190a1b304d1e43995af35d09231d6
│ │ │ │ ├── 70a190a1b304d1e43995af35d09231d6.info
│ │ │ │ ├── 70b265ed18dc14041bedc0263d4578ef
│ │ │ │ ├── 70b265ed18dc14041bedc0263d4578ef.info
│ │ │ │ ├── 70d4d75a2877243758b0750cbc75b6eb
│ │ │ │ ├── 70d4d75a2877243758b0750cbc75b6eb.info
│ │ │ │ ├── 70eae1897c9d308448eb3bb0b5be9f58
│ │ │ │ ├── 70eae1897c9d308448eb3bb0b5be9f58.info
│ │ │ │ ├── 70f955bbb437a494888ef54d97abb474
│ │ │ │ └── 70f955bbb437a494888ef54d97abb474.info
│ │ │ ├── 71/
│ │ │ │ ├── 7116e04a377b195458798657c617e324
│ │ │ │ ├── 7116e04a377b195458798657c617e324.info
│ │ │ │ ├── 718966f960cb50643986195e5fe953ca
│ │ │ │ ├── 718966f960cb50643986195e5fe953ca.info
│ │ │ │ ├── 71bb46b59a9a7a346bbab1e185c723df
│ │ │ │ ├── 71bb46b59a9a7a346bbab1e185c723df.info
│ │ │ │ ├── 71c1514a6bd24e1e882cebbe1904ce04
│ │ │ │ └── 71c1514a6bd24e1e882cebbe1904ce04.info
│ │ │ ├── 72/
│ │ │ │ ├── 7241c7dc25374fc1a6ab3ef9da79c363
│ │ │ │ ├── 7241c7dc25374fc1a6ab3ef9da79c363.info
│ │ │ │ ├── 725600e98a048ad46aacb96a8bb155cd
│ │ │ │ ├── 725600e98a048ad46aacb96a8bb155cd.info
│ │ │ │ ├── 728d2c19676ea3743aaa087aa28c4a16
│ │ │ │ └── 728d2c19676ea3743aaa087aa28c4a16.info
│ │ │ ├── 73/
│ │ │ │ ├── 7341c0cd0aad4994e8fa461cb443aa7d
│ │ │ │ ├── 7341c0cd0aad4994e8fa461cb443aa7d.info
│ │ │ │ ├── 735d54f21944f834f931716514c87a84
│ │ │ │ ├── 735d54f21944f834f931716514c87a84.info
│ │ │ │ ├── 73deb9b8722aa284eab27c4dc90956c6
│ │ │ │ └── 73deb9b8722aa284eab27c4dc90956c6.info
│ │ │ ├── 74/
│ │ │ │ ├── 740b3785866edda4b8d1e1a05570a5f8
│ │ │ │ ├── 740b3785866edda4b8d1e1a05570a5f8.info
│ │ │ │ ├── 742654cad2425334696ba6ed4495cfef
│ │ │ │ ├── 742654cad2425334696ba6ed4495cfef.info
│ │ │ │ ├── 74374298effb78d47b85450f7f724cef
│ │ │ │ ├── 74374298effb78d47b85450f7f724cef.info
│ │ │ │ ├── 743879b4db4bc1a4b829aae4386f4acf
│ │ │ │ ├── 743879b4db4bc1a4b829aae4386f4acf.info
│ │ │ │ ├── 7496af95dfe67cf429ac65edaaf99106
│ │ │ │ └── 7496af95dfe67cf429ac65edaaf99106.info
│ │ │ ├── 75/
│ │ │ │ ├── 750aad009559b814dbc27001341fc1c3
│ │ │ │ ├── 750aad009559b814dbc27001341fc1c3.info
│ │ │ │ ├── 75df57ccb1e44c64085399277405e1ca
│ │ │ │ ├── 75df57ccb1e44c64085399277405e1ca.info
│ │ │ │ ├── 75e7d7a9a57458841a85fe42d9c9141f
│ │ │ │ └── 75e7d7a9a57458841a85fe42d9c9141f.info
│ │ │ ├── 76/
│ │ │ │ ├── 7602252bdb82b8d45ae3483c3a00d3e1
│ │ │ │ ├── 7602252bdb82b8d45ae3483c3a00d3e1.info
│ │ │ │ ├── 7693972390a4ed841a986c0c452c1058
│ │ │ │ ├── 7693972390a4ed841a986c0c452c1058.info
│ │ │ │ ├── 769f6f5dd7c8f2d4c9ab1caba0bd2628
│ │ │ │ ├── 769f6f5dd7c8f2d4c9ab1caba0bd2628.info
│ │ │ │ ├── 76b6bf32a6fcf934aab8c529bddccc81
│ │ │ │ ├── 76b6bf32a6fcf934aab8c529bddccc81.info
│ │ │ │ ├── 76c392e42b5098c458856cdf6ecaaaa1
│ │ │ │ ├── 76c392e42b5098c458856cdf6ecaaaa1.info
│ │ │ │ ├── 76c82729ad712f14bae1a8a279c52ac3
│ │ │ │ └── 76c82729ad712f14bae1a8a279c52ac3.info
│ │ │ ├── 77/
│ │ │ │ ├── 77476292f9fa4905a787e6417853846b
│ │ │ │ ├── 77476292f9fa4905a787e6417853846b.info
│ │ │ │ ├── 7748a1d3701ac824ea7f366ba0388f5d
│ │ │ │ ├── 7748a1d3701ac824ea7f366ba0388f5d.info
│ │ │ │ ├── 77f432980bb30084299a138e15c6f571
│ │ │ │ └── 77f432980bb30084299a138e15c6f571.info
│ │ │ ├── 78/
│ │ │ │ ├── 78213b1ce4da5e6438195d405c9da0f5
│ │ │ │ ├── 78213b1ce4da5e6438195d405c9da0f5.info
│ │ │ │ ├── 782c49e6e68074dc7ba12c95537825ce
│ │ │ │ ├── 782c49e6e68074dc7ba12c95537825ce.info
│ │ │ │ ├── 782de34c17796430ba8d0ceddb60944e
│ │ │ │ ├── 782de34c17796430ba8d0ceddb60944e.info
│ │ │ │ ├── 7883cd788d83a71478342eef943e8150
│ │ │ │ ├── 7883cd788d83a71478342eef943e8150.info
│ │ │ │ ├── 7895e41fc42ee304cbd33be552917a5a
│ │ │ │ └── 7895e41fc42ee304cbd33be552917a5a.info
│ │ │ ├── 79/
│ │ │ │ ├── 794f3951c48395848920fdb593a2ae38
│ │ │ │ ├── 794f3951c48395848920fdb593a2ae38.info
│ │ │ │ ├── 798968d841703b54bb9d08b1da6bc52f
│ │ │ │ ├── 798968d841703b54bb9d08b1da6bc52f.info
│ │ │ │ ├── 79ced2556f0af814a840b86232613ff1
│ │ │ │ ├── 79ced2556f0af814a840b86232613ff1.info
│ │ │ │ ├── 79ff392d1bde4ad78a3836a4a480392d
│ │ │ │ └── 79ff392d1bde4ad78a3836a4a480392d.info
│ │ │ ├── 7a/
│ │ │ │ ├── 7a24ec4b5c3e08e47bf50c8298c1fe0d
│ │ │ │ ├── 7a24ec4b5c3e08e47bf50c8298c1fe0d.info
│ │ │ │ ├── 7a892c920c8ad2848b469ec9579c5219
│ │ │ │ ├── 7a892c920c8ad2848b469ec9579c5219.info
│ │ │ │ ├── 7a98125502f715b4b83cfb77b434e436
│ │ │ │ ├── 7a98125502f715b4b83cfb77b434e436.info
│ │ │ │ ├── 7af6ac3e6b51b8d4aab04adc85b8de2f
│ │ │ │ └── 7af6ac3e6b51b8d4aab04adc85b8de2f.info
│ │ │ ├── 7b/
│ │ │ │ ├── 7b743370ac3e4ec2a1668f5455a8ef8a
│ │ │ │ ├── 7b743370ac3e4ec2a1668f5455a8ef8a.info
│ │ │ │ ├── 7bd96d76711152648a736c4d28d865f2
│ │ │ │ ├── 7bd96d76711152648a736c4d28d865f2.info
│ │ │ │ ├── 7be84a49bb2cd7e4a9ed097ba22794d0
│ │ │ │ └── 7be84a49bb2cd7e4a9ed097ba22794d0.info
│ │ │ ├── 7c/
│ │ │ │ ├── 7c04f0dfa9243c04681a55d90d3ff3fc
│ │ │ │ ├── 7c04f0dfa9243c04681a55d90d3ff3fc.info
│ │ │ │ ├── 7c6295db74da28645bf49db58b7c9c65
│ │ │ │ ├── 7c6295db74da28645bf49db58b7c9c65.info
│ │ │ │ ├── 7cfaad4e53832d94c9421d2dd1ad82f7
│ │ │ │ └── 7cfaad4e53832d94c9421d2dd1ad82f7.info
│ │ │ ├── 7d/
│ │ │ │ ├── 7d36034e63ad8254b9b2f55280fcc040
│ │ │ │ ├── 7d36034e63ad8254b9b2f55280fcc040.info
│ │ │ │ ├── 7d3aa106cfe752241997b3759bf80163
│ │ │ │ ├── 7d3aa106cfe752241997b3759bf80163.info
│ │ │ │ ├── 7d7bd4bcc815cfb44b9990c29dabdb9f
│ │ │ │ ├── 7d7bd4bcc815cfb44b9990c29dabdb9f.info
│ │ │ │ ├── 7db44d889e0cbbf4281132a752f96ce1
│ │ │ │ └── 7db44d889e0cbbf4281132a752f96ce1.info
│ │ │ ├── 7e/
│ │ │ │ ├── 7e609b27ad2caa14c83dd9951b6c13c6
│ │ │ │ ├── 7e609b27ad2caa14c83dd9951b6c13c6.info
│ │ │ │ ├── 7ef6801a8b664544aa9f2ab1bc1f8b60
│ │ │ │ ├── 7ef6801a8b664544aa9f2ab1bc1f8b60.info
│ │ │ │ ├── 7ef8348b8ea834d7e1bc214b07f7fb87
│ │ │ │ └── 7ef8348b8ea834d7e1bc214b07f7fb87.info
│ │ │ ├── 7f/
│ │ │ │ ├── 7f27709c942d91541be1fd6aa5cb3d78
│ │ │ │ ├── 7f27709c942d91541be1fd6aa5cb3d78.info
│ │ │ │ ├── 7f65567c9026afb4db5de3355accc636
│ │ │ │ ├── 7f65567c9026afb4db5de3355accc636.info
│ │ │ │ ├── 7fc2147e42d71644aad0eaf9a3526249
│ │ │ │ └── 7fc2147e42d71644aad0eaf9a3526249.info
│ │ │ ├── 80/
│ │ │ │ ├── 803abab0f7e17044db56f8760186dbd1
│ │ │ │ ├── 803abab0f7e17044db56f8760186dbd1.info
│ │ │ │ ├── 806de5a9211448c8b65c8435ebb48dd4
│ │ │ │ ├── 806de5a9211448c8b65c8435ebb48dd4.info
│ │ │ │ ├── 80ae83fdf1fb2c649bccb8c293b94556
│ │ │ │ ├── 80ae83fdf1fb2c649bccb8c293b94556.info
│ │ │ │ ├── 80b10e1c58509a449a3c5aecc07d4455
│ │ │ │ ├── 80b10e1c58509a449a3c5aecc07d4455.info
│ │ │ │ ├── 80beef77cb19e713c7c2d481b65ed485
│ │ │ │ └── 80beef77cb19e713c7c2d481b65ed485.info
│ │ │ ├── 81/
│ │ │ │ ├── 811d999912a5f3f459a637aad029fbc8
│ │ │ │ ├── 811d999912a5f3f459a637aad029fbc8.info
│ │ │ │ ├── 812aaaefaab404448a3e4db49dfa5206
│ │ │ │ ├── 812aaaefaab404448a3e4db49dfa5206.info
│ │ │ │ ├── 8143d3a8390f2c64685e3bc272bd9e90
│ │ │ │ ├── 8143d3a8390f2c64685e3bc272bd9e90.info
│ │ │ │ ├── 81a142c61a4e14d46bb21b02548ad24d
│ │ │ │ ├── 81a142c61a4e14d46bb21b02548ad24d.info
│ │ │ │ ├── 81ed8c76d2bc4a4c95d092c98af4e58f
│ │ │ │ └── 81ed8c76d2bc4a4c95d092c98af4e58f.info
│ │ │ ├── 82/
│ │ │ │ ├── 821f5482c5a3f4389885f4432433f56f
│ │ │ │ ├── 821f5482c5a3f4389885f4432433f56f.info
│ │ │ │ ├── 826b6becaef90fb458eedebe4c2f3664
│ │ │ │ ├── 826b6becaef90fb458eedebe4c2f3664.info
│ │ │ │ ├── 828075bc53f2de84982a943870529b7b
│ │ │ │ ├── 828075bc53f2de84982a943870529b7b.info
│ │ │ │ ├── 82a8ce43816925d4b971951094cb755c
│ │ │ │ ├── 82a8ce43816925d4b971951094cb755c.info
│ │ │ │ ├── 82bf3f737dec0be43a60891958a8da87
│ │ │ │ ├── 82bf3f737dec0be43a60891958a8da87.info
│ │ │ │ ├── 82cd92ffc29383742932b27ca414c80f
│ │ │ │ └── 82cd92ffc29383742932b27ca414c80f.info
│ │ │ ├── 83/
│ │ │ │ ├── 83088ba2132cbc940b7ca0c679a02b0d
│ │ │ │ ├── 83088ba2132cbc940b7ca0c679a02b0d.info
│ │ │ │ ├── 8313ea704470a264295ec9e09aec6ebc
│ │ │ │ ├── 8313ea704470a264295ec9e09aec6ebc.info
│ │ │ │ ├── 83154bbefa9fb00469e42ff5014345a2
│ │ │ │ ├── 83154bbefa9fb00469e42ff5014345a2.info
│ │ │ │ ├── 833143c443f979e44ae0b8ed899e3b59
│ │ │ │ ├── 833143c443f979e44ae0b8ed899e3b59.info
│ │ │ │ ├── 8349e42a2b30c7a4abd8678c203428ba
│ │ │ │ ├── 8349e42a2b30c7a4abd8678c203428ba.info
│ │ │ │ ├── 83eda34b7da01e04aa894f268158b0c0
│ │ │ │ └── 83eda34b7da01e04aa894f268158b0c0.info
│ │ │ ├── 84/
│ │ │ │ ├── 8413ca0e506d42a1a4bd9769f204ad16
│ │ │ │ ├── 8413ca0e506d42a1a4bd9769f204ad16.info
│ │ │ │ ├── 844873d1afe1c3142ab922324950e1dd
│ │ │ │ ├── 844873d1afe1c3142ab922324950e1dd.info
│ │ │ │ ├── 84a92b25f83d49b9bc132d206b370281
│ │ │ │ ├── 84a92b25f83d49b9bc132d206b370281.info
│ │ │ │ ├── 84b5362754a9d934ba259398b757d0be
│ │ │ │ ├── 84b5362754a9d934ba259398b757d0be.info
│ │ │ │ ├── 84d86c98104d94063ad70bc591530f65
│ │ │ │ └── 84d86c98104d94063ad70bc591530f65.info
│ │ │ ├── 85/
│ │ │ │ ├── 850af9f3bf6d14143baf2ecfbf25db52
│ │ │ │ ├── 850af9f3bf6d14143baf2ecfbf25db52.info
│ │ │ │ ├── 850c54ee0b9e1aa740b1c67792eb1f26
│ │ │ │ ├── 850c54ee0b9e1aa740b1c67792eb1f26.info
│ │ │ │ ├── 853edc343b78a7c4c81cbb3851d48c0a
│ │ │ │ ├── 853edc343b78a7c4c81cbb3851d48c0a.info
│ │ │ │ ├── 8573c56c34e616248a3881b2c56280ef
│ │ │ │ ├── 8573c56c34e616248a3881b2c56280ef.info
│ │ │ │ ├── 85dd7af03f02aea4aae13a3945e3b313
│ │ │ │ ├── 85dd7af03f02aea4aae13a3945e3b313.info
│ │ │ │ ├── 85f3c3a3c2623cd4da1661b0479e2ef2
│ │ │ │ └── 85f3c3a3c2623cd4da1661b0479e2ef2.info
│ │ │ ├── 86/
│ │ │ │ ├── 8620e97e7e9859049934889a52248435
│ │ │ │ ├── 8620e97e7e9859049934889a52248435.info
│ │ │ │ ├── 8645aa9c3c74fb34ba9499e14fb332b5
│ │ │ │ ├── 8645aa9c3c74fb34ba9499e14fb332b5.info
│ │ │ │ ├── 86710e43de46f6f4bac7c8e50813a599
│ │ │ │ ├── 86710e43de46f6f4bac7c8e50813a599.info
│ │ │ │ ├── 86cacab070a0a46e99aedb596a32c4fe
│ │ │ │ └── 86cacab070a0a46e99aedb596a32c4fe.info
│ │ │ ├── 87/
│ │ │ │ ├── 871f8edd56e84b8fb295b10cc3c78f36
│ │ │ │ ├── 871f8edd56e84b8fb295b10cc3c78f36.info
│ │ │ │ ├── 872e4b92d663b05489fe34966680c29d
│ │ │ │ ├── 872e4b92d663b05489fe34966680c29d.info
│ │ │ │ ├── 87357ff0dec4ef348a295235835c6ee4
│ │ │ │ ├── 87357ff0dec4ef348a295235835c6ee4.info
│ │ │ │ ├── 874c0713cdc44f549b0161750b48d2c2
│ │ │ │ ├── 874c0713cdc44f549b0161750b48d2c2.info
│ │ │ │ ├── 874e40a588dbb1e48bc128d686337d4e
│ │ │ │ ├── 874e40a588dbb1e48bc128d686337d4e.info
│ │ │ │ ├── 8795e0dd0041d2f44b1fe1959fc9fb53
│ │ │ │ ├── 8795e0dd0041d2f44b1fe1959fc9fb53.info
│ │ │ │ ├── 87a1ae9719ec25d44a4dbec20ec0f892
│ │ │ │ ├── 87a1ae9719ec25d44a4dbec20ec0f892.info
│ │ │ │ ├── 87ab1bebe13f41f89d5427e7d2c34d58
│ │ │ │ ├── 87ab1bebe13f41f89d5427e7d2c34d58.info
│ │ │ │ ├── 87d720faa37005c08600090e04d8c739
│ │ │ │ └── 87d720faa37005c08600090e04d8c739.info
│ │ │ ├── 88/
│ │ │ │ ├── 882f1a4147a284f028899b9c018e63eb
│ │ │ │ ├── 882f1a4147a284f028899b9c018e63eb.info
│ │ │ │ ├── 88338eb35defad644a48718188e8f219
│ │ │ │ ├── 88338eb35defad644a48718188e8f219.info
│ │ │ │ ├── 88ed537c17c34f339121fe9a7d6d7a0e
│ │ │ │ └── 88ed537c17c34f339121fe9a7d6d7a0e.info
│ │ │ ├── 89/
│ │ │ │ ├── 8938e753b3f47374889d5cf3265b563c
│ │ │ │ ├── 8938e753b3f47374889d5cf3265b563c.info
│ │ │ │ ├── 898bc38486fc899428fbe5bd6adfe473
│ │ │ │ ├── 898bc38486fc899428fbe5bd6adfe473.info
│ │ │ │ ├── 89b31ff5ca0a5eb4797ac65d43949807
│ │ │ │ ├── 89b31ff5ca0a5eb4797ac65d43949807.info
│ │ │ │ ├── 89b48a03f6f43e94e87cc8d2104d3d4d
│ │ │ │ ├── 89b48a03f6f43e94e87cc8d2104d3d4d.info
│ │ │ │ ├── 89df79cf5061c394d82abd40383976e5
│ │ │ │ ├── 89df79cf5061c394d82abd40383976e5.info
│ │ │ │ ├── 89e0061781af2da4d938cac6c7381fdc
│ │ │ │ └── 89e0061781af2da4d938cac6c7381fdc.info
│ │ │ ├── 8a/
│ │ │ │ ├── 8a13cbeb2099aca47bb456f49845f86c
│ │ │ │ ├── 8a13cbeb2099aca47bb456f49845f86c.info
│ │ │ │ ├── 8a4b6301a5afaec4cb87d21383ceb0b3
│ │ │ │ ├── 8a4b6301a5afaec4cb87d21383ceb0b3.info
│ │ │ │ ├── 8a8695521f0d02e499659fee002a26c2
│ │ │ │ ├── 8a8695521f0d02e499659fee002a26c2.info
│ │ │ │ ├── 8aa8171e088f94069bbd1978a053f7dd
│ │ │ │ └── 8aa8171e088f94069bbd1978a053f7dd.info
│ │ │ ├── 8b/
│ │ │ │ ├── 8b22792c3b570444eb18cb78c2af3a74
│ │ │ │ ├── 8b22792c3b570444eb18cb78c2af3a74.info
│ │ │ │ ├── 8b7d06780fca6fc4384580d3ebed9219
│ │ │ │ ├── 8b7d06780fca6fc4384580d3ebed9219.info
│ │ │ │ ├── 8b845b123ab418448a8be2935fa804e0
│ │ │ │ ├── 8b845b123ab418448a8be2935fa804e0.info
│ │ │ │ ├── 8bb59cb2f66d156418ca1bd1e2703233
│ │ │ │ ├── 8bb59cb2f66d156418ca1bd1e2703233.info
│ │ │ │ ├── 8bc2b083b068f3546a9509c805e0541c
│ │ │ │ ├── 8bc2b083b068f3546a9509c805e0541c.info
│ │ │ │ ├── 8bc445bb79654bf496c92d0407840a92
│ │ │ │ ├── 8bc445bb79654bf496c92d0407840a92.info
│ │ │ │ ├── 8bc74398aa3944646ade4ee78cd57484
│ │ │ │ ├── 8bc74398aa3944646ade4ee78cd57484.info
│ │ │ │ ├── 8beed9aab74505d488e6befe54c3f6ef
│ │ │ │ └── 8beed9aab74505d488e6befe54c3f6ef.info
│ │ │ ├── 8c/
│ │ │ │ ├── 8cc83bff6b39f3d44af0de8320999144
│ │ │ │ └── 8cc83bff6b39f3d44af0de8320999144.info
│ │ │ ├── 8d/
│ │ │ │ ├── 8d20eedbe40f0ce41a4c4f633f225de8
│ │ │ │ ├── 8d20eedbe40f0ce41a4c4f633f225de8.info
│ │ │ │ ├── 8d34348f8b97a334291f5cf31adc5d67
│ │ │ │ ├── 8d34348f8b97a334291f5cf31adc5d67.info
│ │ │ │ ├── 8db4dc37ed52fc24ba715aaa8e0fd20f
│ │ │ │ ├── 8db4dc37ed52fc24ba715aaa8e0fd20f.info
│ │ │ │ ├── 8df45492ff0815a488744d61efcecba7
│ │ │ │ └── 8df45492ff0815a488744d61efcecba7.info
│ │ │ ├── 8e/
│ │ │ │ ├── 8e6115ff67c8ba44ba8780322ca78ef8
│ │ │ │ ├── 8e6115ff67c8ba44ba8780322ca78ef8.info
│ │ │ │ ├── 8e78f8a8575e4a04f8337a54e241cdc5
│ │ │ │ └── 8e78f8a8575e4a04f8337a54e241cdc5.info
│ │ │ ├── 8f/
│ │ │ │ ├── 8f74c99a65464bb4b86ccb314ee95a7f
│ │ │ │ ├── 8f74c99a65464bb4b86ccb314ee95a7f.info
│ │ │ │ ├── 8f7652e09069a1943278893d4264401e
│ │ │ │ ├── 8f7652e09069a1943278893d4264401e.info
│ │ │ │ ├── 8f8b248abe6b4dcebd6cdd0d754717f4
│ │ │ │ └── 8f8b248abe6b4dcebd6cdd0d754717f4.info
│ │ │ ├── 90/
│ │ │ │ ├── 900aac3710bc14542a8d164e3f0ff820
│ │ │ │ ├── 900aac3710bc14542a8d164e3f0ff820.info
│ │ │ │ ├── 900f1a451c764dc3bdcc0de815a15935
│ │ │ │ ├── 900f1a451c764dc3bdcc0de815a15935.info
│ │ │ │ ├── 9014630255533ed42915965b4065cde8
│ │ │ │ ├── 9014630255533ed42915965b4065cde8.info
│ │ │ │ ├── 901b761c5c1e22d4e8a3ba7d95bc1f5d
│ │ │ │ ├── 901b761c5c1e22d4e8a3ba7d95bc1f5d.info
│ │ │ │ ├── 906c12bc9cd95d3963c6d58f62522c78
│ │ │ │ ├── 906c12bc9cd95d3963c6d58f62522c78.info
│ │ │ │ ├── 907dff89ca8c76745b031725757e5f8b
│ │ │ │ ├── 907dff89ca8c76745b031725757e5f8b.info
│ │ │ │ ├── 9085046f02f69544eb97fd06b6048fe2
│ │ │ │ ├── 9085046f02f69544eb97fd06b6048fe2.info
│ │ │ │ ├── 90fe1c65e6bb3bc4e90862df7297719e
│ │ │ │ └── 90fe1c65e6bb3bc4e90862df7297719e.info
│ │ │ ├── 91/
│ │ │ │ ├── 9129183a42052cd43b9c284d6dbd541e
│ │ │ │ ├── 9129183a42052cd43b9c284d6dbd541e.info
│ │ │ │ ├── 91319408591cec1478efd3c62f9f418a
│ │ │ │ ├── 91319408591cec1478efd3c62f9f418a.info
│ │ │ │ ├── 91950f78729ab144aa36e94690b28fad
│ │ │ │ ├── 91950f78729ab144aa36e94690b28fad.info
│ │ │ │ ├── 919d97c1a707113409177d498d31cf51
│ │ │ │ ├── 919d97c1a707113409177d498d31cf51.info
│ │ │ │ ├── 91c20d2c22b8b3a4cb6c816bd225591a
│ │ │ │ ├── 91c20d2c22b8b3a4cb6c816bd225591a.info
│ │ │ │ ├── 91f495459b6e34f419ac123740d798b1
│ │ │ │ └── 91f495459b6e34f419ac123740d798b1.info
│ │ │ ├── 92/
│ │ │ │ ├── 92027f7f8cfc4feaa477da0dc38d3d46
│ │ │ │ ├── 92027f7f8cfc4feaa477da0dc38d3d46.info
│ │ │ │ ├── 9202fbba95ea8294cb5e718f028f21b0
│ │ │ │ ├── 9202fbba95ea8294cb5e718f028f21b0.info
│ │ │ │ ├── 926a61ff0dec44a5aab649acb411e9ad
│ │ │ │ ├── 926a61ff0dec44a5aab649acb411e9ad.info
│ │ │ │ ├── 9288066c33474b94b6ee5465f4df1cc0
│ │ │ │ ├── 9288066c33474b94b6ee5465f4df1cc0.info
│ │ │ │ ├── 928dc55e2c8c3ee4dad33b6d561cb6ea
│ │ │ │ ├── 928dc55e2c8c3ee4dad33b6d561cb6ea.info
│ │ │ │ ├── 92a378669877c05c6071d0fed687bb95
│ │ │ │ └── 92a378669877c05c6071d0fed687bb95.info
│ │ │ ├── 93/
│ │ │ │ ├── 93665e8b67658804d99c4487228cc050
│ │ │ │ ├── 93665e8b67658804d99c4487228cc050.info
│ │ │ │ ├── 936bea4b2545c4a4fad2e623b0f6371f
│ │ │ │ ├── 936bea4b2545c4a4fad2e623b0f6371f.info
│ │ │ │ ├── 936c6340f3468444ebb1785b4c311126
│ │ │ │ ├── 936c6340f3468444ebb1785b4c311126.info
│ │ │ │ ├── 9390296e78291b543b2f4a9761ef8139
│ │ │ │ ├── 9390296e78291b543b2f4a9761ef8139.info
│ │ │ │ ├── 93eea84e53d0226479c9a584f19427b5
│ │ │ │ ├── 93eea84e53d0226479c9a584f19427b5.info
│ │ │ │ ├── 93effba7cf7f3824ab0bd048a27a9c02
│ │ │ │ └── 93effba7cf7f3824ab0bd048a27a9c02.info
│ │ │ ├── 94/
│ │ │ │ ├── 94412382cf909c843b9a46a8f6b364f4
│ │ │ │ ├── 94412382cf909c843b9a46a8f6b364f4.info
│ │ │ │ ├── 945f4ecec6df62244b9ebcc363833642
│ │ │ │ ├── 945f4ecec6df62244b9ebcc363833642.info
│ │ │ │ ├── 949b7e126b3f27940885a6808a15458e
│ │ │ │ ├── 949b7e126b3f27940885a6808a15458e.info
│ │ │ │ ├── 94a7f67cf7303d94fa3f076bd9f33095
│ │ │ │ └── 94a7f67cf7303d94fa3f076bd9f33095.info
│ │ │ ├── 95/
│ │ │ │ ├── 9502550ba4785e3499d6c9251fa2114b
│ │ │ │ ├── 9502550ba4785e3499d6c9251fa2114b.info
│ │ │ │ ├── 950890083f4907541a6ed06d70959e49
│ │ │ │ ├── 950890083f4907541a6ed06d70959e49.info
│ │ │ │ ├── 952b3dc7b47846947b37c8d3ae46579a
│ │ │ │ ├── 952b3dc7b47846947b37c8d3ae46579a.info
│ │ │ │ ├── 953fab16d15d5885b3600fcd6388b2ad
│ │ │ │ ├── 953fab16d15d5885b3600fcd6388b2ad.info
│ │ │ │ ├── 9541d86e2fd84c1d9990edf0852d74ab
│ │ │ │ ├── 9541d86e2fd84c1d9990edf0852d74ab.info
│ │ │ │ ├── 9545c9eb3bf94265810463794fec8334
│ │ │ │ ├── 9545c9eb3bf94265810463794fec8334.info
│ │ │ │ ├── 95a2914724952ef40bb590d0607fc878
│ │ │ │ ├── 95a2914724952ef40bb590d0607fc878.info
│ │ │ │ ├── 95b719082a664ea45bb56759eed1f271
│ │ │ │ ├── 95b719082a664ea45bb56759eed1f271.info
│ │ │ │ ├── 95c91abdcc1ea03458c2ea4e9626a5d8
│ │ │ │ ├── 95c91abdcc1ea03458c2ea4e9626a5d8.info
│ │ │ │ ├── 95cdf27b47eb82747ba9e51f41e72a35
│ │ │ │ ├── 95cdf27b47eb82747ba9e51f41e72a35.info
│ │ │ │ ├── 95f85adeda79e994f011eb2152cf4fc9
│ │ │ │ └── 95f85adeda79e994f011eb2152cf4fc9.info
│ │ │ ├── 96/
│ │ │ │ ├── 961642509dec50b44a293d26240140ec
│ │ │ │ ├── 961642509dec50b44a293d26240140ec.info
│ │ │ │ ├── 9650d910fcaefb34cb45f121c1993892
│ │ │ │ ├── 9650d910fcaefb34cb45f121c1993892.info
│ │ │ │ ├── 9685354eb873b8d4699078b307b0f260
│ │ │ │ ├── 9685354eb873b8d4699078b307b0f260.info
│ │ │ │ ├── 968a09f153574430a6e15ae975145768
│ │ │ │ ├── 968a09f153574430a6e15ae975145768.info
│ │ │ │ ├── 96b44f7d98314b139324a8a87eb66067
│ │ │ │ ├── 96b44f7d98314b139324a8a87eb66067.info
│ │ │ │ ├── 96c503bf059df984c86eecf572370347
│ │ │ │ ├── 96c503bf059df984c86eecf572370347.info
│ │ │ │ ├── 96d14b71b907bb52333b2886e665aba6
│ │ │ │ ├── 96d14b71b907bb52333b2886e665aba6.info
│ │ │ │ ├── 96e9072453a441618754c478755b3028
│ │ │ │ └── 96e9072453a441618754c478755b3028.info
│ │ │ ├── 97/
│ │ │ │ ├── 970e7735a0864fd40842a36d053d08fe
│ │ │ │ ├── 970e7735a0864fd40842a36d053d08fe.info
│ │ │ │ ├── 9713795381722eb43b623dffba25d115
│ │ │ │ ├── 9713795381722eb43b623dffba25d115.info
│ │ │ │ ├── 973b024861c5ae84f869aad614234b04
│ │ │ │ ├── 973b024861c5ae84f869aad614234b04.info
│ │ │ │ ├── 976acc75bfafe594cb01142ba21947be
│ │ │ │ ├── 976acc75bfafe594cb01142ba21947be.info
│ │ │ │ ├── 977190a4db46de442aed27279d247df4
│ │ │ │ ├── 977190a4db46de442aed27279d247df4.info
│ │ │ │ ├── 97a05971510726f438153cd4987526fb
│ │ │ │ ├── 97a05971510726f438153cd4987526fb.info
│ │ │ │ ├── 97d6c87381e3e51488b49f5891490b70
│ │ │ │ ├── 97d6c87381e3e51488b49f5891490b70.info
│ │ │ │ ├── 97f2c862ef7ea1d4fa3423506b5cf0ff
│ │ │ │ └── 97f2c862ef7ea1d4fa3423506b5cf0ff.info
│ │ │ ├── 98/
│ │ │ │ ├── 9805855c8e379ed4cad77f639aaddb73
│ │ │ │ ├── 9805855c8e379ed4cad77f639aaddb73.info
│ │ │ │ ├── 980daac0955b74442b91df43f0f1b776
│ │ │ │ ├── 980daac0955b74442b91df43f0f1b776.info
│ │ │ │ ├── 983c76d87fb6f4f4597a526a4b2b5fd7
│ │ │ │ ├── 983c76d87fb6f4f4597a526a4b2b5fd7.info
│ │ │ │ ├── 985eed4bc2fbee941b761b8816d9055d
│ │ │ │ ├── 985eed4bc2fbee941b761b8816d9055d.info
│ │ │ │ ├── 98808b11e78f6c84a841a6b4bc5a29d2
│ │ │ │ ├── 98808b11e78f6c84a841a6b4bc5a29d2.info
│ │ │ │ ├── 98ba0396e4b4ee8498a8f097affcfddf
│ │ │ │ ├── 98ba0396e4b4ee8498a8f097affcfddf.info
│ │ │ │ ├── 98bf0690f0c9686468d3866e3c0e5e45
│ │ │ │ ├── 98bf0690f0c9686468d3866e3c0e5e45.info
│ │ │ │ ├── 98d14ab1acf42df4f88a0561822ac807
│ │ │ │ └── 98d14ab1acf42df4f88a0561822ac807.info
│ │ │ ├── 99/
│ │ │ │ ├── 9945ffed4692c6044b6d3acf81efd694
│ │ │ │ ├── 9945ffed4692c6044b6d3acf81efd694.info
│ │ │ │ ├── 995c08a3305ff9f0dab5e86f340bd9a7
│ │ │ │ ├── 995c08a3305ff9f0dab5e86f340bd9a7.info
│ │ │ │ ├── 99744ed686e28004180091658ee4f5ae
│ │ │ │ ├── 99744ed686e28004180091658ee4f5ae.info
│ │ │ │ ├── 99c5970046bb263469514e56eb6aa519
│ │ │ │ └── 99c5970046bb263469514e56eb6aa519.info
│ │ │ ├── 9a/
│ │ │ │ ├── 9a0f991b6c2f45b44b92e163f9969e8e
│ │ │ │ ├── 9a0f991b6c2f45b44b92e163f9969e8e.info
│ │ │ │ ├── 9a3557da07c729b4eb774b8e30e157a4
│ │ │ │ ├── 9a3557da07c729b4eb774b8e30e157a4.info
│ │ │ │ ├── 9a371bcbba2084dd0a8ebc6826aa8794
│ │ │ │ ├── 9a371bcbba2084dd0a8ebc6826aa8794.info
│ │ │ │ ├── 9a6069768ff3d8043a79348813f86cba
│ │ │ │ ├── 9a6069768ff3d8043a79348813f86cba.info
│ │ │ │ ├── 9ace5095cc37ed849b52109d2ee305d4
│ │ │ │ ├── 9ace5095cc37ed849b52109d2ee305d4.info
│ │ │ │ ├── 9ad0b0c865b01af4ca1b414689e71259
│ │ │ │ └── 9ad0b0c865b01af4ca1b414689e71259.info
│ │ │ ├── 9b/
│ │ │ │ ├── 9b1a3034a9e81704abdd08677a2d035f
│ │ │ │ ├── 9b1a3034a9e81704abdd08677a2d035f.info
│ │ │ │ ├── 9b4f21acd14fdd445b37b76f6587539e
│ │ │ │ ├── 9b4f21acd14fdd445b37b76f6587539e.info
│ │ │ │ ├── 9b5abcb38bac0c54794ad732a3fa0de3
│ │ │ │ ├── 9b5abcb38bac0c54794ad732a3fa0de3.info
│ │ │ │ ├── 9bc2b69915879416f8df18971dc98e2e
│ │ │ │ ├── 9bc2b69915879416f8df18971dc98e2e.info
│ │ │ │ ├── 9bd5a110ed89025499ddee8c7e73778e
│ │ │ │ ├── 9bd5a110ed89025499ddee8c7e73778e.info
│ │ │ │ ├── 9be6112c2b1c3ae44927680ba7b36e10
│ │ │ │ ├── 9be6112c2b1c3ae44927680ba7b36e10.info
│ │ │ │ ├── 9bedab6f9886aee42b33e424bffdb640
│ │ │ │ └── 9bedab6f9886aee42b33e424bffdb640.info
│ │ │ ├── 9c/
│ │ │ │ ├── 9c2177aaf0fde92439246adc2dc0bfa2
│ │ │ │ ├── 9c2177aaf0fde92439246adc2dc0bfa2.info
│ │ │ │ ├── 9c21cfda3336137438c3001d40564be0
│ │ │ │ ├── 9c21cfda3336137438c3001d40564be0.info
│ │ │ │ ├── 9c4a050f089abb04ebd4125e419f4548
│ │ │ │ ├── 9c4a050f089abb04ebd4125e419f4548.info
│ │ │ │ ├── 9c7ad350fb20c854a9112cf4156d1b6e
│ │ │ │ ├── 9c7ad350fb20c854a9112cf4156d1b6e.info
│ │ │ │ ├── 9c7c268fa6492449654839df69f2a2f4
│ │ │ │ ├── 9c7c268fa6492449654839df69f2a2f4.info
│ │ │ │ ├── 9c8ceb9efacb4974bb3b7e2a87137b07
│ │ │ │ ├── 9c8ceb9efacb4974bb3b7e2a87137b07.info
│ │ │ │ ├── 9c9e5198af35eb74d8c5d84a5194b184
│ │ │ │ ├── 9c9e5198af35eb74d8c5d84a5194b184.info
│ │ │ │ ├── 9ce3cf11b8f74594bb7b1e1dba03122d
│ │ │ │ └── 9ce3cf11b8f74594bb7b1e1dba03122d.info
│ │ │ ├── 9d/
│ │ │ │ ├── 9d614808f9add8a4f8e4860db2c7af0d
│ │ │ │ ├── 9d614808f9add8a4f8e4860db2c7af0d.info
│ │ │ │ ├── 9d816a6ab06c6834480f5f45f440e287
│ │ │ │ ├── 9d816a6ab06c6834480f5f45f440e287.info
│ │ │ │ ├── 9db19a04003fca7439552acd4de9baa1
│ │ │ │ ├── 9db19a04003fca7439552acd4de9baa1.info
│ │ │ │ ├── 9de24983a2c6cbe4f925c3e98a79b804
│ │ │ │ └── 9de24983a2c6cbe4f925c3e98a79b804.info
│ │ │ ├── 9e/
│ │ │ │ ├── 9e2b7a65f0a52974193ed497d145b0bc
│ │ │ │ ├── 9e2b7a65f0a52974193ed497d145b0bc.info
│ │ │ │ ├── 9ec94545c5b00344c9bd8e691f15d799
│ │ │ │ ├── 9ec94545c5b00344c9bd8e691f15d799.info
│ │ │ │ ├── 9edc9283e7d6409fab242fe8fb6a822c
│ │ │ │ └── 9edc9283e7d6409fab242fe8fb6a822c.info
│ │ │ ├── 9f/
│ │ │ │ ├── 9f1026265f8e3d54fb6e9f082c43debf
│ │ │ │ ├── 9f1026265f8e3d54fb6e9f082c43debf.info
│ │ │ │ ├── 9f2f480fb2536e54ab8493a4e7421720
│ │ │ │ └── 9f2f480fb2536e54ab8493a4e7421720.info
│ │ │ ├── a0/
│ │ │ │ ├── a002d3737b873954395b7cf862873ab8
│ │ │ │ ├── a002d3737b873954395b7cf862873ab8.info
│ │ │ │ ├── a021b6d2ca2e9404b8a4d94343ecd068
│ │ │ │ ├── a021b6d2ca2e9404b8a4d94343ecd068.info
│ │ │ │ ├── a025ba7ee40d0104db8d08b1d9eabb0d
│ │ │ │ ├── a025ba7ee40d0104db8d08b1d9eabb0d.info
│ │ │ │ ├── a04a45bbed9e1714f9902fc9443669b9
│ │ │ │ ├── a04a45bbed9e1714f9902fc9443669b9.info
│ │ │ │ ├── a0a02e768c802b641b6793fa864f1c2c
│ │ │ │ ├── a0a02e768c802b641b6793fa864f1c2c.info
│ │ │ │ ├── a0b56195e00682b4594dfaeef9d5fa78
│ │ │ │ ├── a0b56195e00682b4594dfaeef9d5fa78.info
│ │ │ │ ├── a0bae4ff8f5baf64aad3b92b8aea0603
│ │ │ │ ├── a0bae4ff8f5baf64aad3b92b8aea0603.info
│ │ │ │ ├── a0fba9bd62d2b5c4bb89c81f58569c58
│ │ │ │ └── a0fba9bd62d2b5c4bb89c81f58569c58.info
│ │ │ ├── a1/
│ │ │ │ ├── a132bd53f9677ee489dac2f1da2b05ea
│ │ │ │ ├── a132bd53f9677ee489dac2f1da2b05ea.info
│ │ │ │ ├── a14a59f2a5c757e469c3e4e17b798c2e
│ │ │ │ └── a14a59f2a5c757e469c3e4e17b798c2e.info
│ │ │ ├── a2/
│ │ │ │ ├── a2a8aecb05814e644abbb070fbd91156
│ │ │ │ ├── a2a8aecb05814e644abbb070fbd91156.info
│ │ │ │ ├── a2cb43d6b0c226443be7e176590837a5
│ │ │ │ ├── a2cb43d6b0c226443be7e176590837a5.info
│ │ │ │ ├── a2cc3e5914c2bb345a87c15d0b894ee8
│ │ │ │ └── a2cc3e5914c2bb345a87c15d0b894ee8.info
│ │ │ ├── a3/
│ │ │ │ ├── a331c23f613bfba4294059442ab01d4e
│ │ │ │ ├── a331c23f613bfba4294059442ab01d4e.info
│ │ │ │ ├── a3529368f4cd0424a89aa51080a16b06
│ │ │ │ ├── a3529368f4cd0424a89aa51080a16b06.info
│ │ │ │ ├── a36d8b72880a8004f96ac54ce4598ff9
│ │ │ │ ├── a36d8b72880a8004f96ac54ce4598ff9.info
│ │ │ │ ├── a3949cc8bd731bb47bedf6589367d0c9
│ │ │ │ ├── a3949cc8bd731bb47bedf6589367d0c9.info
│ │ │ │ ├── a3c7ce509d225e740aed9d6579e2a1e9
│ │ │ │ └── a3c7ce509d225e740aed9d6579e2a1e9.info
│ │ │ ├── a4/
│ │ │ │ ├── a429b38ee9d48c7408c8870baf406034
│ │ │ │ ├── a429b38ee9d48c7408c8870baf406034.info
│ │ │ │ ├── a4610cf559d77b9f256416d9ccaeac55
│ │ │ │ ├── a4610cf559d77b9f256416d9ccaeac55.info
│ │ │ │ ├── a483595b0257945278dc75c5ff7d82ee
│ │ │ │ ├── a483595b0257945278dc75c5ff7d82ee.info
│ │ │ │ ├── a4cac3a64ff3a4540bbabd58e2d7c8b2
│ │ │ │ └── a4cac3a64ff3a4540bbabd58e2d7c8b2.info
│ │ │ ├── a5/
│ │ │ │ ├── a55fb7b4961a425381d1282fc424f966
│ │ │ │ ├── a55fb7b4961a425381d1282fc424f966.info
│ │ │ │ ├── a582090813554df479fb9ca03e9857d3
│ │ │ │ ├── a582090813554df479fb9ca03e9857d3.info
│ │ │ │ ├── a598580d0cfc7224ebed8d2b627d9e00
│ │ │ │ ├── a598580d0cfc7224ebed8d2b627d9e00.info
│ │ │ │ ├── a59c2e62fbd97f84f92c3b546e3903cb
│ │ │ │ ├── a59c2e62fbd97f84f92c3b546e3903cb.info
│ │ │ │ ├── a5c214e5846a99242b348c37e49b2f59
│ │ │ │ └── a5c214e5846a99242b348c37e49b2f59.info
│ │ │ ├── a6/
│ │ │ │ ├── a6238e9452bfc704f82ff36791fe1a45
│ │ │ │ ├── a6238e9452bfc704f82ff36791fe1a45.info
│ │ │ │ ├── a62706dc421fc9b4fa368a8050a930f7
│ │ │ │ ├── a62706dc421fc9b4fa368a8050a930f7.info
│ │ │ │ ├── a667f6654ad7a9548b8c8e68b51c8895
│ │ │ │ ├── a667f6654ad7a9548b8c8e68b51c8895.info
│ │ │ │ ├── a6ab6fd2b91214e8a9c8ec2224a528de
│ │ │ │ └── a6ab6fd2b91214e8a9c8ec2224a528de.info
│ │ │ ├── a7/
│ │ │ │ ├── a704c010bcdb1ec4a9f3417b3c393164
│ │ │ │ ├── a704c010bcdb1ec4a9f3417b3c393164.info
│ │ │ │ ├── a73ebdb6c1006364f8c7b37dc53d8ab7
│ │ │ │ ├── a73ebdb6c1006364f8c7b37dc53d8ab7.info
│ │ │ │ ├── a7842a837a4b13e41ae16193db753418
│ │ │ │ ├── a7842a837a4b13e41ae16193db753418.info
│ │ │ │ ├── a7c91a123806d41a0873fcdcb629b1c4
│ │ │ │ ├── a7c91a123806d41a0873fcdcb629b1c4.info
│ │ │ │ ├── a7ebd1239373d5f41af65ef32d67f445
│ │ │ │ ├── a7ebd1239373d5f41af65ef32d67f445.info
│ │ │ │ ├── a7ec9e7ad8b847b7ae4510af83c5d868
│ │ │ │ └── a7ec9e7ad8b847b7ae4510af83c5d868.info
│ │ │ ├── a8/
│ │ │ │ ├── a809a4b50addbf44b9023b5e7f9fd4d2
│ │ │ │ ├── a809a4b50addbf44b9023b5e7f9fd4d2.info
│ │ │ │ ├── a8604e8f13b3be84b8bc0c1507d8f3f6
│ │ │ │ ├── a8604e8f13b3be84b8bc0c1507d8f3f6.info
│ │ │ │ ├── a8ed4063f2beecd41a234a582202f3c4
│ │ │ │ └── a8ed4063f2beecd41a234a582202f3c4.info
│ │ │ ├── a9/
│ │ │ │ ├── a9126848c43c4dd499da39a90664dd73
│ │ │ │ ├── a9126848c43c4dd499da39a90664dd73.info
│ │ │ │ ├── a956e5803e95df349bd35832492d4014
│ │ │ │ └── a956e5803e95df349bd35832492d4014.info
│ │ │ ├── aa/
│ │ │ │ ├── aa14b70e6a58c5b4fa6663623e3dca91
│ │ │ │ ├── aa14b70e6a58c5b4fa6663623e3dca91.info
│ │ │ │ ├── aa160f27c3fe4052a5850e21108811b6
│ │ │ │ ├── aa160f27c3fe4052a5850e21108811b6.info
│ │ │ │ ├── aa76955fe5bb44f7915d91db8c7043c4
│ │ │ │ └── aa76955fe5bb44f7915d91db8c7043c4.info
│ │ │ ├── ab/
│ │ │ │ ├── ab2114bdc8544297b417dfefe9f1e410
│ │ │ │ ├── ab2114bdc8544297b417dfefe9f1e410.info
│ │ │ │ ├── ab93e1a81defc3243a6e9cd0df3cb443
│ │ │ │ └── ab93e1a81defc3243a6e9cd0df3cb443.info
│ │ │ ├── ac/
│ │ │ │ ├── ac071ac86a8f1af43827e11a522640e4
│ │ │ │ ├── ac071ac86a8f1af43827e11a522640e4.info
│ │ │ │ ├── ac281230df7b14becb40b3c479f1b429
│ │ │ │ ├── ac281230df7b14becb40b3c479f1b429.info
│ │ │ │ ├── ac3f13489022aa34d861a0320a6917b9
│ │ │ │ ├── ac3f13489022aa34d861a0320a6917b9.info
│ │ │ │ ├── ac68f5ae37c8957468562b8da42f9984
│ │ │ │ ├── ac68f5ae37c8957468562b8da42f9984.info
│ │ │ │ ├── ac742e1acf5f82f45b9d8ec53fe15b21
│ │ │ │ ├── ac742e1acf5f82f45b9d8ec53fe15b21.info
│ │ │ │ ├── acc16f0c684508f44813662a300c574b
│ │ │ │ ├── acc16f0c684508f44813662a300c574b.info
│ │ │ │ ├── acfa3573efc38c844be021fdaa8cf8a6
│ │ │ │ └── acfa3573efc38c844be021fdaa8cf8a6.info
│ │ │ ├── ad/
│ │ │ │ ├── ad09d3e70e7b09244b56b51e495a319c
│ │ │ │ ├── ad09d3e70e7b09244b56b51e495a319c.info
│ │ │ │ ├── ad70ff8d98b257540b683737743828cb
│ │ │ │ ├── ad70ff8d98b257540b683737743828cb.info
│ │ │ │ ├── adf7bea9401c1834380d55601add6cfb
│ │ │ │ └── adf7bea9401c1834380d55601add6cfb.info
│ │ │ ├── ae/
│ │ │ │ ├── ae05f0dd1cf145e4e8e905c7971ee433
│ │ │ │ ├── ae05f0dd1cf145e4e8e905c7971ee433.info
│ │ │ │ ├── ae242449e9279d44789513b922d3178a
│ │ │ │ ├── ae242449e9279d44789513b922d3178a.info
│ │ │ │ ├── ae8ce3ffe04ac2c42945fd27e0291fc3
│ │ │ │ ├── ae8ce3ffe04ac2c42945fd27e0291fc3.info
│ │ │ │ ├── aed7ab02155e43341a2dbcb7bc17c160
│ │ │ │ └── aed7ab02155e43341a2dbcb7bc17c160.info
│ │ │ ├── af/
│ │ │ │ ├── af30a361ab68260438b6ec3fb7e64500
│ │ │ │ ├── af30a361ab68260438b6ec3fb7e64500.info
│ │ │ │ ├── af5042802f06c804c8abddd544b77a4a
│ │ │ │ ├── af5042802f06c804c8abddd544b77a4a.info
│ │ │ │ ├── af84cf39b8fa0654badd9278cbd00d77
│ │ │ │ ├── af84cf39b8fa0654badd9278cbd00d77.info
│ │ │ │ ├── afeb55855d7a63b45ba6f8bd97599202
│ │ │ │ └── afeb55855d7a63b45ba6f8bd97599202.info
│ │ │ ├── b0/
│ │ │ │ ├── b09be1f217d34247af54863a2f5587e1
│ │ │ │ ├── b09be1f217d34247af54863a2f5587e1.info
│ │ │ │ ├── b0c73ea1c5ff95e43806e9002c155070
│ │ │ │ ├── b0c73ea1c5ff95e43806e9002c155070.info
│ │ │ │ ├── b0eeee3cdfa56734abca5c1a4e7989ba
│ │ │ │ └── b0eeee3cdfa56734abca5c1a4e7989ba.info
│ │ │ ├── b1/
│ │ │ │ ├── b10cb8fee5b39014d8a417bf413f5e5c
│ │ │ │ ├── b10cb8fee5b39014d8a417bf413f5e5c.info
│ │ │ │ ├── b124f0b8ca43e6e46bdc0322fad15ea3
│ │ │ │ ├── b124f0b8ca43e6e46bdc0322fad15ea3.info
│ │ │ │ ├── b135ec222fdcd11468014c90d11d6821
│ │ │ │ ├── b135ec222fdcd11468014c90d11d6821.info
│ │ │ │ ├── b14b67faac4aff04fac7127cf1ab4f97
│ │ │ │ ├── b14b67faac4aff04fac7127cf1ab4f97.info
│ │ │ │ ├── b180fd8310805e44dbbef545d0231418
│ │ │ │ ├── b180fd8310805e44dbbef545d0231418.info
│ │ │ │ ├── b1c789407b55e3a4c9cc86135a714e33
│ │ │ │ ├── b1c789407b55e3a4c9cc86135a714e33.info
│ │ │ │ ├── b1d8465ba1376b148bdab58965101f47
│ │ │ │ └── b1d8465ba1376b148bdab58965101f47.info
│ │ │ ├── b2/
│ │ │ │ ├── b219c86ce508e478367c0a46e1aa9fe4
│ │ │ │ ├── b219c86ce508e478367c0a46e1aa9fe4.info
│ │ │ │ ├── b222f61a1f7253e4d8e8cc82bfde9e42
│ │ │ │ ├── b222f61a1f7253e4d8e8cc82bfde9e42.info
│ │ │ │ ├── b250be9db55288b48ac121c074d795e6
│ │ │ │ └── b250be9db55288b48ac121c074d795e6.info
│ │ │ ├── b3/
│ │ │ │ ├── b33687803b08daf418e5315de17658b8
│ │ │ │ ├── b33687803b08daf418e5315de17658b8.info
│ │ │ │ ├── b3cdabf2f1e76854d8aab5930305d70d
│ │ │ │ └── b3cdabf2f1e76854d8aab5930305d70d.info
│ │ │ ├── b4/
│ │ │ │ ├── b42e1db66fe9c634798674cb9e1df2ca
│ │ │ │ ├── b42e1db66fe9c634798674cb9e1df2ca.info
│ │ │ │ ├── b458b2c7f196bdc4581b2f9fd6a5d931
│ │ │ │ ├── b458b2c7f196bdc4581b2f9fd6a5d931.info
│ │ │ │ ├── b46e36075dd1c124a8422c228e75e1fb
│ │ │ │ ├── b46e36075dd1c124a8422c228e75e1fb.info
│ │ │ │ ├── b477d1f29b65a674e9d5cdab4eb72b01
│ │ │ │ ├── b477d1f29b65a674e9d5cdab4eb72b01.info
│ │ │ │ ├── b4a5ce78107bc38409a3bb5e8b3289ac
│ │ │ │ ├── b4a5ce78107bc38409a3bb5e8b3289ac.info
│ │ │ │ ├── b4c60b58ddb35c749ad94bd8b5b83168
│ │ │ │ └── b4c60b58ddb35c749ad94bd8b5b83168.info
│ │ │ ├── b5/
│ │ │ │ ├── b52bde26a83564960bcb90217f72b910
│ │ │ │ ├── b52bde26a83564960bcb90217f72b910.info
│ │ │ │ ├── b5489bb3cd68836439785588fffc67a4
│ │ │ │ ├── b5489bb3cd68836439785588fffc67a4.info
│ │ │ │ ├── b557515fff172984e8c4400b43f1c631
│ │ │ │ ├── b557515fff172984e8c4400b43f1c631.info
│ │ │ │ ├── b57629d89799e004182564256307b0cc
│ │ │ │ ├── b57629d89799e004182564256307b0cc.info
│ │ │ │ ├── b5d6c28ed7b94775be9e2560f300247c
│ │ │ │ ├── b5d6c28ed7b94775be9e2560f300247c.info
│ │ │ │ ├── b5f0881228e5827438f74e9b7b33c2dc
│ │ │ │ ├── b5f0881228e5827438f74e9b7b33c2dc.info
│ │ │ │ ├── b5f31b7e60df3e64796fb7ab6f54f489
│ │ │ │ ├── b5f31b7e60df3e64796fb7ab6f54f489.info
│ │ │ │ ├── b5f70efd2f7b286498ca6c00adbb4a13
│ │ │ │ └── b5f70efd2f7b286498ca6c00adbb4a13.info
│ │ │ ├── b6/
│ │ │ │ ├── b611b0a598aeada419afa9737807c598
│ │ │ │ ├── b611b0a598aeada419afa9737807c598.info
│ │ │ │ ├── b6e75d7f429a4e7e9e1ffb4f85cff49f
│ │ │ │ └── b6e75d7f429a4e7e9e1ffb4f85cff49f.info
│ │ │ ├── b7/
│ │ │ │ ├── b7468a027a77337478e133b40b42b4f9
│ │ │ │ ├── b7468a027a77337478e133b40b42b4f9.info
│ │ │ │ ├── b759d61544e231c41bc88530b1d94ee8
│ │ │ │ ├── b759d61544e231c41bc88530b1d94ee8.info
│ │ │ │ ├── b77b1ad9c05af0412725856c6c53b037
│ │ │ │ ├── b77b1ad9c05af0412725856c6c53b037.info
│ │ │ │ ├── b7abcd1a72bb7174ca58e813c6eee9c2
│ │ │ │ ├── b7abcd1a72bb7174ca58e813c6eee9c2.info
│ │ │ │ ├── b7c13973a7ed1444fb514d09b5e7e579
│ │ │ │ ├── b7c13973a7ed1444fb514d09b5e7e579.info
│ │ │ │ ├── b7cabea05434bb9479aee1e121b0d103
│ │ │ │ ├── b7cabea05434bb9479aee1e121b0d103.info
│ │ │ │ ├── b7ff2b2e91321ff4381d4ab45870a32e
│ │ │ │ └── b7ff2b2e91321ff4381d4ab45870a32e.info
│ │ │ ├── b8/
│ │ │ │ ├── b8046f5b741868b458cdb9b358311fa1
│ │ │ │ ├── b8046f5b741868b458cdb9b358311fa1.info
│ │ │ │ ├── b825fd5f27403b84f97726dd9c5a5e6f
│ │ │ │ ├── b825fd5f27403b84f97726dd9c5a5e6f.info
│ │ │ │ ├── b83f06ac0c0696e9563230865ca72b81
│ │ │ │ ├── b83f06ac0c0696e9563230865ca72b81.info
│ │ │ │ ├── b846f69b139b3a341a5699a09fa52b2c
│ │ │ │ ├── b846f69b139b3a341a5699a09fa52b2c.info
│ │ │ │ ├── b86b117346968ac4d9cc63e4385becb7
│ │ │ │ ├── b86b117346968ac4d9cc63e4385becb7.info
│ │ │ │ ├── b88caca58e05ee74486d86fb404c48e2
│ │ │ │ ├── b88caca58e05ee74486d86fb404c48e2.info
│ │ │ │ ├── b8abb41ceb6f62c45a00197ae59224c1
│ │ │ │ ├── b8abb41ceb6f62c45a00197ae59224c1.info
│ │ │ │ ├── b8c3bda3a988b5f4c910a5c3f722d0be
│ │ │ │ ├── b8c3bda3a988b5f4c910a5c3f722d0be.info
│ │ │ │ ├── b8c5993172f27e4419d7d4ed5ef77840
│ │ │ │ └── b8c5993172f27e4419d7d4ed5ef77840.info
│ │ │ ├── b9/
│ │ │ │ ├── b90311a8f07b00f4bbeb2fff3b128d25
│ │ │ │ ├── b90311a8f07b00f4bbeb2fff3b128d25.info
│ │ │ │ ├── b926af22079e00e4a8c073321194cea1
│ │ │ │ ├── b926af22079e00e4a8c073321194cea1.info
│ │ │ │ ├── b9ba34e0b1884454fbc4257260e22b64
│ │ │ │ ├── b9ba34e0b1884454fbc4257260e22b64.info
│ │ │ │ ├── b9c2a6302985d3846b7b9f6fd9e2da9a
│ │ │ │ ├── b9c2a6302985d3846b7b9f6fd9e2da9a.info
│ │ │ │ ├── b9d7bb79ed0c2854a8a5ed7decc3e44f
│ │ │ │ ├── b9d7bb79ed0c2854a8a5ed7decc3e44f.info
│ │ │ │ ├── b9eb962217e00bf4fbc734e109991fca
│ │ │ │ └── b9eb962217e00bf4fbc734e109991fca.info
│ │ │ ├── ba/
│ │ │ │ ├── ba72b974bd5e43240bd91ade68574875
│ │ │ │ ├── ba72b974bd5e43240bd91ade68574875.info
│ │ │ │ ├── bae197be297529d4fa735fbe7c91828d
│ │ │ │ └── bae197be297529d4fa735fbe7c91828d.info
│ │ │ ├── bb/
│ │ │ │ ├── bb05cab7d802aa5468f8f2f86840d984
│ │ │ │ ├── bb05cab7d802aa5468f8f2f86840d984.info
│ │ │ │ ├── bb32bccaf32a6db448d1c0cc99c78688
│ │ │ │ ├── bb32bccaf32a6db448d1c0cc99c78688.info
│ │ │ │ ├── bb42b2d967d6427983c901a4ffc8ecd9
│ │ │ │ └── bb42b2d967d6427983c901a4ffc8ecd9.info
│ │ │ ├── bc/
│ │ │ │ ├── bc00e25696e4132499f56528d3fed2e3
│ │ │ │ ├── bc00e25696e4132499f56528d3fed2e3.info
│ │ │ │ ├── bc98484caab3b6d4facbcff38be93380
│ │ │ │ ├── bc98484caab3b6d4facbcff38be93380.info
│ │ │ │ ├── bc9aa6d5a7945f34882c442e9e201537
│ │ │ │ └── bc9aa6d5a7945f34882c442e9e201537.info
│ │ │ ├── bd/
│ │ │ │ ├── bd1af0a6633ee94ae21c7d1d702cdc12
│ │ │ │ ├── bd1af0a6633ee94ae21c7d1d702cdc12.info
│ │ │ │ ├── bd3e81baa10021f4d877fa36382bab16
│ │ │ │ ├── bd3e81baa10021f4d877fa36382bab16.info
│ │ │ │ ├── bd3ffb9a97575a44a82f9ca086813154
│ │ │ │ ├── bd3ffb9a97575a44a82f9ca086813154.info
│ │ │ │ ├── bdb4f6935641b574b984da8dc27cab45
│ │ │ │ ├── bdb4f6935641b574b984da8dc27cab45.info
│ │ │ │ ├── bdbd564a9fdad0b738e76d030cad1204
│ │ │ │ └── bdbd564a9fdad0b738e76d030cad1204.info
│ │ │ ├── be/
│ │ │ │ ├── be07f70ee67e6d74e851a9333719bbb6
│ │ │ │ ├── be07f70ee67e6d74e851a9333719bbb6.info
│ │ │ │ ├── be156cc527d606b4aaac403e9843186e
│ │ │ │ ├── be156cc527d606b4aaac403e9843186e.info
│ │ │ │ ├── bea62e1faac8f9a48a4cb919ea05cb6a
│ │ │ │ ├── bea62e1faac8f9a48a4cb919ea05cb6a.info
│ │ │ │ ├── bede4033d9f359b41878c4cda6a910b3
│ │ │ │ ├── bede4033d9f359b41878c4cda6a910b3.info
│ │ │ │ ├── bee384ad5b4d1a843a018082e7db53cd
│ │ │ │ └── bee384ad5b4d1a843a018082e7db53cd.info
│ │ │ ├── bf/
│ │ │ │ ├── bf87e20fb5440ec498f441167b5291f8
│ │ │ │ ├── bf87e20fb5440ec498f441167b5291f8.info
│ │ │ │ ├── bfb788a43e03363419155b8af77da971
│ │ │ │ ├── bfb788a43e03363419155b8af77da971.info
│ │ │ │ ├── bfd567a3d1631a761bca9e99fa53d86d
│ │ │ │ ├── bfd567a3d1631a761bca9e99fa53d86d.info
│ │ │ │ ├── bfda56da833e2384a9677cd3c976a436
│ │ │ │ └── bfda56da833e2384a9677cd3c976a436.info
│ │ │ ├── c0/
│ │ │ │ ├── c060426bfd6e82575228df6656368eaa
│ │ │ │ ├── c060426bfd6e82575228df6656368eaa.info
│ │ │ │ ├── c072e5b741a87974385c270827879cbf
│ │ │ │ └── c072e5b741a87974385c270827879cbf.info
│ │ │ ├── c1/
│ │ │ │ ├── c14a5e4bdca08454eb523515cecf43c2
│ │ │ │ ├── c14a5e4bdca08454eb523515cecf43c2.info
│ │ │ │ ├── c16c54fe03afb5740bcc0a2a295cb79d
│ │ │ │ ├── c16c54fe03afb5740bcc0a2a295cb79d.info
│ │ │ │ ├── c171b9ca03610ea4faa426e082a1075d
│ │ │ │ ├── c171b9ca03610ea4faa426e082a1075d.info
│ │ │ │ ├── c18288a8d31fc9043a807ee8a9f1ae64
│ │ │ │ ├── c18288a8d31fc9043a807ee8a9f1ae64.info
│ │ │ │ ├── c18cb9388313e4287ad5895ee735c47d
│ │ │ │ └── c18cb9388313e4287ad5895ee735c47d.info
│ │ │ ├── c2/
│ │ │ │ ├── c2f7f6a88b4c4f20a53deb72f3d9144c
│ │ │ │ └── c2f7f6a88b4c4f20a53deb72f3d9144c.info
│ │ │ ├── c3/
│ │ │ │ ├── c32df609537c54c46adf92992a673693
│ │ │ │ ├── c32df609537c54c46adf92992a673693.info
│ │ │ │ ├── c346a7445959bba46a96de0747e77c2a
│ │ │ │ ├── c346a7445959bba46a96de0747e77c2a.info
│ │ │ │ ├── c35a186b967e6a24d9d844d412fe08a3
│ │ │ │ ├── c35a186b967e6a24d9d844d412fe08a3.info
│ │ │ │ ├── c38ae0585d6a55042a2d678330689685
│ │ │ │ ├── c38ae0585d6a55042a2d678330689685.info
│ │ │ │ ├── c3a595c9a8ed19040bb2612fe168759d
│ │ │ │ ├── c3a595c9a8ed19040bb2612fe168759d.info
│ │ │ │ ├── c3a75354f6ceac94ca15ca9d96593290
│ │ │ │ ├── c3a75354f6ceac94ca15ca9d96593290.info
│ │ │ │ ├── c3de99f9efc582a48995bc8e8c2df418
│ │ │ │ ├── c3de99f9efc582a48995bc8e8c2df418.info
│ │ │ │ ├── c3efd39f2cfb43a4c830d4fd5689900f
│ │ │ │ └── c3efd39f2cfb43a4c830d4fd5689900f.info
│ │ │ ├── c4/
│ │ │ │ ├── c4095d72f77fbb64ea39b8b3ca246622
│ │ │ │ ├── c4095d72f77fbb64ea39b8b3ca246622.info
│ │ │ │ ├── c459424081436584c8cec10767f9ac38
│ │ │ │ ├── c459424081436584c8cec10767f9ac38.info
│ │ │ │ ├── c46b007a3762fc84cb1ee7ca30060f0b
│ │ │ │ ├── c46b007a3762fc84cb1ee7ca30060f0b.info
│ │ │ │ ├── c4777500b5da6094e956c3d4f04de4db
│ │ │ │ ├── c4777500b5da6094e956c3d4f04de4db.info
│ │ │ │ ├── c488c389c17bd8d42b57e25edfc92ebf
│ │ │ │ ├── c488c389c17bd8d42b57e25edfc92ebf.info
│ │ │ │ ├── c49b4cc203aa6414fae5c798d1d0e7d6
│ │ │ │ ├── c49b4cc203aa6414fae5c798d1d0e7d6.info
│ │ │ │ ├── c4c1445ee948a4124bfa9fb818a17e36
│ │ │ │ ├── c4c1445ee948a4124bfa9fb818a17e36.info
│ │ │ │ ├── c4df1124e2787ee0c8d1a911de17ee73
│ │ │ │ └── c4df1124e2787ee0c8d1a911de17ee73.info
│ │ │ ├── c5/
│ │ │ │ ├── c50a694a8232898498c1cdd47ce9873f
│ │ │ │ ├── c50a694a8232898498c1cdd47ce9873f.info
│ │ │ │ ├── c522a644a29fcab2eaf63298c118a65b
│ │ │ │ ├── c522a644a29fcab2eaf63298c118a65b.info
│ │ │ │ ├── c545241cf2e56ec4997d7677f01ef43d
│ │ │ │ ├── c545241cf2e56ec4997d7677f01ef43d.info
│ │ │ │ ├── c5535d742ea2e4941850b421f9c70a1f
│ │ │ │ ├── c5535d742ea2e4941850b421f9c70a1f.info
│ │ │ │ ├── c55a64c7570474f47a94abe39ebfef04
│ │ │ │ ├── c55a64c7570474f47a94abe39ebfef04.info
│ │ │ │ ├── c5acba6181d845c4e92146009bd4480f
│ │ │ │ └── c5acba6181d845c4e92146009bd4480f.info
│ │ │ ├── c6/
│ │ │ │ ├── c606041f02fc7d542b1429806872292b
│ │ │ │ ├── c606041f02fc7d542b1429806872292b.info
│ │ │ │ ├── c67ac6e40bbb6fe47a095b949b609ce0
│ │ │ │ ├── c67ac6e40bbb6fe47a095b949b609ce0.info
│ │ │ │ ├── c68f34993bfe85e489158a29c99a20b5
│ │ │ │ └── c68f34993bfe85e489158a29c99a20b5.info
│ │ │ ├── c7/
│ │ │ │ ├── c7137daaeb11e8647bf1ade9b7e9aa97
│ │ │ │ ├── c7137daaeb11e8647bf1ade9b7e9aa97.info
│ │ │ │ ├── c754112a02f354a6696fa4f2b99e95a5
│ │ │ │ ├── c754112a02f354a6696fa4f2b99e95a5.info
│ │ │ │ ├── c76700ea0062413d9f69409b4e9e151b
│ │ │ │ ├── c76700ea0062413d9f69409b4e9e151b.info
│ │ │ │ ├── c779d3735d950f341ba35154e8b3234b
│ │ │ │ ├── c779d3735d950f341ba35154e8b3234b.info
│ │ │ │ ├── c7cfda246e604b945b12b7afedb094ce
│ │ │ │ └── c7cfda246e604b945b12b7afedb094ce.info
│ │ │ ├── c8/
│ │ │ │ ├── c825bad77a42dd341a8f0a5ef9cd5f4c
│ │ │ │ ├── c825bad77a42dd341a8f0a5ef9cd5f4c.info
│ │ │ │ ├── c851bee4305bddf438cc6ffc515991ce
│ │ │ │ ├── c851bee4305bddf438cc6ffc515991ce.info
│ │ │ │ ├── c890977a36bfdc849872b9337ab89098
│ │ │ │ └── c890977a36bfdc849872b9337ab89098.info
│ │ │ ├── c9/
│ │ │ │ ├── c91c0b6ea03975b419e4cb285a69a10d
│ │ │ │ ├── c91c0b6ea03975b419e4cb285a69a10d.info
│ │ │ │ ├── c9219e99d466b7741a057132d1994f35
│ │ │ │ ├── c9219e99d466b7741a057132d1994f35.info
│ │ │ │ ├── c97b794b51780d349a16826a4c7898d7
│ │ │ │ ├── c97b794b51780d349a16826a4c7898d7.info
│ │ │ │ ├── c995a014808fcd047bebea5fd6813310
│ │ │ │ ├── c995a014808fcd047bebea5fd6813310.info
│ │ │ │ ├── c9aabac5924106d4790d7b3a924ca34d
│ │ │ │ ├── c9aabac5924106d4790d7b3a924ca34d.info
│ │ │ │ ├── c9b23632c77de204abfe8bf7168d48c0
│ │ │ │ └── c9b23632c77de204abfe8bf7168d48c0.info
│ │ │ ├── ca/
│ │ │ │ ├── ca51b19024094d1b87f3e07edb0a75fb
│ │ │ │ ├── ca51b19024094d1b87f3e07edb0a75fb.info
│ │ │ │ ├── ca819640f53b48919bf7774744f7f15e
│ │ │ │ ├── ca819640f53b48919bf7774744f7f15e.info
│ │ │ │ ├── cabaa672b0e3ee91fa7b6da4daab7970
│ │ │ │ ├── cabaa672b0e3ee91fa7b6da4daab7970.info
│ │ │ │ ├── cad095eccea17b741bc4cd264e7441cd
│ │ │ │ ├── cad095eccea17b741bc4cd264e7441cd.info
│ │ │ │ ├── cae60a41b37427b48a00027b3e0fc1e6
│ │ │ │ └── cae60a41b37427b48a00027b3e0fc1e6.info
│ │ │ ├── cb/
│ │ │ │ ├── cb281723220c9964094e6c52e0ece792
│ │ │ │ ├── cb281723220c9964094e6c52e0ece792.info
│ │ │ │ ├── cb319974ad8ebd44aa1e1fbb02640b5b
│ │ │ │ ├── cb319974ad8ebd44aa1e1fbb02640b5b.info
│ │ │ │ ├── cb5112bfbee0a8545af567d810945a2a
│ │ │ │ ├── cb5112bfbee0a8545af567d810945a2a.info
│ │ │ │ ├── cb7c939a806f03341b682c180dc13f08
│ │ │ │ ├── cb7c939a806f03341b682c180dc13f08.info
│ │ │ │ ├── cbab8835092323a4389f2dc7d8f6c781
│ │ │ │ ├── cbab8835092323a4389f2dc7d8f6c781.info
│ │ │ │ ├── cbbca1d8a0434be4bbc7f165523763ac
│ │ │ │ └── cbbca1d8a0434be4bbc7f165523763ac.info
│ │ │ ├── cc/
│ │ │ │ ├── cc22cc13b69c1094c85e176c008b9ef8
│ │ │ │ ├── cc22cc13b69c1094c85e176c008b9ef8.info
│ │ │ │ ├── cc313cc004395df4a9884390556690a5
│ │ │ │ ├── cc313cc004395df4a9884390556690a5.info
│ │ │ │ ├── cc456ba93311a3a43ad896449fee9868
│ │ │ │ ├── cc456ba93311a3a43ad896449fee9868.info
│ │ │ │ ├── cc6401f13df54ba44bfd7cdc93c7d64d
│ │ │ │ ├── cc6401f13df54ba44bfd7cdc93c7d64d.info
│ │ │ │ ├── cce613d1538e76a4785658931c7db093
│ │ │ │ └── cce613d1538e76a4785658931c7db093.info
│ │ │ ├── ce/
│ │ │ │ ├── ce4ec0f498d1b1a4f90fe94e115b6f9a
│ │ │ │ ├── ce4ec0f498d1b1a4f90fe94e115b6f9a.info
│ │ │ │ ├── ce4ff17ca867d2b48b5c8a4181611901
│ │ │ │ ├── ce4ff17ca867d2b48b5c8a4181611901.info
│ │ │ │ ├── ce567ddbf30368344bc7b80e20cac36e
│ │ │ │ ├── ce567ddbf30368344bc7b80e20cac36e.info
│ │ │ │ ├── ce87c287371edde43a4b5fcfdee7b9ef
│ │ │ │ ├── ce87c287371edde43a4b5fcfdee7b9ef.info
│ │ │ │ ├── ce8da628f68c7594b8b9a597fa52db7b
│ │ │ │ ├── ce8da628f68c7594b8b9a597fa52db7b.info
│ │ │ │ ├── ceb629fc661813d40986b4abbefe72c6
│ │ │ │ └── ceb629fc661813d40986b4abbefe72c6.info
│ │ │ ├── cf/
│ │ │ │ ├── cf1fe50a641faac4691bf49eb32ce333
│ │ │ │ ├── cf1fe50a641faac4691bf49eb32ce333.info
│ │ │ │ ├── cf6aca931950a4a6a886e214e9e649c4
│ │ │ │ ├── cf6aca931950a4a6a886e214e9e649c4.info
│ │ │ │ ├── cf97e54bcd5479a46bdbade48da047cc
│ │ │ │ ├── cf97e54bcd5479a46bdbade48da047cc.info
│ │ │ │ ├── cfa73a847eeff06448bb50a8ac6a94e0
│ │ │ │ ├── cfa73a847eeff06448bb50a8ac6a94e0.info
│ │ │ │ ├── cfabb0440166ab443bba8876756fdfa9
│ │ │ │ └── cfabb0440166ab443bba8876756fdfa9.info
│ │ │ ├── d0/
│ │ │ │ ├── d0080567f62c3f94cb75b2927a349e22
│ │ │ │ ├── d0080567f62c3f94cb75b2927a349e22.info
│ │ │ │ ├── d0138170d24533e47b8e6c250c6d7fbc
│ │ │ │ ├── d0138170d24533e47b8e6c250c6d7fbc.info
│ │ │ │ ├── d029640460cf8ff47bbbfe69f49ddf29
│ │ │ │ ├── d029640460cf8ff47bbbfe69f49ddf29.info
│ │ │ │ ├── d061ada5d3169454daf54243390b5fdb
│ │ │ │ ├── d061ada5d3169454daf54243390b5fdb.info
│ │ │ │ ├── d0663d520c26b7c48a4135599e66acf8
│ │ │ │ ├── d0663d520c26b7c48a4135599e66acf8.info
│ │ │ │ ├── d09858396dd7adb4bbdb22ea0c8c3a37
│ │ │ │ ├── d09858396dd7adb4bbdb22ea0c8c3a37.info
│ │ │ │ ├── d0abdd8cb6b29a24c8ee19626ef741b9
│ │ │ │ ├── d0abdd8cb6b29a24c8ee19626ef741b9.info
│ │ │ │ ├── d0b148fe25e99eb48b9724523833bab1
│ │ │ │ ├── d0b148fe25e99eb48b9724523833bab1.info
│ │ │ │ ├── d0ca7b2e84542bf4ab9987087e8d79ad
│ │ │ │ ├── d0ca7b2e84542bf4ab9987087e8d79ad.info
│ │ │ │ ├── d0cd29fb1ad218b48b814bc3e6d8ac0e
│ │ │ │ ├── d0cd29fb1ad218b48b814bc3e6d8ac0e.info
│ │ │ │ ├── d0e3ad91972c66f5238f5b9b7d5ae58a
│ │ │ │ ├── d0e3ad91972c66f5238f5b9b7d5ae58a.info
│ │ │ │ ├── d0fc6f5187a81dc47999eefade6f0935
│ │ │ │ └── d0fc6f5187a81dc47999eefade6f0935.info
│ │ │ ├── d1/
│ │ │ │ ├── d1207768d96c479488b6b81f3483e0c1
│ │ │ │ ├── d1207768d96c479488b6b81f3483e0c1.info
│ │ │ │ ├── d12fd27d9e34a1e43b79b04f9202d548
│ │ │ │ ├── d12fd27d9e34a1e43b79b04f9202d548.info
│ │ │ │ ├── d143f3edd0494bc4c98a421bd59564fa
│ │ │ │ ├── d143f3edd0494bc4c98a421bd59564fa.info
│ │ │ │ ├── d199490a83bb2b844b9695cbf13b01ef
│ │ │ │ ├── d199490a83bb2b844b9695cbf13b01ef.info
│ │ │ │ ├── d19b75372f4e44d4fa4b2cffbb54124b
│ │ │ │ ├── d19b75372f4e44d4fa4b2cffbb54124b.info
│ │ │ │ ├── d1a0a27327b54c3bac52a08929c33f81
│ │ │ │ ├── d1a0a27327b54c3bac52a08929c33f81.info
│ │ │ │ ├── d1b534518943030499685344fd1d476d
│ │ │ │ ├── d1b534518943030499685344fd1d476d.info
│ │ │ │ ├── d1b7ce919aa8864409412e809073cf96
│ │ │ │ ├── d1b7ce919aa8864409412e809073cf96.info
│ │ │ │ ├── d1c9c1ed454d0594b951eb6a76ac62ad
│ │ │ │ └── d1c9c1ed454d0594b951eb6a76ac62ad.info
│ │ │ ├── d2/
│ │ │ │ ├── d208a1684f8aa6a40ad91d6aa9600c14
│ │ │ │ ├── d208a1684f8aa6a40ad91d6aa9600c14.info
│ │ │ │ ├── d20e4e177b86a2843805dd3894f41b42
│ │ │ │ ├── d20e4e177b86a2843805dd3894f41b42.info
│ │ │ │ ├── d2146428d3f1ad54eb7326c9a44b3284
│ │ │ │ ├── d2146428d3f1ad54eb7326c9a44b3284.info
│ │ │ │ ├── d21dcc2386d650c4597f3633c75a1f98
│ │ │ │ ├── d21dcc2386d650c4597f3633c75a1f98.info
│ │ │ │ ├── d256fa541faf5d4409992c631adb98a1
│ │ │ │ └── d256fa541faf5d4409992c631adb98a1.info
│ │ │ ├── d3/
│ │ │ │ ├── d31dfeaa131921f4eae00783cc48146f
│ │ │ │ ├── d31dfeaa131921f4eae00783cc48146f.info
│ │ │ │ ├── d31e5d760880a4e52a3a75322481d0d2
│ │ │ │ ├── d31e5d760880a4e52a3a75322481d0d2.info
│ │ │ │ ├── d3217d58bbd1d2b4aaee933e2e8b9195
│ │ │ │ ├── d3217d58bbd1d2b4aaee933e2e8b9195.info
│ │ │ │ ├── d36a7c7a1ed377c4b8008e53032d7dcf
│ │ │ │ ├── d36a7c7a1ed377c4b8008e53032d7dcf.info
│ │ │ │ ├── d3721d5c6afa8e545995dfaada328476
│ │ │ │ ├── d3721d5c6afa8e545995dfaada328476.info
│ │ │ │ ├── d399317a9fcc74045a7924c9fdf2bcf6
│ │ │ │ ├── d399317a9fcc74045a7924c9fdf2bcf6.info
│ │ │ │ ├── d3cbe921f7b3d9a3257e7c61a5761796
│ │ │ │ ├── d3cbe921f7b3d9a3257e7c61a5761796.info
│ │ │ │ ├── d3d14fa8f6934e14d92e37279e40e89b
│ │ │ │ └── d3d14fa8f6934e14d92e37279e40e89b.info
│ │ │ ├── d4/
│ │ │ │ ├── d40a0edbdcdcf9747a420f3bbe0f18db
│ │ │ │ ├── d40a0edbdcdcf9747a420f3bbe0f18db.info
│ │ │ │ ├── d437fe60bb34f45728664a5d930c1635
│ │ │ │ ├── d437fe60bb34f45728664a5d930c1635.info
│ │ │ │ ├── d44e6804bc58be84ea71a619b468f150
│ │ │ │ ├── d44e6804bc58be84ea71a619b468f150.info
│ │ │ │ ├── d4979bb992c0fb446a4f6c6cbf4ccfb8
│ │ │ │ ├── d4979bb992c0fb446a4f6c6cbf4ccfb8.info
│ │ │ │ ├── d49b2ed20045e034f9cdf6a6d95e6183
│ │ │ │ ├── d49b2ed20045e034f9cdf6a6d95e6183.info
│ │ │ │ ├── d4a52abc72e7b5947a077b1357646e55
│ │ │ │ ├── d4a52abc72e7b5947a077b1357646e55.info
│ │ │ │ ├── d4ef26aa386b44923b61c9c4b505a67c
│ │ │ │ └── d4ef26aa386b44923b61c9c4b505a67c.info
│ │ │ ├── d5/
│ │ │ │ ├── d51458b261e0ecc4a98904e53924dc1c
│ │ │ │ ├── d51458b261e0ecc4a98904e53924dc1c.info
│ │ │ │ ├── d528c8c98d269ca44a06cd9624a03945
│ │ │ │ ├── d528c8c98d269ca44a06cd9624a03945.info
│ │ │ │ ├── d548f82e7e9c0ed49ae5b4a5eecfb2f7
│ │ │ │ ├── d548f82e7e9c0ed49ae5b4a5eecfb2f7.info
│ │ │ │ ├── d56dbb97f857c8040beef6dd1bfc97df
│ │ │ │ ├── d56dbb97f857c8040beef6dd1bfc97df.info
│ │ │ │ ├── d5718b3fe3a758b4a9ec29170290d4f6
│ │ │ │ ├── d5718b3fe3a758b4a9ec29170290d4f6.info
│ │ │ │ ├── d59cefc45e3c31d4a90563364e7258fa
│ │ │ │ ├── d59cefc45e3c31d4a90563364e7258fa.info
│ │ │ │ ├── d5f0b0adc6826e9dd3b72e292e8438be
│ │ │ │ └── d5f0b0adc6826e9dd3b72e292e8438be.info
│ │ │ ├── d6/
│ │ │ │ ├── d6105bc8cf5ce544487daca4cbc62583
│ │ │ │ ├── d6105bc8cf5ce544487daca4cbc62583.info
│ │ │ │ ├── d63dd1a776d383248a21ec2a8a6e7868
│ │ │ │ ├── d63dd1a776d383248a21ec2a8a6e7868.info
│ │ │ │ ├── d64d92e4f04a13e4b99ea8d48e9e8ae9
│ │ │ │ ├── d64d92e4f04a13e4b99ea8d48e9e8ae9.info
│ │ │ │ ├── d685d97a1eb004f49afea0cc982ff728
│ │ │ │ ├── d685d97a1eb004f49afea0cc982ff728.info
│ │ │ │ ├── d691174143fd3774ba63d7c493633b99
│ │ │ │ ├── d691174143fd3774ba63d7c493633b99.info
│ │ │ │ ├── d6a2e6e4803de7b43baacdc355fc144d
│ │ │ │ ├── d6a2e6e4803de7b43baacdc355fc144d.info
│ │ │ │ ├── d6c6a000a805f00649b36b542e8426c2
│ │ │ │ ├── d6c6a000a805f00649b36b542e8426c2.info
│ │ │ │ ├── d6db7caf2e852b75ebb9c6098418179c
│ │ │ │ ├── d6db7caf2e852b75ebb9c6098418179c.info
│ │ │ │ ├── d6e23541e3b2fea489be46f704b64707
│ │ │ │ ├── d6e23541e3b2fea489be46f704b64707.info
│ │ │ │ ├── d6fa2d92fc1b3f34da284357edf89c3b
│ │ │ │ └── d6fa2d92fc1b3f34da284357edf89c3b.info
│ │ │ ├── d7/
│ │ │ │ ├── d72ccd2c66ea846fc842adf682b11526
│ │ │ │ ├── d72ccd2c66ea846fc842adf682b11526.info
│ │ │ │ ├── d79cb9ecc0d4a6d428ab98a681a33897
│ │ │ │ ├── d79cb9ecc0d4a6d428ab98a681a33897.info
│ │ │ │ ├── d7b5b883d3aae8d479647d5ae6182974
│ │ │ │ └── d7b5b883d3aae8d479647d5ae6182974.info
│ │ │ ├── d8/
│ │ │ │ ├── d850db319a63d2546932ff76fe55a498
│ │ │ │ ├── d850db319a63d2546932ff76fe55a498.info
│ │ │ │ ├── d85e5eeaf8f135aeaaebdc8aa3cff6c3
│ │ │ │ ├── d85e5eeaf8f135aeaaebdc8aa3cff6c3.info
│ │ │ │ ├── d8c4a920f001ca64680ed6fdb52d1753
│ │ │ │ └── d8c4a920f001ca64680ed6fdb52d1753.info
│ │ │ ├── d9/
│ │ │ │ ├── d912d4873af534bd4a9d44bf1b52f14e
│ │ │ │ ├── d912d4873af534bd4a9d44bf1b52f14e.info
│ │ │ │ ├── d925cabd9ecd5074aadab0726b96c38f
│ │ │ │ ├── d925cabd9ecd5074aadab0726b96c38f.info
│ │ │ │ ├── d9647b571c5e44729b71d756b3d55317
│ │ │ │ ├── d9647b571c5e44729b71d756b3d55317.info
│ │ │ │ ├── d9682e749d3efc642af54d789d9090a6
│ │ │ │ ├── d9682e749d3efc642af54d789d9090a6.info
│ │ │ │ ├── d973fc1524e4d724081553934c55958c
│ │ │ │ └── d973fc1524e4d724081553934c55958c.info
│ │ │ ├── da/
│ │ │ │ ├── dab656c79e1985c40b31faebcda44442
│ │ │ │ └── dab656c79e1985c40b31faebcda44442.info
│ │ │ ├── db/
│ │ │ │ ├── db339ef553721e94999125c0b9f909dc
│ │ │ │ ├── db339ef553721e94999125c0b9f909dc.info
│ │ │ │ ├── db34f310723c62440a05d3e69f262a70
│ │ │ │ ├── db34f310723c62440a05d3e69f262a70.info
│ │ │ │ ├── db7dd43fe1278a9459cd6036f096b91d
│ │ │ │ ├── db7dd43fe1278a9459cd6036f096b91d.info
│ │ │ │ ├── dbd43d8a3b8122d4e89b055f53382b11
│ │ │ │ └── dbd43d8a3b8122d4e89b055f53382b11.info
│ │ │ ├── dc/
│ │ │ │ ├── dc42784cf147c0c48a680349fa168899
│ │ │ │ ├── dc42784cf147c0c48a680349fa168899.info
│ │ │ │ ├── dc99dfeec967f2644b25dd6bace59b7e
│ │ │ │ ├── dc99dfeec967f2644b25dd6bace59b7e.info
│ │ │ │ ├── dcb49b07db5e5f64e876b498105314f1
│ │ │ │ ├── dcb49b07db5e5f64e876b498105314f1.info
│ │ │ │ ├── dcc8c6e92b172a65719af5ddf47dd968
│ │ │ │ ├── dcc8c6e92b172a65719af5ddf47dd968.info
│ │ │ │ ├── dcf00682bef4d264d84a5c92c8f5a40f
│ │ │ │ └── dcf00682bef4d264d84a5c92c8f5a40f.info
│ │ │ ├── dd/
│ │ │ │ ├── dd2fe74169b54bf58fca17288513ef38
│ │ │ │ ├── dd2fe74169b54bf58fca17288513ef38.info
│ │ │ │ ├── dd85a35169d313840a0874aea1a28629
│ │ │ │ └── dd85a35169d313840a0874aea1a28629.info
│ │ │ ├── de/
│ │ │ │ ├── de86b4ed8106fd84a8bc2f5d69798d53
│ │ │ │ ├── de86b4ed8106fd84a8bc2f5d69798d53.info
│ │ │ │ ├── de9eb5e2046ffc9448f07e495c436506
│ │ │ │ ├── de9eb5e2046ffc9448f07e495c436506.info
│ │ │ │ ├── dec586c160776104da4d9a4e472662bc
│ │ │ │ ├── dec586c160776104da4d9a4e472662bc.info
│ │ │ │ ├── dec9066d4afefe444be0dad3f137730d
│ │ │ │ └── dec9066d4afefe444be0dad3f137730d.info
│ │ │ ├── df/
│ │ │ │ ├── df1ba932d4ce4534e97a0f10c85cd3c9
│ │ │ │ ├── df1ba932d4ce4534e97a0f10c85cd3c9.info
│ │ │ │ ├── df8df80bb65e9ec4280229a9921c4f3c
│ │ │ │ ├── df8df80bb65e9ec4280229a9921c4f3c.info
│ │ │ │ ├── dfc336f10b83bd74eaded16a658275c7
│ │ │ │ ├── dfc336f10b83bd74eaded16a658275c7.info
│ │ │ │ ├── dfd084fea478f3148b7de3d83bab1d8c
│ │ │ │ ├── dfd084fea478f3148b7de3d83bab1d8c.info
│ │ │ │ ├── dff73c4907c95264c8fc095a81f9d51e
│ │ │ │ └── dff73c4907c95264c8fc095a81f9d51e.info
│ │ │ ├── e0/
│ │ │ │ ├── e00a5dea786950546a21b0e2d817e466
│ │ │ │ ├── e00a5dea786950546a21b0e2d817e466.info
│ │ │ │ ├── e05ace3bd15740cda0bad60d89092a5b
│ │ │ │ ├── e05ace3bd15740cda0bad60d89092a5b.info
│ │ │ │ ├── e086b15460c228c4f9b116f0e3e2f175
│ │ │ │ ├── e086b15460c228c4f9b116f0e3e2f175.info
│ │ │ │ ├── e091bb444874ef244b1ba4a813fc1e34
│ │ │ │ ├── e091bb444874ef244b1ba4a813fc1e34.info
│ │ │ │ ├── e0ae6629cc70b514889df37fccb76832
│ │ │ │ ├── e0ae6629cc70b514889df37fccb76832.info
│ │ │ │ ├── e0cb37a014cdcb142af891772a27189c
│ │ │ │ ├── e0cb37a014cdcb142af891772a27189c.info
│ │ │ │ ├── e0db3f3921670cd4ca2e925737c3fba4
│ │ │ │ └── e0db3f3921670cd4ca2e925737c3fba4.info
│ │ │ ├── e1/
│ │ │ │ ├── e165a99d845c10e4ea0f546e542e8684
│ │ │ │ ├── e165a99d845c10e4ea0f546e542e8684.info
│ │ │ │ ├── e177382a693dea644acd34e3e7a3feb3
│ │ │ │ ├── e177382a693dea644acd34e3e7a3feb3.info
│ │ │ │ ├── e17c88b021c2a4c409b3f15b0d80ac62
│ │ │ │ ├── e17c88b021c2a4c409b3f15b0d80ac62.info
│ │ │ │ ├── e19747de3f5aca642ab2be37e372fb86
│ │ │ │ ├── e19747de3f5aca642ab2be37e372fb86.info
│ │ │ │ ├── e1e957d39ca70834f9212a1289b6a0d5
│ │ │ │ ├── e1e957d39ca70834f9212a1289b6a0d5.info
│ │ │ │ ├── e1ef8466c8fd01a549f10baa4d51fa17
│ │ │ │ ├── e1ef8466c8fd01a549f10baa4d51fa17.info
│ │ │ │ ├── e1f640f1769d6274194cf97b0e24602c
│ │ │ │ └── e1f640f1769d6274194cf97b0e24602c.info
│ │ │ ├── e2/
│ │ │ │ ├── e210c8bf2e9c6514d90a1bd77586af1f
│ │ │ │ ├── e210c8bf2e9c6514d90a1bd77586af1f.info
│ │ │ │ ├── e21bec35f48a44298911b25ead550ce3
│ │ │ │ ├── e21bec35f48a44298911b25ead550ce3.info
│ │ │ │ ├── e2392d942829c3b439a231d514e10321
│ │ │ │ ├── e2392d942829c3b439a231d514e10321.info
│ │ │ │ ├── e2cd16a2d73fe7a4c9affa2b790eb5e0
│ │ │ │ └── e2cd16a2d73fe7a4c9affa2b790eb5e0.info
│ │ │ ├── e3/
│ │ │ │ ├── e3882522a08b6f5459b4dea6f8791278
│ │ │ │ ├── e3882522a08b6f5459b4dea6f8791278.info
│ │ │ │ ├── e3b0f810fdea84e40ab4ba20f256f7e8
│ │ │ │ └── e3b0f810fdea84e40ab4ba20f256f7e8.info
│ │ │ ├── e4/
│ │ │ │ ├── e4e0b1de1aee400d81ed4273141e7823
│ │ │ │ ├── e4e0b1de1aee400d81ed4273141e7823.info
│ │ │ │ ├── e4e290d31ab7fb54880746bb8f818e0d
│ │ │ │ └── e4e290d31ab7fb54880746bb8f818e0d.info
│ │ │ ├── e5/
│ │ │ │ ├── e52de21a22b6dd44c9cc19f810c65059
│ │ │ │ ├── e52de21a22b6dd44c9cc19f810c65059.info
│ │ │ │ ├── e58bd3cca6475e54b93632bb6837aeea
│ │ │ │ ├── e58bd3cca6475e54b93632bb6837aeea.info
│ │ │ │ ├── e5d490e301a36f04a9397d7257fb157b
│ │ │ │ └── e5d490e301a36f04a9397d7257fb157b.info
│ │ │ ├── e6/
│ │ │ │ ├── e6323ebef616fee4486ee155cd56d191
│ │ │ │ ├── e6323ebef616fee4486ee155cd56d191.info
│ │ │ │ ├── e6413f4090046814d802ddbff9890878
│ │ │ │ ├── e6413f4090046814d802ddbff9890878.info
│ │ │ │ ├── e69259f6ff914146ad610be5491eb44a
│ │ │ │ ├── e69259f6ff914146ad610be5491eb44a.info
│ │ │ │ ├── e6a1d1e3d2384453a7371b4a07a41ca4
│ │ │ │ └── e6a1d1e3d2384453a7371b4a07a41ca4.info
│ │ │ ├── e7/
│ │ │ │ ├── e74ddf4132f3401409c824bed60280ee
│ │ │ │ ├── e74ddf4132f3401409c824bed60280ee.info
│ │ │ │ ├── e763a90581e2d8143bc9a0e384ce6f0f
│ │ │ │ ├── e763a90581e2d8143bc9a0e384ce6f0f.info
│ │ │ │ ├── e7719e74d14c6ca45a8d38ed1a32e5d9
│ │ │ │ ├── e7719e74d14c6ca45a8d38ed1a32e5d9.info
│ │ │ │ ├── e7a505b341283e14696e86433a5b1ae9
│ │ │ │ └── e7a505b341283e14696e86433a5b1ae9.info
│ │ │ ├── e8/
│ │ │ │ ├── e801faa3b0dd2478dbe801a2441b679e
│ │ │ │ ├── e801faa3b0dd2478dbe801a2441b679e.info
│ │ │ │ ├── e88a766c2b8b47841936c136f4afbba9
│ │ │ │ ├── e88a766c2b8b47841936c136f4afbba9.info
│ │ │ │ ├── e8c30efa89029e447b0dc0efc75b294c
│ │ │ │ └── e8c30efa89029e447b0dc0efc75b294c.info
│ │ │ ├── e9/
│ │ │ │ ├── e90cc37a5ccf4a44dbecc5b7172ec512
│ │ │ │ ├── e90cc37a5ccf4a44dbecc5b7172ec512.info
│ │ │ │ ├── e9253e696cd45794d9aec6d4de366b6e
│ │ │ │ ├── e9253e696cd45794d9aec6d4de366b6e.info
│ │ │ │ ├── e93ec7eb6de342aabd156833e253f838
│ │ │ │ ├── e93ec7eb6de342aabd156833e253f838.info
│ │ │ │ ├── e9745f6a32442194c8dc5a43e9ab86f9
│ │ │ │ ├── e9745f6a32442194c8dc5a43e9ab86f9.info
│ │ │ │ ├── e9a32780b69dcdb438da3e3f43202f54
│ │ │ │ ├── e9a32780b69dcdb438da3e3f43202f54.info
│ │ │ │ ├── e9cac674d67385249b2805670e618c24
│ │ │ │ ├── e9cac674d67385249b2805670e618c24.info
│ │ │ │ ├── e9df95f53f1c1d0c9199e235d6c42b50
│ │ │ │ └── e9df95f53f1c1d0c9199e235d6c42b50.info
│ │ │ ├── ea/
│ │ │ │ ├── ea28dc637ae40484da709200d3328587
│ │ │ │ ├── ea28dc637ae40484da709200d3328587.info
│ │ │ │ ├── ea5aa18a49e4f29d74984ea0ea11a238
│ │ │ │ ├── ea5aa18a49e4f29d74984ea0ea11a238.info
│ │ │ │ ├── ea5e2240e8a7d9046a651557deec40b2
│ │ │ │ ├── ea5e2240e8a7d9046a651557deec40b2.info
│ │ │ │ ├── ea944378afa086f438b3352ad7b0e835
│ │ │ │ ├── ea944378afa086f438b3352ad7b0e835.info
│ │ │ │ ├── ea998292f45ea494d9e100f5f6362f91
│ │ │ │ ├── ea998292f45ea494d9e100f5f6362f91.info
│ │ │ │ ├── eac7b0dfe80ae8b41b71e9e0c040a433
│ │ │ │ ├── eac7b0dfe80ae8b41b71e9e0c040a433.info
│ │ │ │ ├── eafae18265a10964e97bb7c9c1601ef6
│ │ │ │ └── eafae18265a10964e97bb7c9c1601ef6.info
│ │ │ ├── eb/
│ │ │ │ ├── eb1eda9941f181549a0b626e36a4dd26
│ │ │ │ ├── eb1eda9941f181549a0b626e36a4dd26.info
│ │ │ │ ├── eb221cf55b3544646b0c3b6bc790080f
│ │ │ │ ├── eb221cf55b3544646b0c3b6bc790080f.info
│ │ │ │ ├── eb9c5f188a065fc42b24d4f24060e6df
│ │ │ │ ├── eb9c5f188a065fc42b24d4f24060e6df.info
│ │ │ │ ├── ebc4d20cc106cea49b1df1153f0b3b5e
│ │ │ │ ├── ebc4d20cc106cea49b1df1153f0b3b5e.info
│ │ │ │ ├── ebcc5f899d9277642868aeda9a17cbaf
│ │ │ │ ├── ebcc5f899d9277642868aeda9a17cbaf.info
│ │ │ │ ├── ebeedaa04bb53e24ba2e7fb6745e3fd3
│ │ │ │ └── ebeedaa04bb53e24ba2e7fb6745e3fd3.info
│ │ │ ├── ec/
│ │ │ │ ├── ec02776fe29df900b897106d61977735
│ │ │ │ ├── ec02776fe29df900b897106d61977735.info
│ │ │ │ ├── ec06dea06450dae44b5e1f61ed717c4f
│ │ │ │ ├── ec06dea06450dae44b5e1f61ed717c4f.info
│ │ │ │ ├── ec35c13a8280a8d4e817bc4afd8a95de
│ │ │ │ ├── ec35c13a8280a8d4e817bc4afd8a95de.info
│ │ │ │ ├── ec7c645d93308c04d8840982af12101e
│ │ │ │ ├── ec7c645d93308c04d8840982af12101e.info
│ │ │ │ ├── ec817e5e5781e0a4983a1dc8875d1974
│ │ │ │ ├── ec817e5e5781e0a4983a1dc8875d1974.info
│ │ │ │ ├── ecc396d20671d454e8020aa864197779
│ │ │ │ ├── ecc396d20671d454e8020aa864197779.info
│ │ │ │ ├── ece36bb2bc4128d42911bbc757a56860
│ │ │ │ └── ece36bb2bc4128d42911bbc757a56860.info
│ │ │ ├── ed/
│ │ │ │ ├── ed041e68439749a69d0efa0e3d896c2e
│ │ │ │ ├── ed041e68439749a69d0efa0e3d896c2e.info
│ │ │ │ ├── edc553b1b3c8a25438b62783410b26ae
│ │ │ │ ├── edc553b1b3c8a25438b62783410b26ae.info
│ │ │ │ ├── edd2a1fe1acbbde43aad39862bb3f4a8
│ │ │ │ ├── edd2a1fe1acbbde43aad39862bb3f4a8.info
│ │ │ │ ├── edd4f4b395430604d935bcf0b14c7d42
│ │ │ │ ├── edd4f4b395430604d935bcf0b14c7d42.info
│ │ │ │ ├── ede0462698a4a5643aa9872c074acd38
│ │ │ │ └── ede0462698a4a5643aa9872c074acd38.info
│ │ │ ├── ee/
│ │ │ │ ├── ee148e281f3c41c5b4ff5f8a5afe5a6c
│ │ │ │ ├── ee148e281f3c41c5b4ff5f8a5afe5a6c.info
│ │ │ │ ├── ee83d5e1ad2ac4c9aa39e3a6f256062e
│ │ │ │ ├── ee83d5e1ad2ac4c9aa39e3a6f256062e.info
│ │ │ │ ├── eea34a28297f9bc4c9f4c573bc8d5d1c
│ │ │ │ ├── eea34a28297f9bc4c9f4c573bc8d5d1c.info
│ │ │ │ ├── eebde5009793ce948bf5d4c4435b89b9
│ │ │ │ └── eebde5009793ce948bf5d4c4435b89b9.info
│ │ │ ├── ef/
│ │ │ │ ├── ef4c81c9368d5a340b14c2fec1cad345
│ │ │ │ ├── ef4c81c9368d5a340b14c2fec1cad345.info
│ │ │ │ ├── ef563c5a6ecf64d4193dc144cb7d472a
│ │ │ │ ├── ef563c5a6ecf64d4193dc144cb7d472a.info
│ │ │ │ ├── ef5fa6e2005defb4ab5142723827b58e
│ │ │ │ ├── ef5fa6e2005defb4ab5142723827b58e.info
│ │ │ │ ├── ef97f39912c138b4cabdccedfb24093b
│ │ │ │ ├── ef97f39912c138b4cabdccedfb24093b.info
│ │ │ │ ├── efad3ddb7270ac241b9b1357ec5ee2f2
│ │ │ │ ├── efad3ddb7270ac241b9b1357ec5ee2f2.info
│ │ │ │ ├── efcf753a96a07b24dbe5f23a8ad5963d
│ │ │ │ ├── efcf753a96a07b24dbe5f23a8ad5963d.info
│ │ │ │ ├── effb76e1937b45ff8adf45e51a4c08cf
│ │ │ │ └── effb76e1937b45ff8adf45e51a4c08cf.info
│ │ │ ├── f0/
│ │ │ │ ├── f06555f75b070af458a003d92f9efb00
│ │ │ │ ├── f06555f75b070af458a003d92f9efb00.info
│ │ │ │ ├── f079e3afd077fb94fa2bda74d6409499
│ │ │ │ ├── f079e3afd077fb94fa2bda74d6409499.info
│ │ │ │ ├── f0f13f2ab3d6d13cfc6e4656824bfca8
│ │ │ │ └── f0f13f2ab3d6d13cfc6e4656824bfca8.info
│ │ │ ├── f1/
│ │ │ │ ├── f136f1f122a53c64c9af51baecaa9c96
│ │ │ │ ├── f136f1f122a53c64c9af51baecaa9c96.info
│ │ │ │ ├── f15cbb987069826429540d0ea0937442
│ │ │ │ ├── f15cbb987069826429540d0ea0937442.info
│ │ │ │ ├── f1605f5534186904fa2c4c42acbfe01e
│ │ │ │ ├── f1605f5534186904fa2c4c42acbfe01e.info
│ │ │ │ ├── f16e09785c984c445a0467e30f845636
│ │ │ │ ├── f16e09785c984c445a0467e30f845636.info
│ │ │ │ ├── f1b6399349763114d9361bc6dfcd025b
│ │ │ │ ├── f1b6399349763114d9361bc6dfcd025b.info
│ │ │ │ ├── f1c6f7ed858be004eb1c56dada7ee838
│ │ │ │ ├── f1c6f7ed858be004eb1c56dada7ee838.info
│ │ │ │ ├── f1ea944dcf8849ebab391e461b99ccb7
│ │ │ │ └── f1ea944dcf8849ebab391e461b99ccb7.info
│ │ │ ├── f3/
│ │ │ │ ├── f32e959de7955be41a4af6dac2f75b09
│ │ │ │ ├── f32e959de7955be41a4af6dac2f75b09.info
│ │ │ │ ├── f33e570b8b9af1048b80a27e7848cb09
│ │ │ │ ├── f33e570b8b9af1048b80a27e7848cb09.info
│ │ │ │ ├── f3a361a6ad1aff14ba8f48976e94ad76
│ │ │ │ ├── f3a361a6ad1aff14ba8f48976e94ad76.info
│ │ │ │ ├── f3e1b3cbf3fac6a459b1a602167ad311
│ │ │ │ └── f3e1b3cbf3fac6a459b1a602167ad311.info
│ │ │ ├── f4/
│ │ │ │ ├── f4452670096a14945b20cca112e82047
│ │ │ │ ├── f4452670096a14945b20cca112e82047.info
│ │ │ │ ├── f445ca0c614a846449fcd8ae648c24e2
│ │ │ │ ├── f445ca0c614a846449fcd8ae648c24e2.info
│ │ │ │ ├── f4688fdb7df04437aeb418b961361dc5
│ │ │ │ ├── f4688fdb7df04437aeb418b961361dc5.info
│ │ │ │ ├── f4935fb862d54980b1bcbca942962642
│ │ │ │ ├── f4935fb862d54980b1bcbca942962642.info
│ │ │ │ ├── f49bbe06ffa5ae24abe32abdab430c24
│ │ │ │ ├── f49bbe06ffa5ae24abe32abdab430c24.info
│ │ │ │ ├── f4f988528bbbb0846a4cb50efb4587a5
│ │ │ │ └── f4f988528bbbb0846a4cb50efb4587a5.info
│ │ │ ├── f5/
│ │ │ │ ├── f525580684527b147b70cf94aaa70dbc
│ │ │ │ ├── f525580684527b147b70cf94aaa70dbc.info
│ │ │ │ ├── f5600e6ae5a1464da659eca36bef9d64
│ │ │ │ ├── f5600e6ae5a1464da659eca36bef9d64.info
│ │ │ │ ├── f5a0cc9645f0e2d4fb816156dcf3f4dd
│ │ │ │ └── f5a0cc9645f0e2d4fb816156dcf3f4dd.info
│ │ │ ├── f6/
│ │ │ │ ├── f601c0d674119f74db9c15166b3a58c4
│ │ │ │ ├── f601c0d674119f74db9c15166b3a58c4.info
│ │ │ │ ├── f603edd7163537f44927ad2808147a25
│ │ │ │ ├── f603edd7163537f44927ad2808147a25.info
│ │ │ │ ├── f65646ef159c91441bff704a5f7f419b
│ │ │ │ ├── f65646ef159c91441bff704a5f7f419b.info
│ │ │ │ ├── f66454863bc106549a6b53849ee63b41
│ │ │ │ ├── f66454863bc106549a6b53849ee63b41.info
│ │ │ │ ├── f68c7f7359094f045930a108c444e7a4
│ │ │ │ ├── f68c7f7359094f045930a108c444e7a4.info
│ │ │ │ ├── f695b5f9415c40b39ae877eaff41c96e
│ │ │ │ ├── f695b5f9415c40b39ae877eaff41c96e.info
│ │ │ │ ├── f6ba30c492ac73742bc0cfee6817045a
│ │ │ │ ├── f6ba30c492ac73742bc0cfee6817045a.info
│ │ │ │ ├── f6bb32665bcc91b41a7177fd6af08ad6
│ │ │ │ ├── f6bb32665bcc91b41a7177fd6af08ad6.info
│ │ │ │ ├── f6bd368ab00d75c459e2582e017191e6
│ │ │ │ ├── f6bd368ab00d75c459e2582e017191e6.info
│ │ │ │ ├── f6c189a159d3bde4c964cee562e508ea
│ │ │ │ ├── f6c189a159d3bde4c964cee562e508ea.info
│ │ │ │ ├── f6d64d8648793944dbadfd71f0f4b0a1
│ │ │ │ └── f6d64d8648793944dbadfd71f0f4b0a1.info
│ │ │ ├── f7/
│ │ │ │ ├── f700f31b2e40d7f4bb69753fdbbbc2b5
│ │ │ │ ├── f700f31b2e40d7f4bb69753fdbbbc2b5.info
│ │ │ │ ├── f73fc901e4b0f2d4daf11f46506054ba
│ │ │ │ ├── f73fc901e4b0f2d4daf11f46506054ba.info
│ │ │ │ ├── f779e779d62b5ca49b658236c337845d
│ │ │ │ ├── f779e779d62b5ca49b658236c337845d.info
│ │ │ │ ├── f7852b99951997645ae7adaac5f0b083
│ │ │ │ ├── f7852b99951997645ae7adaac5f0b083.info
│ │ │ │ ├── f7a8357347c80dc69c08d0b1a05e2122
│ │ │ │ ├── f7a8357347c80dc69c08d0b1a05e2122.info
│ │ │ │ ├── f7e61a6fdb34813479ec9e958a030910
│ │ │ │ ├── f7e61a6fdb34813479ec9e958a030910.info
│ │ │ │ ├── f7fed0d9d0f7a7f41a8525aa79e790b1
│ │ │ │ └── f7fed0d9d0f7a7f41a8525aa79e790b1.info
│ │ │ ├── f8/
│ │ │ │ ├── f817a38900380be47942905e17e7d39b
│ │ │ │ ├── f817a38900380be47942905e17e7d39b.info
│ │ │ │ ├── f867743975592a743a3581ff042bcc25
│ │ │ │ ├── f867743975592a743a3581ff042bcc25.info
│ │ │ │ ├── f8730045d7da0f84cb11c0d868899577
│ │ │ │ ├── f8730045d7da0f84cb11c0d868899577.info
│ │ │ │ ├── f8964ef46e1d446dc9eb17a36a3e1f14
│ │ │ │ ├── f8964ef46e1d446dc9eb17a36a3e1f14.info
│ │ │ │ ├── f8e6a2d47aba4c6c9b3c5a72d9f48da5
│ │ │ │ ├── f8e6a2d47aba4c6c9b3c5a72d9f48da5.info
│ │ │ │ ├── f8ed4321a98682942b9980996131cf26
│ │ │ │ ├── f8ed4321a98682942b9980996131cf26.info
│ │ │ │ ├── f8f889eee05c15349bc81eeb0883357d
│ │ │ │ └── f8f889eee05c15349bc81eeb0883357d.info
│ │ │ ├── f9/
│ │ │ │ ├── f91a00d2dca52b843b2d50ccf750737d
│ │ │ │ ├── f91a00d2dca52b843b2d50ccf750737d.info
│ │ │ │ ├── f92aa236053c90f41a2e272a05c9186d
│ │ │ │ ├── f92aa236053c90f41a2e272a05c9186d.info
│ │ │ │ ├── f944311c8fff2479fa3ba741f6039fc8
│ │ │ │ ├── f944311c8fff2479fa3ba741f6039fc8.info
│ │ │ │ ├── f96d0ea807c081145a1170ed1b6d71e0
│ │ │ │ ├── f96d0ea807c081145a1170ed1b6d71e0.info
│ │ │ │ ├── f9bd02a3a916be64c9b47b1305149423
│ │ │ │ ├── f9bd02a3a916be64c9b47b1305149423.info
│ │ │ │ ├── f9d8c8b21846a654092a24f25aa41421
│ │ │ │ └── f9d8c8b21846a654092a24f25aa41421.info
│ │ │ ├── fa/
│ │ │ │ ├── fa27413e9edb06a6058d6c894eca0338
│ │ │ │ ├── fa27413e9edb06a6058d6c894eca0338.info
│ │ │ │ ├── fa423365b1ce06a4dbdc6fb4a8597bfa
│ │ │ │ ├── fa423365b1ce06a4dbdc6fb4a8597bfa.info
│ │ │ │ ├── fa6bd40a216346b783a4cce741d277a5
│ │ │ │ └── fa6bd40a216346b783a4cce741d277a5.info
│ │ │ ├── fb/
│ │ │ │ ├── fb1eb8dd5509788428a96514cc36f0d0
│ │ │ │ ├── fb1eb8dd5509788428a96514cc36f0d0.info
│ │ │ │ ├── fb27f3049fe06c246803a4a4c5b7fda3
│ │ │ │ ├── fb27f3049fe06c246803a4a4c5b7fda3.info
│ │ │ │ ├── fb461734117c80c43ab595d699f801eb
│ │ │ │ ├── fb461734117c80c43ab595d699f801eb.info
│ │ │ │ ├── fb5730e24283d0c489e5c7d0bee023d9
│ │ │ │ ├── fb5730e24283d0c489e5c7d0bee023d9.info
│ │ │ │ ├── fb593906b7b6d824087dcaebf6c082e0
│ │ │ │ ├── fb593906b7b6d824087dcaebf6c082e0.info
│ │ │ │ ├── fb660d86885d89a499a31c6ab6f26269
│ │ │ │ └── fb660d86885d89a499a31c6ab6f26269.info
│ │ │ ├── fc/
│ │ │ │ ├── fc34cd6ea308f3940a729e1a44cd0e82
│ │ │ │ ├── fc34cd6ea308f3940a729e1a44cd0e82.info
│ │ │ │ ├── fc3a810351931f5e6183e16b9beb5563
│ │ │ │ ├── fc3a810351931f5e6183e16b9beb5563.info
│ │ │ │ ├── fc46f91ea1e8e4ca2ab693fef9156dbe
│ │ │ │ ├── fc46f91ea1e8e4ca2ab693fef9156dbe.info
│ │ │ │ ├── fc748d99f1f0d484a811a566fc7915ec
│ │ │ │ ├── fc748d99f1f0d484a811a566fc7915ec.info
│ │ │ │ ├── fc8d686a4c18b8d49bb1db4150de0459
│ │ │ │ ├── fc8d686a4c18b8d49bb1db4150de0459.info
│ │ │ │ ├── fcae021c30eccf74790a4e816ba97c19
│ │ │ │ ├── fcae021c30eccf74790a4e816ba97c19.info
│ │ │ │ ├── fcb9be00baf924c4183fc0313e6185c5
│ │ │ │ ├── fcb9be00baf924c4183fc0313e6185c5.info
│ │ │ │ ├── fcc60c1d6bb544d9b712b652f418ff3a
│ │ │ │ ├── fcc60c1d6bb544d9b712b652f418ff3a.info
│ │ │ │ ├── fcd66bf74cbeb264aa99679c7df84427
│ │ │ │ └── fcd66bf74cbeb264aa99679c7df84427.info
│ │ │ ├── fd/
│ │ │ │ ├── fd0a39b4d296d4d509b4f1dbd08d0630
│ │ │ │ ├── fd0a39b4d296d4d509b4f1dbd08d0630.info
│ │ │ │ ├── fd57cf917f61bbb42b8f030436426ddd
│ │ │ │ ├── fd57cf917f61bbb42b8f030436426ddd.info
│ │ │ │ ├── fd6ede1d2f47ab146b2ec0a3969a37cc
│ │ │ │ ├── fd6ede1d2f47ab146b2ec0a3969a37cc.info
│ │ │ │ ├── fd871a8be47119612f7c254e96a822b7
│ │ │ │ ├── fd871a8be47119612f7c254e96a822b7.info
│ │ │ │ ├── fda82b5ca7a4c5f40b497c4f5f4bd950
│ │ │ │ ├── fda82b5ca7a4c5f40b497c4f5f4bd950.info
│ │ │ │ ├── fdb35ef8fc437e14fa4b6c74a0609e86
│ │ │ │ ├── fdb35ef8fc437e14fa4b6c74a0609e86.info
│ │ │ │ ├── fdd19c82588da3e498a0c98951efa6c4
│ │ │ │ ├── fdd19c82588da3e498a0c98951efa6c4.info
│ │ │ │ ├── fde0d25a170598d46a0b9dc16b4527a5
│ │ │ │ └── fde0d25a170598d46a0b9dc16b4527a5.info
│ │ │ ├── fe/
│ │ │ │ ├── fe03a7b0ba57a4d488b6c327ae16c335
│ │ │ │ ├── fe03a7b0ba57a4d488b6c327ae16c335.info
│ │ │ │ ├── fe4aef60e4ace544c8430da8ef8acba2
│ │ │ │ ├── fe4aef60e4ace544c8430da8ef8acba2.info
│ │ │ │ ├── fe87c0e1cc204ed48ad3b37840f39efc
│ │ │ │ ├── fe87c0e1cc204ed48ad3b37840f39efc.info
│ │ │ │ ├── fea12beeeb5a7a448b5e60f50e40975d
│ │ │ │ ├── fea12beeeb5a7a448b5e60f50e40975d.info
│ │ │ │ ├── fea49a0730244a98bf1087f7ca9410a8
│ │ │ │ ├── fea49a0730244a98bf1087f7ca9410a8.info
│ │ │ │ ├── fed9dda667cab45d398d06402bba03f4
│ │ │ │ ├── fed9dda667cab45d398d06402bba03f4.info
│ │ │ │ ├── fedb0f9e5006b1943abae52f52f08a1a
│ │ │ │ └── fedb0f9e5006b1943abae52f52f08a1a.info
│ │ │ └── ff/
│ │ │ ├── ff67c526455160f4690a44f74dee4cbe
│ │ │ ├── ff67c526455160f4690a44f74dee4cbe.info
│ │ │ ├── ff97302ee78d6ad478b433ec557ee303
│ │ │ ├── ff97302ee78d6ad478b433ec557ee303.info
│ │ │ ├── ffb335140c799c4408411d81789fb05c
│ │ │ ├── ffb335140c799c4408411d81789fb05c.info
│ │ │ ├── ffc6271f08270b64ca0aae9c49235d81
│ │ │ ├── ffc6271f08270b64ca0aae9c49235d81.info
│ │ │ ├── ffcbe86028d681144b703991885c535a
│ │ │ └── ffcbe86028d681144b703991885c535a.info
│ │ ├── shadercompiler-UnityShaderCompiler.exe0.log
│ │ ├── shadercompiler-UnityShaderCompiler.exe1.log
│ │ ├── shadercompiler-UnityShaderCompiler.exe2.log
│ │ ├── shadercompiler-UnityShaderCompiler.exe3.log
│ │ ├── shadercompiler-UnityShaderCompiler.exe4.log
│ │ ├── shadercompiler-UnityShaderCompiler.exe5.log
│ │ ├── shadercompiler-UnityShaderCompiler.exe6.log
│ │ └── shadercompiler-UnityShaderCompiler.exe7.log
│ ├── Logs/
│ │ └── Packages-Update.log
│ ├── Packages/
│ │ └── manifest.json
│ ├── ProjectSettings/
│ │ ├── AudioManager.asset
│ │ ├── ClusterInputManager.asset
│ │ ├── DynamicsManager.asset
│ │ ├── EditorBuildSettings.asset
│ │ ├── EditorSettings.asset
│ │ ├── GraphicsSettings.asset
│ │ ├── InputManager.asset
│ │ ├── NavMeshAreas.asset
│ │ ├── NavMeshLayers.asset
│ │ ├── NetworkManager.asset
│ │ ├── PackageManagerSettings.asset
│ │ ├── Physics2DSettings.asset
│ │ ├── PresetManager.asset
│ │ ├── ProjectSettings.asset
│ │ ├── ProjectVersion.txt
│ │ ├── QualitySettings.asset
│ │ ├── TagManager.asset
│ │ ├── TimeManager.asset
│ │ ├── UnityConnectSettings.asset
│ │ ├── VFXManager.asset
│ │ └── XRSettings.asset
│ ├── obj/
│ │ ├── Debug/
│ │ │ ├── Assembly-CSharp-Editor.csproj.FileListAbsolute.txt
│ │ │ ├── Assembly-CSharp-Editor.csprojResolveAssemblyReference.cache
│ │ │ ├── Assembly-CSharp-Editor.pdb
│ │ │ ├── Assembly-CSharp.csproj.FileListAbsolute.txt
│ │ │ ├── Assembly-CSharp.csprojResolveAssemblyReference.cache
│ │ │ ├── Assembly-CSharp.pdb
│ │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache
│ │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs
│ │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs
│ │ │ └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs
│ │ └── Release/
│ │ ├── Assembly-CSharp.csproj.FileListAbsolute.txt
│ │ └── Assembly-CSharp.pdb
│ ├── scattererShaders-csharp.sln
│ └── scattererShaders.sln
├── Proland/
│ └── Textures/
│ └── Atmo/
│ ├── inscatter.raw
│ ├── irradiance.raw
│ └── transmittance.raw
├── Scatterer.cs
├── Utilities/
│ ├── Camera/
│ │ ├── DepthPrePassMerger.cs
│ │ ├── DepthToDistanceCommandBuffer.cs
│ │ ├── DisableAmbientLight.cs
│ │ ├── DisableEffectsChecker.cs
│ │ ├── DisableEffectsForReflectionsCamera.cs
│ │ ├── ReflectionProbeChecker.cs
│ │ ├── ReflectionProbeFixer.cs
│ │ ├── ScreenCopyCommandBuffer.cs
│ │ ├── TweakShadowCascades.cs
│ │ └── WireFrame.cs
│ ├── Dx12UnifiedCamera.cs
│ ├── EVE/
│ │ └── EVEReflectionHandler.cs
│ ├── Math/
│ │ ├── MathUtility.cs
│ │ ├── Matrix3x3.cs
│ │ ├── Matrix3x3d.cs
│ │ ├── Matrix4x4d.cs
│ │ ├── Quat.cs
│ │ ├── Vector2d.cs
│ │ ├── Vector2i.cs
│ │ ├── Vector3d2.cs
│ │ └── Vector4d.cs
│ ├── Misc/
│ │ ├── IcoSphere.cs
│ │ ├── MeshFactory.cs
│ │ ├── PlanetSecondaryLightUpdater.cs
│ │ └── Utils.cs
│ ├── Occlusion/
│ │ ├── ShadowMapCopier.cs
│ │ ├── ShadowMapRetrieveCommandBuffer.cs
│ │ ├── ShadowMaskCopyCommandBuffer.cs
│ │ ├── ShadowMaskModulateCommandBuffer.cs
│ │ └── ShadowRemoveFadeCommandBuffer.cs
│ ├── ReflectionUtils.cs
│ ├── Shader/
│ │ ├── ShaderProperties.cs
│ │ └── ShaderReplacer.cs
│ ├── Textures/
│ │ ├── RenderTextureUtils.cs
│ │ └── VRUtils.cs
│ └── VsyncStartupFix.cs
├── scatterer.csproj
└── scatterer.sln
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.userprefs
scatterer/obj
scatterer/bin
scatterer/bin/Release/Assembly-CSharp-firstpass.dll
scatterer/bin/Release/Assembly-CSharp.dll
scatterer/bin/Release/Mono.Cecil.dll
scatterer/bin/Release/Mono.Security.dll
scatterer/bin/Release/mscorlib.dll
scatterer/bin/Release/System.Core.dll
scatterer/bin/Release/System.dll
scatterer/bin/Release/System.Xml.dll
scatterer/bin/Release/TDx.TDxInput.dll
scatterer/bin/Release/TrackIRUnity.dll
scatterer/bin/Release/UnityEngine.dll
scatterer/Shaders/scattererShaders/Library
================================================
FILE: Readme.md
================================================
Scatterer
---------------------------------------------------------------------------------
Atmospheric scattering graphical effects for Kerbal Space Program.
This project contains the plugin source which is under the following license:
GNU GENERAL PUBLIC LICENSE Version 3
This repo does not contain shaders for versions higher than 0.0772 and they are not necessary to compile/load the plugin. Shaders are loaded dynamically from asset bundles and can be replaced by custom shaders.
Copyright (c) 2015-2022 Ghassen Lahmar
================================================
FILE: license.md
================================================
Copyright (c) 2015-2022 Ghassen Lahmar
You may use, distribute and copy Scatterer under the terms of GNU General
Public License version 3, which is displayed below.
-------------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
/*
* Proland: a procedural landscape rendering library.
* Website : http://proland.inrialpes.fr/
* Copyright (c) 2008-2015 INRIA - LJK (CNRS - Grenoble University)
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Proland is distributed under the Berkeley Software Distribution 3 Licence.
* For any assistance, feedback and enquiries about training programs, you can check out the
* contact page on our website :
* http://proland.inrialpes.fr/
*/
/*
* Main authors: Eric Bruneton, Antoine Begault, Guillaume Piolat.
*/
/*
* Proland-To-Unity
* Website: https://github.com/Scrawk/Proland-To-Unity
*/
/*
* BSD 3-Clause License
*
* Copyright (c) 2022, Justin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Intel Corporation - Outdoor Light Scattering Sample
* Website:https://github.com/GameTechDev/OutdoorLightScattering
*/
/*
*
* Apache License
* Version 2.0, January 2004
*
* http://www.apache.org/licenses/
*
* TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
*
* 1. Definitions.
*
* "License" shall mean the terms and conditions for use, reproduction, and
* distribution as defined by Sections 1 through 9 of this document.
*
* "Licensor" shall mean the copyright owner or entity authorized by the copyright
* owner that is granting the License.
*
* "Legal Entity" shall mean the union of the acting entity and all other entities
* that control, are controlled by, or are under common control with that entity.
* For the purposes of this definition, "control" means (i) the power, direct or
* indirect, to cause the direction or management of such entity, whether by
* contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
* outstanding shares, or (iii) beneficial ownership of such entity.
*
* "You" (or "Your") shall mean an individual or Legal Entity exercising
* permissions granted by this License.
*
* "Source" form shall mean the preferred form for making modifications, including
* but not limited to software source code, documentation source, and configuration
* files.
*
* "Object" form shall mean any form resulting from mechanical transformation or
* translation of a Source form, including but not limited to compiled object code,
* generated documentation, and conversions to other media types.
*
* "Work" shall mean the work of authorship, whether in Source or Object form, made
* available under the License, as indicated by a copyright notice that is included
* in or attached to the work (an example is provided in the Appendix below).
*
* "Derivative Works" shall mean any work, whether in Source or Object form, that
* is based on (or derived from) the Work and for which the editorial revisions,
* annotations, elaborations, or other modifications represent, as a whole, an
* original work of authorship. For the purposes of this License, Derivative Works
* shall not include works that remain separable from, or merely link (or bind by
* name) to the interfaces of, the Work and Derivative Works thereof.
*
* "Contribution" shall mean any work of authorship, including the original version
* of the Work and any modifications or additions to that Work or Derivative Works
* thereof, that is intentionally submitted to Licensor for inclusion in the Work
* by the copyright owner or by an individual or Legal Entity authorized to submit
* on behalf of the copyright owner. For the purposes of this definition,
* "submitted" means any form of electronic, verbal, or written communication sent
* to the Licensor or its representatives, including but not limited to
* communication on electronic mailing lists, source code control systems, and
* issue tracking systems that are managed by, or on behalf of, the Licensor for
* the purpose of discussing and improving the Work, but excluding communication
* that is conspicuously marked or otherwise designated in writing by the copyright
* owner as "Not a Contribution."
*
* "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
* of whom a Contribution has been received by Licensor and subsequently
* incorporated within the Work.
*
* 2. Grant of Copyright License. Subject to the terms and conditions of this
* License, each Contributor hereby grants to You a perpetual, worldwide,
* non-exclusive, no-charge, royalty-free, irrevocable copyright license to
* reproduce, prepare Derivative Works of, publicly display, publicly perform,
* sublicense, and distribute the Work and such Derivative Works in Source or
* Object form.
*
* 3. Grant of Patent License. Subject to the terms and conditions of this License,
* each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
* no-charge, royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and otherwise
* transfer the Work, where such license applies only to those patent claims
* licensable by such Contributor that are necessarily infringed by their
* Contribution(s) alone or by combination of their Contribution(s) with the Work
* to which such Contribution(s) was submitted. If You institute patent litigation
* against any entity (including a cross-claim or counterclaim in a lawsuit)
* alleging that the Work or a Contribution incorporated within the Work
* constitutes direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of the date
* such litigation is filed.
*
* 4. Redistribution. You may reproduce and distribute copies of the Work or
* Derivative Works thereof in any medium, with or without modifications, and in
* Source or Object form, provided that You meet the following conditions:
* You must give any other recipients of the Work or Derivative Works a copy of
* this License; and
*
*
* You must cause any modified files to carry prominent notices stating that You
* changed the files; and
*
*
* You must retain, in the Source form of any Derivative Works that You
* distribute, all copyright, patent, trademark, and attribution notices from the
* Source form of the Work, excluding those notices that do not pertain to any
* part of the Derivative Works; and
*
*
* If the Work includes a "NOTICE" text file as part of its distribution, then
* any Derivative Works that You distribute must include a readable copy of the
* attribution notices contained within such NOTICE file, excluding those notices
* that do not pertain to any part of the Derivative Works, in at least one of
* the following places: within a NOTICE text file distributed as part of the
* Derivative Works; within the Source form or documentation, if provided along
* with the Derivative Works; or, within a display generated by the Derivative
* Works, if and wherever such third-party notices normally appear. The contents
* of the NOTICE file are for informational purposes only and do not modify the
* License. You may add Your own attribution notices within Derivative Works that
* You distribute, alongside or as an addendum to the NOTICE text from the Work,
* provided that such additional attribution notices cannot be construed as
* modifying the License.
* You may add Your own copyright statement to Your modifications and may provide
* additional or different license terms and conditions for use, reproduction, or
* distribution of Your modifications, or for any such Derivative Works as a whole,
* provided Your use, reproduction, and distribution of the Work otherwise complies
* with the conditions stated in this License.
*
* 5. Submission of Contributions. Unless You explicitly state otherwise, any
* Contribution intentionally submitted for inclusion in the Work by You to the
* Licensor shall be under the terms and conditions of this License, without any
* additional terms or conditions. Notwithstanding the above, nothing herein shall
* supersede or modify the terms of any separate license agreement you may have
* executed with Licensor regarding such Contributions.
*
* 6. Trademarks. This License does not grant permission to use the trade names,
* trademarks, service marks, or product names of the Licensor, except as required
* for reasonable and customary use in describing the origin of the Work and
* reproducing the content of the NOTICE file.
*
* 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
* writing, Licensor provides the Work (and each Contributor provides its
* Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied, including, without limitation, any warranties
* or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
* PARTICULAR PURPOSE. You are solely responsible for determining the
* appropriateness of using or redistributing the Work and assume any risks
* associated with Your exercise of permissions under this License.
*
* 8. Limitation of Liability. In no event and under no legal theory, whether in
* tort (including negligence), contract, or otherwise, unless required by
* applicable law (such as deliberate and grossly negligent acts) or agreed to in
* writing, shall any Contributor be liable to You for damages, including any
* direct, indirect, special, incidental, or consequential damages of any character
* arising as a result of this License or out of the use or inability to use the
* Work (including but not limited to damages for loss of goodwill, work stoppage,
* computer failure or malfunction, or any and all other commercial damages or
* losses), even if such Contributor has been advised of the possibility of such
* damages.
*
* 9. Accepting Warranty or Additional Liability. While redistributing the Work or
* Derivative Works thereof, You may choose to offer, and charge a fee for,
* acceptance of support, warranty, indemnity, or other liability obligations
* and/or rights consistent with this License. However, in accepting such
* obligations, You may act only on Your own behalf and on Your sole
* responsibility, not on behalf of any other Contributor, and only if You agree to
* indemnify, defend, and hold each Contributor harmless for any liability incurred
* by, or claims asserted against, such Contributor by reason of your accepting any
* such warranty or additional liability.
*
* END OF TERMS AND CONDITIONS
*
* APPENDIX: How to apply the Apache License to your work
*
* To apply the Apache License to your work, attach the following boilerplate
* notice, with the fields enclosed by brackets "[]" replaced with your own
* identifying information. (Don't include the brackets!) The text should be
* enclosed in the appropriate comment syntax for the file format. We also
* recommend that a file or class name and description of purpose be included on
* the same "printed page" as the copyright notice for easier identification within
* third-party archives.
*
* Copyright [yyyy] [name of copyright owner] Licensed under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or
* agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
================================================
FILE: scatterer/CelestialBodySortableByDistance.cs
================================================
using System;
using System.Collections.Generic;
namespace scatterer
{
public class celestialBodySortableByDistance : IEquatable , IComparable
{
public CelestialBody CelestialBody { get; set; }
public float Distance { get; set; }
public bool usesScatterer { get; set; }
public int scattererIndex { get; set; }
public override string ToString()
{
return "dist: " + Distance + " CelestialBodyName: " + CelestialBody.name;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
celestialBodySortableByDistance objAsCelestialBodySortableByDistance = obj as celestialBodySortableByDistance;
if (objAsCelestialBodySortableByDistance == null) return false;
else return Equals(objAsCelestialBodySortableByDistance);
}
public int SortByNameAscending(string name1, string name2)
{
return name1.CompareTo(name2);
}
// Default comparer for Part type.
public int CompareTo(celestialBodySortableByDistance comparecelestialBodySortableByDistance)
{
// A null value means that this object is greater.
if (comparecelestialBodySortableByDistance == null)
return 1;
else
return this.Distance.CompareTo(comparecelestialBodySortableByDistance.Distance);
}
public override int GetHashCode()
{
return (int)Distance;
}
public bool Equals(celestialBodySortableByDistance other)
{
if (other == null) return false;
return (this.Distance.Equals(other.Distance));
}
// Should also override == and != operators.
}
}
================================================
FILE: scatterer/DataSerialization/ConfigPoint.cs
================================================
using System;
using UnityEngine;
namespace Scatterer
{
public class ConfigPoint
{
[Persistent] public float altitude;
[Persistent] public float skyExposure;
[Persistent] public float skyAlpha;
[Persistent] public float skyExtinctionTint;
[Persistent] public float scatteringExposure;
[Persistent] public float extinctionThickness;
[Persistent] public float postProcessAlpha;
[Persistent] public float postProcessDepth;
[Persistent] public float extinctionTint;
public ConfigPoint(float inAltitude,float inSkyAlpha,float inSkyExposure,float inPostProcessAlpha,
float inPostProcessDepth,float inPostProcessExposure,
float inSkyExtinctionTint, float in_Post_Extinction_Tint,
float inExtinctionThickness)
{
altitude=inAltitude;
skyAlpha=inSkyAlpha;
skyExposure=inSkyExposure;
postProcessAlpha=inPostProcessAlpha;
postProcessDepth=inPostProcessDepth;
scatteringExposure=inPostProcessExposure;
skyExtinctionTint=inSkyExtinctionTint;
extinctionTint = in_Post_Extinction_Tint;
extinctionThickness = inExtinctionThickness;
}
public void getValuesFrom(ConfigPoint inConfigPoint)
{
skyAlpha=inConfigPoint.skyAlpha;
skyExposure=inConfigPoint.skyExposure;
postProcessAlpha=inConfigPoint.postProcessAlpha;
postProcessDepth=inConfigPoint.postProcessDepth;
scatteringExposure=inConfigPoint.scatteringExposure;
skyExtinctionTint=inConfigPoint.skyExtinctionTint;
extinctionTint = inConfigPoint.extinctionTint;
extinctionThickness = inConfigPoint.extinctionThickness;
}
public void interpolateValuesFrom(ConfigPoint inConfigPoint1, ConfigPoint inConfigPoint2, float x)
{
skyAlpha=Mathf.Lerp(inConfigPoint1.skyAlpha, inConfigPoint2.skyAlpha ,x);
skyExposure=Mathf.Lerp(inConfigPoint1.skyExposure, inConfigPoint2.skyExposure ,x);
postProcessAlpha=Mathf.Lerp(inConfigPoint1.postProcessAlpha, inConfigPoint2.postProcessAlpha ,x);
postProcessDepth=Mathf.Lerp(inConfigPoint1.postProcessDepth, inConfigPoint2.postProcessDepth ,x);
scatteringExposure=Mathf.Lerp(inConfigPoint1.scatteringExposure, inConfigPoint2.scatteringExposure ,x);
skyExtinctionTint=Mathf.Lerp(inConfigPoint1.skyExtinctionTint, inConfigPoint2.skyExtinctionTint ,x);
extinctionTint = Mathf.Lerp(inConfigPoint1.extinctionTint, inConfigPoint2.extinctionTint ,x);
extinctionThickness = Mathf.Lerp(inConfigPoint1.extinctionThickness, inConfigPoint2.extinctionThickness ,x);
}
public ConfigPoint()
{
}
}
}
================================================
FILE: scatterer/DataSerialization/ConfigReader.cs
================================================
using System.Collections;
using System.Collections.Generic;
using KSP;
using KSP.IO;
using UnityEngine;
namespace Scatterer
{
public class ConfigReader
{
[Persistent]
public List scattererCelestialBodies = new List {};
[Persistent]
public List celestialLightSourcesData=new List {};
public ConfigNode[] sunflareConfigs;
public UrlDir.UrlConfig[] baseConfigs,atmoConfigs,oceanConfigs;
public void loadConfigs ()
{
baseConfigs = GameDatabase.Instance.GetConfigs ("Scatterer_config"); //only used for displaying filepath
ConfigNode[] confNodes = GameDatabase.Instance.GetConfigNodes ("Scatterer_planetsList");
if (confNodes.Length == 0) {
Utils.LogError ("No planetsList file found, check your install");
return;
}
if (confNodes.Length > 1) {
Utils.LogError ("Multiple planetsList files detected, check your install");
}
ConfigNode.LoadObjectFromConfig (this, confNodes [0]);
atmoConfigs = GameDatabase.Instance.GetConfigs ("Scatterer_atmosphere");
oceanConfigs = GameDatabase.Instance.GetConfigs ("Scatterer_ocean");
sunflareConfigs = GameDatabase.Instance.GetConfigNodes ("Scatterer_sunflare");
}
}
}
================================================
FILE: scatterer/DataSerialization/MainSettingsReadWrite.cs
================================================
using System.Collections;
using System.Collections.Generic;
using KSP;
using KSP.IO;
using UnityEngine;
namespace Scatterer
{
public class MainSettingsReadWrite
{
[Persistent]
public bool autosavePlanetSettingsOnSceneChange=false;
[Persistent]
public bool disableAmbientLight=true;
[Persistent]
public bool integrateWithEVEClouds=true;
// [Persistent]
// public bool integrateEVECloudsGodrays=true;
[Persistent]
public bool overrideNearClipPlane=false;
[Persistent]
public float nearClipPlane=0.5f;
[Persistent]
public bool useOceanShaders = true;
[Persistent]
public bool oceanFoam = true;
[Persistent]
public bool oceanTransparencyAndRefractions = true;
[Persistent]
public bool shadowsOnOcean = true;
[Persistent]
public bool oceanSkyReflections = true;
[Persistent]
public bool oceanCaustics = true;
[Persistent]
public bool oceanLightRays = false;
[Persistent]
public bool oceanCraftWaveInteractions = true;
[Persistent]
public bool oceanCraftWaveInteractionsOverrideWaterCrashTolerance = true;
[Persistent]
public float buoyancyCrashToleranceMultOverride=1.2f * 3f;
[Persistent]
public bool oceanCraftWaveInteractionsOverrideDrag = true;
[Persistent]
public bool oceanCraftWaveInteractionsOverrideRecoveryVelocity = true;
[Persistent]
public float waterMaxRecoveryVelocity = 5f;
[Persistent]
public bool oceanPixelLights = false;
[Persistent]
public bool fullLensFlareReplacement = true;
[Persistent]
public bool sunlightExtinction = true;
[Persistent]
public bool underwaterLightDimming = true;
[Persistent]
public bool showMenuOnStart = true;
[Persistent]
public bool useEclipses = true;
[Persistent]
public bool useRingShadows = true;
//[Persistent]
public bool usePlanetShine = false;
[Persistent]
public bool d3d11ShadowFix = true;
[Persistent]
public bool useLegacyTerrainGodrays = false;
//[Persistent]
public bool mergeDepthPrePass = false;
//[Persistent]
public bool quarterResScattering = true;
[Persistent]
public bool useSubpixelMorphologicalAntialiasing = true;
[Persistent]
public int smaaQuality = 0;
[Persistent]
public bool useTemporalAntiAliasing = true;
[Persistent]
public float taaStationaryBlending = 0.90f;
[Persistent]
public float taaMotionBlending = 0.55f;
[Persistent]
public float taaJitterSpread = 0.9f;
[Persistent]
public float taaSharpness = 0.25f;
[Persistent]
public int disableTaaBelowFrameRateThreshold = 26;
[Persistent]
public bool terrainShadows = false;
//0 - None, 1 - Bruneton, 2 - Uncharted, 3 - Hable but disabled
[Persistent]
public int scatteringTonemapper = 2;
/*
[Persistent]
public float hableToeStrength;
[Persistent]
public float hableToeLength;
[Persistent]
public float hableShoulderStrength;
[Persistent]
public float hableShoulderLength;
[Persistent]
public float hableShoulderAngle;
[Persistent]
public float hableGamma;
*/
[Persistent]
public float unifiedCamShadowsDistance=50000f;
[Persistent]
public float unifiedCamShadowNormalBiasOverride=0.4f;
[Persistent]
public float unifiedCamShadowBiasOverride=0.125f;
[Persistent]
public int unifiedCamShadowResolutionOverride=0;
[Persistent]
public Vector3 unifiedCamShadowCascadeSplitsOverride=Vector3.zero;
[Persistent]
public float dualCamShadowsDistance=50000f;
[Persistent]
public float dualCamShadowNormalBiasOverride=0.4f;
[Persistent]
public float dualCamShadowBiasOverride=0.125f;
[Persistent]
public int dualCamShadowResolutionOverride=0;
[Persistent]
public Vector3 dualCamShadowCascadeSplitsOverride=Vector3.zero;
[Persistent]
public bool useDithering = true;
[Persistent]
public int m_fourierGridSize = 64;
[Persistent]
public int oceanMeshResolution = 8;
[Persistent]
public bool useLowResolutionAtmosphere = false;
public void loadMainSettings ()
{
UrlDir.UrlConfig[] baseConfigs = GameDatabase.Instance.GetConfigs ("Scatterer_config");
if (baseConfigs.Length == 0)
{
Utils.LogError ("No config file found, check your install");
return;
}
if (baseConfigs.Length > 1)
{
Utils.LogError ("Multiple config files detected, check your install");
}
ConfigNode.LoadObjectFromConfig (this, (baseConfigs [0]).config);
}
public void saveMainSettingsIfChanged()
{
UrlDir.UrlConfig[] baseConfigs = GameDatabase.Instance.GetConfigs ("Scatterer_config");
if (baseConfigs.Length == 0)
{
Utils.LogDebug ("No config file found, check your install");
return;
}
if (baseConfigs.Length > 1)
{
Utils.LogDebug ("Multiple config files detected, check your install");
}
MainSettingsReadWrite OldConfig = new MainSettingsReadWrite ();
ConfigNode.LoadObjectFromConfig (OldConfig, (baseConfigs [0]).config);
bool configChanged =
(OldConfig.autosavePlanetSettingsOnSceneChange != autosavePlanetSettingsOnSceneChange ||
OldConfig.disableAmbientLight != disableAmbientLight ||
OldConfig.integrateWithEVEClouds != integrateWithEVEClouds ||
// OldConfig.integrateEVECloudsGodrays != integrateEVECloudsGodrays ||
OldConfig.overrideNearClipPlane != overrideNearClipPlane ||
OldConfig.nearClipPlane != nearClipPlane ||
OldConfig.useOceanShaders != useOceanShaders ||
OldConfig.oceanFoam != oceanFoam ||
OldConfig.oceanTransparencyAndRefractions != oceanTransparencyAndRefractions ||
OldConfig.shadowsOnOcean != shadowsOnOcean ||
OldConfig.oceanSkyReflections != oceanSkyReflections ||
OldConfig.oceanCaustics != oceanCaustics ||
OldConfig.oceanLightRays != oceanLightRays ||
OldConfig.oceanCraftWaveInteractions != oceanCraftWaveInteractions ||
OldConfig.oceanCraftWaveInteractionsOverrideWaterCrashTolerance != oceanCraftWaveInteractionsOverrideWaterCrashTolerance ||
OldConfig.buoyancyCrashToleranceMultOverride != buoyancyCrashToleranceMultOverride ||
OldConfig.oceanCraftWaveInteractionsOverrideDrag != oceanCraftWaveInteractionsOverrideDrag ||
OldConfig.oceanCraftWaveInteractionsOverrideRecoveryVelocity != oceanCraftWaveInteractionsOverrideRecoveryVelocity ||
OldConfig.waterMaxRecoveryVelocity != waterMaxRecoveryVelocity ||
OldConfig.oceanPixelLights != oceanPixelLights ||
OldConfig.fullLensFlareReplacement != fullLensFlareReplacement ||
OldConfig.sunlightExtinction != sunlightExtinction ||
OldConfig.underwaterLightDimming != underwaterLightDimming ||
OldConfig.showMenuOnStart != showMenuOnStart ||
OldConfig.useEclipses != useEclipses ||
OldConfig.useRingShadows != useRingShadows ||
OldConfig.d3d11ShadowFix != d3d11ShadowFix ||
OldConfig.useLegacyTerrainGodrays != useLegacyTerrainGodrays ||
//OldConfig.mergeDepthPrePass != mergeDepthPrePass ||
OldConfig.quarterResScattering != quarterResScattering ||
OldConfig.useSubpixelMorphologicalAntialiasing != useSubpixelMorphologicalAntialiasing ||
OldConfig.smaaQuality != smaaQuality ||
OldConfig.useTemporalAntiAliasing != useTemporalAntiAliasing ||
OldConfig.taaStationaryBlending != taaStationaryBlending ||
OldConfig.taaMotionBlending != taaMotionBlending ||
OldConfig.taaJitterSpread != taaJitterSpread ||
OldConfig.taaSharpness != taaSharpness ||
OldConfig.disableTaaBelowFrameRateThreshold != disableTaaBelowFrameRateThreshold ||
OldConfig.terrainShadows != terrainShadows ||
OldConfig.scatteringTonemapper != scatteringTonemapper ||
/*
OldConfig.hableToeStrength != hableToeStrength ||
OldConfig.hableToeLength != hableToeLength ||
OldConfig.hableShoulderStrength != hableShoulderStrength ||
OldConfig.hableShoulderLength != hableShoulderLength ||
OldConfig.hableShoulderAngle != hableShoulderAngle ||
OldConfig.hableGamma != hableGamma ||
*/
OldConfig.useDithering != useDithering ||
OldConfig.unifiedCamShadowsDistance != unifiedCamShadowsDistance ||
OldConfig.unifiedCamShadowNormalBiasOverride != unifiedCamShadowNormalBiasOverride ||
OldConfig.unifiedCamShadowBiasOverride != unifiedCamShadowBiasOverride ||
OldConfig.unifiedCamShadowCascadeSplitsOverride != unifiedCamShadowCascadeSplitsOverride ||
OldConfig.unifiedCamShadowResolutionOverride != unifiedCamShadowResolutionOverride ||
OldConfig.dualCamShadowsDistance != dualCamShadowsDistance ||
OldConfig.dualCamShadowNormalBiasOverride != dualCamShadowNormalBiasOverride ||
OldConfig.dualCamShadowBiasOverride != dualCamShadowBiasOverride ||
OldConfig.dualCamShadowCascadeSplitsOverride != dualCamShadowCascadeSplitsOverride ||
OldConfig.dualCamShadowResolutionOverride != dualCamShadowResolutionOverride ||
OldConfig.m_fourierGridSize != m_fourierGridSize ||
OldConfig.oceanMeshResolution != oceanMeshResolution) ||
OldConfig.useLowResolutionAtmosphere != useLowResolutionAtmosphere;
if (configChanged)
{
Utils.LogDebug("Main config changed");
baseConfigs [0].config = ConfigNode.CreateConfigFromObject (this);
baseConfigs [0].config.name = "Scatterer_config";
Utils.LogDebug ("Saving settings to: " + baseConfigs [0].parent.url+".cfg");
baseConfigs [0].parent.SaveConfigs ();
}
else
{
Utils.LogDebug("No changes to main config, skipping saving.");
}
}
}
}
================================================
FILE: scatterer/DataSerialization/PlanetshineSource.cs
================================================
using System;
using UnityEngine;
using System.Collections.Generic;
namespace Scatterer
{
public class AtmoPlanetShineSource
{
[Persistent] public string bodyName;
[Persistent] public Vector3 color;
[Persistent] public float intensity;
[Persistent] public bool isSun;
public CelestialBody body;
}
public class PlanetShineLightSource
{
[Persistent] public string bodyName;
[Persistent] public Vector3 color;
[Persistent] public float intensity;
[Persistent] public bool isSun;
[Persistent] public string mainSunCelestialBody;
[Persistent] public float localRange;
[Persistent] public float scaledRange;
[Persistent] public float fadeRadius;
}
}
================================================
FILE: scatterer/DataSerialization/PluginDataReadWrite.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using KSP;
using KSP.IO;
using UnityEngine;
namespace Scatterer
{
public class PluginDataReadWrite
{
[Persistent]
public string guiModifierKey1String=KeyCode.LeftAlt.ToString();
[Persistent]
public string guiModifierKey2String=KeyCode.RightAlt.ToString();
[Persistent]
public string guiKey1String=KeyCode.F10.ToString();
[Persistent]
public string guiKey2String=KeyCode.F11.ToString();
[Persistent]
public int scrollSectionHeight = 500;
[Persistent]
public Vector2 inGameWindowLocation=Vector2.zero;
public KeyCode guiKey1, guiKey2, guiModifierKey1, guiModifierKey2 ;
public void loadPluginData ()
{
try
{
ConfigNode confNode = ConfigNode.Load (Utils.PluginPath + "/config/PluginData/pluginData.cfg");
ConfigNode.LoadObjectFromConfig (this, confNode);
guiKey1 = (KeyCode)Enum.Parse(typeof(KeyCode), guiKey1String);
guiKey2 = (KeyCode)Enum.Parse(typeof(KeyCode), guiKey2String);
guiModifierKey1 = (KeyCode)Enum.Parse(typeof(KeyCode), guiModifierKey1String);
guiModifierKey2 = (KeyCode)Enum.Parse(typeof(KeyCode), guiModifierKey2String);
}
catch (Exception stupid)
{
Utils.LogError("Couldn't load pluginData "+stupid.ToString());
}
}
public void savePluginData ()
{
try
{
var dir = Utils.PluginPath + "/config/PluginData";
if (!System.IO.Directory.Exists(dir)) System.IO.Directory.CreateDirectory(dir);
ConfigNode cnTemp = ConfigNode.CreateConfigFromObject (this);
cnTemp.Save (dir + "/pluginData.cfg");
}
catch (Exception stupid)
{
Utils.LogError("Couldn't save pluginData "+stupid.ToString());
}
}
}
}
================================================
FILE: scatterer/DataSerialization/QualityPresetsLoader.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using KSP;
using KSP.IO;
using UnityEngine;
namespace Scatterer
{
public class QualityPresetsLoader
{
public static String[] GetPresetsList()
{
List presetStrings = new List ();
UrlDir.UrlConfig[] presetsList = GameDatabase.Instance.GetConfigs ("Scatterer_quality_preset");
foreach (UrlDir.UrlConfig _url in presetsList)
{
ConfigNode[] configNodeArray = _url.config.GetNodes("Quality_preset");
foreach(ConfigNode _cn in configNodeArray)
{
if (_cn.HasValue("name"))
{
presetStrings.Add(_cn.GetValue("name"));
}
}
}
return presetStrings.ToArray();
}
public static void LoadPresetIntoMainSettings(MainSettingsReadWrite settings, string presetName)
{
List presetStrings = new List ();
UrlDir.UrlConfig[] presetsList = GameDatabase.Instance.GetConfigs ("Scatterer_quality_preset");
foreach (UrlDir.UrlConfig _url in presetsList)
{
ConfigNode[] configNodeArray = _url.config.GetNodes("Quality_preset");
foreach(ConfigNode _cn in configNodeArray)
{
if (_cn.HasValue("name") && (_cn.GetValue("name") == presetName))
{
LoadConfigNodeIntoMainSettings(settings, _cn);
break;
}
}
}
}
private static void LoadConfigNodeIntoMainSettings(MainSettingsReadWrite settings, ConfigNode cn)
{
MainSettingsReadWrite tempMainSettings = new MainSettingsReadWrite();
Type targetType = tempMainSettings.GetType ();
ConfigNode.LoadObjectFromConfig (tempMainSettings, cn);
foreach (FieldInfo fi in targetType.GetFields())
{
if (cn.HasValue(fi.Name))
{
fi.SetValue(settings, fi.GetValue(tempMainSettings));
}
}
}
public static string FindPresetOfCurrentSettings(MainSettingsReadWrite settings)
{
UrlDir.UrlConfig[] presetsList = GameDatabase.Instance.GetConfigs ("Scatterer_quality_preset");
foreach (UrlDir.UrlConfig _url in presetsList)
{
ConfigNode[] configNodeArray = _url.config.GetNodes("Quality_preset");
foreach(ConfigNode _cn in configNodeArray)
{
if (_cn.HasValue("name"))
{
if (PresetMatchesCurrentSettings(settings,_cn))
{
return _cn.GetValue("name");
}
}
}
}
return ("No preset - custom settings");
}
private static bool PresetMatchesCurrentSettings(MainSettingsReadWrite settings, ConfigNode cn)
{
MainSettingsReadWrite tempMainSettings = new MainSettingsReadWrite();
Type targetType = tempMainSettings.GetType ();
ConfigNode.LoadObjectFromConfig (tempMainSettings, cn);
bool match = true;
bool compared = false;
foreach (FieldInfo fi in targetType.GetFields())
{
if (cn.HasValue(fi.Name))
{
if (!CompareFields(fi, settings, tempMainSettings))
{
return false;
}
compared = true;
}
}
return match && compared;
}
private static bool CompareFields(FieldInfo fi, MainSettingsReadWrite settings1, MainSettingsReadWrite settings2)
{
if (fi.FieldType == typeof(float))
{
return ((float)(fi.GetValue (settings1)) == (float)(fi.GetValue (settings2)));
}
else if (fi.FieldType == typeof(int))
{
return ((int)(fi.GetValue (settings1)) == (int)(fi.GetValue (settings2)));
}
else if (fi.FieldType == typeof(bool))
{
return ((bool)(fi.GetValue (settings1)) == (bool)(fi.GetValue (settings2)));
}
else if (fi.FieldType == typeof(Vector3))
{
return ((Vector3)(fi.GetValue (settings1)) == (Vector3)(fi.GetValue (settings2)));
}
Utils.LogError("Unhandled preset type? "+fi.FieldType.ToString());
return false;
}
}
}
================================================
FILE: scatterer/DataSerialization/ScattererCelestialBody.cs
================================================
using System;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
namespace Scatterer
{
public class ScattererCelestialBody
{
[Persistent] public string celestialBodyName;
[Persistent] public string transformName;
[Persistent] public float loadDistance;
[Persistent] public float unloadDistance;
[Persistent] public bool hasOcean;
[Persistent] public bool usesCloudIntegration;
[Persistent] public bool cloudIntegrationUsesScattererSunColors = false;
[Persistent] public bool flatScaledSpaceModel;
[Persistent] public string mainSunCelestialBody;
[Persistent] public bool sunsUseIntensityCurves = false;
[Persistent] public Color sunColor = Color.white;
[Persistent] public List eclipseCasters=new List {};
[Persistent] public List secondarySuns=new List {};
[Persistent] public List planetshineSources=new List {};
public CelestialBody celestialBody;
public Transform transform;
public bool isFound = false;
public bool active;
public ProlandManager prolandManager;
public ScattererCelestialBody ()
{
}
}
public class SecondarySunConfig
{
[Persistent] public string celestialBodyName;
[Persistent] public Color sunColor = Color.white;
//[Persistent] public List eclipseCasters=new List {}; //maybe don't do this at the start? or at all, especially since we will half-ass it by not being able to eclipse light on terrain anyway
}
public class SecondarySun
{
public SecondarySunConfig config;
public CelestialBody celestialBody;
public Light sunLight = null;
public Light scaledSunLight = null;
//public List eclipseCasters=new List {};
public SecondarySun (SecondarySunConfig inConfig, CelestialBody body)
{
config = inConfig;
celestialBody = body;
}
public static SecondarySun FindSecondarySun (SecondarySunConfig inConfig)
{
var celestialBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.GetName () == inConfig.celestialBodyName);
if (celestialBody == null)
{
Utils.LogError ("Secondary sun " + inConfig.celestialBodyName + " not found, will be unavailable for atmo/ocean effects");
return null;
}
else
{
SecondarySun secondarySun = new SecondarySun(inConfig, celestialBody);
return secondarySun;
}
}
}
}
================================================
FILE: scatterer/Effects/AntiAliasing/GenericAntiAliasing.cs
================================================
using UnityEngine;
namespace Scatterer
{
public abstract class GenericAntiAliasing : MonoBehaviour
{
public GenericAntiAliasing ()
{
}
}
}
================================================
FILE: scatterer/Effects/AntiAliasing/SubpixelMorphologicalAntialiasing.cs
================================================
using System;
using UnityEngine;
using UnityEngine.Rendering;
namespace Scatterer
{
public class SubpixelMorphologicalAntialiasing : GenericAntiAliasing
{
Camera targetCamera;
CommandBuffer SMAACommandBuffer;
Material SMAAMaterial;
enum Pass { EdgeDetection = 0, BlendWeights = 3, NeighborhoodBlending = 6 }
public enum Quality { DepthMode = 0, Medium = 1, High = 2 }
private static CameraEvent SMAACameraEvent = CameraEvent.AfterForwardAlpha; // BeforeImageEffects doesn't work well
Quality quality;
public void forceDepthBuffermode()
{
quality = Quality.DepthMode;
initialized = false;
}
int flipRenderTargetNameID, flopRenderTargetNameID;
static Texture2D areaTex, searchTex;
bool initialized = false;
bool hdrEnabled = false;
public Quality QualityUsed { get => quality; }
public void Awake()
{
targetCamera = GetComponent ();
targetCamera.forceIntoRenderTexture = true;
hdrEnabled = targetCamera.allowHDR;
// surely there are better names for these? They're both temporaries
flipRenderTargetNameID = Shader.PropertyToID("_SMAA_Flip");
flopRenderTargetNameID = Shader.PropertyToID("_SMAA_Flop");
SMAAMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/SubpixelMorphologicalAntialiasing")]);
if (areaTex == null)
areaTex = (Texture2D) ShaderReplacer.Instance.LoadedTextures ["AreaTex"];
if (searchTex == null)
searchTex = (Texture2D)ShaderReplacer.Instance.LoadedTextures ["SearchTex"];
SMAAMaterial.SetTexture("_AreaTex" , areaTex);
SMAAMaterial.SetTexture("_SearchTex", searchTex);
quality = (Quality)((Int32) Mathf.Clamp( (float) Scatterer.Instance.mainSettings.smaaQuality,1f,2f)); //limit to 1 and 2, 1 and 2 are image-based. 0 is depth-based and would make performance worse by having to run for each camera's depth
//only use depth mode when we force it for the IVA camera
SMAACommandBuffer = new CommandBuffer ();
SMAACommandBuffer.name = $"Scatterer SMAA CommandBuffer for {targetCamera.name}";
}
static readonly int MainTextureProperty = Shader.PropertyToID("_MainTexture");
static readonly int BlendTexproperty = Shader.PropertyToID("_BlendTex");
public void OnPreCull()
{
if (!initialized || targetCamera.allowHDR != hdrEnabled)
{
SMAACommandBuffer.Clear ();
hdrEnabled = targetCamera.allowHDR;
var colorFormat = hdrEnabled ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.ARGB32;
SMAACommandBuffer.GetTemporaryRT(flipRenderTargetNameID, -1, -1, 0, FilterMode.Bilinear, colorFormat);
// TODO: how do we make sure to match the previous settings? Do we need to use RenderTextureDescriptor?
//flip.anisoLevel = 1;
//flip.antiAliasing = 1;
//flip.volumeDepth = 0;
//flip.useMipMap = false;
//flip.autoGenerateMips = false;
//flip.wrapMode = TextureWrapMode.Clamp;
//flip.filterMode = FilterMode.Bilinear;
SMAACommandBuffer.GetTemporaryRT(flopRenderTargetNameID, -1, -1, 0, FilterMode.Bilinear, colorFormat);
SMAACommandBuffer.SetRenderTarget (flopRenderTargetNameID);
SMAACommandBuffer.ClearRenderTarget (false, true, Color.clear);
SMAACommandBuffer.SetRenderTarget (flipRenderTargetNameID);
SMAACommandBuffer.ClearRenderTarget (false, true, Color.clear);
SMAACommandBuffer.SetGlobalTexture (MainTextureProperty, BuiltinRenderTextureType.CameraTarget);
SMAACommandBuffer.Blit (null, flipRenderTargetNameID, SMAAMaterial, (int)Pass.EdgeDetection + (int)quality); //screen to flip with edge detection
SMAACommandBuffer.SetGlobalTexture (MainTextureProperty, flipRenderTargetNameID);
SMAACommandBuffer.Blit (null, flopRenderTargetNameID, SMAAMaterial, (int)Pass.BlendWeights + (int)quality); //flip to flop with blendweights
SMAACommandBuffer.SetGlobalTexture (BlendTexproperty, flopRenderTargetNameID);
SMAACommandBuffer.SetGlobalTexture (MainTextureProperty, BuiltinRenderTextureType.CameraTarget);
SMAACommandBuffer.Blit (null, flipRenderTargetNameID, SMAAMaterial, (int)Pass.NeighborhoodBlending); //neighborhood blending to flip
SMAACommandBuffer.Blit (flipRenderTargetNameID, BuiltinRenderTextureType.CameraTarget); //blit back to screen
targetCamera.AddCommandBuffer (SMAACameraEvent, SMAACommandBuffer);
initialized = true;
}
}
public void OnDestroy()
{
SMAAMaterial = null;
if (SMAACommandBuffer !=null)
{
targetCamera.RemoveCommandBuffer (SMAACameraEvent, SMAACommandBuffer);
SMAACommandBuffer.Clear();
SMAACommandBuffer.Release();
SMAACommandBuffer = null;
initialized = false;
}
}
}
}
================================================
FILE: scatterer/Effects/AntiAliasing/TemporalAntiAliasing.cs
================================================
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.XR;
namespace Scatterer
{
// Temporal anti-aliasing from Unity post-processing stack V2
// Modified to not blur the ocean, removed dependency on other postprocessing classes I don't need here so we can initialize and make everything work by just adding this to a camera
// Generating motion vectors for the ocean is both expensive and unnecessary so we should just not apply TAA on the ocean, otherwise it would just blur it without proper motion vectors
public class TemporalAntiAliasing : GenericAntiAliasing
{
public float jitterSpread = 0.9f; //The diameter (in texels) inside which jitter samples are spread. Smaller values result in crisper but more aliased output, while larger values result in more stable, but blurrier, output. Range(0.1f, 1f)
public float sharpness = 0.25f; //Controls the amount of sharpening applied to the color buffer. High values may introduce dark-border artifacts. Range(0f, 3f)
public float stationaryBlending = 0.90f; //The blend coefficient for a stationary fragment. Controls the percentage of history sample blended into the final color. Range(0f, 0.99f)
public float motionBlending = 0.55f; //The blend coefficient for a fragment with significant motion. Controls the percentage of history sample blended into the final color. Range(0f, 0.99f)
public Vector2 jitter { get; private set; } // The current jitter amount
public int sampleIndex { get; private set; } // The current sample index
enum Pass {SolverDilate, SolverNoDilate}
readonly RenderTargetIdentifier[] m_Mrt = new RenderTargetIdentifier[2];
bool m_ResetHistory = true;
bool hdrEnabled = false;
const int k_SampleCount = 8;
// Ping-pong between two history textures as we can't read & write the same target in the same pass
const int eyesCount = 2; const int historyTexturesCount = 2;
RenderTexture[][] historyTextures = new RenderTexture[eyesCount][];
int[] m_HistoryPingPong = new int [eyesCount];
Camera targetCamera;
CommandBuffer temporalAACommandBuffer;
Material temporalAAMaterial;
DepthTextureMode originalDepthTextureMode;
public bool checkOceanDepth = false;
public bool jitterTransparencies = false;
public bool resetMotionVectors = true;
private static int jitterProperty = Shader.PropertyToID("_Jitter");
private static int keepPreviousMotionVectorsProperty = Shader.PropertyToID("TAA_KeepPreviousMotionVectors");
private static CameraEvent TAACameraEvent = CameraEvent.AfterForwardAlpha; // BeforeImageEffects doesn't work well
bool firstFrame = true;
public void Awake()
{
targetCamera = GetComponent();
originalDepthTextureMode = targetCamera.depthTextureMode;
targetCamera.depthTextureMode = DepthTextureMode.Depth | DepthTextureMode.MotionVectors;
targetCamera.forceIntoRenderTexture = true;
temporalAAMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/TemporalAntialiasing")]);
Utils.EnableOrDisableShaderKeywords(temporalAAMaterial, "CUSTOM_OCEAN_ON", "CUSTOM_OCEAN_OFF", false);
jitterSpread = Scatterer.Instance.mainSettings.taaJitterSpread;
sharpness = Scatterer.Instance.mainSettings.taaSharpness;
stationaryBlending = Scatterer.Instance.mainSettings.taaStationaryBlending;
motionBlending = Scatterer.Instance.mainSettings.taaMotionBlending;
const float kMotionAmplification = 100f * 60f;
temporalAAMaterial.SetFloat("_Sharpness", sharpness);
temporalAAMaterial.SetVector("_FinalBlendParameters", new Vector4(stationaryBlending, motionBlending, kMotionAmplification, 0f));
temporalAACommandBuffer = new CommandBuffer();
temporalAACommandBuffer.name = $"Scatterer TAA CommandBuffer for {targetCamera.name}";
}
internal DepthTextureMode GetCameraFlags()
{
return DepthTextureMode.Depth | DepthTextureMode.MotionVectors;
}
internal void ResetHistory()
{
m_ResetHistory = true;
}
Vector2 GenerateRandomOffset()
{
// The variance between 0 and the actual halton sequence values reveals noticeable instability
// in Unity's shadow maps, so we avoid index 0.
var offset = new Vector2(
HaltonSeq.Get((sampleIndex & 1023) + 1, 2) - 0.5f,
HaltonSeq.Get((sampleIndex & 1023) + 1, 3) - 0.5f
);
if (++sampleIndex >= k_SampleCount)
sampleIndex = 0;
return offset;
}
private static class RuntimeUtilities
{
/// Gets a jittered perspective projection matrix for a given camera.
public static Matrix4x4 GetJitteredPerspectiveProjectionMatrix(Camera camera, Vector2 offset)
{
float near = camera.nearClipPlane;
float far = camera.farClipPlane;
float vertical = Mathf.Tan(0.5f * Mathf.Deg2Rad * camera.fieldOfView) * near;
float horizontal = vertical * camera.aspect;
offset.x *= horizontal / (0.5f * camera.pixelWidth);
offset.y *= vertical / (0.5f * camera.pixelHeight);
var matrix = camera.projectionMatrix;
matrix[0, 2] += offset.x / horizontal;
matrix[1, 2] += offset.y / vertical;
return matrix;
}
public static Matrix4x4 GetJitteredOrthographicProjectionMatrix(Camera camera, Vector2 offset)
{
float vertical = camera.orthographicSize;
float horizontal = vertical * camera.aspect;
offset.x *= horizontal / (0.5f * camera.pixelWidth);
offset.y *= vertical / (0.5f * camera.pixelHeight);
float left = offset.x - horizontal;
float right = offset.x + horizontal;
float top = offset.y + vertical;
float bottom = offset.y - vertical;
return Matrix4x4.Ortho(left, right, bottom, top, camera.nearClipPlane, camera.farClipPlane);
}
public static Matrix4x4 GenerateJitteredProjectionMatrixFromOriginal(int screenWidth, int screenHeight, Matrix4x4 origProj, Vector2 jitter)
{
var planes = origProj.decomposeProjection;
float vertFov = Mathf.Abs(planes.top) + Mathf.Abs(planes.bottom);
float horizFov = Mathf.Abs(planes.left) + Mathf.Abs(planes.right);
var planeJitter = new Vector2(jitter.x * horizFov / screenWidth,
jitter.y * vertFov / screenHeight);
planes.left += planeJitter.x;
planes.right += planeJitter.x;
planes.top += planeJitter.y;
planes.bottom += planeJitter.y;
var jitteredMatrix = Matrix4x4.Frustum(planes);
return jitteredMatrix;
}
}
/// Generates a jittered projection matrix for a given camera.
public Matrix4x4 GetJitteredProjectionMatrix(Camera camera)
{
Matrix4x4 cameraProj;
jitter = GenerateRandomOffset();
jitter *= jitterSpread;
cameraProj = camera.orthographic
? RuntimeUtilities.GetJitteredOrthographicProjectionMatrix(camera, jitter)
: RuntimeUtilities.GetJitteredPerspectiveProjectionMatrix(camera, jitter);
jitter = new Vector2(jitter.x / camera.pixelWidth, jitter.y / camera.pixelHeight);
return cameraProj;
}
/// Prepares the jittered and non jittered projection matrices
public void ConfigureJitteredProjectionMatrix(Camera camera)
{
// camera.nonJitteredProjectionMatrix = camera.projectionMatrix; // should this be here? it's in the stock postprocess code
camera.projectionMatrix = GetJitteredProjectionMatrix(camera);
camera.useJitteredProjectionMatrixForTransparentRendering = jitterTransparencies;
}
public void ConfigureStereoJitteredProjectionMatrices(Camera camera)
{
jitter = GenerateRandomOffset();
jitter *= jitterSpread;
// see PostProcessRenderContext.camera set property
int screenWidth, screenHeight;
if (camera.stereoEnabled)
{
screenWidth = XRSettings.eyeTextureWidth;
screenHeight = XRSettings.eyeTextureHeight;
}
else
{
screenWidth = camera.pixelWidth;
screenHeight = camera.pixelHeight;
}
for (var eye = Camera.StereoscopicEye.Left; eye <= Camera.StereoscopicEye.Right; eye++)
{
// This saves off the device generated projection matrices as non-jittered
camera.CopyStereoDeviceProjectionMatrixToNonJittered(eye);
var originalProj = camera.GetStereoNonJitteredProjectionMatrix(eye);
// Currently no support for custom jitter func, as VR devices would need to provide
// original projection matrix as input along with jitter
var jitteredMatrix = RuntimeUtilities.GenerateJitteredProjectionMatrixFromOriginal(screenWidth, screenHeight, originalProj, jitter);
camera.SetStereoProjectionMatrix(eye, jitteredMatrix);
}
// jitter has to be scaled for the actual eye texture size, not just the intermediate texture size
// which could be double-wide in certain stereo rendering scenarios
jitter = new Vector2(jitter.x / screenWidth, jitter.y / screenHeight);
camera.useJitteredProjectionMatrixForTransparentRendering = jitterTransparencies;
}
RenderTexture CheckHistory(int id, CommandBuffer cmd, int activeEye)
{
if (historyTextures[activeEye] == null)
historyTextures[activeEye] = new RenderTexture[historyTexturesCount];
if (hdrEnabled != targetCamera.allowHDR)
ResetHistory();
var historyRT = historyTextures[activeEye][id];
if (m_ResetHistory || historyRT == null || !historyRT.IsCreated())
{
RenderTexture.ReleaseTemporary(historyRT);
int width, height;
if (targetCamera.activeTexture)
{
width = targetCamera.activeTexture.width;
height = targetCamera.activeTexture.height;
}
else
{
width = Screen.width;
height = Screen.height;
}
hdrEnabled = targetCamera.allowHDR;
historyRT = RenderTexture.GetTemporary (width, height, 0, hdrEnabled ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.ARGB32);
historyRT.name = "Temporal Anti-aliasing History id #" + id;
historyRT.filterMode = FilterMode.Bilinear;
historyTextures[activeEye][id] = historyRT;
cmd.Blit(BuiltinRenderTextureType.CameraTarget, historyRT);
}
return historyTextures[activeEye][id];
}
//adapted from the original render() method
public void OnPreCull()
{
bool screenShotModeEnabled = GameSettings.TAKE_SCREENSHOT.GetKeyDown(false);
float currentFps = 1.0f / Time.deltaTime;
bool aboveFpsThreshold = currentFps >= Scatterer.Instance.mainSettings.disableTaaBelowFrameRateThreshold
|| !Scatterer.Instance.mainSettings.useSubpixelMorphologicalAntialiasing;
if (!screenShotModeEnabled && aboveFpsThreshold)
{
temporalAACommandBuffer.Clear();
int activeEye = targetCamera.stereoActiveEye == Camera.MonoOrStereoscopicEye.Right ? 1 : 0;
int pingPongIndex = m_HistoryPingPong[activeEye];
RenderTexture historyRead = CheckHistory(++pingPongIndex % 2, temporalAACommandBuffer, activeEye);
RenderTexture historyWrite = CheckHistory(++pingPongIndex % 2, temporalAACommandBuffer, activeEye);
m_HistoryPingPong[activeEye] = ++pingPongIndex % 2;
if (firstFrame)
{
temporalAACommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, historyWrite);
}
else
{
ConfigureJitteredProjectionMatrix(targetCamera);
//TODO: move to shader properties
if (checkOceanDepth)
Utils.EnableOrDisableShaderKeywords(temporalAAMaterial, "CUSTOM_OCEAN_ON", "CUSTOM_OCEAN_OFF", Scatterer.Instance.scattererCelestialBodiesManager.isCustomOceanEnabledOnScattererPlanet);
temporalAAMaterial.SetTexture(ShaderProperties._HistoryTex_PROPERTY, historyRead);
int pass = (int)Pass.SolverDilate;
temporalAACommandBuffer.SetGlobalTexture(ShaderProperties._ScreenColor_PROPERTY, BuiltinRenderTextureType.CameraTarget);
temporalAACommandBuffer.Blit(null, historyWrite, temporalAAMaterial, pass);
temporalAACommandBuffer.Blit(historyWrite, BuiltinRenderTextureType.CameraTarget);
}
targetCamera.AddCommandBuffer (TAACameraEvent, temporalAACommandBuffer);
m_ResetHistory = false;
firstFrame = false;
if (resetMotionVectors)
{
Shader.SetGlobalInt(keepPreviousMotionVectorsProperty, 0);
}
else
{
Shader.SetGlobalInt(keepPreviousMotionVectorsProperty, 1);
}
}
else
{
firstFrame = true;
}
}
public void OnPostRender()
{
ResetProjection();
targetCamera.RemoveCommandBuffer (TAACameraEvent, temporalAACommandBuffer);
}
// This is needed otherwise transparencies jitter
public void ResetProjection()
{
targetCamera.ResetProjectionMatrix();
targetCamera.nonJitteredProjectionMatrix = targetCamera.projectionMatrix;
}
public void OnDestroy()
{
if (temporalAACommandBuffer != null)
targetCamera.RemoveCommandBuffer (TAACameraEvent, temporalAACommandBuffer);
targetCamera.depthTextureMode = originalDepthTextureMode;
if (historyTextures != null)
{
for (int i = 0; i < historyTextures.Length; i++)
{
if (historyTextures[i] == null)
continue;
for (int j = 0; j < historyTextures[i].Length; j++)
{
RenderTexture.ReleaseTemporary(historyTextures[i][j]);
historyTextures[i][j] = null;
}
historyTextures[i] = null;
}
}
sampleIndex = 0;
m_HistoryPingPong[0] = 0;
m_HistoryPingPong[1] = 1;
ResetHistory();
targetCamera.ResetProjectionMatrix();
}
}
}
================================================
FILE: scatterer/Effects/AntiAliasing/Utils/HaltonSeq.cs
================================================
namespace Scatterer
{
/// Halton sequence utility from unity post-processing stack V2
public static class HaltonSeq
{
///
/// Gets a value from the Halton sequence for a given index and radix.
///
/// The sequence index
/// The sequence base
/// A number from the Halton sequence between 0 and 1.
public static float Get(int index, int radix)
{
float result = 0f;
float fraction = 1f / (float)radix;
while (index > 0)
{
result += (float)(index % radix) * fraction;
index /= radix;
fraction /= (float)radix;
}
return result;
}
}
}
================================================
FILE: scatterer/Effects/PlanetShine/PlanetShineLight.cs
================================================
using System;
using UnityEngine;
namespace Scatterer
{
public class PlanetShineLight : MonoBehaviour
{
public GameObject scaledLight, localLight;
public bool isSun;
public CelestialBody source, sunCelestialBody;
public void updateLight()
{
scaledLight.gameObject.transform.position=ScaledSpace.LocalToScaledSpace(source.transform.position);
localLight.gameObject.transform.position=(source.transform.position);
if (!isSun)
{
localLight.gameObject.transform.LookAt(sunCelestialBody.transform.position);
scaledLight.gameObject.transform.LookAt (ScaledSpace.LocalToScaledSpace (sunCelestialBody.transform.position));
}
}
public void OnDestroy()
{
UnityEngine.Object.Destroy (scaledLight);
UnityEngine.Object.Destroy (localLight);
}
}
}
================================================
FILE: scatterer/Effects/PlanetShine/PlanetshineManager.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Scatterer
{
public class PlanetshineManager
{
List celestialLightSources=new List {};
Cubemap planetShineCookieCubeMap;
public PlanetshineManager ()
{
//load planetshine "cookie" cubemap
planetShineCookieCubeMap = new Cubemap (512, TextureFormat.ARGB32, true);
Texture2D[] cubeMapFaces = new Texture2D[6];
for (int i = 0; i < 6; i++) {
cubeMapFaces [i] = new Texture2D (512, 512);
}
cubeMapFaces [0].LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", Utils.PluginPath + "/planetShineCubemap", "_NegativeX.png")));
cubeMapFaces [1].LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", Utils.PluginPath + "/planetShineCubemap", "_PositiveX.png")));
cubeMapFaces [2].LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", Utils.PluginPath + "/planetShineCubemap", "_NegativeY.png")));
cubeMapFaces [3].LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", Utils.PluginPath + "/planetShineCubemap", "_PositiveY.png")));
cubeMapFaces [4].LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", Utils.PluginPath + "/planetShineCubemap", "_NegativeZ.png")));
cubeMapFaces [5].LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", Utils.PluginPath + "/planetShineCubemap", "_PositiveZ.png")));
planetShineCookieCubeMap.SetPixels (cubeMapFaces [0].GetPixels (), CubemapFace.NegativeX);
planetShineCookieCubeMap.SetPixels (cubeMapFaces [1].GetPixels (), CubemapFace.PositiveX);
planetShineCookieCubeMap.SetPixels (cubeMapFaces [2].GetPixels (), CubemapFace.NegativeY);
planetShineCookieCubeMap.SetPixels (cubeMapFaces [3].GetPixels (), CubemapFace.PositiveY);
planetShineCookieCubeMap.SetPixels (cubeMapFaces [4].GetPixels (), CubemapFace.NegativeZ);
planetShineCookieCubeMap.SetPixels (cubeMapFaces [5].GetPixels (), CubemapFace.PositiveZ);
planetShineCookieCubeMap.Apply ();
foreach (PlanetShineLightSource _aSource in Scatterer.Instance.planetsConfigsReader.celestialLightSourcesData)
{
var celBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.bodyName == _aSource.bodyName);
if (celBody)
{
PlanetShineLight aPsLight = new PlanetShineLight ();
aPsLight.isSun = _aSource.isSun;
aPsLight.source = celBody;
if (!_aSource.isSun)
aPsLight.sunCelestialBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.GetName () == _aSource.mainSunCelestialBody);
// GameObject ScaledPlanetShineLight = (UnityEngine.GameObject)Instantiate (Scatterer.Instance.scaledSpaceSunLight.gameObject);
// GameObject LocalPlanetShineLight = (UnityEngine.GameObject)Instantiate (Scatterer.Instance.scaledSpaceSunLight.gameObject);
//TODO: fix this if I ever come back to it
GameObject ScaledPlanetShineLight = new GameObject();
GameObject LocalPlanetShineLight = new GameObject();
ScaledPlanetShineLight.GetComponent ().type = LightType.Point;
if (!_aSource.isSun)
ScaledPlanetShineLight.GetComponent ().cookie = planetShineCookieCubeMap;
//ScaledPlanetShineLight.GetComponent().range=1E9f;
ScaledPlanetShineLight.GetComponent ().range = _aSource.scaledRange;
ScaledPlanetShineLight.GetComponent ().color = new Color (_aSource.color.x, _aSource.color.y, _aSource.color.z);
ScaledPlanetShineLight.name = celBody.name + "PlanetShineLight(ScaledSpace)";
LocalPlanetShineLight.GetComponent ().type = LightType.Point;
if (!_aSource.isSun)
LocalPlanetShineLight.GetComponent ().cookie = planetShineCookieCubeMap;
//LocalPlanetShineLight.GetComponent().range=1E9f;
LocalPlanetShineLight.GetComponent ().range = _aSource.scaledRange * ScaledSpace.ScaleFactor;
LocalPlanetShineLight.GetComponent ().color = new Color (_aSource.color.x, _aSource.color.y, _aSource.color.z);
LocalPlanetShineLight.GetComponent ().cullingMask = 557591;
LocalPlanetShineLight.GetComponent ().shadows = LightShadows.Soft;
LocalPlanetShineLight.GetComponent ().shadowCustomResolution = 2048;
LocalPlanetShineLight.name = celBody.name + "PlanetShineLight(LocalSpace)";
aPsLight.scaledLight = ScaledPlanetShineLight;
aPsLight.localLight = LocalPlanetShineLight;
celestialLightSources.Add (aPsLight);
Utils.LogDebug ("Added celestialLightSource " + aPsLight.source.name);
}
}
}
public void UpdatePlanetshine ()
{
foreach (PlanetShineLight _aLight in celestialLightSources)
{
_aLight.updateLight();
}
}
public void Cleanup()
{
foreach (PlanetShineLight _aLight in celestialLightSources)
{
_aLight.OnDestroy();
UnityEngine.Object.Destroy(_aLight);
}
}
}
}
================================================
FILE: scatterer/Effects/Proland/Atmosphere/Godrays/LegacyGodraysRenderer.cs
================================================
using UnityEngine;
using UnityEngine.Rendering;
using System.Collections.Generic;
using System;
namespace Scatterer
{
public class LegacyGodraysRenderer : MonoBehaviour
{
SkyNode parentSkyNode;
Camera targetCamera;
Light targetLight;
ComputeBuffer inverseShadowMatricesBuffer;
ComputeShader inverseShadowMatricesComputeShader;
CommandBuffer shadowVolumeCB;
Material volumeDepthMaterial;
GameObject volumeDepthGO;
public RenderTexture volumeDepthTexture;
// GameObject cloudShadowGO;
// MeshRenderer cloudShadowMR;
// Dictionary> shadowRenderCommandBuffers = new Dictionary> ();
// List> cloudsShadowsMaterials = new List>();
// RenderTexture cloudShadowMap;
// CommandBuffer clearShadowMapCB;
bool commandBufferAdded = false;
public LegacyGodraysRenderer ()
{
}
public bool Init(Light inputLight, SkyNode inputParentSkyNode)
{
if (!SystemInfo.supportsComputeShaders)
{
Utils.LogError("Compute shaders not supported, godrays can't be added");
return false;
}
if (ShaderReplacer.Instance.LoadedComputeShaders.ContainsKey ("ComputeInverseShadowMatrices"))
{
inverseShadowMatricesComputeShader = ShaderReplacer.Instance.LoadedComputeShaders ["ComputeInverseShadowMatrices"];
}
else
{
Utils.LogError("Godrays inverse shadow matrices compute shader can't be found, godrays can't be added");
return false;
}
if (ShaderReplacer.Instance.LoadedShaders.ContainsKey ("Scatterer/VolumeDepth"))
{
volumeDepthMaterial = new Material(ShaderReplacer.Instance.LoadedShaders ["Scatterer/VolumeDepth"]);
}
else
{
Utils.LogError("Godrays depth shader can't be found, godrays can't be added");
return false;
}
if (!inputLight)
{
Utils.LogError("Godrays light is null, godrays can't be added");
return false;
}
targetLight = inputLight;
parentSkyNode = inputParentSkyNode;
Utils.EnableOrDisableShaderKeywords (volumeDepthMaterial, "OCEAN_INTERSECT_ANALYTICAL", "OCEAN_INTERSECT_OFF", parentSkyNode.prolandManager.hasOcean && Scatterer.Instance.mainSettings.useOceanShaders);
volumeDepthMaterial.SetFloat ("Rt", parentSkyNode.Rt);
volumeDepthMaterial.SetFloat ("Rg", parentSkyNode.Rg);
Utils.EnableOrDisableShaderKeywords(volumeDepthMaterial, "CLOUDSMAP_ON", "CLOUDSMAP_OFF", false);
//Utils.EnableOrDisableShaderKeywords(volumeDepthMaterial, "DOWNSCALE_DEPTH_ON", "DOWNSCALE_DEPTH_OFF", Scatterer.Instance.mainSettings.quarterResScattering);
Utils.EnableOrDisableShaderKeywords(volumeDepthMaterial, "DOWNSCALE_DEPTH_ON", "DOWNSCALE_DEPTH_OFF", false);
volumeDepthGO = new GameObject ("GodraysVolumeDepth "+inputParentSkyNode.prolandManager.parentCelestialBody.name);
volumeDepthMaterial.renderQueue = 2999; //for debugging only
volumeDepthGO.layer = 15;
MeshFilter _mf = volumeDepthGO.AddComponent ();
_mf.mesh.Clear ();
_mf.mesh = MeshFactory.MakePlane32BitIndexFormat (512, 512, MeshFactory.PLANE.XY, false, false); //fixed with 32bit indices
//_mf.mesh = MeshFactory.MakePlane16BitIndexFormat (256, 256, MeshFactory.PLANE.XY, false, false); //Definitely need to subdivide more here and in the tesselation check edge length and culling
_mf.mesh.bounds = new Bounds (Vector4.zero, new Vector3 (1e18f, 1e18f, 1e18f)); //apparently mathf.Infinity is bad, remember this
MeshRenderer _mr = volumeDepthGO.AddComponent ();
_mr.material = volumeDepthMaterial;
_mr.receiveShadows = false;
_mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
_mr.enabled = false;
//disabled quarter res because I haven't fixed it for the sky and probably the perf hit from finding nearest depth in sky shader isn't worth it
// if (Scatterer.Instance.mainSettings.quarterResScattering)
// volumeDepthTexture = new RenderTexture (Screen.width / 2, Screen.height / 2, 0, RenderTextureFormat.RHalf);
// else
volumeDepthTexture = new RenderTexture (Screen.width, Screen.height, 0, RenderTextureFormat.RHalf); //seems to work if we divide the contents by 100, to keep under half's 65000 limit
volumeDepthTexture.useMipMap = false;
volumeDepthTexture.antiAliasing = 1;
volumeDepthTexture.filterMode = FilterMode.Point;
volumeDepthTexture.Create ();
// if (Scatterer.Instance.mainSettings.integrateEVECloudsGodrays)
// {
// InitCloudShadowCommandBuffers ();
// }
//world to shadow matrices aren't exposed in the C# api so we can't compute the shadow to world matrices from them
//since they are exposed in shaders we use a compute shader to do it
inverseShadowMatricesBuffer = new ComputeBuffer (4, 16 * sizeof(float));
shadowVolumeCB = new CommandBuffer();
shadowVolumeCB.name = "Scatterer legacy godrays CommandBuffer";
shadowVolumeCB.SetComputeBufferParam (inverseShadowMatricesComputeShader, 0, "resultBuffer", inverseShadowMatricesBuffer);
shadowVolumeCB.DispatchCompute(inverseShadowMatricesComputeShader, 0, 4, 1, 1);
shadowVolumeCB.SetRenderTarget(volumeDepthTexture);
//shadowVolumeCB.ClearRenderTarget(false, true, Color.black, 1f); //do this after rendering
shadowVolumeCB.SetShadowSamplingMode (ShadowMapCopy.RenderTexture, ShadowSamplingMode.RawDepth);
shadowVolumeCB.DrawRenderer (_mr, volumeDepthMaterial);
targetCamera = gameObject.GetComponent ();
return true;
}
// void InitCloudShadowCommandBuffers ()
// {
// if (Scatterer.Instance.eveReflectionHandler.EVEClouds2dDictionary.ContainsKey (parentSkyNode.prolandManager.parentCelestialBody.name))
// {
// foreach (EVEClouds2d clouds2d in Scatterer.Instance.eveReflectionHandler.EVEClouds2dDictionary [parentSkyNode.prolandManager.parentCelestialBody.name])
// {
// if (clouds2d.CloudShadowMaterial != null)
// {
// Material cloudShadowDepthMaterial = new Material (ShaderReplacer.Instance.LoadedShaders ["Scatterer-EVE/CloudShadowMap"]);
// cloudShadowDepthMaterial.CopyKeywordsFrom (clouds2d.CloudShadowMaterial);
// if (cloudShadowGO == null)
// {
// cloudShadowGO = GameObject.CreatePrimitive (PrimitiveType.Sphere);
// GameObject.Destroy (cloudShadowGO.GetComponent ());
// MeshFilter cloudShadowMF = cloudShadowGO.GetComponent ();
// cloudShadowMF.mesh.Clear ();
// cloudShadowMF.mesh = IcoSphere.CreateIcoSphereMesh ();
// cloudShadowMR = cloudShadowGO.GetComponent ();
// cloudShadowGO.transform.parent = parentSkyNode.prolandManager.parentCelestialBody.transform;
// cloudShadowMR.receiveShadows = false;
// cloudShadowMR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
// cloudShadowMR.enabled = false;
//
// cloudShadowMap = new RenderTexture (2048, 2048, 0, RenderTextureFormat.RHalf); //replace size after
// cloudShadowMap.useMipMap = false;
// cloudShadowMap.antiAliasing = 1;
// cloudShadowMap.filterMode = FilterMode.Point;
// cloudShadowMap.Create ();
//
// clearShadowMapCB = new CommandBuffer();
// clearShadowMapCB.SetRenderTarget(cloudShadowMap);
// clearShadowMapCB.ClearRenderTarget(false,true,Color.black);
//
// shadowRenderCommandBuffers[ShadowMapPass.DirectionalCascade0] = new List();
// shadowRenderCommandBuffers[ShadowMapPass.DirectionalCascade0].Add(clearShadowMapCB);
//
// Utils.EnableOrDisableShaderKeywords(volumeDepthMaterial, "CLOUDSMAP_ON", "CLOUDSMAP_OFF", true);
// volumeDepthMaterial.SetTexture("cloudShadowMap", cloudShadowMap);
// }
// RenderObjectInCustomCascade (targetLight, cloudShadowMap, cloudShadowMR, cloudShadowDepthMaterial, ShadowMapPass.DirectionalCascade0, 0f, 0f, 0.5f, 0.5f);
// RenderObjectInCustomCascade (targetLight, cloudShadowMap, cloudShadowMR, cloudShadowDepthMaterial, ShadowMapPass.DirectionalCascade1, 0.5f, 0f, 0.5f, 0.5f);
// RenderObjectInCustomCascade (targetLight, cloudShadowMap, cloudShadowMR, cloudShadowDepthMaterial, ShadowMapPass.DirectionalCascade2, 0f, 0.5f, 0.5f, 0.5f);
// RenderObjectInCustomCascade (targetLight, cloudShadowMap, cloudShadowMR, cloudShadowDepthMaterial, ShadowMapPass.DirectionalCascade3, 0.5f, 0.5f, 0.5f, 0.5f);
//
// cloudsShadowsMaterials.Add (new Tuple (clouds2d, cloudShadowDepthMaterial));
// }
// }
// }
// }
// void RenderObjectInCustomCascade(Light targetLight, RenderTexture rt, MeshRenderer mr, Material mat , ShadowMapPass passMask, float startX, float startY, float width, float height)
// {
// CommandBuffer cloudShadowDepthCB = new CommandBuffer();
// Rect cascadeRect = new Rect ((int)(startX * rt.width), (int)(startY * rt.height), (int)(width * rt.width), (int)(height * rt.height));
//
// cloudShadowDepthCB.SetRenderTarget(rt);
// cloudShadowDepthCB.EnableScissorRect(cascadeRect);
// cloudShadowDepthCB.SetViewport(cascadeRect);
// cloudShadowDepthCB.DrawRenderer(mr, mat);
// cloudShadowDepthCB.DisableScissorRect();
//
// if (shadowRenderCommandBuffers.ContainsKey (passMask))
// {
// shadowRenderCommandBuffers[passMask].Add(cloudShadowDepthCB);
// }
// else
// {
// shadowRenderCommandBuffers[passMask] = new List();
// shadowRenderCommandBuffers[passMask].Add(cloudShadowDepthCB);
// }
// }
public void EnableRenderingForFrame()
{
if (!commandBufferAdded)
{
ShadowMapCopier.RequestShadowMapCopy(targetLight);
targetCamera.AddCommandBuffer (CameraEvent.BeforeForwardOpaque, shadowVolumeCB);
// foreach (ShadowMapPass pass in shadowRenderCommandBuffers.Keys)
// {
// foreach (CommandBuffer cb in shadowRenderCommandBuffers[pass])
// {
// targetLight.AddCommandBuffer (LightEvent.AfterShadowMapPass, cb, pass);
// }
// }
commandBufferAdded = true;
}
}
public void RenderingDone()
{
if (commandBufferAdded && targetCamera.stereoActiveEye != Camera.MonoOrStereoscopicEye.Left)
{
targetCamera.RemoveCommandBuffer (CameraEvent.BeforeForwardOpaque, shadowVolumeCB);
// foreach (ShadowMapPass pass in shadowRenderCommandBuffers.Keys) {
// foreach (CommandBuffer cb in shadowRenderCommandBuffers[pass]) {
// targetLight.RemoveCommandBuffer (LightEvent.AfterShadowMapPass, cb);
// }
// }
RenderTexture rt=RenderTexture.active;
RenderTexture.active= volumeDepthTexture;
GL.Clear(false,true,Color.black, 1f);
RenderTexture.active=rt;
commandBufferAdded = false;
}
}
void OnPreCull()
{
if (parentSkyNode && !parentSkyNode.inScaledSpace)
{
EnableRenderingForFrame();
volumeDepthMaterial.SetMatrix(ShaderProperties.CameraToWorld_PROPERTY, targetCamera.cameraToWorldMatrix);
volumeDepthMaterial.SetTexture(ShaderProperties._ShadowMapTextureCopyScatterer_PROPERTY, ShadowMapCopy.RenderTexture);
volumeDepthMaterial.SetBuffer("inverseShadowMatricesBuffer", inverseShadowMatricesBuffer);
//Calculate light's bounding Box englobing camera's frustum up to the shadows distance
//The idea is to create a "projector" from the light's PoV, which is essentially a bounding box cover the whole range from near clip plance to the shadows, so we can project into the scene
Vector3 lightDirForward = targetLight.transform.forward.normalized;
Vector3 lightDirRight = targetLight.transform.right.normalized;
Vector3 lightDirUp = targetLight.transform.up.normalized;
Vector3[] frustumCornersNear = new Vector3[4];
Vector3[] frustumCornersFar = new Vector3[4];
//the corners appear to be in camera Space even though the documentation says in world Space
targetCamera.CalculateFrustumCorners(new Rect(0, 0, 1, 1), targetCamera.nearClipPlane, Camera.MonoOrStereoscopicEye.Mono, frustumCornersNear);
targetCamera.CalculateFrustumCorners(new Rect(0, 0, 1, 1), QualitySettings.shadowDistance, Camera.MonoOrStereoscopicEye.Mono, frustumCornersFar);
//Kopernicus lights have the same position as their suns, so they are impossibly far, replace their position with something closer to get a useable matrix
Matrix4x4 worldToLocalMatrix = parentSkyNode.prolandManager.mainSunLight.transform.worldToLocalMatrix;
worldToLocalMatrix.m03 = Scatterer.Instance.nearCamera.transform.position.x;
worldToLocalMatrix.m13 = Scatterer.Instance.nearCamera.transform.position.y;
worldToLocalMatrix.m23 = Scatterer.Instance.nearCamera.transform.position.z;
//now, calculate the corners positions in light Space
List frustumCornersInLightSpace = new List();
foreach(Vector3 corner in frustumCornersNear)
{
frustumCornersInLightSpace.Add(worldToLocalMatrix.MultiplyPoint(targetCamera.transform.localToWorldMatrix.MultiplyPoint(corner)));
}
foreach(Vector3 corner in frustumCornersFar)
{
frustumCornersInLightSpace.Add(worldToLocalMatrix.MultiplyPoint(targetCamera.transform.localToWorldMatrix.MultiplyPoint(corner)));
}
Bounds bounds = GeometryUtility.CalculateBounds(frustumCornersInLightSpace.ToArray(), Matrix4x4.identity);
//Create an orthogonal projection matrix from the bounding box
Matrix4x4 shadowProjectionMatrix = Matrix4x4.Ortho(
bounds.center.x-bounds.extents.x,
bounds.center.x+bounds.extents.x,
bounds.center.y-bounds.extents.y,
bounds.center.y+bounds.extents.y,
bounds.center.z-bounds.extents.z,
bounds.center.z+bounds.extents.z);
shadowProjectionMatrix = GL.GetGPUProjectionMatrix(shadowProjectionMatrix, false);
//Transformation from world into our "shadow space" matrix
Matrix4x4 VP = shadowProjectionMatrix * worldToLocalMatrix;
//And inverse transformation from "shadow space" into world used to create our mesh
Matrix4x4 lightToWorld = VP.inverse;
volumeDepthMaterial.SetMatrix(ShaderProperties.lightToWorld_PROPERTY, lightToWorld);
volumeDepthMaterial.SetVector(ShaderProperties.lightDirection_PROPERTY, targetLight.transform.forward);
volumeDepthMaterial.SetVector (ShaderProperties._planetPos_PROPERTY, parentSkyNode.parentLocalTransform.position);
// foreach(Tuple tuple in cloudsShadowsMaterials)
// {
// tuple.Item2.CopyPropertiesFromMaterial(tuple.Item1.CloudShadowMaterial);
// tuple.Item2.SetVector(ShaderProperties.lightDirection_PROPERTY, targetLight.transform.forward);
// tuple.Item2.SetFloat(ShaderProperties._godrayCloudThreshold_PROPERTY, parentSkyNode.godrayCloudAlphaThreshold);
// }
}
}
public void OnPostRender()
{
if (parentSkyNode)
{
RenderingDone ();
}
}
public void OnDestroy()
{
RenderingDone ();
if (inverseShadowMatricesBuffer != null)
{
inverseShadowMatricesBuffer.Dispose();
}
if (volumeDepthTexture)
{
volumeDepthTexture.Release();
}
if (volumeDepthGO)
{
DestroyImmediate(volumeDepthGO);
}
// if (cloudShadowGO)
// {
// DestroyImmediate(cloudShadowGO);
// }
}
}
}
================================================
FILE: scatterer/Effects/Proland/Atmosphere/Preprocessing/AtmoPreprocessor.cs
================================================
/*
* Proland: a procedural landscape rendering library.
* Copyright (c) 2008-2011 INRIA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Proland is distributed under a dual-license scheme.
* You can obtain a specific license from Inria: proland-licensing@inria.fr.
*
* Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat.
* Modified and ported to Unity by Justin Hawkins 2014
* Modified and adapted for use with Kerbal Space Program by Ghassen Lahmar 2015-2022
*
*/
using UnityEngine;
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Collections;
using System.Diagnostics;
namespace Scatterer
{
[KSPAddon(KSPAddon.Startup.Instantly, true)]
public class AtmoPreprocessor : MonoBehaviour
{
private static AtmoPreprocessor instance;
public void Awake()
{
if (instance == null)
{
instance = this;
instance.InitMaterials();
Utils.LogDebug("AtmoPreprocessor instance created");
}
else
{
throw new UnityException("Attempted double instance!");
}
}
public static AtmoPreprocessor Instance
{
get
{
return instance;
}
}
public void Start()
{
DontDestroyOnLoad(this);
}
private static bool atmoGenerationRunning = false;
public static Vector4 ScatteringLutDimensionsDefault { get => Scatterer.Instance.mainSettings.useLowResolutionAtmosphere ? scatteringLutDimensionsPreview : scatteringLutDimensionsDefault; }
const int READ = 0; const int WRITE = 1;
float Rg = 60000.0f;
float Rt = 71500.603f;
//Dimensions of the tables
const int TRANSMITTANCE_W = 512;
const int TRANSMITTANCE_H = 128;
const int SKY_W = 64;
const int SKY_H = 16;
private static Vector4 scatteringLutDimensionsDefault = new Vector4(32f, 128f, 32f, 16f); //the one from yusov, double the current one so should be 16 megs in half precision
public static Vector4 scatteringLutDimensionsPreview = new Vector4(16f, 64f, 16f, 2f); //fast preview version, 32x smaller
private static int xTilesDefault = 32, yTilesDefault = 64;
private static int xTilesPreview = 32, yTilesPreview = 16;
Vector4 scatteringLutDimensions = ScatteringLutDimensionsDefault;
int xTiles = xTilesDefault, yTiles = yTilesDefault;
float AVERAGE_GROUND_REFLECTANCE = 0.1f;
Vector4 BETA_R = new Vector4(5.8e-3f, 1.35e-2f, 3.31e-2f, 0.0f);
Vector4 BETA_MSca = new Vector4(4e-3f, 4e-3f, 4e-3f, 0.0f);
float MIE_G = 0.8f;
float HR = 8000.0f;
float HM = 1200.0f;
Vector3 ozoneAbsorption = new Vector3(0.0000003426f, 0.0000008298f, 0.000000036f);
float ozoneHeight = 25000f;
float ozoneFalloff = 15000f;
RenderTexture ozoneTransmittanceRT;
RenderTexture deltaET, deltaSRT, deltaSMT, deltaJT;
public RenderTexture[] irradianceT, inscatterT;
Material transmittanceMaterial, ozoneTransmittanceMaterial, irradianceNMaterial, irradiance1Material, inscatter1Material,
inscatterNMaterial, inscatterSMaterial, copyInscatter1Material, copyInscatterNMaterial, copyIrradianceMaterial, atlasMaterial;
int scatteringOrders = 4; //min is 2 unless you skip that step
bool multipleScattering = true;
bool useOzone = false;
// Process in chunks and return if we spend more time than this
// Otherwise windows thinks the GPU crashed on slower hardware
// https://en.wikipedia.org/wiki/Timeout_Detection_and_Recovery
long generationMsThreshold = 1000;
private void InitMaterials()
{
transmittanceMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/Transmittance")]);
ozoneTransmittanceMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/OzoneTransmittance")]);
irradianceNMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/IrradianceN")]);
irradiance1Material = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/Irradiance1")]);
inscatter1Material = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/Inscatter1")]);
inscatterNMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/InscatterN")]);
inscatterSMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/InscatterS")]);
copyInscatter1Material = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/CopyInscatter1")]);
copyInscatterNMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/CopyInscatterN")]);
copyIrradianceMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/CopyIrradiance")]);
atlasMaterial = new Material(ShaderReplacer.Instance.LoadedShaders[("Scatterer/Preprocessing/Atlas")]);
}
public static float CalculateRt(float inRg, float inHR, float inHM, Vector3 in_betaR, Vector3 in_BETA_MSca, bool useOzone, float ozoneHeight, float ozoneFalloff)
{
float RtHR = - 1000f * inHR * Mathf.Log(0.0000001f / in_betaR.magnitude);
float RtHM = - 1000f * inHM * Mathf.Log(0.0000001f / in_BETA_MSca.magnitude);
float maxHeight = Mathf.Max(RtHR, RtHM);
if (useOzone) maxHeight = Mathf.Max(maxHeight, 1000f * (ozoneHeight + ozoneFalloff));
return inRg + maxHeight;
}
public static void DeleteCache()
{
string cachePath = Utils.GameDataPath + "/ScattererAtmosphereCache/PluginData";
Directory.Delete(cachePath, true);
}
[StructLayout(LayoutKind.Sequential)]
struct AtmoHashData
{
public float Rg;
public float Rt;
public float AVERAGE_GROUND_REFLECTANCE;
public Vector4 BETA_R;
public Vector4 BETA_MSca;
public Vector4 ScatteringLutDimensions;
public float MIE_G;
public float HR;
public float HM;
public Vector3 ozoneAbsorption;
public float ozoneHeight;
public float ozoneFalloff;
public bool useOzone;
public bool useMultipleScattering;
public AtmoHashData(float rg, float rt, float averageGroundReflectance, Vector4 betaR, Vector4 betaMSca, Vector4 scatteringLutDimensions, float mieG, float hr,float hm,Vector3 ozoneAbsorption,float ozoneHeight,float ozoneFalloff,bool useOzone,bool useMultipleScattering)
{
Rg = rg;
Rt = rt;
AVERAGE_GROUND_REFLECTANCE = averageGroundReflectance;
BETA_R = betaR;
BETA_MSca = betaMSca;
ScatteringLutDimensions = scatteringLutDimensions;
MIE_G = mieG;
HR = hr;
HM = hm;
this.ozoneAbsorption = ozoneAbsorption;
this.ozoneHeight = ozoneHeight;
this.ozoneFalloff = ozoneFalloff;
this.useOzone = useOzone;
this.useMultipleScattering = useMultipleScattering;
}
}
public static string GetAtmoHash(float inRG, float inRT, Vector4 inBETA_R, Vector4 inBETA_MSca, float inMIE_G, float inHR, float inHM, float inAverageGroundRreflectance, bool inMultiple, Vector4 inPRECOMPUTED_SCTR_LUT_DIM, bool inUseOzone, Vector4 inOzoneAbsorption, float inOzoneHeight, float inOzoneFalloff)
{
AtmoHashData atmoHashData = new AtmoHashData(
inRG,
inRT,
inAverageGroundRreflectance,
inBETA_R,
inBETA_MSca,
inPRECOMPUTED_SCTR_LUT_DIM,
inMIE_G,
inHR,
inHM,
inUseOzone ? inOzoneAbsorption : Vector4.zero,
inUseOzone ? inOzoneHeight : 0f,
inUseOzone ? inOzoneFalloff : 0f,
inUseOzone,
inMultiple
);
Hash128 result = new Hash128();
HashUtilities.ComputeHash128(ref atmoHashData, ref result);
return result.ToString();
}
public static void Generate(float inRG, float inRT, Vector4 inBETA_R, Vector4 inBETA_MSca, float inMIE_G, float inHR, float inHM, float inGRref, bool inMultiple, Vector4 inScatteringLutDimensions, bool previewMode, string assetPath, bool inUseOzone, Vector4 inOzoneAbsorption, float inOzoneHeight, float inOzoneFalloff, string bodyName)
{
if (!atmoGenerationRunning)
{
Utils.LogInfo("Generating new atmosphere for "+bodyName);
instance.StartCoroutine(instance.GenerateAndSaveAtmoCoroutine(inRG, inRT, inBETA_R, inBETA_MSca, inMIE_G, inHR, inHM, inGRref, inMultiple, inScatteringLutDimensions, previewMode, assetPath, inUseOzone, inOzoneAbsorption, inOzoneHeight, inOzoneFalloff));
}
}
IEnumerator GenerateAndSaveAtmoCoroutine(float inRG, float inRT, Vector4 inBETA_R, Vector4 inBETA_MSca, float inMIE_G, float inHR, float inHM, float inGRref, bool inMultiple, Vector4 inScatteringLutDimensions, bool previewMode, string assetPath, bool inUseOzone, Vector4 inOzoneAbsorption, float inOzoneHeight, float inOzoneFalloff)
{
atmoGenerationRunning = true;
//Rescale to a fixed radius which we know never causes issues
float referenceRadius = 1000000f;
float scaleFactor = referenceRadius / inRG;
Rg = referenceRadius;
Rt = inRT * scaleFactor;
HR = inHR * 1000f * scaleFactor;
HM = inHM * 1000f * scaleFactor;
BETA_R = inBETA_R * 0.001f / scaleFactor;
BETA_MSca = inBETA_MSca * 0.001f / scaleFactor;
MIE_G = inMIE_G;
if (inMultiple)
MIE_G = Mathf.Min (MIE_G, 0.86f); //values of mie_G > 0.86 seem to break multiple scattering for some weird reason
AVERAGE_GROUND_REFLECTANCE = inGRref;
multipleScattering = inMultiple;
scatteringLutDimensions = inScatteringLutDimensions;
useOzone = inUseOzone;
ozoneAbsorption = inOzoneAbsorption * 0.001f / scaleFactor;
if (!useOzone) ozoneAbsorption = Vector4.zero;
ozoneHeight = inOzoneHeight * 1000f * scaleFactor;
ozoneFalloff = inOzoneFalloff * 1000f* scaleFactor;
if (previewMode || Scatterer.Instance.mainSettings.useLowResolutionAtmosphere)
{
xTiles = xTilesPreview; yTiles = yTilesPreview;
}
else
{
xTiles = xTilesDefault; yTiles = yTilesDefault;
}
irradianceT = new RenderTexture[2];
inscatterT = new RenderTexture[2];
ozoneTransmittanceRT = new RenderTexture(TRANSMITTANCE_W, TRANSMITTANCE_H, 0, RenderTextureFormat.ARGBFloat);
ozoneTransmittanceRT.wrapMode = TextureWrapMode.Clamp;
ozoneTransmittanceRT.filterMode = FilterMode.Bilinear;
ozoneTransmittanceRT.Create();
irradianceT[0] = new RenderTexture(SKY_W, SKY_H, 0, RenderTextureFormat.ARGBFloat);
irradianceT[0].wrapMode = TextureWrapMode.Clamp;
irradianceT[0].filterMode = FilterMode.Bilinear;
irradianceT[0].Create();
irradianceT[1] = new RenderTexture(SKY_W, SKY_H, 0, RenderTextureFormat.ARGBFloat);
irradianceT[1].wrapMode = TextureWrapMode.Clamp;
irradianceT[1].filterMode = FilterMode.Bilinear;
irradianceT[1].Create();
deltaET = new RenderTexture(SKY_W, SKY_H, 0, RenderTextureFormat.ARGBFloat);
deltaET.Create();
inscatterT[0] = new RenderTexture((int)(scatteringLutDimensions.x * scatteringLutDimensions.y), (int)(scatteringLutDimensions.z * scatteringLutDimensions.w), 0, RenderTextureFormat.ARGBFloat);
inscatterT[0].wrapMode = TextureWrapMode.Clamp;
inscatterT[0].filterMode = FilterMode.Bilinear;
inscatterT[0].Create();
inscatterT[1] = new RenderTexture((int)(scatteringLutDimensions.x * scatteringLutDimensions.y), (int)(scatteringLutDimensions.z * scatteringLutDimensions.w), 0, RenderTextureFormat.ARGBFloat);
inscatterT[1].wrapMode = TextureWrapMode.Clamp;
inscatterT[1].filterMode = FilterMode.Bilinear;
inscatterT[1].Create();
deltaSRT = new RenderTexture((int)(scatteringLutDimensions.x * scatteringLutDimensions.y), (int)(scatteringLutDimensions.z * scatteringLutDimensions.w), 0, RenderTextureFormat.ARGBFloat);
deltaSRT.wrapMode = TextureWrapMode.Clamp;
deltaSRT.filterMode = FilterMode.Bilinear;
deltaSRT.Create();
deltaSMT = new RenderTexture((int)(scatteringLutDimensions.x * scatteringLutDimensions.y), (int)(scatteringLutDimensions.z * scatteringLutDimensions.w), 0, RenderTextureFormat.ARGBFloat);
deltaSMT.wrapMode = TextureWrapMode.Clamp;
deltaSMT.filterMode = FilterMode.Bilinear;
deltaSMT.Create();
deltaJT = new RenderTexture((int)(scatteringLutDimensions.x * scatteringLutDimensions.y), (int)(scatteringLutDimensions.z * scatteringLutDimensions.w), 0, RenderTextureFormat.ARGBFloat);
deltaJT.wrapMode = TextureWrapMode.Clamp;
deltaJT.filterMode = FilterMode.Bilinear;
deltaJT.Create();
SetParameters(ozoneTransmittanceMaterial);
SetParameters(transmittanceMaterial);
SetParameters(irradianceNMaterial);
SetParameters(irradiance1Material);
SetParameters(inscatter1Material);
SetParameters(inscatterNMaterial);
SetParameters(inscatterSMaterial);
SetParameters(copyInscatter1Material);
SetParameters(copyInscatterNMaterial);
SetParameters(copyIrradianceMaterial);
RTUtility.ClearColor(irradianceT);
yield return Preprocess(assetPath);
ReleaseTextures();
atmoGenerationRunning = false;
}
void SetParameters(Material mat)
{
mat.SetFloat("Rg", Rg);
mat.SetFloat("Rt", Rt);
mat.SetInt("TRANSMITTANCE_W", TRANSMITTANCE_W);
mat.SetInt("TRANSMITTANCE_H", TRANSMITTANCE_H);
mat.SetInt("SKY_W", SKY_W);
mat.SetInt("SKY_H", SKY_H);
mat.SetFloat("AVERAGE_GROUND_REFLECTANCE", AVERAGE_GROUND_REFLECTANCE);
mat.SetFloat("HR", HR);
mat.SetFloat("HM", HM);
mat.SetVector("betaR", BETA_R);
mat.SetVector("betaMSca", BETA_MSca);
mat.SetVector("betaMEx", BETA_MSca / 0.9f);
mat.SetFloat("mieG", Mathf.Clamp(MIE_G, 0.0f, 0.99f));
mat.SetFloat ("Sun_intensity", 10f);
mat.SetVector("PRECOMPUTED_SCTR_LUT_DIM", scatteringLutDimensions);
mat.SetVector ("tiles", new Vector2 (xTiles, yTiles));
mat.SetFloat("ozoneHeight", ozoneHeight);
mat.SetFloat("ozoneFalloff", ozoneFalloff);
mat.SetVector("ozoneAbsorption", new Vector4(ozoneAbsorption.x, ozoneAbsorption.y, ozoneAbsorption.z, 0.0f));
}
IEnumerator Preprocess(string assetPath)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
ComputeTransmittance();
ComputeIrradiance();
yield return ComputeInscatter1(stopwatch);
CopyIrradiance();
yield return CopyInscatter1(stopwatch);
for (int scatteringOrder = 2; scatteringOrder <= (multipleScattering ? scatteringOrders : 2); scatteringOrder++)
{
yield return ComputeInscatterS(2, stopwatch); // is this a mistake? should it be scatteringOrder instead of 2?
ComputeIrradianceN(2);
yield return ComputeInscatterN(stopwatch);
CopyIrradianceK1();
if (multipleScattering)
{
yield return CopyInscatterN(stopwatch);
}
}
if (!Directory.Exists(assetPath))
Directory.CreateDirectory(assetPath);
var atmosphereAtlas = PackTextures(new RenderTexture[] { inscatterT[READ], irradianceT[READ], ozoneTransmittanceRT });
SaveAsHalf(atmosphereAtlas, assetPath + "/atlas");
atmosphereAtlas.Release();
Utils.LogInfo("Atmo generation successful");
}
private RenderTexture PackTextures(RenderTexture[] textures)
{
// Just do the simplest packing possible, top-left to bottom-left
int width = textures.Max(texture => texture.width);
int height = textures.Sum(texture => texture.height);
RenderTexture rt = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat, 0);
rt.wrapMode = TextureWrapMode.Clamp;
rt.Create();
atlasMaterial.SetInt("targetWidth", width);
atlasMaterial.SetInt("targetHeight", height);
int currentHeight = 0;
for (int i = 0; i < textures.Length; i++)
{
var texture = textures[i];
atlasMaterial.SetTexture("inputTexture", texture);
atlasMaterial.SetInt("width", texture.width);
atlasMaterial.SetInt("height", texture.height);
atlasMaterial.SetInt("horizontalOffset", 0);
atlasMaterial.SetInt("verticalOffset", currentHeight);
Graphics.Blit(null, rt, atlasMaterial);
currentHeight += texture.height;
}
return rt;
}
public static List GetPackedTexturesScaleAndOffsets(List dimensions, Vector2 atlasDimensions)
{
var result = new List();
float currentHeight = 0;
foreach(Vector2 dimension in dimensions)
{
Vector2 currentScale = new Vector2(dimension.x / atlasDimensions.x, dimension.y / atlasDimensions.y);
Vector2 currentOffset = new Vector2(0f, currentHeight / atlasDimensions.y);
result.Add(new Vector4(currentScale.x, currentScale.y, currentOffset.x, currentOffset.y));
currentHeight += dimension.y;
}
return result;
}
IEnumerator CopyInscatterN(Stopwatch stopwatch)
{
// adds deltaS into inscatter texture S(line 11 in algorithm 4.1)
yield return ProcessInTiles(stopwatch, (int i, int j) =>
{
copyInscatterNMaterial.SetVector("currentTile", new Vector2(i, j));
copyInscatterNMaterial.SetTexture("deltaSRead", deltaSRT);
copyInscatterNMaterial.SetTexture("inscatterRead", inscatterT[READ]);
Graphics.Blit(null, inscatterT[WRITE], copyInscatterNMaterial, 0);
});
RTUtility.Swap(inscatterT);
}
private void CopyIrradianceK1()
{
// adds deltaE into irradiance texture E (line 10 in algorithm 4.1)
copyIrradianceMaterial.SetFloat("k", 1.0f);
copyIrradianceMaterial.SetTexture("deltaERead", deltaET);
copyIrradianceMaterial.SetTexture("irradianceRead", irradianceT[READ]);
Graphics.Blit(null, irradianceT[WRITE], copyIrradianceMaterial);
RTUtility.Swap(irradianceT);
}
IEnumerator ComputeInscatterN(Stopwatch stopwatch)
{
// computes deltaS (line 9 in algorithm 4.1)
yield return ProcessInTiles(stopwatch, (int i, int j) =>
{
inscatterNMaterial.SetVector("currentTile", new Vector2(i, j));
inscatterNMaterial.SetTexture("transmittanceRead", ozoneTransmittanceRT);
inscatterNMaterial.SetTexture("deltaJRead", deltaJT);
inscatterNMaterial.SetTexture("deltaJReadSampler", deltaJT);
Graphics.Blit(null, deltaSRT, inscatterNMaterial, 0);
});
}
IEnumerator ComputeInscatterS(int scatteringOrder, Stopwatch stopwatch)
{
yield return ProcessInTiles(stopwatch, (int i, int j) =>
{
inscatterSMaterial.SetVector("currentTile", new Vector2(i, j));
inscatterSMaterial.SetInt("first", (scatteringOrder == 2) ? 1 : 0);
inscatterSMaterial.SetTexture("transmittanceRead", ozoneTransmittanceRT);
inscatterSMaterial.SetTexture("deltaERead", deltaET);
inscatterSMaterial.SetTexture("deltaSRRead", deltaSRT);
inscatterSMaterial.SetTexture("deltaSMRead", deltaSMT);
inscatterSMaterial.SetTexture("deltaSRReadSampler", deltaSRT);
inscatterSMaterial.SetTexture("deltaSMReadSampler", deltaSMT);
Graphics.Blit(null, deltaJT, inscatterSMaterial, 0);
});
}
private void ComputeIrradianceN(int scatteringOrder)
{
// computes deltaE (line 8 in algorithm 4.1)
irradianceNMaterial.SetInt("first", (scatteringOrder == 2) ? 1 : 0);
irradianceNMaterial.SetTexture("deltaSRRead", deltaSRT);
irradianceNMaterial.SetTexture("deltaSMRead", deltaSMT);
irradianceNMaterial.SetTexture("deltaSRReadSampler", deltaSRT);
irradianceNMaterial.SetTexture("deltaSMReadSampler", deltaSMT);
Graphics.Blit(null, deltaET, irradianceNMaterial);
}
IEnumerator CopyInscatter1(Stopwatch stopwatch)
{
// copies deltaS into inscatter texture S (line 5 in algorithm 4.1)
yield return ProcessInTiles(stopwatch, (int i, int j) =>
{
copyInscatter1Material.SetVector("currentTile", new Vector2(i, j));
copyInscatter1Material.SetTexture("deltaSRRead", deltaSRT);
copyInscatter1Material.SetTexture("deltaSMRead", deltaSMT);
Graphics.Blit(null, inscatterT[WRITE], copyInscatter1Material, 0);
});
RTUtility.Swap(inscatterT);
}
private void CopyIrradiance()
{
copyIrradianceMaterial.SetFloat("k", 0.0f);
copyIrradianceMaterial.SetTexture("deltaERead", deltaET);
copyIrradianceMaterial.SetTexture("irradianceRead", irradianceT[READ]);
Graphics.Blit(null, irradianceT[WRITE], copyIrradianceMaterial, 0);
RTUtility.Swap(irradianceT);
}
IEnumerator ComputeInscatter1(Stopwatch stopwatch)
{
// computes single scattering texture deltaS (line 3 in algorithm 4.1)
// Rayleigh and Mie separated in deltaSR + deltaSM
inscatter1Material.SetTexture("transmittanceRead", ozoneTransmittanceRT);
yield return ProcessInTiles(stopwatch, (int i, int j) =>
{
inscatter1Material.SetVector("currentTile", new Vector2(i, j));
Graphics.Blit(null, deltaSRT, inscatter1Material, 0); // rayleigh pass
Graphics.Blit(null, deltaSMT, inscatter1Material, 1); // mie pass
});
}
private void ComputeIrradiance()
{
// computes irradiance texture deltaE (line 2 in algorithm 4.1)
irradiance1Material.SetTexture("transmittanceRead", ozoneTransmittanceRT);
Graphics.Blit(null, deltaET, irradiance1Material);
}
private void ComputeTransmittance()
{
Graphics.Blit(null, ozoneTransmittanceRT, ozoneTransmittanceMaterial);
}
//Process in tiles because older GPUs (series 7xx and integrated hd 3xxx) crash when rendering the full res
IEnumerator ProcessInTiles(Stopwatch stopwatch, Action process)
{
for (int i = 0; i < xTiles; i++)
{
for (int j = 0; j < yTiles; j++)
{
process(i, j);
}
if (stopwatch.ElapsedMilliseconds > generationMsThreshold) { yield return new WaitForFixedUpdate(); stopwatch.Restart(); }
}
}
public void OnDestroy()
{
ReleaseTextures();
}
void ReleaseTextures()
{
ozoneTransmittanceRT.Release();
irradianceT[0].Release();
irradianceT[1].Release();
inscatterT[0].Release();
inscatterT[1].Release();
deltaET.Release();
deltaSRT.Release();
deltaSMT.Release();
deltaJT.Release();
}
void SaveAsHalf(RenderTexture rtex, string fileName)
{
Texture2D temp = new Texture2D(rtex.width, rtex.height, TextureFormat.RGBAHalf, false, false);
RenderTexture.active = rtex;
temp.ReadPixels (new Rect (0, 0, rtex.width, rtex.height), 0, 0);
temp.Apply ();
byte[] byteArray = temp.GetRawTextureData();
System.IO.File.WriteAllBytes(fileName + ".half", byteArray);
}
}
}
================================================
FILE: scatterer/Effects/Proland/Atmosphere/SkyNode.cs
================================================
using UnityEngine;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using KSP.IO;
namespace Scatterer
{
public class SkyNode: MonoBehaviour
{
[Persistent] protected string name;
public float Rg; //The radius of the planet
public float Rt; //Radius of the atmosphere, calculated automatically from HR and HM and the scattering factors
[Persistent] public float atmosphereStartRadiusScale = 1f;
[Persistent] public float HR = 8.0f; //Half heights for the atmosphere air density (HR) and particle density (HM), this is the height in km that half the particles are found below
[Persistent] public float HM = 1.2f;
[Persistent] public Vector3 m_betaR = new Vector3 (5.8e-3f, 1.35e-2f, 3.31e-2f);
[Persistent] public Vector3 BETA_MSca = new Vector3 (4e-3f, 4e-3f, 4e-3f); //scatter coefficient for mie
[Persistent] public float m_mieG = 0.85f; //Asymmetry factor for the mie phase function, a higher number means more light is scattered in the forward direction
[Persistent] public Vector3 ozoneAbsorption = new Vector3(0.0003426f, 0.0008298f, 0.000036f); // From Physically Based Sky, Atmosphere & Cloud Rendering in Frostbite (2016), these look better than other coefficients I found in the literature
[Persistent] public float ozoneHeight = 25f; // Ozone density is highest at ozoneHeight(km) and decreases linearly away from that altitude until ozoneFalloff(km), as per Bruneton (2017)
[Persistent] public float ozoneFalloff = 15f; // profile from http://www.kln.ac.lk/science/Chemistry/Teaching_Resources/
[Persistent] public bool useOzone = false;
[Persistent] public float averageGroundReflectance = 0.1f;
[Persistent] public bool multipleScattering = true;
public bool previewMode = false;
public float mainMenuScaleFactor = 1f;
[Persistent] public float godrayStrength = 0.8f;
[Persistent] public float flattenScaledSpaceMesh = 0f;
[Persistent] public float rimBlend = 20f;
[Persistent] public float rimpower = 600f;
[Persistent] public float specR = 0f;
[Persistent] public float specG = 0f;
[Persistent] public float specB = 0f;
[Persistent] public float shininess = 0f;
[Persistent] public float noonSunlightExtinctionStrength = 1f;
[Persistent] public float cloudColorMultiplier=3f;
[Persistent] public float cloudScatteringMultiplier=0.2f;
[Persistent] public float cloudSkyIrradianceMultiplier=0.05f;
[Persistent] public float volumetricsColorMultiplier = 1f;
[Persistent] public bool EVEIntegration_preserveCloudColors = false;
// [Persistent] public float godrayCloudAlphaThreshold = 0.25f;
[Persistent] public List < ConfigPoint > configPoints = new List < ConfigPoint > ();
[Persistent] public bool adjustScaledTexture = false;
[Persistent] public float scaledLandBrightnessAdjust = 1f;
[Persistent] public float scaledLandContrastAdjust = 1f;
[Persistent] public float scaledLandSaturationAdjust = 1f;
[Persistent] public float scaledOceanBrightnessAdjust = 1f;
[Persistent] public float scaledOceanContrastAdjust = 1f;
[Persistent] public float scaledOceanSaturationAdjust = 1f;
//Texture2D m_inscatter, m_irradiance, m_ozoneTransmittance = Texture2D.whiteTexture;
Texture2D atmosphereAtlas; // Combine all the lookup tables to save texture slots on Mac
Vector2 atlasDimensions;
List atlasScaleAndOffsets = new List { Vector4.zero, Vector4.zero, Vector4.zero, Vector4.zero};
//Dimensions of the tables
const int TRANSMITTANCE_W = 512;
const int TRANSMITTANCE_H = 128;
Vector2 transmittanceTableDimensions = new Vector2(TRANSMITTANCE_W, TRANSMITTANCE_H);
const int SKY_W = 64;
const int SKY_H = 16;
Vector4 scatteringLutDimensions = AtmoPreprocessor.ScatteringLutDimensionsDefault;
string celestialBodyName;
public Transform parentScaledTransform, parentLocalTransform;
public ProlandManager prolandManager;
public UrlDir.UrlConfig configUrl;
public bool isConfigModuleManagerPatch = true;
public bool usesCloudIntegration = true;
public float altitude;
public float percentage;
public int currentConfigPoint;
public ConfigPoint interpolatedSettings= new ConfigPoint();
public bool inScaledSpace = true, simulateOceanInteraction=false;
Vector3 sunPosRelPlanet=Vector3.zero;
Matrix4x4 castersMatrix1=Matrix4x4.zero;
Matrix4x4 castersMatrix2=Matrix4x4.zero;
SkySphereContainer skySphere;
GameObject stockSkyGameObject;
MeshRenderer stockScaledPlanetMeshRenderer;
Mesh originalScaledMesh, tweakedScaledmesh;
public ScaledScatteringContainer scaledScatteringContainer;
public Material localScatteringMaterial, skyMaterial, scaledScatteringMaterial, sunflareExtinctionMaterial, scaledEclipseMaterial;
public GenericLocalAtmosphereContainer localScatteringContainer;
public LegacyGodraysRenderer legacyGodraysRenderer;
public bool postprocessingEnabled = true;
GameObject ringObject;
float ringInnerRadius, ringOuterRadius;
Texture2D ringTexture;
bool hasRingObjectAndShadowActivated = false;
bool skyNodeInitiated = false;
bool precomputedAtmoLoaded = false;
bool atmosphereShadersInitiated = false;
public bool useEclipses = false;
Texture2D originalPlanetTexture;
RenderTexture adjustedPlanetTexture;
public void Init ()
{
InitOrRequestPrecomputedAtmo ();
skyMaterial = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/SkySphere")]);
scaledScatteringMaterial = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/ScaledPlanetScattering")]);
localScatteringMaterial = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/DepthBufferScattering")]);
skyMaterial.SetOverrideTag ("IgnoreProjector", "True");
scaledScatteringMaterial.SetOverrideTag ("IgnoreProjector", "True");
localScatteringMaterial.SetOverrideTag ("IgnoreProjector", "True");
useEclipses = Scatterer.Instance.mainSettings.useEclipses && (prolandManager.eclipseCasters.Count > 0) && HighLogic.LoadedScene != GameScenes.MAINMENU ; //disable bugged eclipses on main menu
Utils.EnableOrDisableShaderKeywords (localScatteringMaterial, "ECLIPSES_ON", "ECLIPSES_OFF", useEclipses);
Utils.EnableOrDisableShaderKeywords (localScatteringMaterial, "DISABLE_UNDERWATER_ON", "DISABLE_UNDERWATER_OFF", prolandManager.hasOcean);
if (Scatterer.Instance.mainSettings.useLegacyTerrainGodrays && Scatterer.Instance.unifiedCameraMode && prolandManager.parentCelestialBody.pqsController
&& Scatterer.Instance.mainSettings.terrainShadows && (Scatterer.Instance.mainSettings.unifiedCamShadowResolutionOverride != 0))
{
legacyGodraysRenderer = (LegacyGodraysRenderer)Utils.getEarliestLocalCamera().gameObject.AddComponent(typeof(LegacyGodraysRenderer));
if (!legacyGodraysRenderer.Init(prolandManager.mainSunLight, this))
{
Component.Destroy(legacyGodraysRenderer);
legacyGodraysRenderer = null;
}
}
if (Scatterer.Instance.mainSettings.useRingShadows)
{
InitKopernicusRings ();
}
TweakScaledMesh ();
if (prolandManager.parentCelestialBody.pqsController)
{
prolandManager.parentCelestialBody.pqsController.isActive = false; //sometimes the PQS is forgotten as "active" if a ship is loaded directly around another body, this would mess with the mod
//this sets it to false, if it's really active it will be set to active automatically. EVE mod seems also to have a fix for this
}
if ((HighLogic.LoadedScene != GameScenes.MAINMENU) && (HighLogic.LoadedScene != GameScenes.TRACKSTATION)) // &&useLocalScattering
{
localScatteringContainer = new ScreenSpaceScatteringContainer(localScatteringMaterial, parentLocalTransform, Rt, prolandManager, Scatterer.Instance.mainSettings.quarterResScattering && !legacyGodraysRenderer);
}
if (Scatterer.Instance.mainSettings.fullLensFlareReplacement)
{
sunflareExtinctionMaterial = new Material (ShaderReplacer.Instance.LoadedShaders ["Scatterer/sunFlareExtinction"]);
InitUniforms(sunflareExtinctionMaterial);
if (hasRingObjectAndShadowActivated)
{
sunflareExtinctionMaterial.SetFloat (ShaderProperties.ringInnerRadius_PROPERTY, ringInnerRadius);
sunflareExtinctionMaterial.SetFloat (ShaderProperties.ringOuterRadius_PROPERTY, ringOuterRadius);
sunflareExtinctionMaterial.SetVector (ShaderProperties.ringNormal_PROPERTY, ringObject.transform.up);
sunflareExtinctionMaterial.SetTexture (ShaderProperties.ringTexture_PROPERTY, ringTexture);
}
Utils.EnableOrDisableShaderKeywords (sunflareExtinctionMaterial, "DISABLE_UNDERWATER_ON", "DISABLE_UNDERWATER_OFF", prolandManager.hasOcean);
}
if (useEclipses || hasRingObjectAndShadowActivated)
{
scaledEclipseMaterial = new Material (ShaderReplacer.Instance.LoadedShaders [("Scatterer/ScaledPlanetEclipse")]);
scaledEclipseMaterial.renderQueue = 2001;
Utils.EnableOrDisableShaderKeywords (scaledEclipseMaterial, "ECLIPSES_ON", "ECLIPSES_OFF", useEclipses);
Utils.EnableOrDisableShaderKeywords (scaledEclipseMaterial, "RINGSHADOW_ON", "RINGSHADOW_OFF", hasRingObjectAndShadowActivated);
InitUniforms(scaledEclipseMaterial);
}
stockScaledPlanetMeshRenderer = (MeshRenderer) parentScaledTransform.GetComponent();
skyNodeInitiated = true;
Utils.LogDebug("Skynode initiated for "+celestialBodyName);
}
void InitSkySphere ()
{
float skySphereSize = (1.5f * (Rt - Rg*atmosphereStartRadiusScale) + Rg*atmosphereStartRadiusScale) / ScaledSpace.ScaleFactor;
skySphere = new SkySphereContainer (skySphereSize, skyMaterial, parentLocalTransform, parentScaledTransform);
if (HighLogic.LoadedScene != GameScenes.MAINMENU)
{
if (prolandManager.parentCelestialBody.pqsController != null && prolandManager.parentCelestialBody.pqsController.isActive && HighLogic.LoadedScene != GameScenes.TRACKSTATION)
{
skySphere.SwitchLocalMode ();
}
else
{
skySphere.SwitchScaledMode ();
}
}
skyMaterial.renderQueue = 2998;
InitUniforms (skyMaterial);
}
public void InitScaledScattering ()
{
scaledScatteringContainer = new ScaledScatteringContainer (parentScaledTransform.GetComponent ().sharedMesh, scaledScatteringMaterial, parentLocalTransform, parentScaledTransform);
if (HighLogic.LoadedScene != GameScenes.MAINMENU)
{
if (prolandManager.parentCelestialBody.pqsController != null && prolandManager.parentCelestialBody.pqsController.isActive && HighLogic.LoadedScene != GameScenes.TRACKSTATION)
{
scaledScatteringContainer.SwitchLocalMode ();
}
else
{
scaledScatteringContainer.SwitchScaledMode ();
}
}
scaledScatteringMaterial.renderQueue = 2997;
InitUniforms (scaledScatteringMaterial);
}
public void OnPreRender()
{
UpdateGraphicsUniforms ();
if (!MapView.MapIsEnabled && Scatterer.Instance.mainSettings.sunlightExtinction && precomputedAtmoLoaded)
{
UpdateLightExtinctions ();
}
}
public void UpdateGraphicsUniforms()
{
if (!inScaledSpace && !MapView.MapIsEnabled && postprocessingEnabled && localScatteringContainer!=null)
{
UpdatePostProcessMaterialUniforms (localScatteringContainer.material);
}
if (useEclipses)
{
UpdateEclipseCasters ();
}
if (Scatterer.Instance.mainSettings.integrateWithEVEClouds && usesCloudIntegration)
{
UpdateEVECloudMaterials ();
}
if (Scatterer.Instance.sunflareManager)
{
UpdateSunflareExtinctions ();
}
if (scaledScatteringContainer != null)
scaledScatteringContainer.MeshRenderer.enabled = stockScaledPlanetMeshRenderer.enabled;
if (localScatteringContainer != null)
{
localScatteringContainer.SetInScaledSpace (inScaledSpace);
localScatteringContainer.UpdateContainer ();
}
SetUniforms (skyMaterial);
SetUniforms (scaledScatteringMaterial);
if (sunflareExtinctionMaterial)
SetUniforms (sunflareExtinctionMaterial);
if (scaledEclipseMaterial)
{
scaledEclipseMaterial.SetVector (ShaderProperties._Sun_WorldSunDir_PROPERTY, prolandManager.getDirectionToMainSun ());
scaledEclipseMaterial.SetMatrix (ShaderProperties.lightOccluders1_PROPERTY, castersMatrix1);
scaledEclipseMaterial.SetMatrix (ShaderProperties.lightOccluders2_PROPERTY, castersMatrix2);
scaledEclipseMaterial.SetVector (ShaderProperties.sunPosAndRadius_PROPERTY, new Vector4 (sunPosRelPlanet.x, sunPosRelPlanet.y,
sunPosRelPlanet.z, (float)prolandManager.sunCelestialBody.Radius));
}
}
public void UpdateNode ()
{
if ((prolandManager.parentCelestialBody.pqsController != null) && !(HighLogic.LoadedScene == GameScenes.TRACKSTATION))
{
bool previousState = inScaledSpace;
inScaledSpace = !prolandManager.parentCelestialBody.pqsController.isActive;
//if we go from scaled to local space
if (!inScaledSpace && previousState)
{
SwitchEffectsLocal();
}
//if we go from local to scaled
if (inScaledSpace && !previousState)
{
SwitchEffectsScaled();
}
//For wave interactions, consider we are in scaledSpace only if we aren't in map view, otherwise we can be in the surface but pqsController is inactive
if (!MapView.MapIsEnabled)
simulateOceanInteraction = prolandManager.parentCelestialBody.pqsController.isActive;
}
else
{
inScaledSpace = true;
simulateOceanInteraction = false;
}
if (skyNodeInitiated)
{
if (!precomputedAtmoLoaded)
{
InitOrRequestPrecomputedAtmo();
}
else if (!atmosphereShadersInitiated)
{
InitSkySphere ();
InitPostprocessMaterialUniforms (localScatteringMaterial);
InitScaledScattering ();
try {StartCoroutine(DelayedTweakStockPlanet ());}
catch (Exception e){Utils.LogError("Error when starting SkyNode::DelayedTweakStockPlanet coroutine "+e.Message);};
if (Scatterer.Instance.mainSettings.integrateWithEVEClouds && usesCloudIntegration)
InitEVEClouds ();
InitOceanMaterialUniforms();
atmosphereShadersInitiated = true;
}
InterpolateVariables ();
if (prolandManager.hasOcean && !Scatterer.Instance.mainSettings.useOceanShaders)
{
skySphere.MeshRenderer.enabled = (altitude>=0f);
stockSkyGameObject.SetActive(altitude<0f); //re-enable stock sky meshrenderer, for compatibility with stock underwater effect
}
}
}
public void SwitchEffectsScaled()
{
Utils.LogInfo ("Skynode switch effects to scaled mode: "+prolandManager.parentCelestialBody.name);
if (skySphere != null)
skySphere.SwitchScaledMode ();
if (scaledScatteringContainer != null)
scaledScatteringContainer.SwitchScaledMode ();
if (localScatteringContainer != null)
localScatteringContainer.SetActivated(false);
}
public void SwitchEffectsLocal()
{
Utils.LogInfo ("Skynode switch effects to local mode "+prolandManager.parentCelestialBody.name);
if (skySphere != null)
skySphere.SwitchLocalMode();
if (scaledScatteringContainer != null)
scaledScatteringContainer.SwitchLocalMode ();
if (localScatteringContainer != null)
localScatteringContainer.SetActivated(true);
}
public void SetUniforms (Material mat)
{
mat.SetFloat(ShaderProperties._Alpha_Global_PROPERTY, interpolatedSettings.skyAlpha);
mat.SetFloat(ShaderProperties._Extinction_Tint_PROPERTY, interpolatedSettings.skyExtinctionTint);
mat.SetFloat(ShaderProperties.extinctionTint_PROPERTY, interpolatedSettings.extinctionTint); //extinctionTint for scaled+local
mat.SetFloat(ShaderProperties.extinctionThickness_PROPERTY, interpolatedSettings.extinctionThickness);
mat.SetFloat(ShaderProperties.Rg_PROPERTY, Rg * atmosphereStartRadiusScale);
mat.SetFloat(ShaderProperties.Rt_PROPERTY, Rt);
mat.SetFloat(ShaderProperties.mieG_PROPERTY, Mathf.Clamp(m_mieG, 0.0f, 0.99f));
mat.SetVector(ShaderProperties._Sun_WorldSunDir_PROPERTY, prolandManager.getDirectionToMainSun());
mat.SetFloat(ShaderProperties._SkyExposure_PROPERTY, interpolatedSettings.skyExposure);
mat.SetFloat(ShaderProperties._ScatteringExposure_PROPERTY, interpolatedSettings.scatteringExposure);
if ((prolandManager.secondarySuns.Count > 0) || Scatterer.Instance.mainSettings.usePlanetShine)
{
mat.SetMatrix(ShaderProperties.planetShineSources_PROPERTY, prolandManager.planetShineSourcesMatrix);
mat.SetMatrix(ShaderProperties.planetShineRGB_PROPERTY, prolandManager.planetShineRGBMatrix);
}
UpdateEclipseAndRingUniforms(mat);
if (legacyGodraysRenderer)
{
mat.SetFloat(ShaderProperties._godrayStrength_PROPERTY, godrayStrength);
}
mat.SetColor(ShaderProperties._sunColor_PROPERTY, prolandManager.getIntensityModulatedSunColor());
}
private void UpdateEclipseAndRingUniforms(Material mat)
{
if (useEclipses)
{
mat.SetMatrix(ShaderProperties.lightOccluders1_PROPERTY, castersMatrix1);
mat.SetMatrix(ShaderProperties.lightOccluders2_PROPERTY, castersMatrix2);
mat.SetVector(ShaderProperties.sunPosAndRadius_PROPERTY, new Vector4(sunPosRelPlanet.x, sunPosRelPlanet.y,
sunPosRelPlanet.z, (float)prolandManager.sunCelestialBody.Radius));
}
if (hasRingObjectAndShadowActivated)
{
mat.SetVector(ShaderProperties.ringNormal_PROPERTY, ringObject.transform.up);
}
}
public void SetOceanUniforms (Material mat)
{
if (mat == null)
return;
mat.SetFloat (ShaderProperties._ScatteringExposure_PROPERTY, interpolatedSettings.scatteringExposure);
mat.SetFloat (ShaderProperties.Rg_PROPERTY, Rg*atmosphereStartRadiusScale);
mat.SetFloat (ShaderProperties.Rt_PROPERTY, Rt);
mat.SetFloat (ShaderProperties.mieG_PROPERTY, Mathf.Clamp (m_mieG, 0.0f, 0.99f));
mat.SetVector (ShaderProperties._Sun_WorldSunDir_PROPERTY, prolandManager.getDirectionToMainSun ());
mat.SetVector(ShaderProperties._camForward_PROPERTY, Scatterer.Instance.nearCamera.transform.forward);
mat.SetFloat (ShaderProperties._Alpha_Global_PROPERTY, interpolatedSettings.skyAlpha);
mat.SetFloat (ShaderProperties._SkyExposure_PROPERTY, interpolatedSettings.skyExposure);
UpdatePostProcessMaterialUniforms (mat);
}
public void InitPostprocessMaterialUniforms (Material mat)
{
if (mat == null || !precomputedAtmoLoaded)
return;
mat.SetFloat(ShaderProperties.mieG_PROPERTY, Mathf.Clamp(m_mieG, 0.0f, 0.99f));
mat.SetTexture(ShaderProperties.AtmosphereAtlas_PROPERTY, atmosphereAtlas);
mat.SetVector(ShaderProperties.InscatterAtlasScaleAndOffset_PROPERTY, atlasScaleAndOffsets[0]);
mat.SetVector(ShaderProperties.IrradianceAtlasScaleAndOffset_PROPERTY, atlasScaleAndOffsets[1]);
mat.SetVector(ShaderProperties.TransmittanceAtlasScaleAndOffset_PROPERTY, atlasScaleAndOffsets[2]);
mat.SetVector(ShaderProperties.AtmosphereAtlasDimensions_PROPERTY, new Vector2(atmosphereAtlas.width, atmosphereAtlas.height));
mat.SetFloat(ShaderProperties.M_PI_PROPERTY, Mathf.PI);
mat.SetFloat(ShaderProperties.Rg_PROPERTY, Rg * atmosphereStartRadiusScale);
mat.SetFloat(ShaderProperties.Rt_PROPERTY, Rt);
mat.SetVector(ShaderProperties.PRECOMPUTED_SCTR_LUT_DIM_PROPERTY, scatteringLutDimensions);
mat.SetFloat(ShaderProperties.TRANSMITTANCE_W_PROPERTY, TRANSMITTANCE_W);
mat.SetFloat(ShaderProperties.TRANSMITTANCE_H_PROPERTY, TRANSMITTANCE_H);
mat.SetFloat(ShaderProperties.SKY_W_PROPERTY, SKY_W);
mat.SetFloat(ShaderProperties.SKY_H_PROPERTY, SKY_H);
mat.SetVector(ShaderProperties.betaR_PROPERTY, m_betaR / 1000.0f / mainMenuScaleFactor);
mat.SetFloat(ShaderProperties.mieG_PROPERTY, Mathf.Clamp(m_mieG, 0.0f, 0.99f));
mat.SetVector(ShaderProperties.betaMSca_PROPERTY, BETA_MSca / 1000.0f / mainMenuScaleFactor);
mat.SetVector(ShaderProperties.betaMEx_PROPERTY, (BETA_MSca / 1000.0f / mainMenuScaleFactor) / 0.9f);
mat.SetFloat(ShaderProperties.HR_PROPERTY, HR * 1000.0f * mainMenuScaleFactor);
mat.SetFloat(ShaderProperties.HM_PROPERTY, HM * 1000.0f * mainMenuScaleFactor);
mat.SetVector(ShaderProperties.SUN_DIR_PROPERTY, prolandManager.getDirectionToMainSun());
Utils.EnableOrDisableShaderKeywords(mat, "PLANETSHINE_ON", "PLANETSHINE_OFF", (prolandManager.secondarySuns.Count > 0) || Scatterer.Instance.mainSettings.usePlanetShine);
//When using custom ocean shaders, we don't reuse the ocean mesh to render scattering separately: Instead ocean shader handles scattering internally
//When the ocean starts fading out when transitioning to orbit, ocean shader stops doing scattering, and stops writing to z-buffer
//The ocean floor vertexes are then used by the scattering shader, moving them to the surface to render scattering, this is not needed for stock ocean so disable it
Utils.EnableOrDisableShaderKeywords(mat, "CUSTOM_OCEAN_ON", "CUSTOM_OCEAN_OFF", Scatterer.Instance.mainSettings.useOceanShaders && prolandManager.hasOcean);
Utils.EnableOrDisableShaderKeywords(mat, "DITHERING_ON", "DITHERING_OFF", Scatterer.Instance.mainSettings.useDithering);
if (prolandManager.flatScaledSpaceModel && prolandManager.parentCelestialBody.pqsController)
mat.SetFloat(ShaderProperties._PlanetOpacity_PROPERTY, 0f);
else
mat.SetFloat(ShaderProperties._PlanetOpacity_PROPERTY, 1f);
mat.SetColor(ShaderProperties._sunColor_PROPERTY, prolandManager.getIntensityModulatedSunColor());
mat.SetColor(ShaderProperties.cloudSunColor_PROPERTY, prolandManager.cloudIntegrationUsesScattererSunColors ? prolandManager.getIntensityModulatedSunColor() : prolandManager.mainScaledSunLight.color * prolandManager.mainScaledSunLight.intensity);
float camerasOverlap = 0f;
if (!Scatterer.Instance.unifiedCameraMode)
camerasOverlap = Scatterer.Instance.nearCamera.farClipPlane - Scatterer.Instance.farCamera.nearClipPlane;
mat.SetFloat(ShaderProperties._ScattererCameraOverlap_PROPERTY, camerasOverlap);
InitGodraysUniforms(mat);
Utils.SetToneMapping(mat);
InitEclipseAndRingUniforms(mat);
}
public void UpdatePostProcessMaterialUniforms (Material mat)
{
mat.SetFloat (ShaderProperties._global_alpha_PROPERTY, interpolatedSettings.postProcessAlpha);
mat.SetFloat (ShaderProperties._ScatteringExposure_PROPERTY, interpolatedSettings.scatteringExposure);
mat.SetFloat (ShaderProperties._global_depth_PROPERTY, interpolatedSettings.postProcessDepth *1000000);
if (prolandManager.flatScaledSpaceModel && prolandManager.parentCelestialBody.pqsController)
{
if (MapView.MapIsEnabled)
mat.SetFloat (ShaderProperties._PlanetOpacity_PROPERTY, 0f);
else
mat.SetFloat (ShaderProperties._PlanetOpacity_PROPERTY, 1f - prolandManager.parentCelestialBody.pqsController.surfaceMaterial.GetFloat (ShaderProperties._PlanetOpacity_PROPERTY));
}
mat.SetFloat (ShaderProperties._Post_Extinction_Tint_PROPERTY, interpolatedSettings.extinctionTint);
mat.SetFloat (ShaderProperties.extinctionThickness_PROPERTY, interpolatedSettings.extinctionThickness);
mat.SetVector (ShaderProperties.SUN_DIR_PROPERTY, prolandManager.getDirectionToMainSun ());
mat.SetVector (ShaderProperties._planetPos_PROPERTY, parentLocalTransform.position);
mat.SetColor (ShaderProperties.cloudSunColor_PROPERTY, prolandManager.cloudIntegrationUsesScattererSunColors ? prolandManager.getIntensityModulatedSunColor() : prolandManager.mainScaledSunLight.color * prolandManager.mainScaledSunLight.intensity );
if ((prolandManager.secondarySuns.Count > 0) || Scatterer.Instance.mainSettings.usePlanetShine)
{
mat.SetMatrix (ShaderProperties.planetShineSources_PROPERTY, prolandManager.planetShineSourcesMatrix);
mat.SetMatrix (ShaderProperties.planetShineRGB_PROPERTY, prolandManager.planetShineRGBMatrix);
mat.SetMatrix (ShaderProperties.cloudPlanetShineRGB_PROPERTY, prolandManager.cloudIntegrationUsesScattererSunColors ? prolandManager.planetShineRGBMatrix : prolandManager.planetShineOriginalRGBMatrix );
}
if (legacyGodraysRenderer)
{
mat.SetFloat(ShaderProperties._godrayStrength_PROPERTY, godrayStrength);
}
mat.SetColor (ShaderProperties._sunColor_PROPERTY, prolandManager.getIntensityModulatedSunColor());
UpdateEclipseAndRingUniforms(mat);
}
public void InitUniforms (Material mat)
{
if (mat == null || !precomputedAtmoLoaded)
return;
mat.SetFloat(ShaderProperties.M_PI_PROPERTY, Mathf.PI);
mat.SetFloat(ShaderProperties.mieG_PROPERTY, Mathf.Clamp(m_mieG, 0.0f, 0.99f));
mat.SetVector(ShaderProperties.betaR_PROPERTY, m_betaR / 1000.0f / mainMenuScaleFactor);
mat.SetTexture(ShaderProperties.AtmosphereAtlas_PROPERTY, atmosphereAtlas);
mat.SetVector(ShaderProperties.InscatterAtlasScaleAndOffset_PROPERTY, atlasScaleAndOffsets[0]);
mat.SetVector(ShaderProperties.IrradianceAtlasScaleAndOffset_PROPERTY, atlasScaleAndOffsets[1]);
mat.SetVector(ShaderProperties.TransmittanceAtlasScaleAndOffset_PROPERTY, atlasScaleAndOffsets[2]);
mat.SetVector(ShaderProperties.AtmosphereAtlasDimensions_PROPERTY, atlasDimensions);
mat.SetFloat(ShaderProperties.Rg_PROPERTY, Rg * atmosphereStartRadiusScale);
mat.SetFloat(ShaderProperties.Rt_PROPERTY, Rt);
mat.SetFloat(ShaderProperties.TRANSMITTANCE_W_PROPERTY, TRANSMITTANCE_W);
mat.SetFloat(ShaderProperties.TRANSMITTANCE_H_PROPERTY, TRANSMITTANCE_H);
mat.SetFloat(ShaderProperties.SKY_W_PROPERTY, SKY_W);
mat.SetFloat(ShaderProperties.SKY_H_PROPERTY, SKY_H);
mat.SetVector(ShaderProperties.PRECOMPUTED_SCTR_LUT_DIM_PROPERTY, scatteringLutDimensions);
mat.SetFloat(ShaderProperties.HR_PROPERTY, HR * 1000.0f * mainMenuScaleFactor);
mat.SetFloat(ShaderProperties.HM_PROPERTY, HM * 1000.0f * mainMenuScaleFactor);
mat.SetVector(ShaderProperties.betaMSca_PROPERTY, BETA_MSca / 1000.0f / mainMenuScaleFactor);
mat.SetVector(ShaderProperties.betaMEx_PROPERTY, (BETA_MSca / 1000.0f / mainMenuScaleFactor) / 0.9f);
InitEclipseAndRingUniforms(mat);
Utils.EnableOrDisableShaderKeywords(mat, "PLANETSHINE_ON", "PLANETSHINE_OFF", (prolandManager.secondarySuns.Count > 0) || Scatterer.Instance.mainSettings.usePlanetShine);
Utils.EnableOrDisableShaderKeywords(mat, "DITHERING_ON", "DITHERING_OFF", Scatterer.Instance.mainSettings.useDithering);
mat.SetFloat(ShaderProperties.flatScaledSpaceModel_PROPERTY, prolandManager.flatScaledSpaceModel ? 1f : 0f);
mat.SetColor(ShaderProperties._sunColor_PROPERTY, prolandManager.getIntensityModulatedSunColor());
mat.SetColor(ShaderProperties.cloudSunColor_PROPERTY, prolandManager.cloudIntegrationUsesScattererSunColors ? prolandManager.getIntensityModulatedSunColor() : prolandManager.mainScaledSunLight.color * prolandManager.mainScaledSunLight.intensity);
InitGodraysUniforms(mat);
Utils.SetToneMapping(mat);
}
private void InitGodraysUniforms(Material mat)
{
if (legacyGodraysRenderer != null)
{
mat.SetTexture(ShaderProperties._godrayDepthTexture_PROPERTY, legacyGodraysRenderer.volumeDepthTexture);
mat.EnableKeyword("GODRAYS_LEGACY");
mat.EnableKeyword("RAYMARCHED_GODRAYS_OFF");
mat.DisableKeyword("GODRAYS_OFF");
mat.SetFloat(ShaderProperties.godraysSoftwareSwitch_PROPERTY, 0f);
}
else
{
mat.EnableKeyword("RAYMARCHED_GODRAYS_OFF");
mat.EnableKeyword("GODRAYS_OFF");
mat.SetFloat(ShaderProperties.godraysSoftwareSwitch_PROPERTY, 0f);
}
}
private void InitEclipseAndRingUniforms(Material mat)
{
if (hasRingObjectAndShadowActivated)
{
Utils.EnableOrDisableShaderKeywords(mat, "RINGSHADOW_ON", "RINGSHADOW_OFF", true);
mat.SetFloat("useRingShadow", 1f);
mat.SetFloat(ShaderProperties.ringInnerRadius_PROPERTY, ringInnerRadius);
mat.SetFloat(ShaderProperties.ringOuterRadius_PROPERTY, ringOuterRadius);
mat.SetVector(ShaderProperties.ringNormal_PROPERTY, ringObject.transform.up);
mat.SetTexture(ShaderProperties.ringTexture_PROPERTY, ringTexture);
}
else
{
Utils.EnableOrDisableShaderKeywords(mat, "RINGSHADOW_ON", "RINGSHADOW_OFF", false);
mat.SetFloat("useRingShadow", 0f);
}
Utils.EnableOrDisableShaderKeywords(mat, "ECLIPSES_ON", "ECLIPSES_OFF", useEclipses);
mat.SetFloat("useEclipses", useEclipses ? 1f : 0f);
}
public void TogglePostProcessing()
{
postprocessingEnabled = !postprocessingEnabled;
}
void InitOrRequestPrecomputedAtmo ()
{
Rg = (float) prolandManager.GetRadius ();
Rt = AtmoPreprocessor.CalculateRt (Rg*atmosphereStartRadiusScale, HR*mainMenuScaleFactor, HM*mainMenuScaleFactor, m_betaR/mainMenuScaleFactor, BETA_MSca/mainMenuScaleFactor, useOzone, ozoneHeight/mainMenuScaleFactor, ozoneFalloff/mainMenuScaleFactor);
//Compute atmo hash and path
string cachePath = Utils.GameDataPath + "/ScattererAtmosphereCache/PluginData";
float originalRt = AtmoPreprocessor.CalculateRt ((float) prolandManager.parentCelestialBody.Radius * atmosphereStartRadiusScale, HR, HM, m_betaR, BETA_MSca, useOzone, ozoneHeight, ozoneFalloff);
string atmohash = AtmoPreprocessor.GetAtmoHash((float) prolandManager.parentCelestialBody.Radius * atmosphereStartRadiusScale, originalRt, m_betaR, BETA_MSca, m_mieG, HR, HM, averageGroundReflectance, multipleScattering, scatteringLutDimensions, useOzone, ozoneAbsorption, ozoneHeight, ozoneFalloff);
cachePath += "/" + atmohash;
string atlasPath = cachePath + "/atlas.half";
if (!System.IO.File.Exists (atlasPath))
{
AtmoPreprocessor.Generate ((float) prolandManager.parentCelestialBody.Radius * atmosphereStartRadiusScale, originalRt, m_betaR, BETA_MSca, m_mieG, HR, HM, averageGroundReflectance, multipleScattering, scatteringLutDimensions, previewMode, cachePath, useOzone, ozoneAbsorption, ozoneHeight, ozoneFalloff, prolandManager.parentCelestialBody.name);
precomputedAtmoLoaded = false;
return;
}
LoadPrecomputedAtmo(atlasPath);
precomputedAtmoLoaded = true;
if (atmosphereShadersInitiated)
ReinitAllMaterials();
}
private void LoadPrecomputedAtmo(string atlasPath)
{
var textureDimensions = new List {
new Vector2(scatteringLutDimensions.x * scatteringLutDimensions.y, scatteringLutDimensions.z* scatteringLutDimensions.w),
new Vector2(SKY_W, SKY_H),
new Vector2(TRANSMITTANCE_W, TRANSMITTANCE_H) };
// Textures are packed in the simplest way possible, top-left to bottom-left
int atlasWidth = textureDimensions.Max(texture => (int)texture.x);
int atlasHeight = textureDimensions.Sum(texture => (int)texture.y);
atlasDimensions = new Vector2(atlasWidth, atlasHeight);
atmosphereAtlas = new Texture2D(atlasWidth, atlasHeight, TextureFormat.RGBAHalf, false);
atmosphereAtlas.wrapMode = TextureWrapMode.Clamp;
atmosphereAtlas.filterMode = FilterMode.Bilinear;
atmosphereAtlas.LoadRawTextureData(System.IO.File.ReadAllBytes(atlasPath));
atmosphereAtlas.Apply();
atlasScaleAndOffsets = AtmoPreprocessor.GetPackedTexturesScaleAndOffsets(textureDimensions, atlasDimensions);
}
public void ApplyAtmoFromUI(Vector4 inBETA_R, Vector4 inBETA_MSca, float inMIE_G, float inHR, float inHM, float inGRref, bool inMultiple, bool inFastPreviewMode, float inAtmosphereStartRadiusScale, bool inUseOzone, Vector3 inOzoneAbsorption, float inOzoneHeight, float inOzoneFalloff)
{
m_betaR = inBETA_R;
BETA_MSca = inBETA_MSca;
m_mieG = inMIE_G;
HR = inHR;
HM = inHM;
averageGroundReflectance = inGRref;
multipleScattering = inMultiple;
previewMode = inFastPreviewMode;
scatteringLutDimensions = inFastPreviewMode ? AtmoPreprocessor.scatteringLutDimensionsPreview : AtmoPreprocessor.ScatteringLutDimensionsDefault ;
atmosphereStartRadiusScale = inAtmosphereStartRadiusScale;
ozoneAbsorption = inOzoneAbsorption;
ozoneHeight = inOzoneHeight;
ozoneFalloff = inOzoneFalloff;
useOzone = inUseOzone;
InitOrRequestPrecomputedAtmo ();
float skySphereSize = 2 * (4 * (Rt - Rg*atmosphereStartRadiusScale) + Rg*atmosphereStartRadiusScale) / ScaledSpace.ScaleFactor;
skySphere.Resize (skySphereSize);
}
void ReinitAllMaterials()
{
if (scaledEclipseMaterial)
InitUniforms(scaledEclipseMaterial);
if (skyMaterial)
InitUniforms(skyMaterial);
if (scaledScatteringMaterial)
InitUniforms(scaledScatteringMaterial);
if (sunflareExtinctionMaterial)
InitUniforms(sunflareExtinctionMaterial);
if (localScatteringMaterial)
InitPostprocessMaterialUniforms(localScatteringMaterial);
ReInitMaterialUniformsOnRenderTexturesLoss();
// make the clouds2d material optional
// add fields for volumetrics and raymarched volumetrics
if (Scatterer.Instance.eveReflectionHandler.EVECloudLayers.ContainsKey(celestialBodyName))
{
foreach (EVECloudLayer eveCloudLayer in Scatterer.Instance.eveReflectionHandler.EVECloudLayers[celestialBodyName])
{
if (eveCloudLayer.Clouds2dMaterial != null)
{
InitUniforms(eveCloudLayer.Clouds2dMaterial);
InitPostprocessMaterialUniforms(eveCloudLayer.Clouds2dMaterial);
}
if (eveCloudLayer.ParticleVolumetricsMaterial != null)
{
InitUniforms(eveCloudLayer.ParticleVolumetricsMaterial);
InitPostprocessMaterialUniforms(eveCloudLayer.ParticleVolumetricsMaterial);
}
}
}
InitOceanMaterialUniforms();
}
public void InitOceanMaterialUniforms()
{
if (prolandManager.GetOceanNode())
{
if (prolandManager.GetOceanNode().m_oceanMaterial)
{
InitUniforms(prolandManager.GetOceanNode().m_oceanMaterial);
InitPostprocessMaterialUniforms(prolandManager.GetOceanNode().m_oceanMaterial);
}
if (prolandManager.GetOceanNode().underwaterMaterial)
{
InitPostprocessMaterialUniforms(prolandManager.GetOceanNode().underwaterMaterial);
}
}
}
public void OnDestroy()
{
try {StopAllCoroutines ();}
catch (Exception){}
if (Scatterer.Instance.mainSettings.autosavePlanetSettingsOnSceneChange && !isConfigModuleManagerPatch)
{
SaveToConfigNode ();
}
if (atmosphereAtlas)
{
UnityEngine.Object.DestroyImmediate(atmosphereAtlas);
}
if (skySphere != null)
{
skySphere.Cleanup ();
}
if (scaledScatteringContainer != null)
{
scaledScatteringContainer.Cleanup ();
}
if (localScatteringContainer != null)
{
localScatteringContainer.Cleanup();
}
if (legacyGodraysRenderer)
{
Component.DestroyImmediate(legacyGodraysRenderer);
}
//disable eve integration scatterer flag
if (Scatterer.Instance.mainSettings.integrateWithEVEClouds && usesCloudIntegration)
{
try
{
if(Scatterer.Instance.eveReflectionHandler.EVECloudLayers.ContainsKey(celestialBodyName))
{
foreach(var cloudLayer in Scatterer.Instance.eveReflectionHandler.EVECloudLayers[celestialBodyName])
{
if (cloudLayer.Clouds2dMaterial != null)
{
cloudLayer.Clouds2dMaterial.DisableKeyword("SCATTERER_ON");
cloudLayer.Clouds2dMaterial.EnableKeyword("SCATTERER_OFF");
}
if (cloudLayer.ParticleVolumetricsMaterial != null)
{
cloudLayer.ParticleVolumetricsMaterial.DisableKeyword("SCATTERER_ON");
cloudLayer.ParticleVolumetricsMaterial.EnableKeyword("SCATTERER_OFF");
cloudLayer.ParticleVolumetricsMaterial.SetFloat("isUnderwater", 0f);
}
}
}
}
catch (Exception)
{
//TODO
}
}
if (originalScaledMesh && parentScaledTransform)
{
var mf = parentScaledTransform.GetComponent ();
if (mf) mf.sharedMesh = originalScaledMesh;
}
RestoreStockScaledTexture ();
}
public bool LoadFromConfigNode ()
{
ConfigNode cnToLoad = new ConfigNode();
ConfigNode[] configNodeArray;
bool found = false;
foreach (UrlDir.UrlConfig _url in Scatterer.Instance.planetsConfigsReader.atmoConfigs)
{
configNodeArray = _url.config.GetNodes("Atmo");
//if (_url.config.TryGetNode("Atmo",ref cnToLoad))
foreach(ConfigNode _cn in configNodeArray)
{
if (_cn.HasValue("name") && _cn.GetValue("name") == celestialBodyName)
{
cnToLoad = _cn;
configUrl = _url;
found = true;
break;
}
}
}
if (found)
{
Utils.LogDebug(" Atmosphere config found for: "+celestialBodyName);
ConfigNode.LoadObjectFromConfig (this, cnToLoad);
Rg = (float) prolandManager.GetRadius ();
Rt = AtmoPreprocessor.CalculateRt (Rg * atmosphereStartRadiusScale, HR*mainMenuScaleFactor, HM*mainMenuScaleFactor, m_betaR/mainMenuScaleFactor, BETA_MSca/mainMenuScaleFactor, useOzone, ozoneHeight / mainMenuScaleFactor, ozoneFalloff / mainMenuScaleFactor);
godrayStrength = Mathf.Min(godrayStrength,1.0f);
//compare parentConfigNode with the one on disk to determine if it's a ModuleManager Patch
string parentConfigNodePath = Utils.GameDataPath + configUrl.parent.url +".cfg";
if (System.IO.File.Exists(parentConfigNodePath))
{
ConfigNode cnParentFromFile = ConfigNode.Load(Utils.GameDataPath + configUrl.parent.url +".cfg");
if (cnParentFromFile.HasNode("Scatterer_atmosphere"))
{
int comparisonResult = configUrl.config.ToString().CompareTo(cnParentFromFile.GetNode("Scatterer_atmosphere").ToString());
isConfigModuleManagerPatch = (comparisonResult != 0);
}
}
}
else
{
Utils.LogError(" Atmosphere config not found for: "+celestialBodyName);
Utils.LogDebug(" Removing "+celestialBodyName +" from planets list");
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.Remove(Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.Find(_cb => _cb.celestialBodyName == celestialBodyName));
prolandManager.OnDestroy();
UnityEngine.Object.Destroy (prolandManager);
UnityEngine.Object.Destroy (this);
}
return found;
}
public void SaveToConfigNode ()
{
ConfigNode[] configNodeArray;
bool found = false;
configNodeArray = configUrl.config.GetNodes("Atmo");
foreach(ConfigNode _cn in configNodeArray)
{
if (_cn.HasValue("name") && _cn.GetValue("name") == celestialBodyName)
{
ConfigNode cnTemp = ConfigNode.CreateConfigFromObject (this);
_cn.ClearData();
ConfigNode.Merge (_cn, cnTemp);
_cn.name="Atmo";
Utils.LogDebug(" saving "+celestialBodyName+" atmo config to: "+configUrl.parent.url);
configUrl.parent.SaveConfigs ();
found=true;
break;
}
}
if (!found)
{
Utils.LogDebug(" couldn't find config file to save to");
}
}
void DisableStockSky ()
{
for (int i = 0; i < parentScaledTransform.childCount; i++) {
if (parentScaledTransform.GetChild (i).gameObject.layer == 9) {
if (parentScaledTransform.GetChild (i).gameObject.name == "Atmosphere") {
stockSkyGameObject = parentScaledTransform.GetChild (i).gameObject;
stockSkyGameObject.SetActive (false);
break;
}
}
}
}
IEnumerator DelayedTweakStockPlanet()
{
if (!stockScaledPlanetMeshRenderer.sharedMaterial.HasProperty ("_MainTex")) //this property is absent on gas giants
{
DisableStockSky();
if (adjustScaledTexture)
TweakStockScaledTexture ();
}
else // Have to delay this until Kopernicus loads the on-demand textures and also check it's not a rendertexture (ie overridden by scatterer)
{
while (true)
{
Texture maintex = stockScaledPlanetMeshRenderer.sharedMaterial.GetTexture("_MainTex");
if (maintex != null && maintex is Texture2D)
{
if (adjustScaledTexture)
TweakStockScaledTexture ();
TweakStockAtmosphere ();
yield return StartCoroutine(CheckOnDemandUnload()); //once loaded, wait for it to unload and resume checking again
}
yield return new WaitForSeconds(1f);
}
}
}
// Check if kopernicus on demand unloads the planet, then we have to start waiting for it to load it again
IEnumerator CheckOnDemandUnload()
{
while (true)
{
if (stockScaledPlanetMeshRenderer.sharedMaterial.GetTexture("_MainTex") == null)
{
break;
}
yield return new WaitForSeconds(3f);
}
}
public void TweakStockAtmosphere () //move to utils/scaledUtils etc
{
DisableStockSky ();
List materials = new List(stockScaledPlanetMeshRenderer.sharedMaterials);
materials.RemoveAll(x => x.shader.name == "Scatterer/ScaledPlanetEclipse");
if (useEclipses)
{
var deferred = ReflectionUtils.getType("Deferred.Deferred");
bool deferredInstalled = deferred != null;
// Split the main pass and the additive light passes into separate materials with different renderqueues so we can inject eclipses after the first pass, and make it apply only to the main pass
// But only if deferred is not installed, otherwise this breaks deferred rendering
if (parentScaledTransform.GetComponent() == null && !deferredInstalled)
{
List materialsNoCityLights = new List(materials);
materialsNoCityLights.RemoveAll(x => x.shader.name == "EVE/PlanetCityLight");
Material planetScaledSpaceMaterial = materialsNoCityLights.ElementAt(0);
planetScaledSpaceMaterial.SetShaderPassEnabled("ForwardBase", true);
planetScaledSpaceMaterial.SetShaderPassEnabled("ForwardAdd", false);
materials.Add(Material.Instantiate(planetScaledSpaceMaterial));
materials.Last().CopyPropertiesFromMaterial(materialsNoCityLights.ElementAt(0));
materials.Last().SetShaderPassEnabled("ForwardBase", false);
materials.Last().SetShaderPassEnabled("ForwardAdd", true);
materials.Last().renderQueue = 2002;
PlanetSecondaryLightUpdater secondaryLightUpdater = parentScaledTransform.gameObject.AddComponent();
secondaryLightUpdater.Init(planetScaledSpaceMaterial, materials.Last());
}
materials.Add(scaledEclipseMaterial);
}
stockScaledPlanetMeshRenderer.sharedMaterials = materials.ToArray ();
foreach (Material sharedMaterial in materials)
{
sharedMaterial.SetFloat (Shader.PropertyToID ("_rimBlend"), rimBlend / 100f);
sharedMaterial.SetFloat (Shader.PropertyToID ("_rimPower"), rimpower / 100f);
if (sharedMaterial.shader.name == "Terrain/Scaled Planet (RimAerial) Standard")
{
sharedMaterial.SetColor ("_SpecColor", new Color (specR / 255f, specG / 255f, specB / 255f));
if (HighLogic.LoadedScene == GameScenes.MAINMENU)
{
sharedMaterial.SetFloat ("_Shininess", shininess / 140f); //for some reason still too strong in main menu
}
else
{
sharedMaterial.SetFloat ("_Shininess", shininess / 120f);
}
}
else
{
sharedMaterial.SetColor ("_SpecColor", new Color (specR / 100f, specG / 100f, specB / 100f));
sharedMaterial.SetFloat ("_Shininess", shininess / 100f);
}
}
if (prolandManager.parentCelestialBody.pqsController != null)
{
Utils.EnableOrDisableShaderKeywords(prolandManager.parentCelestialBody.pqsController.fallbackMaterial,"AERIAL_ON", "AERIAL_OFF", false);
Utils.EnableOrDisableShaderKeywords(prolandManager.parentCelestialBody.pqsController.lowQualitySurfaceMaterial,"AERIAL_ON", "AERIAL_OFF", false);
Utils.EnableOrDisableShaderKeywords(prolandManager.parentCelestialBody.pqsController.mediumQualitySurfaceMaterial,"AERIAL_ON", "AERIAL_OFF", false);
Utils.EnableOrDisableShaderKeywords(prolandManager.parentCelestialBody.pqsController.highQualitySurfaceMaterial,"AERIAL_ON", "AERIAL_OFF", false);
Utils.EnableOrDisableShaderKeywords(prolandManager.parentCelestialBody.pqsController.ultraQualitySurfaceMaterial,"AERIAL_ON", "AERIAL_OFF", false);
}
}
public void TweakStockScaledTexture () //move to utils/scaledUtils etc
{
if (HighLogic.LoadedScene != GameScenes.MAINMENU)
{
List materials = new List(stockScaledPlanetMeshRenderer.sharedMaterials);
foreach (Material sharedMaterial in materials)
{
if (sharedMaterial.shader.name.Contains("Terrain/Scaled Planet (RimAerial)"))
{
if (!originalPlanetTexture)
{
Texture maintex = sharedMaterial.GetTexture("_MainTex");
if (maintex is Texture2D)
{
originalPlanetTexture = (Texture2D)maintex;
}
}
if (originalPlanetTexture)
{
if (!adjustedPlanetTexture)
{
adjustedPlanetTexture = new RenderTexture(originalPlanetTexture.width, originalPlanetTexture.height, 0, RenderTextureFormat.ARGB32);
adjustedPlanetTexture.name = "ScattererAdjustedPlanetMap";
adjustedPlanetTexture.autoGenerateMips = true;
adjustedPlanetTexture.Create();
}
Material imageAdjustMat = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/ScaledTextureAdjust")]);
imageAdjustMat.SetTexture("inputTexture", originalPlanetTexture);
imageAdjustMat.SetFloat("_scaledLandBrightnessAdjust", scaledLandBrightnessAdjust);
imageAdjustMat.SetFloat("_scaledLandContrastAdjust", scaledLandContrastAdjust);
imageAdjustMat.SetFloat("_scaledLandSaturationAdjust", scaledLandSaturationAdjust);
imageAdjustMat.SetFloat("_scaledOceanBrightnessAdjust", scaledOceanBrightnessAdjust);
imageAdjustMat.SetFloat("_scaledOceanContrastAdjust", scaledOceanContrastAdjust);
imageAdjustMat.SetFloat("_scaledOceanSaturationAdjust", scaledOceanSaturationAdjust);
Graphics.Blit(originalPlanetTexture, adjustedPlanetTexture, imageAdjustMat);
sharedMaterial.SetTexture("_MainTex", adjustedPlanetTexture);
}
}
}
}
}
public void RestoreStockScaledTexture () //move to utils/scaledUtils etc
{
if (originalPlanetTexture && stockScaledPlanetMeshRenderer)
{
List materials = new List(stockScaledPlanetMeshRenderer.sharedMaterials);
foreach (Material sharedMaterial in materials)
{
if (sharedMaterial.shader.name.Contains("Terrain/Scaled Planet (RimAerial)"))
{
sharedMaterial.SetTexture("_MainTex", originalPlanetTexture);
}
}
}
if (adjustedPlanetTexture)
{
adjustedPlanetTexture.Release();
}
}
public void TweakScaledMesh() //move to utils/scaledUtils etc
{
if (!originalScaledMesh)
{
originalScaledMesh = parentScaledTransform.GetComponent ().sharedMesh;
}
tweakedScaledmesh = (Mesh)Instantiate (originalScaledMesh);
double scaledRadius = prolandManager.GetRadius () / (ScaledSpace.ScaleFactor * parentScaledTransform.localScale.x);
Vector3[] verts = tweakedScaledmesh.vertices;
for (int i=0; i scaledRadius)
{
verts [i] = verts [i].normalized * (Mathf.Lerp (verts [i].magnitude, (float)scaledRadius, flattenScaledSpaceMesh));
}
}
tweakedScaledmesh.vertices = verts;
tweakedScaledmesh.RecalculateNormals ();
tweakedScaledmesh.RecalculateTangents ();
tweakedScaledmesh.RecalculateBounds ();
parentScaledTransform.GetComponent ().sharedMesh = tweakedScaledmesh;
}
public void InterpolateVariables ()
{
if(!(HighLogic.LoadedScene == GameScenes.TRACKSTATION))
{
altitude = Vector3.Distance (Scatterer.Instance.nearCamera.transform.position, parentLocalTransform.position) - Rg;
}
if ((HighLogic.LoadedScene == GameScenes.MAINMENU) || (HighLogic.LoadedScene == GameScenes.TRACKSTATION) || MapView.MapIsEnabled)
{
interpolatedSettings.getValuesFrom(configPoints [configPoints.Count - 1]);
currentConfigPoint = configPoints.Count;
return;
}
if (altitude <= configPoints [0].altitude)
{
interpolatedSettings.getValuesFrom(configPoints [0]);
currentConfigPoint = 0;
}
else if (altitude > configPoints [configPoints.Count - 1].altitude)
{
interpolatedSettings.getValuesFrom(configPoints [configPoints.Count - 1]);
currentConfigPoint = configPoints.Count;
}
else
{
//TODO, replace this with binary search, implement method directly in configPoints class, which will implement a list of config points
for (int j = 1; j < configPoints.Count; j++)
{
if ((altitude > configPoints [j - 1].altitude) && (altitude <= configPoints [j].altitude))
{
percentage = (altitude - configPoints [j - 1].altitude) / (configPoints [j].altitude - configPoints [j - 1].altitude);
interpolatedSettings.interpolateValuesFrom(configPoints [j - 1], configPoints [j], percentage);
currentConfigPoint = j;
}
}
}
}
void UpdateLightExtinctions ()
{
Vector3 sunDirection = prolandManager.getDirectionToMainSun();
Vector3 extinctionPosition = (FlightGlobals.ActiveVessel ? FlightGlobals.ActiveVessel.transform.position : Scatterer.Instance.nearCamera.transform.position) - parentLocalTransform.position;
Color extinction = AtmosphereUtils.getExtinction (extinctionPosition, sunDirection, Rt, Rg * atmosphereStartRadiusScale, HR*1000f, HM*1000f, m_betaR / 1000f, BETA_MSca / 1000f / 0.9f, useOzone, atmosphereAtlas, transmittanceTableDimensions, atlasScaleAndOffsets[2], atlasDimensions);
extinction = Color.Lerp(Color.white, extinction, interpolatedSettings.extinctionThickness);
float extinctionSunsetToNoonTransition = Vector3.Dot(sunDirection, extinctionPosition.normalized);
extinctionSunsetToNoonTransition = Mathf.Clamp01( ((extinctionSunsetToNoonTransition-0.2f) / 0.8f) * (1f - noonSunlightExtinctionStrength) );
extinction = Color.Lerp(extinction, Color.white, extinctionSunsetToNoonTransition);
Scatterer.Instance.sunlightModulatorsManagerInstance.ModulateByColor (prolandManager.mainSunLight, extinction);
foreach(SecondarySun secondarySun in prolandManager.secondarySuns)
{
if (secondarySun.sunLight)
{
extinction = AtmosphereUtils.getExtinction (extinctionPosition, (secondarySun.celestialBody.GetTransform().position - prolandManager.parentCelestialBody.GetTransform().position).normalized, Rt, Rg * atmosphereStartRadiusScale, HR*1000f, HM*1000f, m_betaR / 1000f, BETA_MSca / 1000f / 0.9f, useOzone, atmosphereAtlas, transmittanceTableDimensions, atlasScaleAndOffsets[2], atlasDimensions);
extinction = Color.Lerp(Color.white, extinction, interpolatedSettings.extinctionThickness); //consider getting rid of extinction thickness and tint now
Scatterer.Instance.sunlightModulatorsManagerInstance.ModulateByColor (secondarySun.sunLight, extinction);
}
}
}
void UpdateSunflareExtinctions ()
{
foreach (SunFlare customSunFlare in Scatterer.Instance.sunflareManager.scattererSunFlares.Values)
{
if (customSunFlare.FlareRendering) //not sure if it's worth it to try and add more intelligent culling here, like checking if a ray to the flare intersects the planet/atmo?
{
sunflareExtinctionMaterial.SetVector (ShaderProperties._Sun_WorldSunDir_PROPERTY, prolandManager.getDirectionToCelestialBody (customSunFlare.source).normalized);
if (!MapView.MapIsEnabled)
sunflareExtinctionMaterial.SetVector (ShaderProperties._Globals_WorldCameraPos_PROPERTY, Scatterer.Instance.nearCamera.transform.position - parentLocalTransform.position);
else
sunflareExtinctionMaterial.SetVector (ShaderProperties._Globals_WorldCameraPos_PROPERTY, (Vector3)ScaledSpace.ScaledToLocalSpace (Scatterer.Instance.scaledSpaceCamera.transform.position) - parentLocalTransform.position);
Graphics.Blit (null, customSunFlare.extinctionTexture, sunflareExtinctionMaterial, 0);
if (hasRingObjectAndShadowActivated)
{
sunflareExtinctionMaterial.SetVector (ShaderProperties.ringNormal_PROPERTY, ringObject.transform.up);
Graphics.Blit (null, customSunFlare.extinctionTexture, sunflareExtinctionMaterial, 1);
}
}
}
}
void UpdateEclipseCasters ()
{
float scaleFactor = ScaledSpace.ScaleFactor;
sunPosRelPlanet = Vector3.zero;
sunPosRelPlanet = Vector3.Scale (ScaledSpace.LocalToScaledSpace (prolandManager.sunCelestialBody.transform.position), new Vector3 (scaleFactor, scaleFactor, scaleFactor));
castersMatrix1 = Matrix4x4.zero;
castersMatrix2 = Matrix4x4.zero;
Vector3 casterPosRelPlanet;
float eclipseTerm = 1f;
for (int i = 0; i < Mathf.Min (4, prolandManager.eclipseCasters.Count); i++)
{
casterPosRelPlanet = Vector3.Scale (ScaledSpace.LocalToScaledSpace (prolandManager.eclipseCasters [i].transform.position), new Vector3 (scaleFactor, scaleFactor, scaleFactor)); //wtf is this? this is doing local to scaled and back to local?
castersMatrix1.SetRow (i, new Vector4 (casterPosRelPlanet.x, casterPosRelPlanet.y, casterPosRelPlanet.z, (float)prolandManager.eclipseCasters [i].Radius));
eclipseTerm *= AtmosphereUtils.getEclipseShadow(Scatterer.Instance.nearCamera.transform.position, sunPosRelPlanet, casterPosRelPlanet, (float)prolandManager.eclipseCasters[i].Radius, (float)prolandManager.sunCelestialBody.Radius);
}
for (int i = 4; i < Mathf.Min (8, prolandManager.eclipseCasters.Count); i++)
{
casterPosRelPlanet = Vector3.Scale (ScaledSpace.LocalToScaledSpace (prolandManager.eclipseCasters [i].transform.position), new Vector3 (scaleFactor, scaleFactor, scaleFactor));
castersMatrix2.SetRow (i - 4, new Vector4 (casterPosRelPlanet.x, casterPosRelPlanet.y, casterPosRelPlanet.z, (float)prolandManager.eclipseCasters [i].Radius));
eclipseTerm *= AtmosphereUtils.getEclipseShadow(Scatterer.Instance.nearCamera.transform.position, sunPosRelPlanet, casterPosRelPlanet, (float)prolandManager.eclipseCasters[i].Radius, (float)prolandManager.sunCelestialBody.Radius);
}
Scatterer.Instance.sunlightModulatorsManagerInstance.ModulateByAttenuation(prolandManager.mainSunLight, eclipseTerm);
}
void InitKopernicusRings ()
{
ringObject = GameObject.Find (celestialBodyName + "Ring");
if (ringObject) {
Utils.LogDebug (" Found ring for " + celestialBodyName);
Material ringMat = ringObject.GetComponent ().material;
hasRingObjectAndShadowActivated = true;
MonoBehaviour[] scripts = (MonoBehaviour[])ringObject.GetComponents ();
foreach (MonoBehaviour _script in scripts) {
if (_script.GetType ().ToString ().Contains ("Ring")) {
const BindingFlags flags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
FieldInfo[] fields = _script.GetType ().GetFields (flags);
foreach (FieldInfo fi in fields) {
//Utils.Log("fi.Name "+fi.Name+" fi.GetType() "+fi.GetType());
}
try {
ringTexture = _script.GetType ().GetField ("texture", flags).GetValue (_script) as Texture2D;
Utils.LogDebug (" ring texture fetch successful");
Utils.LogDebug (" ringTexture.width " + ringTexture.width.ToString ());
Utils.LogDebug (" ringTexture.height " + ringTexture.height.ToString ());
MeshRenderer ringMR = _script.GetType ().GetField ("ringMr", flags).GetValue (_script) as MeshRenderer;
Utils.LogDebug (" ring MeshRenderer fetch successful");
ringInnerRadius = ringMR.material.GetFloat ("innerRadius");
ringOuterRadius = ringMR.material.GetFloat ("outerRadius");
Utils.LogDebug (" ring innerRadius (with parent scale) " + ringInnerRadius.ToString ());
Utils.LogDebug (" ring outerRadius (with parent scale) " + ringOuterRadius.ToString ());
int tiles = (int)_script.GetType ().GetField ("tiles", flags).GetValue (_script);
if (tiles > 0) {
throw new Exception ("Scatterer doesn't support tiled/thick Kopernicus rings (not implemented)");
}
ringInnerRadius *= ScaledSpace.ScaleFactor;
ringInnerRadius = Mathf.Max(ringInnerRadius,(float)(prolandManager.m_radius)* (1f + 10f/600000f)); //prevent inner ring radius from intersecting planet's radius because that's stupid and it breaks the shader
ringOuterRadius *= ScaledSpace.ScaleFactor;
}
catch (Exception e) {
Utils.LogError ("Kopernicus ring exception: " + e.ToString ());
Utils.LogDebug ("Disabling ring shadows for " + celestialBodyName);
hasRingObjectAndShadowActivated = false;
}
}
}
}
}
public void InitEVEClouds()
{
if ((Scatterer.Instance.eveReflectionHandler.EVEInstance != null) && Scatterer.Instance.eveReflectionHandler.EVECloudLayers.ContainsKey(celestialBodyName))
{
try
{
Scatterer.Instance.eveReflectionHandler.invokeClouds2dReassign(celestialBodyName); // After the shader has been replaced by the modified scatterer shader, the properties are lost, this sets them again
foreach (var cloudLayer in Scatterer.Instance.eveReflectionHandler.EVECloudLayers[celestialBodyName])
{
if (cloudLayer.Clouds2dMaterial != null)
{
Utils.EnableOrDisableShaderKeywords(cloudLayer.Clouds2dMaterial, "SCATTERER_ON", "SCATTERER_OFF", true);
InitUniforms (cloudLayer.Clouds2dMaterial);
InitPostprocessMaterialUniforms (cloudLayer.Clouds2dMaterial);
if (HighLogic.LoadedScene == GameScenes.MAINMENU)
{
//Wrongly defined to ON in mainmenu by EVE, causing messed up extinction calculations
Utils.EnableOrDisableShaderKeywords(cloudLayer.Clouds2dMaterial, "WORLD_SPACE_ON", "WORLD_SPACE_OFF", false);
}
}
if (cloudLayer.ParticleVolumetricsMaterial != null)
{
Utils.EnableOrDisableShaderKeywords(cloudLayer.ParticleVolumetricsMaterial, "SCATTERER_ON", "SCATTERER_OFF", true);
InitUniforms(cloudLayer.ParticleVolumetricsMaterial);
InitPostprocessMaterialUniforms(cloudLayer.ParticleVolumetricsMaterial);
cloudLayer.ParticleVolumetricsMaterial.SetFloat("isUnderwater", 0f);
}
if (cloudLayer.CloudShadowMaterial != null)
{
Utils.EnableOrDisableShaderKeywords(cloudLayer.CloudShadowMaterial, "SCATTERER_OCEAN_ON", "SCATTERER_OCEAN_OFF", Scatterer.Instance.mainSettings.useOceanShaders && prolandManager.hasOcean);
}
}
}
catch (Exception e)
{
Utils.LogError ("Error initiating EVE Clouds on planet: " + celestialBodyName + " Exception returned: " + e.ToString ());
}
}
}
void UpdateEVECloudMaterials ()
{
if (Scatterer.Instance.eveReflectionHandler.EVECloudLayers.ContainsKey (celestialBodyName))
{
foreach (var cloudLayer in Scatterer.Instance.eveReflectionHandler.EVECloudLayers[celestialBodyName])
{
if (cloudLayer.Clouds2dMaterial != null)
{
SetUniforms (cloudLayer.Clouds2dMaterial);
UpdatePostProcessMaterialUniforms(cloudLayer.Clouds2dMaterial);
cloudLayer.Clouds2dMaterial.SetFloat(ShaderProperties.cloudColorMultiplier_PROPERTY, cloudColorMultiplier);
cloudLayer.Clouds2dMaterial.SetFloat(ShaderProperties.cloudScatteringMultiplier_PROPERTY, cloudScatteringMultiplier);
cloudLayer.Clouds2dMaterial.SetFloat(ShaderProperties.cloudSkyIrradianceMultiplier_PROPERTY, cloudSkyIrradianceMultiplier);
cloudLayer.Clouds2dMaterial.SetFloat(ShaderProperties.preserveCloudColors_PROPERTY, EVEIntegration_preserveCloudColors ? 1f : 0f);
}
if (cloudLayer.ParticleVolumetricsMaterial != null)
{
SetUniforms(cloudLayer.ParticleVolumetricsMaterial);
UpdatePostProcessMaterialUniforms(cloudLayer.ParticleVolumetricsMaterial);
cloudLayer.ParticleVolumetricsMaterial.SetVector(ShaderProperties._PlanetWorldPos_PROPERTY, parentLocalTransform.position);
cloudLayer.ParticleVolumetricsMaterial.SetFloat(ShaderProperties.cloudColorMultiplier_PROPERTY, volumetricsColorMultiplier);
}
}
}
}
public void TogglePreserveCloudColors()
{
EVEIntegration_preserveCloudColors =!EVEIntegration_preserveCloudColors;
}
public void SetCelestialBodyName(string name) {
celestialBodyName = name;
}
public void SetParentScaledTransform(Transform parentTransform) {
parentScaledTransform = parentTransform;
}
public void SetParentLocalTransform(Transform parentTransform) {
parentLocalTransform = parentTransform;
}
//to be called on loss of rendertextures, ie alt-enter
public void ReInitMaterialUniformsOnRenderTexturesLoss()
{
if (localScatteringContainer != null)
{
InitPostprocessMaterialUniforms (localScatteringContainer.material);
}
}
public void SetUnderwater(bool value)
{
if (localScatteringContainer != null)
localScatteringContainer.SetUnderwater(value);
if ((Scatterer.Instance.eveReflectionHandler.EVEInstance != null) && Scatterer.Instance.eveReflectionHandler.EVECloudLayers.ContainsKey(celestialBodyName))
{
foreach (var cloudLayer in Scatterer.Instance.eveReflectionHandler.EVECloudLayers[celestialBodyName])
{
if (cloudLayer.ParticleVolumetricsMaterial != null)
{
cloudLayer.ParticleVolumetricsMaterial.SetFloat("isUnderwater", value ? 1f : 0f);
}
}
}
}
}
}
================================================
FILE: scatterer/Effects/Proland/Atmosphere/Utils/AtmospherePQS.cs
================================================
//note: allows adding a material to PQS, not currently in use as projector works better
//could be adapted for use with future grass/trees shader however
using System;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEngine;
using System.Collections.Generic;
namespace Scatterer
{
public class AtmospherePQS : PQSMod
{
Material atmosphereMaterial;
public override void OnSphereActive()
{
}
public override void OnQuadCreate(PQ quad)
{
List materials = new List (quad.meshRenderer.sharedMaterials);
materials.Add (atmosphereMaterial);
quad.meshRenderer.sharedMaterials= materials.ToArray();
}
public override void OnQuadDestroy(PQ quad)
{
List materials = new List (quad.meshRenderer.sharedMaterials);
materials.Remove(materials.Find(mat => mat.shader.name == "Scatterer/AtmosphericLocalScatter")); //probably slow
quad.meshRenderer.sharedMaterials = materials.ToArray ();
}
public void Apply(PQS pqs)
{
if (pqs != null)
{
this.sphere = pqs;
this.transform.parent = pqs.transform;
this.requirements = PQS.ModiferRequirements.Default;
this.modEnabled = true;
this.order = 10; //?
this.transform.localPosition = Vector3.zero;
this.transform.localRotation = Quaternion.identity;
this.transform.localScale = Vector3.one;
atmosphereMaterial = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/AtmosphericLocalScatter")]);
Utils.LogDebug ("AtmospherePQS applied");
}
}
public void Cleanup()
{
Utils.LogDebug ("AtmospherePQS removed");
}
}
}
================================================
FILE: scatterer/Effects/Proland/Atmosphere/Utils/AtmosphereProjectorContainer.cs
================================================
using System;
using UnityEngine;
namespace Scatterer
{
public class AtmosphereProjectorContainer : GenericLocalAtmosphereContainer
{
public Projector projector = null;
public AtmosphereProjectorContainer (Material atmosphereMaterial, Transform parentTransform, float Rt, ProlandManager parentManager) : base (atmosphereMaterial, parentTransform, Rt, parentManager)
{
scatteringGO = new GameObject("Scatterer atmosphere projector "+atmosphereMaterial.name);
projector = scatteringGO.AddComponent();
projector.aspectRatio = 1;
projector.orthographic = true;
projector.orthographicSize = 2*Rt;
projector.nearClipPlane = 1;
projector.farClipPlane = 4*Rt;
projector.ignoreLayers = ~((1<<0) | (1<<1) | (1<<4) | (1<<15) | (1<<16) | (1<<19)); //ignore all except 4 water 15 local 16 kerbals and 19 parts
scatteringGO.layer = 15;
scatteringGO.transform.position = parentTransform.forward * 2*Rt + parentTransform.position;
scatteringGO.transform.forward = parentTransform.position - scatteringGO.transform.position;
scatteringGO.transform.parent = parentTransform;
projector.material = atmosphereMaterial;
projector.material.CopyKeywordsFrom (atmosphereMaterial);
}
public override void UpdateContainer ()
{
bool isEnabled = !underwater && !inScaledSpace && activated;
projector.enabled = isEnabled;
scatteringGO.SetActive(isEnabled);
}
public override void Cleanup ()
{
SetActivated (false);
if(scatteringGO)
{
if(scatteringGO.transform && scatteringGO.transform.parent)
{
scatteringGO.transform.parent = null;
}
Component.Destroy(projector);
GameObject.DestroyImmediate(scatteringGO);
projector = null;
scatteringGO = null;
}
}
}
}
================================================
FILE: scatterer/Effects/Proland/Atmosphere/Utils/AtmosphereUtils.cs
================================================
using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using KSP.IO;
namespace Scatterer
{
public static class AtmosphereUtils
{
private static float Limit(float r, float mu, float Rg, float Rt)
{
float dout = -r * mu + Mathf.Sqrt(r * r * (mu * mu - 1f) + Rt * Rt);
float delta2 = r * r * (mu * mu - 1f) + (Rg) * (Rg);
if (delta2 >= 0f)
{
float din = -r * mu - Mathf.Sqrt(delta2);
if (din >= 0f)
{
dout = Mathf.Min(dout, din);
}
}
return dout;
}
// optical depth for ray (r,mu) of length d, using analytic formula
// (mu=cos(view zenith angle)), intersections with ground ignored
// H=height scale of exponential density function
private static float OpticalDepth(float H, float r, float mu, float d, float Rg, float Rt)
{
float a = Mathf.Sqrt((0.5f/H)*r);
Vector2 a01 = a*new Vector2(mu, mu + d / r);
Vector2 a01s = new Vector2(Mathf.Sign(a01.x),Mathf.Sign(a01.y));
Vector2 a01sq = a01*a01;
float x = a01s.y > a01s.x ? Mathf.Exp(a01sq.x) : 0f;
Vector2 y = a01s / (2.3193f* new Vector2(Mathf.Abs(a01.x), Mathf.Abs(a01.y)) + new Vector2(Mathf.Sqrt(1.52f*a01sq.x + 4f), Mathf.Sqrt(1.52f*a01sq.y + 4f))) * new Vector2(1f, Mathf.Exp(-d/H*(d/(2f*r)+mu)));
return Mathf.Sqrt((6.2831f*H)*r) * Mathf.Exp((Rg-r)/H) * (x + Vector2.Dot(y, new Vector2(1f, -1f)));
}
private static float OpticalDepthToBoundaries(float H, float r, float mu, float Rg, float Rt)
{
float result = 0f;
float d = Limit(r, mu, Rg, Rt);
result = OpticalDepth(H, r, mu, d, Rg, Rt);
return mu < -Mathf.Sqrt(1f - (Rg / r) * (Rg / r)) ? 1e9f : result;
}
private static Color AnalyticTransmittance(float r, float mu, float Rt, float Rg, float HR, float HM, Vector3 betaR, Vector3 betaMEx)
{
Vector3 depth = betaR * OpticalDepthToBoundaries(HR, r, mu, Rg, Rt) + betaMEx * OpticalDepthToBoundaries(HM, r, mu, Rg, Rt);
depth.x = Mathf.Clamp (Mathf.Exp (-depth.x), 1e-36f, 1f);
depth.y = Mathf.Clamp (Mathf.Exp(-depth.y), 1e-36f, 1f);
depth.z = Mathf.Clamp (Mathf.Exp(-depth.z), 1e-36f, 1f);
return new Color (depth.x,depth.y,depth.z,1f);
}
private static Vector2 GetTransmittanceUV(float r, float mu, float Rt, float Rg)
{
float uR, uMu;
uR = Mathf.Sqrt(Mathf.Max(0, (r - Rg)) / (Rt - Rg));
uMu = Mathf.Atan((mu + 0.15f) / (1.0f + 0.15f) * Mathf.Tan(1.5f)) / 1.5f;
return new Vector2(uMu, uR);
}
public static Color getOzoneExtinction(float r, float mu, float Rt, float Rg, Texture2D atmosphereAtlas, Vector2 ozoneTextureDimensions, Vector4 textureScaleAndOffsetInAtlas, Vector2 AtmosphereAtlasDimensions)
{
Vector2 uv = GetTransmittanceUV(r, mu, Rt, Rg);
uv = remapUVToAtlas(uv, ozoneTextureDimensions, textureScaleAndOffsetInAtlas, AtmosphereAtlasDimensions);
// Unity's get pixel Bilinear doesn't work exactly like shader-based bilinear sampling
// See thread https://forum.unity.com/threads/confusion-about-texture-getpixelbinear.1236826/
// Therefore manually remap from shader-based UV to unity-style UV to be able to sample bilinear correctly here
// The equivalent transformation is just to remove a half-texel offset
// Note that I checked all the math 10 times and compared GetPixelBilinear() to what the shader tex2Dlod outputs and confirmed
// There is always a half texel offset
uv -= new Vector2(0.5f, 0.5f) / AtmosphereAtlasDimensions;
return atmosphereAtlas.GetPixelBilinear(uv.x, uv.y);
}
private static Vector2 remapUVToAtlas(Vector2 uv, Vector2 oldTexDimensions, Vector4 textureScaleAndOffsetInAtlas, Vector2 AtmosphereAtlasDimensions)
{
// Remove half pixel offset
uv -= new Vector2(0.5f, 0.5f) / oldTexDimensions;
// Clamp, note the half pixel offset is taken into account on both sides
uv.x = Mathf.Clamp(uv.x, 0f, 1f - 1.0f / oldTexDimensions.x);
uv.y = Mathf.Clamp(uv.y, 0f, 1f - 1.0f / oldTexDimensions.y);
// Scale, offset and add new half pixel offset
uv = uv * new Vector2(textureScaleAndOffsetInAtlas.x, textureScaleAndOffsetInAtlas.y) +
new Vector2(textureScaleAndOffsetInAtlas.z, textureScaleAndOffsetInAtlas.w) +
new Vector2(0.5f, 0.5f) / AtmosphereAtlasDimensions;
return uv;
}
public static Color getExtinction(Vector3 camera, Vector3 viewdir, float Rt, float Rg, float HR, float HM, Vector3 betaR, Vector3 betaMEx, bool useOzone, Texture2D atmosphereAtlas, Vector2 ozoneTextureDimensions, Vector4 textureScaleAndOffsetInAtlas, Vector2 AtmosphereAtlasDimensions)
{
float r = camera.magnitude;
float rMu = Vector3.Dot(camera, viewdir);
float mu = rMu / r;
float deltaSq = Mathf.Sqrt(rMu * rMu - r * r + Rt*Rt);
float din = Mathf.Max(-rMu - deltaSq, 0f);
if (din > 0f)
{
camera += din * viewdir;
rMu += din;
mu = rMu / Rt;
r = Rt;
}
Color extinction = (r > Rt) ? Color.white : AnalyticTransmittance(r, mu, Rt, Rg, HR, HM, betaR, betaMEx);
if (useOzone && r < Rt)
extinction *= getOzoneExtinction(r, mu, Rt, Rg, atmosphereAtlas, ozoneTextureDimensions, textureScaleAndOffsetInAtlas, AtmosphereAtlasDimensions);
return extinction;
}
public static Color Hdr(Color L, float exposure) {
L = L * exposure;
L.r = L.r < 1.413 ? Mathf.Pow(L.r * 0.38317f, 1.0f / 2.2f) : 1.0f - Mathf.Exp(-L.r);
L.g = L.g < 1.413 ? Mathf.Pow(L.g * 0.38317f, 1.0f / 2.2f) : 1.0f - Mathf.Exp(-L.g);
L.b = L.b < 1.413 ? Mathf.Pow(L.b * 0.38317f, 1.0f / 2.2f) : 1.0f - Mathf.Exp(-L.b);
return L;
}
public static Color SimpleSkyirradiance(Vector3 worldP, Vector3 worldS, float Rt, float Rg, Color sunColor, Texture2D m_irradiance)
{
float r = worldP.magnitude;
if (r < 0.9 * Rg)
{
worldP.z += Rg;
r = worldP.magnitude;
}
Vector3 worldV = worldP.normalized; // vertical vector
float muS = Vector3.Dot(worldV, worldS.normalized);
// factor 2.0 : hack to increase sky contribution (numerical simulation of
// "precompued atmospheric scattering" gives less luminance than in reality)
Color skyE = 2.0f * SkyIrradiance(r, muS, Rt, Rg, sunColor, m_irradiance);
return skyE;
}
// incident sky light at given position, integrated over the hemisphere (irradiance)
// r=length(x)
// muS=dot(x,s) / r
private static Color SkyIrradiance(float r, float muS, float Rt, float Rg, Color sunColor, Texture2D m_irradiance)
{
return Irradiance(r, muS, Rt, Rg, m_irradiance) * sunColor;
}
private static Color Irradiance(float r, float muS, float Rt, float Rg, Texture2D m_irradiance)
{
Vector2 uv = GetIrradianceUV(r, muS, Rt, Rg);
return m_irradiance.GetPixelBilinear(uv.x, uv.y);
}
private static Vector2 GetIrradianceUV(float r, float muS, float Rt, float Rg)
{
float uR = (r - Rg) / (Rt - Rg);
float uMuS = (muS + 0.2f) / (1.0f + 0.2f);
return new Vector2(uMuS, uR);
}
public static float getEclipseShadow(Vector3 worldPos, Vector3 worldLightPos, Vector3 occluderSpherePosition, float occluderSphereRadius, float lightSourceRadius)
{
var lightDirection = worldLightPos - worldPos;
float lightDistance = lightDirection.magnitude;
lightDirection = lightDirection / lightDistance;
// computation of level of shadowing w
var sphereDirection = occluderSpherePosition - worldPos; //occluder planet
float sphereDistance = sphereDirection.magnitude;
sphereDirection = sphereDirection / sphereDistance;
float dd = lightDistance * (Mathf.Asin(Mathf.Min(1.0f, (Vector3.Cross(lightDirection, sphereDirection)).magnitude))
- Mathf.Asin(Mathf.Min(1.0f, occluderSphereRadius / sphereDistance)));
float w = smoothstep(-1.0f, 1.0f, -dd / lightSourceRadius);
w = w * smoothstep(0.0f, 0.2f, Vector3.Dot(lightDirection, sphereDirection));
return (1 - w);
}
// Reimplement because the Mathf Smoothstep doesn't match what is done in shaders
public static float smoothstep(float a, float b, float x)
{
float t = Mathf.Clamp01((x - a) / (b - a));
return t * t * (3.0f - (2.0f * t));
}
}
}
================================================
FILE: scatterer/Effects/Proland/Atmosphere/Utils/GenericLocalAtmosphereContainer.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using UnityEngine;
namespace Scatterer
{
public abstract class GenericLocalAtmosphereContainer
{
protected GameObject scatteringGO = null;
protected bool inScaledSpace = true;
protected bool underwater = false;
protected bool activated = false;
public Material material;
public ProlandManager manager;
public GenericLocalAtmosphereContainer (Material atmosphereMaterial, Transform parentTransform, float Rt, ProlandManager parentManager)
{
material = atmosphereMaterial;
manager = parentManager;
}
public void SetActivated (bool pEnabled)
{
activated = pEnabled;
}
public void SetInScaledSpace (bool pInScaledSpace)
{
inScaledSpace = pInScaledSpace;
}
public void SetUnderwater (bool pUnderwater)
{
underwater = pUnderwater;
}
public abstract void UpdateContainer ();
public abstract void Cleanup ();
}
}
================================================
FILE: scatterer/Effects/Proland/Atmosphere/Utils/ScaledScatteringContainer.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Scatterer
{
public class ScaledScatteringContainer
{
GameObject scaledScatteringGO;
MeshRenderer scaledScatteringMR;
public GameObject GameObject { get { return scaledScatteringGO; } }
public MeshRenderer MeshRenderer { get { return scaledScatteringMR; } }
Transform parentLocalTransform, parentScaledTransform;
public ScaledScatteringContainer(Mesh planetMesh, Material material, Transform inParentLocalTransform, Transform inParentScaledTransform)
{
parentScaledTransform = inParentScaledTransform;
parentLocalTransform = inParentLocalTransform;
string goName = "Scatterer scaled atmo";
var existingGoTransform = parentScaledTransform.FindChild(goName);
if (existingGoTransform != null)
{
GameObject.DestroyImmediate(existingGoTransform.gameObject);
}
scaledScatteringGO = new GameObject (goName);
//if depthBufferMode + new blending etc etc
scaledScatteringGO.AddComponent ();
scaledScatteringGO.transform.SetParent (parentScaledTransform, false);
MeshFilter skySphereMF = scaledScatteringGO.AddComponent();
skySphereMF.mesh = (Mesh) Mesh.Instantiate (planetMesh);
scaledScatteringMR = scaledScatteringGO.AddComponent();
scaledScatteringMR.sharedMaterial = material;
Utils.EnableOrDisableShaderKeywords (scaledScatteringMR.sharedMaterial, "LOCAL_MODE_ON", "LOCAL_MODE_OFF", false);
scaledScatteringMR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
scaledScatteringMR.receiveShadows = false;
scaledScatteringMR.motionVectorGenerationMode = MotionVectorGenerationMode.Camera;
scaledScatteringMR.enabled = true;
if (HighLogic.LoadedScene == GameScenes.MAINMENU)
scaledScatteringGO.layer = 15;
else
scaledScatteringGO.layer = 10;
}
public void ApplyNewMesh(Mesh planetMesh)
{
MeshFilter skySphereMF = scaledScatteringGO.GetComponent();
skySphereMF.mesh.Clear ();
skySphereMF.mesh = (Mesh) Mesh.Instantiate (planetMesh);
}
public void SwitchLocalMode()
{
scaledScatteringGO.layer = 15;
scaledScatteringGO.transform.localScale = parentScaledTransform.localScale * ScaledSpace.ScaleFactor;
scaledScatteringGO.transform.localPosition = Vector3.zero;
scaledScatteringGO.transform.SetParent(parentLocalTransform, false);
Utils.EnableOrDisableShaderKeywords (scaledScatteringMR.sharedMaterial, "LOCAL_MODE_ON", "LOCAL_MODE_OFF", true);
}
public void SwitchScaledMode()
{
scaledScatteringGO.layer = 10;
scaledScatteringGO.transform.localScale = Vector3.one;
scaledScatteringGO.transform.localPosition = Vector3.zero;
scaledScatteringGO.transform.localRotation = Quaternion.identity;
scaledScatteringGO.transform.SetParent(parentScaledTransform, false);
Utils.EnableOrDisableShaderKeywords (scaledScatteringMR.sharedMaterial, "LOCAL_MODE_ON", "LOCAL_MODE_OFF", false);
}
public void Cleanup()
{
if (scaledScatteringMR != null)
{
scaledScatteringMR.enabled = false;
UnityEngine.Component.Destroy (scaledScatteringMR);
}
if (scaledScatteringGO != null)
{
scaledScatteringGO.SetActive(false);
UnityEngine.Object.Destroy(scaledScatteringGO);
}
}
}
public class ScaledScatteringScreenCopy : MonoBehaviour
{
void OnWillRenderObject()
{
Camera cam = Camera.current;
if (!cam)
return;
ScreenCopyCommandBuffer.EnableScreenCopyForFrame (cam);
}
}
}
================================================
FILE: scatterer/Effects/Proland/Atmosphere/Utils/ScreenSpaceScatteringContainer.cs
================================================
using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine.Rendering;
using KSP.IO;
namespace Scatterer
{
public class ScreenSpaceScattering : MonoBehaviour
{
public Material material;
MeshRenderer scatteringMR;
public bool hasOcean = false;
bool quarterRes = false;
//Dictionary to check if we added the ScatteringCommandBuffer to the camera
private Dictionary cameraToScatteringCommandBuffer = new Dictionary();
public void Init(bool inQuarterRes)
{
scatteringMR = gameObject.GetComponent();
material.SetOverrideTag("IgnoreProjector", "True");
scatteringMR.sharedMaterial = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/invisible")]);
scatteringMR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
scatteringMR.receiveShadows = false;
scatteringMR.enabled = true;
GetComponent().mesh.bounds = new Bounds (Vector4.zero, new Vector3 (Mathf.Infinity, Mathf.Infinity, Mathf.Infinity));
gameObject.layer = (int) 15;
quarterRes = inQuarterRes;
}
public void SetActive(bool active)
{
scatteringMR.enabled = active;
}
void OnWillRenderObject()
{
if (scatteringMR.enabled && material != null)
{
Camera cam = Camera.current;
if (!cam)
return;
if (!hasOcean)
ScreenCopyCommandBuffer.EnableScreenCopyForFrame (cam);
if (cameraToScatteringCommandBuffer.ContainsKey (cam))
{
if (cameraToScatteringCommandBuffer[cam] != null)
{
cameraToScatteringCommandBuffer[cam].EnableForThisFrame();
}
}
else
{
//we add null to the cameras we don't want to render on so we don't do a string compare every time
if ((cam.name == "TRReflectionCamera") || (cam.name=="Reflection Probes Camera")) //I think this should be this way to scattering as well but test I guess
{
cameraToScatteringCommandBuffer[cam] = null;
}
else
{
ScatteringCommandBuffer scatteringCommandBuffer = (ScatteringCommandBuffer) cam.gameObject.AddComponent(typeof(ScatteringCommandBuffer));
scatteringCommandBuffer.targetRenderer = scatteringMR;
scatteringCommandBuffer.targetMaterial = material;
scatteringCommandBuffer.Initialize(hasOcean, quarterRes);
scatteringCommandBuffer.EnableForThisFrame();
cameraToScatteringCommandBuffer[cam] = scatteringCommandBuffer;
}
}
}
}
public void OnDestroy()
{
foreach (var scatteringCommandBuffer in cameraToScatteringCommandBuffer.Values)
{
if (scatteringCommandBuffer)
{
Component.DestroyImmediate(scatteringCommandBuffer);
}
}
}
}
public class ScatteringCommandBuffer : MonoBehaviour
{
bool renderingEnabled = false;
public MeshRenderer targetRenderer;
public Material targetMaterial;
private Camera targetCamera;
private CommandBuffer rendererCommandBuffer, quarterResRendererCommandBuffer;
// cached values; if these change we need to recreate the RTs
int m_width, m_height;
bool m_hdrEnabled;
bool m_hasOcean;
//downscaledRenderTexture0 will hold scattering.RGB in RGB channels and extinction.R in alpha, downscaledRenderTexture1 will hold extinction.GB in RG
private RenderTexture downscaledRenderTexture0, downscaledRenderTexture1, downscaledDepthRenderTexture;
private Material downscaleDepthMaterial, compositeScatteringMaterial;
public void Initialize(bool inHasOcean, bool quarterRes)
{
targetCamera = GetComponent ();
targetCamera.depthTextureMode = targetCamera.depthTextureMode | DepthTextureMode.Depth;
m_hasOcean = inHasOcean;
//if no depth downscaling, render directly to screen
rendererCommandBuffer = new CommandBuffer();
rendererCommandBuffer.name = "Scatterer screen-space scattering CommandBuffer";
targetMaterial.SetInt(ShaderProperties._ZwriteVariable_PROPERTY, inHasOcean ? 1 : 0);
rendererCommandBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget);
rendererCommandBuffer.DrawRenderer(targetRenderer, targetMaterial, 0, 0); //pass 0 render to screen
if (quarterRes)
{
quarterResRendererCommandBuffer = new CommandBuffer();
quarterResRendererCommandBuffer.name = "Scatterer 1/4 res screen-space scattering CommandBuffer";
downscaleDepthMaterial = new Material(ShaderReplacer.Instance.LoadedShaders [("Scatterer/DownscaleDepth")]);
compositeScatteringMaterial = new Material(ShaderReplacer.Instance.LoadedShaders [("Scatterer/CompositeDownscaledScattering")]);
Utils.EnableOrDisableShaderKeywords(compositeScatteringMaterial, "CUSTOM_OCEAN_ON", "CUSTOM_OCEAN_OFF", inHasOcean);
compositeScatteringMaterial.SetInt (ShaderProperties._ZwriteVariable_PROPERTY, inHasOcean ? 1 : 0);
Utils.SetToneMapping(compositeScatteringMaterial);
int width, height;
GetRenderDimensions(out width, out height);
SetupQuarterResCommandBuffer(width, height);
}
}
void SetupQuarterResCommandBuffer(int width, int height)
{
CreateRenderTextures(width, height);
quarterResRendererCommandBuffer.Clear();
//1) Downscale depth
if (m_hasOcean)
quarterResRendererCommandBuffer.Blit(null, downscaledDepthRenderTexture, downscaleDepthMaterial, 1); //ocean depth buffer downsample
else
quarterResRendererCommandBuffer.Blit(null, downscaledDepthRenderTexture, downscaleDepthMaterial, 0); //default depth buffer downsample
quarterResRendererCommandBuffer.SetGlobalTexture("ScattererDownscaledScatteringDepth", downscaledDepthRenderTexture);
//2) Render 1/4 res scattering+extinction to 1 RGBA + 1 RG texture
RenderTargetIdentifier[] downscaledRenderTextures = { new RenderTargetIdentifier(downscaledRenderTexture0), new RenderTargetIdentifier(downscaledRenderTexture1) };
quarterResRendererCommandBuffer.SetRenderTarget(downscaledRenderTextures, downscaledRenderTexture0.depthBuffer);
quarterResRendererCommandBuffer.ClearRenderTarget(false, true, Color.clear);
quarterResRendererCommandBuffer.DrawRenderer(targetRenderer, targetMaterial, 0, 1); //pass 1 render to textures
quarterResRendererCommandBuffer.SetGlobalTexture("DownscaledScattering0", downscaledRenderTexture0);
quarterResRendererCommandBuffer.SetGlobalTexture("DownscaledScattering1", downscaledRenderTexture1);
//3) Render quad to screen that reads from downscaled textures and full res depth and performs near-depth upsampling
quarterResRendererCommandBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget);
quarterResRendererCommandBuffer.DrawRenderer(targetRenderer, compositeScatteringMaterial, 0, 0);
}
void GetRenderDimensions(out int width, out int height)
{
if (targetCamera.activeTexture)
{
width = targetCamera.activeTexture.width;
height = targetCamera.activeTexture.height;
}
else
{
width = targetCamera.pixelWidth;
height = targetCamera.pixelHeight;
}
}
void CreateRenderTextures (int width, int height)
{
m_width = width;
m_height = height;
m_hdrEnabled = targetCamera.allowHDR;
width /= 2;
height /= 2;
if (downscaledRenderTexture0 != null) downscaledRenderTexture0.Release();
if (downscaledRenderTexture1 != null) downscaledRenderTexture1.Release();
if (downscaledDepthRenderTexture != null) downscaledDepthRenderTexture.Release();
downscaledRenderTexture0 = new RenderTexture (width, height, 0, m_hdrEnabled ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.ARGB32);
downscaledRenderTexture0.anisoLevel = 1;
downscaledRenderTexture0.antiAliasing = 1;
downscaledRenderTexture0.volumeDepth = 0;
downscaledRenderTexture0.useMipMap = false;
downscaledRenderTexture0.autoGenerateMips = false;
downscaledRenderTexture0.filterMode = FilterMode.Point;
downscaledRenderTexture0.Create ();
downscaledRenderTexture1 = new RenderTexture (width, height, 0, m_hdrEnabled ? RenderTextureFormat.RGHalf : RenderTextureFormat.RG16);
downscaledRenderTexture1.anisoLevel = 1;
downscaledRenderTexture1.antiAliasing = 1;
downscaledRenderTexture1.volumeDepth = 0;
downscaledRenderTexture1.useMipMap = false;
downscaledRenderTexture1.autoGenerateMips = false;
downscaledRenderTexture1.filterMode = FilterMode.Point;
downscaledRenderTexture1.Create ();
downscaledDepthRenderTexture = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat);
downscaledDepthRenderTexture.anisoLevel = 1;
downscaledDepthRenderTexture.antiAliasing = 1;
downscaledDepthRenderTexture.volumeDepth = 0;
downscaledDepthRenderTexture.useMipMap = false;
downscaledDepthRenderTexture.autoGenerateMips = false;
downscaledDepthRenderTexture.filterMode = FilterMode.Point;
downscaledDepthRenderTexture.Create();
}
public void EnableForThisFrame()
{
if (!renderingEnabled)
{
bool screenShotModeEnabled = GameSettings.TAKE_SCREENSHOT.GetKeyDown(false);
if (quarterResRendererCommandBuffer != null && !screenShotModeEnabled)
{
int width, height;
GetRenderDimensions(out width, out height);
if (width != m_width || height != m_height || targetCamera.allowHDR != m_hdrEnabled)
{
SetupQuarterResCommandBuffer(width, height);
}
targetCamera.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, quarterResRendererCommandBuffer);
}
else
targetCamera.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, rendererCommandBuffer);
renderingEnabled = true;
}
}
void OnPreRender()
{
targetMaterial.SetMatrix(ShaderProperties.CameraToWorld_PROPERTY, targetCamera.cameraToWorldMatrix);
}
void OnPostRender()
{
if (renderingEnabled && targetCamera.stereoActiveEye != Camera.MonoOrStereoscopicEye.Left)
{
targetCamera.RemoveCommandBuffer(CameraEvent.BeforeForwardAlpha, rendererCommandBuffer);
if (quarterResRendererCommandBuffer != null) targetCamera.RemoveCommandBuffer(CameraEvent.BeforeForwardAlpha, quarterResRendererCommandBuffer);
renderingEnabled = false;
}
}
public void OnDestroy ()
{
if (targetCamera && rendererCommandBuffer != null)
{
targetCamera.RemoveCommandBuffer (CameraEvent.BeforeForwardAlpha, rendererCommandBuffer);
rendererCommandBuffer = null;
if (quarterResRendererCommandBuffer != null)
{
targetCamera.RemoveCommandBuffer(CameraEvent.BeforeForwardAlpha, quarterResRendererCommandBuffer);
quarterResRendererCommandBuffer = null;
}
renderingEnabled = true;
if (downscaledDepthRenderTexture)
downscaledDepthRenderTexture.Release();
if (downscaledRenderTexture0)
downscaledRenderTexture0.Release();
if (downscaledRenderTexture1)
downscaledRenderTexture1.Release();
}
}
}
public class ScreenSpaceScatteringContainer : GenericLocalAtmosphereContainer
{
ScreenSpaceScattering screenSpaceScattering;
public ScreenSpaceScatteringContainer (Material atmosphereMaterial, Transform parentTransform, float Rt, ProlandManager parentManager, bool quarterRes) : base (atmosphereMaterial, parentTransform, Rt, parentManager)
{
scatteringGO = GameObject.CreatePrimitive(PrimitiveType.Quad);
scatteringGO.name = "Scatterer screenspace scattering " + parentManager.parentCelestialBody.name;
GameObject.Destroy (scatteringGO.GetComponent ());
scatteringGO.transform.localScale = Vector3.one;
//for now just disable this from reflection probe because no idea how to add the effect on it, no access to depth buffer and I don't feel like the perf hit would be worth to enable it
//this will be handled by the ocean if it is present
//TODO: remove this after finalizing 1/4 res since now we just use commandbuffer
if (!manager.hasOcean || !Scatterer.Instance.mainSettings.useOceanShaders)
{
DisableEffectsChecker disableEffectsChecker = scatteringGO.AddComponent ();
disableEffectsChecker.manager = this.manager;
}
screenSpaceScattering = scatteringGO.AddComponent();
scatteringGO.transform.position = parentTransform.position;
scatteringGO.transform.parent = parentTransform;
screenSpaceScattering.material = atmosphereMaterial;
screenSpaceScattering.material.CopyKeywordsFrom (atmosphereMaterial);
screenSpaceScattering.hasOcean = manager.hasOcean && Scatterer.Instance.mainSettings.useOceanShaders;
screenSpaceScattering.Init(quarterRes);
}
public override void UpdateContainer ()
{
bool isEnabled = !underwater && !inScaledSpace && activated;
screenSpaceScattering.SetActive(isEnabled);
scatteringGO.SetActive(isEnabled);
}
public override void Cleanup ()
{
SetActivated (false);
if(scatteringGO)
{
if(scatteringGO.transform && scatteringGO.transform.parent)
{
scatteringGO.transform.parent = null;
}
Component.DestroyImmediate(screenSpaceScattering);
GameObject.DestroyImmediate(scatteringGO);
}
}
}
}
================================================
FILE: scatterer/Effects/Proland/Atmosphere/Utils/SkySphereContainer.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Scatterer
{
public class SkySphereContainer
{
GameObject skySphereGO;
MeshRenderer skySphereMR;
public GameObject GameObject { get { return skySphereGO; } }
public MeshRenderer MeshRenderer { get { return skySphereMR; } }
Transform parentLocalTransform, parentScaledTransform;
MeshFilter skySphereMF;
public SkySphereContainer(float size, Material material, Transform inParentLocalTransform, Transform inParentScaledTransform)
{
skySphereGO = GameObject.CreatePrimitive(PrimitiveType.Sphere);
GameObject.Destroy (skySphereGO.GetComponent ());
skySphereGO.transform.localScale = Vector3.one;
skySphereMF = skySphereGO.GetComponent();
Vector3[] verts = skySphereMF.mesh.vertices;
for (int i = 0; i < verts.Length; i++)
{
verts[i] = verts[i].normalized * size;
}
skySphereMF.mesh.vertices = verts;
skySphereMF.mesh.RecalculateBounds();
skySphereMF.mesh.RecalculateNormals();
skySphereMR = skySphereGO.GetComponent();
skySphereMR.sharedMaterial = material;
Utils.EnableOrDisableShaderKeywords (skySphereMR.sharedMaterial, "LOCAL_SKY_ON", "LOCAL_SKY_OFF", false);
skySphereMR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
skySphereMR.receiveShadows = false;
skySphereMR.motionVectorGenerationMode = MotionVectorGenerationMode.Camera;
skySphereMR.enabled = true;
if (HighLogic.LoadedScene == GameScenes.MAINMENU)
skySphereGO.layer = 15;
else
skySphereGO.layer = 9;
skySphereGO.transform.position = inParentScaledTransform.position;
skySphereGO.transform.parent = inParentScaledTransform;
parentScaledTransform = inParentScaledTransform;
parentLocalTransform = inParentLocalTransform;
}
public void SwitchLocalMode()
{
skySphereGO.layer = 15;
skySphereGO.transform.parent = null;
skySphereGO.transform.position = parentLocalTransform.position;
skySphereGO.transform.localScale = new Vector3(ScaledSpace.ScaleFactor, ScaledSpace.ScaleFactor, ScaledSpace.ScaleFactor);
skySphereGO.transform.parent = parentLocalTransform;
Utils.EnableOrDisableShaderKeywords (skySphereMR.sharedMaterial, "LOCAL_SKY_ON", "LOCAL_SKY_OFF", true);
skySphereGO.AddComponent ().Init(skySphereMR.sharedMaterial);
}
public void SwitchScaledMode()
{
skySphereGO.layer = 9;
skySphereGO.transform.parent = null;
skySphereGO.transform.position = parentScaledTransform.position;
skySphereGO.transform.localScale = Vector3.one;
skySphereGO.transform.parent = parentScaledTransform;
Utils.EnableOrDisableShaderKeywords (skySphereMR.sharedMaterial, "LOCAL_SKY_ON", "LOCAL_SKY_OFF", false);
var scrCopy = skySphereGO.GetComponent ();
if (scrCopy)
UnityEngine.Component.DestroyImmediate (scrCopy);
}
public void Resize(float size)
{
Vector3[] verts = skySphereMF.mesh.vertices;
for (int i = 0; i < verts.Length; i++)
{
verts[i] = verts[i].normalized * size;
}
skySphereMF.mesh.vertices = verts;
skySphereMF.mesh.RecalculateBounds();
skySphereMF.mesh.RecalculateNormals();
}
public void Cleanup()
{
if (skySphereMR != null)
{
skySphereMR.enabled = false;
UnityEngine.Component.DestroyImmediate (skySphereMR);
}
if (skySphereGO != null)
{
UnityEngine.Object.DestroyImmediate(skySphereGO);
}
}
}
public class SkySphereScreenCopy : MonoBehaviour
{
Material material;
public void Init(Material material)
{
this.material = material;
}
void OnWillRenderObject()
{
Camera cam = Camera.current;
if (!cam)
return;
if (cam == Scatterer.Instance.nearCamera && !Scatterer.Instance.unifiedCameraMode)
{
material.SetFloat(ShaderProperties.renderSkyOnCurrentCamera_PROPERTY, 0f);
}
else
{
material.SetFloat(ShaderProperties.renderSkyOnCurrentCamera_PROPERTY, 1f);
}
ScreenCopyCommandBuffer.EnableScreenCopyForFrame (cam);
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/Caustics/CausticsLightRaysRenderer.cs
================================================
using UnityEngine;
using UnityEngine.Rendering;
using System.Collections.Generic;
using System;
namespace Scatterer
{
// First class inits the material and OnWillRender adds a script to relevant cameras, the given script adds and removes commandbuffers before and after rendering? yes, also enables only OnWillRender and if underwater
public class CausticsLightRaysRenderer : MonoBehaviour
{
public Material CausticsLightRaysMaterial;
Texture2D causticsTexture;
public bool isEnabled = false;
public bool commandBufferAdded = false;
public OceanNode oceanNode;
private Dictionary CameraToLightRaysScript = new Dictionary();
public CausticsLightRaysRenderer ()
{
}
//Todo refactor and make caustics class which handles the common code of lightrays and shadowmask?
public bool Init(string causticsTexturePath,Vector2 causticsLayer1Scale,Vector2 causticsLayer1Speed,Vector2 causticsLayer2Scale,
Vector2 causticsLayer2Speed, float causticsMultiply, float causticsMinBrightness, float oceanRadius, float blurDepth, OceanNode oceanNodeIn, float lightRaysStrength)
{
if (string.IsNullOrEmpty (causticsTexturePath) || !System.IO.File.Exists (Utils.GameDataPath+causticsTexturePath))
{
Utils.LogInfo("Caustics texture "+ Utils.GameDataPath+causticsTexturePath +" not found, disabling caustics light rays for current planet");
return false;
}
else
{
if (CausticsLightRaysMaterial == null) {
CausticsLightRaysMaterial = new Material (ShaderReplacer.Instance.LoadedShaders [("Scatterer/CausticsGodraysRaymarch")]);
}
causticsTexture = new Texture2D (1, 1);
causticsTexture.LoadImage (System.IO.File.ReadAllBytes (Utils.GameDataPath+causticsTexturePath));
causticsTexture.wrapMode = TextureWrapMode.Repeat;
CausticsLightRaysMaterial.SetTexture ("_CausticsTexture", causticsTexture);
CausticsLightRaysMaterial.SetVector ("layer1Scale", causticsLayer1Scale);
CausticsLightRaysMaterial.SetVector ("layer1Speed", causticsLayer1Speed);
CausticsLightRaysMaterial.SetVector ("layer2Scale", causticsLayer2Scale);
CausticsLightRaysMaterial.SetVector ("layer2Speed", causticsLayer2Speed);
CausticsLightRaysMaterial.SetFloat ("causticsMultiply", causticsMultiply);
CausticsLightRaysMaterial.SetFloat ("causticsMinBrightness", causticsMinBrightness);
CausticsLightRaysMaterial.SetFloat ("oceanRadius", oceanRadius);
CausticsLightRaysMaterial.SetFloat ("causticsBlurDepth", blurDepth);
CausticsLightRaysMaterial.SetFloat ("transparencyDepth", oceanNodeIn.transparencyDepth);
CausticsLightRaysMaterial.SetFloat ("lightRaysStrength", lightRaysStrength);
CausticsLightRaysMaterial.EnableKeyword ("SPHERE_PLANET");
CausticsLightRaysMaterial.DisableKeyword ("FLAT_PLANET"); //for testing in unity editor only, obviously, Kerbin is not flat I swear
oceanNode = oceanNodeIn;
isEnabled = true;
return true;
}
}
public void OnWillRenderObject()
{
if (isEnabled && oceanNode.isUnderwater)
{
Camera cam = Camera.current;
if (!cam || MapView.MapIsEnabled || oceanNode.prolandManager.skyNode.inScaledSpace)
return;
if (!CameraToLightRaysScript.ContainsKey (cam))
{
if ((cam.name == "Reflection Probes Camera") || (cam.name == "ScattererPartialDepthBuffer"))
{
//we add it anyway to avoid doing a string compare
CameraToLightRaysScript [cam] = null;
}
else
{
CameraToLightRaysScript [cam] = (CausticsLightRaysCameraScript)cam.gameObject.AddComponent (typeof(CausticsLightRaysCameraScript));
CameraToLightRaysScript [cam].CausticsLightRaysMaterial = CausticsLightRaysMaterial;
CameraToLightRaysScript [cam].Init (oceanNode);
}
}
else
{
if (CameraToLightRaysScript [cam] != null)
{
CameraToLightRaysScript [cam].EnableForThisFrame ();
}
}
}
}
public void OnDestroy ()
{
foreach (CausticsLightRaysCameraScript script in CameraToLightRaysScript.Values)
{
if (script != null)
{
script.CleanUp();
Component.Destroy(script);
}
}
}
}
public class CausticsLightRaysCameraScript : MonoBehaviour
{
public Material CausticsLightRaysMaterial, compositeLightRaysMaterial;
CommandBuffer commandBuffer;
Camera targetCamera;
private RenderTexture targetRT, targetRT2;
private RenderTexture downscaledDepthRT;
private Material downscaleDepthMaterial;
bool isInitialized = false;
bool renderingEnabled = false;
Light targetLight;
private OceanNode oceanNode;
public CausticsLightRaysCameraScript ()
{
}
public void Init(OceanNode oceanNodeIn)
{
targetCamera = GetComponent();
if (targetCamera.targetTexture)
{
targetRT = new RenderTexture (targetCamera.targetTexture.width / 4, targetCamera.targetTexture.height / 4, 0, RenderTextureFormat.R8);
}
else
{
targetRT = new RenderTexture (Screen.width / 4, Screen.height / 4, 0, RenderTextureFormat.R8);
}
targetRT.anisoLevel = 1;
targetRT.antiAliasing = 1;
targetRT.volumeDepth = 0;
targetRT.useMipMap = true;
targetRT.autoGenerateMips = false;
targetRT.filterMode = FilterMode.Bilinear;
targetRT.Create();
targetRT2 = new RenderTexture (targetRT.width, targetRT.height, 0, RenderTextureFormat.R8);
targetRT2.anisoLevel = 1;
targetRT2.antiAliasing = 1;
targetRT2.volumeDepth = 0;
targetRT2.useMipMap = true;
targetRT2.autoGenerateMips = false;
targetRT2.filterMode = FilterMode.Bilinear;
targetRT2.Create();
downscaledDepthRT = new RenderTexture(targetRT.width, targetRT.height, 0, RenderTextureFormat.RFloat);
downscaledDepthRT.anisoLevel = 1;
downscaledDepthRT.antiAliasing = 1;
downscaledDepthRT.volumeDepth = 0;
downscaledDepthRT.useMipMap = false;
downscaledDepthRT.autoGenerateMips = false;
downscaledDepthRT.filterMode = FilterMode.Point;
downscaledDepthRT.Create();
downscaleDepthMaterial = new Material(ShaderReplacer.Instance.LoadedShaders [("Scatterer/DownscaleDepth")]);
compositeLightRaysMaterial = new Material (ShaderReplacer.Instance.LoadedShaders [("Scatterer/CompositeCausticsGodrays")]);
compositeLightRaysMaterial.SetTexture ("LightRaysTexture", targetRT);
compositeLightRaysMaterial.SetColor(ShaderProperties._sunColor_PROPERTY, oceanNodeIn.prolandManager.getIntensityModulatedSunColor());
compositeLightRaysMaterial.SetVector ("_Underwater_Color", oceanNodeIn.m_UnderwaterColor);
commandBuffer = new CommandBuffer();
commandBuffer.name = "Scatterer caustics renderer CommandBuffer";
//downscale depth to 1/16
commandBuffer.Blit(null, downscaledDepthRT, downscaleDepthMaterial, 0);
commandBuffer.SetGlobalTexture("ScattererDownscaledDepth", downscaledDepthRT);
//render
commandBuffer.Blit(null, targetRT, CausticsLightRaysMaterial);
//bilateral blur, 2 taps seems enough
commandBuffer.SetGlobalVector ("BlurDir", new Vector2(0,1));
commandBuffer.SetGlobalTexture ("TextureToBlur", targetRT);
commandBuffer.Blit(null, targetRT2, downscaleDepthMaterial, 2);
commandBuffer.SetGlobalVector ("BlurDir", new Vector2(1,0));
commandBuffer.SetGlobalTexture ("TextureToBlur", targetRT2);
commandBuffer.Blit(null, targetRT, downscaleDepthMaterial, 2);
//copy to screen
commandBuffer.Blit(null, BuiltinRenderTextureType.CameraTarget, compositeLightRaysMaterial);
targetLight = oceanNodeIn.prolandManager.mainSunLight;
oceanNode = oceanNodeIn;
isInitialized = true;
}
public void EnableForThisFrame()
{
if (isInitialized)
{
targetCamera.AddCommandBuffer(CameraEvent.AfterForwardAlpha, commandBuffer);
//TODO: move this out of here
float warpTime = (TimeWarp.CurrentRate > 1) ? (float) Planetarium.GetUniversalTime() : 0f;
CausticsLightRaysMaterial.SetFloat (ShaderProperties.warpTime_PROPERTY, warpTime);
// If we use sunlightExtinction, reuse already computed extinction color
if (Scatterer.Instance.mainSettings.sunlightExtinction)
{
compositeLightRaysMaterial.SetColor(ShaderProperties._sunColor_PROPERTY, oceanNode.prolandManager.getIntensityModulatedSunColor() * Scatterer.Instance.sunlightModulatorsManagerInstance.GetLastModulateColor(targetLight));
}
renderingEnabled = true;
}
}
public void OnPostRender()
{
if (renderingEnabled && targetCamera.stereoActiveEye != Camera.MonoOrStereoscopicEye.Left)
{
targetCamera.RemoveCommandBuffer(CameraEvent.AfterForwardAlpha, commandBuffer);
renderingEnabled = false;
}
}
public void CleanUp()
{
renderingEnabled = false;
if (commandBuffer != null)
{
if (targetCamera)
{
targetCamera.RemoveCommandBuffer (CameraEvent.AfterForwardAlpha, commandBuffer);
}
commandBuffer.Dispose ();
}
targetRT.Release ();
targetRT2.Release ();
downscaledDepthRT.Release ();
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/Caustics/CausticsShadowMaskModulate.cs
================================================
// after light's screenspace shadow mask is computed, apply caustics to it
using UnityEngine;
using UnityEngine.Rendering;
using System.Collections.Generic;
using System;
namespace Scatterer
{
//transform this to general caustics class, pass to it the light and once of the ocean's meshrenderers?
//how to handle the lightrays? do we need to render a quad to screen? do we set it as texture which the underwaterProjector reads from?
public class CausticsShadowMaskModulate : MonoBehaviour
{
private CommandBuffer m_Buffer;
private Light sunLight;
public Material CausticsShadowMaskModulateMaterial;
Texture2D causticsTexture;
public bool isEnabled = false;
public bool commandBufferAdded = false;
public CausticsShadowMaskModulate ()
{
}
public bool Init(string causticsTexturePath,Vector2 causticsLayer1Scale,Vector2 causticsLayer1Speed,Vector2 causticsLayer2Scale,
Vector2 causticsLayer2Speed, float causticsMultiply, float causticsMinBrightness, float oceanRadius, float blurDepth, Light inputSunlight)
{
if (string.IsNullOrEmpty (causticsTexturePath) || !System.IO.File.Exists (Utils.GameDataPath+causticsTexturePath))
{
Utils.LogInfo("Caustics texture "+ Utils.GameDataPath+causticsTexturePath +" not found, disabling caustics for current planet");
return false;
}
else
{
if (!CausticsShadowMaskModulateMaterial) {
CausticsShadowMaskModulateMaterial = new Material (ShaderReplacer.Instance.LoadedShaders [("Scatterer/CausticsOcclusion")]);
}
causticsTexture = new Texture2D (1, 1);
causticsTexture.LoadImage (System.IO.File.ReadAllBytes (Utils.GameDataPath+causticsTexturePath));
causticsTexture.wrapMode = TextureWrapMode.Repeat;
CausticsShadowMaskModulateMaterial.SetTexture ("_CausticsTexture", causticsTexture);
CausticsShadowMaskModulateMaterial.SetVector ("layer1Scale", causticsLayer1Scale);
CausticsShadowMaskModulateMaterial.SetVector ("layer1Speed", causticsLayer1Speed);
CausticsShadowMaskModulateMaterial.SetVector ("layer2Scale", causticsLayer2Scale);
CausticsShadowMaskModulateMaterial.SetVector ("layer2Speed", causticsLayer2Speed);
CausticsShadowMaskModulateMaterial.SetFloat ("causticsMultiply", causticsMultiply);
CausticsShadowMaskModulateMaterial.SetFloat ("causticsMinBrightness", causticsMinBrightness);
CausticsShadowMaskModulateMaterial.SetFloat ("oceanRadius", oceanRadius);
CausticsShadowMaskModulateMaterial.SetFloat ("causticsBlurDepth", blurDepth);
CausticsShadowMaskModulateMaterial.EnableKeyword ("SPHERE_PLANET");
CausticsShadowMaskModulateMaterial.DisableKeyword ("FLAT_PLANET"); //for testing in unity editor only, obviously, Kerbin is not flat I swear
sunLight = inputSunlight;
m_Buffer = new CommandBuffer ();
m_Buffer.name = "Scatterer caustics shadowMask modulate CommandBuffer";
m_Buffer.Blit (null, BuiltinRenderTextureType.CurrentActive, CausticsShadowMaskModulateMaterial);
AddCommandBuffer ();
isEnabled = true;
return true;
}
}
public void AddCommandBuffer()
{
sunLight.AddCommandBuffer (LightEvent.AfterScreenspaceMask, m_Buffer);
commandBufferAdded = true;
}
public void UpdateCaustics()
{
if (isEnabled)
{
float warpTime = (TimeWarp.CurrentRate > 1) ? (float) Planetarium.GetUniversalTime() : 0f;
CausticsShadowMaskModulateMaterial.SetFloat (ShaderProperties.warpTime_PROPERTY, warpTime);
}
if (commandBufferAdded && !isEnabled)
{
RemoveCommandBuffer();
}
else if (!commandBufferAdded && isEnabled)
{
AddCommandBuffer();
}
}
public void RemoveCommandBuffer ()
{
if (sunLight)
sunLight.RemoveCommandBuffer (LightEvent.AfterScreenspaceMask, m_Buffer);
commandBufferAdded = false;
}
public void OnDestroy ()
{
RemoveCommandBuffer ();
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/FourierCPU.cs
================================================
using UnityEngine;
using System.Collections;
namespace Scatterer
{
public class FourierCPU
{
int m_size;
float m_fsize;
int m_passes;
public float[] m_butterflyLookupTable = null;
public FourierCPU(int size)
{
if (!Mathf.IsPowerOfTwo(size))
{
Utils.LogDebug("Fourier grid size must be pow2 number, changing to nearest pow2 number");
size = Mathf.NextPowerOfTwo(size);
}
m_size = size; //must be pow2 num
m_fsize = (float)m_size;
m_passes = (int)(Mathf.Log(m_fsize) / Mathf.Log(2.0f));
}
//Performs two FFTs on two complex numbers packed in a vector4
Vector4 FFT(Vector2 w, Vector4 input1, Vector4 input2)
{
input1.x += w.x * input2.x - w.y * input2.y;
input1.y += w.y * input2.x + w.x * input2.y;
input1.z += w.x * input2.z - w.y * input2.w;
input1.w += w.y * input2.z + w.x * input2.w;
return input1;
}
//Performs one FFT on a complex number
Vector2 FFT(Vector2 w, Vector2 input1, Vector2 input2)
{
input1.x += w.x * input2.x - w.y * input2.y;
input1.y += w.y * input2.x + w.x * input2.y;
return input1;
}
public int PeformFFT(int startIdx, Vector4[,] data0, Vector4[,] data1, Vector4[,] data2)
{
int x; int y; int i;
int idx = 0; int idx1; int bftIdx;
int X; int Y;
Vector2 w;
int j = startIdx;
for (i = 0; i < m_passes; i++, j++)
{
idx = j % 2;
idx1 = (j + 1) % 2;
for (x = 0; x < m_size; x++)
{
for (y = 0; y < m_size; y++)
{
bftIdx = 4 * (x + i * m_size);
X = (int)m_butterflyLookupTable[bftIdx + 0];
Y = (int)m_butterflyLookupTable[bftIdx + 1];
w.x = m_butterflyLookupTable[bftIdx + 2];
w.y = m_butterflyLookupTable[bftIdx + 3];
data0[idx, x + y * m_size] = FFT(w, data0[idx1, X + y * m_size], data0[idx1, Y + y * m_size]);
data1[idx, x + y * m_size] = FFT(w, data1[idx1, X + y * m_size], data1[idx1, Y + y * m_size]);
data2[idx, x + y * m_size] = FFT(w, data2[idx1, X + y * m_size], data2[idx1, Y + y * m_size]);
}
}
}
for (i = 0; i < m_passes; i++, j++)
{
idx = j % 2;
idx1 = (j + 1) % 2;
for (x = 0; x < m_size; x++)
{
for (y = 0; y < m_size; y++)
{
bftIdx = 4 * (y + i * m_size);
X = (int)m_butterflyLookupTable[bftIdx + 0];
Y = (int)m_butterflyLookupTable[bftIdx + 1];
w.x = m_butterflyLookupTable[bftIdx + 2];
w.y = m_butterflyLookupTable[bftIdx + 3];
data0[idx, x + y * m_size] = FFT(w, data0[idx1, x + X * m_size], data0[idx1, x + Y * m_size]);
data1[idx, x + y * m_size] = FFT(w, data1[idx1, x + X * m_size], data1[idx1, x + Y * m_size]);
data2[idx, x + y * m_size] = FFT(w, data2[idx1, x + X * m_size], data2[idx1, x + Y * m_size]);
}
}
}
return idx;
}
public int PeformFFT(int startIdx, Vector4[,] data0, Vector4[,] data1)
{
int x; int y; int i;
int idx = 0; int idx1; int bftIdx;
int X; int Y;
Vector2 w;
int j = startIdx;
for (i = 0; i < m_passes; i++, j++)
{
idx = j % 2;
idx1 = (j + 1) % 2;
for (x = 0; x < m_size; x++)
{
for (y = 0; y < m_size; y++)
{
bftIdx = 4 * (x + i * m_size);
X = (int)m_butterflyLookupTable[bftIdx + 0];
Y = (int)m_butterflyLookupTable[bftIdx + 1];
w.x = m_butterflyLookupTable[bftIdx + 2];
w.y = m_butterflyLookupTable[bftIdx + 3];
data0[idx, x + y * m_size] = FFT(w, data0[idx1, X + y * m_size], data0[idx1, Y + y * m_size]);
data1[idx, x + y * m_size] = FFT(w, data1[idx1, X + y * m_size], data1[idx1, Y + y * m_size]);
}
}
}
for (i = 0; i < m_passes; i++, j++)
{
idx = j % 2;
idx1 = (j + 1) % 2;
for (x = 0; x < m_size; x++)
{
for (y = 0; y < m_size; y++)
{
bftIdx = 4 * (y + i * m_size);
X = (int)m_butterflyLookupTable[bftIdx + 0];
Y = (int)m_butterflyLookupTable[bftIdx + 1];
w.x = m_butterflyLookupTable[bftIdx + 2];
w.y = m_butterflyLookupTable[bftIdx + 3];
data0[idx, x + y * m_size] = FFT(w, data0[idx1, x + X * m_size], data0[idx1, x + Y * m_size]);
data1[idx, x + y * m_size] = FFT(w, data1[idx1, x + X * m_size], data1[idx1, x + Y * m_size]);
}
}
}
return idx;
}
public int PeformFFT(int startIdx, Vector4[,] data0)
{
int x; int y; int i;
int idx = 0; int idx1; int bftIdx;
int X; int Y;
Vector2 w;
int j = startIdx;
for (i = 0; i < m_passes; i++, j++)
{
idx = j % 2;
idx1 = (j + 1) % 2;
for (x = 0; x < m_size; x++)
{
for (y = 0; y < m_size; y++)
{
bftIdx = 4 * (x + i * m_size);
X = (int)m_butterflyLookupTable[bftIdx + 0];
Y = (int)m_butterflyLookupTable[bftIdx + 1];
w.x = m_butterflyLookupTable[bftIdx + 2];
w.y = m_butterflyLookupTable[bftIdx + 3];
data0[idx, x + y * m_size] = FFT(w, data0[idx1, X + y * m_size], data0[idx1, Y + y * m_size]);
}
}
}
for (i = 0; i < m_passes; i++, j++)
{
idx = j % 2;
idx1 = (j + 1) % 2;
for (x = 0; x < m_size; x++)
{
for (y = 0; y < m_size; y++)
{
bftIdx = 4 * (y + i * m_size);
X = (int)m_butterflyLookupTable[bftIdx + 0];
Y = (int)m_butterflyLookupTable[bftIdx + 1];
w.x = m_butterflyLookupTable[bftIdx + 2];
w.y = m_butterflyLookupTable[bftIdx + 3];
data0[idx, x + y * m_size] = FFT(w, data0[idx1, x + X * m_size], data0[idx1, x + Y * m_size]);
}
}
}
return idx;
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/FourierGPU.cs
================================================
using UnityEngine;
using System.Collections;
namespace Scatterer
{
public class FourierGPU
{
const int PASS_X_1 = 0, PASS_Y_1 = 1;
const int PASS_X_2 = 2, PASS_Y_2 = 3;
const int PASS_X_3 = 4, PASS_Y_3 = 5;
int m_size;
float m_fsize;
int m_passes;
Texture2D[] m_butterflyLookupTable = null;
Material m_fourier;
public FourierGPU(int size)
{
if(size > 256)
{
Utils.LogDebug("FourierGPU::FourierGPU - fourier grid size must not be greater than 256, changing to 256");
size = 256;
}
if(!Mathf.IsPowerOfTwo(size))
{
Utils.LogDebug("FourierGPU::FourierGPU - fourier grid size must be pow2 number, changing to nearest pow2 number");
size = Mathf.NextPowerOfTwo(size);
}
Shader shader = ShaderReplacer.Instance.LoadedShaders[("Scatterer/Fourier")];
if(shader == null) Utils.LogDebug("FourierGPU::FourierGPU - Could not find shader Math/Fourier");
m_fourier = new Material(shader);
m_size = size; //must be pow2 num
m_fsize = (float)m_size;
m_passes = (int)(Mathf.Log(m_fsize)/Mathf.Log(2.0f));
m_butterflyLookupTable = new Texture2D[m_passes];
ComputeButterflyLookupTable();
m_fourier.SetFloat("_Size", m_fsize);
}
int BitReverse(int i)
{
int j = i;
int Sum = 0;
int W = 1;
int M = m_size / 2;
while(M != 0)
{
j = ((i&M) > M-1) ? 1 : 0;
Sum += j * W;
W *= 2;
M /= 2;
}
return Sum;
}
Texture2D Make1DTex(int i)
{
Texture2D tex = new Texture2D(m_size, 1, TextureFormat.ARGB32, false, true);
tex.filterMode = FilterMode.Point;
tex.wrapMode = TextureWrapMode.Clamp;
return tex;
}
void ComputeButterflyLookupTable()
{
for(int i = 0; i < m_passes; i++)
{
int nBlocks = (int) Mathf.Pow(2, m_passes - 1 - i);
int nHInputs = (int) Mathf.Pow(2, i);
m_butterflyLookupTable[i] = Make1DTex(i);
for (int j = 0; j < nBlocks; j++)
{
for (int k = 0; k < nHInputs; k++)
{
int i1, i2, j1, j2;
if (i == 0)
{
i1 = j * nHInputs * 2 + k;
i2 = j * nHInputs * 2 + nHInputs + k;
j1 = BitReverse(i1);
j2 = BitReverse(i2);
}
else
{
i1 = j * nHInputs * 2 + k;
i2 = j * nHInputs * 2 + nHInputs + k;
j1 = i1;
j2 = i2;
}
m_butterflyLookupTable[i].SetPixel(i1, 0, new Color( (float)j1 / 255.0f, (float)j2 / 255.0f, (float)(k*nBlocks) / 255.0f, 0));
m_butterflyLookupTable[i].SetPixel(i2, 0, new Color( (float)j1 / 255.0f, (float)j2 / 255.0f, (float)(k*nBlocks) / 255.0f, 1));
}
}
m_butterflyLookupTable[i].Apply();
}
}
public int PeformFFT(RenderTexture[] data0, RenderTexture[] data1)
{
RenderTexture[] pass0 = new RenderTexture[]{ data0[0], data1[0] };
RenderTexture[] pass1 = new RenderTexture[]{ data0[1], data1[1] };
int i;
int idx = 0; int idx1;
int j = 0;
for(i = 0; i < m_passes; i++, j++)
{
idx = j%2;
idx1 = (j+1)%2;
m_fourier.SetTexture(ShaderProperties._ButterFlyLookUp_PROPERTY, m_butterflyLookupTable[i]);
m_fourier.SetTexture(ShaderProperties._ReadBuffer0_PROPERTY, data0[idx1]);
m_fourier.SetTexture(ShaderProperties._ReadBuffer1_PROPERTY, data1[idx1]);
if(idx == 0)
RTUtility.MultiTargetBlit(pass0, m_fourier, PASS_X_2);
else
RTUtility.MultiTargetBlit(pass1, m_fourier, PASS_X_2);
}
for(i = 0; i < m_passes; i++, j++)
{
idx = j%2;
idx1 = (j+1)%2;
m_fourier.SetTexture(ShaderProperties._ButterFlyLookUp_PROPERTY, m_butterflyLookupTable[i]);
m_fourier.SetTexture(ShaderProperties._ReadBuffer0_PROPERTY, data0[idx1]);
m_fourier.SetTexture(ShaderProperties._ReadBuffer1_PROPERTY, data1[idx1]);
if(idx == 0)
RTUtility.MultiTargetBlit(pass0, m_fourier, PASS_Y_2);
else
RTUtility.MultiTargetBlit(pass1, m_fourier, PASS_Y_2);
}
return idx;
}
public int PeformFFT(RenderTexture[] data0, RenderTexture[] data1, RenderTexture[] data2)
{
RenderTexture[] pass0 = new RenderTexture[]{ data0[0], data1[0], data2[0] };
RenderTexture[] pass1 = new RenderTexture[]{ data0[1], data1[1], data2[1] };
int i;
int idx = 0; int idx1;
int j = 0;
for(i = 0; i < m_passes; i++, j++)
{
idx = j%2;
idx1 = (j+1)%2;
m_fourier.SetTexture(ShaderProperties._ButterFlyLookUp_PROPERTY, m_butterflyLookupTable[i]);
m_fourier.SetTexture(ShaderProperties._ReadBuffer0_PROPERTY, data0[idx1]);
m_fourier.SetTexture(ShaderProperties._ReadBuffer1_PROPERTY, data1[idx1]);
m_fourier.SetTexture("_ReadBuffer2", data2[idx1]);
if(idx == 0)
RTUtility.MultiTargetBlit(pass0, m_fourier, PASS_X_3);
else
RTUtility.MultiTargetBlit(pass1, m_fourier, PASS_X_3);
}
for(i = 0; i < m_passes; i++, j++)
{
idx = j%2;
idx1 = (j+1)%2;
m_fourier.SetTexture(ShaderProperties._ButterFlyLookUp_PROPERTY, m_butterflyLookupTable[i]);
m_fourier.SetTexture(ShaderProperties._ReadBuffer0_PROPERTY, data0[idx1]);
m_fourier.SetTexture(ShaderProperties._ReadBuffer1_PROPERTY, data1[idx1]);
m_fourier.SetTexture("_ReadBuffer2", data2[idx1]);
if(idx == 0)
RTUtility.MultiTargetBlit(pass0, m_fourier, PASS_Y_3);
else
RTUtility.MultiTargetBlit(pass1, m_fourier, PASS_Y_3);
}
return idx;
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/GPUWaveInteractionHandler.cs
================================================
using UnityEngine;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine.Rendering;
namespace Scatterer
{
public class GPUWaveInteractionHandler
{
private ComputeShader findHeightsShader;
private List partsBuoyancies = new List();
private bool heightsRequestInProgress = false;
private bool cameraHeightRequested = false;
private float[] heights = { };
private ComputeBuffer positionsBuffer, heightsBuffer;
private int frameLatencyCounter = 1;
private bool paused = false;
private KSP.UI.Screens.AltimeterSliderButtons altimeterRecoveryButton;
private bool altimeterRecoveryButtonOverriden = false;
private MethodInfo recoveryButtonSetUnlockMethod;
private object[] setUnlockParametersArray;
private float maxWaveInteractionShipAltitude = 500.0f;
private bool isHomeworld = false;
public GPUWaveInteractionHandler(float inMaxWaveInteractionShipAltitude, bool inIsHomeworld)
{
maxWaveInteractionShipAltitude = inMaxWaveInteractionShipAltitude;
isHomeworld = inIsHomeworld;
findHeightsShader = ShaderReplacer.Instance.LoadedComputeShaders["FindHeights"];
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideWaterCrashTolerance)
{
PhysicsGlobals.BuoyancyCrashToleranceMult = Scatterer.Instance.mainSettings.buoyancyCrashToleranceMultOverride;
}
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideDrag)
{
PhysicsGlobals.BuoyancyWaterDragTimer = double.NegativeInfinity; // this is needed to avoid the excessive drag that is applied when first hitting the water and which basically kills seaplanes with the smallest waves
}
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideRecoveryVelocity)
{
GameEvents.onGamePause.Add(ForcePauseMenuSaving);
GameEvents.onGameUnpause.Add(UnPause);
if (inIsHomeworld)
{
KSP.UI.Screens.AltimeterSliderButtons[] sliderButtons = Resources.FindObjectsOfTypeAll();
if (sliderButtons.Length > 0)
{
altimeterRecoveryButton = sliderButtons[0];
BindingFlags Flags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
recoveryButtonSetUnlockMethod = altimeterRecoveryButton.GetType().GetMethod("setUnlock", Flags);
if (recoveryButtonSetUnlockMethod == null)
{
Utils.LogError("No setUnlock method found in AltimeterSliderButtons");
altimeterRecoveryButton = null;
return;
}
setUnlockParametersArray = new object[] { 2 }; //The state for unlocking the altimeterSliderButtons
}
}
}
}
public void SetMaterialProperties(Vector4 choppyness, Vector4 gridSizes, RenderTexture map0, RenderTexture map3, RenderTexture map4)
{
findHeightsShader.SetVector(ShaderProperties._Ocean_Choppyness_PROPERTY, choppyness);
findHeightsShader.SetVector(ShaderProperties._Ocean_GridSizes_PROPERTY, gridSizes);
findHeightsShader.SetTexture(0, ShaderProperties._Ocean_Map0_PROPERTY, map0);
findHeightsShader.SetTexture(0, ShaderProperties._Ocean_Map3_PROPERTY, map3);
findHeightsShader.SetTexture(0, ShaderProperties._Ocean_Map4_PROPERTY, map4);
}
public float UpdateInteractions(double cameraHeight, float waterHeightAtCameraPosition, Vector3 ux, Vector3 uy, Vector3 offsetVector3)
{
UpdateRecoveryButton();
return UpdateHeights(cameraHeight, waterHeightAtCameraPosition, ux, uy, offsetVector3);
}
private float UpdateHeights(double cameraHeight, float waterHeightAtCameraPosition, Vector3 ux, Vector3 uy, Vector3 offsetVector3)
{
if (!heightsRequestInProgress)
{
waterHeightAtCameraPosition = ApplyWaterLevelHeights(waterHeightAtCameraPosition);
List positionsList = new List();
BuildPartsPositionsList(positionsList, partsBuoyancies, ux, uy, offsetVector3);
AddCameraPosition(positionsList, cameraHeight, new Vector2(offsetVector3.x, offsetVector3.y));
RequestAsyncWaterLevelHeights(positionsList);
}
else
{
frameLatencyCounter++;
}
return waterHeightAtCameraPosition;
}
private void UpdateRecoveryButton()
{
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideRecoveryVelocity && !paused && FlightGlobals.ActiveVessel != null)
{
if ((altimeterRecoveryButton != null) && (FlightGlobals.ActiveVessel.altitude <= Mathf.Abs(maxWaveInteractionShipAltitude))
&& (FlightGlobals.ActiveVessel.IsClearToSave() == ClearToSaveStatus.CLEAR) && (FlightGlobals.ActiveVessel.situation == Vessel.Situations.SPLASHED)
&& (FlightGlobals.ActiveVessel.srf_velocity.sqrMagnitude < Scatterer.Instance.mainSettings.waterMaxRecoveryVelocity * Scatterer.Instance.mainSettings.waterMaxRecoveryVelocity))
{
FlightGlobals.ActiveVessel.srf_velocity = Vector3d.zero;
if (!altimeterRecoveryButton.led.IsOn || (altimeterRecoveryButton.led.color != KSP.UI.Screens.LED.colorIndices.green))
{
recoveryButtonSetUnlockMethod.Invoke(altimeterRecoveryButton, setUnlockParametersArray);
altimeterRecoveryButton.StopAllCoroutines();
altimeterRecoveryButtonOverriden = true;
}
}
else if (altimeterRecoveryButtonOverriden)
{
altimeterRecoveryButton.StartCoroutine("UnlockRecovery", FlightGlobals.ActiveVessel);
altimeterRecoveryButton.StartCoroutine("UnlockReturnToKSC", FlightGlobals.ActiveVessel);
altimeterRecoveryButtonOverriden = false;
}
}
}
void BuildPartsPositionsList(List positionsList, List partsBuoyanciesList, Vector3 ux, Vector3 uy, Vector3 offsetVector3)
{
foreach (Vessel vessel in FlightGlobals.VesselsLoaded)
{
if (vessel.altitude <= Mathf.Abs(maxWaveInteractionShipAltitude))
{
foreach (Part part in vessel.parts)
{
if (part.partBuoyancy)
{
//To be more accurate I'd need to take ceter of buoyancy and transform it to worldPos but that would add a matrix multiply for every part, which I'm not about to do
Vector3 relativePartPos = part.transform.position - Scatterer.Instance.nearCamera.transform.position;
Vector2 oceanPos = new Vector2(Vector3.Dot(relativePartPos, ux) + offsetVector3.x, Vector3.Dot(relativePartPos, uy) + offsetVector3.y);
positionsList.Add(oceanPos);
partsBuoyanciesList.Add(part.partBuoyancy);
}
}
}
}
}
void AddCameraPosition(List positionsList, double cameraHeight, Vector2 cameraOceanPosition)
{
if (cameraHeight <= Mathf.Abs(maxWaveInteractionShipAltitude))
{
positionsList.Add(cameraOceanPosition);
cameraHeightRequested = true;
}
}
float ApplyWaterLevelHeights(float waterHeightAtCameraPosition)
{
//partBuoyancy has no way to override the force direction (it uses -g direction directly) however, maybe do a parent addforce at position with the buoyancy effective position with the normal? will always be hacky probably
if (cameraHeightRequested)
{
waterHeightAtCameraPosition = heights[heights.Length - 1];
}
if (partsBuoyancies!=null)
{
for (int i = 0; i < partsBuoyancies.Count; i++)
{
if (partsBuoyancies[i] != null)
{
partsBuoyancies[i].waterLevel = heights[i];
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideDrag)
{
partsBuoyancies[i].wasSplashed = true; // changing these is also need so the game doesn't apply excessive drag on splashes which makes seaplanes unusable
partsBuoyancies[i].splashed = true;
}
}
}
}
partsBuoyancies.Clear();
cameraHeightRequested = false;
return waterHeightAtCameraPosition;
}
void RequestAsyncWaterLevelHeights(List positionsList)
{
int size = positionsList.Count;
if (size > 0)
{
positionsBuffer = new ComputeBuffer(size, 2 * sizeof(float));
positionsBuffer.SetData(positionsList);
findHeightsShader.SetBuffer(0, "positions", positionsBuffer);
heightsBuffer = new ComputeBuffer(size, sizeof(float));
findHeightsShader.SetBuffer(0, "result", heightsBuffer);
findHeightsShader.Dispatch(0, size, 1, 1); //worry about figuring out threads and groups later
AsyncGPUReadback.Request(heightsBuffer, OnCompletePartHeightsReadback);
frameLatencyCounter = 1;
heightsRequestInProgress = true;
}
}
void OnCompletePartHeightsReadback(AsyncGPUReadbackRequest request)
{
if (request.hasError)
{
Utils.LogError("GPU readback error detected.");
return;
}
heights = request.GetData().ToArray();
heightsRequestInProgress = false;
positionsBuffer.Dispose();
heightsBuffer.Dispose();
}
public void ForcePauseMenuSaving()
{
if (!paused && FlightGlobals.ActiveVessel != null && (FlightGlobals.ActiveVessel.altitude <= Mathf.Abs(maxWaveInteractionShipAltitude))
&& (FlightGlobals.ActiveVessel.IsClearToSave() == ClearToSaveStatus.CLEAR) && (FlightGlobals.ActiveVessel.situation == Vessel.Situations.SPLASHED)
&& (FlightGlobals.ActiveVessel.srf_velocity.sqrMagnitude < Scatterer.Instance.mainSettings.waterMaxRecoveryVelocity * Scatterer.Instance.mainSettings.waterMaxRecoveryVelocity))
{
Utils.LogInfo("Overriding pause menu recovery and save options");
paused = true;
FlightGlobals.ActiveVessel.srf_velocity = Vector3d.zero;
PauseMenu.Display();
}
}
public void UnPause()
{
paused = false;
}
public void Cleanup()
{
GameEvents.onGamePause.Remove(ForcePauseMenuSaving);
GameEvents.onGameUnpause.Remove(UnPause);
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/OceanCameraUpdateHook.cs
================================================
using UnityEngine;
using System;
namespace Scatterer
{
public class OceanCameraUpdateHook : MonoBehaviour
{
public OceanNode oceanNode;
Matrix4x4 cameraToScreen,screenToCamera;
Matrix4x4d m_oldlocalToOcean = Matrix4x4d.Identity ();
// Whenever any camera will render us, call the method which updates the material with the right params
public void OnWillRenderObject()
{
Camera cam = Camera.current;
if (!cam || MapView.MapIsEnabled || !oceanNode.prolandManager.skyNode.simulateOceanInteraction)
return;
updateCameraSpecificUniforms (oceanNode.m_oceanMaterial, cam);
if (Scatterer.Instance.mainSettings.oceanTransparencyAndRefractions && (cam == Scatterer.Instance.farCamera || cam == Scatterer.Instance.nearCamera))
{
if (Scatterer.Instance.unifiedCameraMode)
{
oceanNode.m_oceanMaterial.EnableKeyword("REFRACTIONS_AND_TRANSPARENCY_ON");
oceanNode.m_oceanMaterial.DisableKeyword("REFRACTIONS_AND_TRANSPARENCY_MERGED_DEPTH");
}
else
{
oceanNode.m_oceanMaterial.EnableKeyword("REFRACTIONS_AND_TRANSPARENCY_MERGED_DEPTH");
oceanNode.m_oceanMaterial.DisableKeyword("REFRACTIONS_AND_TRANSPARENCY_ON");
}
oceanNode.m_oceanMaterial.DisableKeyword("REFRACTIONS_AND_TRANSPARENCY_OFF");
}
else
{
oceanNode.m_oceanMaterial.EnableKeyword("REFRACTIONS_AND_TRANSPARENCY_OFF");
oceanNode.m_oceanMaterial.DisableKeyword("REFRACTIONS_AND_TRANSPARENCY_ON");
oceanNode.m_oceanMaterial.DisableKeyword("REFRACTIONS_AND_TRANSPARENCY_MERGED_DEPTH");
}
}
public void updateCameraSpecificUniforms (Material oceanMaterial, Camera inCamera)
{
cameraToScreen = GL.GetGPUProjectionMatrix (inCamera.projectionMatrix, false);
screenToCamera = cameraToScreen.inverse;
oceanNode.m_oceanMaterial.SetMatrix (ShaderProperties._Globals_CameraToScreen_PROPERTY, cameraToScreen);
oceanNode.m_oceanMaterial.SetMatrix (ShaderProperties._Globals_ScreenToCamera_PROPERTY, screenToCamera);
//Calculates the required data for the projected grid
// compute ltoo = localToOcean transform, where ocean frame = tangent space at
// camera projection on sphere radius in local space
//move these to dedicated projected grid class?
Matrix4x4 ctol1 = inCamera.cameraToWorldMatrix;
Matrix4x4d cameraToWorld = new Matrix4x4d (ctol1.m00, ctol1.m01, ctol1.m02, ctol1.m03,
ctol1.m10, ctol1.m11, ctol1.m12, ctol1.m13,
ctol1.m20, ctol1.m21, ctol1.m22, ctol1.m23,
ctol1.m30, ctol1.m31, ctol1.m32, ctol1.m33);
Vector3d translation;
if (HighLogic.LoadedScene == GameScenes.SPACECENTER)
{
translation = oceanNode.prolandManager.parentLocalTransform.position; //have to use this in space center or get the tsunami bug
}
else
{
translation = oceanNode.prolandManager.parentCelestialBody.position; //more precise, especially with RSS, but breaks a bit in KSC
}
Matrix4x4d worldToLocal = new Matrix4x4d(1, 0, 0, -translation.x,
0, 1, 0, -translation.y,
0, 0, 1, -translation.z,
0, 0, 0, 1);
Matrix4x4d camToLocal = worldToLocal * cameraToWorld;
Matrix4x4d localToCam = camToLocal.Inverse ();
// camera in local space relative to planet's origin
Vector3d2 cl = new Vector3d2 ();
cl = camToLocal * Vector3d2.Zero ();
double radius = oceanNode.prolandManager.GetRadius ();
oceanNode.uz = cl.Normalized (); // unit z vector of ocean frame, in local space
if (m_oldlocalToOcean != Matrix4x4d.Identity ())
{
oceanNode.ux = (new Vector3d2 (m_oldlocalToOcean.m [1, 0], m_oldlocalToOcean.m [1, 1], m_oldlocalToOcean.m [1, 2])).Cross (oceanNode.uz).Normalized ();
}
else
{
oceanNode.ux = Vector3d2.UnitZ ().Cross (oceanNode.uz).Normalized ();
}
oceanNode.uy = oceanNode.uz.Cross (oceanNode.ux); // unit y vector
//Wind moves in -Ux direction, which by default points north for some reason, can rotate it to any desired direction this way
oceanNode.oo = oceanNode.uz * (radius); // origin of ocean frame, in local space
//local to ocean transform
//computed from oo and ux, uy, uz should be correct
Matrix4x4d localToOcean = new Matrix4x4d (
oceanNode.ux.x, oceanNode.ux.y, oceanNode.ux.z, -oceanNode.ux.Dot (oceanNode.oo),
oceanNode.uy.x, oceanNode.uy.y, oceanNode.uy.z, -oceanNode.uy.Dot (oceanNode.oo),
oceanNode.uz.x, oceanNode.uz.y, oceanNode.uz.z, -oceanNode.uz.Dot (oceanNode.oo),
0.0, 0.0, 0.0, 1.0);
Matrix4x4d cameraToOcean = localToOcean * camToLocal;
Matrix4x4d worldToOcean = localToOcean * worldToLocal;
Vector3d2 delta = new Vector3d2 (0, 0, 0);
if (m_oldlocalToOcean != Matrix4x4d.Identity ())
{
delta = localToOcean * (m_oldlocalToOcean.Inverse () * Vector3d2.Zero ());
oceanNode.m_Offset += delta;
}
//reset offset when bigger than 20000 to avoid floating point issues when later casting the offset to float
if (Mathf.Max (Mathf.Abs ((float)oceanNode.m_Offset.x), Mathf.Abs ((float)oceanNode.m_Offset.y)) > 20000f)
{
oceanNode.m_Offset.x=0.0;
oceanNode.m_Offset.y=0.0;
}
m_oldlocalToOcean = localToOcean;
// Matrix4x4d ctos = ModifiedProjectionMatrix (inCamera); //moved to command buffer
// Matrix4x4d stoc = ctos.Inverse ();
Vector3d2 oc = cameraToOcean * Vector3d2.Zero ();
oceanNode.height = oc.z;
oceanNode.offset = new Vector3d2 (-oceanNode.m_Offset.x, -oceanNode.m_Offset.y, oceanNode.height);
//old horizon code
//This breaks down when you tilt the camera by 90 degrees in any direction
//I made some new horizon code down, scroll down
// Vector4d stoc_w = (stoc * Vector4d.UnitW ()).XYZ0 ();
// Vector4d stoc_x = (stoc * Vector4d.UnitX ()).XYZ0 ();
// Vector4d stoc_y = (stoc * Vector4d.UnitY ()).XYZ0 ();
//
// Vector3d2 A0 = (cameraToOcean * stoc_w).XYZ ();
// Vector3d2 dA = (cameraToOcean * stoc_x).XYZ ();
// Vector3d2 B = (cameraToOcean * stoc_y).XYZ ();
//
// Vector3d2 horizon1, horizon2;
//
// double h1 = h * (h + 2.0 * radius);
// double h2 = (h + radius) * (h + radius);
// double alpha = B.Dot (B) * h1 - B.z * B.z * h2;
//
// double beta0 = (A0.Dot (B) * h1 - B.z * A0.z * h2) / alpha;
// double beta1 = (dA.Dot (B) * h1 - B.z * dA.z * h2) / alpha;
//
// double gamma0 = (A0.Dot (A0) * h1 - A0.z * A0.z * h2) / alpha;
// double gamma1 = (A0.Dot (dA) * h1 - A0.z * dA.z * h2) / alpha;
// double gamma2 = (dA.Dot (dA) * h1 - dA.z * dA.z * h2) / alpha;
//
// horizon1 = new Vector3d2 (-beta0, -beta1, 0.0);
// horizon2 = new Vector3d2 (beta0 * beta0 - gamma0, 2.0 * (beta0 * beta1 - gamma1), beta1 * beta1 - gamma2);
Vector3d2 sunDir = new Vector3d2 (oceanNode.prolandManager.getDirectionToMainSun ());
Vector3d2 oceanSunDir = localToOcean.ToMatrix3x3d () * sunDir;
oceanMaterial.SetMatrix (ShaderProperties._Globals_CameraToWorld_PROPERTY, cameraToWorld .ToMatrix4x4());
oceanMaterial.SetVector (ShaderProperties._Ocean_SunDir_PROPERTY, oceanSunDir.ToVector3 ());
oceanMaterial.SetMatrix (ShaderProperties._Ocean_CameraToOcean_PROPERTY, cameraToOcean.ToMatrix4x4 ());
oceanMaterial.SetMatrix (ShaderProperties._Ocean_OceanToCamera_PROPERTY, cameraToOcean.Inverse ().ToMatrix4x4 ());
// oceanMaterial.SetMatrix (ShaderProperties._Globals_CameraToScreen_PROPERTY, ctos.ToMatrix4x4 ());
// oceanMaterial.SetMatrix (ShaderProperties._Globals_ScreenToCamera_PROPERTY, stoc.ToMatrix4x4 ());
oceanMaterial.SetMatrix (ShaderProperties._Globals_WorldToOcean_PROPERTY, worldToOcean.ToMatrix4x4 ());
oceanMaterial.SetMatrix (ShaderProperties._Globals_OceanToWorld_PROPERTY, worldToOcean.Inverse ().ToMatrix4x4 ());
oceanMaterial.SetVector (ShaderProperties._Ocean_CameraPos_PROPERTY, oceanNode.offset.ToVector3 ());
//horizon calculations
//these are used to find where the horizon line is on screen
//and "clamp" vertexes that are above it back to it
//as the grid is projected on the whole screen, vertexes over the horizon need to be dealt with
//simply passing a flag to drop fragments or moving these vertexes offscreen will cause issues
//as the horizon line can be between two vertexes and the horizon line will appear "pixelated"
//as whole chunks go missing
//these need to be done here
//1)for double precision
//2)for speed
Vector3d2 sphereDir=localToCam * Vector3d2.Zero (); //vector to center of planet
double OHL = sphereDir.Magnitude (); //distance to center of planet
sphereDir = sphereDir.Normalized (); //direction to center of planet
double rHorizon = Math.Sqrt(OHL * OHL - radius * radius); //distance to the horizon, i.e distance to ocean sphere tangent
//Theta=angle to horizon, now all that is left to do is check the viewdir against this angle in the shader
double cosTheta= rHorizon / (OHL);
double sinTheta= Math.Sqrt (1- cosTheta*cosTheta);
oceanMaterial.SetVector (ShaderProperties.sphereDir_PROPERTY, sphereDir.ToVector3 ());
oceanMaterial.SetFloat (ShaderProperties.cosTheta_PROPERTY, (float) cosTheta);
oceanMaterial.SetFloat (ShaderProperties.sinTheta_PROPERTY, (float) sinTheta);
//planetshine properties
if ((oceanNode.prolandManager.secondarySuns.Count > 0) || Scatterer.Instance.mainSettings.usePlanetShine)
{
Matrix4x4 planetShineSourcesMatrix=oceanNode.prolandManager.planetShineSourcesMatrix;
Vector3d2 oceanSunDir2;
for (int i=0;i<4;i++)
{
Vector4 row = planetShineSourcesMatrix.GetRow(i);
if (row.w != 0f)
{
oceanSunDir2=localToOcean.ToMatrix3x3d () * new Vector3d2(row.x,row.y,row.z);
planetShineSourcesMatrix.SetRow(i,new Vector4((float)oceanSunDir2.x,(float)oceanSunDir2.y,(float)oceanSunDir2.z,row.w));
}
}
oceanMaterial.SetMatrix (ShaderProperties.planetShineSources_PROPERTY, planetShineSourcesMatrix);
oceanMaterial.SetMatrix (ShaderProperties.planetShineRGB_PROPERTY, oceanNode.prolandManager.planetShineRGBMatrix);
}
Matrix4x4 worldToLightMatrix = oceanNode.prolandManager.mainSunLight.transform.worldToLocalMatrix;
if (oceanNode.prolandManager.parentCelestialBody.transform.position.sqrMagnitude < oceanNode.prolandManager.mainSunLight.transform.position.sqrMagnitude)
{
worldToLightMatrix.m03 = oceanNode.prolandManager.parentCelestialBody.transform.position.x;
worldToLightMatrix.m13 = oceanNode.prolandManager.parentCelestialBody.transform.position.y;
worldToLightMatrix.m23 = oceanNode.prolandManager.parentCelestialBody.transform.position.z;
}
if (oceanNode.causticsShadowMaskModulator)
{
oceanNode.causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetMatrix (ShaderProperties.CameraToWorld_PROPERTY, inCamera.cameraToWorldMatrix);
oceanNode.causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetMatrix (ShaderProperties.WorldToLight_PROPERTY, worldToLightMatrix);
oceanNode.causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetVector (ShaderProperties.PlanetOrigin_PROPERTY, oceanNode.prolandManager.parentLocalTransform.position);
}
if (oceanNode.causticsLightRaysRenderer)
{
oceanNode.causticsLightRaysRenderer.CausticsLightRaysMaterial.SetMatrix (ShaderProperties.CameraToWorld_PROPERTY, inCamera.cameraToWorldMatrix);
oceanNode.causticsLightRaysRenderer.CausticsLightRaysMaterial.SetMatrix (ShaderProperties.WorldToLight_PROPERTY, worldToLightMatrix);
oceanNode.causticsLightRaysRenderer.CausticsLightRaysMaterial.SetVector (ShaderProperties.LightDir_PROPERTY, oceanNode.prolandManager.mainSunLight.transform.forward);
oceanNode.causticsLightRaysRenderer.CausticsLightRaysMaterial.SetVector (ShaderProperties.PlanetOrigin_PROPERTY, oceanNode.prolandManager.parentLocalTransform.position);
}
}
public void OnDestroy()
{
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/OceanFFTcpu.cs
================================================
/*
* Proland: a procedural landscape rendering library.
* Copyright (c) 2008-2011 INRIA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Proland is distributed under a dual-license scheme.
* You can obtain a specific license from Inria: proland-licensing@inria.fr.
*
* Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat.
* Modified and ported to Unity by Justin Hawkins 2014
*
*
*/
using UnityEngine;
using System;
using System.Collections;
using System.Threading;
namespace Scatterer {
/*
* Unused CPU FFT version, ship interaction is better done with async GPU readback so this CPU version is not needed. Kept for reference
* Extend the base class OceanNode to provide the data need
* to create the waves using fourier transform which can then be applied
* to the projected grid handled by the OceanNode.
* All the fourier transforms are performed on the CPU
*/
public class OceanFFTcpu: OceanNode {
WriteFloat m_writeFloat;
Vector2 m_varianceMax;
public float WAVE_CM = 0.23f; // Eq 59
public float WAVE_KM = 370.0f; // Eq 59
[Persistent] public float AMP = 1.0f;
Material m_initSpectrumMat;
Material m_initDisplacementMat;
public int m_ansio = 2;
[Persistent] public float m_windSpeed = 5.0f; //A higher wind speed gives greater swell to the waves
[Persistent] public float m_omega = 0.84f; //A lower number means the waves last longer and will build up larger waves
public Vector4 m_gridSizes = new Vector4(5488, 392, 28, 2); //Size in meters (i.e. in spatial domain) of each grid
public Vector4 m_choppyness = new Vector4(2.3f, 2.1f, 1.3f, 0.9f); //Strength of sideways displacement for each grid
public int m_fourierGridSize = 64; //This is the fourier transform size, must pow2 number. Recommend no higher or lower than 64, 128 or 256.
[Persistent] public int m_varianceSize = 4;
float m_fsize;
float m_maxSlopeVariance;
protected int m_idx = 0;
protected Vector4 m_spectrumOffset;
protected Vector4 m_inverseGridSizes;
protected RenderTexture m_spectrum01, m_spectrum23;
protected RenderTexture m_WTable;
public bool rendertexturesCreated {
get {
return (m_WTable.IsCreated());
}
}
RenderTexture[] m_fourierBuffer0, m_fourierBuffer1, m_fourierBuffer2;
RenderTexture[] m_fourierBuffer3, m_fourierBuffer4;
public RenderTexture m_map0, m_map1, m_map2, m_map3, m_map4;
public Texture3D variance {
get {
return m_variance;
}
}
Texture3D m_variance;
protected FourierGPU m_fourier;
public override float GetMaxSlopeVariance() {
return m_maxSlopeVariance;
}
//CPU wave stuff
float FFTtimer=0;
volatile int m_bufferIdx = 0;
public volatile bool done0=true,done1=true,done2=true,done3=true,done4=true,done5=true;
public volatile bool done=true;
int m_passes;
float[] m_butterflyLookupTable = null;
Vector4[,] m_fourierBuffer0vector;
Vector4[,] m_fourierBuffer1vector, m_fourierBuffer2vector,m_fourierBuffer3vector,m_fourierBuffer4vector;
Vector4[] m_spectrum01vector, m_spectrum23vector, m_WTablevector;
// volatile Vector4[,] m_fourierBuffer0vectorResults, m_fourierBuffer3vectorResults,m_fourierBuffer4vectorResults;
Vector4[,] m_fourierBuffer0vectorResults, m_fourierBuffer3vectorResults,m_fourierBuffer4vectorResults;
protected FourierCPU m_CPUfourier;
public override void Init(ProlandManager manager)
{
base.Init(manager);
m_initSpectrumMat = new Material(ShaderReplacer.Instance.LoadedShaders[ ("Proland/Ocean/InitSpectrum")]);
m_initDisplacementMat = new Material(ShaderReplacer.Instance.LoadedShaders[ ("Proland/Ocean/InitDisplacement")]);
m_fourierGridSize = Scatterer.Instance.mainSettings.m_fourierGridSize;
if (m_fourierGridSize > 256) {
Utils.LogDebug("Proland::OceanFFTcpu::Start - fourier grid size must not be greater than 256, changing to 256");
m_fourierGridSize = 256;
}
if (!Mathf.IsPowerOfTwo(m_fourierGridSize)) {
Utils.LogDebug("Proland::OceanFFTcpu::Start - fourier grid size must be pow2 number, changing to nearest pow2 number");
m_fourierGridSize = Mathf.NextPowerOfTwo(m_fourierGridSize);
}
m_fsize = (float) m_fourierGridSize;
m_spectrumOffset = new Vector4(1.0f + 0.5f / m_fsize, 1.0f + 0.5f / m_fsize, 0, 0);
float factor = 2.0f * Mathf.PI * m_fsize;
m_inverseGridSizes = new Vector4(factor / m_gridSizes.x, factor / m_gridSizes.y, factor / m_gridSizes.z, factor / m_gridSizes.w);
m_fourier = new FourierGPU(m_fourierGridSize);
m_writeFloat = new WriteFloat(m_fourierGridSize, m_fourierGridSize);
//#if CPUmode
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions)
{
m_CPUfourier = new FourierCPU (m_fourierGridSize);
m_passes = (int)(Mathf.Log (m_fsize) / Mathf.Log (2.0f));
ComputeButterflyLookupTable ();
m_CPUfourier.m_butterflyLookupTable = m_butterflyLookupTable;
m_fourierBuffer0vector = new Vector4[2, m_fourierGridSize * m_fourierGridSize];
m_fourierBuffer0vectorResults = new Vector4[2, m_fourierGridSize * m_fourierGridSize];
m_fourierBuffer1vector = new Vector4[2, m_fourierGridSize * m_fourierGridSize];
m_fourierBuffer2vector = new Vector4[2, m_fourierGridSize * m_fourierGridSize];
m_fourierBuffer3vector = new Vector4[2, m_fourierGridSize * m_fourierGridSize];
m_fourierBuffer4vector = new Vector4[2, m_fourierGridSize * m_fourierGridSize];
m_fourierBuffer3vectorResults = new Vector4[2, m_fourierGridSize * m_fourierGridSize];
m_fourierBuffer4vectorResults = new Vector4[2, m_fourierGridSize * m_fourierGridSize];
}
//#endif
//Create the data needed to make the waves each frame
CreateRenderTextures();
GenerateWavesSpectrum();
CreateWTable();
m_initSpectrumMat.SetTexture (ShaderProperties._Spectrum01_PROPERTY, m_spectrum01);
m_initSpectrumMat.SetTexture (ShaderProperties._Spectrum23_PROPERTY, m_spectrum23);
m_initSpectrumMat.SetTexture (ShaderProperties._WTable_PROPERTY, m_WTable);
m_initSpectrumMat.SetVector (ShaderProperties._Offset_PROPERTY, m_spectrumOffset);
m_initSpectrumMat.SetVector (ShaderProperties._InverseGridSizes_PROPERTY, m_inverseGridSizes);
m_initDisplacementMat.SetVector (ShaderProperties._InverseGridSizes_PROPERTY, m_inverseGridSizes);
//#if CPUmode
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions)
{
CreateWTableForCPU ();
}
//#endif
}
Vector2 GetSlopeVariances(Vector2 k, float A, float B, float C, float spectrumX, float spectrumY) {
float w = 1.0f - Mathf.Exp(A * k.x * k.x + B * k.x * k.y + C * k.y * k.y);
return new Vector2((k.x * k.x) * w, (k.y * k.y) * w) * (spectrumX * spectrumX + spectrumY * spectrumY) * 2.0f;
}
///
/// Iterate over the spectrum and find the variance.
/// Use in the BRDF equations.
///
Vector2 ComputeVariance(float slopeVarianceDelta, float[] inSpectrum01, float[] inSpectrum23, float idxX, float idxY, float idxZ) {
const float SCALE = 10.0f;
float A = Mathf.Pow(idxX / ((float) m_varianceSize - 1.0f), 4.0f) * SCALE;
float C = Mathf.Pow(idxZ / ((float) m_varianceSize - 1.0f), 4.0f) * SCALE;
float B = (2.0f * idxY / ((float) m_varianceSize - 1.0f) - 1.0f) * Mathf.Sqrt(A * C);
A = -0.5f * A;
B = -B;
C = -0.5f * C;
Vector2 slopeVariances = new Vector2(slopeVarianceDelta, slopeVarianceDelta);
for (int x = 0; x < m_fourierGridSize; x++) {
for (int y = 0; y < m_fourierGridSize; y++) {
int i = x >= m_fsize / 2.0f ? x - m_fourierGridSize : x;
int j = y >= m_fsize / 2.0f ? y - m_fourierGridSize : y;
Vector2 k = new Vector2(i, j) * 2.0f * Mathf.PI;
slopeVariances += GetSlopeVariances(k / m_gridSizes.x, A, B, C, inSpectrum01[(x + y * m_fourierGridSize) * 4 + 0], inSpectrum01[(x + y * m_fourierGridSize) * 4 + 1]);
slopeVariances += GetSlopeVariances(k / m_gridSizes.y, A, B, C, inSpectrum01[(x + y * m_fourierGridSize) * 4 + 2], inSpectrum01[(x + y * m_fourierGridSize) * 4 + 3]);
slopeVariances += GetSlopeVariances(k / m_gridSizes.z, A, B, C, inSpectrum23[(x + y * m_fourierGridSize) * 4 + 0], inSpectrum23[(x + y * m_fourierGridSize) * 4 + 1]);
slopeVariances += GetSlopeVariances(k / m_gridSizes.w, A, B, C, inSpectrum23[(x + y * m_fourierGridSize) * 4 + 2], inSpectrum23[(x + y * m_fourierGridSize) * 4 + 3]);
}
}
return slopeVariances;
}
/*
* Initializes the data to the shader that needs to
* have the fourier transform applied to it this frame.
*/
protected virtual void InitWaveSpectrum(float t) {
// init heights (0) and slopes (1,2)
RenderTexture[] buffers012 = new RenderTexture[] {
m_fourierBuffer0[1], m_fourierBuffer1[1], m_fourierBuffer2[1]
};
m_initSpectrumMat.SetFloat (ShaderProperties._T_PROPERTY, t);
// RTUtility.MultiTargetBlit(buffers012, m_initSpectrumMat);
RTUtility.MultiTargetBlit(buffers012, m_initSpectrumMat, 0);
// Init displacement (3,4)
RenderTexture[] buffers34 = new RenderTexture[] {
m_fourierBuffer3[1], m_fourierBuffer4[1]
};
m_initDisplacementMat.SetTexture (ShaderProperties._Buffer1_PROPERTY, m_fourierBuffer1[1]);
m_initDisplacementMat.SetTexture (ShaderProperties._Buffer2_PROPERTY, m_fourierBuffer2[1]);
// RTUtility.MultiTargetBlit(buffers34, m_initDisplacementMat);
RTUtility.MultiTargetBlit(buffers34, m_initDisplacementMat, 0);
}
void InitWaveSpectrumCPU(float time)
{
Vector2 uv, st, k1, k2, k3, k4, h1, h2, h3, h4, h12, h34, n1, n2, n3, n4;
Vector4 s12, s34, s12c, s34c;
int rx, ry;
// init heights (0) and slopes (1,2)
for (int x = 0; x < m_fourierGridSize; x++)
{
for (int y = 0; y < m_fourierGridSize; y++)
{
uv.x = x / m_fsize;
uv.y = y / m_fsize;
st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x;
st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y;
rx = x;
ry = y;
s12 = m_spectrum01vector[rx + ry * m_fourierGridSize];
s34 = m_spectrum23vector[rx + ry * m_fourierGridSize];
rx = (m_fourierGridSize - x) % m_fourierGridSize;
ry = (m_fourierGridSize - y) % m_fourierGridSize;
s12c = m_spectrum01vector[rx + ry * m_fourierGridSize];
s34c = m_spectrum23vector[rx + ry * m_fourierGridSize];
k1 = st * m_inverseGridSizes.x;
k2 = st * m_inverseGridSizes.y;
k3 = st * m_inverseGridSizes.z;
k4 = st * m_inverseGridSizes.w;
h1 = GetSpectrum(time, m_WTablevector[x + y * m_fourierGridSize].x, s12.x, s12.y, s12c.x, s12c.y);
h2 = GetSpectrum(time, m_WTablevector[x + y * m_fourierGridSize].y, s12.z, s12.w, s12c.z, s12c.w);
h3 = GetSpectrum(time, m_WTablevector[x + y * m_fourierGridSize].z, s34.x, s34.y, s34c.x, s34c.y);
h4 = GetSpectrum(time, m_WTablevector[x + y * m_fourierGridSize].w, s34.z, s34.w, s34c.z, s34c.w);
//heights
h12 = h1 + COMPLEX(h2);
h34 = h3 + COMPLEX(h4);
//slopes (normals)
n1 = COMPLEX(k1.x * h1) - k1.y * h1;
n2 = COMPLEX(k2.x * h2) - k2.y * h2;
n3 = COMPLEX(k3.x * h3) - k3.y * h3;
n4 = COMPLEX(k4.x * h4) - k4.y * h4;
//Heights in last two channels (h34) have been removed as I found they arent really need for the shader
//h3 and h4 still needs to be calculated for the slope but they are no longer save and transformed by the fourier step
//m_fourierBuffer0vector[1, x+y*m_fourierGridSize] = new Vector4(h12.x, h12.y, h34.x, h34.y); //I put this back
int i = x + y * m_fourierGridSize;
// m_fourierBuffer0vector[1, i] = h12;
m_fourierBuffer0vector[1, i] = new Vector4(h12.x, h12.y, h34.x, h34.y);
m_fourierBuffer1vector[1, i] = new Vector4(n1.x, n1.y, n2.x, n2.y);
m_fourierBuffer2vector[1, i] = new Vector4(n3.x, n3.y, n4.x, n4.y);
// Init displacement (3,4)
float K1 = (k1).magnitude;
float K2 = (k2).magnitude;
float K3 = (k3).magnitude;
float K4 = (k4).magnitude;
float IK1 = K1 == 0.0f ? 0.0f : 1.0f / K1;
float IK2 = K2 == 0.0f ? 0.0f : 1.0f / K2;
float IK3 = K3 == 0.0f ? 0.0f : 1.0f / K3;
float IK4 = K4 == 0.0f ? 0.0f : 1.0f / K4;
Vector4 result = new Vector4(0f,0f,0f,0f);
result.x=m_fourierBuffer1vector[1,i].x * IK1;
result.y=m_fourierBuffer1vector[1,i].y * IK1;
result.z=m_fourierBuffer1vector[1,i].z * IK2;
result.w=m_fourierBuffer1vector[1,i].w * IK2;
m_fourierBuffer3vector[1, i] = result;
Vector4 result2 = new Vector4(0f,0f,0f,0f);
result.x=m_fourierBuffer2vector[1,i].x * IK3;
result.y=m_fourierBuffer2vector[1,i].y * IK3;
result.z=m_fourierBuffer2vector[1,i].z * IK4;
result.w=m_fourierBuffer2vector[1,i].w * IK4;
m_fourierBuffer4vector[1, i] = result2;
}
}
}
public override void UpdateNode() {
// if (!m_spectrum01.IsCreated()) {
// waitBeforeReloadCnt++;
// if (waitBeforeReloadCnt >= 2) {
//
// CreateRenderTextures();
// GenerateWavesSpectrum();
// CreateWTable();
//
// Utils.Log("Recreated OceanFFTcpu Data");
// waitBeforeReloadCnt = 0;
// }
// }
//
// else
{
float t;
if (TimeWarp.CurrentRate > 4)
{
t = (float) Planetarium.GetUniversalTime();
}
else
{
t = Time.time;
}
// t = Time.realtimeSinceStartup;
if (!MapView.MapIsEnabled)
{
InitWaveSpectrum(t);
//Perform fourier transform and record what is the current index
m_idx = m_fourier.PeformFFT(m_fourierBuffer0, m_fourierBuffer1, m_fourierBuffer2);
m_fourier.PeformFFT(m_fourierBuffer3, m_fourierBuffer4);
Graphics.Blit(m_fourierBuffer0[m_idx], m_map0);
Graphics.Blit(m_fourierBuffer1[m_idx], m_map1);
Graphics.Blit(m_fourierBuffer2[m_idx], m_map2);
Graphics.Blit(m_fourierBuffer3[m_idx], m_map3);
Graphics.Blit(m_fourierBuffer4[m_idx], m_map4);
m_oceanMaterial.SetVector (ShaderProperties._Ocean_MapSize_PROPERTY, new Vector2(m_fsize, m_fsize));
m_oceanMaterial.SetVector (ShaderProperties._Ocean_Choppyness_PROPERTY, m_choppyness);
m_oceanMaterial.SetVector (ShaderProperties._Ocean_GridSizes_PROPERTY, m_gridSizes);
m_oceanMaterial.SetFloat (ShaderProperties._Ocean_HeightOffset_PROPERTY, 0f);
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Variance_PROPERTY, m_variance);
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map0_PROPERTY, m_map0);
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map1_PROPERTY, m_map1);
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map2_PROPERTY, m_map2);
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map3_PROPERTY, m_map3);
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map4_PROPERTY, m_map4);
m_oceanMaterial.SetVector (ShaderProperties._VarianceMax_PROPERTY, m_varianceMax);
}
//#if CPUmode
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions)
{
if(!(done0&&done1&&done2&&done3&&done4&&done5))
{
base.UpdateNode();
return;
}
done0 = false;
done1 = false;
done2 = false;
done3 = false;
done4 = false;
done5 = false;
FFTtimer = Time.realtimeSinceStartup;
Nullable time = t;
ThreadPool.QueueUserWorkItem(new WaitCallback(RunThreaded), time);
CommitResults (ref m_fourierBuffer0vector, ref m_fourierBuffer0vectorResults);
CommitResults (ref m_fourierBuffer3vector, ref m_fourierBuffer3vectorResults);
CommitResults (ref m_fourierBuffer4vector, ref m_fourierBuffer4vectorResults);
}
//#endif
base.UpdateNode();
}
}
//Craft-wave interactions
//Note: This version was a proof of concept, the final version is the GPU readback version in OceanFFTgpu, this is only kept here for reference
public void FixedUpdate()
{
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions)
{
foreach (Vessel vessel in FlightGlobals.VesselsLoaded)
{
foreach (Part part in vessel.parts)
{
if (part.partBuoyancy)
{
Vector3 relativePartPos = part.partBuoyancy.transform.position-Scatterer.Instance.nearCamera.transform.position;
float newheight= findHeight(new Vector3(Vector3.Dot(relativePartPos,ux.ToVector3())+offsetVector3.x,
Vector3.Dot(relativePartPos,uy.ToVector3())+offsetVector3.y,
0f),0.02f);
part.partBuoyancy.waterLevel=newheight;
part.partBuoyancy.wasSplashed=part.partBuoyancy.splashed;
part.partBuoyancy.slow=true;
}
}
}
}
}
public override void OnDestroy()
{
base.OnDestroy();
m_map0.Release();
m_map1.Release();
m_map2.Release();
m_map3.Release();
m_map4.Release();
m_spectrum01.Release();
m_spectrum23.Release();
m_WTable.Release();
for (int i = 0; i < 2; i++) {
m_fourierBuffer0[i].Release();
m_fourierBuffer1[i].Release();
m_fourierBuffer2[i].Release();
m_fourierBuffer3[i].Release();
m_fourierBuffer4[i].Release();
}
}
protected virtual void CreateRenderTextures() {
RenderTextureFormat mapFormat = RenderTextureFormat.ARGBHalf;
RenderTextureFormat format = RenderTextureFormat.ARGBHalf;
//These texture hold the actual data use in the ocean renderer
CreateMap(ref m_map0, mapFormat, m_ansio, true);
CreateMap(ref m_map1, mapFormat, m_ansio, true);
CreateMap(ref m_map2, mapFormat, m_ansio, true);
CreateMap(ref m_map3, mapFormat, m_ansio, true);
CreateMap(ref m_map4, mapFormat, m_ansio, true);
//These textures are used to perform the fourier transform
CreateBuffer(ref m_fourierBuffer0, format); //heights
CreateBuffer(ref m_fourierBuffer1, format); // slopes X
CreateBuffer(ref m_fourierBuffer2, format); // slopes Y
CreateBuffer(ref m_fourierBuffer3, format); // displacement X
CreateBuffer(ref m_fourierBuffer4, format); // displacement Y
//These textures hold the specturm the fourier transform is performed on
m_spectrum01 = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format);
m_spectrum01.filterMode = FilterMode.Point;
m_spectrum01.wrapMode = TextureWrapMode.Repeat;
// m_spectrum01.enableRandomWrite = false;
m_spectrum01.enableRandomWrite = false;
m_spectrum01.Create();
m_spectrum23 = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format);
m_spectrum23.filterMode = FilterMode.Point;
m_spectrum23.wrapMode = TextureWrapMode.Repeat;
m_spectrum23.enableRandomWrite = false;
m_spectrum23.Create();
m_WTable = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format);
m_WTable.filterMode = FilterMode.Point;
m_WTable.wrapMode = TextureWrapMode.Clamp;
m_WTable.enableRandomWrite = false;
m_WTable.Create();
m_variance = new Texture3D(m_varianceSize, m_varianceSize, m_varianceSize, TextureFormat.ARGB32, true);
m_variance.wrapMode = TextureWrapMode.Clamp;
m_variance.filterMode = FilterMode.Bilinear;
}
protected void CreateBuffer(ref RenderTexture[] tex, RenderTextureFormat format) {
tex = new RenderTexture[2];
for (int i = 0; i < 2; i++) {
tex[i] = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format);
tex[i].filterMode = FilterMode.Point;
tex[i].wrapMode = TextureWrapMode.Clamp;
tex[i].Create();
}
}
protected void CreateMap(ref RenderTexture map, RenderTextureFormat format, int ansio, bool useMipMaps) {
map = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format);
map.filterMode = FilterMode.Trilinear;
map.wrapMode = TextureWrapMode.Repeat;
map.anisoLevel = ansio;
// map.useMipMap = true;
map.useMipMap = useMipMaps;
map.Create();
}
float sqr(float x) {
return x * x;
}
float omega(float k) {
return Mathf.Sqrt(9.81f * k * (1.0f + sqr(k / WAVE_KM)));
} // Eq 24
float Spectrum(float kx, float ky, bool omnispectrum) {
//I know this is a big chunk of ugly math but dont worry to much about what it all means
//It recreates a statistcally representative model of a wave spectrum in the frequency domain.
float U10 = m_windSpeed;
// phase speed
float k = Mathf.Sqrt(kx * kx + ky * ky);
float c = omega(k) / k;
// spectral peak
float kp = 9.81f * sqr(m_omega / U10); // after Eq 3
float cp = omega(kp) / kp;
// friction velocity
float z0 = 3.7e-5f * sqr(U10) / 9.81f * Mathf.Pow(U10 / cp, 0.9f); // Eq 66
float u_star = 0.41f * U10 / Mathf.Log(10.0f / z0); // Eq 60
float Lpm = Mathf.Exp(-5.0f / 4.0f * sqr(kp / k)); // after Eq 3
float gamma = (m_omega < 1.0f) ? 1.7f : 1.7f + 6.0f * Mathf.Log(m_omega); // after Eq 3 // log10 or log?
float sigma = 0.08f * (1.0f + 4.0f / Mathf.Pow(m_omega, 3.0f)); // after Eq 3
float Gamma = Mathf.Exp(-1.0f / (2.0f * sqr(sigma)) * sqr(Mathf.Sqrt(k / kp) - 1.0f));
float Jp = Mathf.Pow(gamma, Gamma); // Eq 3
float Fp = Lpm * Jp * Mathf.Exp(-m_omega / Mathf.Sqrt(10.0f) * (Mathf.Sqrt(k / kp) - 1.0f)); // Eq 32
float alphap = 0.006f * Mathf.Sqrt(m_omega); // Eq 34
float Bl = 0.5f * alphap * cp / c * Fp; // Eq 31
float alpham = 0.01f * (u_star < WAVE_CM ? 1.0f + Mathf.Log(u_star / WAVE_CM) : 1.0f + 3.0f * Mathf.Log(u_star / WAVE_CM)); // Eq 44
float Fm = Mathf.Exp(-0.25f * sqr(k / WAVE_KM - 1.0f)); // Eq 41
float Bh = 0.5f * alpham * WAVE_CM / c * Fm * Lpm; // Eq 40 (fixed)
Bh *= Lpm; // bug fix???
if (omnispectrum) return AMP * (Bl + Bh) / (k * sqr(k)); // Eq 30
float a0 = Mathf.Log(2.0f) / 4.0f;
float ap = 4.0f;
float am = 0.13f * u_star / WAVE_CM; // Eq 59
float Delta = (float) System.Math.Tanh(a0 + ap * Mathf.Pow(c / cp, 2.5f) + am * Mathf.Pow(WAVE_CM / c, 2.5f)); // Eq 57
float phi = Mathf.Atan2(ky, kx);
if (kx < 0.0f) return 0.0f;
Bl *= 2.0f;
Bh *= 2.0f;
// remove waves perpendicular to wind dir
float tweak = Mathf.Sqrt(Mathf.Max(kx / Mathf.Sqrt(kx * kx + ky * ky), 0.0f));
return AMP * (Bl + Bh) * (1.0f + Delta * Mathf.Cos(2.0f * phi)) / (2.0f * Mathf.PI * sqr(sqr(k))) * tweak; // Eq 67
}
Vector2 GetSpectrumSample(float i, float j, float lengthScale, float kMin) {
float dk = 2.0f * Mathf.PI / lengthScale;
float kx = i * dk;
float ky = j * dk;
Vector2 result = new Vector2(0.0f, 0.0f);
float rnd = UnityEngine.Random.value;
if (Mathf.Abs(kx) >= kMin || Mathf.Abs(ky) >= kMin) {
float S = Spectrum(kx, ky, false);
float h = Mathf.Sqrt(S / 2.0f) * dk;
float phi = rnd * 2.0f * Mathf.PI;
result.x = h * Mathf.Cos(phi);
result.y = h * Mathf.Sin(phi);
}
return result;
}
float GetSlopeVariance(float kx, float ky, Vector2 spectrumSample) {
float kSquare = kx * kx + ky * ky;
float real = spectrumSample.x;
float img = spectrumSample.y;
float hSquare = real * real + img * img;
return kSquare * hSquare * 2.0f;
}
void GenerateWavesSpectrum() {
// Slope variance due to all waves, by integrating over the full spectrum.
// Used by the BRDF rendering model
float theoreticSlopeVariance = 0.0f;
float k = 5e-3f;
while (k < 1e3f) {
float nextK = k * 1.001f;
theoreticSlopeVariance += k * k * Spectrum(k, 0, true) * (nextK - k);
k = nextK;
}
float[] spectrum01 = new float[m_fourierGridSize * m_fourierGridSize * 4];
float[] spectrum23 = new float[m_fourierGridSize * m_fourierGridSize * 4];
//#if CPUmode
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions)
{
m_spectrum01vector = new Vector4[m_fourierGridSize * m_fourierGridSize];
m_spectrum23vector = new Vector4[m_fourierGridSize * m_fourierGridSize];
}
//#endif
int idx;
float i;
float j;
float totalSlopeVariance = 0.0f;
Vector2 sample12XY;
Vector2 sample12ZW;
Vector2 sample34XY;
Vector2 sample34ZW;
UnityEngine.Random.seed = 0;
for (int x = 0; x < m_fourierGridSize; x++) {
for (int y = 0; y < m_fourierGridSize; y++) {
idx = x + y * m_fourierGridSize;
i = (x >= m_fourierGridSize / 2) ? (float)(x - m_fourierGridSize) : (float) x;
j = (y >= m_fourierGridSize / 2) ? (float)(y - m_fourierGridSize) : (float) y;
sample12XY = GetSpectrumSample(i, j, m_gridSizes.x, Mathf.PI / m_gridSizes.x);
sample12ZW = GetSpectrumSample(i, j, m_gridSizes.y, Mathf.PI * m_fsize / m_gridSizes.x);
sample34XY = GetSpectrumSample(i, j, m_gridSizes.z, Mathf.PI * m_fsize / m_gridSizes.y);
sample34ZW = GetSpectrumSample(i, j, m_gridSizes.w, Mathf.PI * m_fsize / m_gridSizes.z);
//#if CPUmode
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions)
{
m_spectrum01vector[idx].x = sample12XY.x;
m_spectrum01vector[idx].y = sample12XY.y;
m_spectrum01vector[idx].z = sample12ZW.x;
m_spectrum01vector[idx].w = sample12ZW.y;
m_spectrum23vector[idx].x = sample34XY.x;
m_spectrum23vector[idx].y = sample34XY.y;
m_spectrum23vector[idx].z = sample34ZW.x;
m_spectrum23vector[idx].w = sample34ZW.y;
}
//#endif
spectrum01[idx * 4 + 0] = sample12XY.x;
spectrum01[idx * 4 + 1] = sample12XY.y;
spectrum01[idx * 4 + 2] = sample12ZW.x;
spectrum01[idx * 4 + 3] = sample12ZW.y;
spectrum23[idx * 4 + 0] = sample34XY.x;
spectrum23[idx * 4 + 1] = sample34XY.y;
spectrum23[idx * 4 + 2] = sample34ZW.x;
spectrum23[idx * 4 + 3] = sample34ZW.y;
i *= 2.0f * Mathf.PI;
j *= 2.0f * Mathf.PI;
totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.x, j / m_gridSizes.x, sample12XY);
totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.y, j / m_gridSizes.y, sample12ZW);
totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.z, j / m_gridSizes.z, sample34XY);
totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.w, j / m_gridSizes.w, sample34ZW);
}
}
m_writeFloat.WriteIntoRenderTexture(m_spectrum01, 4, spectrum01);
m_writeFloat.WriteIntoRenderTexture(m_spectrum23, 4, spectrum23);
float slopeVarianceDelta = 0.5f * (theoreticSlopeVariance - totalSlopeVariance);
m_varianceMax = new Vector2(float.NegativeInfinity, float.NegativeInfinity);
Vector2[, , ] variance32bit = new Vector2[m_varianceSize, m_varianceSize, m_varianceSize];
Color[] variance8bit = new Color[m_varianceSize * m_varianceSize * m_varianceSize];
for (int x = 0; x < m_varianceSize; x++) {
for (int y = 0; y < m_varianceSize; y++) {
for (int z = 0; z < m_varianceSize; z++) {
variance32bit[x, y, z] = ComputeVariance(slopeVarianceDelta, spectrum01, spectrum23, x, y, z);
if (variance32bit[x, y, z].x > m_varianceMax.x) m_varianceMax.x = variance32bit[x, y, z].x;
if (variance32bit[x, y, z].y > m_varianceMax.y) m_varianceMax.y = variance32bit[x, y, z].y;
}
}
}
for (int x = 0; x < m_varianceSize; x++) {
for (int y = 0; y < m_varianceSize; y++) {
for (int z = 0; z < m_varianceSize; z++) {
idx = x + y * m_varianceSize + z * m_varianceSize * m_varianceSize;
variance8bit[idx] = new Color(variance32bit[x, y, z].x / m_varianceMax.x, variance32bit[x, y, z].y / m_varianceMax.y, 0.0f, 1.0f);
}
}
}
m_variance.SetPixels(variance8bit);
m_variance.Apply();
// m_maxSlopeVariance = 0.0f;
// for (int v = 0; v < m_varianceSize * m_varianceSize * m_varianceSize; v++) {
// m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, varianceData[v]);
// }
m_maxSlopeVariance = 0.0f;
for(int v = 0; v < m_varianceSize*m_varianceSize*m_varianceSize; v++)
{
m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, variance8bit[v].r*m_varianceMax.x);
m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, variance8bit[v].g*m_varianceMax.y);
}
}
void CreateWTable() {
//Some values need for the InitWaveSpectrum function can be precomputed
Vector2 uv, st;
float k1, k2, k3, k4, w1, w2, w3, w4;
float[] table = new float[m_fourierGridSize * m_fourierGridSize * 4];
for (int x = 0; x < m_fourierGridSize; x++) {
for (int y = 0; y < m_fourierGridSize; y++) {
uv = new Vector2(x, y) / m_fsize;
st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x;
st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y;
k1 = (st * m_inverseGridSizes.x).magnitude;
k2 = (st * m_inverseGridSizes.y).magnitude;
k3 = (st * m_inverseGridSizes.z).magnitude;
k4 = (st * m_inverseGridSizes.w).magnitude;
w1 = Mathf.Sqrt(9.81f * k1 * (1.0f + k1 * k1 / (WAVE_KM * WAVE_KM)));
w2 = Mathf.Sqrt(9.81f * k2 * (1.0f + k2 * k2 / (WAVE_KM * WAVE_KM)));
w3 = Mathf.Sqrt(9.81f * k3 * (1.0f + k3 * k3 / (WAVE_KM * WAVE_KM)));
w4 = Mathf.Sqrt(9.81f * k4 * (1.0f + k4 * k4 / (WAVE_KM * WAVE_KM)));
table[(x + y * m_fourierGridSize) * 4 + 0] = w1;
table[(x + y * m_fourierGridSize) * 4 + 1] = w2;
table[(x + y * m_fourierGridSize) * 4 + 2] = w3;
table[(x + y * m_fourierGridSize) * 4 + 3] = w4;
}
}
m_writeFloat.WriteIntoRenderTexture(m_WTable, 4, table);
}
///
/// Some of the values needed in the InitWaveSpectrum function can be precomputed.
/// If the grid sizes change this function must called again.
///
void CreateWTableForCPU()
{
Vector2 uv, st;
float k1, k2, k3, k4, w1, w2, w3, w4;
m_WTablevector = new Vector4[m_fourierGridSize * m_fourierGridSize];
for (int x = 0; x < m_fourierGridSize; x++)
{
for (int y = 0; y < m_fourierGridSize; y++)
{
uv = new Vector2(x, y) / m_fsize;
st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x;
st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y;
k1 = (st * m_inverseGridSizes.x).magnitude;
k2 = (st * m_inverseGridSizes.y).magnitude;
k3 = (st * m_inverseGridSizes.z).magnitude;
k4 = (st * m_inverseGridSizes.w).magnitude;
w1 = Mathf.Sqrt(9.81f * k1 * (1.0f + k1 * k1 / (WAVE_KM * WAVE_KM)));
w2 = Mathf.Sqrt(9.81f * k2 * (1.0f + k2 * k2 / (WAVE_KM * WAVE_KM)));
w3 = Mathf.Sqrt(9.81f * k3 * (1.0f + k3 * k3 / (WAVE_KM * WAVE_KM)));
w4 = Mathf.Sqrt(9.81f * k4 * (1.0f + k4 * k4 / (WAVE_KM * WAVE_KM)));
m_WTablevector[x + y * m_fourierGridSize] = new Vector4(w1, w2, w3, w4);
}
}
}
Vector2 GetSpectrum(float t, float w, float s0x, float s0y, float s0cx, float s0cy)
{
float c = Mathf.Cos(w * t);
float s = Mathf.Sin(w * t);
return new Vector2((s0x + s0cx) * c - (s0y + s0cy) * s, (s0x - s0cx) * s + (s0y - s0cy) * c);
}
Vector2 COMPLEX(Vector2 z)
{
return new Vector2(-z.y, z.x); // returns i times z (complex number)
}
public virtual void onThreadsDone()
{
return;
}
void CommitResults(ref Vector4[,] data, ref Vector4[,] output)
{
for (int x = 0; x < m_fourierGridSize; x++)
{
for (int y = 0; y < m_fourierGridSize; y++)
{
int i = x + y * m_fourierGridSize;
output[m_bufferIdx,i] = data[m_bufferIdx, i];
}
}
}
//main thread that launches the other threads
void RunThreaded(object o)
{
Nullable time = o as Nullable;
InitWaveSpectrumCPU(time.Value);
ThreadPool.QueueUserWorkItem(new WaitCallback(RunThreaded1), time);
ThreadPool.QueueUserWorkItem(new WaitCallback(RunThreaded2), time);
ThreadPool.QueueUserWorkItem(new WaitCallback(RunThreaded3), time);
ThreadPool.QueueUserWorkItem(new WaitCallback(RunThreaded4), time);
ThreadPool.QueueUserWorkItem(new WaitCallback(RunThreaded5), time);
done0 = true;
}
void RunThreaded1(object o)
{
Nullable time = o as Nullable;
m_bufferIdx = m_CPUfourier.PeformFFT(0, m_fourierBuffer0vector);
done1 = true;
}
void RunThreaded2(object o)
{
Nullable time = o as Nullable;
m_CPUfourier.PeformFFT(0, m_fourierBuffer1vector);
done2 = true;
}
void RunThreaded3(object o)
{
Nullable time = o as Nullable;
m_CPUfourier.PeformFFT(0, m_fourierBuffer2vector);
done3 = true;
}
void RunThreaded4(object o)
{
Nullable time = o as Nullable;
m_CPUfourier.PeformFFT(0, m_fourierBuffer3vector);
done4 = true;
}
void RunThreaded5(object o)
{
Nullable time = o as Nullable;
m_CPUfourier.PeformFFT(0, m_fourierBuffer4vector);
done5 = true;
}
void ComputeButterflyLookupTable()
{
m_butterflyLookupTable = new float[m_fourierGridSize * m_passes * 4];
for (int i = 0; i < m_passes; i++)
{
int nBlocks = (int)Mathf.Pow(2, m_passes - 1 - i);
int nHInputs = (int)Mathf.Pow(2, i);
for (int j = 0; j < nBlocks; j++)
{
for (int k = 0; k < nHInputs; k++)
{
int i1, i2, j1, j2;
if (i == 0)
{
i1 = j * nHInputs * 2 + k;
i2 = j * nHInputs * 2 + nHInputs + k;
j1 = BitReverse(i1);
j2 = BitReverse(i2);
}
else
{
i1 = j * nHInputs * 2 + k;
i2 = j * nHInputs * 2 + nHInputs + k;
j1 = i1;
j2 = i2;
}
float wr = Mathf.Cos(2.0f * Mathf.PI * (float)(k * nBlocks) / m_fsize);
float wi = Mathf.Sin(2.0f * Mathf.PI * (float)(k * nBlocks) / m_fsize);
int offset1 = 4 * (i1 + i * m_fourierGridSize);
m_butterflyLookupTable[offset1 + 0] = j1;
m_butterflyLookupTable[offset1 + 1] = j2;
m_butterflyLookupTable[offset1 + 2] = wr;
m_butterflyLookupTable[offset1 + 3] = wi;
int offset2 = 4 * (i2 + i * m_fourierGridSize);
m_butterflyLookupTable[offset2 + 0] = j1;
m_butterflyLookupTable[offset2 + 1] = j2;
m_butterflyLookupTable[offset2 + 2] = -wr;
m_butterflyLookupTable[offset2 + 3] = -wi;
}
}
}
}
int BitReverse(int i)
{
int j = i;
int Sum = 0;
int W = 1;
int M = m_fourierGridSize / 2;
while (M != 0)
{
j = ((i & M) > M - 1) ? 1 : 0;
Sum += j * W;
W *= 2;
M /= 2;
}
return Sum;
}
void OnGUI(){
// GUI.DrawTexture(new Rect(0,0,512, 512), m_map0tex2DScaleMode.ScaleToFit, false);
// GUI.DrawTexture(new Rect(0,0,512, 512), m_map0, ScaleMode.ScaleToFit, false);
// GUI.DrawTexture(new Rect(512,0,512, 512), m_map0);
}
///
/// Get the two indices that need to be sampled for bilinear filtering.
///
public void Index(double x, int sx, out int ix0, out int ix1)
{
ix0 = (int)x;
ix1 = (int)x + (int)Math.Sign(x);
// if(m_wrap)
// {
if(ix0 >= sx || ix0 <= -sx) ix0 = ix0 % sx;
if(ix0 < 0) ix0 = sx - -ix0;
if(ix1 >= sx || ix1 <= -sx) ix1 = ix1 % sx;
if(ix1 < 0) ix1 = sx - -ix1;
// }
// else
// {
// if(ix0 < 0) ix0 = 0;
// else if(ix0 >= sx) ix0 = sx-1;
//
// if(ix1 < 0) ix1 = 0;
// else if(ix1 >= sx) ix1 = sx-1;
// }
//
}
public void GetUsingBilinearFiltering(float x, float y, float[] v, Vector4[,] m_data, int m_c)
{
//un-normalize cords
x *= (float)m_fourierGridSize;
y *= (float)m_fourierGridSize;
x -= 0.5f;
y -= 0.5f;
int x0, x1;
float fx = Math.Abs(x - (int)x);
Index(x, m_fourierGridSize, out x0, out x1);
int y0, y1;
float fy = Math.Abs(y - (int)y);
Index(y, m_fourierGridSize, out y0, out y1);
// for(int c = 0; c < m_c; c++) //change this loop to work with Vector4 format
// {
// float v0 = m_data[(x0 + y0 * m_size) * m_c + c] * (1.0f-fx) + m_data[(x1 + y0 * m_size) * m_c + c] * fx;
// float v1 = m_data[(x0 + y1 * m_size) * m_c + c] * (1.0f-fx) + m_data[(x1 + y1 * m_size) * m_c + c] * fx;
//
// v[c] = v0 * (1.0f-fy) + v1 * fy;
// }
float v0 = m_data[m_bufferIdx,(x0 + y0 * m_fourierGridSize)].x * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y0 * m_fourierGridSize)].x * fx;
float v1 = m_data[m_bufferIdx,(x0 + y1 * m_fourierGridSize)].x * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y1 * m_fourierGridSize)].x * fx;
v[0] = v0 * (1.0f-fy) + v1 * fy;
v0 = m_data[m_bufferIdx,(x0 + y0 * m_fourierGridSize)].y * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y0 * m_fourierGridSize)].y * fx;
v1 = m_data[m_bufferIdx,(x0 + y1 * m_fourierGridSize)].y * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y1 * m_fourierGridSize)].y * fx;
v[1] = v0 * (1.0f-fy) + v1 * fy;
v0 = m_data[m_bufferIdx,(x0 + y0 * m_fourierGridSize)].z * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y0 * m_fourierGridSize)].z * fx;
v1 = m_data[m_bufferIdx,(x0 + y1 * m_fourierGridSize)].z * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y1 * m_fourierGridSize)].z * fx;
v[2] = v0 * (1.0f-fy) + v1 * fy;
v0 = m_data[m_bufferIdx,(x0 + y0 * m_fourierGridSize)].w * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y0 * m_fourierGridSize)].w * fx;
v1 = m_data[m_bufferIdx,(x0 + y1 * m_fourierGridSize)].w * (1.0f-fx) + m_data[m_bufferIdx,(x1 + y1 * m_fourierGridSize)].w * fx;
v[3] = v0 * (1.0f-fy) + v1 * fy;
}
///
/// This will return the ocean height at any world pos.
///
public float SampleHeight(Vector3 worldPos)
{
float ht = 0.0f;
int HEIGHTS_CHANNELS = 4;
float[] result = new float[HEIGHTS_CHANNELS];
Vector2 pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.x;
GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer0vectorResults, 4);
ht += result[0];
pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.y;
GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer0vectorResults, 4);
ht += result[1];
pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.z;
GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer0vectorResults, 4);
ht += result[2];
pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.w;
GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer0vectorResults, 4);
ht += result[3];
return ht;
}
///
/// This will return the ocean displacement at any world pos.
///
public Vector2 SampleDisplacement(Vector3 worldPos)
{
Vector2 disp = Vector2.zero;
int HEIGHTS_CHANNELS = 4;
float[] result = new float[HEIGHTS_CHANNELS];
Vector2 pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.x;
GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer3vectorResults, 4);
disp.x += result[0]* m_choppyness.x ;
disp.y += result[1]* m_choppyness.x;
pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.y;
GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer3vectorResults, 4);
disp.x += result[2]* m_choppyness.y;
disp.y += result[3]* m_choppyness.y;
pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.z;
GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer4vectorResults, 4);
disp.x += result[0]* m_choppyness.z;
disp.y += result[1]* m_choppyness.z;
pos = new Vector2(worldPos.x, worldPos.y) / m_gridSizes.w;
GetUsingBilinearFiltering(pos.x, pos.y, result, m_fourierBuffer4vectorResults, 4);
disp.x += result[2]* m_choppyness.w;
disp.y += result[3]* m_choppyness.w;
return disp;
}
//Essentially a search method to find which point on the ocean is displaced sideways to end up at our part's position, so we can sample the correct height
//Thanks to Scrawk (Justin Hawkins) for the tip
//Original source: Water technology of uncharted p.126 https://www.gdcvault.com/play/1015309/Water-Technology-of
public float findHeight(Vector3 worldPos, float precision)
{
int it = 0;
Vector3 currentPosition = worldPos;
Vector2 displacement = SampleDisplacement (currentPosition);
Vector3 resultingPosition = currentPosition + new Vector3 (displacement.x, displacement.y, 0f);
while ( ((resultingPosition - worldPos).magnitude > precision) && it<40 )
{
Vector3 newPosition = currentPosition - (resultingPosition - worldPos);
Vector3 newDisplacement = SampleDisplacement (newPosition);
Vector3 newResultingPosition = newPosition + new Vector3 (newDisplacement.x, newDisplacement.y, 0f);
currentPosition = newPosition;
resultingPosition = newResultingPosition;
it++;
}
return (SampleHeight (currentPosition));
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/OceanFFTgpu.cs
================================================
/*
* Proland: a procedural landscape rendering library.
* Copyright (c) 2008-2011 INRIA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Proland is distributed under a dual-license scheme.
* You can obtain a specific license from Inria: proland-licensing@inria.fr.
*
* Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat.
* Modified and ported to Unity by Justin Hawkins 2014
*
*
*/
using UnityEngine;
namespace Scatterer {
/*
* Extend the base class OceanNode to provide the data need
* to create the waves using fourier transform which can then be applied
* to the projected grid handled by the OceanNode.
* All the fourier transforms are performed on the GPU
*/
public class OceanFFTgpu: OceanNode {
WriteFloat m_writeFloat;
public float WAVE_CM = 0.23f; // Eq 59
public float WAVE_KM = 370.0f; // Eq 59
[Persistent] public float AMP = 1.0f;
Material m_initSpectrumMat, m_initDisplacementMat;
public int mapsAniso = 2;
[Persistent] public float m_windSpeed = 5.0f; //A higher wind speed gives greater swell to the waves
[Persistent] public float m_omega = 0.84f; //A lower number means the waves last longer and will build up larger waves
[Persistent] public float m_gravity = 9.81f;
public Vector4 m_gridSizes = new Vector4(5488, 392, 28, 2); //Size in meters (i.e. in spatial domain) of each grid
public Vector4 m_choppyness = new Vector4(2.3f, 2.1f, 1.3f, 0.9f); //strenght of sideways displacement for each grid
public int m_fourierGridSize = 64; //This is the fourier transform size, must pow2 number. Recommend no higher or lower than 64, 128 or 256.
private int m_varianceSize = 4;
float m_fsize;
float m_maxSlopeVariance;
protected int m_idx = 0;
protected Vector4 m_spectrumOffset;
protected Vector4 m_inverseGridSizes;
protected RenderTexture m_spectrum01, m_spectrum23;
protected RenderTexture m_WTable;
public bool rendertexturesCreated {
get {
return (m_WTable.IsCreated());
}
}
RenderTexture[] m_fourierBuffer0, m_fourierBuffer1, m_fourierBuffer2;
RenderTexture[] m_fourierBuffer3, m_fourierBuffer4;
public RenderTexture m_map0, m_map1, m_map2, m_map3, m_map4;
private ComputeShader m_varianceShader;
RenderTexture m_varianceRenderTexture;
Texture3D m_varianceTexture;
Vector2 m_varianceMax;
protected FourierGPU m_fourier;
public override float GetMaxSlopeVariance()
{
return m_maxSlopeVariance;
}
[Persistent] public float maxWaveInteractionShipAltitude = 500.0f;
// These are all oceanWhiteCaps settings but I add them here so they don't mess up serialization of gui
public float m_foamMipMapBias = -2.0f;
[Persistent] public float m_whiteCapStr = 0.1f;
[Persistent] public float shoreFoam = 1.0f;
[Persistent] public float m_farWhiteCapStr = 0.1f;
private GPUWaveInteractionHandler waveInteractionHandler = null;
public void Awake()
{
}
public override void Init(ProlandManager manager)
{
base.Init(manager);
if (m_gravity == 0f)
{
m_gravity = (float)(prolandManager.parentCelestialBody.GeeASL * 9.81d);
}
m_initSpectrumMat = new Material(ShaderReplacer.Instance.LoadedShaders[ ("Proland/Ocean/InitSpectrum")]);
m_initDisplacementMat = new Material(ShaderReplacer.Instance.LoadedShaders[ ("Proland/Ocean/InitDisplacement")]);
m_fourierGridSize = Scatterer.Instance.mainSettings.m_fourierGridSize;
if (m_fourierGridSize > 256) {
Utils.LogDebug("Proland::OceanFFT::Start - fourier grid size must not be greater than 256, changing to 256");
m_fourierGridSize = 256;
}
if (!Mathf.IsPowerOfTwo(m_fourierGridSize)) {
Utils.LogDebug("Proland::OceanFFT::Start - fourier grid size must be pow2 number, changing to nearest pow2 number");
m_fourierGridSize = Mathf.NextPowerOfTwo(m_fourierGridSize);
}
m_fsize = (float) m_fourierGridSize;
m_spectrumOffset = new Vector4(1.0f + 0.5f / m_fsize, 1.0f + 0.5f / m_fsize, 0, 0);
float factor = 2.0f * Mathf.PI * m_fsize;
m_inverseGridSizes = new Vector4(factor / m_gridSizes.x, factor / m_gridSizes.y, factor / m_gridSizes.z, factor / m_gridSizes.w);
m_fourier = new FourierGPU(m_fourierGridSize);
m_writeFloat = new WriteFloat(m_fourierGridSize, m_fourierGridSize);
m_varianceSize = SystemInfo.supportsComputeShaders ? 16 : 4;
//Create the data needed to make the waves each frame
CreateRenderTextures();
GenerateWavesSpectrum();
CreateWTable();
m_initSpectrumMat.SetTexture (ShaderProperties._Spectrum01_PROPERTY, m_spectrum01);
m_initSpectrumMat.SetTexture (ShaderProperties._Spectrum23_PROPERTY, m_spectrum23);
m_initSpectrumMat.SetTexture (ShaderProperties._WTable_PROPERTY, m_WTable);
m_initSpectrumMat.SetVector (ShaderProperties._Offset_PROPERTY, m_spectrumOffset);
m_initSpectrumMat.SetVector (ShaderProperties._InverseGridSizes_PROPERTY, m_inverseGridSizes);
m_initDisplacementMat.SetVector (ShaderProperties._InverseGridSizes_PROPERTY, m_inverseGridSizes);
m_oceanMaterial.SetVector (ShaderProperties._Ocean_MapSize_PROPERTY, new Vector2(m_fsize, m_fsize));
m_oceanMaterial.SetVector (ShaderProperties._Ocean_Choppyness_PROPERTY, m_choppyness);
m_oceanMaterial.SetVector (ShaderProperties._Ocean_GridSizes_PROPERTY, m_gridSizes);
Utils.EnableOrDisableShaderKeywords (m_oceanMaterial, "FOAM_ON", "FOAM_OFF", false);
if (SystemInfo.supportsAsyncGPUReadback && SystemInfo.supportsComputeShaders && Scatterer.Instance.mainSettings.oceanCraftWaveInteractions)
{
waveInteractionHandler = new GPUWaveInteractionHandler(maxWaveInteractionShipAltitude, prolandManager.parentCelestialBody.isHomeWorld);
}
}
Vector2 GetSlopeVariances(Vector2 k, float A, float B, float C, float spectrumX, float spectrumY) {
float w = 1.0f - Mathf.Exp(A * k.x * k.x + B * k.x * k.y + C * k.y * k.y);
return new Vector2((k.x * k.x) * w, (k.y * k.y) * w) * (spectrumX * spectrumX + spectrumY * spectrumY) * 2.0f;
}
///
/// Iterate over the spectrum and find the variance.
/// Use in the BRDF equations.
///
Vector2 ComputeVariance(float slopeVarianceDelta, float[] inSpectrum01, float[] inSpectrum23, float idxX, float idxY, float idxZ) {
const float SCALE = 10.0f;
float A = Mathf.Pow(idxX / ((float) m_varianceSize - 1.0f), 4.0f) * SCALE;
float C = Mathf.Pow(idxZ / ((float) m_varianceSize - 1.0f), 4.0f) * SCALE;
float B = (2.0f * idxY / ((float) m_varianceSize - 1.0f) - 1.0f) * Mathf.Sqrt(A * C);
A = -0.5f * A;
B = -B;
C = -0.5f * C;
Vector2 slopeVariances = new Vector2(slopeVarianceDelta, slopeVarianceDelta);
for (int x = 0; x < m_fourierGridSize; x++) {
for (int y = 0; y < m_fourierGridSize; y++) {
int i = x >= m_fsize / 2.0f ? x - m_fourierGridSize : x;
int j = y >= m_fsize / 2.0f ? y - m_fourierGridSize : y;
Vector2 k = new Vector2(i, j) * 2.0f * Mathf.PI;
slopeVariances += GetSlopeVariances(k / m_gridSizes.x, A, B, C, inSpectrum01[(x + y * m_fourierGridSize) * 4 + 0], inSpectrum01[(x + y * m_fourierGridSize) * 4 + 1]);
slopeVariances += GetSlopeVariances(k / m_gridSizes.y, A, B, C, inSpectrum01[(x + y * m_fourierGridSize) * 4 + 2], inSpectrum01[(x + y * m_fourierGridSize) * 4 + 3]);
slopeVariances += GetSlopeVariances(k / m_gridSizes.z, A, B, C, inSpectrum23[(x + y * m_fourierGridSize) * 4 + 0], inSpectrum23[(x + y * m_fourierGridSize) * 4 + 1]);
slopeVariances += GetSlopeVariances(k / m_gridSizes.w, A, B, C, inSpectrum23[(x + y * m_fourierGridSize) * 4 + 2], inSpectrum23[(x + y * m_fourierGridSize) * 4 + 3]);
}
}
return slopeVariances;
}
/*
* Initializes the data to the shader that needs to
* have the fourier transform applied to it this frame.
*/
protected virtual void InitWaveSpectrum(float t)
{
// init heights (0) and slopes (1,2)
RenderTexture[] buffers012 = new RenderTexture[]
{
m_fourierBuffer0[1], m_fourierBuffer1[1], m_fourierBuffer2[1]
};
m_initSpectrumMat.SetFloat (ShaderProperties._T_PROPERTY, t);
RTUtility.MultiTargetBlit(buffers012, m_initSpectrumMat, 0);
// Init displacement (3,4)
RenderTexture[] buffers34 = new RenderTexture[]
{
m_fourierBuffer3[1], m_fourierBuffer4[1]
};
m_initDisplacementMat.SetTexture (ShaderProperties._Buffer1_PROPERTY, m_fourierBuffer1[1]);
m_initDisplacementMat.SetTexture (ShaderProperties._Buffer2_PROPERTY, m_fourierBuffer2[1]);
// RTUtility.MultiTargetBlit(buffers34, m_initDisplacementMat);
RTUtility.MultiTargetBlit(buffers34, m_initDisplacementMat, 0);
}
public override void UpdateNode()
{
if (!prolandManager.skyNode.inScaledSpace || (prolandManager.skyNode.simulateOceanInteraction && (waveInteractionHandler != null)))
{
//keep within low float exponents, otherwise we lose precision
float t = (float)(Planetarium.GetUniversalTime() % 100000.0);
InitWaveSpectrum(t);
//Perform fourier transform and record what is the current index
m_idx = m_fourier.PeformFFT(m_fourierBuffer0, m_fourierBuffer1, m_fourierBuffer2);
m_fourier.PeformFFT(m_fourierBuffer3, m_fourierBuffer4);
//Copy the contents of the completed fourier transform to the map textures.
//You could just use the buffer textures (m_fourierBuffer0,1,2,etc) to read from for the ocean shader
//but they need to have mipmaps and unity updates the mipmaps
//every time the texture is renderer into. This impacts performance during fourier transform stage as mipmaps would be updated every pass
//and there is no way to disable and then enable mipmaps on render textures in Unity at time of writting.
Graphics.Blit(m_fourierBuffer0[m_idx], m_map0);
Graphics.Blit(m_fourierBuffer1[m_idx], m_map1);
Graphics.Blit(m_fourierBuffer2[m_idx], m_map2);
Graphics.Blit(m_fourierBuffer3[m_idx], m_map3);
Graphics.Blit(m_fourierBuffer4[m_idx], m_map4);
//m_oceanMaterial.SetFloat (ShaderProperties._Ocean_HeightOffset_PROPERTY, m_oceanLevel);
m_oceanMaterial.SetFloat (ShaderProperties._Ocean_HeightOffset_PROPERTY, 0f);
if (SystemInfo.supportsComputeShaders)
{
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Variance_PROPERTY, m_varianceRenderTexture );
}
else
{
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Variance_PROPERTY, m_varianceTexture);
}
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map0_PROPERTY, m_map0);
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map1_PROPERTY, m_map1);
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map2_PROPERTY, m_map2);
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map3_PROPERTY, m_map3);
m_oceanMaterial.SetTexture (ShaderProperties._Ocean_Map4_PROPERTY, m_map4);
m_oceanMaterial.SetVector (ShaderProperties._VarianceMax_PROPERTY, SystemInfo.supportsComputeShaders? Vector2.one : m_varianceMax);
// don't need to be done every frame
if (waveInteractionHandler != null)
{
waveInteractionHandler.SetMaterialProperties(m_choppyness, m_gridSizes, m_map0, m_map3, m_map4);
}
}
base.UpdateNode();
}
public override void OnDestroy()
{
base.OnDestroy();
m_map0.Release();
m_map1.Release();
m_map2.Release();
m_map3.Release();
m_map4.Release();
m_spectrum01.Release();
m_spectrum23.Release();
m_WTable.Release();
for (int i = 0; i < 2; i++) {
m_fourierBuffer0[i].Release();
m_fourierBuffer1[i].Release();
m_fourierBuffer2[i].Release();
m_fourierBuffer3[i].Release();
m_fourierBuffer4[i].Release();
}
if (waveInteractionHandler != null)
{
waveInteractionHandler.Cleanup();
}
}
protected virtual void CreateRenderTextures()
{
RenderTextureFormat mapFormat = RenderTextureFormat.ARGBFloat;
RenderTextureFormat fourierTransformformat = RenderTextureFormat.ARGBHalf;
//These texture hold the actual data use in the ocean renderer
CreateMap(ref m_map0, mapFormat, mapsAniso, true);
CreateMap(ref m_map1, mapFormat, mapsAniso, true);
CreateMap(ref m_map2, mapFormat, mapsAniso, true);
CreateMap(ref m_map3, mapFormat, mapsAniso, true);
CreateMap(ref m_map4, mapFormat, mapsAniso, true);
//These textures are used to perform the fourier transform
CreateBuffer(ref m_fourierBuffer0, fourierTransformformat); //heights
CreateBuffer(ref m_fourierBuffer1, fourierTransformformat); // slopes X
CreateBuffer(ref m_fourierBuffer2, fourierTransformformat); // slopes Y
CreateBuffer(ref m_fourierBuffer3, fourierTransformformat); // displacement X
CreateBuffer(ref m_fourierBuffer4, fourierTransformformat); // displacement Y
//These textures hold the specturm the fourier transform is performed on
m_spectrum01 = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, fourierTransformformat);
m_spectrum01.filterMode = FilterMode.Point;
m_spectrum01.wrapMode = TextureWrapMode.Repeat;
m_spectrum01.enableRandomWrite = false;
m_spectrum01.Create();
m_spectrum23 = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, fourierTransformformat);
m_spectrum23.filterMode = FilterMode.Point;
m_spectrum23.wrapMode = TextureWrapMode.Repeat;
m_spectrum23.enableRandomWrite = false;
m_spectrum23.Create();
m_WTable = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, fourierTransformformat);
m_WTable.filterMode = FilterMode.Point;
m_WTable.wrapMode = TextureWrapMode.Clamp;
m_WTable.enableRandomWrite = false;
m_WTable.Create();
if (SystemInfo.supportsComputeShaders)
{
m_varianceRenderTexture = new RenderTexture(m_varianceSize, m_varianceSize, 0, RenderTextureFormat.RHalf);
m_varianceRenderTexture.volumeDepth = m_varianceSize;
m_varianceRenderTexture.wrapMode = TextureWrapMode.Clamp;
m_varianceRenderTexture.filterMode = FilterMode.Bilinear;
m_varianceRenderTexture.dimension = UnityEngine.Rendering.TextureDimension.Tex3D;
m_varianceRenderTexture.enableRandomWrite = true;
m_varianceRenderTexture.useMipMap = true;
m_varianceRenderTexture.Create();
}
else
{
m_varianceTexture = new Texture3D (m_varianceSize, m_varianceSize, m_varianceSize, TextureFormat.ARGB32, true);
m_varianceTexture.wrapMode = TextureWrapMode.Clamp;
m_varianceTexture.filterMode = FilterMode.Bilinear;
}
}
protected void CreateBuffer(ref RenderTexture[] tex, RenderTextureFormat format)
{
tex = new RenderTexture[2];
for (int i = 0; i < 2; i++)
{
tex[i] = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format);
tex[i].filterMode = FilterMode.Point;
tex[i].wrapMode = TextureWrapMode.Clamp;
tex[i].Create();
}
}
protected void CreateMap(ref RenderTexture map, RenderTextureFormat format, int ansio, bool useMipMaps)
{
map = new RenderTexture(m_fourierGridSize, m_fourierGridSize, 0, format);
map.filterMode = FilterMode.Trilinear;
map.wrapMode = TextureWrapMode.Repeat;
map.anisoLevel = ansio;
map.useMipMap = useMipMaps;
map.Create();
}
float sqr(float x) {
return x * x;
}
float omega(float k)
{
return Mathf.Sqrt(m_gravity * k * (1.0f + sqr(k / WAVE_KM)));
} // Eq 24
float Spectrum(float kx, float ky, bool omnispectrum)
{
//I know this is a big chunk of ugly math but dont worry to much about what it all means
//It recreates a statistcally representative model of a wave spectrum in the frequency domain.
//How to rotate the windDirection in the spectrum: https://github.com/Scrawk/Ceto/blob/07f8f45955a989983fe2330ea17eaf3f44c82031/Assets/Ceto/Scripts/Spectrum/CustomWaveSpectrumExample.cs#L248-L250
//But I prefere to rotate the Ux and Uy axis, that way can change the wind direction without regenerating spectrum
float U10 = m_windSpeed;
// phase speed
float k = Mathf.Sqrt(kx * kx + ky * ky);
float c = omega(k) / k;
// spectral peak
float kp = m_gravity * sqr(m_omega / U10); // after Eq 3
float cp = omega(kp) / kp;
// friction velocity
float z0 = 3.7e-5f * sqr(U10) / m_gravity * Mathf.Pow(U10 / cp, 0.9f); // Eq 66
float u_star = 0.41f * U10 / Mathf.Log(10.0f / z0); // Eq 60
float Lpm = Mathf.Exp(-5.0f / 4.0f * sqr(kp / k)); // after Eq 3
float gamma = (m_omega < 1.0f) ? 1.7f : 1.7f + 6.0f * Mathf.Log(m_omega); // after Eq 3 // log10 or log?
float sigma = 0.08f * (1.0f + 4.0f / Mathf.Pow(m_omega, 3.0f)); // after Eq 3
float Gamma = Mathf.Exp(-1.0f / (2.0f * sqr(sigma)) * sqr(Mathf.Sqrt(k / kp) - 1.0f));
float Jp = Mathf.Pow(gamma, Gamma); // Eq 3
float Fp = Lpm * Jp * Mathf.Exp(-m_omega / Mathf.Sqrt(10.0f) * (Mathf.Sqrt(k / kp) - 1.0f)); // Eq 32
float alphap = 0.006f * Mathf.Sqrt(m_omega); // Eq 34
float Bl = 0.5f * alphap * cp / c * Fp; // Eq 31
float alpham = 0.01f * (u_star < WAVE_CM ? 1.0f + Mathf.Log(u_star / WAVE_CM) : 1.0f + 3.0f * Mathf.Log(u_star / WAVE_CM)); // Eq 44
float Fm = Mathf.Exp(-0.25f * sqr(k / WAVE_KM - 1.0f)); // Eq 41
float Bh = 0.5f * alpham * WAVE_CM / c * Fm * Lpm; // Eq 40 (fixed)
Bh *= Lpm; // bug fix???
if (omnispectrum) return AMP * (Bl + Bh) / (k * sqr(k)); // Eq 30
float a0 = Mathf.Log(2.0f) / 4.0f;
float ap = 4.0f;
float am = 0.13f * u_star / WAVE_CM; // Eq 59
float Delta = (float) System.Math.Tanh(a0 + ap * Mathf.Pow(c / cp, 2.5f) + am * Mathf.Pow(WAVE_CM / c, 2.5f)); // Eq 57
float phi = Mathf.Atan2(ky, kx);
if (kx < 0.0f) return 0.0f;
Bl *= 2.0f;
Bh *= 2.0f;
// remove waves perpendicular to wind dir
float tweak = Mathf.Sqrt(Mathf.Max(kx / Mathf.Sqrt(kx * kx + ky * ky), 0.0f));
return AMP * (Bl + Bh) * (1.0f + Delta * Mathf.Cos(2.0f * phi)) / (2.0f * Mathf.PI * sqr(sqr(k))) * tweak; // Eq 67
}
Vector2 GetSpectrumSample(float i, float j, float lengthScale, float kMin)
{
float dk = 2.0f * Mathf.PI / lengthScale;
float kx = i * dk;
float ky = j * dk;
Vector2 result = new Vector2(0.0f, 0.0f);
float rnd = UnityEngine.Random.value;
if (Mathf.Abs(kx) >= kMin || Mathf.Abs(ky) >= kMin) {
float S = Spectrum(kx, ky, false);
float h = Mathf.Sqrt(S / 2.0f) * dk;
float phi = rnd * 2.0f * Mathf.PI;
result.x = h * Mathf.Cos(phi);
result.y = h * Mathf.Sin(phi);
}
return result;
}
float GetSlopeVariance(float kx, float ky, Vector2 spectrumSample)
{
float kSquare = kx * kx + ky * ky;
float real = spectrumSample.x;
float img = spectrumSample.y;
float hSquare = real * real + img * img;
return kSquare * hSquare * 2.0f;
}
void GenerateWavesSpectrum()
{
// Slope variance due to all waves, by integrating over the full spectrum.
// Used by the BRDF rendering model
float theoreticSlopeVariance = 0.0f;
float k = 5e-3f;
while (k < 1e3f) {
float nextK = k * 1.001f;
theoreticSlopeVariance += k * k * Spectrum(k, 0, true) * (nextK - k);
k = nextK;
}
float[] spectrum01 = new float[m_fourierGridSize * m_fourierGridSize * 4];
float[] spectrum23 = new float[m_fourierGridSize * m_fourierGridSize * 4];
int idx;
float i;
float j;
float totalSlopeVariance = 0.0f;
Vector2 sample12XY;
Vector2 sample12ZW;
Vector2 sample34XY;
Vector2 sample34ZW;
UnityEngine.Random.seed = 0;
for (int x = 0; x < m_fourierGridSize; x++)
{
for (int y = 0; y < m_fourierGridSize; y++)
{
idx = x + y * m_fourierGridSize;
i = (x >= m_fourierGridSize / 2) ? (float)(x - m_fourierGridSize) : (float) x;
j = (y >= m_fourierGridSize / 2) ? (float)(y - m_fourierGridSize) : (float) y;
sample12XY = GetSpectrumSample(i, j, m_gridSizes.x, Mathf.PI / m_gridSizes.x);
sample12ZW = GetSpectrumSample(i, j, m_gridSizes.y, Mathf.PI * m_fsize / m_gridSizes.x);
sample34XY = GetSpectrumSample(i, j, m_gridSizes.z, Mathf.PI * m_fsize / m_gridSizes.y);
sample34ZW = GetSpectrumSample(i, j, m_gridSizes.w, Mathf.PI * m_fsize / m_gridSizes.z);
spectrum01[idx * 4 + 0] = sample12XY.x;
spectrum01[idx * 4 + 1] = sample12XY.y;
spectrum01[idx * 4 + 2] = sample12ZW.x;
spectrum01[idx * 4 + 3] = sample12ZW.y;
spectrum23[idx * 4 + 0] = sample34XY.x;
spectrum23[idx * 4 + 1] = sample34XY.y;
spectrum23[idx * 4 + 2] = sample34ZW.x;
spectrum23[idx * 4 + 3] = sample34ZW.y;
i *= 2.0f * Mathf.PI;
j *= 2.0f * Mathf.PI;
totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.x, j / m_gridSizes.x, sample12XY);
totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.y, j / m_gridSizes.y, sample12ZW);
totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.z, j / m_gridSizes.z, sample34XY);
totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.w, j / m_gridSizes.w, sample34ZW);
}
}
//This can be replaced by a texture2D now and the whole thing with a set raw data + apply
m_writeFloat.WriteIntoRenderTexture(m_spectrum01, 4, spectrum01);
m_writeFloat.WriteIntoRenderTexture(m_spectrum23, 4, spectrum23);
if (!SystemInfo.supportsComputeShaders)
{
// Compute variance for the BRDF, copied from the dx9 project
float slopeVarianceDelta = 0.5f * (theoreticSlopeVariance - totalSlopeVariance);
m_varianceMax = new Vector2 (float.NegativeInfinity, float.NegativeInfinity);
Vector2[, , ] variance32bit = new Vector2[m_varianceSize, m_varianceSize, m_varianceSize];
Color[] variance8bit = new Color[m_varianceSize * m_varianceSize * m_varianceSize];
for (int x = 0; x < m_varianceSize; x++)
{
for (int y = 0; y < m_varianceSize; y++)
{
for (int z = 0; z < m_varianceSize; z++)
{
variance32bit [x, y, z] = ComputeVariance (slopeVarianceDelta, spectrum01, spectrum23, x, y, z);
if (variance32bit [x, y, z].x > m_varianceMax.x)
m_varianceMax.x = variance32bit [x, y, z].x;
if (variance32bit [x, y, z].y > m_varianceMax.y)
m_varianceMax.y = variance32bit [x, y, z].y;
}
}
}
for (int x = 0; x < m_varianceSize; x++)
{
for (int y = 0; y < m_varianceSize; y++)
{
for (int z = 0; z < m_varianceSize; z++)
{
idx = x + y * m_varianceSize + z * m_varianceSize * m_varianceSize;
variance8bit [idx] = new Color (variance32bit [x, y, z].x / m_varianceMax.x, variance32bit [x, y, z].y / m_varianceMax.y, 0.0f, 1.0f);
}
}
}
m_varianceTexture.SetPixels (variance8bit);
m_varianceTexture.Apply ();
m_maxSlopeVariance = 0.0f;
for (int v = 0; v < m_varianceSize*m_varianceSize*m_varianceSize; v++)
{
m_maxSlopeVariance = Mathf.Max (m_maxSlopeVariance, variance8bit [v].r * m_varianceMax.x);
m_maxSlopeVariance = Mathf.Max (m_maxSlopeVariance, variance8bit [v].g * m_varianceMax.y);
}
}
else
{
m_varianceShader = ShaderReplacer.Instance.LoadedComputeShaders["SlopeVariance"];
m_varianceShader.SetFloat("_SlopeVarianceDelta", 0.5f * (theoreticSlopeVariance - totalSlopeVariance));
m_varianceShader.SetFloat("_VarianceSize", (float)m_varianceSize);
m_varianceShader.SetFloat("_Size", m_fsize);
m_varianceShader.SetVector("_GridSizes", m_gridSizes);
m_varianceShader.SetTexture(0, "_Spectrum01", m_spectrum01);
m_varianceShader.SetTexture(0, "_Spectrum23", m_spectrum23);
m_varianceShader.SetTexture(0, "des", m_varianceRenderTexture);
m_varianceShader.Dispatch(0,m_varianceSize/4,m_varianceSize/4,m_varianceSize/4);
//Find the maximum value for slope variance
ComputeBuffer buffer = new ComputeBuffer(m_varianceSize*m_varianceSize*m_varianceSize, sizeof(float));
CBUtility.ReadFromRenderTexture(m_varianceRenderTexture, 1, buffer, ShaderReplacer.Instance.LoadedComputeShaders["ReadData"]);
float[] varianceData = new float[m_varianceSize*m_varianceSize*m_varianceSize];
buffer.GetData(varianceData);
m_maxSlopeVariance = 0.0f;
for(int v = 0; v < m_varianceSize*m_varianceSize*m_varianceSize; v++) {
m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, varianceData[v]);
}
buffer.Release();
}
}
void CreateWTable()
{
//Some values need for the InitWaveSpectrum function can be precomputed
Vector2 uv, st;
float k1, k2, k3, k4, w1, w2, w3, w4;
float[] table = new float[m_fourierGridSize * m_fourierGridSize * 4];
for (int x = 0; x < m_fourierGridSize; x++) {
for (int y = 0; y < m_fourierGridSize; y++) {
uv = new Vector2(x, y) / m_fsize;
st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x;
st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y;
k1 = (st * m_inverseGridSizes.x).magnitude;
k2 = (st * m_inverseGridSizes.y).magnitude;
k3 = (st * m_inverseGridSizes.z).magnitude;
k4 = (st * m_inverseGridSizes.w).magnitude;
w1 = Mathf.Sqrt(m_gravity * k1 * (1.0f + k1 * k1 / (WAVE_KM * WAVE_KM)));
w2 = Mathf.Sqrt(m_gravity * k2 * (1.0f + k2 * k2 / (WAVE_KM * WAVE_KM)));
w3 = Mathf.Sqrt(m_gravity * k3 * (1.0f + k3 * k3 / (WAVE_KM * WAVE_KM)));
w4 = Mathf.Sqrt(m_gravity * k4 * (1.0f + k4 * k4 / (WAVE_KM * WAVE_KM)));
table[(x + y * m_fourierGridSize) * 4 + 0] = w1;
table[(x + y * m_fourierGridSize) * 4 + 1] = w2;
table[(x + y * m_fourierGridSize) * 4 + 2] = w3;
table[(x + y * m_fourierGridSize) * 4 + 3] = w4;
}
}
m_writeFloat.WriteIntoRenderTexture(m_WTable, 4, table);
}
Vector2 GetSpectrum(float t, float w, float s0x, float s0y, float s0cx, float s0cy)
{
float c = Mathf.Cos(w * t);
float s = Mathf.Sin(w * t);
return new Vector2((s0x + s0cx) * c - (s0y + s0cy) * s, (s0x - s0cx) * s + (s0y - s0cy) * c);
}
Vector2 COMPLEX(Vector2 z)
{
return new Vector2(-z.y, z.x); // returns i times z (complex number)
}
int BitReverse(int i)
{
int j = i;
int Sum = 0;
int W = 1;
int M = m_fourierGridSize / 2;
while (M != 0)
{
j = ((i & M) > M - 1) ? 1 : 0;
Sum += j * W;
W *= 2;
M /= 2;
}
return Sum;
}
//FixedUpdate is responsible for physics, apply part displacement here
public void FixedUpdate()
{
if (waveInteractionHandler != null && prolandManager.GetSkyNode().simulateOceanInteraction)
{
waterHeightAtCameraPosition = waveInteractionHandler.UpdateInteractions(height, waterHeightAtCameraPosition, ux.ToVector3(), uy.ToVector3(), offsetVector3);
}
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/OceanNode.cs
================================================
/*
* Proland: a procedural landscape rendering library.
* Copyright (c) 2008-2011 INRIA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Proland is distributed under a dual-license scheme.
* You can obtain a specific license from Inria: proland-licensing@inria.fr.
*
* Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat.
* Modified and ported to Unity by Justin Hawkins 2014
*
*
*/
using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine.Rendering;
using KSP.IO;
using UnityEngine.XR;
namespace Scatterer
{
//TODO: refactor and clean up this class
public abstract class OceanNode: MonoBehaviour
{
public UrlDir.UrlConfig configUrl;
public ProlandManager prolandManager;
public Material m_oceanMaterial;
OceanRenderingHook oceanRenderingHook;
[Persistent]
public Vector3 m_oceanUpwellingColor = new Vector3 (0.0039f, 0.0156f, 0.047f);
[Persistent]
public Vector3 m_UnderwaterColor = new Vector3 (0.1f, 0.75f, 0.8f);
//Size of each grid in the projected grid. (number of pixels on screen)
public int m_resolution = 4;
int m_screenWidth;
int m_screenHeight;
[Persistent]
public float offScreenVertexStretch = 1.25f;
[Persistent]
public float alphaRadius = 3000f;
[Persistent]
public float transparencyDepth = 60f;
[Persistent]
public float darknessDepth = 1000f;
[Persistent]
public float refractionIndex = 1.33f;
[Persistent]
public float skyReflectionStrength = 1f;
public bool isUnderwater = false;
bool underwaterMode = false;
bool oceanDraw = true;
public int numGrids;
Mesh[] m_screenGrids;
GameObject[] waterGameObjects;
public MeshRenderer[] waterMeshRenderers;
MeshFilter[] waterMeshFilters;
public GenericLocalAtmosphereContainer underwaterScattering;
public Material underwaterMaterial;
public Vector3 offsetVector3{
get {
return offset.ToVector3();
}
}
public double height = 0;
public Vector3d2 m_Offset = Vector3d2.Zero();
public Vector3d2 offset = Vector3d2.Zero(), ux=Vector3d2.Zero(), uy=Vector3d2.Zero(), uz=Vector3d2.Zero(), oo=Vector3d2.Zero();
OceanCameraUpdateHook oceanCameraProjectionMatModifier;
UnderwaterDimmingHook underwaterDimmingHook;
public float planetOpacity=1f; //planetOpacity to fade out the ocean when PQS is fading out
//Concrete classes must provide a function that returns the
//variance of the waves need for the BRDF rendering of waves
public abstract float GetMaxSlopeVariance ();
//caustics
[Persistent]
public string causticsTexturePath="";
[Persistent]
public Vector2 causticsLayer1Scale;
[Persistent]
public Vector2 causticsLayer1Speed;
[Persistent]
public Vector2 causticsLayer2Scale;
[Persistent]
public Vector2 causticsLayer2Speed;
[Persistent]
public float causticsMultiply;
[Persistent]
public float causticsUnderwaterLightBoost;
[Persistent]
public float causticsMinBrightness;
[Persistent]
public float causticsBlurDepth;
[Persistent]
public float lightRaysStrength=1f;
public CausticsShadowMaskModulate causticsShadowMaskModulator;
public CausticsLightRaysRenderer causticsLightRaysRenderer;
protected float waterHeightAtCameraPosition = 0f;
public virtual void Init (ProlandManager manager)
{
m_resolution = Scatterer.Instance.mainSettings.oceanMeshResolution;
m_screenWidth = Screen.width;
m_screenHeight = Screen.height;
if (XRSettings.loadedDeviceName != string.Empty)
{
m_screenWidth = Math.Max(m_screenWidth, XRSettings.eyeTextureWidth);
m_screenHeight = Math.Max(m_screenHeight, XRSettings.eyeTextureHeight);
}
prolandManager = manager;
loadFromConfigNode ();
InitOceanMaterial ();
//Worth moving to projected Grid Class?
CreateProjectedGridMeshes (true);
oceanCameraProjectionMatModifier = waterGameObjects[0].AddComponent();
oceanCameraProjectionMatModifier.oceanNode = this;
oceanRenderingHook = waterGameObjects[0].AddComponent();
oceanRenderingHook.targetMaterial = m_oceanMaterial;
oceanRenderingHook.targetRenderer = waterMeshRenderers [0];
oceanRenderingHook.celestialBodyName = prolandManager.parentCelestialBody.name;
DisableEffectsChecker disableEffectsChecker = waterGameObjects[0].AddComponent();
disableEffectsChecker.manager = this.prolandManager;
if (Scatterer.Instance.mainSettings.shadowsOnOcean || Scatterer.Instance.mainSettings.oceanLightRays)
{
ShadowMapRetrieveCommandBuffer retriever = prolandManager.mainSunLight.gameObject.GetComponent();
if (!retriever)
prolandManager.mainSunLight.gameObject.AddComponent (typeof(ShadowMapRetrieveCommandBuffer));
}
InitUnderwaterMaterial ();
underwaterScattering = new ScreenSpaceScatteringContainer(underwaterMaterial,prolandManager.parentLocalTransform,(float)prolandManager.m_radius, prolandManager, false); //this shouldn't need quarter res as it isn't expensive
underwaterScattering.SetInScaledSpace(false);
underwaterScattering.SetActivated(false);
underwaterScattering.UpdateContainer ();
//dimming
//TODO: maybe this can be changed, instead of complicated hooks on the Camera, add it to the light, like causticsShadowMaskModulate?
if ((Scatterer.Instance.mainSettings.underwaterLightDimming || Scatterer.Instance.mainSettings.oceanCaustics) && (HighLogic.LoadedScene != GameScenes.MAINMENU))
{
underwaterDimmingHook = (UnderwaterDimmingHook) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent(typeof(UnderwaterDimmingHook));
underwaterDimmingHook.oceanNode = this;
}
if (Scatterer.Instance.mainSettings.oceanCaustics && (HighLogic.LoadedScene == GameScenes.FLIGHT))
{
//why doesn't this work with IVA camera? do they have a separate light?
causticsShadowMaskModulator = (CausticsShadowMaskModulate) prolandManager.mainSunLight.gameObject.AddComponent (typeof(CausticsShadowMaskModulate));
if(!causticsShadowMaskModulator.Init(causticsTexturePath, causticsLayer1Scale, causticsLayer1Speed, causticsLayer2Scale, causticsLayer2Speed,
causticsMultiply, causticsMinBrightness, (float)manager.GetRadius(), causticsBlurDepth, prolandManager.mainSunLight))
{
UnityEngine.Object.DestroyImmediate (causticsShadowMaskModulator);
causticsShadowMaskModulator = null;
}
if (Scatterer.Instance.mainSettings.oceanLightRays)
{
causticsLightRaysRenderer = (CausticsLightRaysRenderer) waterGameObjects[0].AddComponent();
if (!causticsLightRaysRenderer.Init(causticsTexturePath, causticsLayer1Scale, causticsLayer1Speed, causticsLayer2Scale, causticsLayer2Speed,
causticsMultiply, causticsMinBrightness, (float)manager.GetRadius(), causticsBlurDepth, this, lightRaysStrength))
{
UnityEngine.Object.DestroyImmediate (causticsLightRaysRenderer);
causticsLightRaysRenderer = null;
}
}
}
}
public virtual void UpdateNode ()
{
oceanDraw = !MapView.MapIsEnabled && !prolandManager.skyNode.inScaledSpace;
foreach (MeshRenderer _mr in waterMeshRenderers)
{
_mr.enabled = oceanDraw;
}
isUnderwater = height < waterHeightAtCameraPosition;
underwaterScattering.SetActivated(isUnderwater);
if (underwaterMode ^ isUnderwater)
{
toggleUnderwaterMode();
}
if (causticsShadowMaskModulator)
{
causticsShadowMaskModulator.isEnabled = oceanDraw && (prolandManager.GetSkyNode().altitude < 6000f);
causticsShadowMaskModulator.UpdateCaustics ();
}
}
public void updateNonCameraSpecificUniforms (Material oceanMaterial)
{
prolandManager.GetSkyNode ().SetOceanUniforms (oceanMaterial);
if (underwaterMode)
{
prolandManager.GetSkyNode ().UpdatePostProcessMaterialUniforms (underwaterMaterial);
}
planetOpacity = 1f - prolandManager.parentCelestialBody.pqsController.surfaceMaterial.GetFloat (ShaderProperties._PlanetOpacity_PROPERTY);
m_oceanMaterial.SetFloat (ShaderProperties._PlanetOpacity_PROPERTY, planetOpacity);
m_oceanMaterial.SetInt (ShaderProperties._ZwriteVariable_PROPERTY, 1);
}
public void OnPreCull()
{
if (!MapView.MapIsEnabled && Scatterer.Instance.nearCamera && prolandManager.skyNode.simulateOceanInteraction)
{
updateNonCameraSpecificUniforms(m_oceanMaterial);
}
}
void CreateProjectedGridMeshes (bool use32BitIndexMesh)
{
//Create the projected grid. The resolution is the size in pixels
//of each square in the grid. If not using 32-bit index meshes, the verts of
//the mesh will exceed the max verts for a mesh in Unity. In this case
//split the mesh up into smaller meshes.
m_resolution = Mathf.Max (1, m_resolution);
//The number of squares in the grid on the x and y axis
int NX = m_screenWidth / m_resolution;
int NY = m_screenHeight / m_resolution;
numGrids = 1;
const int MAX_VERTS = 65000; //The number of meshes need to make a grid of this resolution, if not using 32-bit index meshes
if (!use32BitIndexMesh && (NX * NY > MAX_VERTS))
{
numGrids += (NX * NY) / MAX_VERTS;
}
m_screenGrids = new Mesh[numGrids];
waterGameObjects = new GameObject[numGrids];
waterMeshRenderers = new MeshRenderer[numGrids];
waterMeshFilters = new MeshFilter[numGrids];
//Make the meshes. The end product will be a grid of verts that cover
//the screen on the x and y axis with the z depth at 0. This grid is then
//projected as the ocean by the shader
for (int i = 0; i < numGrids; i++)
{
NY = m_screenHeight / numGrids / m_resolution;
if (use32BitIndexMesh)
m_screenGrids [i] = MeshFactory.MakePlane32BitIndexFormat (NX, NY, MeshFactory.PLANE.XY, false, true, (float)i / (float)numGrids, 1.0f / (float)numGrids);
else
m_screenGrids [i] = MeshFactory.MakePlane (NX, NY, MeshFactory.PLANE.XY, false, true, (float)i / (float)numGrids, 1.0f / (float)numGrids);
m_screenGrids [i].bounds = new Bounds (Vector3.zero, new Vector3 (1e8f, 1e8f, 1e8f));
waterGameObjects [i] = new GameObject ();
waterGameObjects [i].transform.position = prolandManager.parentCelestialBody.transform.position;
waterGameObjects [i].transform.parent = prolandManager.parentCelestialBody.transform;
//might be redundant
waterMeshFilters [i] = waterGameObjects [i].AddComponent ();
waterMeshFilters [i].mesh.Clear ();
waterMeshFilters [i].mesh = m_screenGrids [i];
waterGameObjects [i].layer = 15;
waterMeshRenderers [i] = waterGameObjects [i].AddComponent ();
if (Scatterer.Instance.mainSettings.oceanPixelLights)
{
m_oceanMaterial.SetPass (1); //Disable the main pass so we can render it with our commandbuffer. Pixel light passes render after scattering in depth buffer mode, and before scattering in projector mode
waterMeshRenderers [i].sharedMaterial = m_oceanMaterial;
waterMeshRenderers [i].material = m_oceanMaterial;
}
else
{
waterMeshRenderers [i].material = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/invisible")]);
}
waterMeshRenderers [i].receiveShadows = Scatterer.Instance.mainSettings.shadowsOnOcean && (QualitySettings.shadows != ShadowQuality.Disable);
waterMeshRenderers [i].shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
waterMeshRenderers [i].enabled = true;
}
}
void InitOceanMaterial ()
{
m_oceanMaterial = new Material (ShaderReplacer.Instance.LoadedShaders [("Scatterer/OceanWhiteCaps")]);
Utils.EnableOrDisableShaderKeywords (m_oceanMaterial, "SKY_REFLECTIONS_ON", "SKY_REFLECTIONS_OFF", Scatterer.Instance.mainSettings.oceanSkyReflections);
Utils.EnableOrDisableShaderKeywords (m_oceanMaterial, "PLANETSHINE_ON", "PLANETSHINE_OFF", (prolandManager.secondarySuns.Count > 0) || Scatterer.Instance.mainSettings.usePlanetShine);
if (Scatterer.Instance.mainSettings.shadowsOnOcean && (QualitySettings.shadows != ShadowQuality.Disable))
{
Utils.EnableOrDisableShaderKeywords (m_oceanMaterial, "OCEAN_SHADOWS_HARD", "OCEAN_SHADOWS_SOFT", (QualitySettings.shadows == ShadowQuality.HardOnly));
m_oceanMaterial.DisableKeyword ("OCEAN_SHADOWS_OFF");
}
else
{
m_oceanMaterial.EnableKeyword ("OCEAN_SHADOWS_OFF");
m_oceanMaterial.DisableKeyword ("OCEAN_SHADOWS_HARD");
m_oceanMaterial.DisableKeyword ("OCEAN_SHADOWS_SOFT");
}
m_oceanMaterial.EnableKeyword("DEPTH_BUFFER_MODE_ON");
m_oceanMaterial.DisableKeyword("PROJECTOR_MODE");
m_oceanMaterial.DisableKeyword("PROJECTOR_MODE_GODRAYS");
Utils.EnableOrDisableShaderKeywords (m_oceanMaterial, "DEPTH_BUFFER_MODE_ON", "DEPTH_BUFFER_MODE_OFF", true);
m_oceanMaterial.SetOverrideTag ("IgnoreProjector", "True");
if (!Scatterer.Instance.unifiedCameraMode && DepthToDistanceCommandBuffer.RenderTexture != null)
m_oceanMaterial.SetTexture(ShaderProperties._customDepthTexture_PROPERTY, DepthToDistanceCommandBuffer.RenderTexture);
m_oceanMaterial.renderQueue=2502;
m_oceanMaterial.SetVector (ShaderProperties._Ocean_Color_PROPERTY, m_oceanUpwellingColor);
m_oceanMaterial.SetVector ("_Underwater_Color", m_UnderwaterColor);
m_oceanMaterial.SetVector (ShaderProperties._Ocean_ScreenGridSize_PROPERTY, new Vector2 ((float)m_resolution / (float)m_screenWidth, (float)m_resolution / (float)m_screenHeight));
//oceanMaterial.SetFloat (ShaderProperties._Ocean_Radius_PROPERTY, (float)(radius+m_oceanLevel));
m_oceanMaterial.SetFloat (ShaderProperties._Ocean_Radius_PROPERTY, (float)(prolandManager.GetRadius()));
m_oceanMaterial.SetFloat (ShaderProperties.alphaRadius_PROPERTY, alphaRadius);
m_oceanMaterial.SetFloat ("skyReflectionStrength", skyReflectionStrength);
m_oceanMaterial.SetFloat ("refractionIndex", refractionIndex); //these don't need to be updated every frame
m_oceanMaterial.SetFloat ("transparencyDepth", transparencyDepth);
m_oceanMaterial.SetFloat ("darknessDepth", darknessDepth);
float camerasOverlap = 0f;
if (!Scatterer.Instance.unifiedCameraMode)
camerasOverlap = Scatterer.Instance.nearCamera.farClipPlane - Scatterer.Instance.farCamera.nearClipPlane;
m_oceanMaterial.SetFloat("_ScattererCameraOverlap",camerasOverlap);
m_oceanMaterial.SetFloat ("offScreenVertexStretch", offScreenVertexStretch);
}
void InitUnderwaterMaterial ()
{
underwaterMaterial = new Material (ShaderReplacer.Instance.LoadedShaders [("Scatterer/UnderwaterScatterDepthBuffer")]);
underwaterMaterial.renderQueue = 2502; //draw over fairings which is 2450 and over ocean which is 2501
underwaterMaterial.SetFloat ("transparencyDepth", transparencyDepth);
underwaterMaterial.SetFloat ("darknessDepth", darknessDepth);
underwaterMaterial.SetVector ("_Underwater_Color", m_UnderwaterColor);
underwaterMaterial.SetFloat ("Rg",(float)prolandManager.m_radius);
Utils.EnableOrDisableShaderKeywords (underwaterMaterial, "DITHERING_ON", "DITHERING_OFF", Scatterer.Instance.mainSettings.useDithering);
}
void toggleUnderwaterMode()
{
if (underwaterMode) //switch to over water
{
underwaterScattering.SetActivated(false);
underwaterScattering.UpdateContainer ();
m_oceanMaterial.EnableKeyword("UNDERWATER_OFF");
m_oceanMaterial.DisableKeyword("UNDERWATER_ON");
prolandManager.GetSkyNode().SetUnderwater(false);
}
else //switch to underwater
{
underwaterScattering.SetActivated(true);
underwaterScattering.UpdateContainer ();
m_oceanMaterial.EnableKeyword("UNDERWATER_ON");
m_oceanMaterial.DisableKeyword("UNDERWATER_OFF");
prolandManager.GetSkyNode().SetUnderwater(true);
}
underwaterMode = !underwaterMode;
}
public virtual void OnDestroy ()
{
if (oceanCameraProjectionMatModifier)
{
Component.Destroy (oceanCameraProjectionMatModifier);
UnityEngine.Object.Destroy (oceanCameraProjectionMatModifier);
}
for (int i = 0; i < numGrids; i++)
{
DestroyImmediate(waterGameObjects[i]);
Component.DestroyImmediate(waterMeshFilters[i]);
Component.DestroyImmediate(waterMeshRenderers[i]);
UnityEngine.Object.DestroyImmediate(m_screenGrids [i]);
}
UnityEngine.Object.DestroyImmediate(m_oceanMaterial);
UnityEngine.Object.DestroyImmediate(underwaterMaterial);
if (underwaterDimmingHook)
Component.DestroyImmediate(underwaterDimmingHook);
if (underwaterScattering!=null)
{
underwaterScattering.Cleanup();
}
if (causticsShadowMaskModulator)
{
UnityEngine.Object.DestroyImmediate (causticsShadowMaskModulator);
}
if (causticsLightRaysRenderer)
{
UnityEngine.Object.DestroyImmediate(causticsLightRaysRenderer);
}
if (oceanRenderingHook)
{
Component.DestroyImmediate(oceanRenderingHook);
}
}
public void applyUnderwaterDimming () //called OnPostRender of scaledSpace Camera by hook, needs to be done before farCamera onPreCull where the color is set
{
if (!MapView.MapIsEnabled && isUnderwater)
{
float finalDim = 1f;
if (Scatterer.Instance.mainSettings.underwaterLightDimming)
{
float underwaterDim = Mathf.Abs(Vector3.Distance (Scatterer.Instance.nearCamera.transform.position, prolandManager.parentLocalTransform.position)-(float)prolandManager.m_radius);
underwaterDim = Mathf.Lerp(1.0f,0.0f,underwaterDim / darknessDepth);
finalDim*=underwaterDim;
}
if (causticsShadowMaskModulator)
{
finalDim*=causticsUnderwaterLightBoost; //replace by caustics multiplier
}
Scatterer.Instance.sunlightModulatorsManagerInstance.ModulateByAttenuation(prolandManager.mainSunLight, finalDim);
}
}
public void saveToConfigNode ()
{
ConfigNode[] configNodeArray;
bool found = false;
configNodeArray = configUrl.config.GetNodes("Ocean");
foreach(ConfigNode _cn in configNodeArray)
{
if (_cn.HasValue("name") && _cn.GetValue("name") == prolandManager.parentCelestialBody.name)
{
ConfigNode cnTemp = ConfigNode.CreateConfigFromObject (this);
_cn.ClearData();
ConfigNode.Merge (_cn, cnTemp);
_cn.name="Ocean";
Utils.LogDebug("saving "+prolandManager.parentCelestialBody.name+
" ocean config to: "+configUrl.parent.url);
configUrl.parent.SaveConfigs ();
found=true;
break;
}
}
if (!found)
{
Utils.LogDebug("couldn't find config file to save to");
}
}
public void loadFromConfigNode ()
{
ConfigNode cnToLoad = new ConfigNode();
ConfigNode[] configNodeArray;
bool found = false;
foreach (UrlDir.UrlConfig _url in Scatterer.Instance.planetsConfigsReader.oceanConfigs)
{
configNodeArray = _url.config.GetNodes("Ocean");
foreach(ConfigNode _cn in configNodeArray)
{
if (_cn.HasValue("name") && _cn.GetValue("name") == prolandManager.parentCelestialBody.name)
{
cnToLoad = _cn;
configUrl = _url;
found = true;
break;
}
}
}
if (found)
{
Utils.LogDebug("Ocean config found for: "+prolandManager.parentCelestialBody.name);
ConfigNode.LoadObjectFromConfig (this, cnToLoad);
}
else
{
Utils.LogDebug("Ocean config not found for: "+prolandManager.parentCelestialBody.name);
Utils.LogDebug("Removing ocean for "+prolandManager.parentCelestialBody.name +" from planets list");
(Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.Find(_cb => _cb.celestialBodyName == prolandManager.parentCelestialBody.name)).hasOcean = false;
UnityEngine.Component.DestroyImmediate (this);
}
}
public void setWaterMeshrenderersEnabled (bool enabled)
{
for (int i=0; i < numGrids; i++)
{
waterMeshRenderers[i].enabled=enabled && oceanDraw;
}
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/OceanRenderingHook.cs
================================================
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
namespace Scatterer
{
public class OceanRenderingHook : MonoBehaviour
{
public bool isEnabled = false;
public OceanRenderingHook ()
{
}
public MeshRenderer targetRenderer;
public Material targetMaterial;
public string celestialBodyName;
//Dictionary to check if we added the OceanCommandBuffer to the camera
private Dictionary cameraToOceanCommandBuffer = new Dictionary();
void OnWillRenderObject()
{
Camera cam = Camera.current;
if (!cam || !targetRenderer || !targetMaterial)
return;
// Render ocean MeshRenderer for this frame
// If projector mode render directly to screen
// If depth buffer mode render to separate buffer so we can have the ocean's color and depth to be used by the scattering shader
if (cameraToOceanCommandBuffer.ContainsKey (cam))
{
if (cameraToOceanCommandBuffer[cam] != null)
{
cameraToOceanCommandBuffer[cam].EnableForThisFrame();
// Enable screen copying for this frame
if (Scatterer.Instance.mainSettings.oceanTransparencyAndRefractions && (cam == Scatterer.Instance.farCamera || cam == Scatterer.Instance.nearCamera))
ScreenCopyCommandBuffer.EnableScreenCopyForFrame(cam);
}
}
else
{
//we add null to the cameras we don't want to render on so we don't do a string compare every time
if ((cam.name == "TRReflectionCamera") || (cam.name=="Reflection Probes Camera") || (cam.name == "DepthCamera") || (cam.name == "NearCamera"))
{
cameraToOceanCommandBuffer[cam] = null;
}
else
{
OceanCommandBuffer oceanCommandBuffer = (OceanCommandBuffer) cam.gameObject.AddComponent(typeof(OceanCommandBuffer));
oceanCommandBuffer.targetRenderer = targetRenderer;
oceanCommandBuffer.targetMaterial = targetMaterial;
oceanCommandBuffer.celestialBodyName = celestialBodyName;
oceanCommandBuffer.Initialize();
oceanCommandBuffer.EnableForThisFrame();
cameraToOceanCommandBuffer[cam] = oceanCommandBuffer;
}
}
}
public void OnDestroy ()
{
foreach (OceanCommandBuffer oceanCommandBuffer in cameraToOceanCommandBuffer.Values)
{
if (oceanCommandBuffer)
Component.DestroyImmediate(oceanCommandBuffer);
}
}
}
public class OceanCommandBuffer : MonoBehaviour
{
bool renderingEnabled = false;
bool hdrEnabled = false;
public MeshRenderer targetRenderer;
public Material targetMaterial;
public string celestialBodyName;
private Camera targetCamera;
private CommandBuffer rendererCommandBuffer;
private int oceanRenderTextureNameID, depthCopyRenderTextureNameID;
private Material copyCameraDepthMaterial;
bool oceanScreenShotModeEnabled = false;
public void Initialize()
{
targetCamera = GetComponent();
copyCameraDepthMaterial = new Material(ShaderReplacer.Instance.LoadedShaders["Scatterer/CopyCameraDepth"]);
rendererCommandBuffer = new CommandBuffer();
rendererCommandBuffer.name = "Ocean MeshRenderer CommandBuffer";
oceanRenderTextureNameID = Shader.PropertyToID(nameof(oceanRenderTextureNameID));
depthCopyRenderTextureNameID = Shader.PropertyToID(nameof(depthCopyRenderTextureNameID));
RecreateCommandBuffer();
}
private void RecreateCommandBuffer()
{
rendererCommandBuffer.Clear();
// review: not sure if these automatically generate mips.
// might need to use the overload that takes RenderTextureDescriptor to disable them
rendererCommandBuffer.GetTemporaryRT(
depthCopyRenderTextureNameID,
-1, -1, // width, height: use camera dimensions
0, // depth buffer bits
FilterMode.Point,
RenderTextureFormat.RFloat);
rendererCommandBuffer.GetTemporaryRT(
oceanRenderTextureNameID,
-1, -1, // width, height: use camera dimensions
0, // depth buffer bits
FilterMode.Point,
hdrEnabled ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.ARGB32);
// Init depth render texture
rendererCommandBuffer.Blit(null, depthCopyRenderTextureNameID, copyCameraDepthMaterial, 3);
// Draw ocean renderer, output as normal to the screen, and ocean depth to the depth texture
RenderTargetIdentifier[] oceanRenderTargets = { new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget), new RenderTargetIdentifier(depthCopyRenderTextureNameID) };
rendererCommandBuffer.SetRenderTarget(oceanRenderTargets, BuiltinRenderTextureType.CameraTarget);
rendererCommandBuffer.DrawRenderer(targetRenderer, targetMaterial, 0, 0); //this doesn't work with pixel lights so render only the main pass here and render pixel lights the regular way
//they will render on top of depth buffer scattering but that's not a noticeable issue, especially since ocean lights are soft additive
// expose the new depth buffer
rendererCommandBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget);
rendererCommandBuffer.SetGlobalTexture("ScattererDepthCopy", depthCopyRenderTextureNameID);
// enable cloud shadows
rendererCommandBuffer.SetGlobalFloat(ShaderProperties.render_ocean_cloud_shadow_PROPERTY, 1f);
// draw cloud shadows
if (Scatterer.Instance.eveReflectionHandler.EVECloudLayers.ContainsKey(celestialBodyName))
{
foreach (var clouds2d in Scatterer.Instance.eveReflectionHandler.EVECloudLayers[celestialBodyName])
{
if (clouds2d.CloudShadowMaterial != null)
{
rendererCommandBuffer.Blit(null, BuiltinRenderTextureType.CameraTarget, clouds2d.CloudShadowMaterial);
}
}
}
// disable it for regular cloud shadows
rendererCommandBuffer.SetGlobalFloat(ShaderProperties.render_ocean_cloud_shadow_PROPERTY, 0f);
// recopy the screen and expose it as input for the scattering
rendererCommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, new RenderTargetIdentifier(oceanRenderTextureNameID));
// then set the textures for the scattering shader
rendererCommandBuffer.SetGlobalTexture("ScattererScreenCopy", oceanRenderTextureNameID);
}
public void EnableForThisFrame()
{
if (!renderingEnabled)
{
if (hdrEnabled != targetCamera.allowHDR)
{
RecreateCommandBuffer();
}
targetCamera.AddCommandBuffer(CameraEvent.AfterImageEffectsOpaque, rendererCommandBuffer); //ocean renders on AfterImageEffectsOpaque, local scattering (with it's depth downscale) can render and copy to screen on afterForwardAlpha
renderingEnabled = true;
}
}
void OnPostRender()
{
if (renderingEnabled && targetCamera.stereoActiveEye != Camera.MonoOrStereoscopicEye.Left)
{
targetCamera.RemoveCommandBuffer(CameraEvent.AfterImageEffectsOpaque, rendererCommandBuffer);
renderingEnabled = false;
}
}
public void OnDestroy ()
{
if (targetCamera && rendererCommandBuffer != null)
{
targetCamera.RemoveCommandBuffer (CameraEvent.AfterImageEffectsOpaque, rendererCommandBuffer);
rendererCommandBuffer.Release();
rendererCommandBuffer = null;
renderingEnabled = false;
}
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/OceanWhiteCaps.cs
================================================
using UnityEngine;
using System.Collections;
namespace Scatterer {
/*
* Extend the OceanFFT node to also generate ocean white caps.
*/
public class OceanWhiteCaps: OceanFFTgpu {
[Persistent]
protected string name;
Material m_initJacobiansMat;
Material m_whiteCapsPrecomputeMat;
RenderTexture[] m_fourierBuffer5, m_fourierBuffer6, m_fourierBuffer7;
int foamAniso = 9;
RenderTexture m_foam0, m_foam1;
public override void Init(ProlandManager manager)
{
base.Init(manager);
m_initJacobiansMat = new Material(ShaderReplacer.Instance.LoadedShaders[ ("Proland/Ocean/InitJacobians")]);
m_whiteCapsPrecomputeMat = new Material(ShaderReplacer.Instance.LoadedShaders[("Proland/Ocean/WhiteCapsPrecompute0")]);
m_initJacobiansMat.SetTexture(ShaderProperties._Spectrum01_PROPERTY, m_spectrum01);
m_initJacobiansMat.SetTexture(ShaderProperties._Spectrum23_PROPERTY, m_spectrum23);
m_initJacobiansMat.SetTexture(ShaderProperties._WTable_PROPERTY, m_WTable);
m_initJacobiansMat.SetVector (ShaderProperties._Offset_PROPERTY, m_spectrumOffset);
m_initJacobiansMat.SetVector (ShaderProperties._InverseGridSizes_PROPERTY, m_inverseGridSizes);
m_oceanMaterial.SetFloat (ShaderProperties._Ocean_WhiteCapStr_PROPERTY, m_whiteCapStr);
m_oceanMaterial.SetFloat (ShaderProperties.farWhiteCapStr_PROPERTY, m_farWhiteCapStr);
m_oceanMaterial.SetTexture(ShaderProperties._Ocean_Foam0_PROPERTY, m_foam0);
m_oceanMaterial.SetTexture(ShaderProperties._Ocean_Foam1_PROPERTY, m_foam1);
m_oceanMaterial.SetFloat (ShaderProperties.shoreFoam_PROPERTY, shoreFoam);
Utils.EnableOrDisableShaderKeywords (m_oceanMaterial, "FOAM_ON", "FOAM_OFF", true);
}
protected override void CreateRenderTextures()
{
RenderTextureFormat format = RenderTextureFormat.ARGBHalf;
CreateMap(ref m_foam0, format, foamAniso, true);
CreateMap(ref m_foam1, format, foamAniso, true);
m_foam1.mipMapBias = m_foamMipMapBias;
//These textures are used to perform the fourier transform
CreateBuffer(ref m_fourierBuffer5, format); // Jacobians XX
CreateBuffer(ref m_fourierBuffer6, format); // Jacobians YY
CreateBuffer(ref m_fourierBuffer7, format); // Jacobians XY
//Make sure the base textures are also created
base.CreateRenderTextures();
}
public override void OnDestroy()
{
base.OnDestroy();
m_foam0.Release();
m_foam1.Release();
for (int i = 0; i < 2; i++)
{
m_fourierBuffer5[i].Release();
m_fourierBuffer6[i].Release();
m_fourierBuffer7[i].Release();
}
}
protected override void InitWaveSpectrum(float t)
{
base.InitWaveSpectrum(t);
// Init jacobians (5,6,7)
RenderTexture[] buffers567 = new RenderTexture[]{m_fourierBuffer5[1], m_fourierBuffer6[1], m_fourierBuffer7[1]};
m_initJacobiansMat.SetFloat (ShaderProperties._T_PROPERTY, t);
RTUtility.MultiTargetBlit(buffers567, m_initJacobiansMat, 0);
}
public override void UpdateNode() {
base.UpdateNode();
if (!MapView.MapIsEnabled && prolandManager.skyNode.simulateOceanInteraction)
{
m_fourier.PeformFFT(m_fourierBuffer5, m_fourierBuffer6, m_fourierBuffer7);
//fixed block, two passes, fixes mipmapping issue resulting in black ocean
m_whiteCapsPrecomputeMat.SetTexture(ShaderProperties._Map5_PROPERTY, m_fourierBuffer5[m_idx]);
m_whiteCapsPrecomputeMat.SetTexture(ShaderProperties._Map6_PROPERTY, m_fourierBuffer6[m_idx]);
m_whiteCapsPrecomputeMat.SetTexture(ShaderProperties._Map7_PROPERTY, m_fourierBuffer7[m_idx]);
m_whiteCapsPrecomputeMat.SetVector (ShaderProperties._Choppyness_PROPERTY, m_choppyness);
//RenderTexture[] buffers = new RenderTexture[] {m_foam0, m_foam1};
//RTUtility.MultiTargetBlit(buffers, m_whiteCapsPrecomputeMat, 0); //causes mipmapping issue resulting in black ocean
Graphics.Blit (null, m_foam0, m_whiteCapsPrecomputeMat, 0);
Graphics.Blit (null, m_foam1, m_whiteCapsPrecomputeMat, 1);
}
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/UnderwaterDimmingHook.cs
================================================
using UnityEngine;
namespace Scatterer
{
public class UnderwaterDimmingHook : MonoBehaviour
{
public OceanNode oceanNode;
public void OnPostRender()
{
oceanNode.applyUnderwaterDimming ();
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/Utils/CBUtility.cs
================================================
using UnityEngine;
using UnityEngine.Rendering;
using System;
using System.IO;
namespace Scatterer
{
static public class CBUtility
{
public static ComputeBuffer CreateArgBuffer(int vertexCountPerInstance, int instanceCount, int startVertex, int startInstance)
{
ComputeBuffer buffer = new ComputeBuffer(4, sizeof(int), ComputeBufferType.IndirectArguments);
int[] args = new int[] { vertexCountPerInstance, instanceCount, startVertex, startInstance };
buffer.SetData(args);
return buffer;
}
public static int GetVertexCountPerInstance(ComputeBuffer buffer)
{
int[] args = new int[] { 0, 0, 0, 0 };
buffer.GetData(args);
return args[0];
}
private static string[,] readNames2D = new string[,]
{
{"read2DC1", "_Tex2D", "_Buffer2DC1"},
{"read2DC2", "_Tex2D", "_Buffer2DC2"},
{"read2DC3", "_Tex2D", "_Buffer2DC3"},
{"read2DC4", "_Tex2D", "_Buffer2DC4"}
};
private static string[,] readNames3D = new string[,]
{
{"read3DC1", "_Tex3D", "_Buffer3DC1"},
{"read3DC2", "_Tex3D", "_Buffer3DC2"},
{"read3DC3", "_Tex3D", "_Buffer3DC3"},
{"read3DC4", "_Tex3D", "_Buffer3DC4"}
};
public static void ReadFromRenderTexture(RenderTexture tex, int channels, ComputeBuffer buffer, ComputeShader readData)
{
if (tex == null)
throw new ArgumentException("RenderTexture is null");
if (buffer == null)
throw new ArgumentException("Buffer is null");
if (readData == null)
throw new ArgumentException("Computer shader is null");
if (channels < 1 || channels > 4)
throw new ArgumentException("Channels must be 1, 2, 3, or 4");
if (!tex.IsCreated())
throw new ArgumentException("Tex has not been created (Call Create() on tex)");
int kernel = -1;
int depth = 1;
if(tex.dimension == TextureDimension.Tex3D)
{
depth = tex.volumeDepth;
kernel = readData.FindKernel(readNames3D[channels - 1, 0]);
readData.SetTexture(kernel, readNames3D[channels - 1, 1], tex);
readData.SetBuffer(kernel, readNames3D[channels - 1, 2], buffer);
}
else
{
kernel = readData.FindKernel(readNames2D[channels - 1, 0]);
readData.SetTexture(kernel, readNames2D[channels - 1, 1], tex);
readData.SetBuffer(kernel, readNames2D[channels - 1, 2], buffer);
}
if (kernel == -1)
throw new ArgumentException("Could not find kernel " + readNames2D[channels - 1, 0]);
int width = tex.width;
int height = tex.height;
readData.SetInt("_Width", width);
readData.SetInt("_Height", height);
readData.SetInt("_Depth", depth);
//run the compute shader. Runs in threads of 8 so non divisable by 8 numbers will need
//some extra threadBlocks. This will result in some unneeded threads running
int padX = (width % 8 == 0) ? 0 : 1;
int padY = (height % 8 == 0) ? 0 : 1;
int padZ = (depth % 8 == 0) ? 0 : 1;
readData.Dispatch(kernel, Mathf.Max(1, width / 8 + padX), Mathf.Max(1, height / 8 + padY), Mathf.Max(1, depth / 8 + padZ));
}
public static void ReadSingleFromRenderTexture(RenderTexture tex, float x, float y, float z, ComputeBuffer buffer, ComputeShader readData, bool useBilinear)
{
if (tex == null)
throw new ArgumentException("RenderTexture is null");
if (buffer == null)
throw new ArgumentException("Buffer is null");
if (readData == null)
throw new ArgumentException("Computer shader is null");
if (!tex.IsCreated())
throw new ArgumentException("Tex has not been created (Call Create() on tex)");
int kernel = -1;
int depth = 1;
if (tex.dimension == TextureDimension.Tex3D)
{
if(useBilinear)
kernel = readData.FindKernel("readSingleBilinear3D");
else
kernel = readData.FindKernel("readSingle3D");
depth = tex.volumeDepth;
readData.SetTexture(kernel, "_Tex3D", tex);
readData.SetBuffer(kernel, "_BufferSingle3D", buffer);
}
else
{
if (useBilinear)
kernel = readData.FindKernel("readSingleBilinear2D");
else
kernel = readData.FindKernel("readSingle2D");
readData.SetTexture(kernel, "_Tex2D", tex);
readData.SetBuffer(kernel, "_BufferSingle2D", buffer);
}
if (kernel == -1)
throw new ArgumentException("Could not find kernel readSingle for " + tex.dimension);
int width = tex.width;
int height = tex.height;
//used for point sampling
readData.SetInt("_IdxX", (int)x);
readData.SetInt("_IdxY", (int)y);
readData.SetInt("_IdxZ", (int)z);
//used for bilinear sampling
readData.SetVector("_UV", new Vector4(x / (float)(width - 1), y / (float)(height - 1), z / (float)(depth - 1), 0.0f));
readData.Dispatch(kernel, 1, 1, 1);
}
public static void WriteIntoRenderTexture(RenderTexture tex, int channels, ComputeBuffer buffer, ComputeShader writeData)
{
if (tex == null)
throw new ArgumentException("RenderTexture is null");
if (buffer == null)
throw new ArgumentException("Buffer is null");
if (writeData == null)
throw new ArgumentException("Computer shader is null");
if (channels < 1 || channels > 4)
throw new ArgumentException("Channels must be 1, 2, 3, or 4");
if (!tex.enableRandomWrite)
throw new ArgumentException("You must enable random write on render texture");
if (!tex.IsCreated())
throw new ArgumentException("Tex has not been created (Call Create() on tex)");
int kernel = -1;
int depth = 1;
string D = "2D";
string C = "C" + channels.ToString();
if (tex.dimension == TextureDimension.Tex3D)
{
depth = tex.volumeDepth;
D = "3D";
}
kernel = writeData.FindKernel("write" + D + C);
if (kernel == -1)
throw new ArgumentException("Could not find kernel " + "write" + D + C);
int width = tex.width;
int height = tex.height;
//set the compute shader uniforms
writeData.SetTexture(kernel, "_Des" + D + C, tex);
writeData.SetInt("_Width", width);
writeData.SetInt("_Height", height);
writeData.SetInt("_Depth", depth);
writeData.SetBuffer(kernel, "_Buffer" + D + C, buffer);
//run the compute shader. Runs in threads of 8 so non divisable by 8 numbers will need
//some extra threadBlocks. This will result in some unneeded threads running
int padX = (width % 8 == 0) ? 0 : 1;
int padY = (height % 8 == 0) ? 0 : 1;
int padZ = (depth % 8 == 0) ? 0 : 1;
writeData.Dispatch(kernel, Mathf.Max(1, width / 8 + padX), Mathf.Max(1, height / 8 + padY), Mathf.Max(1, depth / 8 + padZ));
}
public static void WriteIntoRenderTexture(RenderTexture tex, int channels, string path, ComputeBuffer buffer, ComputeShader writeData)
{
if (tex == null)
throw new ArgumentException("RenderTexture is null");
if (buffer == null)
throw new ArgumentException("buffer is null");
if (writeData == null)
throw new ArgumentException("Computer shader is null");
if (channels < 1 || channels > 4)
throw new ArgumentException("Channels must be 1, 2, 3, or 4");
if (!tex.enableRandomWrite)
throw new ArgumentException("You must enable random write on render texture");
if (!tex.IsCreated())
throw new ArgumentException("Tex has not been created (Call Create() on tex)");
int kernel = -1;
int depth = 1;
string D = "2D";
string C = "C" + channels.ToString();
if (tex.dimension == TextureDimension.Tex3D)
{
depth = tex.volumeDepth;
D = "3D";
}
kernel = writeData.FindKernel("write" + D + C);
if (kernel == -1)
throw new ArgumentException("Could not find kernel " + "write" + D + C);
int width = tex.width;
int height = tex.height;
int size = width * height * depth * channels;
float[] map = new float[size];
LoadRawFile(path, map, size);
buffer.SetData(map);
//set the compute shader uniforms
writeData.SetTexture(kernel, "_Des" + D + C, tex);
writeData.SetInt("_Width", width);
writeData.SetInt("_Height", height);
writeData.SetInt("_Depth", depth);
writeData.SetBuffer(kernel, "_Buffer" + D + C, buffer);
//run the compute shader. Runs in threads of 8 so non divisable by 8 numbers will need
//some extra threadBlocks. This will result in some unneeded threads running
int padX = (width % 8 == 0) ? 0 : 1;
int padY = (height % 8 == 0) ? 0 : 1;
int padZ = (depth % 8 == 0) ? 0 : 1;
writeData.Dispatch(kernel, Mathf.Max(1, width / 8 + padX), Mathf.Max(1, height / 8 + padY), Mathf.Max(1, depth / 8 + padZ));
}
private static void LoadRawFile(string path, float[] map, int size)
{
FileInfo fi = new FileInfo(path);
if (fi == null)
throw new ArgumentException("Raw file not found (" + path + ")");
FileStream fs = fi.OpenRead();
byte[] data = new byte[fi.Length];
fs.Read(data, 0, (int)fi.Length);
fs.Close();
//divide by 4 as there are 4 bytes in a 32 bit float
if (size > fi.Length / 4)
throw new ArgumentException("Raw file is not the required size (" + path + ")");
for (int x = 0, i = 0; x < size; x++, i += 4)
{
//Convert 4 bytes to 1 32 bit float
map[x] = System.BitConverter.ToSingle(data, i);
};
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/Utils/FakeOceanPQS.cs
================================================
using System;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Scatterer
{
public class FakeOceanPQS : PQSMod
{
bool coroutineStarted = false;
Material originalOceanMaterial;
IEnumerator StopSphereCoroutine()
{
while (true)
{
for (int i=0; i<10; i++)
yield return new WaitForFixedUpdate ();
sphere.StopAllCoroutines ();
sphere.DeactivateSphere();
}
}
public override void OnSphereStarted()
{
if (!coroutineStarted)
{
StartCoroutine (StopSphereCoroutine ());
coroutineStarted = true;
}
}
public void Apply(PQS pqs)
{
if (pqs != null)
{
this.sphere = pqs;
this.transform.parent = pqs.transform;
this.requirements = PQS.ModiferRequirements.Default;
this.modEnabled = true;
this.order = 0;
originalOceanMaterial = pqs.surfaceMaterial;
Material invisibleOceanMaterial = new Material (ShaderReplacer.Instance.LoadedShaders[("Scatterer/invisible")]);
invisibleOceanMaterial.SetOverrideTag ("IgnoreProjector", "True");
invisibleOceanMaterial.SetOverrideTag ("ForceNoShadowCasting", "True");
pqs.surfaceMaterial = invisibleOceanMaterial;
sphere.StopAllCoroutines ();
sphere.DeactivateSphere();
}
}
public void Remove()
{
this.StopAllCoroutines ();
sphere.surfaceMaterial = originalOceanMaterial;
sphere.StartUpSphere ();
gameObject.DestroyGameObject ();
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/Utils/OceanUtils.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using KSP;
using KSP.IO;
using UnityEngine;
namespace Scatterer
{
public static class OceanUtils
{
public static bool oceanRemoved = false;
public static void removeStockOceansIfNotDone()
{
if (!oceanRemoved)
{
removeStockOceans();
oceanRemoved = true;
}
}
private static void removeStockOceans()
{
foreach (ScattererCelestialBody sctBody in Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies)
{
if (sctBody.hasOcean)
{
bool removed = false;
var celBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.bodyName == sctBody.celestialBodyName);
if (celBody == null) {
celBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.bodyName == sctBody.transformName);
}
if (celBody != null)
{
PQS pqs = celBody.pqsController;
if ((pqs != null) && (pqs.ChildSpheres != null) && (pqs.ChildSpheres.Count () != 0)) {
PQS ocean = pqs.ChildSpheres [0];
if (ocean != null)
{
GameObject go = new GameObject ("Scatterer stock ocean disabler "+sctBody.celestialBodyName);
FakeOceanPQS fakeOcean = go.AddComponent ();
fakeOcean.Apply (ocean);
removed = true;
}
}
}
if (!removed)
{
Utils.LogDebug ("Couldn't remove stock ocean for " + sctBody.celestialBodyName);
}
}
}
Utils.LogDebug ("Removed stock oceans");
}
//We can disable scatterer oceans and re-enable stock oceans without restarting the game
//but once started the stock ocean "pollutes" the scene with gameObjects that remain and lower performance so it isn't recommended but the option is there
public static void restoreOceansIfNeeded()
{
if (oceanRemoved)
{
FakeOceanPQS[] fakes = (FakeOceanPQS[])FakeOceanPQS.FindObjectsOfType (typeof(FakeOceanPQS));
foreach (FakeOceanPQS fake in fakes)
{
fake.Remove ();
Component.Destroy(fake);
}
oceanRemoved = false;
Utils.LogDebug ("Stock oceans restored");
}
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/Utils/RTUtility.cs
================================================
using UnityEngine;
using System.Collections;
namespace Scatterer
{
static public class RTUtility
{
static public void MultiTargetBlit(RenderTexture[] des, Material mat, int pass)
{
RenderBuffer[] rb = new RenderBuffer[des.Length];
for(int i = 0; i < des.Length; i++)
rb[i] = des[i].colorBuffer;
Graphics.SetRenderTarget(rb, des[0].depthBuffer);
GL.PushMatrix();
GL.LoadOrtho();
mat.SetPass(pass);
GL.Begin(GL.QUADS);
GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, 0.1f);
GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(1.0f, 0.0f, 0.1f);
GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 0.1f);
GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 1.0f, 0.1f);
GL.End();
GL.PopMatrix();
}
static public void MultiTargetBlit(RenderBuffer[] des_rb, RenderBuffer des_db, Material mat, int pass)
{
Graphics.SetRenderTarget(des_rb, des_db);
GL.PushMatrix();
GL.LoadOrtho();
mat.SetPass(pass);
GL.Begin(GL.QUADS);
GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, 0.1f);
GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(1.0f, 0.0f, 0.1f);
GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 0.1f);
GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 1.0f, 0.1f);
GL.End();
GL.PopMatrix();
}
static public void Swap(RenderTexture[] texs)
{
RenderTexture temp = texs[0];
texs[0] = texs[1];
texs[1] = temp;
}
static public void ClearColor(RenderTexture[] texs)
{
for(int i = 0; i < texs.Length; i++)
{
Graphics.SetRenderTarget(texs[i]);
GL.Clear(false,true, Color.clear);
}
}
}
}
================================================
FILE: scatterer/Effects/Proland/Ocean/Utils/WriteFloat.cs
================================================
using UnityEngine;
using System;
using System.Collections;
using System.IO;
namespace Scatterer
{
//This class is now obsolete and can be replaced with a single blit
///
/// This class is designed to take 32 bit floating point data and get it into a 2D render texture.
/// As there is no way in Unity to load floating point data straight into a render texture (with out dx11) the data for each
/// channel must be encoded into a ARGB32 format texture and then decoded via a shader into the render texture.
///
/// At the moment there are some conditions that must be meet for this to work
///
/// 1 - The data must be 32 bit floating point but the render texture format can be float or half.
///
/// 2 - The encode/decode step only works on data in the range 0 - 0.9999 but the function will find the highest number and normalize the
/// the data if its over 1 and then un-normalize it in the shader. This way you can have numbers greater than 1.
/// The function will also find the lowest number and if its below 0 it will add this value to all the data so the lowest number is 0.
/// This way you can have numbers lower than 0. This only works when copying data into a render texture.
/// When trying to get it out of a render texture you will need to make sure the data is in the range 0 - 0.9999
/// as there is not easy way to iterate over the texture and find the min and max values.
///
/// 3 - When trying encode/decode values it does not seem to work on values equal to 1 so Ive stated the max range as 0.9999.
///
/// 4 - Ive added the ability to load a raw file and copy the data into a render texture.
/// You can load 32 bit or 16 bit data. 16 bit data can be big endian or little endian
///
public class WriteFloat
{
const float MAX_VALUE = 0.999999f;
///
/// The material which will write the encoded
/// data into the render texture.
///
Material m_writeToFloat;
///
/// The textures to hold the encoded data.
/// To increase performance Ive made it so these
/// textures are created once and reused.
/// This does mean that the data must match the texture size.
/// You can call the resize function to recreate the
/// textures at a new size if needed.
///
Texture2D m_mapR, m_mapG, m_mapB, m_mapA;
///
/// The current size of the maps.
///
int m_width, m_height;
///
/// Create a new object that can write data into a render texture of dimensions w and h.
///
public WriteFloat(int w, int h)
{
Shader shader = ShaderReplacer.Instance.LoadedShaders[("EncodeFloat/WriteToFloat")];
if(shader == null)
{
throw new InvalidOperationException("Could not find shader EncodeFloat/WriteToFloat. Did you change the shaders name?");
}
m_writeToFloat = new Material(shader);
m_width = w;
m_height = h;
m_mapR = new Texture2D(w, h, TextureFormat.ARGB32, false, true);
m_mapR.filterMode = FilterMode.Point;
m_mapR.wrapMode = TextureWrapMode.Clamp;
m_mapG = new Texture2D(w, h, TextureFormat.ARGB32, false, true);
m_mapG.filterMode = FilterMode.Point;
m_mapG.wrapMode = TextureWrapMode.Clamp;
m_mapB = new Texture2D(w, h, TextureFormat.ARGB32, false, true);
m_mapB.filterMode = FilterMode.Point;
m_mapB.wrapMode = TextureWrapMode.Clamp;
m_mapA = new Texture2D(w, h, TextureFormat.ARGB32, false, true);
m_mapA.filterMode = FilterMode.Point;
m_mapA.wrapMode = TextureWrapMode.Clamp;
}
///
/// Resize to new dimensions.
///
public void Resize(int w, int h)
{
m_width = w;
m_height = h;
m_mapR.Resize(w, h, TextureFormat.ARGB32, false);
m_mapG.Resize(w, h, TextureFormat.ARGB32, false);
m_mapB.Resize(w, h, TextureFormat.ARGB32, false);
m_mapA.Resize(w, h, TextureFormat.ARGB32, false);
}
///
/// This will write the values in data array into tex
///
/// The texture to write into
/// The number of channels in texture
/// The data to write into texture. Size must width * height * channels.
public void WriteIntoRenderTexture(RenderTexture tex, int channels, float[] data)
{
if(channels < 1 || channels > 4)
{
Utils.LogDebug("Channels must be 1, 2, 3, or 4");
return;
}
int w = tex.width;
int h = tex.height;
if(w != m_width || h != m_height)
{
Utils.LogDebug("Render texture not the correct dimensions");
return;
}
int size = w*h*channels;
Color[] map = new Color[size];
float max = 1.0f;
float min = 0.0f;
LoadData(data, map, size, ref min, ref max);
Write(w, h, channels, min, max, tex, map);
}
///
/// Load 32 bit float data from raw file and write into render texture
/// width the option of writting the loaded data into the fdata array if it is not null.
///
/// The texture to write into
/// The number of channels in texture
/// The data to write into texture. Size must width * height * channels.
/// If this is not the data in the file will be written into this.
// public void WriteIntoRenderTexture(RenderTexture tex, int channels, string path, float[] fdata = null)
public void WriteIntoRenderTexture(RenderTexture tex, int channels, string path, float[] fdata)
{
if(channels < 1 || channels > 4)
{
Utils.LogDebug("EncodeFloat::WriteIntoRenderTexture - Channels must be 1, 2, 3, or 4");
return;
}
int w = tex.width;
int h = tex.height;
if(w != m_width || h != m_height)
{
Utils.LogDebug("Render texture not the correct dimensions");
return;
}
int size = w*h*channels;
Color[] map = new Color[size];
if(fdata == null) fdata = new float[size];
float max = 1.0f;
float min = 0.0f;
if(!LoadRawFile(path, map, size, ref min, ref max, fdata))
{
Utils.LogDebug("EncodeFloat::WriteIntoRenderTexture - Error loading raw file " + path);
return;
}
Write(w, h, channels, min, max, tex, map);
}
///
/// Load 16 bit float data from raw file and write into render texture
/// width the option of writting the loaded data in to the fdata array if it is not null.
///
/// The texture to write into
/// The number of channels in texture
/// The data to write into texture. Size must width * height * channels.
/// If this is not the data in the file will be written into this.
// public void WriteIntoRenderTexture16bit(RenderTexture tex, int channels, string path, bool bigEndian, float[] fdata = null)
public void WriteIntoRenderTexture16bit(RenderTexture tex, int channels, string path, bool bigEndian, float[] fdata)
{
if(channels < 1 || channels > 4)
{
Utils.LogDebug("Channels must be 1, 2, 3, or 4");
return;
}
int w = tex.width;
int h = tex.height;
if(w != m_width || h != m_height)
{
Utils.LogDebug("Render texture not the correct dimensions");
return;
}
int size = w*h*channels;
Color[] map = new Color[size];
if(fdata == null) fdata = new float[size];
float max = 1.0f;
float min = 0.0f;
if(!LoadRawFile16(path, map, size, ref min, ref max, fdata, bigEndian))
{
Utils.LogDebug("EncodeFloat::WriteIntoRenderTexture16bit - Error loading raw file " + path);
return;
}
Write(w, h, channels, min, max, tex, map);
}
///
/// Write the encoded float in map into texture.
///
void Write(int w, int h, int c, float min, float max, RenderTexture tex, Color[] map)
{
for(int x = 0; x < w; x++)
{
for(int y = 0; y < h; y++)
{
if(c > 0)
m_mapR.SetPixel(x, y, map[(x+y*w)*c+0]);
else
m_mapR.SetPixel(x, y, Color.clear);
if(c > 1)
m_mapG.SetPixel(x, y, map[(x+y*w)*c+1]);
else
m_mapG.SetPixel(x, y, Color.clear);
if(c > 2)
m_mapB.SetPixel(x, y, map[(x+y*w)*c+2]);
else
m_mapB.SetPixel(x, y, Color.clear);
if(c > 3)
m_mapA.SetPixel(x, y, map[(x+y*w)*c+3]);
else
m_mapA.SetPixel(x, y, Color.clear);
}
}
m_mapR.Apply();
m_mapG.Apply();
m_mapB.Apply();
m_mapA.Apply();
m_writeToFloat.SetFloat("_Max", max);
m_writeToFloat.SetFloat("_Min", min);
m_writeToFloat.SetTexture("_TexR", m_mapR);
m_writeToFloat.SetTexture("_TexG", m_mapG);
m_writeToFloat.SetTexture("_TexB", m_mapB);
m_writeToFloat.SetTexture("_TexA", m_mapA);
Graphics.Blit(null, tex, m_writeToFloat);
}
///
/// Encode a float into 4 bytes as normilized floats.
///
float[] EncodeFloatRGBA(float val)
{
float[] kEncodeMul = new float[]{ 1.0f, 255.0f, 65025.0f, 160581375.0f };
float kEncodeBit = 1.0f / 255.0f;
for( int i = 0; i < kEncodeMul.Length; ++i )
{
kEncodeMul[i] *= val;
// Frac
kEncodeMul[i] = ( float )( kEncodeMul[i] - System.Math.Truncate( kEncodeMul[i] ) );
}
// enc -= enc.yzww * kEncodeBit;
float[] yzww = new float[] { kEncodeMul[1], kEncodeMul[2], kEncodeMul[3], kEncodeMul[3] };
for( int i = 0; i < kEncodeMul.Length; ++i )
{
kEncodeMul[i] -= yzww[i] * kEncodeBit;
}
return kEncodeMul;
}
///
/// Find the range of the data and then pak it into the map.
///
void LoadData(float[] data, Color[] map, int size, ref float min, ref float max)
{
for(int x = 0 ; x < size; x++)
{
//Find the min and max range of data
if(data[x] > max) max = data[x];
if(data[x] < min) min = data[x];
};
min = Mathf.Abs(min);
max += min;
PackData(map, size, min, max, data);
}
///
/// Load the data from a 32 bit file, find the range of the data and then pak it into the map.
///
bool LoadRawFile(string path, Color[] map, int size, ref float min, ref float max, float[] fdata)
{
FileInfo fi = new FileInfo(path);
if(fi == null)
{
Utils.LogDebug("Raw file not found");
return false;
}
FileStream fs = fi.OpenRead();
byte[] data = new byte[fi.Length];
fs.Read(data, 0, (int)fi.Length);
fs.Close();
//divide by 4 as there are 4 bytes in a 32 bit float
if(size > fi.Length/4)
{
Utils.LogDebug("Raw file is not the required size");
return false;
}
int i = 0;
for(int x = 0 ; x < size; x++)
{
//Convert 4 bytes to 1 32 bit float
fdata[x] = System.BitConverter.ToSingle(data, i);
//Find the min and max range of data
if(fdata[x] > max) max = fdata[x];
if(fdata[x] < min) min = fdata[x];
i += 4; // theres 4 bytes in 32 bits so increment i by 4
};
min = Mathf.Abs(min);
max += min;
PackData(map, size, min, max, fdata);
return true;
}
///
/// Load the data from a 16 bit file, find the range of the data and then pak it into the map.
///
bool LoadRawFile16(string path, Color[] map, int size, ref float min, ref float max, float[] fdata, bool bigendian)
{
FileInfo fi = new FileInfo(path);
if(fi == null)
{
Utils.LogDebug("Raw file not found");
return false;
}
FileStream fs = fi.OpenRead();
byte[] data = new byte[fi.Length];
fs.Read(data, 0, (int)fi.Length);
fs.Close();
//divide by 2 as there are 2 bytes in a 16 bit float
if(size > fi.Length/2)
{
Utils.LogDebug("Raw file is not the required size");
return false;
}
int i = 0;
for(int x = 0 ; x < size; x++)
{
//Extract 16 bit data and normalize.
fdata[x] = (bigendian) ? (data[i++]*256.0f + data[i++]) : (data[i++] + data[i++]*256.0f);
fdata[x] /= 65535.0f;
//Find the min and max range of data
if(fdata[x] > max) max = fdata[x];
if(fdata[x] < min) min = fdata[x];
};
min = Mathf.Abs(min);
max += min;
PackData(map, size, min, max, fdata);
return true;
}
///
/// Encode data into the map.
///
void PackData(Color[] map, int size, float min, float max, float[] data)
{
for(int x = 0 ; x < size; x++)
{
float normalizedData = (data[x] + min) / max;
//does not work on value of one
if(normalizedData >= 1.0f) normalizedData = MAX_VALUE;
float[] farray = EncodeFloatRGBA(normalizedData);
map[x] = new Color(farray[0], farray[1], farray[2], farray[3]);
};
}
public void OnDestroy ()
{
UnityEngine.Object.Destroy(m_mapA);
UnityEngine.Object.Destroy(m_mapR);
UnityEngine.Object.Destroy(m_mapG);
UnityEngine.Object.Destroy(m_mapB);
UnityEngine.Object.Destroy (m_writeToFloat);
}
}
}
================================================
FILE: scatterer/Effects/Proland/ProlandManager.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using KSP;
using KSP.IO;
using UnityEngine;
namespace Scatterer
{
/*
* A manager to organise what order update functions are called
* Manages all effects taken from Proland (ie Precomputed Scattering and Ocean, maybe one day forests...)
* The class structures from original Proland are kept, with some added Utilities related to scatterer and KSP
* Provides a location for common settings and allows the nodes to access each other
*/
public class ProlandManager: MonoBehaviour
{
public bool hasOcean = false;
public bool usesCloudIntegration = true;
public bool cloudIntegrationUsesScattererSunColors = false;
public bool flatScaledSpaceModel = false;
public double m_radius = 600000.0;
public float mainMenuScaleFactor = 1f;
OceanFFTgpu oceanNode;
public SkyNode skyNode;
public Color sunColor;
public CelestialBody parentCelestialBody;
public Transform parentScaledTransform;
public Transform parentLocalTransform;
public bool sunsUseIntensityCurves;
public CelestialBody sunCelestialBody;
public List eclipseCasters=new List {};
public List planetshineSources=new List {};
public List secondarySuns=new List {};
public Light mainSunLight, mainScaledSunLight;
public ScattererCelestialBody scattererCelestialBody;
public Matrix4x4 planetShineSourcesMatrix=Matrix4x4.zero;
public Matrix4x4 planetShineRGBMatrix=Matrix4x4.zero; //Contains the colors set in the scatterer config
public Matrix4x4 planetShineOriginalRGBMatrix=Matrix4x4.zero; //Contains the original colors of the directional lights, if available
public void Init(ScattererCelestialBody scattererBody)
{
scattererCelestialBody = scattererBody;
parentCelestialBody = scattererBody.celestialBody;
sunColor=scattererBody.sunColor;
flatScaledSpaceModel = scattererBody.flatScaledSpaceModel;
usesCloudIntegration = scattererBody.usesCloudIntegration;
cloudIntegrationUsesScattererSunColors = scattererBody.cloudIntegrationUsesScattererSunColors;
hasOcean = scattererBody.hasOcean;
sunsUseIntensityCurves = scattererBody.sunsUseIntensityCurves;
sunCelestialBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.GetName () == scattererBody.mainSunCelestialBody);
mainSunLight = findLight (scattererBody.mainSunCelestialBody);
mainScaledSunLight = findScaledLight (scattererBody.mainSunCelestialBody);
if (!mainSunLight)
{
Utils.LogError ("No light found for " + scattererBody.mainSunCelestialBody + " for body " + parentCelestialBody.name + ". Defaulting to main sunlight, godrays, lightrays and caustics may look wrong, check your Kopernicus configuration.");
mainSunLight = Scatterer.Instance.sunLight;
}
else
{
if (Scatterer.Instance.mainSettings.terrainShadows)
Scatterer.Instance.SetShadowsForLight (mainSunLight);
else
Scatterer.Instance.DisableCustomShadowResForLight (mainSunLight);
}
if (HighLogic.LoadedScene == GameScenes.MAINMENU)
{
parentScaledTransform = Utils.GetMainMenuObject(scattererBody.celestialBody).transform;
parentLocalTransform = Utils.GetMainMenuObject(scattererBody.celestialBody).transform;
}
else
{
parentScaledTransform = scattererBody.transform;
parentLocalTransform = scattererBody.celestialBody.transform;
}
FindEclipseCasters (scattererBody);
FindPlanetShineSources (scattererBody);
if (HighLogic.LoadedScene == GameScenes.MAINMENU)
{
GameObject _go = Utils.GetMainMenuObject(scattererBody.celestialBody);
if (_go)
{
MeshRenderer _mr = _go.GetComponent ();
if (_mr)
{
var sctBodyTransform = ScaledSpace.Instance.transform.FindChild (parentCelestialBody.name);
mainMenuScaleFactor = (_go.transform.localScale.x / sctBodyTransform.localScale.x);
m_radius = mainMenuScaleFactor * parentCelestialBody.Radius;
}
}
}
else
{
m_radius = parentCelestialBody.Radius;
}
InitSecondarySuns ();
InitSkyAndOceanNodes ();
}
//TODO: move to utils
Light findLight (string sunCelestialBody)
{
Light light = Scatterer.Instance.lights.SingleOrDefault (_light => (_light != null) && (_light.gameObject != null) && (_light.gameObject.name == sunCelestialBody));
if (!light && (sunCelestialBody == "Sun"))
light = Scatterer.Instance.sunLight;
return light;
}
Light findScaledLight (string sunCelestialBody)
{
Light light = Scatterer.Instance.lights.SingleOrDefault (_light => (_light != null) && (_light.gameObject != null) && (_light.gameObject.name == ("Scaledspace SunLight "+sunCelestialBody)));
if (!light && (sunCelestialBody == "Sun"))
light = Scatterer.Instance.scaledSpaceSunLight;
return light;
}
void FindEclipseCasters (ScattererCelestialBody scattererBody)
{
if (Scatterer.Instance.mainSettings.useEclipses) {
for (int k = 0; k < scattererBody.eclipseCasters.Count; k++) {
var cc = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.GetName () == scattererBody.eclipseCasters [k]);
if (cc == null)
Utils.LogDebug ("Eclipse caster " + scattererBody.eclipseCasters [k] + " not found for " + scattererBody.celestialBodyName);
else {
eclipseCasters.Add (cc);
Utils.LogDebug ("Added eclipse caster " + scattererBody.eclipseCasters [k] + " for " + scattererBody.celestialBodyName);
}
}
}
}
void FindPlanetShineSources (ScattererCelestialBody scattererBody)
{
if (Scatterer.Instance.mainSettings.usePlanetShine) {
for (int k = 0; k < scattererBody.planetshineSources.Count; k++)
{
var cc = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.GetName () == scattererBody.planetshineSources [k].bodyName);
if (cc == null)
Utils.LogDebug ("planetshine source " + scattererBody.planetshineSources [k].bodyName + " not found for " + scattererBody.celestialBodyName);
else {
AtmoPlanetShineSource src = scattererBody.planetshineSources [k];
src.body = cc;
scattererBody.planetshineSources [k].body = cc;
planetshineSources.Add (src);
Utils.LogDebug ("Added planetshine source" + scattererBody.planetshineSources [k].bodyName + " for " + scattererBody.celestialBodyName);
}
}
}
}
void InitSkyAndOceanNodes ()
{
skyNode = (SkyNode)Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent (typeof(SkyNode));
skyNode.prolandManager = this;
skyNode.SetCelestialBodyName (parentCelestialBody.name);
skyNode.SetParentScaledTransform (parentScaledTransform);
skyNode.SetParentLocalTransform (parentLocalTransform);
skyNode.usesCloudIntegration = usesCloudIntegration;
skyNode.mainMenuScaleFactor = mainMenuScaleFactor;
if (skyNode.LoadFromConfigNode ())
{
skyNode.Init ();
if (hasOcean && Scatterer.Instance.mainSettings.useOceanShaders && (HighLogic.LoadedScene != GameScenes.MAINMENU))
{
if (Scatterer.Instance.mainSettings.oceanFoam)
oceanNode = (OceanFFTgpu) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent(typeof(OceanWhiteCaps));
else
oceanNode = (OceanFFTgpu) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent(typeof(OceanFFTgpu));
oceanNode.Init (this);
}
}
}
public void Update()
{
if (secondarySuns.Count > 0)
{
UpdateSecondarySuns();
}
skyNode.UpdateNode();
if (oceanNode)
{
oceanNode.UpdateNode();
}
}
void FindSecondarySuns (ScattererCelestialBody scattererBody)
{
foreach (SecondarySunConfig sunConfig in scattererBody.secondarySuns)
{
SecondarySun secondarySun = SecondarySun.FindSecondarySun (sunConfig);
if (secondarySun != null)
{
secondarySun.sunLight = findLight (sunConfig.celestialBodyName);
secondarySun.scaledSunLight = findScaledLight (sunConfig.celestialBodyName);
secondarySuns.Add (secondarySun);
}
}
}
void InitSecondarySuns ()
{
FindSecondarySuns (scattererCelestialBody);
planetShineRGBMatrix = Matrix4x4.zero;
for (int i = 0; i < Math.Min (4, secondarySuns.Count); i++)
{
planetShineRGBMatrix.SetRow (i, new Vector4 (secondarySuns[i].config.sunColor.r, secondarySuns[i].config.sunColor.g, secondarySuns[i].config.sunColor.b, 1.0f));
if (secondarySuns[i].scaledSunLight != null)
planetShineOriginalRGBMatrix.SetRow (i, new Vector4 (secondarySuns[i].scaledSunLight.color.r, secondarySuns[i].scaledSunLight.color.g, secondarySuns[i].scaledSunLight.color.b, 1.0f));
else
planetShineOriginalRGBMatrix.SetRow(i, planetShineRGBMatrix.GetRow(i));
}
}
void UpdateSecondarySuns ()
{
planetShineSourcesMatrix = Matrix4x4.zero;
for (int i = 0; i < Math.Min (4, secondarySuns.Count); i++)
{
Vector3 sourcePosRelPlanet = Vector3.Scale (secondarySuns[i].celestialBody.position - parentCelestialBody.GetTransform ().position, new Vector3d (ScaledSpace.ScaleFactor, ScaledSpace.ScaleFactor, ScaledSpace.ScaleFactor)); //has to be this that is borked
planetShineSourcesMatrix.SetRow (i, new Vector4 (sourcePosRelPlanet.x, sourcePosRelPlanet.y, sourcePosRelPlanet.z, 1.0f));
if (secondarySuns[i].scaledSunLight != null)
{
if (sunsUseIntensityCurves)
{
planetShineRGBMatrix[i,3] = secondarySuns[i].scaledSunLight.intensity;
}
if (!cloudIntegrationUsesScattererSunColors)
{
planetShineOriginalRGBMatrix.SetRow (i, new Vector4 (secondarySuns[i].scaledSunLight.color.r, secondarySuns[i].scaledSunLight.color.g, secondarySuns[i].scaledSunLight.color.b, secondarySuns[i].scaledSunLight.intensity));
}
}
}
}
public void OnDestroy()
{
if (skyNode)
{
skyNode.OnDestroy(); // no idea why this doesn't fire by itself sometimes
Component.Destroy(skyNode);
}
if (oceanNode)
{
oceanNode.OnDestroy();
Component.Destroy(oceanNode);
}
}
//TODO: change this so that it takes the new configNode and that's all? May not be possible depending on if it needs to recreate lightraysRenderer and stuff
//Therefor add an option to init from configNode? yep
public void reBuildOcean()
{
if (oceanNode)
{
Component.DestroyImmediate(oceanNode);
if (Scatterer.Instance.mainSettings.oceanFoam)
oceanNode = (OceanFFTgpu) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent(typeof(OceanWhiteCaps));
else
oceanNode = (OceanFFTgpu) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent(typeof(OceanFFTgpu));
oceanNode.Init(this);
Utils.LogDebug("Rebuilt Ocean");
}
if (skyNode)
skyNode.InitOceanMaterialUniforms();
}
public Vector3 getDirectionToMainSun()
{
if (HighLogic.LoadedScene == GameScenes.MAINMENU)
{
return (Scatterer.Instance.mainMenuLight.gameObject.transform.forward*(-1));
}
else
return (sunCelestialBody.GetTransform().position - parentCelestialBody.GetTransform().position).normalized;
}
public Vector3 getDirectionToCelestialBody(CelestialBody target)
{
return (target.GetTransform().position - parentCelestialBody.GetTransform().position);
}
public double GetRadius() {
return m_radius;
}
public OceanFFTgpu GetOceanNode() {
return oceanNode;
}
public SkyNode GetSkyNode() {
return skyNode;
}
public Color getIntensityModulatedSunColor()
{
return (sunsUseIntensityCurves ? sunColor * mainScaledSunLight.intensity : sunColor);
}
}
}
================================================
FILE: scatterer/Effects/ScattererCelestialBodiesManager.cs
================================================
// Manages loading,unloading and updating for all the Scatterer-enabled celestial bodies
// Will spawn/delete/update a ProlandManager for each body if within range
using System;
using System.Linq;
using UnityEngine;
namespace Scatterer
{
public class ScattererCelestialBodiesManager
{
public bool underwater = false;
bool pqsEnabledOnScattererPlanet = false;
public bool isPQSEnabledOnScattererPlanet{get{return pqsEnabledOnScattererPlanet;}}
bool customOceanEnabledOnScattererPlanet = false;
public bool isCustomOceanEnabledOnScattererPlanet{get{return customOceanEnabledOnScattererPlanet;}}
public ScattererCelestialBodiesManager ()
{
}
public void Init()
{
findCelestialBodies ();
}
public void Update()
{
UpdateProlandManagers ();
}
void UpdateProlandManagers ()
{
pqsEnabledOnScattererPlanet = false;
underwater = false;
customOceanEnabledOnScattererPlanet = false;
foreach (ScattererCelestialBody scattererCelestialBody in Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies)
{
float minDistance; //smallest distance to either the camera or ship
if (scattererCelestialBody.isFound)
{
minDistance = Vector3.Distance (Scatterer.Instance.scaledSpaceCamera.transform.position, scattererCelestialBody.transform.position) * ScaledSpace.ScaleFactor;
minDistance = FlightGlobals.ActiveVessel ? Mathf.Min(minDistance, Vector3.Distance (FlightGlobals.ActiveVessel.transform.position, ScaledSpace.ScaledToLocalSpace (scattererCelestialBody.transform.position))) : minDistance;
if (scattererCelestialBody.active)
{
if (minDistance > scattererCelestialBody.unloadDistance)
{
unloadEffectsForBody(scattererCelestialBody);
break;
}
else
{
updateBody (scattererCelestialBody, ref pqsEnabledOnScattererPlanet, ref underwater, ref customOceanEnabledOnScattererPlanet);
}
}
else
{
if (minDistance < scattererCelestialBody.loadDistance && scattererCelestialBody.transform && scattererCelestialBody.celestialBody)
{
loadEffectsForBody (scattererCelestialBody);
break;
}
}
}
}
}
void findCelestialBodies()
{
foreach (ScattererCelestialBody sctBody in Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies)
{
Utils.LogDebug("Finding ScattererCelestialBody name: "+sctBody.celestialBodyName+". TransformName: "+sctBody.transformName);
var celBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.bodyName == sctBody.celestialBodyName);
if (celBody == null)
{
Utils.LogDebug("ScattererCelestialBody not found by name, trying transformName");
celBody = FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.bodyName == sctBody.transformName);
}
if (celBody == null)
{
Utils.LogError("ScattererCelestialBody "+sctBody.celestialBodyName+" not found by name, or transformName. Effects for this body won't be available.");
continue;
}
else
{
Utils.LogDebug ("Found ScattererCelestialBody: " + sctBody.celestialBodyName + ", actual ingame name: " + celBody.GetName ());
}
sctBody.celestialBody = celBody;
var sctBodyTransform = ScaledSpace.Instance.transform.FindChild (sctBody.transformName);
if (!sctBodyTransform)
{
sctBodyTransform = ScaledSpace.Instance.transform.FindChild (sctBody.celestialBodyName);
}
else
{
sctBody.transform = sctBodyTransform;
sctBody.isFound = true;
}
sctBody.active = false;
}
}
void loadEffectsForBody (ScattererCelestialBody scattererCelestialBody)
{
try
{
if (HighLogic.LoadedScene == GameScenes.TRACKSTATION || HighLogic.LoadedScene == GameScenes.MAINMENU)
scattererCelestialBody.hasOcean = false;
scattererCelestialBody.prolandManager = new ProlandManager ();
scattererCelestialBody.prolandManager.Init (scattererCelestialBody);
scattererCelestialBody.active = true;
if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.Contains (scattererCelestialBody))
{
Scatterer.Instance.guiHandler.LoadPlanet(Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.IndexOf (scattererCelestialBody));
}
else
{
throw new Exception ("Planet already removed from planets list");
}
Utils.LogDebug ("Effects loaded for " + scattererCelestialBody.celestialBodyName);
}
catch (Exception exception)
{
if (HighLogic.LoadedScene != GameScenes.MAINMENU || !exception.Message.Contains("No correct main menu object found for "))
Utils.LogError ("Effects couldn't be loaded for " + scattererCelestialBody.celestialBodyName + ", " + exception.ToString ());
try {
scattererCelestialBody.prolandManager.OnDestroy ();
}
catch (Exception exception2) {
Utils.LogDebug ("manager couldn't be removed for " + scattererCelestialBody.celestialBodyName + " because of exception: " + exception2.ToString ());
}
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.Remove (scattererCelestialBody);
if (HighLogic.LoadedScene != GameScenes.MAINMENU)
{
Utils.LogDebug ("" + scattererCelestialBody.celestialBodyName + " removed from active planets.");
}
return;
}
}
ScattererCelestialBody updateBody (ScattererCelestialBody scattererCelestialBody, ref bool inPqsEnabledOnScattererPlanet, ref bool inUnderwater, ref bool inCustomOceanEnabledOnScattererPlanet)
{
scattererCelestialBody.prolandManager.Update ();
inPqsEnabledOnScattererPlanet = inPqsEnabledOnScattererPlanet || !scattererCelestialBody.prolandManager.skyNode.inScaledSpace;
if (inPqsEnabledOnScattererPlanet && scattererCelestialBody.prolandManager.GetOceanNode()) {
inCustomOceanEnabledOnScattererPlanet = true;
inUnderwater = scattererCelestialBody.prolandManager.GetOceanNode ().isUnderwater;
}
return scattererCelestialBody;
}
void unloadEffectsForBody(ScattererCelestialBody scattererCelestialBody)
{
scattererCelestialBody.prolandManager.OnDestroy ();
UnityEngine.Object.DestroyImmediate (scattererCelestialBody.prolandManager);
scattererCelestialBody.prolandManager = null;
scattererCelestialBody.active = false;
Utils.LogDebug ("Effects unloaded for " + scattererCelestialBody.celestialBodyName);
}
public void Cleanup()
{
foreach (ScattererCelestialBody scattererCelestialBody in Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies)
{
if (scattererCelestialBody.active)
{
scattererCelestialBody.prolandManager.OnDestroy ();
UnityEngine.Object.DestroyImmediate (scattererCelestialBody.prolandManager);
scattererCelestialBody.prolandManager = null;
scattererCelestialBody.active = false;
Utils.LogDebug ("Effects unloaded for " + scattererCelestialBody.celestialBodyName);
}
}
}
}
}
================================================
FILE: scatterer/Effects/SunFlare/SunFlare.cs
================================================
//rendering steps
//scaledSpaceCamera.OnPrecull -> skynodes update the extinction texture one after one
//camerahook on the relevant scaledSpace or farCamera -> clear the extinction texture before the next frame
//while taking care of keeping it around until the rendering has finished (either nearCamera or scaledCamera)
using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using KSP.IO;
namespace Scatterer
{
public class SunFlare : MonoBehaviour
{
public ConfigNode configNodeToLoad;
public Material sunglareMaterial;
public CelestialBody source;
public string sourceName;
public Transform sourceScaledTransform;
static Dictionary texturesDictionary = new Dictionary ();
public RenderTexture extinctionTexture;
int waitBeforeReloadCnt = 0;
SunflareCameraHook nearCameraHook, scaledCameraHook;
RaycastHit hit;
bool hitStatus=false;
bool flareRendering=false;
public bool FlareRendering {
get {
return flareRendering;
}
}
float sunGlareScale=1;
float sunGlareFade=1;
float ghostFade=1;
Mesh screenMesh;
GameObject sunflareGameObject;
public int syntaxVersion = 1;
SunflareSettingsV1 settingsV1;
SunflareSettingsV2 settingsV2;
public void start()
{
LoadSettings ();
sunglareMaterial = new Material (ShaderReplacer.Instance.LoadedShaders["Scatterer/sunFlare"]);
sunglareMaterial.SetOverrideTag ("IGNOREPROJECTOR", "True");
sunglareMaterial.SetOverrideTag ("IgnoreProjector", "True");
Utils.EnableOrDisableShaderKeywords (sunglareMaterial, "SCATTERER_MERGED_DEPTH_ON", "SCATTERER_MERGED_DEPTH_OFF", !Scatterer.Instance.unifiedCameraMode);
if (!Scatterer.Instance.unifiedCameraMode)
{
if (HighLogic.LoadedScene != GameScenes.TRACKSTATION && DepthToDistanceCommandBuffer.RenderTexture != null)
{
sunglareMaterial.SetTexture ("_customDepthTexture", DepthToDistanceCommandBuffer.RenderTexture);
}
else
sunglareMaterial.SetTexture ("_customDepthTexture", Texture2D.whiteTexture); //keep this in mind for when doing multiple points check and ditching raycast
}
sunglareMaterial.renderQueue = 3100;
screenMesh = MeshFactory.MakePlane (2, 2, MeshFactory.PLANE.XY, false, false);
screenMesh.bounds = new Bounds (Vector4.zero, new Vector3 (Mathf.Infinity, Mathf.Infinity, Mathf.Infinity));
sunflareGameObject = new GameObject ();
MeshFilter sunflareGameObjectMeshFilter;
if (sunflareGameObject.GetComponent ())
sunflareGameObjectMeshFilter = sunflareGameObject.GetComponent ();
else
sunflareGameObjectMeshFilter = sunflareGameObject.AddComponent();
sunflareGameObjectMeshFilter.mesh.Clear ();
sunflareGameObjectMeshFilter.mesh = screenMesh;
MeshRenderer sunflareGameObjectMeshRenderer;
if (sunflareGameObject.GetComponent ())
sunflareGameObjectMeshRenderer = sunflareGameObject.GetComponent ();
else
sunflareGameObjectMeshRenderer = sunflareGameObject.AddComponent();
sunflareGameObjectMeshRenderer.sharedMaterial = sunglareMaterial;
sunflareGameObjectMeshRenderer.material = sunglareMaterial;
sunflareGameObjectMeshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
sunflareGameObjectMeshRenderer.receiveShadows = false;
sunflareGameObjectMeshRenderer.enabled = true;
sunflareGameObject.layer = 10; //start in scaledspace
scaledCameraHook = (SunflareCameraHook) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent (typeof(SunflareCameraHook));
scaledCameraHook.flare = this;
scaledCameraHook.useDbufferOnCamera = 0f;
if (!(HighLogic.LoadedScene == GameScenes.TRACKSTATION))
{
nearCameraHook = (SunflareCameraHook)Scatterer.Instance.nearCamera.gameObject.AddComponent (typeof(SunflareCameraHook));
nearCameraHook.flare = this;
nearCameraHook.useDbufferOnCamera = 1f;
}
ApplySunflareConfig ();
sunglareMaterial.SetFloat (ShaderProperties.aspectRatio_PROPERTY, Scatterer.Instance.scaledSpaceCamera.aspect);
Shader.SetGlobalTexture(ShaderProperties.scattererReconstructedCloud_PROPERTY, Texture2D.whiteTexture); // Temporary way to pass volumetric cloud extinction, if raymarched volumetrics are loaded they override this
Utils.LogDebug ("Added custom sun flare for "+sourceName);
}
public void updateProperties()
{
var sunViewPortPos = Scatterer.Instance.scaledSpaceCamera.WorldToViewportPoint (sourceScaledTransform.position);
hitStatus=false;
if (sunViewPortPos.z > 0)
{
if (syntaxVersion == 1)
{
float dist = (float) (Scatterer.Instance.scaledSpaceCamera.transform.position - sourceScaledTransform.position)
.magnitude;
sunGlareScale = dist / 2266660f * Scatterer.Instance.scaledSpaceCamera.fieldOfView / 60f;
//if dist > 1.25*sunglareFadeDistance -->1
//if dist < 0.25*sunglareFadeDistance -->0
//else values smoothstepped in between
sunGlareFade = Mathf.SmoothStep (0, 1, (dist / settingsV1.sunGlareFadeDistance) - 0.25f);
//if dist < 0.5 * ghostFadeDistance -->1
//if dist > 1.5 * ghostFadeDistance -->0
//else values smoothstepped in between
ghostFade = Mathf.SmoothStep (0, 1, (dist - 0.5f * settingsV1.ghostFadeDistance) / (settingsV1.ghostFadeDistance));
ghostFade = 1 - ghostFade;
sunglareMaterial.SetFloat (ShaderProperties.sunGlareScale_PROPERTY, sunGlareScale);
sunglareMaterial.SetFloat (ShaderProperties.sunGlareFade_PROPERTY, sunGlareFade);
sunglareMaterial.SetFloat (ShaderProperties.ghost1Fade_PROPERTY, ghostFade);
sunglareMaterial.SetFloat (ShaderProperties.ghost2Fade_PROPERTY, ghostFade);
sunglareMaterial.SetFloat (ShaderProperties.ghost3Fade_PROPERTY, ghostFade);
}
else if (syntaxVersion == 2)
{
float dist = (float) (Scatterer.Instance.scaledSpaceCamera.transform.position - sourceScaledTransform.position).magnitude / ((float) source.Radius / ScaledSpace.ScaleFactor); //distance measured in stellar radius
if (settingsV2.flares.Count > 0)
{
float intensity = settingsV2.flares[0].intensityCurve.Curve.Evaluate(dist);
float scale = settingsV2.flares[0].scaleCurve.Curve.Evaluate(dist);
sunglareMaterial.SetVector ("flareSettings", new Vector3(intensity, settingsV2.flares[0].displayAspectRatio,1f/scale));
}
if (settingsV2.flares.Count > 1)
{
float intensity = settingsV2.flares[1].intensityCurve.Evaluate(dist);
float scale = settingsV2.flares[1].scaleCurve.Evaluate(dist);
sunglareMaterial.SetVector ("spikesSettings", new Vector3(intensity, settingsV2.flares[1].displayAspectRatio,1f/scale));
}
//ghostFade is now per ghost
if (settingsV2.ghosts.Count > 0)
{
ghostFade = settingsV2.ghosts[0].intensityCurve.Evaluate(dist);
sunglareMaterial.SetFloat (ShaderProperties.ghost1Fade_PROPERTY, ghostFade);
}
if (settingsV2.ghosts.Count > 1)
{
ghostFade = settingsV2.ghosts[1].intensityCurve.Evaluate(dist);
sunglareMaterial.SetFloat (ShaderProperties.ghost2Fade_PROPERTY, ghostFade);
}
if (settingsV2.ghosts.Count > 2)
{
ghostFade = settingsV2.ghosts[2].intensityCurve.Evaluate(dist);
sunglareMaterial.SetFloat (ShaderProperties.ghost3Fade_PROPERTY, ghostFade);
}
}
if (!MapView.MapIsEnabled && !(HighLogic.LoadedScene == GameScenes.TRACKSTATION))
{
hitStatus = Physics.Raycast (Scatterer.Instance.nearCamera.transform.position,
(source.transform.position - Scatterer.Instance.nearCamera.transform.position).normalized,
out hit, Mathf.Infinity, (int)((1 << 15) + (1 << 0)));
if (!hitStatus) {
hitStatus = Physics.Raycast (Scatterer.Instance.scaledSpaceCamera.transform.position,
(sourceScaledTransform.position - Scatterer.Instance.scaledSpaceCamera.transform.position)
.normalized, out hit, Mathf.Infinity, (int)((1 << 10)));
}
sunglareMaterial.SetVector(ShaderProperties.sunWorldPosition_PROPERTY, (Vector3)ScaledSpace.ScaledToLocalSpace(new Vector3d(sourceScaledTransform.position.x, sourceScaledTransform.position.y, sourceScaledTransform.position.z)));
}
else
{
hitStatus = Physics.Raycast (Scatterer.Instance.scaledSpaceCamera.transform.position, (sourceScaledTransform.position - Scatterer.Instance.transform.position).normalized, out hit, Mathf.Infinity, (int)((1 << 10)));
sunglareMaterial.SetVector(ShaderProperties.sunWorldPosition_PROPERTY, sourceScaledTransform.position);
}
if(hitStatus)
{
//if sun visible, draw sunflare
if(hit.transform == sourceScaledTransform)
hitStatus=false;
}
if (HighLogic.LoadedScene != GameScenes.TRACKSTATION && DepthToDistanceCommandBuffer.RenderTexture != null)
sunglareMaterial.SetTexture (ShaderProperties._customDepthTexture_PROPERTY, DepthToDistanceCommandBuffer.RenderTexture);
}
flareRendering = !hitStatus && (sunViewPortPos.z > 0) && !Scatterer.Instance.scattererCelestialBodiesManager.underwater;
sunglareMaterial.SetFloat(ShaderProperties.renderSunFlare_PROPERTY, flareRendering ? 1.0f : 0.0f);
}
public void Update()
{
//if rendertexture is lost, wait a bit before re-creating it
if (!extinctionTexture.IsCreated())
{
waitBeforeReloadCnt++;
if (waitBeforeReloadCnt >= 2)
{
extinctionTexture.Create();
waitBeforeReloadCnt = 0;
}
}
//enable or disable scaled or near script depending on trackstation or mapview
if (!MapView.MapIsEnabled && HighLogic.LoadedScene != GameScenes.TRACKSTATION)
{
nearCameraHook.enabled = true;
scaledCameraHook.enabled = false;
sunflareGameObject.layer = 15;
}
else
{
if (nearCameraHook)
nearCameraHook.enabled=false;
scaledCameraHook.enabled=true;
sunflareGameObject.layer = 10;
}
}
public void ClearExtinction()
{
RenderTexture rt=RenderTexture.active;
RenderTexture.active= extinctionTexture;
GL.Clear(false,true,Color.white);
//restore active rendertexture
RenderTexture.active=rt;
}
public void OnDestroy()
{
if (nearCameraHook)
{
Component.Destroy (nearCameraHook);
UnityEngine.Object.Destroy (nearCameraHook);
}
if (scaledCameraHook)
{
Component.Destroy (scaledCameraHook);
UnityEngine.Object.Destroy (scaledCameraHook);
}
if (extinctionTexture)
{
extinctionTexture.Release();
UnityEngine.Object.Destroy (extinctionTexture);
}
}
public void Configure(CelestialBody source, string sourceName, Transform sourceScaledTransform, ConfigNode configNodeToLoad)
{
this.source = source;
this.sourceName = sourceName;
this.sourceScaledTransform = sourceScaledTransform;
this.configNodeToLoad = configNodeToLoad;
}
public void LoadSettings ()
{
LoadSettingsFromConfigNode (configNodeToLoad);
}
void LoadSettingsFromConfigNode (ConfigNode node)
{
if (node.HasValue ("syntaxVersion"))
{
if (node.TryGetValue ("syntaxVersion", ref syntaxVersion) && ((syntaxVersion == 1) || (syntaxVersion == 2)))
{
Utils.LogDebug ("Sunflare syntax version: " + syntaxVersion.ToString ());
}
else
{
Utils.LogDebug ("Invalid sunflare syntax version found: " + node.GetValue ("syntaxVersion") + ", defaulting to version 1 for retro-compatibility");
syntaxVersion = 1;
}
}
else
{
Utils.LogDebug ("No sunflare syntax version found, defaulting to version 1 for retro-compatibility");
syntaxVersion = 1;
}
if (syntaxVersion == 1)
{
settingsV1 = new SunflareSettingsV1 ();
ConfigNode.LoadObjectFromConfig (settingsV1, node);
}
else
{
settingsV2 = new SunflareSettingsV2 ();
settingsV2.Load(node);
}
}
public void ApplyFromUI(ConfigNode node)
{
LoadSettingsFromConfigNode (node);
configNodeToLoad = node;
ApplySunflareConfig ();
}
void ApplySunflareConfig ()
{
if (syntaxVersion == 1)
{
ApplySyntaxV1FlareConfig ();
}
else if (syntaxVersion == 2)
{
ApplySyntaxV2FlareConfig ();
}
extinctionTexture = new RenderTexture (4, 4, 0, RenderTextureFormat.ARGB32);
extinctionTexture.antiAliasing = 1;
extinctionTexture.filterMode = FilterMode.Point;
extinctionTexture.Create ();
sunglareMaterial.SetTexture ("extinctionTexture", extinctionTexture);
}
void ApplySyntaxV1FlareConfig ()
{
LoadAndSetTexture ("sunFlare" , (String.Format ("{0}/{1}", Utils.GameDataPath + settingsV1.assetPath, "sunFlare.png")));
LoadAndSetTexture ("sunSpikes", (String.Format ("{0}/{1}", Utils.GameDataPath + settingsV1.assetPath, "sunSpikes.png")));
LoadAndSetTexture ("sunGhost1", (String.Format ("{0}/{1}", Utils.GameDataPath + settingsV1.assetPath, "Ghost1.png")));
LoadAndSetTexture ("sunGhost2", (String.Format ("{0}/{1}", Utils.GameDataPath + settingsV1.assetPath, "Ghost2.png")));
LoadAndSetTexture ("sunGhost3", (String.Format ("{0}/{1}", Utils.GameDataPath + settingsV1.assetPath, "Ghost3.png")));
//didn't want to serialize the matrices directly as the result is pretty unreadable
//sorry about the mess, syntax v2 is cleaner
Matrix4x4 ghost1Settings1 = Matrix4x4.zero;
for (int i = 0; i < settingsV1.ghost1SettingsList1.Count; i++)
{
ghost1Settings1.SetRow (i, settingsV1.ghost1SettingsList1 [i]);
}
Matrix4x4 ghost1Settings2 = Matrix4x4.zero;
for (int i = 0; i < settingsV1.ghost1SettingsList2.Count; i++)
{
ghost1Settings2.SetRow (i, settingsV1.ghost1SettingsList2 [i]);
}
//ghost 2
Matrix4x4 ghost2Settings1 = Matrix4x4.zero;
for (int i = 0; i < settingsV1.ghost2SettingsList1.Count; i++)
{
ghost2Settings1.SetRow (i, settingsV1.ghost2SettingsList1 [i]);
}
Matrix4x4 ghost2Settings2 = Matrix4x4.zero;
for (int i = 0; i < settingsV1.ghost2SettingsList2.Count; i++)
{
ghost2Settings2.SetRow (i, settingsV1.ghost2SettingsList2 [i]);
}
//ghost 3
Matrix4x4 ghost3Settings1 = Matrix4x4.zero;
for (int i = 0; i < settingsV1.ghost3SettingsList1.Count; i++)
{
ghost3Settings1.SetRow (i, settingsV1.ghost3SettingsList1 [i]);
}
Matrix4x4 ghost3Settings2 = Matrix4x4.zero;
for (int i = 0; i < settingsV1.ghost3SettingsList2.Count; i++)
{
ghost3Settings2.SetRow (i, settingsV1.ghost3SettingsList2 [i]);
}
sunglareMaterial.SetVector ("flareSettings", settingsV1.flareSettings);
sunglareMaterial.SetVector ("spikesSettings", settingsV1.spikesSettings);
sunglareMaterial.SetMatrix ("ghost1Settings1", ghost1Settings1);
sunglareMaterial.SetMatrix ("ghost1Settings2", ghost1Settings2);
sunglareMaterial.SetMatrix ("ghost2Settings1", ghost2Settings1);
sunglareMaterial.SetMatrix ("ghost2Settings2", ghost2Settings2);
sunglareMaterial.SetMatrix ("ghost3Settings1", ghost3Settings1);
sunglareMaterial.SetMatrix ("ghost3Settings2", ghost3Settings2);
sunglareMaterial.SetVector ("flareColor", settingsV1.flareColor);
}
void ApplySyntaxV2FlareConfig ()
{
sunglareMaterial.SetVector ("flareSettings", Vector3.zero);
sunglareMaterial.SetVector ("spikesSettings", Vector3.zero);
sunglareMaterial.SetMatrix ("ghost1Settings1", Matrix4x4.zero);
sunglareMaterial.SetMatrix ("ghost1Settings2", Matrix4x4.zero);
sunglareMaterial.SetMatrix ("ghost2Settings1", Matrix4x4.zero);
sunglareMaterial.SetMatrix ("ghost2Settings2", Matrix4x4.zero);
sunglareMaterial.SetMatrix ("ghost3Settings1", Matrix4x4.zero);
sunglareMaterial.SetMatrix ("ghost3Settings2", Matrix4x4.zero);
sunglareMaterial.SetFloat (ShaderProperties.sunGlareScale_PROPERTY, 1f);
sunglareMaterial.SetFloat (ShaderProperties.sunGlareFade_PROPERTY, 1f);
//For the 2 flares the scale and intensity have to be overriden from curve I think, or just leave intensity at 1 here and override fade from curve?
//TODO: replace only the second 1f with the 1/value from the scaleCurve
if (settingsV2.flares.Count > 0)
{
LoadAndSetTexture ("sunFlare", Utils.GameDataPath + settingsV2.flares[0].texture);
sunglareMaterial.SetVector ("flareSettings", new Vector3(1f, settingsV2.flares[0].displayAspectRatio,1f));
}
if (settingsV2.flares.Count > 1)
{
LoadAndSetTexture ("sunSpikes", Utils.GameDataPath + settingsV2.flares[1].texture);
sunglareMaterial.SetVector ("spikesSettings", new Vector3(1f, settingsV2.flares[1].displayAspectRatio,1f));
}
if (settingsV2.flares.Count > 2)
{
Utils.LogError ("More than 2 flares used on sunflare " + sourceName + ", only 2 are supported, additional flares will not be used");
}
//All static settings are set for ghosts, all that's left to do is configure the fade from ghost intensity curves
if (settingsV2.ghosts.Count > 0)
{
LoadAndSetTexture ("sunGhost1", Utils.GameDataPath + settingsV2.ghosts[0].texture);
SetGhostParameters ("ghost1Settings1", "ghost1Settings2", settingsV2.ghosts[0]);
}
if (settingsV2.ghosts.Count > 1)
{
LoadAndSetTexture ("sunGhost2", Utils.GameDataPath + settingsV2.ghosts[1].texture);
SetGhostParameters ("ghost2Settings1", "ghost2Settings2", settingsV2.ghosts[1]);
}
if (settingsV2.ghosts.Count > 2)
{
LoadAndSetTexture ("sunGhost3", Utils.GameDataPath + settingsV2.ghosts[2].texture);
SetGhostParameters ("ghost3Settings1", "ghost3Settings2", settingsV2.ghosts[2]);
}
if (settingsV2.ghosts.Count > 3)
{
Utils.LogError ("More than 3 ghosts used on sunflare " + sourceName + ", only 3 are supported, additional ghosts will not be used");
}
sunglareMaterial.SetVector ("flareColor", settingsV2.flareColor);
}
void SetGhostParameters (string shaderParam1, string shaderParam2, GhostSettings ghostSettings )
{
Matrix4x4 ghostSettings1 = Matrix4x4.zero;
for (int i = 0; (i < ghostSettings.instances.Count) && (i < 4); i++)
{
ghostSettings1.SetRow (i, new Vector4 (ghostSettings.instances [i].intensityMultiplier, ghostSettings.instances [i].displayAspectRatio, 1f / ghostSettings.instances [i].scale, ghostSettings.instances [i].sunToScreenCenterPosition));
}
Matrix4x4 ghostSettings2 = Matrix4x4.zero;
for (int i = 4; (i < ghostSettings.instances.Count) && (i < 8); i++)
{
ghostSettings2.SetRow (i-4, new Vector4 (ghostSettings.instances [i].intensityMultiplier, ghostSettings.instances [i].displayAspectRatio, 1f / ghostSettings.instances [i].scale, ghostSettings.instances [i].sunToScreenCenterPosition));
}
sunglareMaterial.SetMatrix (shaderParam1, ghostSettings1);
sunglareMaterial.SetMatrix (shaderParam2, ghostSettings2);
}
void LoadAndSetTexture (string textureName, string path)
{
Texture2D texture = null;
if (texturesDictionary.ContainsKey (path))
{
texture = texturesDictionary[path];
}
else
{
if (Path.GetExtension(path) == ".dds")
{
texture = Utils.LoadDDSTexture(System.IO.File.ReadAllBytes (path),path);
}
else
{
texture = new Texture2D(1, 1);
texture.LoadImage(System.IO.File.ReadAllBytes(path));
}
texturesDictionary[path] = texture;
}
texture.wrapMode = TextureWrapMode.Clamp;
sunglareMaterial.SetTexture (textureName, texture);
}
}
}
================================================
FILE: scatterer/Effects/SunFlare/SunflareCameraHook.cs
================================================
using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using KSP.IO;
namespace Scatterer
{
public class SunflareCameraHook : MonoBehaviour
{
public SunFlare flare;
public float useDbufferOnCamera;
public SunflareCameraHook ()
{
}
public void OnPreRender()
{
if(flare)
{
flare.updateProperties ();
flare.sunglareMaterial.SetFloat(ShaderProperties.renderOnCurrentCamera_PROPERTY,1.0f);
flare.sunglareMaterial.SetFloat(ShaderProperties.useDbufferOnCamera_PROPERTY,useDbufferOnCamera);
}
}
public void OnPostRender()
{
if(flare)
{
flare.ClearExtinction ();
flare.sunglareMaterial.SetFloat(ShaderProperties.renderOnCurrentCamera_PROPERTY,0.0f);
flare.sunglareMaterial.SetFloat(ShaderProperties.useDbufferOnCamera_PROPERTY,useDbufferOnCamera);
}
}
}
}
================================================
FILE: scatterer/Effects/SunFlare/SunflareManager.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Scatterer
{
public class SunflareManager : MonoBehaviour
{
public Dictionary scattererSunFlares = new Dictionary();
public SunflareManager ()
{
}
public void Init()
{
StartCoroutine (InitCoroutine());
}
IEnumerator InitCoroutine()
{
foreach (ConfigNode _sunflareConfigs in Scatterer.Instance.planetsConfigsReader.sunflareConfigs)
{
foreach (ConfigNode _cn in _sunflareConfigs.GetNodes())
{
if (scattererSunFlares.ContainsKey(_cn.name))
continue;
SunFlare customSunFlare = (SunFlare)Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent (typeof(SunFlare));
try
{
customSunFlare.Configure(FlightGlobals.Bodies.SingleOrDefault (_cb => _cb.GetName () == _cn.name),
_cn.name,Utils.GetScaledTransform (_cn.name), _cn);
customSunFlare.start ();
scattererSunFlares.Add (_cn.name, customSunFlare);
}
catch (Exception exception)
{
Utils.LogDebug ("Custom sunflare cannot be added to " + _cn.name + " " + exception.ToString ());
Component.Destroy (customSunFlare);
UnityEngine.Object.Destroy (customSunFlare);
continue;
}
yield return new WaitForFixedUpdate ();
}
}
DisableStockSunflares ();
}
//TODO: decouple and let every sunflare update itself, based on the GameObject it is linked to?
public void UpdateFlares()
{
foreach (SunFlare customSunFlare in scattererSunFlares.Values)
{
customSunFlare.Update();
}
}
public void OnDestroy()
{
if (this)
StopAllCoroutines();
ReenableStockSunflares ();
foreach (SunFlare customSunFlare in scattererSunFlares.Values)
{
Component.DestroyImmediate (customSunFlare);
}
}
void DisableStockSunflares ()
{
global::SunFlare[] stockFlares = (global::SunFlare[])global::SunFlare.FindObjectsOfType (typeof(global::SunFlare));
foreach (global::SunFlare _flare in stockFlares)
{
if (scattererSunFlares.ContainsKey (_flare.sun.name))
{
Utils.LogDebug ("Disabling stock sunflare for " + _flare.sun.name);
_flare.sunFlare.enabled = false;
_flare.enabled = false;
_flare.gameObject.SetActive (false);
}
}
}
void ReenableStockSunflares ()
{
global::SunFlare[] stockFlares = (global::SunFlare[]) global::SunFlare.FindObjectsOfType(typeof( global::SunFlare));
foreach(global::SunFlare _flare in stockFlares)
{
if (scattererSunFlares.ContainsKey (_flare.sun.name))
{
_flare.sunFlare.enabled=true;
}
}
}
}
}
================================================
FILE: scatterer/Effects/SunFlare/SunflareSettingsV1.cs
================================================
using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.Collections.Generic;
namespace Scatterer
{
public class SunflareSettingsV1
{
[Persistent]
public int syntaxVersion = 1;
[Persistent]
public string assetPath;
[Persistent]
public float sunGlareFadeDistance = 250000;
[Persistent]
public float ghostFadeDistance = 13500000;
[Persistent]
public Vector3 flareSettings = Vector3.zero;
[Persistent]
public Vector3 spikesSettings = Vector3.zero;
[Persistent]
public List ghost1SettingsList1=new List{};
[Persistent]
public List ghost1SettingsList2=new List{};
[Persistent]
public List ghost2SettingsList1=new List{};
[Persistent]
public List ghost2SettingsList2=new List{};
[Persistent]
public List ghost3SettingsList1=new List{};
[Persistent]
public List ghost3SettingsList2=new List{};
[Persistent]
public Vector3 flareColor = Vector3.one;
public SunflareSettingsV1 ()
{
}
}
}
================================================
FILE: scatterer/Effects/SunFlare/SunflareSettingsV2.cs
================================================
using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.Collections.Generic;
namespace Scatterer
{
public class SunflareSettingsV2
{
[Persistent] public int syntaxVersion = 2;
[Persistent] public Vector3 flareColor = Vector3.one;
[Persistent] public List flares = new List {};
[Persistent] public List ghosts = new List {};
public SunflareSettingsV2 ()
{
}
public void Load(ConfigNode node)
{
ConfigNode.LoadObjectFromConfig (this, node);
if (node.HasNode ("flares") && node.GetNode("flares").HasNode("Item"))
{
ConfigNode[] flareNodes = node.GetNode("flares").GetNodes("Item");
for (int i = 0; i < flareNodes.Length; i++) { flares[i].Load(flareNodes[i]);}
}
if (node.HasNode ("ghosts") && node.GetNode("ghosts").HasNode("Item"))
{
ConfigNode[] ghostNodes = node.GetNode("ghosts").GetNodes("Item");
for (int i = 0; i< ghostNodes.Length; i++) {ghosts[i].Load(ghostNodes[i]);}
}
}
}
public class FlareSettings
{
[Persistent] public string texture;
[Persistent] public float displayAspectRatio;
[Persistent] public FloatCurve scaleCurve = new FloatCurve(new [] {new Keyframe(0, 1), new Keyframe(1, 1)});
[Persistent] public FloatCurve intensityCurve = new FloatCurve(new [] {new Keyframe(0, 1), new Keyframe(1, 1)});
public void Load(ConfigNode node)
{
if (node.HasNode ("scaleCurve"))
scaleCurve.Load (node.GetNode ("scaleCurve"));
if (node.HasNode ("intensityCurve"))
intensityCurve.Load (node.GetNode ("intensityCurve"));
}
}
public class GhostSettings
{
[Persistent] public string texture;
[Persistent] public FloatCurve intensityCurve = new FloatCurve(new [] {new Keyframe(0, 1), new Keyframe(1, 1)});
[Persistent] public List instances = new List {};
public void Load(ConfigNode node)
{
if (node.HasNode ("intensityCurve"))
intensityCurve.Load (node.GetNode ("intensityCurve"));
}
}
//not sure this will serialize or reach the depth limit thing
public class GhostInstanceSettings
{
[Persistent] public float intensityMultiplier;
[Persistent] public float displayAspectRatio;
[Persistent] public float scale;
[Persistent] public float sunToScreenCenterPosition;
}
}
================================================
FILE: scatterer/Effects/SunlightModulator/SunlightModulator.cs
================================================
using UnityEngine;
using System.Collections.Generic;
namespace Scatterer
{
public class SunlightModulatorsManager
{
public void ModulateByAttenuation(Light light, float inAttenuation)
{
FindOrCreateModulator (light).ModulateByAttenuation (inAttenuation);
}
public void ModulateByColor(Light light, Color inColor)
{
FindOrCreateModulator (light).ModulateByColor (inColor);
}
public Color GetLastModulateColor(Light light)
{
return FindOrCreateModulator (light).lastModulateColor;
}
public Color GetOriginalLightColor(Light light)
{
return FindOrCreateModulator (light).getOriginalColor();
}
private SunlightModulator FindOrCreateModulator(Light light)
{
if (modulatorsDictionary.ContainsKey (light))
{
return modulatorsDictionary [light];
}
else
{
modulatorsDictionary[light] = (SunlightModulator) Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent(typeof(SunlightModulator));
modulatorsDictionary[light].Init(light);
return modulatorsDictionary[light];
}
}
private Dictionary modulatorsDictionary = new Dictionary ();
public void Cleanup()
{
foreach (SunlightModulator modulator in modulatorsDictionary.Values)
{
Component.DestroyImmediate(modulator);
}
}
}
public class SunlightModulator : MonoBehaviour
{
Color originalColor = Color.white, modulateColor;
public Color lastModulateColor;
Light sunLight;
bool applyModulation = false;
bool originalColorStored = false;
public SunlightModulatorPreRenderHook preRenderHook;
public SunlightModulatorPostRenderHook postRenderHook;
public void Init(Light light)
{
sunLight = light;
preRenderHook = (SunlightModulatorPreRenderHook) Utils.getEarliestLocalCamera().gameObject.AddComponent(typeof(SunlightModulatorPreRenderHook));
preRenderHook.Init (this);
postRenderHook = (SunlightModulatorPostRenderHook) Scatterer.Instance.nearCamera.gameObject.AddComponent(typeof(SunlightModulatorPostRenderHook)); //less than optimal, doesn't affect internalCamera
postRenderHook.Init (this);
}
public void OnPreCull() //added to scaledSpaceCamera, called before any calls from skyNode or oceanNode
{
storeOriginalColor ();
}
private void storeOriginalColor() //may not be necessary every frame?
{
if (sunLight.color != Color.black)
{
originalColor = sunLight.color;
originalColorStored = true;
}
}
public Color getOriginalColor()
{
return originalColor;
}
public void ModulateByAttenuation(float inAttenuation) //called by skynode, ie scaledSpaceCamera onPreCull
{
modulateColor *= inAttenuation;
applyModulation = true;
}
public void ModulateByColor(Color inColor)
{
modulateColor *= inColor;
applyModulation = true;
}
public void applyColorModulation() //called by hook on farCamera onPreRender
{
if (applyModulation && originalColorStored)
{
sunLight.color = modulateColor * originalColor;
lastModulateColor = sunLight.color;
modulateColor = Color.white;
}
}
public void restoreOriginalColor() //called by hook on nearCamera/IVAcamera onPostRender //may not be necessary every frame?
{
if (applyModulation && originalColorStored)
{
sunLight.color = originalColor;
applyModulation = false;
}
}
public void OnDestroy()
{
Component.Destroy (preRenderHook);
Component.Destroy (postRenderHook);
}
}
}
================================================
FILE: scatterer/Effects/SunlightModulator/SunlightModulatorPostRenderHook.cs
================================================
using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using KSP.IO;
namespace Scatterer
{
public class SunlightModulatorPostRenderHook : MonoBehaviour
{
SunlightModulator targetModulator;
public SunlightModulatorPostRenderHook ()
{
}
public void Init(SunlightModulator target)
{
targetModulator = target;
}
public void OnPostRender()
{
targetModulator.restoreOriginalColor ();
}
public void OnDestroy()
{
targetModulator.postRenderHook = null;
}
}
}
================================================
FILE: scatterer/Effects/SunlightModulator/SunlightModulatorPreRenderHook.cs
================================================
using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using KSP.IO;
namespace Scatterer
{
public class SunlightModulatorPreRenderHook : MonoBehaviour
{
SunlightModulator targetModulator;
public SunlightModulatorPreRenderHook ()
{
}
public void Init(SunlightModulator target)
{
targetModulator = target;
}
public void OnPreCull() //needs to be onPreCull, onPreRender is too late
{
targetModulator.applyColorModulation ();
}
public void OnDestroy()
{
targetModulator.preRenderHook = null;
}
}
}
================================================
FILE: scatterer/Effects/Tonemapping/HableCurve.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Scatterer
{
// From unity postprocessing
///
/// A raw implementation of John Hable's artist-friendly tonemapping curve.
/// See http://filmicworlds.com/blog/filmic-tonemapping-with-piecewise-power-curves/
///
public class HableCurve
{
class Segment
{
public float offsetX;
public float offsetY;
public float scaleX;
public float scaleY;
public float lnA;
public float B;
public float Eval(float x)
{
float x0 = (x - offsetX) * scaleX;
float y0 = 0f;
// log(0) is undefined but our function should evaluate to 0. There are better ways to handle this,
// but it's doing it the slow way here for clarity.
if (x0 > 0)
y0 = Mathf.Exp(lnA + B * Mathf.Log(x0));
return y0 * scaleY + offsetY;
}
}
struct DirectParams
{
internal float x0;
internal float y0;
internal float x1;
internal float y1;
internal float W;
internal float overshootX;
internal float overshootY;
internal float gamma;
}
///
/// The curve's white point.
///
public float whitePoint { get; private set; }
///
/// The inverse of the curve's white point.
///
public float inverseWhitePoint { get; private set; }
internal float x0 { get; private set; }
internal float x1 { get; private set; }
internal float y0 { get; private set; }
internal float y1 { get; private set; }
// Toe, mid, shoulder
readonly Segment[] m_Segments = new Segment[3];
///
/// Creates a new curve.
///
public HableCurve()
{
for (int i = 0; i < 3; i++)
m_Segments[i] = new Segment();
uniforms = new Uniforms(this);
}
///
/// Evaluates a given point on the curve.
///
/// The point within the curve to evaluate (on the horizontal axis)
/// The value of the curve, at the point specified
public float Eval(float x)
{
float normX = x * inverseWhitePoint;
int index = (normX < x0) ? 0 : ((normX < x1) ? 1 : 2);
var segment = m_Segments[index];
float ret = segment.Eval(normX);
return ret;
}
///
/// Returns the base-2 exponential function of , which is 2
/// raised to the power .
///
/// Value of the exponent
/// The base-2 exponential function of
public static float Exp2(float x)
{
return Mathf.Exp(x * 0.69314718055994530941723212145818f);
}
///
/// Initializes the curve with given settings.
///
/// Affects the transition between the toe and the mid section of
/// the curve. A value of 0 means no toe, a value of 1 means a very hard transition
/// Affects how much of the dynamic range is in the toe. With a
/// small value, the toe will be very short and quickly transition into the linear section,
/// and with a longer value having a longer toe
/// Affects the transition between the mid section and the
/// shoulder of the curve. A value of 0 means no shoulder, a value of 1 means a very hard
/// transition
/// Affects how many F-stops (EV) to add to the dynamic range
/// of the curve
/// Affects how much overshoot to add to the shoulder
/// Applies a gamma function to the curve
public void Init(float toeStrength, float toeLength, float shoulderStrength, float shoulderLength, float shoulderAngle, float gamma)
{
var dstParams = new DirectParams();
// This is not actually the display gamma. It's just a UI space to avoid having to
// enter small numbers for the input.
const float kPerceptualGamma = 2.2f;
// Constraints
{
toeLength = Mathf.Pow(Mathf.Clamp01(toeLength), kPerceptualGamma);
toeStrength = Mathf.Clamp01(toeStrength);
shoulderAngle = Mathf.Clamp01(shoulderAngle);
shoulderStrength = Mathf.Clamp(shoulderStrength, 1e-5f, 1f - 1e-5f);
shoulderLength = Mathf.Max(0f, shoulderLength);
gamma = Mathf.Max(1e-5f, gamma);
}
// Apply base params
{
// Toe goes from 0 to 0.5
float x0 = toeLength * 0.5f;
float y0 = (1f - toeStrength) * x0; // Lerp from 0 to x0
float remainingY = 1f - y0;
float initialW = x0 + remainingY;
float y1_offset = (1f - shoulderStrength) * remainingY;
float x1 = x0 + y1_offset;
float y1 = y0 + y1_offset;
// Filmic shoulder strength is in F stops
float extraW = Exp2(shoulderLength) - 1f;
float W = initialW + extraW;
dstParams.x0 = x0;
dstParams.y0 = y0;
dstParams.x1 = x1;
dstParams.y1 = y1;
dstParams.W = W;
// Bake the linear to gamma space conversion
dstParams.gamma = gamma;
}
dstParams.overshootX = (dstParams.W * 2f) * shoulderAngle * shoulderLength;
dstParams.overshootY = 0.5f * shoulderAngle * shoulderLength;
InitSegments(dstParams);
}
public void SetMaterialParams(Material mat)
{
/*
mat.SetVector("_CustomToneCurve", uniforms.curve);
mat.SetVector("_y0y1", uniforms.y0y1);
mat.SetVector("_ToeSegmentA", uniforms.toeSegmentA);
mat.SetVector("_ToeSegmentB", uniforms.toeSegmentB);
mat.SetVector("_MidSegmentA", uniforms.midSegmentA);
mat.SetVector("_MidSegmentB", uniforms.midSegmentB);
mat.SetVector("_ShoSegmentA", uniforms.shoSegmentA);
mat.SetVector("_ShoSegmentB", uniforms.shoSegmentB);
*/
Shader.SetGlobalVector("_CustomToneCurve", uniforms.curve);
Shader.SetGlobalVector("_y0y1", uniforms.y0y1);
Shader.SetGlobalVector("_ToeSegmentA", uniforms.toeSegmentA);
Shader.SetGlobalVector("_ToeSegmentB", uniforms.toeSegmentB);
Shader.SetGlobalVector("_MidSegmentA", uniforms.midSegmentA);
Shader.SetGlobalVector("_MidSegmentB", uniforms.midSegmentB);
Shader.SetGlobalVector("_ShoSegmentA", uniforms.shoSegmentA);
Shader.SetGlobalVector("_ShoSegmentB", uniforms.shoSegmentB);
}
void InitSegments(DirectParams srcParams)
{
var paramsCopy = srcParams;
whitePoint = srcParams.W;
inverseWhitePoint = 1f / srcParams.W;
// normalize params to 1.0 range
paramsCopy.W = 1f;
paramsCopy.x0 /= srcParams.W;
paramsCopy.x1 /= srcParams.W;
paramsCopy.overshootX = srcParams.overshootX / srcParams.W;
float toeM = 0f;
float shoulderM = 0f;
{
float m, b;
AsSlopeIntercept(out m, out b, paramsCopy.x0, paramsCopy.x1, paramsCopy.y0, paramsCopy.y1);
float g = srcParams.gamma;
// Base function of linear section plus gamma is
// y = (mx+b)^g
//
// which we can rewrite as
// y = exp(g*ln(m) + g*ln(x+b/m))
//
// and our evaluation function is (skipping the if parts):
/*
float x0 = (x - offsetX) * scaleX;
y0 = exp(m_lnA + m_B*log(x0));
return y0*scaleY + m_offsetY;
*/
var midSegment = m_Segments[1];
midSegment.offsetX = -(b / m);
midSegment.offsetY = 0f;
midSegment.scaleX = 1f;
midSegment.scaleY = 1f;
midSegment.lnA = g * Mathf.Log(m);
midSegment.B = g;
toeM = EvalDerivativeLinearGamma(m, b, g, paramsCopy.x0);
shoulderM = EvalDerivativeLinearGamma(m, b, g, paramsCopy.x1);
// apply gamma to endpoints
paramsCopy.y0 = Mathf.Max(1e-5f, Mathf.Pow(paramsCopy.y0, paramsCopy.gamma));
paramsCopy.y1 = Mathf.Max(1e-5f, Mathf.Pow(paramsCopy.y1, paramsCopy.gamma));
paramsCopy.overshootY = Mathf.Pow(1f + paramsCopy.overshootY, paramsCopy.gamma) - 1f;
}
this.x0 = paramsCopy.x0;
this.x1 = paramsCopy.x1;
this.y0 = paramsCopy.y0;
this.y1 = paramsCopy.y1;
// Toe section
{
var toeSegment = m_Segments[0];
toeSegment.offsetX = 0;
toeSegment.offsetY = 0f;
toeSegment.scaleX = 1f;
toeSegment.scaleY = 1f;
float lnA, B;
SolveAB(out lnA, out B, paramsCopy.x0, paramsCopy.y0, toeM);
toeSegment.lnA = lnA;
toeSegment.B = B;
}
// Shoulder section
{
// Use the simple version that is usually too flat
var shoulderSegment = m_Segments[2];
float x0 = (1f + paramsCopy.overshootX) - paramsCopy.x1;
float y0 = (1f + paramsCopy.overshootY) - paramsCopy.y1;
float lnA, B;
SolveAB(out lnA, out B, x0, y0, shoulderM);
shoulderSegment.offsetX = (1f + paramsCopy.overshootX);
shoulderSegment.offsetY = (1f + paramsCopy.overshootY);
shoulderSegment.scaleX = -1f;
shoulderSegment.scaleY = -1f;
shoulderSegment.lnA = lnA;
shoulderSegment.B = B;
}
// Normalize so that we hit 1.0 at our white point. We wouldn't have do this if we
// skipped the overshoot part.
{
// Evaluate shoulder at the end of the curve
float scale = m_Segments[2].Eval(1f);
float invScale = 1f / scale;
m_Segments[0].offsetY *= invScale;
m_Segments[0].scaleY *= invScale;
m_Segments[1].offsetY *= invScale;
m_Segments[1].scaleY *= invScale;
m_Segments[2].offsetY *= invScale;
m_Segments[2].scaleY *= invScale;
}
}
// Find a function of the form:
// f(x) = e^(lnA + Bln(x))
// where
// f(0) = 0; not really a constraint
// f(x0) = y0
// f'(x0) = m
void SolveAB(out float lnA, out float B, float x0, float y0, float m)
{
B = (m * x0) / y0;
lnA = Mathf.Log(y0) - B * Mathf.Log(x0);
}
// Convert to y=mx+b
void AsSlopeIntercept(out float m, out float b, float x0, float x1, float y0, float y1)
{
float dy = (y1 - y0);
float dx = (x1 - x0);
if (dx == 0)
m = 1f;
else
m = dy / dx;
b = y0 - x0 * m;
}
// f(x) = (mx+b)^g
// f'(x) = gm(mx+b)^(g-1)
float EvalDerivativeLinearGamma(float m, float b, float g, float x)
{
float ret = g * m * Mathf.Pow(m * x + b, g - 1f);
return ret;
}
///
/// Utility class to retrieve curve values for shader evaluation.
///
public class Uniforms
{
HableCurve parent;
internal Uniforms(HableCurve parent)
{
this.parent = parent;
}
///
/// A pre-built holding: (inverseWhitePoint, x0, x1, 0).
///
public Vector4 curve
{
get { return new Vector4(parent.inverseWhitePoint, parent.x0, parent.x1, 0f); }
}
public Vector2 y0y1
{
get { return new Vector2(parent.y0, parent.y1); }
}
///
/// A pre-built holding: (toe.offsetX, toe.offsetY, toe.scaleX, toe.scaleY).
///
public Vector4 toeSegmentA
{
get
{
var toe = parent.m_Segments[0];
return new Vector4(toe.offsetX, toe.offsetY, toe.scaleX, toe.scaleY);
}
}
///
/// A pre-built holding: (toe.lnA, toe.B, 0, 0).
///
public Vector4 toeSegmentB
{
get
{
var toe = parent.m_Segments[0];
return new Vector4(toe.lnA, toe.B, 0f, 0f);
}
}
///
/// A pre-built holding: (mid.offsetX, mid.offsetY, mid.scaleX, mid.scaleY).
///
public Vector4 midSegmentA
{
get
{
var mid = parent.m_Segments[1];
return new Vector4(mid.offsetX, mid.offsetY, mid.scaleX, mid.scaleY);
}
}
///
/// A pre-built holding: (mid.lnA, mid.B, 0, 0).
///
public Vector4 midSegmentB
{
get
{
var mid = parent.m_Segments[1];
return new Vector4(mid.lnA, mid.B, 0f, 0f);
}
}
///
/// A pre-built holding: (toe.offsetX, toe.offsetY, toe.scaleX, toe.scaleY).
///
public Vector4 shoSegmentA
{
get
{
var sho = parent.m_Segments[2];
return new Vector4(sho.offsetX, sho.offsetY, sho.scaleX, sho.scaleY);
}
}
///
/// A pre-built holding: (sho.lnA, sho.B, 0, 0).
///
public Vector4 shoSegmentB
{
get
{
var sho = parent.m_Segments[2];
return new Vector4(sho.lnA, sho.B, 0f, 0f);
}
}
}
///
/// The builtin instance for this curve.
///
public readonly Uniforms uniforms;
}
}
================================================
FILE: scatterer/GUI/AtmoGUI.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using KSP;
using KSP.IO;
using UnityEngine;
namespace Scatterer
{
public class AtmoGUI
{
float Rg = 600000.0f;
float atmosphereStartRadiusScale = 1f;
float HR = 3.2f;
float HM = 0.48f;
Vector3 m_betaR = new Vector3(0.029f, 0.0675f, 0.1655f);
Vector3 BETA_MSca = new Vector3(0.02f,0.02f,0.02f);
Vector3 ozoneAbsorption = new Vector3(0.0000003426f, 0.0000008298f, 0.000000036f);
float ozoneHeight = 25f;
float ozoneFalloff = 15f;
bool useOzone = false;
float m_mieG = 0.85f;
float AVERAGE_GROUND_REFLECTANCE = 0.1f;
float rescale = 1f, thickenRayleigh = 1f, thickenMie = 1f, thickenOzone = 1f;
bool multipleScattering = true;
bool fastPreviewMode = false;
SkyNode targetSkyNode;
int selPlanet;
public AtmoGUI ()
{
}
public void drawAtmoGUI(int selectedPlanet)
{
GUILayout.BeginHorizontal();
GUILayout.Label("Atmosphere start radius ");
GUILayout.TextField((Rg * atmosphereStartRadiusScale).ToString());
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Scale start radius");
atmosphereStartRadiusScale=(float)(float.Parse(GUILayout.TextField(atmosphereStartRadiusScale.ToString())));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Atmo height (auto)");
GUILayout.TextField((AtmoPreprocessor.CalculateRt (Rg*atmosphereStartRadiusScale, HR, HM, m_betaR, BETA_MSca, useOzone, ozoneHeight, ozoneFalloff)-Rg*atmosphereStartRadiusScale).ToString());
GUILayout.EndHorizontal();
GUIvector3NoButton ("Rayleigh Scattering - Beta_R:", ref m_betaR);
GUILayout.BeginHorizontal();
GUILayout.Label("Thicken");
thickenRayleigh=(float)(float.Parse(GUILayout.TextField(thickenRayleigh.ToString("00.000"))));
if (GUILayout.Button ("Go"))
{
m_betaR*=thickenRayleigh;
generate();
}
GUILayout.EndHorizontal();
GUIvector3NoButton ("Mie Scattering - Beta_MSca:", ref BETA_MSca);
GUILayout.BeginHorizontal();
GUILayout.Label("Thicken");
thickenMie=(float)(float.Parse(GUILayout.TextField(thickenMie.ToString("00.000"))));
if (GUILayout.Button ("Go"))
{
BETA_MSca*=thickenMie;
generate();
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Mie G (Mie phase function asymmetry)");
m_mieG = (float)(float.Parse(GUILayout.TextField(m_mieG.ToString())));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Rayleigh density scale height");
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("HR (in KM)");
HR=(float)(float.Parse(GUILayout.TextField(HR.ToString())));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Mie density scale height");
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("HM (in KM)");
HM=(float)(float.Parse(GUILayout.TextField(HM.ToString())));
GUILayout.EndHorizontal();
GUIvector3NoButton("Ozone absorption:", ref ozoneAbsorption);
GUILayout.BeginHorizontal();
GUILayout.Label("Thicken");
thickenOzone = (float)(float.Parse(GUILayout.TextField(thickenOzone.ToString("00.000"))));
if (GUILayout.Button("Go"))
{
ozoneAbsorption *= thickenOzone;
generate();
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Ozone layer altitude (km)");
ozoneHeight = (float)(float.Parse(GUILayout.TextField(ozoneHeight.ToString())));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Ozone layer falloff/extents (km)");
ozoneFalloff = (float)(float.Parse(GUILayout.TextField(ozoneFalloff.ToString())));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Use Ozone: " + useOzone.ToString() + " ");
if (GUILayout.Button("Toggle"))
useOzone = !useOzone;
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Auto rescale");
rescale=(float)(float.Parse(GUILayout.TextField(rescale.ToString("00.000"))));
if (GUILayout.Button ("Go"))
{
HR*=rescale;
HM*=rescale;
m_betaR/=rescale;
BETA_MSca/=rescale;
ozoneHeight *= rescale;
ozoneFalloff *= rescale;
ozoneAbsorption /= rescale;
generate();
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Average ground reflectance");
AVERAGE_GROUND_REFLECTANCE=(float)(float.Parse(GUILayout.TextField(AVERAGE_GROUND_REFLECTANCE.ToString())));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Multiple scattering: "+multipleScattering.ToString()+" ");
if (GUILayout.Button ("Toggle"))
multipleScattering = !multipleScattering;
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Fast preview mode: "+fastPreviewMode.ToString());
if (GUILayout.Button ("Toggle"))
fastPreviewMode = !fastPreviewMode;
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
if (GUILayout.Button ("Generate"))
{
generate();
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
if (GUILayout.Button ("Delete atmo cache"))
{
AtmoPreprocessor.DeleteCache();
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal ();
if (!targetSkyNode.isConfigModuleManagerPatch)
{
if (GUILayout.Button ("Save atmo"))
{
targetSkyNode.SaveToConfigNode ();
}
}
if (GUILayout.Button ("Load atmo")) {
targetSkyNode.LoadFromConfigNode ();
loadSettingsForPlanet(selPlanet);
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
GUILayout.Label (".cfg file used:");
GUIStyle guiStyle = new GUIStyle(GUI.skin.textArea);
if (targetSkyNode.isConfigModuleManagerPatch)
guiStyle.normal.textColor = Color.red;
GUILayout.TextField (targetSkyNode.isConfigModuleManagerPatch ? "ModuleManager patch detected, saving disabled" : targetSkyNode.configUrl.parent.url, guiStyle);
GUILayout.EndHorizontal ();
}
void generate()
{
Utils.LogDebug ("Generating atmosphere from UI for planet: " + targetSkyNode.prolandManager.scattererCelestialBody.celestialBodyName + "" +
"With settings:" +
"Rg " + (Rg*atmosphereStartRadiusScale).ToString () +
" HR " + HR.ToString () +
" HM " + HM.ToString () +
" m_betaR " + m_betaR.ToString () +
" BETA_MSca " + BETA_MSca.ToString () +
" m_mieG " + m_mieG.ToString () +
" ozoneAbsorption " + ozoneAbsorption.ToString() +
" ozoneHeight " + ozoneHeight.ToString() +
" ozoneFalloff " + ozoneFalloff.ToString() +
" useOzone " + useOzone.ToString() +
" AVERAGE_GROUND_REFLECTANCE " + AVERAGE_GROUND_REFLECTANCE.ToString () +
" multipleScattering " + multipleScattering.ToString () +
" fastPreviewMode " + fastPreviewMode.ToString ());
targetSkyNode.ApplyAtmoFromUI (m_betaR, BETA_MSca, m_mieG, HR, HM, AVERAGE_GROUND_REFLECTANCE, multipleScattering, fastPreviewMode, atmosphereStartRadiusScale, useOzone, ozoneAbsorption, ozoneHeight, ozoneFalloff);
}
public void loadSettingsForPlanet(int selectedPlanet)
{
if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].active)
{
targetSkyNode = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetSkyNode();
selPlanet = selectedPlanet;
Rg = targetSkyNode.Rg;
atmosphereStartRadiusScale = targetSkyNode.atmosphereStartRadiusScale;
HR = targetSkyNode.HR;
HM = targetSkyNode.HM;
m_betaR = targetSkyNode.m_betaR;
BETA_MSca = targetSkyNode.BETA_MSca;
m_mieG = targetSkyNode.m_mieG;
AVERAGE_GROUND_REFLECTANCE = targetSkyNode.averageGroundReflectance;
multipleScattering = targetSkyNode.multipleScattering;
ozoneAbsorption = targetSkyNode.ozoneAbsorption;
ozoneHeight = targetSkyNode.ozoneHeight;
ozoneFalloff = targetSkyNode.ozoneFalloff;
useOzone = targetSkyNode.useOzone;
fastPreviewMode = false;
rescale=1f;
thickenRayleigh=1f;
thickenMie=1f;
}
}
public void GUIvector3NoButton (string label, ref Vector3 target)
{
GUILayout.BeginHorizontal ();
GUILayout.Label (label);
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
GUILayout.Label ("R");
target.x = float.Parse(GUILayout.TextField(target.x.ToString()));
GUILayout.Label ("G");
target.y = float.Parse(GUILayout.TextField(target.y.ToString()));
GUILayout.Label ("B");
target.z = float.Parse (GUILayout.TextField (target.z.ToString()));
GUILayout.EndHorizontal ();
}
}
}
================================================
FILE: scatterer/GUI/ConfigPointGUI.cs
================================================
using System;
using UnityEngine;
namespace Scatterer
{
public class ConfigPointGUI
{
public int selectedConfigPoint = 0;
private Vector2 _scroll;
Vector3 sunColor=Vector3.one;
float rimBlend = 20f;
float rimpower = 600f;
float cloudColorMultiplier=1f;
float cloudScatteringMultiplier=1f;
float cloudSkyIrradianceMultiplier = 1f;
float volumetricsColorMultiplier=1f;
float godrayStrength = 1.0f;
// float godrayCloudAlphaThreshold = 0.1f;
float extinctionThickness = 1f;
float skyExtinctionTint = 1f;
float noonSunlightExtinctionStrength = 1f;
float specR = 0f, specG = 0f, specB = 0f, shininess = 0f, flattenScaledSpaceMesh = 0f;
//ConfigPoint variables
float pointAltitude = 0f;
float newCfgPtAlt = 0f;
int configPointsCnt;
float postProcessingalpha = 78f;
float postProcessDepth = 200f;
float extinctionTint=100f;
float postProcessExposure = 18f;
//sky properties
float exposure = 25f;
float alphaGlobal = 100f;
public ConfigPointGUI ()
{
}
public void DrawConfigPointGUI (int selectedPlanet)
{
configPointsCnt = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints.Count;
ConfigPoint _cur = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints [selectedConfigPoint];
//if (!MapView.MapIsEnabled)
{
GUILayout.BeginHorizontal ();
GUILayout.Label ("New point altitude:");
newCfgPtAlt = Convert.ToSingle (GUILayout.TextField (newCfgPtAlt.ToString ()));
if (GUILayout.Button ("Add")) {
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints.Insert (selectedConfigPoint + 1, new ConfigPoint (newCfgPtAlt, alphaGlobal / 100, exposure / 100, postProcessingalpha / 100, postProcessDepth / 10000, postProcessExposure / 100, skyExtinctionTint / 100, extinctionTint / 100, extinctionThickness));
selectedConfigPoint += 1;
configPointsCnt = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints.Count;
loadConfigPoint (selectedConfigPoint, selectedPlanet);
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
GUILayout.Label ("Config point:");
if (GUILayout.Button ("<")) {
if (selectedConfigPoint > 0) {
selectedConfigPoint -= 1;
loadConfigPoint (selectedConfigPoint, selectedPlanet);
}
}
GUILayout.TextField ((selectedConfigPoint).ToString ());
if (GUILayout.Button (">")) {
if (selectedConfigPoint < configPointsCnt - 1) {
selectedConfigPoint += 1;
loadConfigPoint (selectedConfigPoint, selectedPlanet);
}
}
//GUILayout.Label (String.Format("Total:{0}", configPointsCnt));
if (GUILayout.Button ("Delete")) {
if (configPointsCnt <= 1)
Debug.LogError ("Can't delete config point, one or no points remaining");
else {
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints.RemoveAt (selectedConfigPoint);
if (selectedConfigPoint >= configPointsCnt - 1) {
selectedConfigPoint = configPointsCnt - 2;
}
configPointsCnt = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints.Count;
loadConfigPoint (selectedConfigPoint, selectedPlanet);
}
}
GUILayout.EndHorizontal ();
GUIfloat ("Point altitude", ref pointAltitude, ref _cur.altitude);
_scroll = GUILayout.BeginScrollView (_scroll, false, true, GUILayout.Width (400), GUILayout.Height (Scatterer.Instance.pluginData.scrollSectionHeight));
GUILayout.Label ("(settings with a * are global and not cfgPoint dependent)");
GUILayout.Label ("Sky");
GUIfloat ("Sky Exposure", ref exposure, ref _cur.skyExposure);
GUIfloat ("Sky Alpha", ref alphaGlobal, ref _cur.skyAlpha);
GUIfloat ("Sky Extinction Tint", ref skyExtinctionTint, ref _cur.skyExtinctionTint);
GUILayout.Label ("Scattering and Extinction");
GUIfloat ("Scattering Exposure (scaled+local)", ref postProcessExposure, ref _cur.scatteringExposure);
GUIfloat ("Extinction Tint (scaled+local)", ref extinctionTint, ref _cur.extinctionTint);
GUIfloat ("Extinction Thickness (scaled+local)", ref extinctionThickness, ref _cur.extinctionThickness);
GUIfloat ("Noon Sunlight Extinction strength*", ref noonSunlightExtinctionStrength, ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies[selectedPlanet].prolandManager.skyNode.noonSunlightExtinctionStrength);
GUILayout.Label ("Post Processing");
GUIfloat ("Post Processing Alpha", ref postProcessingalpha, ref _cur.postProcessAlpha);
GUIfloat ("Post Processing Depth", ref postProcessDepth, ref _cur.postProcessDepth);
GUILayout.Label ("Godrays");
GUILayout.BeginHorizontal ();
GUILayout.Label ("Legacy Godrays strength*");
godrayStrength = Mathf.Min(float.Parse (GUILayout.TextField (godrayStrength.ToString ("0.000"))),1.0f);
if (GUILayout.Button ("Set")) {
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.godrayStrength = godrayStrength;
}
GUILayout.EndHorizontal ();
}
if (Scatterer.Instance.mainSettings.integrateWithEVEClouds && Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.usesCloudIntegration) {
GUILayout.Label ("EVE integration");
GUIfloat ("2d Cloud Color Multiplier*", ref cloudColorMultiplier, ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.cloudColorMultiplier);
GUIfloat ("2d Cloud Scattering Multiplier*", ref cloudScatteringMultiplier, ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.cloudScatteringMultiplier);
GUIfloat ("2d Cloud Sky irradiance Multiplier*", ref cloudSkyIrradianceMultiplier, ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.cloudSkyIrradianceMultiplier);
GUIfloat ("Particle Volumetrics Color Multiplier*", ref volumetricsColorMultiplier, ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.volumetricsColorMultiplier);
GUILayout.BeginHorizontal ();
GUILayout.Label ("Preserve 2d cloud colors*");
GUILayout.TextField (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.EVEIntegration_preserveCloudColors.ToString ());
if (GUILayout.Button ("Toggle"))
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.TogglePreserveCloudColors ();
GUILayout.EndHorizontal ();
// GUIfloat ("Godray alpha threshold* (alpha value above which a cloud casts a godray)", ref godrayCloudAlphaThreshold, ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.godrayCloudAlphaThreshold);
// GUIfloat("Volumetrics Scattering Multiplier", ref volumetricsScatteringMultiplier, ref Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.volumetricsScatteringMultiplier);
// GUIfloat("Volumetrics Sky irradiance Multiplier", ref volumetricsSkyIrradianceMultiplier, ref Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.volumetricsSkyIrradianceMultiplier);
}
GUILayout.Label ("ScaledSpace model");
GUILayout.BeginHorizontal ();
GUILayout.Label ("RimBlend*");
rimBlend = Convert.ToSingle (GUILayout.TextField (rimBlend.ToString ()));
GUILayout.Label ("RimPower*");
rimpower = Convert.ToSingle (GUILayout.TextField (rimpower.ToString ()));
if (GUILayout.Button ("Set")) {
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.rimBlend = rimBlend;
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.rimpower = rimpower;
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.TweakStockAtmosphere ();
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
GUILayout.Label ("Spec*: R");
specR = (float)(Convert.ToDouble (GUILayout.TextField (specR.ToString ())));
GUILayout.Label ("G");
specG = (float)(Convert.ToDouble (GUILayout.TextField (specG.ToString ())));
GUILayout.Label ("B");
specB = (float)(Convert.ToDouble (GUILayout.TextField (specB.ToString ())));
GUILayout.Label ("shine*");
shininess = (float)(Convert.ToDouble (GUILayout.TextField (shininess.ToString ())));
if (GUILayout.Button ("Set")) {
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.specR = specR;
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.specG = specG;
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.specB = specB;
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.shininess = shininess;
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.flattenScaledSpaceMesh = flattenScaledSpaceMesh;
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.TweakStockAtmosphere ();
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
GUILayout.Label ("Flatten scaled mesh");
flattenScaledSpaceMesh = (float)(Convert.ToDouble (GUILayout.TextField (flattenScaledSpaceMesh.ToString ("0.000"))));
if (GUILayout.Button ("Set")) {
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.flattenScaledSpaceMesh = flattenScaledSpaceMesh;
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.TweakScaledMesh();
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.scaledScatteringContainer.ApplyNewMesh(Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.parentScaledTransform.GetComponent ().sharedMesh);
}
GUILayout.EndHorizontal ();
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.adjustScaledTexture = GUILayout.Toggle (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.adjustScaledTexture, "Adjust scaled texture");
if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.adjustScaledTexture)
{
GUILayout.BeginHorizontal ();
GUILayout.Label ("Land (brightness/contrast/saturation)");
GUILayout.EndHorizontal ();
var node = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode;
GUILayout.BeginHorizontal ();
node.scaledLandBrightnessAdjust = (float)(Convert.ToDouble (GUILayout.TextField (node.scaledLandBrightnessAdjust.ToString ("0.00"))));
node.scaledLandContrastAdjust = (float)(Convert.ToDouble (GUILayout.TextField (node.scaledLandContrastAdjust.ToString ("0.00"))));
node.scaledLandSaturationAdjust = (float)(Convert.ToDouble (GUILayout.TextField (node.scaledLandSaturationAdjust.ToString ("0.00"))));
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
GUILayout.Label ("Ocean (brightness/contrast/saturation)");
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
node.scaledOceanBrightnessAdjust = (float)(Convert.ToDouble (GUILayout.TextField (node.scaledOceanBrightnessAdjust.ToString ("0.00"))));
node.scaledOceanContrastAdjust = (float)(Convert.ToDouble (GUILayout.TextField (node.scaledOceanContrastAdjust.ToString ("0.00"))));
node.scaledOceanSaturationAdjust = (float)(Convert.ToDouble (GUILayout.TextField (node.scaledOceanSaturationAdjust.ToString ("0.00"))));
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
if (GUILayout.Button ("Set")) {
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.TweakStockScaledTexture();
}
GUILayout.EndHorizontal ();
}
GUILayout.Label ("Misc");
GUIColorNoButton("Sunlight color "+ Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.mainSunLight.name+ " (Not saved automatically, save manually to PlanetsList)", ref Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.sunColor);
int index = 0;
foreach (SecondarySun secondarySun in Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.secondarySuns)
{
Vector4 colorVect = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.planetShineRGBMatrix.GetRow(index);
Color col = new Color(colorVect.x, colorVect.y, colorVect.z);
GUIColorNoButton("Secondary sunlight color "+secondarySun.config.celestialBodyName, ref col);
colorVect = new Vector4(col.r, col.g, col.b, colorVect.w);
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.planetShineRGBMatrix.SetRow(index, colorVect);
index++;
}
GUILayout.EndScrollView ();
GUILayout.BeginHorizontal ();
if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.currentConfigPoint == 0)
GUILayout.Label ("Current state:Lowest configPoint, cfgPoint 0");
else
if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.currentConfigPoint >= configPointsCnt)
GUILayout.Label (String.Format ("Current state:Highest configPoint, cfgPoint{0}", Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.currentConfigPoint - 1));
else
GUILayout.Label (String.Format ("Current state:{0}% cfgPoint{1} + {2}% cfgPoint{3} ", (int)(100 * (1 - Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.percentage)), Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.currentConfigPoint - 1, (int)(100 * Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.percentage), Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.currentConfigPoint));
GUILayout.EndHorizontal ();
// GUILayout.BeginHorizontal ();
// if (GUILayout.Button ("toggle sky"))
// {
// Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.skyEnabled = !Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.skyEnabled;
// if (Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.skyEnabled)
// Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.tweakStockAtmosphere();
// else
// Core.Instance.planetsListReader.scattererCelestialBodies [selectedPlanet].prolandManager.m_skyNode.RestoreStockAtmosphere();
// }
// GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
if (!Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.isConfigModuleManagerPatch)
{
if (GUILayout.Button ("Save atmo"))
{
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.SaveToConfigNode ();
}
}
if (GUILayout.Button ("Load atmo")) {
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.LoadFromConfigNode ();
getSettingsFromSkynode (selectedPlanet);
loadConfigPoint (selectedConfigPoint, selectedPlanet);
//Restore sun color, hacky I know
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.sunColor = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.scattererCelestialBody.sunColor;
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
GUILayout.Label (".cfg file used:");
GUIStyle guiStyle = new GUIStyle(GUI.skin.textArea);
if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.isConfigModuleManagerPatch)
guiStyle.normal.textColor = Color.red;
GUILayout.TextField (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.isConfigModuleManagerPatch ? "ModuleManager patch detected, saving disabled" : Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configUrl.parent.url, guiStyle);
GUILayout.EndHorizontal ();
}
public void loadSettingsForPlanet(int selectedPlanet)
{
selectedConfigPoint = 0;
if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].active)
{
loadConfigPoint (selectedConfigPoint, selectedPlanet);
getSettingsFromSkynode (selectedPlanet);
}
}
public void getSettingsFromSkynode (int selectedPlanet)
{
SkyNode skyNode = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode;
ConfigPoint selected = skyNode.configPoints [selectedConfigPoint];
postProcessingalpha = selected.postProcessAlpha;
postProcessDepth = selected.postProcessDepth;
extinctionTint = selected.extinctionTint;
postProcessExposure = selected.scatteringExposure;
exposure = selected.skyExposure;
alphaGlobal = selected.skyAlpha;
configPointsCnt = skyNode.configPoints.Count;
specR = skyNode.specR;
specG = skyNode.specG;
specB = skyNode.specB;
shininess = skyNode.shininess;
flattenScaledSpaceMesh = skyNode.flattenScaledSpaceMesh;
rimBlend = skyNode.rimBlend;
rimpower = skyNode.rimpower;
skyExtinctionTint = selected.skyExtinctionTint;
extinctionThickness = selected.extinctionThickness;
cloudColorMultiplier = skyNode.cloudColorMultiplier;
cloudScatteringMultiplier = skyNode.cloudScatteringMultiplier;
cloudSkyIrradianceMultiplier = skyNode.cloudSkyIrradianceMultiplier;
volumetricsColorMultiplier = skyNode.volumetricsColorMultiplier;
// volumetricsScatteringMultiplier = skyNode.volumetricsScatteringMultiplier;
// volumetricsSkyIrradianceMultiplier = skyNode.volumetricsSkyIrradianceMultiplier;
godrayStrength = skyNode.godrayStrength;
// godrayCloudAlphaThreshold = skyNode.godrayCloudAlphaThreshold;
}
public void loadConfigPoint (int point, int selectedPlanet)
{
ConfigPoint _cur = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.configPoints [point];
postProcessDepth = _cur.postProcessDepth;
extinctionTint = _cur.extinctionTint;
postProcessExposure = _cur.scatteringExposure;
postProcessingalpha = _cur.postProcessAlpha;
alphaGlobal = _cur.skyAlpha;
exposure = _cur.skyExposure;
skyExtinctionTint = _cur.skyExtinctionTint;
extinctionThickness = _cur.extinctionThickness;
pointAltitude = _cur.altitude;
}
public void GUIfloat (string label, ref float local, ref float target)
{
GUILayout.BeginHorizontal ();
GUILayout.Label (label);
local = float.Parse (GUILayout.TextField (local.ToString ()));
if (GUILayout.Button ("Set")) {
target = local;
}
GUILayout.EndHorizontal ();
}
public void GUIColorNoButton (string label, ref Color target)
{
GUILayout.BeginHorizontal ();
GUILayout.Label (label);
target.r = float.Parse (GUILayout.TextField (target.r.ToString ()));
target.g = float.Parse (GUILayout.TextField (target.g.ToString ()));
target.b = float.Parse (GUILayout.TextField (target.b.ToString ()));
GUILayout.EndHorizontal ();
}
}
}
================================================
FILE: scatterer/GUI/GUIhandler.cs
================================================
using System;
using UnityEngine;
namespace Scatterer
{
public class GUIhandler: MonoBehaviour
{
public Rect windowRect = new Rect (0, 0, 400, 50);
public int windowId;
public bool visible = false;
public bool mainOptions=false;
public bool sunflareOptions=false;
public int selectedPlanet = 0;
bool wireFrame = false;
enum PlanetSettingsTabs
{
Atmo,
Ocean,
ConfigPoints,
}
PlanetSettingsTabs selectedPlanetSettingsTab = PlanetSettingsTabs.Atmo;
MainOptionsGUI mainOptionsGUI = new MainOptionsGUI();
ConfigPointGUI configPointGUI = new ConfigPointGUI ();
AtmoGUI atmoGUI = new AtmoGUI ();
OceanGUI oceanGUI = new OceanGUI ();
SunflareGUI sunflareGUI = new SunflareGUI ();
public GUIhandler ()
{
}
public void Init()
{
windowId = UnityEngine.Random.Range(int.MinValue, int.MaxValue);
mainOptions = (HighLogic.LoadedScene == GameScenes.SPACECENTER);
windowRect.x=Scatterer.Instance.pluginData.inGameWindowLocation.x;
windowRect.y=Scatterer.Instance.pluginData.inGameWindowLocation.y;
//prevent window from going offscreen, only do this on start as otherwise it messes with lower resolutions
windowRect.x = Mathf.Clamp(windowRect.x, 0, Screen.width - windowRect.width);
windowRect.y = Mathf.Clamp(windowRect.y, 0, Screen.height - windowRect.height);
}
public void UpdateGUIvisible()
{
if ((Input.GetKey (Scatterer.Instance.pluginData.guiModifierKey1) || Input.GetKey (Scatterer.Instance.pluginData.guiModifierKey2)) && (Input.GetKeyDown (Scatterer.Instance.pluginData.guiKey1) || (Input.GetKeyDown (Scatterer.Instance.pluginData.guiKey2))))
{
if (ToolbarButton.Instance.button!= null)
{
if (visible)
ToolbarButton.Instance.button.SetFalse(false);
else
ToolbarButton.Instance.button.SetTrue(false);
}
visible = !visible;
}
}
public void DrawGui()
{
if (visible)
{
windowRect = GUILayout.Window (windowId, windowRect, DrawScattererWindow,"Scatterer v"+Scatterer.Instance.versionNumber+": "
+ Scatterer.Instance.pluginData.guiModifierKey1String+"/"+Scatterer.Instance.pluginData.guiModifierKey2String +"+" +Scatterer.Instance.pluginData.guiKey1String
+"/"+Scatterer.Instance.pluginData.guiKey2String+" toggle");
}
}
public void DrawScattererWindow (int windowId)
{
if (mainOptions)
{
mainOptionsGUI.DrawOptionsMenu ();
}
else if (Scatterer.Instance.isActive)
{
GUILayout.BeginHorizontal ();
if (GUILayout.Button ("Planet settings"))
{
windowRect.width = 400;
windowRect.height = 40;
sunflareOptions = false;
}
if (Scatterer.Instance.mainSettings.fullLensFlareReplacement && Scatterer.Instance.sunflareManager && Scatterer.Instance.sunflareManager.scattererSunFlares != null)
{
if (GUILayout.Button ("Sunflare settings"))
{
windowRect.width = 400;
windowRect.height = 40;
sunflareGUI.InitSunflareGUI();
sunflareOptions = true;
}
}
GUILayout.EndHorizontal ();
if (sunflareOptions)
{
sunflareGUI.DrawSunflareGUI();
}
else
{
DrawPlanetSelectionHeader ();
if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].active)
{
GUILayout.BeginHorizontal ();
if (GUILayout.Button("Atmosphere"))
{
windowRect.width = 300;
windowRect.height = 40;
selectedPlanetSettingsTab = PlanetSettingsTabs.Atmo;
}
if (GUILayout.Button("Ocean") && Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies[selectedPlanet].hasOcean)
{
windowRect.width = 400;
windowRect.height = 40;
selectedPlanetSettingsTab = PlanetSettingsTabs.Ocean;
}
if (GUILayout.Button ("Config points"))
{
windowRect.width = 400;
windowRect.height = 40;
selectedPlanetSettingsTab = PlanetSettingsTabs.ConfigPoints;
}
GUILayout.EndHorizontal ();
if (selectedPlanetSettingsTab == PlanetSettingsTabs.ConfigPoints)
{
configPointGUI.DrawConfigPointGUI(selectedPlanet);
}
else if (selectedPlanetSettingsTab == PlanetSettingsTabs.Atmo)
{
atmoGUI.drawAtmoGUI (selectedPlanet);
}
else
{
oceanGUI.drawOceanGUI (selectedPlanet);
}
}
DrawSharedFooterGUI ();
}
}
else
{
GUILayout.Label (String.Format ("Inactive in tracking station and VAB/SPH"));
GUILayout.EndHorizontal ();
}
GUI.DragWindow();
}
//move the getSettings, loadConfigPoint, selectedConfigPoint = 0; to method in ConfigPoint GUI
void DrawPlanetSelectionHeader ()
{
GUILayout.BeginHorizontal ();
GUILayout.Label ("Planet:");
if (GUILayout.Button ("<"))
{
if (selectedPlanet > 0)
{
selectedPlanet -= 1;
configPointGUI.loadSettingsForPlanet(selectedPlanet);
atmoGUI.loadSettingsForPlanet(selectedPlanet);
if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].active && Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].hasOcean)
{
oceanGUI.buildOceanGUI (selectedPlanet);
}
}
}
GUILayout.TextField ((Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].celestialBodyName).ToString ());
if (GUILayout.Button (">")) {
if (selectedPlanet < Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies.Count - 1) {
selectedPlanet += 1;
configPointGUI.loadSettingsForPlanet(selectedPlanet);
atmoGUI.loadSettingsForPlanet(selectedPlanet);
if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].active && Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].hasOcean)
{
oceanGUI.buildOceanGUI (selectedPlanet);
}
}
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
GUILayout.Label ("Loaded:" + Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].active.ToString () + ". Has ocean:" + Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].hasOcean.ToString ());
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
GUILayout.Label ("Load distance:" + Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].loadDistance.ToString () + ". Unload distance:" + Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].unloadDistance.ToString ());
GUILayout.EndHorizontal ();
}
void DrawSharedFooterGUI ()
{
if (Scatterer.Instance.mainSettings.integrateWithEVEClouds)
{
GUILayout.BeginHorizontal();
if (GUILayout.Button("Map EVE clouds"))
{
Scatterer.Instance.eveReflectionHandler.MapEVEClouds();
foreach (ScattererCelestialBody _cel in Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies)
{
if (_cel.active)
{
_cel.prolandManager.skyNode.InitEVEClouds();
}
}
}
GUILayout.EndHorizontal();
}
GUILayout.BeginHorizontal();
if (GUILayout.Button ("Toggle WireFrame")) {
if (wireFrame) {
if (HighLogic.LoadedScene != GameScenes.TRACKSTATION) {
if (Scatterer.Instance.nearCamera.gameObject.GetComponent (typeof(Wireframe)))
Component.Destroy (Scatterer.Instance.nearCamera.gameObject.GetComponent (typeof(Wireframe)));
if (Scatterer.Instance.farCamera && Scatterer.Instance.farCamera.gameObject.GetComponent (typeof(Wireframe)))
Component.Destroy (Scatterer.Instance.farCamera.gameObject.GetComponent (typeof(Wireframe)));
}
if (Scatterer.Instance.scaledSpaceCamera.gameObject.GetComponent (typeof(Wireframe)))
Component.Destroy (Scatterer.Instance.scaledSpaceCamera.gameObject.GetComponent (typeof(Wireframe)));
wireFrame = false;
}
else {
if (HighLogic.LoadedScene != GameScenes.TRACKSTATION) {
Scatterer.Instance.nearCamera.gameObject.AddComponent (typeof(Wireframe));
if (Scatterer.Instance.farCamera)
Scatterer.Instance.farCamera.gameObject.AddComponent (typeof(Wireframe));
}
Scatterer.Instance.scaledSpaceCamera.gameObject.AddComponent (typeof(Wireframe));
wireFrame = true;
}
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
if (GUILayout.Button ("Reload shader bundles")) {
ShaderReplacer.Instance.LoadAssetBundle ();
}
GUILayout.EndHorizontal ();
}
public void LoadPlanet(int planetIndex)
{
selectedPlanetSettingsTab = PlanetSettingsTabs.Atmo;
selectedPlanet = planetIndex;
configPointGUI.loadSettingsForPlanet (selectedPlanet);
atmoGUI.loadSettingsForPlanet(selectedPlanet);
if (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode())
{
oceanGUI.buildOceanGUI (planetIndex);
}
}
}
}
================================================
FILE: scatterer/GUI/MainOptionsGUI.cs
================================================
using System;
using System.Linq;
using UnityEngine;
namespace Scatterer
{
public class MainOptionsGUI
{
enum MainMenuTabs
{
QualityPresets,
IndividualSettings
}
enum IndividualSettingsTabs
{
Scattering,
Ocean,
Sunflare,
Lighting,
Shadows,
EVEintegration,
Misc
}
MainMenuTabs selectedMainMenuTab = MainMenuTabs.QualityPresets;
IndividualSettingsTabs selectedIndividualSettingsTab = IndividualSettingsTabs.Scattering;
String[] qualityPresetsStrings;
string currentPreset;
int selQualityPresetInt = -1;
public MainOptionsGUI ()
{
}
public void DrawOptionsMenu ()
{
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("Menu scroll section height");
Scatterer.Instance.pluginData.scrollSectionHeight = (Int32)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.pluginData.scrollSectionHeight.ToString ())));
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
{
GUILayout.Label (".cfg file used (display only):");
GUILayout.TextField (Scatterer.Instance.planetsConfigsReader.baseConfigs [0].parent.url);
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
{
if (GUILayout.Button ("Quality Presets"))
{
InitPresets();
selectedMainMenuTab = MainMenuTabs.QualityPresets;
}
if (GUILayout.Button ("Customize Settings"))
{
selectedMainMenuTab = MainMenuTabs.IndividualSettings;
}
}
GUILayout.EndHorizontal ();
if (selectedMainMenuTab == MainMenuTabs.QualityPresets)
{
DrawQualityPresets();
}
else
{
DrawIndividualSettings ();
}
}
void DrawQualityPresets ()
{
if (qualityPresetsStrings == null)
{
InitPresets();
}
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
{
GUILayout.Label("Current preset:");
GUILayout.TextField(currentPreset);
}
GUILayout.EndHorizontal();
selQualityPresetInt = GUILayout.SelectionGrid(selQualityPresetInt, qualityPresetsStrings, 1);
GUILayout.Label("");
if (GUILayout.Button("Apply preset"))
{
if (qualityPresetsStrings.Count() > 0)
{
Utils.LogInfo("Applying quality preset " + qualityPresetsStrings[selQualityPresetInt]);
QualityPresetsLoader.LoadPresetIntoMainSettings(Scatterer.Instance.mainSettings, qualityPresetsStrings[selQualityPresetInt]);
currentPreset = qualityPresetsStrings[selQualityPresetInt];
}
}
GUILayout.EndVertical();
}
private void InitPresets()
{
if (qualityPresetsStrings == null)
{
qualityPresetsStrings = QualityPresetsLoader.GetPresetsList();
}
currentPreset = QualityPresetsLoader.FindPresetOfCurrentSettings(Scatterer.Instance.mainSettings);
int index = qualityPresetsStrings.IndexOf(currentPreset);
selQualityPresetInt = index;
}
void DrawIndividualSettings ()
{
GUILayout.BeginHorizontal ();
{
if (GUILayout.Button ("Scattering")) {
selectedIndividualSettingsTab = IndividualSettingsTabs.Scattering;
}
if (GUILayout.Button ("Ocean")) {
selectedIndividualSettingsTab = IndividualSettingsTabs.Ocean;
}
if (GUILayout.Button ("Sunflare")) {
selectedIndividualSettingsTab = IndividualSettingsTabs.Sunflare;
}
if (GUILayout.Button ("Lighting")) {
selectedIndividualSettingsTab = IndividualSettingsTabs.Lighting;
}
if (GUILayout.Button ("Shadows")) {
selectedIndividualSettingsTab = IndividualSettingsTabs.Shadows;
}
if (GUILayout.Button ("EVE Clouds")) {
selectedIndividualSettingsTab = IndividualSettingsTabs.EVEintegration;
}
if (GUILayout.Button ("Misc.")) {
selectedIndividualSettingsTab = IndividualSettingsTabs.Misc;
}
}
GUILayout.EndHorizontal ();
if (selectedIndividualSettingsTab == IndividualSettingsTabs.Scattering)
{
Scatterer.Instance.mainSettings.useLegacyTerrainGodrays = GUILayout.Toggle(Scatterer.Instance.mainSettings.useLegacyTerrainGodrays, "Legacy terrain godrays (Requires long-distance shadows and shadowMapResolution override, Directx11 only)");
if (Scatterer.Instance.mainSettings.useLegacyTerrainGodrays)
{
//Godrays tesselation placeholder
}
//Scatterer.Instance.mainSettings.quarterResScattering = GUILayout.Toggle (Scatterer.Instance.mainSettings.quarterResScattering, "Render scattering in 1/4 resolution (speedup, incompatible and disabled with godrays)");
//Scatterer.Instance.mainSettings.mergeDepthPrePass = GUILayout.Toggle (Scatterer.Instance.mainSettings.mergeDepthPrePass, "Merge depth pre-pass into main depth for culling (experimental, may give small speedup but may cause z-fighting");
Scatterer.Instance.mainSettings.useTemporalAntiAliasing = GUILayout.Toggle(Scatterer.Instance.mainSettings.useTemporalAntiAliasing, "Temporal Antialiasing (TAA), can combine with SMAA");
if (Scatterer.Instance.mainSettings.useTemporalAntiAliasing)
{
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("Stationary blending");
Scatterer.Instance.mainSettings.taaStationaryBlending = Mathf.Clamp(float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.taaStationaryBlending.ToString("0.00"))),0f,0.99f);
GUILayout.Label(" Motion blending");
Scatterer.Instance.mainSettings.taaMotionBlending = Mathf.Clamp(float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.taaMotionBlending.ToString("0.00"))),0f,0.99f);
GUILayout.Label(" Sample spread");
Scatterer.Instance.mainSettings.taaJitterSpread = Mathf.Clamp(float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.taaJitterSpread.ToString("0.00"))),0.1f,1f);
GUILayout.Label(" Sharpness");
Scatterer.Instance.mainSettings.taaSharpness = Mathf.Clamp(float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.taaSharpness.ToString("0.00"))), 0f, 1f);
}
GUILayout.EndHorizontal();
}
GUILayout.BeginHorizontal();
GUILayout.Label("Disable TAA below framerate threshold (when SMAA is enabled)");
Scatterer.Instance.mainSettings.disableTaaBelowFrameRateThreshold = Convert.ToInt32(GUILayout.TextField(Scatterer.Instance.mainSettings.disableTaaBelowFrameRateThreshold.ToString()));
GUILayout.EndHorizontal();
Scatterer.Instance.mainSettings.useSubpixelMorphologicalAntialiasing = GUILayout.Toggle(Scatterer.Instance.mainSettings.useSubpixelMorphologicalAntialiasing, "Subpixel Morphological Antialiasing (SMAA), can combine with TAA");
if (Scatterer.Instance.mainSettings.useSubpixelMorphologicalAntialiasing)
{
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("SMAA quality (1:normal,2:high)");
Scatterer.Instance.mainSettings.smaaQuality = (Int32) Mathf.Clamp( (float)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.mainSettings.smaaQuality.ToString ()))),1f,2f);
}
GUILayout.EndHorizontal ();
}
GUILayout.BeginHorizontal ();
GUILayout.Label ("Tonemapper (0:disabled,1:bruneton,2:uncharted)");
Scatterer.Instance.mainSettings.scatteringTonemapper = (Int32) Mathf.Clamp( (float)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.mainSettings.scatteringTonemapper.ToString ()))),0f,2f);
GUILayout.EndHorizontal ();
/*
if (Scatterer.Instance.mainSettings.scatteringTonemapper == 3)
{
GUILayout.BeginHorizontal();
{
GUILayout.Label("Toe strength");
Scatterer.Instance.mainSettings.hableToeStrength =float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.hableToeStrength.ToString("0.00")));
GUILayout.Label("Toe length");
Scatterer.Instance.mainSettings.hableToeLength = float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.hableToeLength.ToString("0.00")));
GUILayout.Label("Shoulder strength");
Scatterer.Instance.mainSettings.hableShoulderStrength = float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.hableShoulderStrength.ToString("0.00")));
GUILayout.Label("Shoulder length");
Scatterer.Instance.mainSettings.hableShoulderLength = float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.hableShoulderLength.ToString("0.00")));
GUILayout.Label("Shoulder angle");
Scatterer.Instance.mainSettings.hableShoulderAngle = float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.hableShoulderAngle.ToString("0.00")));
GUILayout.Label("Gamma");
Scatterer.Instance.mainSettings.hableGamma = float.Parse(GUILayout.TextField(Scatterer.Instance.mainSettings.hableGamma.ToString("0.00")));
}
GUILayout.EndHorizontal();
}
*/
GUILayout.BeginHorizontal();
Scatterer.Instance.mainSettings.useLowResolutionAtmosphere = GUILayout.Toggle(Scatterer.Instance.mainSettings.useLowResolutionAtmosphere, "Use low resolution atmosphere (for slower machines that get white atmos)");
GUILayout.EndHorizontal();
}
else if (selectedIndividualSettingsTab == IndividualSettingsTabs.Ocean)
{
Scatterer.Instance.mainSettings.useOceanShaders = GUILayout.Toggle (Scatterer.Instance.mainSettings.useOceanShaders, "Ocean shaders");
if (Scatterer.Instance.mainSettings.useOceanShaders)
{
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("\t");
GUILayout.BeginVertical ();
{
GUILayout.BeginHorizontal ();
GUILayout.Label ("Fourier grid size (64:fast,128:normal,256:HQ)");
Scatterer.Instance.mainSettings.m_fourierGridSize = (Int32)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.mainSettings.m_fourierGridSize.ToString ())));
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
GUILayout.Label ("Mesh resolution (pixels covered by a mesh quad, lower is better but slower)");
Scatterer.Instance.mainSettings.oceanMeshResolution = (Int32)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.mainSettings.oceanMeshResolution.ToString ())));
GUILayout.EndHorizontal ();
Scatterer.Instance.mainSettings.oceanTransparencyAndRefractions = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanTransparencyAndRefractions, "Transparency and refractions");
Scatterer.Instance.mainSettings.oceanFoam = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanFoam, "Foam");
Scatterer.Instance.mainSettings.oceanSkyReflections = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanSkyReflections, "Sky reflections");
Scatterer.Instance.mainSettings.shadowsOnOcean = GUILayout.Toggle (Scatterer.Instance.mainSettings.shadowsOnOcean, "Surface receives shadows");
Scatterer.Instance.mainSettings.oceanPixelLights = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanPixelLights, "Secondary lights compatibility (huge performance hit when lights on)");
Scatterer.Instance.mainSettings.oceanCaustics = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanCaustics, "Underwater caustics");
Scatterer.Instance.mainSettings.oceanLightRays = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanLightRays, "Underwater light rays");
GUI.contentColor = SystemInfo.supportsAsyncGPUReadback && SystemInfo.supportsComputeShaders ? Color.white : Color.gray;
Scatterer.Instance.mainSettings.oceanCraftWaveInteractions = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions, "Waves interact with ships (Requires asyncGPU readback, Directx11 only)");
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractions) {
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("\t");
GUILayout.BeginVertical ();
{
Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideWaterCrashTolerance = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideWaterCrashTolerance, "Override water crash tolerance");
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideWaterCrashTolerance) {
GUILayout.BeginHorizontal ();
GUILayout.Label ("Crash tolerance (default is 1.2)");
Scatterer.Instance.mainSettings.buoyancyCrashToleranceMultOverride = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.buoyancyCrashToleranceMultOverride.ToString ("00.00")));
GUILayout.EndHorizontal ();
}
Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideDrag = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideDrag, "Override water drag");
Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideRecoveryVelocity = GUILayout.Toggle (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideRecoveryVelocity, "Override max water recovery velocity");
if (Scatterer.Instance.mainSettings.oceanCraftWaveInteractionsOverrideRecoveryVelocity) {
GUILayout.BeginHorizontal ();
GUILayout.Label ("Maximum recovery velocity (default is 0.3)");
Scatterer.Instance.mainSettings.waterMaxRecoveryVelocity = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.waterMaxRecoveryVelocity.ToString ("00.00")));
GUILayout.EndHorizontal ();
}
}
GUILayout.EndVertical ();
}
GUILayout.EndHorizontal ();
}
}
GUILayout.EndVertical ();
}
GUILayout.EndHorizontal ();
}
}
else if (selectedIndividualSettingsTab == IndividualSettingsTabs.Lighting)
{
Scatterer.Instance.mainSettings.useEclipses = GUILayout.Toggle (Scatterer.Instance.mainSettings.useEclipses, "Eclipses (WIP, sky/orbit only for now)");
Scatterer.Instance.mainSettings.useRingShadows = GUILayout.Toggle (Scatterer.Instance.mainSettings.useRingShadows, "Kopernicus ring shadows (linear only, tiled rings not supported)");
Scatterer.Instance.mainSettings.disableAmbientLight = GUILayout.Toggle (Scatterer.Instance.mainSettings.disableAmbientLight, "Disable scaled space ambient light");
Scatterer.Instance.mainSettings.sunlightExtinction = GUILayout.Toggle (Scatterer.Instance.mainSettings.sunlightExtinction, "Sunlight extinction (direct sun light changes color with sunset/dusk)");
Scatterer.Instance.mainSettings.underwaterLightDimming = GUILayout.Toggle (Scatterer.Instance.mainSettings.underwaterLightDimming, "Dim light underwater");
}
else if (selectedIndividualSettingsTab == IndividualSettingsTabs.Shadows)
{
Scatterer.Instance.mainSettings.d3d11ShadowFix = GUILayout.Toggle (Scatterer.Instance.mainSettings.d3d11ShadowFix, "1.9+ Directx11 flickering shadows fix (recommended for 1.9, 1.10)");
Scatterer.Instance.mainSettings.terrainShadows = GUILayout.Toggle (Scatterer.Instance.mainSettings.terrainShadows, "Long-Distance Terrain shadows");
if (Scatterer.Instance.mainSettings.terrainShadows)
{
GUILayout.BeginHorizontal ();
{
GUILayout.Label (" ");
GUILayout.BeginVertical ();
{
GUI.contentColor = Scatterer.Instance.unifiedCameraMode ? Color.white : Color.gray;
GUILayout.Label ((Scatterer.Instance.unifiedCameraMode ? "[Active] " : "[Inactive] ") + "Unified camera mode (1.9+ Directx11):");
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("\t");
GUILayout.BeginVertical ();
{
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("Shadows Distance (in meters):");
Scatterer.Instance.mainSettings.unifiedCamShadowsDistance = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.unifiedCamShadowsDistance.ToString ("0")));
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("Shadowmap resolution (power of 2, zero for no override):");
Scatterer.Instance.mainSettings.unifiedCamShadowResolutionOverride = (Int32)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.mainSettings.unifiedCamShadowResolutionOverride.ToString ())));
}
GUILayout.EndHorizontal ();
GUIvector3NoButton ("Shadow cascade splits (zeroes for no override):", ref Scatterer.Instance.mainSettings.unifiedCamShadowCascadeSplitsOverride);
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("Shadow bias (0 for no override)");
Scatterer.Instance.mainSettings.unifiedCamShadowBiasOverride = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.unifiedCamShadowBiasOverride.ToString ("0.000")));
GUILayout.Label ("Normal bias (0 for no override)");
Scatterer.Instance.mainSettings.unifiedCamShadowNormalBiasOverride = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.unifiedCamShadowNormalBiasOverride.ToString ("0.000")));
}
GUILayout.EndHorizontal ();
}
GUILayout.EndVertical ();
}
GUILayout.EndHorizontal ();
GUI.contentColor = !Scatterer.Instance.unifiedCameraMode ? Color.white : Color.gray;
GUILayout.Label ((!Scatterer.Instance.unifiedCameraMode ? "[Active] " : "[Inactive] ") + "Dual camera mode (1.8, 1.9 and 1.10 Opengl):");
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("\t");
GUILayout.BeginVertical ();
{
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("Shadows Distance (in meters):");
Scatterer.Instance.mainSettings.dualCamShadowsDistance = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.dualCamShadowsDistance.ToString ("0")));
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("Shadowmap resolution (power of 2, zero for no override):");
Scatterer.Instance.mainSettings.dualCamShadowResolutionOverride = (Int32)(Convert.ToInt32 (GUILayout.TextField (Scatterer.Instance.mainSettings.dualCamShadowResolutionOverride.ToString ())));
}
GUILayout.EndHorizontal ();
GUIvector3NoButton ("Shadow cascade splits (zeroes for no override):", ref Scatterer.Instance.mainSettings.dualCamShadowCascadeSplitsOverride);
GUILayout.BeginHorizontal ();
{
GUILayout.Label ("Shadow bias (0 for no override)");
Scatterer.Instance.mainSettings.dualCamShadowBiasOverride = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.dualCamShadowBiasOverride.ToString ("0.000")));
GUILayout.Label ("Normal bias (0 for no override)");
Scatterer.Instance.mainSettings.dualCamShadowNormalBiasOverride = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.dualCamShadowNormalBiasOverride.ToString ("0.000")));
}
GUILayout.EndHorizontal ();
}
GUILayout.EndVertical ();
}
GUILayout.EndHorizontal ();
GUILayout.EndVertical ();
}
GUILayout.EndHorizontal ();
}
}
}
else if (selectedIndividualSettingsTab == IndividualSettingsTabs.Sunflare)
{
Scatterer.Instance.mainSettings.fullLensFlareReplacement = GUILayout.Toggle (Scatterer.Instance.mainSettings.fullLensFlareReplacement, "Lens flare shader");
}
else if (selectedIndividualSettingsTab == IndividualSettingsTabs.EVEintegration)
{
Scatterer.Instance.mainSettings.integrateWithEVEClouds = GUILayout.Toggle (Scatterer.Instance.mainSettings.integrateWithEVEClouds, "Integrate effects with EVE clouds (may require restart)");
// if (Scatterer.Instance.mainSettings.integrateWithEVEClouds)
// {
// Scatterer.Instance.mainSettings.integrateEVECloudsGodrays = GUILayout.Toggle (Scatterer.Instance.mainSettings.integrateEVECloudsGodrays, "EVE clouds cast godrays (require godrays)");
// }
}
else if (selectedIndividualSettingsTab == IndividualSettingsTabs.Misc)
{
GUILayout.BeginHorizontal ();
{
Scatterer.Instance.mainSettings.overrideNearClipPlane = GUILayout.Toggle (Scatterer.Instance.mainSettings.overrideNearClipPlane, "Override Near ClipPlane (not recommended - restart on disable)");
Scatterer.Instance.mainSettings.nearClipPlane = float.Parse (GUILayout.TextField (Scatterer.Instance.mainSettings.nearClipPlane.ToString ("0.000")));
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
{
Scatterer.Instance.mainSettings.useDithering = GUILayout.Toggle (Scatterer.Instance.mainSettings.useDithering, "Use dithering (Reduces color banding in sky and scattering, disable if you notice dithering patterns");
}
GUILayout.EndHorizontal ();
}
}
public void GUIvector3NoButton (string label, ref Vector3 target)
{
GUILayout.BeginHorizontal ();
GUILayout.Label (label);
target.x = float.Parse (GUILayout.TextField (target.x.ToString ("0.0000")));
target.y = float.Parse (GUILayout.TextField (target.y.ToString ("0.0000")));
target.z = float.Parse (GUILayout.TextField (target.z.ToString ("0.0000")));
GUILayout.EndHorizontal ();
}
}
}
================================================
FILE: scatterer/GUI/ModularGUI/AbstractGUIModule.cs
================================================
//Generic GUIModule, to be overriden by concrete classes that provide their own implementation of RenderGUI
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using UnityEngine;
namespace Scatterer
{
public abstract class AbstractGUIModule
{
static protected BindingFlags Flags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
public AbstractGUIModule ()
{
}
public abstract void RenderGUI ();
}
}
================================================
FILE: scatterer/GUI/ModularGUI/GUIModuleBool.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using UnityEngine;
namespace Scatterer
{
public class GUIModuleBool : AbstractGUIModule
{
bool localVariable = false;
string label = "";
object targetObject;
FieldInfo targetField;
public GUIModuleBool (string label, object targetObject, string fieldName)
{
this.label = label;
this.targetObject = targetObject;
Type targetType = targetObject.GetType ();
this.targetField = targetType.GetField(fieldName, Flags);
this.localVariable = (bool) targetField.GetValue(targetObject);
}
public override void RenderGUI()
{
GUILayout.BeginHorizontal ();
GUILayout.Label (label);
GUILayout.TextField (targetField.GetValue(targetObject).ToString ());
if (GUILayout.Button ("Toggle"))
{
targetField.SetValue(targetObject, !(bool)targetField.GetValue(targetObject));
}
GUILayout.EndHorizontal ();
}
}
}
================================================
FILE: scatterer/GUI/ModularGUI/GUIModuleFloat.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using UnityEngine;
namespace Scatterer
{
public class GUIModuleFloat : AbstractGUIModule
{
float localVariable = 0f;
string label = "";
object targetObject;
FieldInfo targetField;
public GUIModuleFloat (string label, object targetObject, string fieldName)
{
this.label = label;
this.targetObject = targetObject;
Type targetType = targetObject.GetType ();
this.targetField = targetType.GetField(fieldName, Flags);
this.localVariable = (float) targetField.GetValue(targetObject);
}
public override void RenderGUI()
{
GUILayout.BeginHorizontal ();
GUILayout.Label (label);
localVariable = float.Parse (GUILayout.TextField (localVariable.ToString ()));
if (GUILayout.Button ("Set"))
{
targetField.SetValue(targetObject, localVariable);
}
GUILayout.EndHorizontal ();
}
}
}
================================================
FILE: scatterer/GUI/ModularGUI/GUIModuleInt.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using UnityEngine;
namespace Scatterer
{
public class GUIModuleInt : AbstractGUIModule
{
int localVariable = 0;
string label = "";
object targetObject;
FieldInfo targetField;
public GUIModuleInt (string label, object targetObject, string fieldName)
{
this.label = label;
this.targetObject = targetObject;
Type targetType = targetObject.GetType ();
this.targetField = targetType.GetField(fieldName, Flags);
this.localVariable = (int) targetField.GetValue(targetObject);
}
public override void RenderGUI()
{
GUILayout.BeginHorizontal ();
GUILayout.Label (label);
localVariable = (Int32)(Convert.ToInt32 (GUILayout.TextField (localVariable.ToString ())));
if (GUILayout.Button ("Set"))
{
targetField.SetValue(targetObject, localVariable);
}
GUILayout.EndHorizontal ();
}
}
}
================================================
FILE: scatterer/GUI/ModularGUI/GUIModuleLabel.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using UnityEngine;
namespace Scatterer
{
public class GUIModuleLabel : AbstractGUIModule
{
string label = "";
public GUIModuleLabel (string label)
{
this.label = label;
}
public override void RenderGUI()
{
GUILayout.BeginHorizontal ();
GUILayout.Label (label);
GUILayout.EndHorizontal ();
}
}
}
================================================
FILE: scatterer/GUI/ModularGUI/GUIModuleString.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using UnityEngine;
namespace Scatterer
{
public class GUIModuleString : AbstractGUIModule
{
string localVariable = "";
string label = "";
object targetObject;
FieldInfo targetField;
public GUIModuleString (string label, object targetObject, string fieldName)
{
this.label = label;
this.targetObject = targetObject;
Type targetType = targetObject.GetType ();
this.targetField = targetType.GetField(fieldName, Flags);
this.localVariable = (string) targetField.GetValue(targetObject);
}
public override void RenderGUI()
{
GUILayout.BeginHorizontal ();
GUILayout.Label (label);
localVariable = GUILayout.TextField (localVariable);
if (GUILayout.Button ("Set"))
{
targetField.SetValue(targetObject, localVariable);
}
GUILayout.EndHorizontal ();
}
}
}
================================================
FILE: scatterer/GUI/ModularGUI/GUIModuleVector2.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using UnityEngine;
namespace Scatterer
{
public class GUIModuleVector2 : AbstractGUIModule
{
Vector2 localVariable = new Vector2(0f,0f);
string label = "";
object targetObject;
FieldInfo targetField;
public GUIModuleVector2 (string label, object targetObject, string fieldName)
{
this.label = label;
this.targetObject = targetObject;
Type targetType = targetObject.GetType ();
this.targetField = targetType.GetField(fieldName, Flags);
this.localVariable = (Vector2) targetField.GetValue(targetObject);
}
public override void RenderGUI()
{
GUILayout.BeginHorizontal ();
GUILayout.Label (label);
localVariable.x = float.Parse (GUILayout.TextField (localVariable.x.ToString ()));
localVariable.y = float.Parse (GUILayout.TextField (localVariable.y.ToString ()));
if (GUILayout.Button ("Set"))
{
targetField.SetValue(targetObject, localVariable);
}
GUILayout.EndHorizontal ();
}
}
}
================================================
FILE: scatterer/GUI/ModularGUI/GUIModuleVector3.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using UnityEngine;
namespace Scatterer
{
public class GUIModuleVector3 : AbstractGUIModule
{
Vector3 localVariable = new Vector3(0f,0f,0f);
string label = "";
object targetObject;
FieldInfo targetField;
public GUIModuleVector3 (string label, object targetObject, string fieldName)
{
this.label = label;
this.targetObject = targetObject;
Type targetType = targetObject.GetType ();
this.targetField = targetType.GetField(fieldName, Flags);
this.localVariable = (Vector3) targetField.GetValue(targetObject);
}
public override void RenderGUI()
{
GUILayout.BeginHorizontal ();
GUILayout.Label (label);
localVariable.x = float.Parse (GUILayout.TextField (localVariable.x.ToString ()));
localVariable.y = float.Parse (GUILayout.TextField (localVariable.y.ToString ()));
localVariable.z = float.Parse (GUILayout.TextField (localVariable.z.ToString ()));
if (GUILayout.Button ("Set"))
{
targetField.SetValue(targetObject, localVariable);
}
GUILayout.EndHorizontal ();
}
}
}
================================================
FILE: scatterer/GUI/ModularGUI/GUIModuleVector4.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using UnityEngine;
namespace Scatterer
{
public class GUIModuleVector4 : AbstractGUIModule
{
Vector4 localVariable = new Vector4(0f,0f,0f,0f);
string label = "";
object targetObject;
FieldInfo targetField;
public GUIModuleVector4 (string label, object targetObject, string fieldName)
{
this.label = label;
this.targetObject = targetObject;
Type targetType = targetObject.GetType ();
this.targetField = targetType.GetField(fieldName, Flags);
this.localVariable = (Vector4) targetField.GetValue(targetObject);
}
public override void RenderGUI()
{
GUILayout.BeginHorizontal ();
GUILayout.Label (label);
localVariable.x = float.Parse (GUILayout.TextField (localVariable.x.ToString ()));
localVariable.y = float.Parse (GUILayout.TextField (localVariable.y.ToString ()));
localVariable.z = float.Parse (GUILayout.TextField (localVariable.z.ToString ()));
localVariable.w = float.Parse (GUILayout.TextField (localVariable.w.ToString ()));
if (GUILayout.Button ("Set"))
{
targetField.SetValue(targetObject, localVariable);
}
GUILayout.EndHorizontal ();
}
}
}
================================================
FILE: scatterer/GUI/ModularGUI/ModularGUI.cs
================================================
//A modular gui class to simplify writing a GUI
//Define the gui once and have render everything
//Submodules can be used to access and modify private fields of the main types, and hold their own local variables so I don't have to juggle them
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using UnityEngine;
namespace Scatterer
{
public class ModularGUI
{
List Modules = new List();
public ModularGUI ()
{
}
public void RenderGUI()
{
foreach (AbstractGUIModule module in Modules)
{
module.RenderGUI();
}
}
public void AddModule(AbstractGUIModule module)
{
this.Modules.Add (module);
}
public void ClearModules()
{
Modules.Clear ();
}
}
}
================================================
FILE: scatterer/GUI/OceanGUI.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using KSP;
using KSP.IO;
using UnityEngine;
namespace Scatterer
{
public class OceanGUI
{
ModularGUI oceanModularGUI = new ModularGUI();
private Vector2 _scroll;
public OceanGUI ()
{
}
public void buildOceanGUI(int selectedPlanet)
{
OceanFFTgpu oceanNode = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode ();
oceanModularGUI.ClearModules ();
oceanModularGUI.AddModule(new GUIModuleLabel("To apply press \"rebuild ocean\" and wait"));
oceanModularGUI.AddModule(new GUIModuleLabel("Keep in mind this saves your current settings"));
oceanModularGUI.AddModule(new GUIModuleLabel(""));
oceanModularGUI.AddModule(new GUIModuleLabel("Waves physical model settings"));
oceanModularGUI.AddModule(new GUIModuleFloat("Wave amplitude (AMP)", oceanNode, "AMP"));
oceanModularGUI.AddModule(new GUIModuleFloat("Wind Speed (m/s)", oceanNode, "m_windSpeed"));
oceanModularGUI.AddModule(new GUIModuleFloat("Omega (inverse wave age)", oceanNode, "m_omega"));
oceanModularGUI.AddModule(new GUIModuleFloat("Gravity (m/s², set to 0 for auto)", oceanNode, "m_gravity"));
oceanModularGUI.AddModule(new GUIModuleFloat("Off screen vertex coverage (Increase with big waves)", oceanNode, "offScreenVertexStretch"));
oceanModularGUI.AddModule(new GUIModuleLabel(""));
oceanModularGUI.AddModule (new GUIModuleLabel ("Surface shading settings"));
oceanModularGUI.AddModule(new GUIModuleVector3("Ocean Upwelling Color", oceanNode, "m_oceanUpwellingColor"));
oceanModularGUI.AddModule(new GUIModuleFloat("Transparency Depth", oceanNode, "transparencyDepth"));
oceanModularGUI.AddModule(new GUIModuleFloat("Foam strength (m_whiteCapStr)", oceanNode, "m_whiteCapStr"));
oceanModularGUI.AddModule(new GUIModuleFloat("Shore/shallow foam strength", oceanNode, "shoreFoam"));
oceanModularGUI.AddModule(new GUIModuleFloat("Far foam strength (m_farWhiteCapStr)", oceanNode, "m_farWhiteCapStr"));
oceanModularGUI.AddModule(new GUIModuleFloat("Far foam strength radius (alphaRadius)", oceanNode, "alphaRadius"));
oceanModularGUI.AddModule(new GUIModuleFloat("Sky reflection strength", oceanNode, "skyReflectionStrength"));
oceanModularGUI.AddModule(new GUIModuleLabel(""));
oceanModularGUI.AddModule (new GUIModuleLabel ("Underwater shading Settings"));
oceanModularGUI.AddModule(new GUIModuleFloat("Refraction Index", oceanNode, "refractionIndex"));
oceanModularGUI.AddModule(new GUIModuleFloat("Darkness Depth", oceanNode, "darknessDepth"));
oceanModularGUI.AddModule(new GUIModuleVector3("Ocean Underwater Color", oceanNode, "m_UnderwaterColor"));
if (Scatterer.Instance.mainSettings.oceanCaustics || Scatterer.Instance.mainSettings.oceanLightRays)
{
oceanModularGUI.AddModule(new GUIModuleLabel(""));
oceanModularGUI.AddModule(new GUIModuleLabel("Caustics/lightrays Settings"));
oceanModularGUI.AddModule (new GUIModuleString ("Caustics texture path", oceanNode, "causticsTexturePath"));
oceanModularGUI.AddModule (new GUIModuleVector2 ("Caustics layer 1 scale", oceanNode, "causticsLayer1Scale"));
oceanModularGUI.AddModule (new GUIModuleVector2 ("caustics layer 1 speed", oceanNode, "causticsLayer1Speed"));
oceanModularGUI.AddModule (new GUIModuleVector2 ("Caustics Layer 2 scale", oceanNode, "causticsLayer2Scale"));
oceanModularGUI.AddModule (new GUIModuleVector2 ("caustics Layer 2 speed", oceanNode, "causticsLayer2Speed"));
oceanModularGUI.AddModule (new GUIModuleFloat ("Caustics texture multiply", oceanNode, "causticsMultiply"));
oceanModularGUI.AddModule (new GUIModuleFloat ("Caustics underwater light boost", oceanNode, "causticsUnderwaterLightBoost"));
oceanModularGUI.AddModule (new GUIModuleFloat ("Caustics minimum brightness (of dark areas in the caustics texture)", oceanNode, "causticsMinBrightness"));
oceanModularGUI.AddModule (new GUIModuleFloat ("Caustics blur depth", oceanNode, "causticsBlurDepth"));
oceanModularGUI.AddModule (new GUIModuleFloat ("Light rays strength", oceanNode, "lightRaysStrength"));
}
oceanModularGUI.AddModule(new GUIModuleLabel(""));
oceanModularGUI.AddModule (new GUIModuleLabel ("Performance settings"));
oceanModularGUI.AddModule (new GUIModuleLabel ("Current fourierGridSize (change from KSC menu): " + Scatterer.Instance.mainSettings.m_fourierGridSize.ToString ()));
oceanModularGUI.AddModule (new GUIModuleLabel ("Current mesh resolution (change from KSC menu): " + Scatterer.Instance.mainSettings.oceanMeshResolution.ToString ()));
}
public void drawOceanGUI (int selectedPlanet)
{
OceanFFTgpu oceanNode = Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode ();
//GUItoggle("Toggle ocean", ref stockOcean);
_scroll = GUILayout.BeginScrollView (_scroll, false, true, GUILayout.Width (400), GUILayout.Height (Scatterer.Instance.pluginData.scrollSectionHeight + 100));
{
oceanModularGUI.RenderGUI();
}
GUILayout.EndScrollView ();
GUILayout.BeginHorizontal ();
if (GUILayout.Button ("Apply settings/Rebuild ocean")) {
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode ().saveToConfigNode ();
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.reBuildOcean ();
buildOceanGUI(selectedPlanet);
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
if (!Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.skyNode.isConfigModuleManagerPatch)
{
if (GUILayout.Button ("Save ocean"))
{
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode ().saveToConfigNode ();
}
}
if (GUILayout.Button ("Load ocean")) {
Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode ().loadFromConfigNode ();
buildOceanGUI (selectedPlanet);
}
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal ();
GUILayout.Label (".cfg file used:");
GUILayout.TextField (Scatterer.Instance.planetsConfigsReader.scattererCelestialBodies [selectedPlanet].prolandManager.GetOceanNode ().configUrl.parent.url);
GUILayout.EndHorizontal ();
}
}
}
================================================
FILE: scatterer/GUI/SunflareGUI.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime;
using KSP;
using KSP.IO;
using UnityEngine;
namespace Scatterer
{
public class SunflareGUI
{
String[] sunflareStrings;
int selSunflareGridInt = 0;
private Vector2 sunflareListScrollPosition = new Vector2();
bool editingSunflare = false;
string sunflareText = "";
private Vector2 sunflareEditScrollPosition = new Vector2();
public SunflareGUI ()
{
}
public void InitSunflareGUI()
{
sunflareStrings = new string[Scatterer.Instance.sunflareManager.scattererSunFlares.Count];
for (int i=0; i
latest
C:\Program Files\Unity2019.2\Editor\Data\Tools\RoslynScripts
unity_csc.bat
Debug
AnyCPU
10.0.20506
2.0
{1BA7E86D-23C1-619A-C471-A2388FCC27DA}
Library
Properties
Assembly-CSharp-Editor
v4.7.1
512
.
true
full
false
Temp\bin\Debug\
DEBUG;TRACE;UNITY_2019_2_21;UNITY_2019_2;UNITY_2019;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;INCLUDE_DYNAMIC_GI;ENABLE_MONO_BDWGC;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_4_6;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER
prompt
4
0169
False
pdbonly
true
Temp\bin\Release\
prompt
4
0169
False
true
true
false
false
false
C:\Program Files\Unity2019.2\Editor\Data\Managed/UnityEngine/UnityEngine.dll
C:\Program Files\Unity2019.2\Editor\Data\Managed/UnityEditor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.TestRunner.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.TestRunner.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.VSCode.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.UI.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.CollabProxy.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Rider.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.UI.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AndroidJNIModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.DSPGraphModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.FileSystemHttpModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.InputLegacyModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.LocalizationModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ProfilerModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.StreamingModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TextCoreModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityTestProtocolModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VFXModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll
C:/Program Files/Unity2019.2/Editor/Data/UnityExtensions/Unity/UnityVR/Editor/UnityEditor.VR.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEditor.Graphs.dll
C:/Program Files/Unity2019.2/Editor/Data/PlaybackEngines/WindowsStandaloneSupport/UnityEditor.WindowsStandalone.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/PlaybackEngines/WebGLSupport/UnityEditor.WebGL.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/PlaybackEngines/MacStandaloneSupport/UnityEditor.OSXStandalone.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/PlaybackEngines/LinuxStandaloneSupport/UnityEditor.LinuxStandalone.Extensions.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.0/net35/unity-custom/nunit.framework.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Core.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Runtime.Serialization.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.Linq.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.Vectors.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Net.Http.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Microsoft.CSharp.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Data.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/Microsoft.Win32.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/netstandard.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.AppContext.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Concurrent.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.NonGeneric.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Specialized.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Annotations.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.EventBasedAsync.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.TypeConverter.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Console.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Data.Common.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Contracts.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Debug.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.FileVersionInfo.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.StackTrace.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TextWriterTraceListener.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Tools.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TraceSource.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Drawing.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Dynamic.Runtime.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Calendars.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Compression.ZipFile.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.DriveInfo.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Watcher.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.IsolatedStorage.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.MemoryMappedFiles.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Pipes.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.UnmanagedMemoryStream.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Expressions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Parallel.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Queryable.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Http.Rtc.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NameResolution.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NetworkInformation.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Ping.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Requests.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Security.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Sockets.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebHeaderCollection.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.Client.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ObjectModel.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.ILGeneration.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.Lightweight.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Reader.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.ResourceManager.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Writer.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.CompilerServices.VisualC.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Handles.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.RuntimeInformation.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.WindowsRuntime.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Numerics.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Formatters.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Json.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Xml.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Claims.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Algorithms.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Csp.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Encoding.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.X509Certificates.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Principal.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.SecureString.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Duplex.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Http.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.NetTcp.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Security.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.RegularExpressions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Overlapped.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.Parallel.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Thread.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.ThreadPool.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Timer.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ValueTuple.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.ReaderWriter.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XDocument.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlDocument.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlSerializer.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.XDocument.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.Lang.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/Boo.Lang.dll
{87622294-0BFC-2C93-A2E6-774E6D27C210}
Assembly-CSharp
================================================
FILE: scatterer/OldShaders/scattererShaders/Assembly-CSharp-Editor.csproj.orig
================================================
latest
C:\Program Files\Unity2019.4\Editor\Data\Tools\RoslynScripts
unity_csc.bat
Debug
AnyCPU
10.0.20506
2.0
{1BA7E86D-23C1-619A-C471-A2388FCC27DA}
Library
Properties
Assembly-CSharp-Editor
v4.7.1
512
.
true
full
false
Temp\bin\Debug\
<<<<<<< HEAD
DEBUG;TRACE;UNITY_2019_4_18;UNITY_2019_4;UNITY_2019;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AR;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_EVENT_QUEUE;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;INCLUDE_DYNAMIC_GI;ENABLE_MONO_BDWGC;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;PLATFORM_STANDALONE;PLATFORM_STANDALONE_WIN;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;GFXDEVICE_WAITFOREVENT_MESSAGEPUMP;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_4_6;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;UNITY_POST_PROCESSING_STACK_V2;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER
=======
DEBUG;TRACE;UNITY_2019_2_21;UNITY_2019_2;UNITY_2019;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;INCLUDE_DYNAMIC_GI;ENABLE_MONO_BDWGC;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_4_6;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;UNITY_POST_PROCESSING_STACK_V2;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER
>>>>>>> parent of d91e357... Revert "Experiments with blending + eclipse raymarching, stashed for later"
prompt
4
0169
False
pdbonly
true
Temp\bin\Release\
prompt
4
0169
False
true
true
false
false
false
C:\Program Files\Unity2019.4\Editor\Data\Managed/UnityEngine/UnityEngine.dll
C:\Program Files\Unity2019.4\Editor\Data\Managed/UnityEditor.dll
<<<<<<< HEAD
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.dll
=======
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.TestRunner.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.TestRunner.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.VSCode.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.UI.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.CollabProxy.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Rider.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.UI.dll
>>>>>>> parent of d91e357... Revert "Experiments with blending + eclipse raymarching, stashed for later"
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.AndroidJNIModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.DSPGraphModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.InputLegacyModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.LocalizationModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ProfilerModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.StreamingModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.SubsystemsModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.TextCoreModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityTestProtocolModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.VFXModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEditor.dll
C:/Program Files/Unity2019.4/Editor/Data/UnityExtensions/Unity/UnityVR/Editor/UnityEditor.VR.dll
C:/Program Files/Unity2019.4/Editor/Data/Managed/UnityEditor.Graphs.dll
C:/Program Files/Unity2019.4/Editor/Data/PlaybackEngines/WindowsStandaloneSupport/UnityEditor.WindowsStandalone.Extensions.dll
C:/Program Files/Unity2019.4/Editor/Data/PlaybackEngines/WebGLSupport/UnityEditor.WebGL.Extensions.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/PackageCache/com.unity.ext.nunit@1.0.6/net35/unity-custom/nunit.framework.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Core.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Runtime.Serialization.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.Linq.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.Vectors.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Net.Http.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Microsoft.CSharp.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Data.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/Microsoft.Win32.Primitives.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/netstandard.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.AppContext.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Concurrent.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.NonGeneric.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Specialized.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Annotations.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.EventBasedAsync.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Primitives.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.TypeConverter.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Console.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Data.Common.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Contracts.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Debug.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.FileVersionInfo.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.StackTrace.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TextWriterTraceListener.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Tools.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TraceSource.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Drawing.Primitives.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Dynamic.Runtime.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Calendars.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Extensions.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Compression.ZipFile.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.DriveInfo.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Primitives.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Watcher.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.IsolatedStorage.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.MemoryMappedFiles.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Pipes.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.UnmanagedMemoryStream.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Expressions.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Parallel.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Queryable.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Http.Rtc.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NameResolution.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NetworkInformation.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Ping.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Primitives.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Requests.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Security.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Sockets.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebHeaderCollection.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.Client.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ObjectModel.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.ILGeneration.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.Lightweight.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Extensions.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Primitives.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Reader.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.ResourceManager.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Writer.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.CompilerServices.VisualC.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Extensions.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Handles.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.RuntimeInformation.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.WindowsRuntime.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Numerics.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Formatters.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Json.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Primitives.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Xml.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Claims.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Algorithms.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Csp.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Encoding.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Primitives.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.X509Certificates.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Principal.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.SecureString.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Duplex.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Http.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.NetTcp.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Primitives.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Security.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.Extensions.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.RegularExpressions.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Overlapped.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.Parallel.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Thread.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.ThreadPool.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Timer.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ValueTuple.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.ReaderWriter.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XDocument.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlDocument.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlSerializer.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.XDocument.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.Lang.dll
C:/Program Files/Unity2019.4/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/Boo.Lang.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.TestRunner.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.TestRunner.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.VSCode.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.UI.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.CollabProxy.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Rider.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.UI.dll
{87622294-0BFC-2C93-A2E6-774E6D27C210}
Assembly-CSharp
================================================
FILE: scatterer/OldShaders/scattererShaders/Assembly-CSharp.csproj
================================================
latest
C:\Program Files\Unity2019.2\Editor\Data\Tools\RoslynScripts
unity_csc.bat
Debug
AnyCPU
10.0.20506
2.0
{87622294-0BFC-2C93-A2E6-774E6D27C210}
Library
Properties
Assembly-CSharp
v4.7.1
512
.
true
full
false
Temp\bin\Debug\
DEBUG;TRACE;UNITY_2019_2_21;UNITY_2019_2;UNITY_2019;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;INCLUDE_DYNAMIC_GI;ENABLE_MONO_BDWGC;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_STANDARD_2_0;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;UNITY_POST_PROCESSING_STACK_V2;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER
prompt
4
0169
False
pdbonly
true
Temp\bin\Release\
prompt
4
0169
False
true
true
false
false
false
C:\Program Files\Unity2019.2\Editor\Data\Managed/UnityEngine/UnityEngine.dll
C:\Program Files\Unity2019.2\Editor\Data\Managed/UnityEditor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.VSCode.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.UI.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.CollabProxy.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Rider.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.UI.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AndroidJNIModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.DSPGraphModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.FileSystemHttpModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.InputLegacyModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.LocalizationModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ProfilerModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.StreamingModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TextCoreModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityTestProtocolModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VFXModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Core.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Runtime.Serialization.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.Linq.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.Vectors.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Net.Http.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Microsoft.CSharp.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Data.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/Microsoft.Win32.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/netstandard.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.AppContext.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Concurrent.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.NonGeneric.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Specialized.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Annotations.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.EventBasedAsync.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.TypeConverter.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Console.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Data.Common.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Contracts.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Debug.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.FileVersionInfo.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.StackTrace.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TextWriterTraceListener.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Tools.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TraceSource.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Drawing.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Dynamic.Runtime.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Calendars.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Compression.ZipFile.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.DriveInfo.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Watcher.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.IsolatedStorage.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.MemoryMappedFiles.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Pipes.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.UnmanagedMemoryStream.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Expressions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Parallel.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Queryable.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Http.Rtc.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NameResolution.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NetworkInformation.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Ping.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Requests.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Security.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Sockets.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebHeaderCollection.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.Client.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ObjectModel.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.ILGeneration.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.Lightweight.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Reader.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.ResourceManager.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Writer.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.CompilerServices.VisualC.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Handles.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.RuntimeInformation.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.WindowsRuntime.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Numerics.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Formatters.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Json.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Xml.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Claims.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Algorithms.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Csp.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Encoding.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.X509Certificates.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Principal.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.SecureString.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Duplex.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Http.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.NetTcp.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Security.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.RegularExpressions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Overlapped.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.Parallel.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Thread.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.ThreadPool.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Timer.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ValueTuple.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.ReaderWriter.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XDocument.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlDocument.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlSerializer.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.XDocument.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.Lang.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/Boo.Lang.dll
================================================
FILE: scatterer/OldShaders/scattererShaders/Assembly-CSharp.csproj.orig
================================================
latest
C:\Program Files\Unity2019.2\Editor\Data\Tools\RoslynScripts
unity_csc.bat
Debug
AnyCPU
10.0.20506
2.0
{87622294-0BFC-2C93-A2E6-774E6D27C210}
Library
Properties
Assembly-CSharp
v4.7.1
512
.
true
full
false
Temp\bin\Debug\
DEBUG;TRACE;UNITY_2019_2_21;UNITY_2019_2;UNITY_2019;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_INCLUDE_TESTS;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;INCLUDE_DYNAMIC_GI;ENABLE_MONO_BDWGC;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_STANDARD_2_0;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;UNITY_POST_PROCESSING_STACK_V2;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER
prompt
4
0169
False
pdbonly
true
Temp\bin\Release\
prompt
4
0169
False
true
true
false
false
false
C:\Program Files\Unity2019.2\Editor\Data\Managed/UnityEngine/UnityEngine.dll
C:\Program Files\Unity2019.2\Editor\Data\Managed/UnityEditor.dll
<<<<<<< HEAD
=======
>>>>>>> c935259... split into individual maps, is slower, therefore I think the compiler optimizes 1-2 channel accesses
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.VSCode.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEngine.UI.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Timeline.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.CollabProxy.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.Rider.Editor.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/Unity.TextMeshPro.dll
C:/gh/scattererGithub/Scatterer/scatterer/Shaders/scattererShaders/Library/ScriptAssemblies/UnityEditor.UI.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AndroidJNIModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.DSPGraphModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.FileSystemHttpModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.InputLegacyModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.LocalizationModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ProfilerModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.StreamingModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TextCoreModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityTestProtocolModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VFXModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll
C:/Program Files/Unity2019.2/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Core.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Runtime.Serialization.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.Linq.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.Vectors.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Net.Http.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Microsoft.CSharp.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Data.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/Microsoft.Win32.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/netstandard.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.AppContext.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Concurrent.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.NonGeneric.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Specialized.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Annotations.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.EventBasedAsync.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.TypeConverter.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Console.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Data.Common.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Contracts.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Debug.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.FileVersionInfo.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.StackTrace.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TextWriterTraceListener.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Tools.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TraceSource.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Drawing.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Dynamic.Runtime.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Calendars.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Compression.ZipFile.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.DriveInfo.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Watcher.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.IsolatedStorage.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.MemoryMappedFiles.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Pipes.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.UnmanagedMemoryStream.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Expressions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Parallel.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Queryable.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Http.Rtc.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NameResolution.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NetworkInformation.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Ping.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Requests.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Security.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Sockets.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebHeaderCollection.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.Client.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ObjectModel.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.ILGeneration.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.Lightweight.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Reader.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.ResourceManager.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Writer.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.CompilerServices.VisualC.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Handles.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.RuntimeInformation.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.WindowsRuntime.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Numerics.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Formatters.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Json.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Xml.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Claims.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Algorithms.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Csp.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Encoding.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.X509Certificates.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Principal.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.SecureString.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Duplex.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Http.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.NetTcp.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Primitives.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Security.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.Extensions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.RegularExpressions.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Overlapped.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.Parallel.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Thread.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.ThreadPool.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Timer.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ValueTuple.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.ReaderWriter.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XDocument.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlDocument.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlSerializer.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.XDocument.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.Lang.dll
C:/Program Files/Unity2019.2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/Boo.Lang.dll
================================================
FILE: scatterer/OldShaders/scattererShaders/Assembly-UnityScript.unityproj
================================================
Debug
AnyCPU
10.0.20506
2.0
{07FD5666-7B78-6483-21E2-6D1791113BE7}
Library
Properties
Assembly-UnityScript
v3.5
512
Assets
true
full
false
Temp\bin\Debug\
DEBUG;TRACE;UNITY_5_2_4;UNITY_5_2;UNITY_5;ENABLE_NEW_BUGREPORTER;ENABLE_2D_PHYSICS;ENABLE_4_6_FEATURES;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_DUCK_TYPING;ENABLE_FRAME_DEBUGGER;ENABLE_GENERICS;ENABLE_HOME_SCREEN;ENABLE_IMAGEEFFECTS;ENABLE_LIGHT_PROBES_LEGACY;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_PLUGIN_INSPECTOR;ENABLE_SHADOWS;ENABLE_SINGLE_INSTANCE_BUILD_SETTING;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_RAKNET;ENABLE_UNET;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_HUB;ENABLE_CLOUD_PROJECT_ID;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_METRICS;ENABLE_REFLECTION_BUFFERS;INCLUDE_DYNAMIC_GI;INCLUDE_GI;INCLUDE_IL2CPP;INCLUDE_DIRECTX12;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_LOCALIZATION;ENABLE_ANDROID_ATLAS_ETC1_COMPRESSION;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_SUBSTANCE;ENABLE_TEXTUREID_MAP;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_LOG_MIXED_STACKTRACE;ENABLE_UNITYWEBREQUEST;ENABLE_EVENT_QUEUE;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN
prompt
4
0169
pdbonly
true
Temp\bin\Release\
prompt
4
0169
E:/gh/Unity5/Editor/Data/Managed/UnityEngine.dll
E:/gh/Unity5/Editor/Data/Managed/UnityEditor.dll
E:/gh/Unity5/Editor/Data/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll
E:/gh/Unity5/Editor/Data/UnityExtensions/Unity/Networking/UnityEngine.Networking.dll
E:/gh/Unity5/Editor/Data/Managed/Mono.Cecil.dll
E:/gh/Unity5/Editor/Data/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.Xcode.dll
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/AssetBundles/AssetBundles.meta
================================================
fileFormatVersion: 2
guid: fb1eb8dd5509788428a96514cc36f0d0
timeCreated: 1520625575
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/AssetBundles.meta
================================================
fileFormatVersion: 2
guid: 5d4d7b45df12a6845beb7d6a034a41a2
folderAsset: yes
timeCreated: 1520623653
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Editor/ExportAssetBundle.cs
================================================
using UnityEditor;
using UnityEngine;
using System;
using System.Linq;
using System.IO;
using System.Collections;
namespace scattererShaders
{
public class CreateAssetBundles
{
[MenuItem ("Assets/Build AssetBundles for release")]
static void BuildAllAssetBundles ()
{
BuildTarget[] platforms = { BuildTarget.StandaloneWindows, BuildTarget.StandaloneOSX, BuildTarget.StandaloneLinux64 };
string[] platformExts = { "-windows", "-macosx", "-linux" };
BuildBundles(platforms, platformExts);
}
[MenuItem ("Assets/Build AssetBundles for local openGL")]
static void BuildOpenGL ()
{
BuildTarget[] platforms = {BuildTarget.StandaloneLinux64};
string[] platformExts = { "-linux"};
BuildBundles(platforms, platformExts);
}
[MenuItem ("Assets/Build AssetBundles for local dx11")]
static void BuildDx11 ()
{
BuildTarget[] platforms = {BuildTarget.StandaloneWindows};
string[] platformExts = { "-windows"};
BuildBundles(platforms, platformExts);
}
static void BuildBundles (BuildTarget[] platforms, string[] platformExts)
{
// Put the bundles in a folder called "AssetBundles"
//var outDir = "Assets/AssetBundles";
var outDir = "C:/Steam/steamapps/common/Kerbal Space Program/GameData/scatterer/shaders";
var outDir2 = "C:/Steam/steamapps/common/Kerbal Space Program 1.9/GameData/scatterer/shaders";
if (!Directory.Exists (outDir))
Directory.CreateDirectory (outDir);
if (!Directory.Exists (outDir2))
Directory.CreateDirectory (outDir2);
var opts = BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.ForceRebuildAssetBundle;
for (var i = 0; i < platforms.Length; ++i)
{
BuildPipeline.BuildAssetBundles(outDir, opts, platforms[i]);
var outFile = outDir + "/scatterershaders" + platformExts[i];
var outFile2 = outDir2 + "/scatterershaders" + platformExts[i];
FileUtil.ReplaceFile(outDir + "/scatterershaders", outFile);
FileUtil.ReplaceFile(outDir + "/scatterershaders", outFile2);
}
//cleanup
foreach (string file in Directory.GetFiles(outDir, "*.*").Where(item => (item.EndsWith(".meta") || item.EndsWith(".manifest"))))
{
File.Delete(file);
}
File.Delete (outDir + "/CompiledAssetBundles");
File.Delete(outDir+"/scatterershaders");
File.Delete(outDir+"/shaders");
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Editor/ExportAssetBundle.cs.meta
================================================
fileFormatVersion: 2
guid: 661266b8a30572e4fb9365bba3866896
timeCreated: 1474706063
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Editor/KSPCurveEditor.cs
================================================
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MuMech
{
public class KSPCurveEditor : EditorWindow
{
[MenuItem("KSP/Curve Editor")]
static void Init()
{
EditorWindow.GetWindow(typeof(KSPCurveEditor));
}
AnimationCurve curve = new AnimationCurve();
Vector2 scrollPos = new Vector2();
string textVersion;
List points = new List();
bool curveNeedsUpdate = false, textChanged = false;
float lastCurve = 0;
void OnGUI()
{
textChanged = false;
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true), GUILayout.Height(50));
EditorGUILayout.LabelField("Click curve to edit ->", GUILayout.ExpandWidth(false));
curve = EditorGUILayout.CurveField(curve, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
GUILayout.EndHorizontal();
string newT = EditorGUILayout.TextArea(textVersion, GUILayout.ExpandWidth(true), GUILayout.Height(100));
if (newT != textVersion)
{
textVersion = newT;
textChanged = true;
}
scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.BeginVertical();
GUILayout.Label("X", GUILayout.ExpandWidth(true));
foreach (FloatString4 p in points)
{
string ns = EditorGUILayout.TextField(p.strings[0]);
if (ns != p.strings[0])
{
p.strings[0] = ns;
p.UpdateFloats();
curveNeedsUpdate = true;
}
}
GUILayout.EndVertical();
GUILayout.BeginVertical();
GUILayout.Label("Y", GUILayout.ExpandWidth(true));
foreach (FloatString4 p in points)
{
string ns = EditorGUILayout.TextField(p.strings[1]);
if (ns != p.strings[1])
{
p.strings[1] = ns;
p.UpdateFloats();
curveNeedsUpdate = true;
}
}
GUILayout.EndVertical();
GUILayout.BeginVertical();
GUILayout.Label("Auto", GUILayout.ExpandWidth(true));
foreach (FloatString4 p in points)
{
bool a = EditorGUILayout.Toggle(p.twoMode);
if (a != p.twoMode)
{
p.twoMode = a;
curveNeedsUpdate = true;
}
}
GUILayout.EndVertical();
GUILayout.BeginVertical();
GUILayout.Label("In Tangent", GUILayout.ExpandWidth(true));
foreach (FloatString4 p in points)
{
if (!p.twoMode)
{
string ns = EditorGUILayout.TextField(p.strings[2]);
if (ns != p.strings[2])
{
p.strings[2] = ns;
p.UpdateFloats();
curveNeedsUpdate = true;
}
}
else
{
EditorGUILayout.TextField("");
}
}
GUILayout.EndVertical();
GUILayout.BeginVertical();
GUILayout.Label("Out Tangent", GUILayout.ExpandWidth(true));
foreach (FloatString4 p in points)
{
if (!p.twoMode)
{
string ns = EditorGUILayout.TextField(p.strings[3]);
if (ns != p.strings[3])
{
p.strings[3] = ns;
p.UpdateFloats();
curveNeedsUpdate = true;
}
}
else
{
EditorGUILayout.TextField("");
}
}
GUILayout.EndVertical();
GUILayout.EndHorizontal();
EditorGUILayout.EndScrollView();
}
static float HashAnimationCurve(AnimationCurve c)
{
float h = 0;
foreach (Keyframe k in c.keys)
{
h += k.time + k.value + k.inTangent + k.outTangent + k.tangentMode;
}
return h;
}
void Update()
{
if (textChanged)
{
StringToCurve(textVersion);
}
if (curveNeedsUpdate)
{
UpdateCurve();
}
float newCurve = HashAnimationCurve(curve);
if (lastCurve != newCurve)
{
points = new List();
for (int i = 0; i < curve.keys.Length; i++)
{
FloatString4 nv = new FloatString4(curve.keys[i].time, curve.keys[i].value, curve.keys[i].inTangent, curve.keys[i].outTangent, (curve.keys[i].tangentMode == 10));
nv.UpdateStrings();
points.Add(nv);
}
if (!textChanged)
{
textVersion = CurveToString();
}
lastCurve = newCurve;
}
}
string CurveToString()
{
string buff = "";
foreach (FloatString4 p in points)
{
if (p.twoMode)
{
buff += "key = " + p.floats.x + " " + p.floats.y + "\n";
}
else
{
buff += "key = " + p.floats.x + " " + p.floats.y + " " + p.floats.z + " " + p.floats.w + "\n";
}
}
return buff;
}
void StringToCurve(string data)
{
points = new List();
string[] lines = data.Split('\n');
foreach (string line in lines)
{
string[] pcs = line.Split(new char[] { '=', ' ' }, StringSplitOptions.RemoveEmptyEntries);
if ((pcs.Length >= 3) && (pcs[0] == "key"))
{
FloatString4 nv = new FloatString4();
if (pcs.Length >= 5)
{
nv.strings = new string[] { pcs[1], pcs[2], pcs[3], pcs[4] };
nv.twoMode = false;
}
else
{
nv.strings = new string[] { pcs[1], pcs[2], "0", "0" };
nv.twoMode = true;
}
nv.UpdateFloats();
points.Add(nv);
}
}
if (!textChanged)
{
textVersion = CurveToString();
}
curveNeedsUpdate = true;
}
void UpdateCurve()
{
points.Sort();
curve = new AnimationCurve();
foreach (FloatString4 v in points)
{
Keyframe k = new Keyframe(v.floats.x, v.floats.y, v.floats.z, v.floats.w);
if (v.twoMode)
{
k.tangentMode = 10;
}
else
{
k.tangentMode = 1;
}
curve.AddKey(k);
}
for (int i = 0; i < curve.keys.Length; i++)
{
if (points[i].twoMode)
{
curve.SmoothTangents(i, 0);
}
}
if (!textChanged)
{
textVersion = CurveToString();
}
lastCurve = HashAnimationCurve(curve);
curveNeedsUpdate = false;
}
}
public class FloatString4 : IComparable
{
public Vector4 floats;
public string[] strings;
public bool twoMode;
public int CompareTo(FloatString4 other)
{
if (other == null) return 1;
return floats.x.CompareTo(other.floats.x);
}
public FloatString4()
{
floats = new Vector4();
strings = new string[] { "0", "0", "0", "0" };
twoMode = false;
}
public FloatString4(float x, float y, float z = 0, float w = 0, bool twoMode = true)
{
floats = new Vector4(x, y, z, w);
this.twoMode = twoMode;
UpdateStrings();
}
public void UpdateFloats()
{
float x, y, z, w;
float.TryParse(strings[0], out x);
float.TryParse(strings[1], out y);
float.TryParse(strings[2], out z);
float.TryParse(strings[3], out w);
floats = new Vector4(x, y, z, w);
}
public void UpdateStrings()
{
strings = new string[] { floats.x.ToString(), floats.y.ToString(), floats.z.ToString(), floats.w.ToString() };
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Editor/KSPCurveEditor.cs.meta
================================================
fileFormatVersion: 2
guid: 63cd91d36b6b0e4479ef6e61ad4f6f9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Editor.meta
================================================
fileFormatVersion: 2
guid: 98bf0690f0c9686468d3866e3c0e5e45
folderAsset: yes
timeCreated: 1520625078
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/AreaTex.tga.meta
================================================
fileFormatVersion: 2
guid: b7c13973a7ed1444fb514d09b5e7e579
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 10
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 1
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 0
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 0
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: PS4
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/CustomTAA.shader
================================================
// Modified TAA shader to not blur out the scatterer ocean
Shader "Scatterer/TemporalAntialiasing" {
SubShader {
Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
Pass {
Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
Cull Off
ZTest Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
#pragma multi_compile CUSTOM_OCEAN_OFF CUSTOM_OCEAN_ON
sampler2D _ScreenColor;
float4 _ScreenColor_TexelSize;
sampler2D _HistoryTex;
sampler2D _CameraDepthTexture;
float4 _CameraDepthTexture_TexelSize;
sampler2D _CameraMotionVectorsTexture;
#if defined (CUSTOM_OCEAN_ON)
uniform sampler2D ScattererDepthCopy;
#endif
float2 _Jitter;
float4 _FinalBlendParameters; // x: static, y: dynamic, z: motion amplification
float _Sharpness;
// Constants
#define HALF_MAX 65504.0 // (2 - 2^-10) * 2^15
#define HALF_MAX_MINUS1 65472.0 // (2 - 2^-9) * 2^15
#define EPSILON 1.0e-4
#define PI 3.14159265359
#define TWO_PI 6.28318530718
#define FOUR_PI 12.56637061436
#define INV_PI 0.31830988618
#define INV_TWO_PI 0.15915494309
#define INV_FOUR_PI 0.07957747155
#define HALF_PI 1.57079632679
#define INV_HALF_PI 0.636619772367
#define FLT_EPSILON 1.192092896e-07 // Smallest positive number, such that 1.0 + FLT_EPSILON != 1.0
#define FLT_MIN 1.175494351e-38 // Minimum representable positive floating-point number
#define FLT_MAX 3.402823466e+38 // Maximum representable floating-point number
struct v2f
{
float4 pos : SV_POSITION;
float4 screenPos : TEXCOORD0;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.screenPos = ComputeScreenPos(o.pos);
return o;
}
float2 GetClosestFragment(float2 uv)
{
float2 k = _CameraDepthTexture_TexelSize.xy;
float4 neighborhood = float4(
tex2D(_CameraDepthTexture, uv - k).r,
tex2D(_CameraDepthTexture, uv + float2(k.x, -k.y)).r,
tex2D(_CameraDepthTexture, uv + float2(-k.x, k.y)).r,
tex2D(_CameraDepthTexture, uv + k).r
);
#if SHADER_API_D3D11
#define COMPARE_DEPTH(a, b) step(b, a)
#else
#define COMPARE_DEPTH(a, b) step(a, b)
#endif
float3 result = float3(0.0, 0.0, SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv));
result = lerp(result, float3(-1.0, -1.0, neighborhood.x), COMPARE_DEPTH(neighborhood.x, result.z));
result = lerp(result, float3( 1.0, -1.0, neighborhood.y), COMPARE_DEPTH(neighborhood.y, result.z));
result = lerp(result, float3(-1.0, 1.0, neighborhood.z), COMPARE_DEPTH(neighborhood.z, result.z));
result = lerp(result, float3( 1.0, 1.0, neighborhood.w), COMPARE_DEPTH(neighborhood.w, result.z));
return (uv + result.xy * k);
}
float3 Min3(float3 a, float3 b, float3 c)
{
return min(min(a, b), c);
}
float4 ClipToAABB(float4 color, float3 minimum, float3 maximum)
{
// Note: only clips towards aabb center (but fast!)
float3 center = 0.5 * (maximum + minimum);
float3 extents = 0.5 * (maximum - minimum);
// This is actually `distance`, however the keyword is reserved
float3 offset = color.rgb - center;
float3 ts = abs(extents / (offset + 0.0001));
float t = saturate(Min3(ts.x, ts.y, ts.z));
color.rgb = center + offset * t;
return color;
}
float4 Solve(float2 motion, float2 texcoord)
{
const float2 k = _ScreenColor_TexelSize.xy;
float2 uv = texcoord - _Jitter;
float4 color = tex2Dlod(_ScreenColor, float4(uv,0.0,0.0));
float4 topLeft = tex2D(_ScreenColor, (uv - k * 0.5));
float4 bottomRight = tex2D(_ScreenColor, (uv + k * 0.5));
float4 corners = 4.0 * (topLeft + bottomRight) - 2.0 * color;
// Sharpen output
color += (color - (corners * 0.166667)) * 2.718282 * _Sharpness;
color = clamp(color, 0.0, HALF_MAX_MINUS1);
// Tonemap color and history samples
float4 average = (corners + color) * 0.142857;
float4 history = tex2D(_HistoryTex, texcoord - motion);
float motionLength = length(motion);
float2 luma = float2(Luminance(average), Luminance(color));
//float nudge = 4.0 * abs(luma.x - luma.y);
float nudge = lerp(4.0, 0.25, saturate(motionLength * 100.0)) * abs(luma.x - luma.y);
float4 minimum = min(bottomRight, topLeft) - nudge;
float4 maximum = max(topLeft, bottomRight) + nudge;
// Clip history samples
history = ClipToAABB(history, minimum.xyz, maximum.xyz);
// Blend method
float weight = clamp(
lerp(_FinalBlendParameters.x, _FinalBlendParameters.y, motionLength * _FinalBlendParameters.z),
_FinalBlendParameters.y, _FinalBlendParameters.x
);
#if defined (CUSTOM_OCEAN_ON)
float oceanDepth = tex2Dlod(ScattererDepthCopy, float4(uv,0,0));
float zdepth = tex2Dlod(_CameraDepthTexture, float4(uv,0,0));
if (oceanDepth != zdepth)
{
weight*= 0.35; //seems to be the best of both worlds, still antialiases but doesn't blur the ocean much
}
#endif
color = lerp(color, history, weight);
color = clamp(color, 0.0, HALF_MAX_MINUS1);
return color;
}
float4 frag(v2f i) : SV_Target
{
float2 uv = i.screenPos.xy / i.screenPos.w;
#if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12
if (_ProjectionParams.x > 0) {uv.y = 1.0 - uv.y;}
#endif
float2 closest = GetClosestFragment(uv);
float2 motion = tex2Dlod(_CameraMotionVectorsTexture, float4(closest,0.0,0.0)).xy;
return Solve(motion, uv);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/CustomTAA.shader.meta
================================================
fileFormatVersion: 2
guid: ad09d3e70e7b09244b56b51e495a319c
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SMAA.cginc
================================================
// Ported to Unity & tweaked by Thomas Hourdel (thomas@hourdel.com)
//#include "Colors.hlsl"
/**
* Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com)
* Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com)
* Copyright (C) 2013 Belen Masia (bmasia@unizar.es)
* Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com)
* Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to
* do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. As clarification, there
* is no requirement that the copyright notice and permission be included in
* binary distributions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* _______ ___ ___ ___ ___
* / || \/ | / \ / \
* | (---- | \ / | / ^ \ / ^ \
* \ \ | |\/| | / /_\ \ / /_\ \
* ----) | | | | | / _____ \ / _____ \
* |_______/ |__| |__| /__/ \__\ /__/ \__\
*
* E N H A N C E D
* S U B P I X E L M O R P H O L O G I C A L A N T I A L I A S I N G
*
* http://www.iryoku.com/smaa/
*
* Hi, welcome aboard!
*
* Here you'll find instructions to get the shader up and running as fast as
* possible.
*
* IMPORTANTE NOTICE: when updating, remember to update both this file and the
* precomputed textures! They may change from version to version.
*
* The shader has three passes, chained together as follows:
*
* |input|------------------�
* v |
* [ SMAA*EdgeDetection ] |
* v |
* |edgesTex| |
* v |
* [ SMAABlendingWeightCalculation ] |
* v |
* |blendTex| |
* v |
* [ SMAANeighborhoodBlending ] <------�
* v
* |output|
*
* Note that each [pass] has its own vertex and pixel shader. Remember to use
* oversized triangles instead of quads to avoid overshading along the
* diagonal.
*
* You've three edge detection methods to choose from: luma, color or depth.
* They represent different quality/performance and anti-aliasing/sharpness
* tradeoffs, so our recommendation is for you to choose the one that best
* suits your particular scenario:
*
* - Depth edge detection is usually the fastest but it may miss some edges.
*
* - Luma edge detection is usually more expensive than depth edge detection,
* but catches visible edges that depth edge detection can miss.
*
* - Color edge detection is usually the most expensive one but catches
* chroma-only edges.
*
* For quickstarters: just use luma edge detection.
*
* The general advice is to not rush the integration process and ensure each
* step is done correctly (don't try to integrate SMAA T2x with predicated edge
* detection from the start!). Ok then, let's go!
*
* 1. The first step is to create two RGBA temporal render targets for holding
* |edgesTex| and |blendTex|.
*
* In DX10 or DX11, you can use a RG render target for the edges texture.
* In the case of NVIDIA GPUs, using RG render targets seems to actually be
* slower.
*
* On the Xbox 360, you can use the same render target for resolving both
* |edgesTex| and |blendTex|, as they aren't needed simultaneously.
*
* 2. Both temporal render targets |edgesTex| and |blendTex| must be cleared
* each frame. Do not forget to clear the alpha channel!
*
* 3. The next step is loading the two supporting precalculated textures,
* 'areaTex' and 'searchTex'. You'll find them in the 'Textures' folder as
* C++ headers, and also as regular DDS files. They'll be needed for the
* 'SMAABlendingWeightCalculation' pass.
*
* If you use the C++ headers, be sure to load them in the format specified
* inside of them.
*
* You can also compress 'areaTex' and 'searchTex' using BC5 and BC4
* respectively, if you have that option in your content processor pipeline.
* When compressing then, you get a non-perceptible quality decrease, and a
* marginal performance increase.
*
* 4. All samplers must be set to linear filtering and clamp.
*
* After you get the technique working, remember that 64-bit inputs have
* half-rate linear filtering on GCN.
*
* If SMAA is applied to 64-bit color buffers, switching to point filtering
* when accesing them will increase the performance. Search for
* 'SMAASamplePoint' to see which textures may benefit from point
* filtering, and where (which is basically the color input in the edge
* detection and resolve passes).
*
* 5. All texture reads and buffer writes must be non-sRGB, with the exception
* of the input read and the output write in
* 'SMAANeighborhoodBlending' (and only in this pass!). If sRGB reads in
* this last pass are not possible, the technique will work anyway, but
* will perform antialiasing in gamma space.
*
* IMPORTANT: for best results the input read for the color/luma edge
* detection should *NOT* be sRGB.
*
* 6. Before including SMAA.h you'll have to setup the render target metrics,
* the target and any optional configuration defines. Optionally you can
* use a preset.
*
* You have the following targets available:
* SMAA_HLSL_3
* SMAA_HLSL_4
* SMAA_HLSL_4_1
* SMAA_GLSL_3 *
* SMAA_GLSL_4 *
*
* * (See SMAA_INCLUDE_VS and SMAA_INCLUDE_PS below).
*
* And four presets:
* SMAA_PRESET_LOW (%60 of the quality)
* SMAA_PRESET_MEDIUM (%80 of the quality)
* SMAA_PRESET_HIGH (%95 of the quality)
* SMAA_PRESET_ULTRA (%99 of the quality)
*
* For example:
* #define SMAA_RT_METRICS float4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
* #define SMAA_HLSL_4
* #define SMAA_PRESET_HIGH
* #include "SMAA.h"
*
* Note that SMAA_RT_METRICS doesn't need to be a macro, it can be a
* uniform variable. The code is designed to minimize the impact of not
* using a constant value, but it is still better to hardcode it.
*
* Depending on how you encoded 'areaTex' and 'searchTex', you may have to
* add (and customize) the following defines before including SMAA.h:
* #define SMAA_AREATEX_SELECT(sample) sample.rg
* #define SMAA_SEARCHTEX_SELECT(sample) sample.r
*
* If your engine is already using porting macros, you can define
* SMAA_CUSTOM_SL, and define the porting functions by yourself.
*
* 7. Then, you'll have to setup the passes as indicated in the scheme above.
* You can take a look into SMAA.fx, to see how we did it for our demo.
* Checkout the function wrappers, you may want to copy-paste them!
*
* 8. It's recommended to validate the produced |edgesTex| and |blendTex|.
* You can use a screenshot from your engine to compare the |edgesTex|
* and |blendTex| produced inside of the engine with the results obtained
* with the reference demo.
*
* 9. After you get the last pass to work, it's time to optimize. You'll have
* to initialize a stencil buffer in the first pass (discard is already in
* the code), then mask execution by using it the second pass. The last
* pass should be executed in all pixels.
*
*
* After this point you can choose to enable predicated thresholding,
* temporal supersampling and motion blur integration:
*
* a) If you want to use predicated thresholding, take a look into
* SMAA_PREDICATION; you'll need to pass an extra texture in the edge
* detection pass.
*
* b) If you want to enable temporal supersampling (SMAA T2x):
*
* 1. The first step is to render using subpixel jitters. I won't go into
* detail, but it's as simple as moving each vertex position in the
* vertex shader, you can check how we do it in our DX10 demo.
*
* 2. Then, you must setup the temporal resolve. You may want to take a look
* into SMAAResolve for resolving 2x modes. After you get it working, you'll
* probably see ghosting everywhere. But fear not, you can enable the
* CryENGINE temporal reprojection by setting the SMAA_REPROJECTION macro.
* Check out SMAA_DECODE_VELOCITY if your velocity buffer is encoded.
*
* 3. The next step is to apply SMAA to each subpixel jittered frame, just as
* done for 1x.
*
* 4. At this point you should already have something usable, but for best
* results the proper area textures must be set depending on current jitter.
* For this, the parameter 'subsampleIndices' of
* 'SMAABlendingWeightCalculationPS' must be set as follows, for our T2x
* mode:
*
* @SUBSAMPLE_INDICES
*
* | S# | Camera Jitter | subsampleIndices |
* +----+------------------+---------------------+
* | 0 | ( 0.25, -0.25) | float4(1, 1, 1, 0) |
* | 1 | (-0.25, 0.25) | float4(2, 2, 2, 0) |
*
* These jitter positions assume a bottom-to-top y axis. S# stands for the
* sample number.
*
* More information about temporal supersampling here:
* http://iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf
*
* c) If you want to enable spatial multisampling (SMAA S2x):
*
* 1. The scene must be rendered using MSAA 2x. The MSAA 2x buffer must be
* created with:
* - DX10: see below (*)
* - DX10.1: D3D10_STANDARD_MULTISAMPLE_PATTERN or
* - DX11: D3D11_STANDARD_MULTISAMPLE_PATTERN
*
* This allows to ensure that the subsample order matches the table in
* @SUBSAMPLE_INDICES.
*
* (*) In the case of DX10, we refer the reader to:
* - SMAA::detectMSAAOrder and
* - SMAA::msaaReorder
*
* These functions allow to match the standard multisample patterns by
* detecting the subsample order for a specific GPU, and reordering
* them appropriately.
*
* 2. A shader must be run to output each subsample into a separate buffer
* (DX10 is required). You can use SMAASeparate for this purpose, or just do
* it in an existing pass (for example, in the tone mapping pass, which has
* the advantage of feeding tone mapped subsamples to SMAA, which will yield
* better results).
*
* 3. The full SMAA 1x pipeline must be run for each separated buffer, storing
* the results in the final buffer. The second run should alpha blend with
* the existing final buffer using a blending factor of 0.5.
* 'subsampleIndices' must be adjusted as in the SMAA T2x case (see point
* b).
*
* d) If you want to enable temporal supersampling on top of SMAA S2x
* (which actually is SMAA 4x):
*
* 1. SMAA 4x consists on temporally jittering SMAA S2x, so the first step is
* to calculate SMAA S2x for current frame. In this case, 'subsampleIndices'
* must be set as follows:
*
* | F# | S# | Camera Jitter | Net Jitter | subsampleIndices |
* +----+----+--------------------+-------------------+----------------------+
* | 0 | 0 | ( 0.125, 0.125) | ( 0.375, -0.125) | float4(5, 3, 1, 3) |
* | 0 | 1 | ( 0.125, 0.125) | (-0.125, 0.375) | float4(4, 6, 2, 3) |
* +----+----+--------------------+-------------------+----------------------+
* | 1 | 2 | (-0.125, -0.125) | ( 0.125, -0.375) | float4(3, 5, 1, 4) |
* | 1 | 3 | (-0.125, -0.125) | (-0.375, 0.125) | float4(6, 4, 2, 4) |
*
* These jitter positions assume a bottom-to-top y axis. F# stands for the
* frame number. S# stands for the sample number.
*
* 2. After calculating SMAA S2x for current frame (with the new subsample
* indices), previous frame must be reprojected as in SMAA T2x mode (see
* point b).
*
* e) If motion blur is used, you may want to do the edge detection pass
* together with motion blur. This has two advantages:
*
* 1. Pixels under heavy motion can be omitted from the edge detection process.
* For these pixels we can just store "no edge", as motion blur will take
* care of them.
* 2. The center pixel tap is reused.
*
* Note that in this case depth testing should be used instead of stenciling,
* as we have to write all the pixels in the motion blur pass.
*
* That's it!
*/
//-----------------------------------------------------------------------------
// SMAA Presets
/**
* Note that if you use one of these presets, the following configuration
* macros will be ignored if set in the "Configurable Defines" section.
*/
#if defined(SMAA_PRESET_LOW)
#define SMAA_THRESHOLD 0.15
#define SMAA_MAX_SEARCH_STEPS 4
#define SMAA_DISABLE_DIAG_DETECTION
#define SMAA_DISABLE_CORNER_DETECTION
#elif defined(SMAA_PRESET_MEDIUM)
#define SMAA_THRESHOLD 0.1
#define SMAA_MAX_SEARCH_STEPS 8
#define SMAA_DISABLE_DIAG_DETECTION
#define SMAA_DISABLE_CORNER_DETECTION
#elif defined(SMAA_PRESET_HIGH)
#define SMAA_THRESHOLD 0.1
#define SMAA_MAX_SEARCH_STEPS 16
#define SMAA_MAX_SEARCH_STEPS_DIAG 8
#define SMAA_CORNER_ROUNDING 25
#elif defined(SMAA_PRESET_ULTRA)
#define SMAA_THRESHOLD 0.05
#define SMAA_MAX_SEARCH_STEPS 32
#define SMAA_MAX_SEARCH_STEPS_DIAG 16
#define SMAA_CORNER_ROUNDING 25
#endif
//-----------------------------------------------------------------------------
// Configurable Defines
/**
* SMAA_THRESHOLD specifies the threshold or sensitivity to edges.
* Lowering this value you will be able to detect more edges at the expense of
* performance.
*
* Range: [0, 0.5]
* 0.1 is a reasonable value, and allows to catch most visible edges.
* 0.05 is a rather overkill value, that allows to catch 'em all.
*
* If temporal supersampling is used, 0.2 could be a reasonable value, as low
* contrast edges are properly filtered by just 2x.
*/
#ifndef SMAA_THRESHOLD
#define SMAA_THRESHOLD 0.1
#endif
/**
* SMAA_DEPTH_THRESHOLD specifies the threshold for depth edge detection.
*
* Range: depends on the depth range of the scene.
*/
#ifndef SMAA_DEPTH_THRESHOLD
#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD)
#endif
/**
* SMAA_MAX_SEARCH_STEPS specifies the maximum steps performed in the
* horizontal/vertical pattern searches, at each side of the pixel.
*
* In number of pixels, it's actually the double. So the maximum line length
* perfectly handled by, for example 16, is 64 (by perfectly, we meant that
* longer lines won't look as good, but still antialiased).
*
* Range: [0, 112]
*/
#ifndef SMAA_MAX_SEARCH_STEPS
#define SMAA_MAX_SEARCH_STEPS 16
#endif
/**
* SMAA_MAX_SEARCH_STEPS_DIAG specifies the maximum steps performed in the
* diagonal pattern searches, at each side of the pixel. In this case we jump
* one pixel at time, instead of two.
*
* Range: [0, 20]
*
* On high-end machines it is cheap (between a 0.8x and 0.9x slower for 16
* steps), but it can have a significant impact on older machines.
*
* Define SMAA_DISABLE_DIAG_DETECTION to disable diagonal processing.
*/
#ifndef SMAA_MAX_SEARCH_STEPS_DIAG
#define SMAA_MAX_SEARCH_STEPS_DIAG 8
#endif
/**
* SMAA_CORNER_ROUNDING specifies how much sharp corners will be rounded.
*
* Range: [0, 100]
*
* Define SMAA_DISABLE_CORNER_DETECTION to disable corner processing.
*/
#ifndef SMAA_CORNER_ROUNDING
#define SMAA_CORNER_ROUNDING 25
#endif
/**
* If there is an neighbor edge that has SMAA_LOCAL_CONTRAST_FACTOR times
* bigger contrast than current edge, current edge will be discarded.
*
* This allows to eliminate spurious crossing edges, and is based on the fact
* that, if there is too much contrast in a direction, that will hide
* perceptually contrast in the other neighbors.
*/
#ifndef SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR
#define SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR 2.0
#endif
/**
* Predicated thresholding allows to better preserve texture details and to
* improve performance, by decreasing the number of detected edges using an
* additional buffer like the light accumulation buffer, object ids or even the
* depth buffer (the depth buffer usage may be limited to indoor or short range
* scenes).
*
* It locally decreases the luma or color threshold if an edge is found in an
* additional buffer (so the global threshold can be higher).
*
* This method was developed by Playstation EDGE MLAA team, and used in
* Killzone 3, by using the light accumulation buffer. More information here:
* http://iryoku.com/aacourse/downloads/06-MLAA-on-PS3.pptx
*/
#ifndef SMAA_PREDICATION
#define SMAA_PREDICATION 0
#endif
/**
* Threshold to be used in the additional predication buffer.
*
* Range: depends on the input, so you'll have to find the magic number that
* works for you.
*/
#ifndef SMAA_PREDICATION_THRESHOLD
#define SMAA_PREDICATION_THRESHOLD 0.01
#endif
/**
* How much to scale the global threshold used for luma or color edge
* detection when using predication.
*
* Range: [1, 5]
*/
#ifndef SMAA_PREDICATION_SCALE
#define SMAA_PREDICATION_SCALE 2.0
#endif
/**
* How much to locally decrease the threshold.
*
* Range: [0, 1]
*/
#ifndef SMAA_PREDICATION_STRENGTH
#define SMAA_PREDICATION_STRENGTH 0.4
#endif
/**
* Temporal reprojection allows to remove ghosting artifacts when using
* temporal supersampling. We use the CryEngine 3 method which also introduces
* velocity weighting. This feature is of extreme importance for totally
* removing ghosting. More information here:
* http://iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf
*
* Note that you'll need to setup a velocity buffer for enabling reprojection.
* For static geometry, saving the previous depth buffer is a viable
* alternative.
*/
#ifndef SMAA_REPROJECTION
#define SMAA_REPROJECTION 0
#endif
/**
* Temporal reprojection allows to remove ghosting artifacts when using
* temporal supersampling. However, the default reprojection requires a velocity buffer
* in order to function properly.
*
* A velocity buffer might not always be available (hi Unity 5!). To handle such cases
* we provide a UV-based approximation for calculating motion vectors on the fly.
*/
#ifndef SMAA_UV_BASED_REPROJECTION
#define SMAA_UV_BASED_REPROJECTION 0
#endif
/**
* SMAA_REPROJECTION_WEIGHT_SCALE controls the velocity weighting. It allows to
* remove ghosting trails behind the moving object, which are not removed by
* just using reprojection. Using low values will exhibit ghosting, while using
* high values will disable temporal supersampling under motion.
*
* Behind the scenes, velocity weighting removes temporal supersampling when
* the velocity of the subsamples differs (meaning they are different objects).
*
* Range: [0, 80]
*/
#ifndef SMAA_REPROJECTION_WEIGHT_SCALE
#define SMAA_REPROJECTION_WEIGHT_SCALE 30.0
#endif
/**
* On some compilers, discard cannot be used in vertex shaders. Thus, they need
* to be compiled separately.
*/
#ifndef SMAA_INCLUDE_VS
#define SMAA_INCLUDE_VS 1
#endif
#ifndef SMAA_INCLUDE_PS
#define SMAA_INCLUDE_PS 1
#endif
//-----------------------------------------------------------------------------
// Texture Access Defines
#ifndef SMAA_AREATEX_SELECT
#if defined(SMAA_HLSL_3)
#define SMAA_AREATEX_SELECT(sample) sample.ra
#else
#define SMAA_AREATEX_SELECT(sample) sample.rg
#endif
#endif
#ifndef SMAA_SEARCHTEX_SELECT
#define SMAA_SEARCHTEX_SELECT(sample) sample.r
#endif
#ifndef SMAA_DECODE_VELOCITY
#define SMAA_DECODE_VELOCITY(sample) sample.rg
#endif
//-----------------------------------------------------------------------------
// Non-Configurable Defines
#define SMAA_AREATEX_MAX_DISTANCE 16
#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20
#define SMAA_AREATEX_PIXEL_SIZE (1.0 / float2(160.0, 560.0))
#define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0)
#define SMAA_SEARCHTEX_SIZE float2(66.0, 33.0)
#define SMAA_SEARCHTEX_PACKED_SIZE float2(64.0, 16.0)
#define SMAA_CORNER_ROUNDING_NORM (float(SMAA_CORNER_ROUNDING) / 100.0)
//-----------------------------------------------------------------------------
// Porting Functions
#if defined(SMAA_HLSL_3)
#define SMAATexture2D(tex) sampler2D tex
#define SMAATexturePass2D(tex) tex
#define SMAASampleLevelZero(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0))
#define SMAASampleLevelZeroPoint(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0))
#define SMAASampleLevelZeroOffset(tex, coord, offset) tex2Dlod(tex, float4(coord + offset * SMAA_RT_METRICS.xy, 0.0, 0.0))
#define SMAASample(tex, coord) tex2D(tex, coord)
#define SMAASamplePoint(tex, coord) tex2D(tex, coord)
#define SMAASampleOffset(tex, coord, offset) tex2D(tex, coord + offset * SMAA_RT_METRICS.xy)
//#define SMAA_FLATTEN [flatten]
//#define SMAA_BRANCH [branch]
#define SMAA_FLATTEN
#define SMAA_BRANCH
#endif
#if defined(SMAA_HLSL_4) || defined(SMAA_HLSL_4_1)
//SamplerState LinearSampler { Filter = MIN_MAG_LINEAR_MIP_POINT; AddressU = Clamp; AddressV = Clamp; };
//SamplerState PointSampler { Filter = MIN_MAG_MIP_POINT; AddressU = Clamp; AddressV = Clamp; };
#define SMAATexture2D(tex) Texture2D tex
#define SMAATexturePass2D(tex) tex
#define SMAASampleLevelZero(tex, coord) tex.SampleLevel(LinearSampler, coord, 0)
#define SMAASampleLevelZeroPoint(tex, coord) tex.SampleLevel(PointSampler, coord, 0)
#define SMAASampleLevelZeroOffset(tex, coord, offset) tex.SampleLevel(LinearSampler, coord, 0, offset)
#define SMAASample(tex, coord) tex.Sample(LinearSampler, coord)
#define SMAASamplePoint(tex, coord) tex.Sample(PointSampler, coord)
#define SMAASampleOffset(tex, coord, offset) tex.Sample(LinearSampler, coord, offset)
#define SMAA_FLATTEN [flatten]
#define SMAA_BRANCH [branch]
#define SMAATexture2DMS2(tex) Texture2DMS tex
#define SMAALoad(tex, pos, sample) tex.Load(pos, sample)
#if defined(SMAA_HLSL_4_1)
#define SMAAGather(tex, coord) tex.Gather(LinearSampler, coord, 0)
#endif
#endif
#if defined(SMAA_GLSL_3) || defined(SMAA_GLSL_4)
#define SMAATexture2D(tex) sampler2D tex
#define SMAATexturePass2D(tex) tex
#define SMAASampleLevelZero(tex, coord) textureLod(tex, coord, 0.0)
#define SMAASampleLevelZeroPoint(tex, coord) textureLod(tex, coord, 0.0)
#define SMAASampleLevelZeroOffset(tex, coord, offset) textureLodOffset(tex, coord, 0.0, offset)
#define SMAASample(tex, coord) texture(tex, coord)
#define SMAASamplePoint(tex, coord) texture(tex, coord)
#define SMAASampleOffset(tex, coord, offset) texture(tex, coord, offset)
#define SMAA_FLATTEN
#define SMAA_BRANCH
#define lerp(a, b, t) mix(a, b, t)
#define saturate(a) clamp(a, 0.0, 1.0)
#if defined(SMAA_GLSL_4)
#define mad(a, b, c) fma(a, b, c)
#define SMAAGather(tex, coord) textureGather(tex, coord)
#else
#define mad(a, b, c) (a * b + c)
#endif
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define int2 ivec2
#define int3 ivec3
#define int4 ivec4
#define bool2 bvec2
#define bool3 bvec3
#define bool4 bvec4
#endif
#if !defined(SMAA_HLSL_3) && !defined(SMAA_HLSL_4) && !defined(SMAA_HLSL_4_1) && !defined(SMAA_GLSL_3) && !defined(SMAA_GLSL_4) && !defined(SMAA_CUSTOM_SL)
#error you must define the shading language: SMAA_HLSL_*, SMAA_GLSL_* or SMAA_CUSTOM_SL
#endif
//-----------------------------------------------------------------------------
// Misc functions
/**
* Gathers current pixel, and the top-left neighbors.
*/
float3 SMAAGatherNeighbours(float2 texcoord,
float4 offset[3],
SMAATexture2D(tex)) {
#ifdef SMAAGather
return SMAAGather(tex, texcoord + SMAA_RT_METRICS.xy * float2(-0.5, -0.5)).grb;
#else
float P = SMAASamplePoint(tex, texcoord).r;
float Pleft = SMAASamplePoint(tex, offset[0].xy).r;
float Ptop = SMAASamplePoint(tex, offset[0].zw).r;
return float3(P, Pleft, Ptop);
#endif
}
/**
* Adjusts the threshold by means of predication.
*/
float2 SMAACalculatePredicatedThreshold(float2 texcoord,
float4 offset[3],
SMAATexture2D(predicationTex)) {
float3 neighbours = SMAAGatherNeighbours(texcoord, offset, SMAATexturePass2D(predicationTex));
float2 delta = abs(neighbours.xx - neighbours.yz);
float2 edges = step(SMAA_PREDICATION_THRESHOLD, delta);
return SMAA_PREDICATION_SCALE * SMAA_THRESHOLD * (1.0 - SMAA_PREDICATION_STRENGTH * edges);
}
/**
* Conditional move:
*/
void SMAAMovc(bool2 cond, inout float2 variable, float2 value) {
SMAA_FLATTEN if (cond.x) variable.x = value.x;
SMAA_FLATTEN if (cond.y) variable.y = value.y;
}
void SMAAMovc(bool4 cond, inout float4 variable, float4 value) {
SMAAMovc(cond.xy, variable.xy, value.xy);
SMAAMovc(cond.zw, variable.zw, value.zw);
}
#if SMAA_INCLUDE_VS
//-----------------------------------------------------------------------------
// Vertex Shaders
/**
* Edge Detection Vertex Shader
*/
void SMAAEdgeDetectionVS(float2 texcoord,
out float4 offset[3]) {
offset[0] = mad(SMAA_RT_METRICS.xyxy, float4(-1.0, 0.0, 0.0, -1.0), texcoord.xyxy);
offset[1] = mad(SMAA_RT_METRICS.xyxy, float4( 1.0, 0.0, 0.0, 1.0), texcoord.xyxy);
offset[2] = mad(SMAA_RT_METRICS.xyxy, float4(-2.0, 0.0, 0.0, -2.0), texcoord.xyxy);
}
/**
* Blend Weight Calculation Vertex Shader
*/
void SMAABlendingWeightCalculationVS(float2 texcoord,
out float2 pixcoord,
out float4 offset[3]) {
pixcoord = texcoord * SMAA_RT_METRICS.zw;
// We will use these offsets for the searches later on (see @PSEUDO_GATHER4):
offset[0] = mad(SMAA_RT_METRICS.xyxy, float4(-0.25, -0.125, 1.25, -0.125), texcoord.xyxy);
offset[1] = mad(SMAA_RT_METRICS.xyxy, float4(-0.125, -0.25, -0.125, 1.25), texcoord.xyxy);
// And these for the searches, they indicate the ends of the loops:
offset[2] = mad(SMAA_RT_METRICS.xxyy,
float4(-2.0, 2.0, -2.0, 2.0) * float(SMAA_MAX_SEARCH_STEPS),
float4(offset[0].xz, offset[1].yw));
}
/**
* Neighborhood Blending Vertex Shader
*/
void SMAANeighborhoodBlendingVS(float2 texcoord,
out float4 offset) {
offset = mad(SMAA_RT_METRICS.xyxy, float4( 1.0, 0.0, 0.0, 1.0), texcoord.xyxy);
}
#endif // SMAA_INCLUDE_VS
#if SMAA_INCLUDE_PS
//-----------------------------------------------------------------------------
// Edge Detection Pixel Shaders (First Pass)
/**
* Luma Edge Detection
*
* IMPORTANT NOTICE: luma edge detection requires gamma-corrected colors, and
* thus 'colorTex' should be a non-sRGB texture.
*/
float2 SMAALumaEdgeDetectionPS(float2 texcoord,
float4 offset[3],
SMAATexture2D(colorTex)
#if SMAA_PREDICATION
, SMAATexture2D(predicationTex)
#endif
) {
// Calculate the threshold:
#if SMAA_PREDICATION
float2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, SMAATexturePass2D(predicationTex));
#else
float2 threshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD);
#endif
// Calculate lumas:
float3 weights = float3(0.2126, 0.7152, 0.0722);
float L = dot(SMAASamplePoint(colorTex, texcoord).rgb, weights);
float Lleft = dot(SMAASamplePoint(colorTex, offset[0].xy).rgb, weights);
float Ltop = dot(SMAASamplePoint(colorTex, offset[0].zw).rgb, weights);
// We do the usual threshold:
float4 delta;
delta.xy = abs(L - float2(Lleft, Ltop));
float2 edges = step(threshold, delta.xy);
// Then discard if there is no edge:
if (dot(edges, float2(1.0, 1.0)) == 0.0)
discard;
// Calculate right and bottom deltas:
float Lright = dot(SMAASamplePoint(colorTex, offset[1].xy).rgb, weights);
float Lbottom = dot(SMAASamplePoint(colorTex, offset[1].zw).rgb, weights);
delta.zw = abs(L - float2(Lright, Lbottom));
// Calculate the maximum delta in the direct neighborhood:
float2 maxDelta = max(delta.xy, delta.zw);
// Calculate left-left and top-top deltas:
float Lleftleft = dot(SMAASamplePoint(colorTex, offset[2].xy).rgb, weights);
float Ltoptop = dot(SMAASamplePoint(colorTex, offset[2].zw).rgb, weights);
delta.zw = abs(float2(Lleft, Ltop) - float2(Lleftleft, Ltoptop));
// Calculate the final maximum delta:
maxDelta = max(maxDelta.xy, delta.zw);
float finalDelta = max(maxDelta.x, maxDelta.y);
// Local contrast adaptation:
#if !defined(SHADER_API_OPENGL)
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
#endif
return edges;
}
/**
* Color Edge Detection
*
* IMPORTANT NOTICE: color edge detection requires gamma-corrected colors, and
* thus 'colorTex' should be a non-sRGB texture.
*/
float2 SMAAColorEdgeDetectionPS(float2 texcoord,
float4 offset[3],
SMAATexture2D(colorTex)
#if SMAA_PREDICATION
, SMAATexture2D(predicationTex)
#endif
) {
// Calculate the threshold:
#if SMAA_PREDICATION
float2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, predicationTex);
#else
float2 threshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD);
#endif
// Calculate color deltas:
float4 delta;
float3 C = SMAASamplePoint(colorTex, texcoord).rgb;
float3 Cleft = SMAASamplePoint(colorTex, offset[0].xy).rgb;
float3 t = abs(C - Cleft);
delta.x = max(max(t.r, t.g), t.b);
float3 Ctop = SMAASamplePoint(colorTex, offset[0].zw).rgb;
t = abs(C - Ctop);
delta.y = max(max(t.r, t.g), t.b);
// We do the usual threshold:
float2 edges = step(threshold, delta.xy);
// Then discard if there is no edge:
if (dot(edges, float2(1.0, 1.0)) == 0.0)
discard;
// Calculate right and bottom deltas:
float3 Cright = SMAASamplePoint(colorTex, offset[1].xy).rgb;
t = abs(C - Cright);
delta.z = max(max(t.r, t.g), t.b);
float3 Cbottom = SMAASamplePoint(colorTex, offset[1].zw).rgb;
t = abs(C - Cbottom);
delta.w = max(max(t.r, t.g), t.b);
// Calculate the maximum delta in the direct neighborhood:
float2 maxDelta = max(delta.xy, delta.zw);
// Calculate left-left and top-top deltas:
float3 Cleftleft = SMAASamplePoint(colorTex, offset[2].xy).rgb;
t = abs(Cleft - Cleftleft);
delta.z = max(max(t.r, t.g), t.b);
float3 Ctoptop = SMAASamplePoint(colorTex, offset[2].zw).rgb;
t = abs(Ctop - Ctoptop);
delta.w = max(max(t.r, t.g), t.b);
// Calculate the final maximum delta:
maxDelta = max(maxDelta.xy, delta.zw);
float finalDelta = max(maxDelta.x, maxDelta.y);
// Local contrast adaptation:
#if !defined(SHADER_API_OPENGL)
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
#endif
return edges;
}
/**
* Depth Edge Detection
*/
float2 SMAADepthEdgeDetectionPS(float2 texcoord,
float4 offset[3],
SMAATexture2D(depthTex)) {
float3 neighbours = SMAAGatherNeighbours(texcoord, offset, SMAATexturePass2D(depthTex));
float2 delta = abs(neighbours.xx - float2(neighbours.y, neighbours.z));
float2 edges = step(SMAA_DEPTH_THRESHOLD, delta);
if (dot(edges, float2(1.0, 1.0)) == 0.0)
discard;
return edges;
}
//-----------------------------------------------------------------------------
// Diagonal Search Functions
#if !defined(SMAA_DISABLE_DIAG_DETECTION)
/**
* Allows to decode two binary values from a bilinear-filtered access.
*/
float2 SMAADecodeDiagBilinearAccess(float2 e) {
// Bilinear access for fetching 'e' have a 0.25 offset, and we are
// interested in the R and G edges:
//
// +---G---+-------+
// | x o R x |
// +-------+-------+
//
// Then, if one of these edge is enabled:
// Red: (0.75 * X + 0.25 * 1) => 0.25 or 1.0
// Green: (0.75 * 1 + 0.25 * X) => 0.75 or 1.0
//
// This function will unpack the values (mad + mul + round):
// wolframalpha.com: round(x * abs(5 * x - 5 * 0.75)) plot 0 to 1
e.r = e.r * abs(5.0 * e.r - 5.0 * 0.75);
return round(e);
}
float4 SMAADecodeDiagBilinearAccess(float4 e) {
e.rb = e.rb * abs(5.0 * e.rb - 5.0 * 0.75);
return round(e);
}
/**
* These functions allows to perform diagonal pattern searches.
*/
float2 SMAASearchDiag1(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out float2 e) {
float4 coord = float4(texcoord, -1.0, 1.0);
float3 t = float3(SMAA_RT_METRICS.xy, 1.0);
while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) &&
coord.w > 0.9) {
coord.xyz = mad(t, float3(dir, 1.0), coord.xyz);
e = SMAASampleLevelZero(edgesTex, coord.xy).rg;
coord.w = dot(e, float2(0.5, 0.5));
}
return coord.zw;
}
float2 SMAASearchDiag2(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out float2 e) {
float4 coord = float4(texcoord, -1.0, 1.0);
coord.x += 0.25 * SMAA_RT_METRICS.x; // See @SearchDiag2Optimization
float3 t = float3(SMAA_RT_METRICS.xy, 1.0);
while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) &&
coord.w > 0.9) {
coord.xyz = mad(t, float3(dir, 1.0), coord.xyz);
// @SearchDiag2Optimization
// Fetch both edges at once using bilinear filtering:
e = SMAASampleLevelZero(edgesTex, coord.xy).rg;
e = SMAADecodeDiagBilinearAccess(e);
// Non-optimized version:
// e.g = SMAASampleLevelZero(edgesTex, coord.xy).g;
// e.r = SMAASampleLevelZeroOffset(edgesTex, coord.xy, int2(1, 0)).r;
coord.w = dot(e, float2(0.5, 0.5));
}
return coord.zw;
}
/**
* Similar to SMAAArea, this calculates the area corresponding to a certain
* diagonal distance and crossing edges 'e'.
*/
float2 SMAAAreaDiag(SMAATexture2D(areaTex), float2 dist, float2 e, float offset) {
float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE_DIAG, SMAA_AREATEX_MAX_DISTANCE_DIAG), e, dist);
// We do a scale and bias for mapping to texel space:
texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE);
// Diagonal areas are on the second half of the texture:
texcoord.x += 0.5;
// Move to proper place, according to the subpixel offset:
texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset;
// Do it!
return SMAA_AREATEX_SELECT(SMAASampleLevelZero(areaTex, texcoord));
}
/**
* This searches for diagonal patterns and returns the corresponding weights.
*/
float2 SMAACalculateDiagWeights(SMAATexture2D(edgesTex), SMAATexture2D(areaTex), float2 texcoord, float2 e, float4 subsampleIndices) {
float2 weights = float2(0.0, 0.0);
// Search for the line ends:
float4 d;
float2 end;
if (e.r > 0.0) {
d.xz = SMAASearchDiag1(SMAATexturePass2D(edgesTex), texcoord, float2(-1.0, 1.0), end);
d.x += float(end.y > 0.9);
} else
d.xz = float2(0.0, 0.0);
d.yw = SMAASearchDiag1(SMAATexturePass2D(edgesTex), texcoord, float2(1.0, -1.0), end);
SMAA_BRANCH
if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3
// Fetch the crossing edges:
float4 coords = mad(float4(-d.x + 0.25, d.x, d.y, -d.y - 0.25), SMAA_RT_METRICS.xyxy, texcoord.xyxy);
float4 c;
c.xy = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).rg;
c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).rg;
c.yxwz = SMAADecodeDiagBilinearAccess(c.xyzw);
// Non-optimized version:
// float4 coords = mad(float4(-d.x, d.x, d.y, -d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy);
// float4 c;
// c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).g;
// c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, 0)).r;
// c.z = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).g;
// c.w = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, -1)).r;
// Merge crossing edges at each side into a single value:
float2 cc = mad(float2(2.0, 2.0), c.xz, c.yw);
// Remove the crossing edge if we didn't found the end of the line:
SMAAMovc(bool2(step(float2(0.9, 0.9), d.zw)), cc, float2(0.0, 0.0));
// Fetch the areas for this line:
weights += SMAAAreaDiag(SMAATexturePass2D(areaTex), d.xy, cc, subsampleIndices.z);
}
// Search for the line ends:
d.xz = SMAASearchDiag2(SMAATexturePass2D(edgesTex), texcoord, float2(-1.0, -1.0), end);
if (SMAASampleLevelZeroOffset(edgesTex, texcoord, int2(1, 0)).r > 0.0) {
d.yw = SMAASearchDiag2(SMAATexturePass2D(edgesTex), texcoord, float2(1.0, 1.0), end);
d.y += float(end.y > 0.9);
} else
d.yw = float2(0.0, 0.0);
SMAA_BRANCH
if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3
// Fetch the crossing edges:
float4 coords = mad(float4(-d.x, -d.x, d.y, d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy);
float4 c;
c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).g;
c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, -1)).r;
c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).gr;
float2 cc = mad(float2(2.0, 2.0), c.xz, c.yw);
// Remove the crossing edge if we didn't found the end of the line:
SMAAMovc(bool2(step(float2(0.9, 0.9), d.zw)), cc, float2(0.0, 0.0));
// Fetch the areas for this line:
weights += SMAAAreaDiag(SMAATexturePass2D(areaTex), d.xy, cc, subsampleIndices.w).gr;
}
return weights;
}
#endif
//-----------------------------------------------------------------------------
// Horizontal/Vertical Search Functions
/**
* This allows to determine how much length should we add in the last step
* of the searches. It takes the bilinearly interpolated edge (see
* @PSEUDO_GATHER4), and adds 0, 1 or 2, depending on which edges and
* crossing edges are active.
*/
float SMAASearchLength(SMAATexture2D(searchTex), float2 e, float offset) {
// The texture is flipped vertically, with left and right cases taking half
// of the space horizontally:
float2 scale = SMAA_SEARCHTEX_SIZE * float2(0.5, -1.0);
float2 bias = SMAA_SEARCHTEX_SIZE * float2(offset, 1.0);
// Scale and bias to access texel centers:
scale += float2(-1.0, 1.0);
bias += float2( 0.5, -0.5);
// Convert from pixel coordinates to texcoords:
// (We use SMAA_SEARCHTEX_PACKED_SIZE because the texture is cropped)
scale *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE;
bias *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE;
// Lookup the search texture:
return SMAA_SEARCHTEX_SELECT(SMAASampleLevelZero(searchTex, mad(scale, e, bias)));
}
/**
* Horizontal/vertical search functions for the 2nd pass.
*/
float SMAASearchXLeft(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) {
/**
* @PSEUDO_GATHER4
* This texcoord has been offset by (-0.25, -0.125) in the vertex shader to
* sample between edge, thus fetching four edges in a row.
* Sampling with different offsets in each direction allows to disambiguate
* which edges are active from the four fetched ones.
*/
float2 e = float2(0.0, 1.0);
while (texcoord.x > end &&
e.g > 0.8281 && // Is there some edge not activated?
e.r == 0.0) { // Or is there a crossing edge that breaks the line?
e = SMAASampleLevelZero(edgesTex, texcoord).rg;
texcoord = mad(-float2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord);
}
float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0), 3.25);
return mad(SMAA_RT_METRICS.x, offset, texcoord.x);
// Non-optimized version:
// We correct the previous (-0.25, -0.125) offset we applied:
// texcoord.x += 0.25 * SMAA_RT_METRICS.x;
// The searches are bias by 1, so adjust the coords accordingly:
// texcoord.x += SMAA_RT_METRICS.x;
// Disambiguate the length added by the last step:
// texcoord.x += 2.0 * SMAA_RT_METRICS.x; // Undo last step
// texcoord.x -= SMAA_RT_METRICS.x * (255.0 / 127.0) * SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0);
// return mad(SMAA_RT_METRICS.x, offset, texcoord.x);
}
float SMAASearchXRight(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) {
float2 e = float2(0.0, 1.0);
while (texcoord.x < end &&
e.g > 0.8281 && // Is there some edge not activated?
e.r == 0.0) { // Or is there a crossing edge that breaks the line?
e = SMAASampleLevelZero(edgesTex, texcoord).rg;
texcoord = mad(float2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord);
}
float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.5), 3.25);
return mad(-SMAA_RT_METRICS.x, offset, texcoord.x);
}
float SMAASearchYUp(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) {
float2 e = float2(1.0, 0.0);
while (texcoord.y > end &&
e.r > 0.8281 && // Is there some edge not activated?
e.g == 0.0) { // Or is there a crossing edge that breaks the line?
e = SMAASampleLevelZero(edgesTex, texcoord).rg;
texcoord = mad(-float2(0.0, 2.0), SMAA_RT_METRICS.xy, texcoord);
}
float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e.gr, 0.0), 3.25);
return mad(SMAA_RT_METRICS.y, offset, texcoord.y);
}
float SMAASearchYDown(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) {
float2 e = float2(1.0, 0.0);
while (texcoord.y < end &&
e.r > 0.8281 && // Is there some edge not activated?
e.g == 0.0) { // Or is there a crossing edge that breaks the line?
e = SMAASampleLevelZero(edgesTex, texcoord).rg;
texcoord = mad(float2(0.0, 2.0), SMAA_RT_METRICS.xy, texcoord);
}
float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e.gr, 0.5), 3.25);
return mad(-SMAA_RT_METRICS.y, offset, texcoord.y);
}
/**
* Ok, we have the distance and both crossing edges. So, what are the areas
* at each side of current edge?
*/
float2 SMAAArea(SMAATexture2D(areaTex), float2 dist, float e1, float e2, float offset) {
// Rounding prevents precision errors of bilinear filtering:
float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE), round(4.0 * float2(e1, e2)), dist);
// We do a scale and bias for mapping to texel space:
texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE);
// Move to proper place, according to the subpixel offset:
texcoord.y = mad(SMAA_AREATEX_SUBTEX_SIZE, offset, texcoord.y);
// Do it!
return SMAA_AREATEX_SELECT(SMAASampleLevelZero(areaTex, texcoord));
}
//-----------------------------------------------------------------------------
// Corner Detection Functions
void SMAADetectHorizontalCornerPattern(SMAATexture2D(edgesTex), inout float2 weights, float4 texcoord, float2 d) {
#if !defined(SMAA_DISABLE_CORNER_DETECTION)
float2 leftRight = step(d.xy, d.yx);
float2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight;
rounding /= leftRight.x + leftRight.y; // Reduce blending for pixels in the center of a line.
float2 factor = float2(1.0, 1.0);
factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(0, 1)).r;
factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(1, 1)).r;
factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(0, -2)).r;
factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(1, -2)).r;
weights *= saturate(factor);
#endif
}
void SMAADetectVerticalCornerPattern(SMAATexture2D(edgesTex), inout float2 weights, float4 texcoord, float2 d) {
#if !defined(SMAA_DISABLE_CORNER_DETECTION)
float2 leftRight = step(d.xy, d.yx);
float2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight;
rounding /= leftRight.x + leftRight.y;
float2 factor = float2(1.0, 1.0);
factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2( 1, 0)).g;
factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2( 1, 1)).g;
factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(-2, 0)).g;
factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(-2, 1)).g;
weights *= saturate(factor);
#endif
}
//-----------------------------------------------------------------------------
// Blending Weight Calculation Pixel Shader (Second Pass)
float4 SMAABlendingWeightCalculationPS(float2 texcoord,
float2 pixcoord,
float4 offset[3],
SMAATexture2D(edgesTex),
SMAATexture2D(areaTex),
SMAATexture2D(searchTex),
float4 subsampleIndices) { // Just pass zero for SMAA 1x, see @SUBSAMPLE_INDICES.
float4 weights = float4(0.0, 0.0, 0.0, 0.0);
float2 e = SMAASample(edgesTex, texcoord).rg;
SMAA_BRANCH
if (e.g > 0.0) { // Edge at north
#if !defined(SMAA_DISABLE_DIAG_DETECTION)
// Diagonals have both north and west edges, so searching for them in
// one of the boundaries is enough.
weights.rg = SMAACalculateDiagWeights(SMAATexturePass2D(edgesTex), SMAATexturePass2D(areaTex), texcoord, e, subsampleIndices);
// We give priority to diagonals, so if we find a diagonal we skip
// horizontal/vertical processing.
SMAA_BRANCH
if (weights.r == -weights.g) { // weights.r + weights.g == 0.0
#endif
float2 d;
// Find the distance to the left:
float3 coords;
coords.x = SMAASearchXLeft(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[0].xy, offset[2].x);
coords.y = offset[1].y; // offset[1].y = texcoord.y - 0.25 * SMAA_RT_METRICS.y (@CROSSING_OFFSET)
d.x = coords.x;
// Now fetch the left crossing edges, two at a time using bilinear
// filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to
// discern what value each edge has:
float e1 = SMAASampleLevelZero(edgesTex, coords.xy).r;
// Find the distance to the right:
coords.z = SMAASearchXRight(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[0].zw, offset[2].y);
d.y = coords.z;
// We want the distances to be in pixel units (doing this here allow to
// better interleave arithmetic and memory accesses):
d = abs(round(mad(SMAA_RT_METRICS.zz, d, -pixcoord.xx)));
// SMAAArea below needs a sqrt, as the areas texture is compressed
// quadratically:
float2 sqrt_d = sqrt(d);
// Fetch the right crossing edges:
float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.zy, int2(1, 0)).r;
// Ok, we know how this pattern looks like, now it is time for getting
// the actual area:
weights.rg = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.y);
// Fix corners:
coords.y = texcoord.y;
SMAADetectHorizontalCornerPattern(SMAATexturePass2D(edgesTex), weights.rg, coords.xyzy, d);
#if !defined(SMAA_DISABLE_DIAG_DETECTION)
} else
e.r = 0.0; // Skip vertical processing.
#endif
}
SMAA_BRANCH
if (e.r > 0.0) { // Edge at west
float2 d;
// Find the distance to the top:
float3 coords;
coords.y = SMAASearchYUp(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[1].xy, offset[2].z);
coords.x = offset[0].x; // offset[1].x = texcoord.x - 0.25 * SMAA_RT_METRICS.x;
d.x = coords.y;
// Fetch the top crossing edges:
float e1 = SMAASampleLevelZero(edgesTex, coords.xy).g;
// Find the distance to the bottom:
coords.z = SMAASearchYDown(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[1].zw, offset[2].w);
d.y = coords.z;
// We want the distances to be in pixel units:
d = abs(round(mad(SMAA_RT_METRICS.ww, d, -pixcoord.yy)));
// SMAAArea below needs a sqrt, as the areas texture is compressed
// quadratically:
float2 sqrt_d = sqrt(d);
// Fetch the bottom crossing edges:
float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.xz, int2(0, 1)).g;
// Get the area for this direction:
weights.ba = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.x);
// Fix corners:
coords.x = texcoord.x;
SMAADetectVerticalCornerPattern(SMAATexturePass2D(edgesTex), weights.ba, coords.xyxz, d);
}
return weights;
}
//-----------------------------------------------------------------------------
// UV-based reprojection functions
#if SMAA_UV_BASED_REPROJECTION
float2 SMAAReproject(float2 texcoord)
{
// UV to clip-position:
// -- This must be sampled at exactly mip 0 due to possible gradient divergence
// -- as this function is called within a control flow block down below.
float depth = SMAASampleLevelZero(_CameraDepthTexture, texcoord).r;
float3 clipPosition = float3(2. * texcoord - 1., depth);
// Reproject
float4 previousClipPosition = mul(_ReprojectionMatrix, float4(clipPosition, 1.));
previousClipPosition.xyz /= previousClipPosition.w;
// Clip-position to UV
return (.5 * previousClipPosition.xy + .5);
}
#endif
//-----------------------------------------------------------------------------
// Neighborhood Blending Pixel Shader (Third Pass)
float4 SMAANeighborhoodBlendingPS(float2 texcoord,
float4 offset,
SMAATexture2D(colorTex),
SMAATexture2D(blendTex)
#if SMAA_REPROJECTION
, SMAATexture2D(velocityTex)
#endif
) {
// Fetch the blending weights for current pixel:
float4 a;
a.x = SMAASample(blendTex, offset.xy).a; // Right
a.y = SMAASample(blendTex, offset.zw).g; // Top
a.wz = SMAASample(blendTex, texcoord).xz; // Bottom / Left
// Is there any blending weight with a value greater than 0.0?
SMAA_BRANCH
if (dot(a, float4(1.0, 1.0, 1.0, 1.0)) < 1e-5) {
float4 color = SMAASampleLevelZero(colorTex, texcoord);
#if SMAA_REPROJECTION
float2 velocity = SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, texcoord));
#elif SMAA_UV_BASED_REPROJECTION
float2 velocity = texcoord - SMAAReproject(texcoord);
#endif
#if (SMAA_REPROJECTION || SMAA_UV_BASED_REPROJECTION)
// Pack velocity into the alpha channel:
color.a = sqrt(5.0 * length(velocity));
#endif
return color;
} else {
bool h = max(a.x, a.z) > max(a.y, a.w); // max(horizontal) > max(vertical)
// Calculate the blending offsets:
float4 blendingOffset = float4(0.0, a.y, 0.0, a.w);
float2 blendingWeight = a.yw;
SMAAMovc(bool4(h, h, h, h), blendingOffset, float4(a.x, 0.0, a.z, 0.0));
SMAAMovc(bool2(h, h), blendingWeight, a.xz);
blendingWeight /= dot(blendingWeight, float2(1.0, 1.0));
// Calculate the texture coordinates:
float4 blendingCoord = mad(blendingOffset, float4(SMAA_RT_METRICS.xy, -SMAA_RT_METRICS.xy), texcoord.xyxy);
// We exploit bilinear filtering to mix current pixel with the chosen
// neighbor:
float4 color = blendingWeight.x * SMAASampleLevelZero(colorTex, blendingCoord.xy);
color += blendingWeight.y * SMAASampleLevelZero(colorTex, blendingCoord.zw);
#if SMAA_REPROJECTION
// Antialias velocity for proper reprojection in a later stage:
float2 velocity = blendingWeight.x * SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, blendingCoord.xy));
velocity += blendingWeight.y * SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, blendingCoord.zw));
#elif SMAA_UV_BASED_REPROJECTION
// Antialias velocity for proper reprojection in a later stage:
float2 velocity = blendingWeight.x * (blendingCoord.xy - SMAAReproject(blendingCoord.xy));
velocity += blendingWeight.y * (blendingCoord.zw - SMAAReproject(blendingCoord.zw));
#endif
#if (SMAA_REPROJECTION || SMAA_UV_BASED_REPROJECTION)
// Pack velocity into the alpha channel:
color.a = sqrt(5.0 * length(velocity));
#endif
return color;
}
}
//-----------------------------------------------------------------------------
// Temporal Resolve Pixel Shader (Optional Pass)
float4 SMAAResolvePS(float2 texcoord,
SMAATexture2D(currentColorTex),
SMAATexture2D(previousColorTex)
#if SMAA_REPROJECTION
, SMAATexture2D(velocityTex)
#endif
) {
#if SMAA_REPROJECTION
// Velocity is assumed to be calculated for motion blur, so we need to
// inverse it for reprojection:
float2 velocity = -SMAA_DECODE_VELOCITY(SMAASamplePoint(velocityTex, texcoord).rg);
#elif SMAA_UV_BASED_REPROJECTION
float2 velocity = SMAAReproject(texcoord) - texcoord;
#endif
#if (SMAA_REPROJECTION || SMAA_UV_BASED_REPROJECTION)
// Fetch current pixel:
float4 current = SMAASamplePoint(currentColorTex, texcoord);
// Reproject current coordinates and fetch previous pixel:
float4 previous = SMAASamplePoint(previousColorTex, texcoord + velocity);
// Attenuate the previous pixel if the velocity is different:
float delta = abs(current.a * current.a - previous.a * previous.a) / 5.0;
float weight = 0.5 * saturate(1.0 - sqrt(delta) * SMAA_REPROJECTION_WEIGHT_SCALE);
// Blend the pixels according to the calculated weight:
// return lerp(current, previous, weight);
// Neighbour clamp
// Contributed by pommak
float4 n0 = SMAASampleOffset(currentColorTex, texcoord, float2(-1, -1));
float4 n1 = SMAASampleOffset(currentColorTex, texcoord, float2(+1, -1));
float4 n2 = SMAASampleOffset(currentColorTex, texcoord, float2(-1, +1));
float4 n3 = SMAASampleOffset(currentColorTex, texcoord, float2(+1, +1));
float4 cmax = max(n0, max(n1, max(n2, n3)));
float4 cmin = min(n0, min(n1, min(n2, n3)));
float4 avg = 0.25 * (n0+n1+n2+n3);
float4 wk = abs(avg - current);
float blend = saturate(lerp(0.35, 0.85, wk));
// Clamp previous to neighbours colors
float4 previousClamped = clamp(previous, cmin, cmax);
float4 color = lerp(lerp(current, previousClamped, 0.5*weight), previousClamped, weight);
return color;
#else
// Just blend the pixels:
float4 current = SMAASamplePoint(currentColorTex, texcoord);
float4 previous = SMAASamplePoint(previousColorTex, texcoord);
return lerp(current, previous, 0.5);
#endif
}
//-----------------------------------------------------------------------------
// Separate Multisamples Pixel Shader (Optional Pass)
#ifdef SMAALoad
void SMAASeparatePS(float4 position,
float2 texcoord,
out float4 target0,
out float4 target1,
SMAATexture2DMS2(colorTexMS)) {
int2 pos = int2(position.xy);
target0 = SMAALoad(colorTexMS, pos, 0);
target1 = SMAALoad(colorTexMS, pos, 1);
}
#endif
//-----------------------------------------------------------------------------
#endif // SMAA_INCLUDE_PS
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SMAA.cginc.meta
================================================
fileFormatVersion: 2
guid: 3edf75dd062cabf449c243d3c0da9464
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SMAA.shader
================================================
Shader "Scatterer/SubpixelMorphologicalAntialiasing"
{
SubShader
{
Cull Off ZWrite Off ZTest Always
// 0 - Edge detection (Low)
Pass
{
CGPROGRAM
#pragma vertex VertEdge
#pragma fragment FragEdge
#define SMAA_PRESET_LOW
#include "SMAABridge.cginc"
ENDCG
}
// 1 - Edge detection (Medium)
Pass
{
CGPROGRAM
#pragma vertex VertEdge
#pragma fragment FragEdge
#define SMAA_PRESET_MEDIUM
#include "SMAABridge.cginc"
ENDCG
}
// 2 - Edge detection (High)
Pass
{
CGPROGRAM
#pragma vertex VertEdge
#pragma fragment FragEdge
#define SMAA_PRESET_HIGH
#include "SMAABridge.cginc"
ENDCG
}
// 3 - Blend Weights Calculation (Low)
Pass
{
CGPROGRAM
#pragma vertex VertBlend
#pragma fragment FragBlend
#define SMAA_PRESET_LOW
#include "SMAABridge.cginc"
ENDCG
}
// 4 - Blend Weights Calculation (Medium)
Pass
{
CGPROGRAM
#pragma vertex VertBlend
#pragma fragment FragBlend
#define SMAA_PRESET_MEDIUM
#include "SMAABridge.cginc"
ENDCG
}
// 5 - Blend Weights Calculation (High)
Pass
{
CGPROGRAM
#pragma vertex VertBlend
#pragma fragment FragBlend
#define SMAA_PRESET_HIGH
#include "SMAABridge.cginc"
ENDCG
}
// 6 - Neighborhood Blending
Pass
{
CGPROGRAM
#pragma vertex VertNeighbor
#pragma fragment FragNeighbor
#include "SMAABridge.cginc"
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SMAA.shader.meta
================================================
fileFormatVersion: 2
guid: 89df79cf5061c394d82abd40383976e5
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SMAABridge.cginc
================================================
#ifndef UNITY_POSTFX_SMAA_BRIDGE
#define UNITY_POSTFX_SMAA_BRIDGE
//#include "StdLib.hlsl"
sampler2D _MainTexture;
sampler2D _BlendTex;
sampler2D _AreaTex;
sampler2D _SearchTex;
float4 _MainTexture_TexelSize;
#define SMAA_RT_METRICS _MainTexture_TexelSize
#define SMAA_AREATEX_SELECT(s) s.rg
#define SMAA_SEARCHTEX_SELECT(s) s.a
#define LinearSampler sampler_MainTexture
#define PointSampler sampler_MainTexture
#define SMAA_HLSL_3
#include "SMAA.cginc"
struct AttributesDefault
{
float3 vertex : POSITION;
};
struct VaryingsDefault
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float2 texcoordStereo : TEXCOORD1;
#if STEREO_INSTANCING_ENABLED
uint stereoTargetEyeIndex : SV_RenderTargetArrayIndex;
#endif
};
// Vertex manipulation
float2 TransformTriangleVertexToUV(float2 vertex)
{
//float2 uv = (vertex + 1.0) * 0.5;
float2 uv = vertex;
return uv;
}
// ----------------------------------------------------------------------------------------
// Edge Detection
struct VaryingsEdge
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float4 offsets[3] : TEXCOORD1;
};
VaryingsEdge VertEdge(AttributesDefault v)
{
VaryingsEdge o;
o.vertex = float4((v.vertex.xy-0.5)*2.0, 0.0, 1.0);
o.texcoord = TransformTriangleVertexToUV(v.vertex.xy);
#if UNITY_UV_STARTS_AT_TOP
o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
#endif
o.offsets[0] = mad(SMAA_RT_METRICS.xyxy, float4(-1.0, 0.0, 0.0, -1.0), o.texcoord.xyxy);
o.offsets[1] = mad(SMAA_RT_METRICS.xyxy, float4( 1.0, 0.0, 0.0, 1.0), o.texcoord.xyxy);
o.offsets[2] = mad(SMAA_RT_METRICS.xyxy, float4(-2.0, 0.0, 0.0, -2.0), o.texcoord.xyxy);
return o;
}
float4 FragEdge(VaryingsEdge i) : SV_Target
{
return float4(SMAAColorEdgeDetectionPS(i.texcoord, i.offsets, _MainTexture), 0.0, 0.0);
}
// ----------------------------------------------------------------------------------------
// Blend Weights Calculation
struct VaryingsBlend
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float2 pixcoord : TEXCOORD1;
float4 offsets[3] : TEXCOORD2;
};
VaryingsBlend VertBlend(AttributesDefault v)
{
VaryingsBlend o;
o.vertex = float4((v.vertex.xy-0.5)*2.0, 0.0, 1.0);
o.texcoord = TransformTriangleVertexToUV(v.vertex.xy);
#if UNITY_UV_STARTS_AT_TOP
o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
#endif
o.pixcoord = o.texcoord * SMAA_RT_METRICS.zw;
// We will use these offsets for the searches later on (see @PSEUDO_GATHER4):
o.offsets[0] = mad(SMAA_RT_METRICS.xyxy, float4(-0.250, -0.125, 1.250, -0.125), o.texcoord.xyxy);
o.offsets[1] = mad(SMAA_RT_METRICS.xyxy, float4(-0.125, -0.250, -0.125, 1.250), o.texcoord.xyxy);
// And these for the searches, they indicate the ends of the loops:
o.offsets[2] = mad(SMAA_RT_METRICS.xxyy, float4(-2.0, 2.0, -2.0, 2.0) * float(SMAA_MAX_SEARCH_STEPS),
float4(o.offsets[0].xz, o.offsets[1].yw));
//potentially the offsets or pixcoord are broken, texcoord seems to be fine
//textures _AreaTex and _SearchTex should be fine but not sure
//perhaps mad is messed up?
return o;
}
float4 FragBlend(VaryingsBlend i) : SV_Target
{
return SMAABlendingWeightCalculationPS(i.texcoord, i.pixcoord, i.offsets, _MainTexture, _AreaTex, _SearchTex, 0);
}
// ----------------------------------------------------------------------------------------
// Neighborhood Blending
struct VaryingsNeighbor
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float4 offset : TEXCOORD1;
};
VaryingsNeighbor VertNeighbor(AttributesDefault v)
{
VaryingsNeighbor o;
o.vertex = float4((v.vertex.xy-0.5)*2.0, 0.0, 1.0);
o.texcoord = TransformTriangleVertexToUV(v.vertex.xy);
#if UNITY_UV_STARTS_AT_TOP
o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
#endif
o.offset = mad(SMAA_RT_METRICS.xyxy, float4(1.0, 0.0, 0.0, 1.0), o.texcoord.xyxy);
return o;
}
float4 FragNeighbor(VaryingsNeighbor i) : SV_Target
{
return SMAANeighborhoodBlendingPS(i.texcoord, i.offset, _MainTexture, _BlendTex);
}
#endif
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SMAABridge.cginc.meta
================================================
fileFormatVersion: 2
guid: d12fd27d9e34a1e43b79b04f9202d548
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA/SearchTex.tga.meta
================================================
fileFormatVersion: 2
guid: b14b67faac4aff04fac7127cf1ab4f97
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 10
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 1
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 1
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 0
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 2
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 10
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: PS4
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/AA.meta
================================================
fileFormatVersion: 2
guid: 7db44d889e0cbbf4281132a752f96ce1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/CompositeDownscaledScattering.shader
================================================
Shader "Scatterer/CompositeDownscaledScattering" {
SubShader {
Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
Pass {
Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
Cull Off
ZTest Off
ZWrite [_ZwriteVariable]
Blend SrcAlpha OneMinusSrcAlpha //traditional alpha-blending
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
#include "../CommonAtmosphere.cginc"
#pragma multi_compile CUSTOM_OCEAN_OFF CUSTOM_OCEAN_ON
uniform sampler2D DownscaledScattering0; //Scattering RGB, extinction.R
uniform sampler2D DownscaledScattering1; //Extinction.GB
uniform sampler2D ScattererDownscaledScatteringDepth;
float4 ScattererDownscaledScatteringDepth_TexelSize;
#if defined (CUSTOM_OCEAN_ON)
uniform sampler2D ScattererScreenCopy;
uniform sampler2D ScattererDepthCopy;
float4 ScattererDepthCopy_TexelSize;
#define fullresDepthTexture ScattererDepthCopy;
#define fullresDepthTexture_TexelSize ScattererDepthCopy_TexelSize;
#else
uniform sampler2D _CameraDepthTexture;
float4 _CameraDepthTexture_TexelSize;
#define fullresDepthTexture _CameraDepthTexture;
#define fullresDepthTexture_TexelSize _CameraDepthTexture_TexelSize;
uniform sampler2D ScattererScreenCopyBeforeOcean;
#endif
struct v2f
{
float4 screenPos : TEXCOORD0;
};
v2f vert(appdata_base v, out float4 outpos: SV_POSITION)
{
v2f o;
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)
outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y *_ProjectionParams.x, -1.0 , 1.0);
#else
outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y, 0.0 , 1.0);
#endif
o.screenPos = ComputeScreenPos(outpos);
return o;
}
struct fout
{
float4 color : COLOR;
#if defined (CUSTOM_OCEAN_ON)
float depth : DEPTH;
#endif
};
void UpdateNearestSample( inout float MinDist,
inout float2 NearestUV,
float Z,
float2 UV,
float ZFull
)
{
float Dist = abs(Z - ZFull);
#if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12
if ((Dist < MinDist) && (Z > 0.0))
#else
if ((Dist < MinDist) && (Z < 1.0))
#endif
{
MinDist = Dist;
NearestUV = UV;
}
}
fout frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS)
{
float2 uv = i.screenPos.xy / i.screenPos.w;
#if defined (CUSTOM_OCEAN_ON)
float zdepth = tex2Dlod(ScattererDepthCopy, float4(uv,0,0));
#else
float zdepth = tex2Dlod(_CameraDepthTexture, float4(uv,0,0));
#endif
//read full resolution depth
float ZFull = Linear01Depth(zdepth);
#if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12
if (_ProjectionParams.x > 0) {uv.y = 1.0 - uv.y;}
if (zdepth == 0.0) {discard;}
#else
if (zdepth == 1.0) {discard;}
#endif
//find low res depth texture texel size
float2 lowResTexelSize = ScattererDownscaledScatteringDepth_TexelSize.xy;
float2 lowResUV = uv;
float MinDist = 1.0;
float2 UV00 = lowResUV - 0.5 * lowResTexelSize;
float2 NearestUV = UV00;
float Z00 = Linear01Depth( SAMPLE_DEPTH_TEXTURE( ScattererDownscaledScatteringDepth, UV00) );
UpdateNearestSample(MinDist, NearestUV, Z00, UV00, ZFull);
float2 UV10 = float2(UV00.x+lowResTexelSize.x, UV00.y);
float Z10 = Linear01Depth( SAMPLE_DEPTH_TEXTURE( ScattererDownscaledScatteringDepth, UV10) );
UpdateNearestSample(MinDist, NearestUV, Z10, UV10, ZFull);
float2 UV01 = float2(UV00.x, UV00.y+lowResTexelSize.y);
float Z01 = Linear01Depth( SAMPLE_DEPTH_TEXTURE( ScattererDownscaledScatteringDepth, UV01) );
UpdateNearestSample(MinDist, NearestUV, Z01, UV01, ZFull);
float2 UV11 = UV00 + lowResTexelSize;
float Z11 = Linear01Depth( SAMPLE_DEPTH_TEXTURE( ScattererDownscaledScatteringDepth, UV11) );
UpdateNearestSample(MinDist, NearestUV, Z11, UV11, ZFull);
float4 col0 = tex2Dlod(DownscaledScattering0, float4(NearestUV,0,0));
float2 col1 = tex2Dlod(DownscaledScattering1, float4(NearestUV,0,0)).rg;
float3 inscatter = col0.rgb;
float3 extinction = float3(col0.a,col1.rg);
#if defined (CUSTOM_OCEAN_ON)
float3 backGrnd = tex2Dlod(ScattererScreenCopy, float4(uv.x, uv.y,0.0,0.0));
#else
float3 backGrnd = tex2Dlod(ScattererScreenCopyBeforeOcean, float4(uv.x, uv.y,0.0,0.0));
#endif
//composite backGround by extinction
backGrnd*=extinction;
//composite background with inscatter, soft-blend it
backGrnd+= (1.0 - backGrnd) * dither(inscatter, screenPos);
fout output;
output.color = float4(backGrnd,1.0);
#if defined (CUSTOM_OCEAN_ON)
output.depth = zdepth; //this needs to only be done if rendering with an ocean
#endif
return output;
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/CompositeDownscaledScattering.shader.meta
================================================
fileFormatVersion: 2
guid: 94a7f67cf7303d94fa3f076bd9f33095
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/DepthBufferScattering.shader
================================================
Shader "Scatterer/DepthBufferScattering" {
SubShader {
Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
Pass { //Pass 0: render to screen directly
Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
Cull Off
ZTest Off
ZWrite [_ZwriteVariable]
Blend SrcAlpha OneMinusSrcAlpha //traditional alpha-blending
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
#include "../CommonAtmosphere.cginc"
#include "../DepthCommon.cginc"
#include "Godrays/GodraysCommon.cginc"
// #pragma multi_compile ECLIPSES_OFF ECLIPSES_ON
// #pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON
#pragma multi_compile CUSTOM_OCEAN_OFF CUSTOM_OCEAN_ON
#pragma multi_compile DITHERING_OFF DITHERING_ON
#pragma multi_compile GODRAYS_OFF GODRAYS_ON
uniform float _global_alpha;
uniform float _global_depth;
uniform float3 _planetPos; //planet origin, in world space
uniform float3 _camForward; //camera's viewing direction, in world space
uniform float _ScatteringExposure;
uniform float _PlanetOpacity; //to smooth transition from/to scaledSpace
uniform float _Post_Extinction_Tint;
uniform float extinctionThickness;
#if defined (GODRAYS_ON)
uniform sampler2D _godrayDepthTexture;
uniform float _godrayStrength;
#endif
uniform float _openglThreshold;
#if defined (CUSTOM_OCEAN_ON)
uniform sampler2D ScattererScreenCopy;
uniform sampler2D ScattererDepthCopy;
#else
uniform sampler2D ScattererScreenCopyBeforeOcean;
#endif
float4x4 CameraToWorld;
#if defined (PLANETSHINE_ON)
uniform float4x4 planetShineSources;
uniform float4x4 planetShineRGB;
#endif
struct v2f
{
float3 camPosRelPlanet : TEXCOORD0;
float4 screenPos : TEXCOORD1;
};
v2f vert(appdata_base v, out float4 outpos: SV_POSITION)
{
v2f o;
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)
outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y *_ProjectionParams.x, -1.0 , 1.0);
#else
outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y, 0.0 , 1.0);
#endif
o.camPosRelPlanet = _WorldSpaceCameraPos - _planetPos;
o.screenPos = ComputeScreenPos(outpos);
return o;
}
//this needs to only be done if rendering with an ocean
//probably hurts performance on low-spec machines so disable it
struct fout
{
float4 color : COLOR;
#if defined (CUSTOM_OCEAN_ON)
float depth : DEPTH;
#endif
};
fout frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS)
{
float2 uv = i.screenPos.xy / i.screenPos.w;
#if defined (CUSTOM_OCEAN_ON)
float zdepth = tex2Dlod(ScattererDepthCopy, float4(uv,0,0));
#else
float zdepth = tex2Dlod(_CameraDepthTexture, float4(uv,0,0));
#endif
#if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12
if (_ProjectionParams.x > 0) {uv.y = 1.0 - uv.y;}
if (zdepth == 0.0) {discard;}
#else
if (zdepth == 1.0) {discard;}
#endif
float3 absWorldPos = getPreciseWorldPosFromDepth(i.screenPos.xy / i.screenPos.w, zdepth, CameraToWorld);
float3 worldPos = absWorldPos - _planetPos; //worldPos relative to planet origin
float3 groundPos = normalize (worldPos) * Rg * 1.0008;
float Rt2 = Rg + (Rt - Rg) * _experimentalAtmoScale;
worldPos = (length(worldPos) < Rt2) ? lerp(groundPos,worldPos,_PlanetOpacity) : worldPos; //fades to flatScaledSpace planet shading to ease the transition to scaledSpace
worldPos= (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix
#if defined (CUSTOM_OCEAN_ON)
float3 backGrnd = tex2Dlod(ScattererScreenCopy, float4(uv.x, uv.y,0.0,0.0));
#else
float3 backGrnd = tex2Dlod(ScattererScreenCopyBeforeOcean, float4(uv.x, uv.y,0.0,0.0));
#endif
float minDistance = length(worldPos-i.camPosRelPlanet);
float3 inscatter=0.0;
float3 extinction=1.0;
#if defined (GODRAYS_ON)
//extinction of the full distance to the terrain, not just the lit part when factoring in godrays
float3 fullSegmentExtinction = getExtinction(i.camPosRelPlanet, worldPos, 1.0, 1.0, 1.0);
float godrayDepth = 0.0;
godrayDepth = sampleGodrayDepth(_godrayDepthTexture, uv, 1.0);
//trying to find the optical depth from the terrain level
float muTerrain = dot(normalize(worldPos), normalize(_WorldSpaceCameraPos - absWorldPos));
godrayDepth = _godrayStrength * DistanceFromOpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(worldPos), muTerrain, godrayDepth, minDistance);
worldPos -= godrayDepth * normalize(worldPos-i.camPosRelPlanet);
#endif
inscatter+= InScattering2(i.camPosRelPlanet, worldPos,SUN_DIR,extinction);
inscatter*= (minDistance <= _global_depth) ? (1 - exp(-1 * (4 * minDistance / _global_depth))) : 1.0 ; //somehow the shader compiler for OpenGL behaves differently around braces
inscatter = hdr(inscatter,_ScatteringExposure) *_global_alpha;
#if defined (GODRAYS_ON)
extinction = fullSegmentExtinction;
#endif
float extinctionAverage=(extinction.r+extinction.g+extinction.b)/3;
//lerped manually because of an issue with opengl or whatever
extinction = _Post_Extinction_Tint * extinction + (1-_Post_Extinction_Tint) * float3(extinctionAverage,extinctionAverage,extinctionAverage);
extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) );
//composite backGround by extinction
backGrnd*=extinction;
//composite background with inscatter, soft-blend it
backGrnd+= (1.0 - backGrnd) * dither(inscatter,screenPos);
fout output;
output.color = float4(backGrnd,1.0);
#if defined (CUSTOM_OCEAN_ON)
output.depth = zdepth; //this needs to only be done if rendering with an ocean
#endif
return output;
}
ENDCG
}
Pass { //Pass 1: render to 1/4 res textures
Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
Cull Off
ZTest Off
ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
#include "../CommonAtmosphere.cginc"
#include "../DepthCommon.cginc"
#include "Godrays/GodraysCommon.cginc"
// #pragma multi_compile ECLIPSES_OFF ECLIPSES_ON
// #pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON
#pragma multi_compile GODRAYS_OFF GODRAYS_ON
uniform float _global_alpha;
uniform float _global_depth;
uniform float3 _planetPos; //planet origin, in world space
uniform float3 _camForward; //camera's viewing direction, in world space
uniform float _ScatteringExposure;
uniform float _PlanetOpacity; //to smooth transition from/to scaledSpace
uniform float _Post_Extinction_Tint;
uniform float extinctionThickness;
#if defined (GODRAYS_ON)
uniform sampler2D _godrayDepthTexture;
uniform float _godrayStrength;
#endif
uniform float _openglThreshold;
uniform sampler2D ScattererDownscaledScatteringDepth;
float4x4 CameraToWorld;
#if defined (PLANETSHINE_ON)
uniform float4x4 planetShineSources;
uniform float4x4 planetShineRGB;
#endif
struct v2f
{
float3 camPosRelPlanet : TEXCOORD0;
float4 screenPos : TEXCOORD1;
};
v2f vert(appdata_base v, out float4 outpos: SV_POSITION)
{
v2f o;
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)
outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y *_ProjectionParams.x, -1.0 , 1.0);
#else
outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y, 0.0 , 1.0);
#endif
o.camPosRelPlanet = _WorldSpaceCameraPos - _planetPos;
o.screenPos = ComputeScreenPos(outpos);
return o;
}
struct fout
{
float4 col0 : COLOR0;
float4 col1 : COLOR1;
};
fout frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS)
{
fout output;
float2 uv = i.screenPos.xy / i.screenPos.w;
float zdepth = tex2Dlod(ScattererDownscaledScatteringDepth, float4(uv,0,0));
#if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12
if (_ProjectionParams.x > 0) {uv.y = 1.0 - uv.y;}
if (zdepth == 0.0) {discard;}
#else
if (zdepth == 1.0) {discard;}
#endif
float3 absWorldPos = getPreciseWorldPosFromDepth(i.screenPos.xy / i.screenPos.w, zdepth, CameraToWorld);
float3 worldPos = absWorldPos - _planetPos; //worldPos relative to planet origin
float3 groundPos = normalize (worldPos) * Rg * 1.0008;
float Rt2 = Rg + (Rt - Rg) * _experimentalAtmoScale;
worldPos = (length(worldPos) < Rt2) ? lerp(groundPos,worldPos,_PlanetOpacity) : worldPos; //fades to flatScaledSpace planet shading to ease the transition to scaledSpace
//this wasn't applied in extinction shader, not sure if it will be an issue
worldPos= (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix
float minDistance = length(worldPos-i.camPosRelPlanet);
#if defined (GODRAYS_ON)
//extinction of the full distance to the terrain, not just the lit part when factoring in godrays
float3 fullSegmentExtinction = getExtinction(i.camPosRelPlanet, worldPos, 1.0, 1.0, 1.0);
float godrayDepth = 0.0;
godrayDepth = sampleGodrayDepth(_godrayDepthTexture, uv, 1.0);
//trying to find the optical depth from the terrain level
float muTerrain = dot(normalize(worldPos), normalize(_WorldSpaceCameraPos - absWorldPos));
godrayDepth = _godrayStrength * DistanceFromOpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(worldPos), muTerrain, godrayDepth, minDistance);
worldPos -= godrayDepth * normalize(worldPos-i.camPosRelPlanet);
#endif
float3 inscatter=0.0;
float3 extinction=1.0;
inscatter+= InScattering2(i.camPosRelPlanet, worldPos,SUN_DIR,extinction);
inscatter*= (minDistance <= _global_depth) ? (1 - exp(-1 * (4 * minDistance / _global_depth))) : 1.0 ; //somehow the shader compiler for OpenGL behaves differently around braces
inscatter = hdr(inscatter,_ScatteringExposure) *_global_alpha;
output.col0.rgb = inscatter;
#if defined (GODRAYS_ON)
extinction = fullSegmentExtinction;
#endif
float extinctionAverage=(extinction.r+extinction.g+extinction.b)/3;
//lerped manually because of an issue with opengl or whatever
extinction = _Post_Extinction_Tint * extinction + (1-_Post_Extinction_Tint) * float3(extinctionAverage,extinctionAverage,extinctionAverage);
extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) );
output.col0.a = extinction.r;
output.col1 = float4(extinction.g,extinction.b,1.0,1.0);
return output;
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/DepthBufferScattering.shader.meta
================================================
fileFormatVersion: 2
guid: 470fdf3cd8176d94e8aadd242240fe3c
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/ComputeInverseShadowMatrices.compute
================================================
#pragma kernel CSMain
float4x4 unity_WorldToShadow[4];
RWStructuredBuffer resultBuffer;
//from https://answers.unity.com/questions/218333/shader-inversefloat4x4-function.html
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);
}
[numthreads(1,1,1)]
void CSMain (uint id : SV_DispatchThreadID)
{
resultBuffer[id] = inverse(unity_WorldToShadow[id]);
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/ComputeInverseShadowMatrices.compute.meta
================================================
fileFormatVersion: 2
guid: eac7b0dfe80ae8b41b71e9e0c040a433
ComputeShaderImporter:
externalObjects: {}
currentAPIMask: 131076
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/GodraysCommon.cginc
================================================
//Factor to divide the godray depth by before storing
//Half have a max value of ~65000, we need to divide the depth value to be able to store it in a half texture
#define textureDivisionFactor 100.0;
inline float sampleGodrayDepth(sampler2D _godrayDepthTexture, float2 depthUV, float _godrayStrength)
{
float godrayDepth = tex2Dlod(_godrayDepthTexture, float4(depthUV,0,0)).r;
godrayDepth*=_godrayStrength*textureDivisionFactor;
return max(godrayDepth,0.0);
}
inline float writeGodrayToTexture(float depth)
{
return depth / textureDivisionFactor;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/GodraysCommon.cginc.meta
================================================
fileFormatVersion: 2
guid: 9f2f480fb2536e54ab8493a4e7421720
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/ShadowVolumeUtils.cginc
================================================
//check if ray defined by origin and end intersects frustum
//for it to intersect frustum origin and end must be on different ends of one of the axes
bool intersectsFrustum(float3 origin, float3 end)
{
return !(origin.x > 1.0 && end.x > 1.0 || origin.x < -1.0 && end.x < -1.0)
|| !(origin.y > 1.0 && end.y > 1.0 || origin.y < -1.0 && end.y < -1.0)
|| !(origin.z < 0.0 && end.z < 0.0);
}
float rayDistanceToPoint(float3 rayOrigin, float3 rayDirection, float3 targetPoint)
{
return length(cross(rayDirection, targetPoint - rayOrigin));
}
inline bool between(float a, float b, float x)
{
return (x > a) && (x < b);
}
//cascadeWeights -> 0,1,2,3 -> zero is the most detailed -> 3 is the least detailed
//0 is in lower left corner, 1 in lower right corner, 2 in upper left corner, 3 in upper right corner, in the case of regular cascades no split spheres, not sure about splitSpheres
//Still need to check the shadowMap for each cascade though to make sure we have a depth value at that coordinate
inline fixed pickMostDetailedCascade(float4 wpos, out float4 shadowPos, sampler2D shadowMap)
{
float zdepth = 0;
shadowPos = 0;
for (int i=0; i<4;i++)
{
float3 coords = mul (unity_WorldToShadow[i], wpos).xyz;
zdepth = tex2Dlod(shadowMap, float4(coords.xy,0.0,0.0)).r;
float startX = fmod(i,2) * 0.5;
float startY = (i/2) * 0.5;
if (between(startX, startX+0.5, coords.x) && between(startY, startY+0.5, coords.y) && (zdepth > 0.0) && ((zdepth < 0.98) || (i==3) ))
{
shadowPos = float4(coords.xy, zdepth, 1.0);
return i;
}
}
return -1;
}
//same but pick between regular shadowMap and cloud shadowMap
inline fixed pickMostDetailedCascadeCloud(float4 wpos, out float4 shadowPos, sampler2D shadowMap, sampler2D cloudShadowMap, out float isCloud)
{
shadowPos = 0;
for (int i=0; i<4;i++)
{
float3 coords = mul (unity_WorldToShadow[i], wpos).xyz;
float zdepth = tex2Dlod(shadowMap, float4(coords.xy,0.0,0.0)).r;
float zdepthCloud = tex2Dlod(cloudShadowMap, float4(coords.xy,0.0,0.0)).r;
float maxDepth = max(zdepth,zdepthCloud);
float startX = fmod(i,2) * 0.5;
float startY = (i/2) * 0.5;
if (between(startX, startX+0.5, coords.x) && between(startY, startY+0.5, coords.y) && (maxDepth > 0.0) && ((maxDepth < 0.98) || (i==3) ))
{
isCloud = (zdepthCloud > zdepth) ? 1.0 : 0.0;
shadowPos = float4(coords.xy, maxDepth, 1.0);
return i;
}
}
return -1;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/ShadowVolumeUtils.cginc.meta
================================================
fileFormatVersion: 2
guid: c14a5e4bdca08454eb523515cecf43c2
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/VolumeDepth - Copy.shader.BAK
================================================
Shader "Scatterer/VolumeDepth"
{
Properties
{
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Cull Off
ZWrite Off
ZTest Always
Blend One One
// Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma hull hull
#pragma domain domain
#include "UnityCG.cginc"
#include "UnityShadowLibrary.cginc"
#include "ShadowVolumeUtils.cginc"
#pragma multi_compile DUAL_DEPTH_OFF DUAL_DEPTH_ON
sampler2D _ShadowMapTextureCopyScatterer;
sampler2D _CameraDepthTexture;
float4x4 CameraToWorld;
#if defined(DUAL_DEPTH_ON)
UNITY_DECLARE_DEPTH_TEXTURE(AdditionalDepthBuffer);
float4x4 ScattererAdditionalInvProjection;
#endif
StructuredBuffer inverseShadowMatricesBuffer;
float4x4 lightToWorld;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2t //vertex 2 tesselation
{
float4 pos : INTERNALTESSPOS;
float4 worldOriginPos : TEXCOORD0;
float4 worldEndPos : TEXCOORD1;
};
struct d2f //domain 2 frag
{
float4 pos : SV_POSITION;
float3 outputColor: TEXCOORD0;
float4 viewPos: TEXCOORD1;
float4 projPos : TEXCOORD2;
float displacedPatch : TEXCOORD3;
};
v2t vert (appdata v)
{
v2t o;
//o.pos = float4(2.0*(v.uv-0.5),0.0,1.0); //try modifying this, clip space goes from -1 to 1, our UVs go from?to?
//o.pos = float4(2.5*(v.uv-0.5),0.0,1.0);
o.pos = float4(3.0*(v.uv-0.5),0.0,1.0); //HOLY FUCK THIS FIXES THE DISAPPEARING CHUNKS WHAT THE FUCK, so there was some weird boundary issue, also 10 KM WORKS WELL, 50 KM has glitches, 35 KM also has glitches
//20 KM also still has glitches what the fuck??
o.worldOriginPos = mul(lightToWorld,o.pos);
o.worldEndPos = mul(lightToWorld,float4(o.pos.x,o.pos.y,10.0,1.0));
//o.worldEndPos = mul(lightToWorld,float4(0.5,0.5,10.0,1.0)); //eliminates box issue but causes holes
//o.worldEndPos = mul(lightToWorld,float4(o.pos.x,o.pos.y,100.0,1.0));
//o.worldEndPos = mul(lightToWorld,float4(o.pos.x,o.pos.y,10000.0,1.0));
return o;
}
struct OutputPatchConstant
{
float edge[3]: SV_TessFactor;
float inside : SV_InsideTessFactor;
};
OutputPatchConstant constantsFixed(InputPatch patch)
{
OutputPatchConstant o;
// bool isVisible = false;
//
// for (int i=0;i<3;i++)
// {
// float4 clipSpaceOrigin = mul(UNITY_MATRIX_VP, patch[i].worldOriginPos);
// float4 clipSpaceEnd = mul(UNITY_MATRIX_VP, patch[i].worldEndPos);
// isVisible = isVisible || intersectsFrustum(clipSpaceOrigin.xyz/clipSpaceOrigin.w, clipSpaceEnd.xyz/clipSpaceEnd.w); //consider this to be working though I'm not sure, maybe pass a color?
// }
//
// if (!isVisible)
// {
// o.edge[0] = 0.0;
// o.edge[1] = 0.0;
// o.edge[2] = 0.0;
// o.inside = 0.0;
// }
// else
{
// //this was really complicated to get working, and although I'm not completely sure about it, it has less holes than my cascade method
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float maxTesselationFactor = 64.0;
float distEdge0 = rayDistanceToPoint(0.5*(patch[1].worldOriginPos+patch[2].worldOriginPos), lightDir, _WorldSpaceCameraPos);
float distEdge1 = rayDistanceToPoint(0.5*(patch[2].worldOriginPos+patch[0].worldOriginPos), lightDir, _WorldSpaceCameraPos);
float distEdge2 = rayDistanceToPoint(0.5*(patch[0].worldOriginPos+patch[1].worldOriginPos), lightDir, _WorldSpaceCameraPos);
//
//// float factor0 = clamp(maxTesselationFactor * 25.0 / distEdge0,1.0,maxTesselationFactor);
//// float factor1 = clamp(maxTesselationFactor * 25.0 / distEdge1,1.0,maxTesselationFactor);
//// float factor2 = clamp(maxTesselationFactor * 25.0 / distEdge2,1.0,maxTesselationFactor);
//
float factor0 = clamp(maxTesselationFactor * 225.0 / distEdge0,1.0,maxTesselationFactor);
float factor1 = clamp(maxTesselationFactor * 225.0 / distEdge1,1.0,maxTesselationFactor);
float factor2 = clamp(maxTesselationFactor * 225.0 / distEdge2,1.0,maxTesselationFactor);
//float insideFactor = max(factor0, max(factor1,factor2)); //doesn't seem to be always correct, so try to think about it, think about what causes cracks in this case, it's normal, every triangle's max isn't necessarily the adjacent triangle's max
o.edge[0] = factor0;
o.edge[1] = factor1;
o.edge[2] = factor2;
o.inside = (factor0 + factor1 + factor2) / 3.0; //doesn't seem to be always correct, so try to think about it, think about what causes cracks in this case, it's normal, every triangle's max isn't necessarily the adjacent triangle's max
// o.edge[0] = 16;
// o.edge[1] = 16;
// o.edge[2] = 16;
// o.inside = 16; //doesn't seem to be always correct, so try to think about it, think about what causes cracks in this case, it's normal, every triangle's max isn't necessarily the adjacent triangle's max
// o.edge[0] = 1;
// o.edge[1] = 1;
// o.edge[2] = 1;
// o.inside = 1; //doesn't seem to be always correct, so try to think about it, think about what causes cracks in this case, it's normal, every triangle's max isn't necessarily the adjacent triangle's max
}
return o;
}
[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[patchconstantfunc("constantsFixed")]
[outputcontrolpoints(3)]
v2t hull(InputPatch patch, uint id : SV_OutputControlPointID)
{
return patch[id];
}
inline bool between(float a, float b, float x)
{
return (x > a) && (x < b);
}
//cascadeWeights -> 0,1,2,3 -> zero is the most detailed -> 3 is the least detailed
//0 is in lower left corner, 1 in lower right corner, 2 in upper left corner, 3 in upper right corner, in the case of regular cascades no split spheres, not sure about splitSpheres
//Still need to check the shadowMap for each cascade though to make sure we have a depth value at that coordinate
inline fixed pickMostDetailedCascade(float4 wpos, out float4 shadowPos, sampler2D shadowMap)
{
float3 coords0 = mul (unity_WorldToShadow[0], wpos).xyz;
float3 coords1 = mul (unity_WorldToShadow[1], wpos).xyz;
float3 coords2 = mul (unity_WorldToShadow[2], wpos).xyz;
float3 coords3 = mul (unity_WorldToShadow[3], wpos).xyz;
float zdepth = 0;
shadowPos = 0;
if (between(0.0, 0.5, coords0.x) && between(0.0, 0.5, coords0.y) && ((zdepth = tex2Dlod(shadowMap, float4(coords0.xy,0.0,0.0)).r) > 0.0 ) && (zdepth<1.0))
{
shadowPos = float4(coords0.xy, zdepth, 1.0);
return 0;
}
else if (between(0.5, 1.0, coords1.x) && between(0.0, 0.5, coords1.y) && ((zdepth = tex2Dlod(shadowMap, float4(coords1.xy,0.0,0.0)).r) > 0.0) && (zdepth<1.0))
{
shadowPos = float4(coords1.xy, zdepth, 1.0);
return 1;
}
else if (between(0.0, 0.5, coords2.x) && between(0.5, 1.0, coords2.y) && ((zdepth = tex2Dlod(shadowMap, float4(coords2.xy,0.0,0.0)).r) > 0.0) && (zdepth<1.0))
{
shadowPos = float4(coords2.xy, zdepth, 1.0);
return 2;
}
else if (between(0.5, 1.0, coords3.x) && between(0.5, 1.0, coords3.y) && ((zdepth = tex2Dlod(shadowMap, float4(coords3.xy,0.0,0.0)).r) > 0.0) && (zdepth<1.0))
{
shadowPos = float4(coords3.xy, zdepth, 1.0);
return 3;
}
else
{
return -1;
}
}
[domain("tri")]
d2f domain(OutputPatchConstant tessFactors,const OutputPatch vs, float3 d:SV_DomainLocation)
{
d2f o;
float3 worldPos = vs[0].worldOriginPos.xyz/vs[0].worldOriginPos.w * d.x + vs[1].worldOriginPos.xyz/vs[1].worldOriginPos.w * d.y + vs[2].worldOriginPos.xyz/vs[2].worldOriginPos.w * d.z;
float4 finalWorldPos = 0;
float4 shadowPos = 0;
fixed cascadeIndex = pickMostDetailedCascade (float4(worldPos,1.0), shadowPos, _ShadowMapTextureCopyScatterer); //only support 4 cascades here
float4x4 shadowToWorld = inverseShadowMatricesBuffer[max(cascadeIndex,0)];
//finalWorldPos = (cascadeIndex > -1) ? mul( shadowToWorld, shadowPos) : float4(worldPos.xyz - 750000.0 * normalize(_WorldSpaceLightPos0.xyz), 1.0);
//finalWorldPos = (cascadeIndex > -1) ? mul( shadowToWorld, shadowPos) : float4(_WorldSpaceCameraPos.xyz - 100000.0 * normalize(_WorldSpaceLightPos0.xyz), 1.0); //eliminates the glitchy square thing
//finalWorldPos = (cascadeIndex > -1) ? mul( shadowToWorld, shadowPos) : float4(_WorldSpaceCameraPos.xyz - 700000.0 * normalize(_WorldSpaceLightPos0.xyz), 1.0); //still has holes although it seems to project to infinity
o.displacedPatch=1.0;
finalWorldPos = mul( shadowToWorld, shadowPos);
if (cascadeIndex < 0.0)
{
// float3 coords3 = mul (unity_WorldToShadow[3], float4(worldPos,1.0)).xyz;
// //float4 madeUpShadowPos = float4( coords3.xy, 10.0, 1.0);
// float4 madeUpShadowPos = float4( 0.75,0.75, 10000.0, 1.0);
float3 worldEndPos = vs[0].worldEndPos.xyz/vs[0].worldEndPos.w * d.x + vs[1].worldEndPos.xyz/vs[1].worldEndPos.w * d.y + vs[2].worldEndPos.xyz/vs[2].worldEndPos.w * d.z; //ideally we would project this to our far plane and tag it as undisplaced
//worldEndPos-= 100000.0 * normalize(_WorldSpaceLightPos0.xyz);
finalWorldPos = float4(worldEndPos,1.0);
//finalWorldPos = float4(worldPos,1.0);
o.displacedPatch = 0.0;
}
//maybe project by the final cascade and a made up depth anyway?
//color debugging stuff
o.outputColor = float3(cascadeIndex == 0, cascadeIndex == 1, cascadeIndex ==2);
o.outputColor = (cascadeIndex == -1) ? 0 : ((cascadeIndex == 3) ? 1.0 : o.outputColor );
o.pos=UnityWorldToClipPos(finalWorldPos);
//o.pos=UnityWorldToClipPos(worldPos);
o.viewPos = float4(UnityWorldToViewPos(finalWorldPos),1.0);
o.projPos = ComputeScreenPos(o.pos);
return o;
}
float4 frag (d2f i, fixed facing : VFACE) : SV_Target
{
float2 depthUV = i.projPos.xy/i.projPos.w;
float zdepth = tex2Dlod(_CameraDepthTexture, float4(depthUV,0,0));
#ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
float4 depthClipPos = float4(depthUV, zdepth, 1.0);
depthClipPos.xyz = 2.0f * depthClipPos.xyz - 1.0f;
float4 depthViewPos = mul(unity_CameraInvProjection, depthClipPos);
float depthLength = length(depthViewPos.xyz/depthViewPos.w);
//#if defined(DUAL_DEPTH_ON)
// zdepth = SAMPLE_DEPTH_TEXTURE(AdditionalDepthBuffer, depthUV);
//
//#ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z)
// zdepth = 1 - zdepth;
//#endif
// depthClipPos = float4(depthUV, zdepth, 1.0);
// depthClipPos.xyz = 2.0f * depthClipPos.xyz - 1.0f;
// float4 depthViewPos2 = mul(ScattererAdditionalInvProjection, depthClipPos);
//
// depthLength = (depthLength < 8000) || (depthLength > 50000) ? depthLength : length(depthViewPos2.xyz/depthViewPos2.w); //the 50000 is hardcoded shadow distance, hopefully we don't even need this crap
//#endif
float viewLength = length(i.viewPos.xyz/i.viewPos.w);
//viewLength = (zdepth > 0.0) ? min(viewLength, depthLength) : viewLength;
//viewLength = (zdepth > 0.0) ? min(viewLength, depthLength) : viewLength; //this is for the sky
//viewLength = min(viewLength, depthLength);
if (viewLength>depthLength) //discard what is behind terrain, will probably not work for clouds?
viewLength = 0.0;
// if (i.displacedPatch == 0.0) //not working with a factor of 3
// viewLength = 0.0;
// return facing > 0 ? viewLength : -viewLength;
// float cameraDepth = abs(i.viewPos.z/i.viewPos.w) / 750000;
//
// if (cameraDepth >= 0.9)
// {
// viewLength = 0.0;
// //return float4(0.0,0.0,0.0,0.0);
// }
return facing > 0 ? viewLength : -viewLength;
//return float4(cameraDepth,cameraDepth,cameraDepth,1.0); //reaches nearly white on that goddamn square, why isn't it clipped?
// return facing > 0 ? float4(0.0,1.0,0.0,1.0) : float4(1.0,0.0,0.0,1.0);
//return i.displacedPatch > 0.0 ? float4(1.0,1.0,1.0,1.0) : float4(1.0,0.0,0.0,1.0);
//return float4(i.outputColor,1.0);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/VolumeDepth - Copy.shader.BAK.meta
================================================
fileFormatVersion: 2
guid: 78213b1ce4da5e6438195d405c9da0f5
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/VolumeDepth.shader
================================================
Shader "Scatterer/VolumeDepth"
{
Properties
{
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Cull Off
ZWrite Off
ZTest Always
Blend One One
// Cull Off
// Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma hull hull
#pragma domain domain
#include "UnityCG.cginc"
#include "UnityShadowLibrary.cginc"
#include "ShadowVolumeUtils.cginc"
#include "../../IntersectCommon.cginc"
#include "GodraysCommon.cginc"
//if no ocean -> use camera depth buffer: OCEAN_INTERSECT_OFF
//if ocean and in depth buffer mode -> use ocean depth buffer: OCEAN_INTERSECT_DEPTH
//if ocean and in projector mode -> use analytical ocean intersect: OCEAN_INTERSECT_ANALYTICAL
#pragma multi_compile OCEAN_INTERSECT_OFF OCEAN_INTERSECT_ANALYTICAL
#pragma multi_compile CLOUDSMAP_OFF CLOUDSMAP_ON
#pragma multi_compile DOWNSCALE_DEPTH_OFF DOWNSCALE_DEPTH_ON
sampler2D _ShadowMapTextureCopyScatterer;
sampler2D _CameraDepthTexture;
float4 _CameraDepthTexture_TexelSize;
float4x4 CameraToWorld;
float3 lightDirection;
float3 _planetPos;
float Rg;
float Rt;
float _experimentalAtmoScale;
sampler2D cloudShadowMap;
StructuredBuffer inverseShadowMatricesBuffer;
float4x4 lightToWorld;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2t //vertex 2 tesselation
{
float4 pos : INTERNALTESSPOS;
float4 worldOriginPos : TEXCOORD0;
float4 worldEndPos : TEXCOORD1;
};
struct d2f //domain 2 frag
{
float4 pos : SV_POSITION;
float4 viewPos: TEXCOORD0;
float4 projPos : TEXCOORD1;
float4 finalWorldPos : TEXCOORD2;
float isCloud : TEXCOORD3;
};
v2t vert (appdata v)
{
v2t o;
//o.pos = float4(2.0*(v.uv-0.5),0.0,1.0); //try modifying this, clip space goes from -1 to 1, our UVs go from?to?
//o.pos = float4(3.0*(v.uv-0.5),0.0,1.0); //HOLY FUCK THIS FIXES THE DISAPPEARING CHUNKS WHAT THE FUCK
o.pos = float4(2.9*(v.uv-0.5),0.0,1.0);
o.worldOriginPos = mul(lightToWorld,o.pos);
o.worldEndPos = mul(lightToWorld,float4(o.pos.x,o.pos.y,1.0,1.0));
return o;
}
struct OutputPatchConstant
{
float edge[3]: SV_TessFactor;
float inside : SV_InsideTessFactor;
};
OutputPatchConstant tesselationConstants(InputPatch patch)
{
OutputPatchConstant o;
bool isVisible = false;
for (int i=0;i<3;i++)
{
float4 clipSpaceOrigin = mul(UNITY_MATRIX_VP, patch[i].worldOriginPos);
float4 clipSpaceEnd = mul(UNITY_MATRIX_VP, patch[i].worldEndPos);
isVisible = isVisible || intersectsFrustum(clipSpaceOrigin.xyz/clipSpaceOrigin.w, clipSpaceEnd.xyz/clipSpaceEnd.w); //consider this to be working though I'm not sure, maybe pass a color?
}
if (!isVisible)
{
o.edge[0] = 0.0;
o.edge[1] = 0.0;
o.edge[2] = 0.0;
o.inside = 0.0;
}
else
{
float maxTesselationFactor = 64.0;
float distEdge0 = rayDistanceToPoint(0.5*(patch[1].worldOriginPos+patch[2].worldOriginPos), lightDirection, _WorldSpaceCameraPos);
float distEdge1 = rayDistanceToPoint(0.5*(patch[2].worldOriginPos+patch[0].worldOriginPos), lightDirection, _WorldSpaceCameraPos);
float distEdge2 = rayDistanceToPoint(0.5*(patch[0].worldOriginPos+patch[1].worldOriginPos), lightDirection, _WorldSpaceCameraPos);
float factor0 = clamp(maxTesselationFactor * 225.0 / distEdge0,1.0,maxTesselationFactor);
float factor1 = clamp(maxTesselationFactor * 225.0 / distEdge1,1.0,maxTesselationFactor);
float factor2 = clamp(maxTesselationFactor * 225.0 / distEdge2,1.0,maxTesselationFactor);
// float factor0 = clamp(maxTesselationFactor * 225.0 / distEdge0,4.0,maxTesselationFactor); // min of 4.0 is slooooow
// float factor1 = clamp(maxTesselationFactor * 225.0 / distEdge1,4.0,maxTesselationFactor);
// float factor2 = clamp(maxTesselationFactor * 225.0 / distEdge2,4.0,maxTesselationFactor);
//float insideFactor = max(factor0, max(factor1,factor2)); //doesn't seem to be always correct, so try to think about it, think about what causes cracks in this case, it's normal, every triangle's max isn't necessarily the adjacent triangle's max
o.edge[0] = factor0;
o.edge[1] = factor1;
o.edge[2] = factor2;
o.inside = (factor0 + factor1 + factor2) / 3.0; //doesn't seem to be always correct, so try to think about it, think about what causes cracks in this case, it's normal, every triangle's max isn't necessarily the adjacent triangle's max
}
return o;
}
[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[patchconstantfunc("tesselationConstants")]
[outputcontrolpoints(3)]
v2t hull(InputPatch patch, uint id : SV_OutputControlPointID)
{
return patch[id];
}
[domain("tri")]
d2f domain(OutputPatchConstant tessFactors,const OutputPatch vs, float3 d:SV_DomainLocation)
{
d2f o;
float3 worldPos = vs[0].worldOriginPos.xyz/vs[0].worldOriginPos.w * d.x + vs[1].worldOriginPos.xyz/vs[1].worldOriginPos.w * d.y + vs[2].worldOriginPos.xyz/vs[2].worldOriginPos.w * d.z;
float4 finalWorldPos = 0;
float4 shadowPos = 0;
float isCloud = 0;
//only support 4 cascades here
#if defined(CLOUDSMAP_ON)
fixed cascadeIndex = pickMostDetailedCascadeCloud (float4(worldPos,1.0), shadowPos, _ShadowMapTextureCopyScatterer, cloudShadowMap, isCloud);
#else
fixed cascadeIndex = pickMostDetailedCascade (float4(worldPos,1.0), shadowPos, _ShadowMapTextureCopyScatterer);
#endif
float4x4 shadowToWorld = inverseShadowMatricesBuffer[max(cascadeIndex,0)];
finalWorldPos = mul( shadowToWorld, shadowPos);
if (cascadeIndex < 0.0)
{
//finalWorldPos = float4(_WorldSpaceCameraPos.xyz + lightDirection * 700000,1.0); //this works well for stock but breaks with parallax, what gives?
finalWorldPos = float4(_WorldSpaceCameraPos.xyz + lightDirection * 500000,1.0);
}
o.pos=UnityWorldToClipPos(finalWorldPos);
o.viewPos = float4(UnityWorldToViewPos(finalWorldPos),1.0);
o.projPos = ComputeScreenPos(o.pos);
o.finalWorldPos = finalWorldPos;
o.isCloud = isCloud;
return o;
}
// optical depth for ray (r,mu) of length d, using analytic formula
// (mu=cos(view zenith angle)), intersections with ground ignored
// H=height scale of exponential density function
float OpticalDepth(float H, float r, float mu, float d)
{
float a = sqrt((0.5/H)*r);
float2 a01 = a*float2(mu, mu + d / r);
float2 a01s = sign(a01);
float2 a01sq = a01*a01;
float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0;
float2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * float2(1.0, exp(-d/H*(d/(2.0*r)+mu)));
return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, float2(1.0, -1.0)));
}
//gets the min depth for surrounding 4 depth texels, in downscaled case
float getMinDepth(float2 uv)
{
float2 texelSize = 0.5 * _CameraDepthTexture_TexelSize.xy;
float2 taps[4] = { float2(uv + float2(-1,-1)*texelSize), float2(uv + float2(-1,1)*texelSize),
float2(uv + float2(1,-1)*texelSize), float2(uv + float2(1,1)*texelSize) };
float depth1 = tex2D(_CameraDepthTexture, taps[0]).r;
float depth2 = tex2D(_CameraDepthTexture, taps[1]).r;
float depth3 = tex2D(_CameraDepthTexture, taps[2]).r;
float depth4 = tex2D(_CameraDepthTexture, taps[3]).r;
//Only return zero if all samples are zero, otherwise return the smallest which isn't zero
float result = depth4;
result = (result == 0.0) || (depth3 == 0.0) ? max(result, depth3) : min (result,depth3);
result = (result == 0.0) || (depth2 == 0.0) ? max(result, depth2) : min (result,depth2);
result = (result == 0.0) || (depth1 == 0.0) ? max(result, depth1) : min (result,depth1);
return result;
}
float4 frag (d2f i, fixed facing : VFACE) : SV_Target
{
float2 depthUV = i.projPos.xy/i.projPos.w;
#if defined(DOWNSCALE_DEPTH_ON)
float zdepth = getMinDepth(depthUV);
#else
float zdepth = tex2Dlod(_CameraDepthTexture, float4(depthUV,0,0));
#endif
float linearDepth = Linear01Depth(zdepth);
#ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
float4 depthClipPos = float4(depthUV, zdepth, 1.0);
depthClipPos.xyz = 2.0 * depthClipPos.xyz - 1.0;
float4 depthViewPos = mul(unity_CameraInvProjection, depthClipPos);
depthViewPos.xyz /= depthViewPos.w;
float3 rayDirection = normalize(depthViewPos.xyz);
float3 cameraForwardDir = float3(0,0,-1);
float aa = dot(rayDirection, cameraForwardDir);
depthViewPos.xyz = rayDirection * linearDepth/aa * _ProjectionParams.z;
float depthLength = length(depthViewPos.xyz);
float3 viewDir = normalize(i.finalWorldPos.xyz/i.finalWorldPos.w - _WorldSpaceCameraPos);
float viewLength = length(i.viewPos.xyz/i.viewPos.w);
if (zdepth != 1.0) //cap by terrain distance
{
viewLength = min(depthLength, viewLength);
}
// else //ray going into the sky
// {
// if (i.isCloud > 0.0)
// {
// viewLength*= 0.3; //this looks nice against the sky but where terrain and shadow meet it looks like shite
// }
// }
#if defined(OCEAN_INTERSECT_ANALYTICAL) //cap by boundary to ocean
float oceanIntersectDistance = intersectSphereOutside(_WorldSpaceCameraPos, viewDir, _planetPos, Rg);
if ((oceanIntersectDistance > 0.0) && (oceanIntersectDistance <= viewLength))
{
viewLength = oceanIntersectDistance;
}
#endif
float mu = dot(normalize(_WorldSpaceCameraPos-_planetPos), viewDir);
viewLength = OpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(_WorldSpaceCameraPos-_planetPos), mu, viewLength);
viewLength = writeGodrayToTexture(viewLength);
return facing > 0 ? viewLength : -viewLength;
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays/VolumeDepth.shader.meta
================================================
fileFormatVersion: 2
guid: 4e82512e02403f342aefc6129f4d04a4
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Godrays.meta
================================================
fileFormatVersion: 2
guid: d399317a9fcc74045a7924c9fdf2bcf6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/Preprocessing.meta
================================================
fileFormatVersion: 2
guid: 6124ad3c57404c3429a93ca37df030e9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/ProjectorScattering.shader
================================================
Shader "Scatterer/AtmosphericLocalScatter" {
SubShader {
Tags {"Queue" = "Transparent-497" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
//extinction pass
Pass {
Tags {"Queue" = "Transparent-497" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
//Cull Front
Cull Back
ZTest LEqual
ZWrite Off
Blend DstColor Zero //multiplicative
Offset 0.0, -0.07
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
#include "../CommonAtmosphere.cginc"
#pragma multi_compile CUSTOM_OCEAN_OFF CUSTOM_OCEAN_ON
uniform float _global_alpha;
uniform float _global_depth;
uniform float3 _planetPos; //planet origin, in world space
uniform float3 _camForward; //camera's viewing direction, in world space
uniform float _PlanetOpacity; //to smooth transition from/to scaledSpace
uniform float _Post_Extinction_Tint;
uniform float extinctionThickness;
uniform float _openglThreshold;
uniform float4x4 _Globals_CameraToWorld;
// //eclipse uniforms
//#if defined (ECLIPSES_ON)
// uniform float4 sunPosAndRadius; //xyz sun pos w radius
// uniform float4x4 lightOccluders1; //array of light occluders
// //for each float4 xyz pos w radius
// uniform float4x4 lightOccluders2;
//#endif
#if defined (PLANETSHINE_ON)
uniform float4x4 planetShineSources;
uniform float4x4 planetShineRGB;
#endif
struct v2f
{
float4 pos: SV_POSITION;
float4 worldPos : TEXCOORD0;
float3 _camPos : TEXCOORD1;
};
v2f vert(appdata_base v)
{
v2f o;
float4 worldPos = mul(unity_ObjectToWorld,v.vertex);
worldPos.xyz/=worldPos.w; //needed?
#if defined (CUSTOM_OCEAN_ON)
worldPos.xyz = (_PlanetOpacity < 1.0) && (length(worldPos.xyz-_planetPos) < Rg) ? _planetPos+Rg* normalize(worldPos.xyz-_planetPos) : worldPos.xyz;
#endif
o.worldPos = float4(worldPos.xyz,1.0);
o.pos = mul (UNITY_MATRIX_VP,o.worldPos);
o._camPos = _WorldSpaceCameraPos - _planetPos;
return o;
}
half4 frag(v2f i) : SV_Target
{
float3 worldPos = i.worldPos.xyz/i.worldPos.w - _planetPos; //worldPos relative to planet origin
half returnPixel = (( (length(i._camPos)-Rg) < 1000 ) && (length(worldPos) < (Rg-50))) ? 0.0: 1.0; //enable in case of ocean and close enough to water surface, works well for kerbin
worldPos= (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix
float3 extinction = getExtinction(i._camPos, worldPos, 1.0, 1.0, 1.0);
float average=(extinction.r+extinction.g+extinction.b)/3;
//lerped manually because of an issue with opengl or whatever
extinction = _Post_Extinction_Tint * extinction + (1-_Post_Extinction_Tint) * float3(average,average,average);
extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) );
extinction = (returnPixel == 1.0) ? extinction : float3(1.0,1.0,1.0);
return float4(extinction,1.0);
}
ENDCG
}
//scattering pass
Pass {
Tags {"Queue" = "Transparent-498" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
//Cull Front
Cull Back
ZTest LEqual
ZWrite [_ZwriteVariable]
Blend OneMinusDstColor One //soft additive
//Blend SrcAlpha OneMinusSrcAlpha //alpha
Offset 0.0, -0.07
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
#include "../CommonAtmosphere.cginc"
#include "Godrays/GodraysCommon.cginc"
// #pragma multi_compile ECLIPSES_OFF ECLIPSES_ON
#pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON
#pragma multi_compile CUSTOM_OCEAN_OFF CUSTOM_OCEAN_ON
#pragma multi_compile DITHERING_OFF DITHERING_ON
#pragma multi_compile GODRAYS_OFF GODRAYS_ON
uniform float _global_alpha;
uniform float _global_depth;
uniform float3 _planetPos; //planet origin, in world space
uniform float3 _camForward; //camera's viewing direction, in world space
uniform float _ScatteringExposure;
uniform float _PlanetOpacity; //to smooth transition from/to scaledSpace
#if defined (GODRAYS_ON)
uniform sampler2D _godrayDepthTexture;
uniform float _godrayStrength;
#endif
uniform float _openglThreshold;
uniform float4x4 _Globals_CameraToWorld;
// //eclipse uniforms
//#if defined (ECLIPSES_ON)
// uniform float4 sunPosAndRadius; //xyz sun pos w radius
// uniform float4x4 lightOccluders1; //array of light occluders
// //for each float4 xyz pos w radius
// uniform float4x4 lightOccluders2;
//#endif
#if defined (PLANETSHINE_ON)
uniform float4x4 planetShineSources;
uniform float4x4 planetShineRGB;
#endif
struct v2f
{
float4 worldPos : TEXCOORD0;
float3 _camPos : TEXCOORD1;
#if defined (GODRAYS_ON)
float4 projPos : TEXCOORD2;
#endif
};
v2f vert(appdata_base v, out float4 outpos: SV_POSITION)
{
v2f o;
float4 worldPos = mul(unity_ObjectToWorld,v.vertex);
worldPos.xyz/=worldPos.w; //needed?
//display scattering at ocean level when we are fading out local shading
//at the same time ocean stops rendering it's own scattering
#if defined (CUSTOM_OCEAN_ON)
worldPos.xyz = (_PlanetOpacity < 1.0) && (length(worldPos.xyz-_planetPos) < Rg) ? _planetPos+Rg* normalize(worldPos.xyz-_planetPos) : worldPos.xyz;
#endif
o.worldPos = float4(worldPos.xyz,1.0);
o.worldPos.xyz*=worldPos.w;
outpos = mul (UNITY_MATRIX_VP,o.worldPos);
o._camPos = _WorldSpaceCameraPos - _planetPos;
#if defined (GODRAYS_ON)
o.projPos = ComputeScreenPos(outpos);
#endif
return o;
}
half4 frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target
{
float3 worldPos = i.worldPos.xyz/i.worldPos.w - _planetPos; //worldPos relative to planet origin
half returnPixel = (( (length(i._camPos)-Rg) < 1000 ) && (length(worldPos) < (Rg-50))) ? 0.0: 1.0; //enable in case of ocean and close enough to water surface, works well for kerbin
float3 groundPos = normalize (worldPos) * Rg*1.0008;
float Rt2 = Rg + (Rt - Rg) * _experimentalAtmoScale;
worldPos = (length(worldPos) < Rt2) ? lerp(groundPos,worldPos,_PlanetOpacity) : worldPos; //fades to flatScaledSpace planet shading to ease the transition to scaledSpace
worldPos= (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix
float minDistance = length(worldPos-i._camPos);
float3 inscatter=0.0;
float3 extinction=1.0;
//TODO: put planetshine stuff in callable function
#if defined (PLANETSHINE_ON)
for (int j=0; j<4;++j)
{
if (planetShineRGB[j].w == 0) break;
float intensity=1;
if (planetShineSources[j].w != 1.0f)
{
intensity = 0.57f*max((0.75-dot(normalize(planetShineSources[j].xyz - worldPos),SUN_DIR)),0); //if source is not a sun compute intensity of light from angle to light source
//totally made up formula by eyeballing it
}
inscatter+=InScattering2(i._camPos, worldPos, normalize(planetShineSources[j].xyz),extinction) //lot of potential extinction recomputations here
*planetShineRGB[j].xyz*planetShineRGB[j].w*intensity;
}
#endif
#if defined (GODRAYS_ON)
float2 depthUV = i.projPos.xy/i.projPos.w;
float godrayDepth = 0.0;
godrayDepth = sampleGodrayDepth(_godrayDepthTexture, depthUV, 1.0);
//trying to find the optical depth from the terrain level
float muTerrain = dot(normalize(i.worldPos.xyz/i.worldPos.w - _planetPos), normalize(_WorldSpaceCameraPos - i.worldPos.xyz/i.worldPos.w));
godrayDepth = _godrayStrength * DistanceFromOpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(i.worldPos.xyz/i.worldPos.w - _planetPos), muTerrain, godrayDepth, minDistance);
worldPos -= godrayDepth * normalize(worldPos-i._camPos);
#endif
inscatter+= InScattering2(i._camPos, worldPos,SUN_DIR,extinction);
inscatter*= (minDistance <= _global_depth) ? (1 - exp(-1 * (4 * minDistance / _global_depth))) : 1.0 ; //somehow the shader compiler for OpenGL behaves differently around braces
//#if defined (ECLIPSES_ON)
// float eclipseShadow = 1;
//
// for (int i=0; i<4; ++i)
// {
// if (lightOccluders1[i].w <= 0) break;
// eclipseShadow*=getEclipseShadow(worldPos, sunPosAndRadius.xyz,lightOccluders1[i].xyz,
// lightOccluders1[i].w, sunPosAndRadius.w) ;
// }
//
// for (int j=0; j<4; ++j)
// {
// if (lightOccluders2[j].w <= 0) break;
// eclipseShadow*=getEclipseShadow(worldPos, sunPosAndRadius.xyz,lightOccluders2[j].xyz,
// lightOccluders2[j].w, sunPosAndRadius.w) ;
// }
//
// inscatter*=eclipseShadow;
//#endif
inscatter = hdr(inscatter,_ScatteringExposure) *_global_alpha;
return float4(dither(inscatter,screenPos)*returnPixel,1.0);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/ProjectorScattering.shader.meta
================================================
fileFormatVersion: 2
guid: 9052dff19a12cb34bb02a7f74b75c4dd
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/ScaledPlanetScattering.shader
================================================
Shader "Scatterer/ScaledPlanetScattering" {
SubShader
{
Tags {"QUEUE"="Geometry+1" "IgnoreProjector"="True" }
Pass { //extinction pass
ZWrite Off
ZTest LEqual
Cull Back
Offset -0.05, -0.05
Blend DstColor Zero //multiplicative
CGPROGRAM
#include "UnityCG.cginc"
#pragma glsl
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#include "../CommonAtmosphere.cginc"
#include "../EclipseCommon.cginc"
#include "../RingCommon.cginc"
#define useAnalyticSkyTransmittance
#pragma multi_compile ECLIPSES_OFF ECLIPSES_ON
#pragma multi_compile RINGSHADOW_OFF RINGSHADOW_ON
#pragma multi_compile LOCAL_MODE_OFF LOCAL_MODE_ON
uniform float _Alpha_Global;
uniform float extinctionTint;
uniform float extinctionThickness;
uniform float3 _Sun_WorldSunDir;
uniform float flatScaledSpaceModel;
struct v2f
{
float4 pos: SV_POSITION;
float3 worldPos : TEXCOORD0;
float3 planetOrigin: TEXCOORD1;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
//this is a hack to make the scaledScattering "fill in" for the local scattering when it gets cut off bu the limited clip plane
//essentially render both scaled scattering and sky at max depth and check the z-buffer, that way only render where localScattering hasn't rendered
#if defined(LOCAL_MODE_ON)
#ifdef SHADER_API_D3D11
OUT.pos.z = 0.00000000000001;
#else
OUT.pos.z = (1.0 - 0.00000000000001) * OUT.pos.w;
OUT.pos = ( _ProjectionParams.y > 200.0 ) ? OUT.pos : float4(2.0,2.0,2.0,1.0); //cull on near camera on OpenGL
#endif
#endif
OUT.worldPos = mul(unity_ObjectToWorld, v.vertex);
OUT.planetOrigin = mul (unity_ObjectToWorld, float4(0,0,0,1)).xyz;
#if defined(LOCAL_MODE_OFF)
OUT.worldPos *= 6000.0;
OUT.planetOrigin *= 6000.0;
#endif
return OUT;
}
half4 frag(v2f IN): COLOR
{
float3 extinction=0.0;
float3 WCP = _WorldSpaceCameraPos;
#if defined(LOCAL_MODE_OFF)
WCP*=6000.0;
#endif
float3 planetSurfacePosition = IN.worldPos-IN.planetOrigin;
float3 planetSurfaceScatteringPosition = (flatScaledSpaceModel == 1.0) ? normalize(planetSurfacePosition) * Rg * 1.0001 : planetSurfacePosition * (6005.0/6000.0); //1.0001 Rg and 6005*6000 to avoid some precision artifacts
extinction = getExtinction((WCP-IN.planetOrigin), planetSurfaceScatteringPosition, 1.0, 1.0, 1.0);
#if defined (ECLIPSES_ON)
extinction*= getEclipseShadows(IN.worldPos);
#endif
#if defined (RINGSHADOW_ON)
extinction *= getLinearRingColor(IN.worldPos, _Sun_WorldSunDir, IN.planetOrigin).a;
#endif
float average=(extinction.r+extinction.g+extinction.b)/3;
extinction = extinctionTint * extinction + (1-extinctionTint) * float3(average,average,average);
extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) );
return float4(extinction,1.0);
}
ENDCG
}
Pass { //scattering pass
ZWrite On
ZTest LEqual
Cull Back
Offset -0.05, -0.05
Blend OneMinusDstColor One //soft additive
CGPROGRAM
#include "UnityCG.cginc"
#pragma glsl
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#include "../CommonAtmosphere.cginc"
#include "../EclipseCommon.cginc"
#include "../RingCommon.cginc"
#pragma multi_compile ECLIPSES_OFF ECLIPSES_ON
#pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON
#pragma multi_compile RINGSHADOW_OFF RINGSHADOW_ON
#pragma multi_compile LOCAL_MODE_OFF LOCAL_MODE_ON
//#pragma fragmentoption ARB_precision_hint_nicest
uniform float _Alpha_Global;
uniform float3 _Sun_WorldSunDir;
uniform float _ScatteringExposure;
#if defined (PLANETSHINE_ON)
uniform float4x4 planetShineSources;
uniform float4x4 planetShineRGB;
#endif
//sampler2D _MainTex;
uniform float flatScaledSpaceModel;
struct v2f
{
float4 pos: SV_POSITION;
float3 worldPos : TEXCOORD0;
float3 planetOrigin: TEXCOORD1;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
#if defined(LOCAL_MODE_ON)
#ifdef SHADER_API_D3D11
OUT.pos.z = 0.00000000000001;
#else
OUT.pos.z = (1.0 - 0.00000000000001) * OUT.pos.w;
OUT.pos = ( _ProjectionParams.y > 200.0 ) ? OUT.pos : float4(2.0,2.0,2.0,1.0); //cull on near camera on OpenGL
#endif
#endif
OUT.worldPos = mul(unity_ObjectToWorld, v.vertex);
OUT.planetOrigin = mul (unity_ObjectToWorld, float4(0,0,0,1)).xyz;
#if defined(LOCAL_MODE_OFF)
OUT.worldPos *= 6000.0;
OUT.planetOrigin *= 6000.0;
#endif
return OUT;
}
half4 frag(v2f IN): COLOR
{
float3 inscatter=0.0;
float3 extinction=0.0;
float3 WCP = _WorldSpaceCameraPos;
#if defined(LOCAL_MODE_OFF)
WCP*=6000.0;
#endif
float3 planetSurfacePosition = IN.worldPos-IN.planetOrigin;
float3 planetSurfaceScatteringPosition = (flatScaledSpaceModel == 1.0) ? normalize(planetSurfacePosition) * Rg * 1.0001 : planetSurfacePosition * (6005.0/6000.0); //1.0001 Rg and 6005*6000 to avoid some precision artifacts
inscatter= InScattering2((WCP-IN.planetOrigin), planetSurfaceScatteringPosition, _Sun_WorldSunDir,extinction);
#if defined (ECLIPSES_ON)
inscatter *= getEclipseShadows(IN.worldPos);
#endif
#if defined (RINGSHADOW_ON)
inscatter *= getLinearRingColor(IN.worldPos, _Sun_WorldSunDir, IN.planetOrigin).a;
#endif
///////////////////PLANETSHINE///////////////////////////////
//#if defined (PLANETSHINE_ON)
// float3 inscatter2=0;
// float intensity=1;
// for (int i=0; i<4; ++i)
// {
// if (planetShineRGB[i].w == 0) break;
//
// //if source is not a sun compute intensity of light from angle to light source
// intensity=1;
// if (planetShineSources[i].w != 1.0f)
// {
//// intensity = 0.5f*(1-dot(normalize(planetShineSources[i].xyz - worldPos),WSD));
// intensity = 0.57f*max((0.75-dot(normalize(planetShineSources[i].xyz - planetSurfacePosition),WSD)),0);
// }
//
// inscatter2+=SkyRadiance3(WCP - IN.planetOrigin, d, normalize(planetShineSources[i].xyz))
// *planetShineRGB[i].xyz*planetShineRGB[i].w*intensity;
// }
//
// finalColor+=inscatter2;
//#endif
/////////////////////////////////////////////////////////////
return float4(hdr(inscatter,_ScatteringExposure),1.0);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/ScaledPlanetScattering.shader.meta
================================================
fileFormatVersion: 2
guid: f4452670096a14945b20cca112e82047
timeCreated: 1541873026
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/SkySphere.shader
================================================
Shader "Scatterer/SkySphere"
{
SubShader
{
Tags {"QUEUE"="Geometry+1" "IgnoreProjector"="True" }
Pass //extinction pass, I should really just put the shared components in an include file to clean this up
{
Tags {"QUEUE"="Geometry+1" "IgnoreProjector"="True" }
ZWrite Off
cull Front
Blend DstColor Zero //multiplicative blending
CGPROGRAM
#include "UnityCG.cginc"
#pragma glsl
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#include "../CommonAtmosphere.cginc"
#pragma multi_compile LOCAL_SKY_OFF LOCAL_SKY_ON
uniform float _Alpha_Global;
uniform float _Extinction_Tint;
uniform float extinctionMultiplier;
uniform float _experimentalExtinctionScale;
uniform float3 _Sun_WorldSunDir;
uniform float extinctionThickness;
struct v2f
{
float4 pos : SV_POSITION;
float3 worldPos : TEXCOORD0;
float3 planetOrigin: TEXCOORD1;
};
v2f vert(appdata_base v)
{
v2f OUT;
//v.vertex.xyz*= (_experimentalExtinctionScale * (Rt-Rg)+ Rg) / Rt;
OUT.pos = UnityObjectToClipPos(v.vertex);
//this is a hack to make the sky and scaledScattering "fill in" for the local scattering when it gets cut off bu the limited clip plane
//essentially render both scaled scattering and sky at max depth and check the z-buffer, that way only render where localScattering hasn't rendered
#if defined (LOCAL_SKY_ON)
#ifdef SHADER_API_D3D11
OUT.pos.z = 0.0;
#else
OUT.pos.z = OUT.pos.w;
OUT.pos = ( _ProjectionParams.y > 200.0 ) ? OUT.pos : float4(2.0,2.0,2.0,1.0); //cull on near camera on OpenGL
#endif
#endif
OUT.worldPos = mul(unity_ObjectToWorld, v.vertex);
OUT.planetOrigin = mul (unity_ObjectToWorld, float4(0,0,0,1)).xyz;
#if defined (LOCAL_SKY_OFF)
OUT.planetOrigin *= 6000; //all calculations are done in localSpace
#endif
return OUT;
}
float4 frag(v2f IN) : COLOR
{
float3 extinction = float3(1,1,1);
float3 WCP = _WorldSpaceCameraPos;
#if defined (LOCAL_SKY_OFF)
WCP *= 6000;
#endif
float3 viewDir = normalize(IN.worldPos-_WorldSpaceCameraPos);
//Rt=Rg+(Rt-Rg)*_experimentalExtinctionScale;
float3 viewdir=normalize(viewDir);
float3 camera=WCP - IN.planetOrigin;
float r = length(camera);
float rMu = dot(camera, viewdir);
float mu = rMu / r;
float r0 = r;
float mu0 = mu;
float dSq = rMu * rMu - r * r + Rt*Rt;
float deltaSq = sqrt(dSq);
float din = max(-rMu - deltaSq, 0.0);
if (din > 0.0)
{
camera += din * viewdir;
rMu += din;
mu = rMu / Rt;
r = Rt;
}
if (r > Rt || dSq < 0.0)
{
return float4(1.0,1.0,1.0,1.0);
}
extinction = Transmittance(r, mu); //this doesn't scale correctly as the view angle would have to be adjusted in a non-trivial way, and even then, intersections with the ground in the precomputed radius won't be adjusted for
//Best to switch to analyticTransmittance, with scaling of HR and HM with experimentalAtmoScale, and rescaling HR and HM when applying config to the scaled Body
float average=(extinction.r+extinction.g+extinction.b)/3;
extinction = _Extinction_Tint * extinction + (1-_Extinction_Tint) * float3(average,average,average);
extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) );
return float4(extinction,1.0);
}
ENDCG
}
Pass //inscattering pass
{
Tags {"QUEUE"="Geometry+1" "IgnoreProjector"="True" }
ZWrite Off
cull Front
//Blend One One //additive blending
Blend OneMinusDstColor One //soft additive
CGPROGRAM
#include "UnityCG.cginc"
#pragma glsl
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#include "../CommonAtmosphere.cginc"
#include "../EclipseCommon.cginc"
#include "../RingCommon.cginc"
#include "Godrays/GodraysCommon.cginc"
#pragma multi_compile ECLIPSES_OFF ECLIPSES_ON
#pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON
#pragma multi_compile RINGSHADOW_OFF RINGSHADOW_ON
#pragma multi_compile DITHERING_OFF DITHERING_ON
#pragma multi_compile GODRAYS_OFF GODRAYS_ON
#pragma multi_compile LOCAL_SKY_OFF LOCAL_SKY_ON
uniform float _Alpha_Global;
uniform float3 _Sun_WorldSunDir;
uniform float _SkyExposure;
#if defined (PLANETSHINE_ON)
uniform float4x4 planetShineSources;
uniform float4x4 planetShineRGB;
#endif
uniform sampler2D _godrayDepthTexture;
uniform float _godrayStrength;
struct v2f
{
float4 pos : SV_POSITION;
float3 worldPos : TEXCOORD0;
float3 planetOrigin: TEXCOORD1;
#if defined(GODRAYS_ON) && defined(LOCAL_SKY_ON)
float4 projPos : TEXCOORD2;
#endif
};
v2f vert(appdata_base v)
{
v2f OUT;
v.vertex.xyz*= (_experimentalAtmoScale * (Rt-Rg)+ Rg) / Rt;
OUT.pos = UnityObjectToClipPos(v.vertex);
#if defined (LOCAL_SKY_ON)
#ifdef SHADER_API_D3D11
OUT.pos.z = 0.0;
#else
OUT.pos.z = OUT.pos.w;
OUT.pos = ( _ProjectionParams.y > 200.0 ) ? OUT.pos : float4(2.0,2.0,2.0,1.0); //cull on near camera on OpenGL
#endif
#endif
OUT.worldPos = mul(unity_ObjectToWorld, v.vertex);
OUT.planetOrigin = mul (unity_ObjectToWorld, float4(0,0,0,1)).xyz;
#if defined (LOCAL_SKY_OFF)
OUT.planetOrigin *= 6000; //all calculations are done in localSpace
#endif
#if defined(GODRAYS_ON) && defined(LOCAL_SKY_ON)
OUT.projPos = ComputeScreenPos(OUT.pos);
#endif
return OUT;
}
float4 frag(v2f IN) : SV_Target
{
float3 WSD = _Sun_WorldSunDir;
float3 WCP = _WorldSpaceCameraPos;
#if defined (LOCAL_SKY_OFF)
WCP *= 6000;
#endif
float3 viewDir = normalize(IN.worldPos-_WorldSpaceCameraPos);
float3 scatteringCameraPos = WCP - IN.planetOrigin;
#if defined(GODRAYS_ON) && defined(LOCAL_SKY_ON)
float2 depthUV = IN.projPos.xy/IN.projPos.w;
float godrayDepth = 0.0;
godrayDepth = sampleGodrayDepth(_godrayDepthTexture, depthUV, 1.0);
//trying to find the optical depth from the camera level, should probably remove these from the boundary of the atmo and not the camera level?
float muCamera = dot(normalize(_WorldSpaceCameraPos - IN.planetOrigin), viewDir);
godrayDepth = DistanceFromOpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(_WorldSpaceCameraPos - IN.planetOrigin), muCamera, godrayDepth, 500000.0);
//cap by 0.3*distance to atmo boundary
float skyIntersectDistance = intersectSphereInside(_WorldSpaceCameraPos, viewDir, IN.planetOrigin, Rg + _experimentalAtmoScale * (Rt-Rg));
godrayDepth = min(0.3 * skyIntersectDistance, godrayDepth);
godrayDepth *= _godrayStrength;
scatteringCameraPos = scatteringCameraPos + viewDir * godrayDepth ;
#endif
float3 inscatter = SkyRadiance3(scatteringCameraPos, viewDir, WSD);
float3 finalColor = inscatter;
float eclipseShadow = 1;
//find worldPos of the point in the atmo we're looking at directly
//necessary for eclipses, ring shadows and planetshine
float3 worldPos;
#if defined (PLANETSHINE_ON) || defined (ECLIPSES_ON) || defined (RINGSHADOW_ON)
float interSectPt= intersectSphereInside(WCP,viewDir,IN.planetOrigin,Rt);//*_rimQuickFixMultiplier
if (interSectPt != -1)
{
worldPos = WCP + viewDir * interSectPt;
}
#endif
#if defined (ECLIPSES_ON)
if (interSectPt != -1)
{
finalColor*= getEclipseShadows(worldPos);
}
#endif
#if defined (RINGSHADOW_ON)
if (interSectPt != -1)
{
finalColor *= getLinearRingColor(worldPos, _Sun_WorldSunDir, IN.planetOrigin).a;
}
#endif
/////////////////PLANETSHINE///////////////////////////////
#if defined (PLANETSHINE_ON)
float3 inscatter2=0;
float intensity=1;
for (int i=0; i<4; ++i)
{
if (planetShineRGB[i].w == 0) break;
//if source is not a sun compute intensity of light from angle to light source
intensity=1;
if (planetShineSources[i].w != 1.0f)
{
// intensity = 0.5f*(1-dot(normalize(planetShineSources[i].xyz - worldPos),WSD));
intensity = 0.57f*max((0.75-dot(normalize(planetShineSources[i].xyz - worldPos),WSD)),0);
}
inscatter2+=SkyRadiance3(WCP - IN.planetOrigin, viewDir, normalize(planetShineSources[i].xyz)) *planetShineRGB[i].xyz*planetShineRGB[i].w*intensity;
}
finalColor+=inscatter2;
#endif
///////////////////////////////////////////////////////////
return float4(_Alpha_Global*dither(hdr(finalColor,_SkyExposure), IN.pos),1.0);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo/SkySphere.shader.meta
================================================
fileFormatVersion: 2
guid: 1e5ee557da46d59498c484308be5067e
timeCreated: 1541870321
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Atmo.meta
================================================
fileFormatVersion: 2
guid: e5d490e301a36f04a9397d7257fb157b
folderAsset: yes
timeCreated: 1552241563
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/ClippingUtils.cginc
================================================
uniform float _ScattererCameraOverlap;
//not sure if good idea to use a bool
bool fragmentInsideOfClippingRange(float depth)
{
UNITY_BRANCH
if (_ProjectionParams.z > 1000.0) //if farcamera
{
return (depth > (_ProjectionParams.y+1.0+_ScattererCameraOverlap)); //if fragment depth outside of current camera clipping range, return empty pixel
}
else //if nearcamera
{
return (depth <= (_ProjectionParams.z+1.0));
}
}
bool oceanFragmentInsideOfClippingRange(float depth)
{
UNITY_BRANCH
if (_ProjectionParams.z > 1000.0) //if farcamera
{
return (depth > (_ProjectionParams.y+_ScattererCameraOverlap)); //if fragment depth outside of current camera clipping range, return empty pixel
}
else //if nearcamera
{
return (depth <= (_ProjectionParams.z+1.0));
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/ClippingUtils.cginc.meta
================================================
fileFormatVersion: 2
guid: a3c7ce509d225e740aed9d6579e2a1e9
timeCreated: 1545494286
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/CommonAtmosphere.cginc
================================================
//
// Precomputed Atmospheric Scattering
// Copyright (c) 2008 INRIA
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: Eric Bruneton
// Modified and ported to Unity by Justin Hawkins 2013
//
// #define useHorizonHack
#define useAnalyticTransmittance
uniform sampler2D _Transmittance;
uniform sampler2D _Inscatter;
uniform sampler2D _Irradiance;
uniform float TRANSMITTANCE_W;
uniform float TRANSMITTANCE_H;
uniform float SKY_W;
uniform float SKY_H;
uniform float M_PI;
uniform float3 EARTH_POS;
// Rayleigh
uniform float HR;
uniform float3 betaR;
// Mie
uniform float HM;
uniform float3 betaMSca;
uniform float3 betaMEx;
uniform float mieG;
uniform float Rg;
uniform float Rt;
uniform float RL;
uniform float RES_R;
uniform float RES_MU;
uniform float RES_MU_S;
uniform float RES_NU;
uniform float3 SUN_DIR;
#define _Sun_Intensity 100.0;
uniform float3 _sunColor;
uniform float _experimentalAtmoScale;
uniform float _viewdirOffset;
uniform float cloudTerminatorSmooth;
#include "IntersectCommon.cginc"
/** returns the matrix {{0.0,3.0},{2.0,1.0}} */
float bayer2(const float2 xy)
{
return fmod(3.0*xy.x+2.0*xy.y,4.0);
}
/**
* Non-normalized Bayer-Pattern for power-of-two sized matrices (see https://en.wikipedia.org/wiki/Ordered_dithering for the formula).
* sizeExpOfTwo determines the dimension of the matrix to generate. For instance having sizeExpOfTwo == 3 yields an 8x8 matrix, sizeExpOfTwo == 4 yields 16x16.
* The needed normalization factor is (2**(sizeExpOfTwo))**2, so for sizeExpOfTwo == 3 the normalization would be 64.
* xy: Indices inside the matrix. For performance reasons they are not sanitized, so make sure you use valid indices.
* Floating point variant. Known to be exact up to sizeExpOfTwo == 12 (might be better, just not tested)
*/
float bayerPattern(const int sizeExpOfTwo, float2 xy)
{
float factor = 1.0;
float summand = 0.0;
//The code would get easier to read if a while-loop were used, but then the compiler would have a harder time unrolling it.
for(int i=1;i 0.0 ? float4(1.0, 0.0, 0.0, 0.5 - 0.5 / RES_MU) : float4(-1.0, H * H, H, 0.5 + 0.5 / RES_MU);
float uR = 0.5 / RES_R + rho / H * (1.0 - 1.0 / float(RES_R));
float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / RES_MU);
// paper formula
// float uMuS = 0.5 / float(RES_MU_S) + max((1.0 - exp(-3.0 * muS - 0.6)) / (1.0 - exp(-3.6)), 0.0) * (1.0 - 1.0 / float(RES_MU_S));
// better formula
float uMuS = 0.5 / RES_MU_S + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / RES_MU_S);
float _lerp = (nu + 1.0) / 2.0 * (RES_NU - 1.0);
float uNu = floor(_lerp);
_lerp = _lerp - uNu;
//original 3D lookup
//return tex3Dlod(table, float4((uNu + uMuS) / RES_NU, uMu, uR, 0)) * (1.0 - _lerp) + tex3Dlod(table, float4((uNu + uMuS + 1.0) / RES_NU, uMu, uR, 0)) * _lerp;
//new 2D lookup
float u_0 = floor(uR*RES_R-1)/(RES_R);
float u_1 = floor(uR*RES_R)/(RES_R);
float u_frac = frac(uR*RES_R);
float4 A = tex2Dlod(table, float4((uNu + uMuS) / RES_NU, uMu / RES_R + u_0,0.0,0.0)) * (1.0 - _lerp) + tex2Dlod(table, float4((uNu + uMuS + 1.0) / RES_NU, uMu / RES_R + u_0,0.0,0.0)) * _lerp;
float4 B = tex2Dlod(table, float4((uNu + uMuS) / RES_NU, uMu / RES_R + u_1,0.0,0.0)) * (1.0 - _lerp) + tex2Dlod(table, float4((uNu + uMuS + 1.0) / RES_NU, uMu / RES_R + u_1,0.0,0.0)) * _lerp;
return (A * (1.0-u_frac) + B * u_frac);
}
float3 GetMie(float4 rayMie)
{
// approximated single Mie scattering (cf. approximate Cm in paragraph "Angular precision")
// rayMie.rgb=C*, rayMie.w=Cm,r
return rayMie.rgb * rayMie.w / max(rayMie.r, 1e-4) * (betaR.r / betaR);
}
float PhaseFunctionR(float mu)
{
// Rayleigh phase function
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
}
float PhaseFunctionM(float mu)
{
// Mie phase function
return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG*mieG) * pow(1.0 + (mieG*mieG) - 2.0*mieG*mu, -3.0/2.0) * (1.0 + mu * mu) / (2.0 + mieG*mieG);
}
float3 Transmittance(float r, float mu)
{
// transmittance(=transparency) of atmosphere for infinite ray (r,mu)
// (mu=cos(view zenith angle)), intersections with ground ignored
float uR, uMu;
uR = sqrt((r - Rg) / (Rt - Rg));
uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
//#if !defined(SHADER_API_OPENGL)
return tex2Dlod (_Transmittance, float4(uMu, uR,0.0,0.0)).rgb;
//#else
// return tex2D (_Transmittance, float2(uMu, uR)).rgb;
//#endif
}
// optical depth for ray (r,mu) of length d, using analytic formula
// (mu=cos(view zenith angle)), intersections with ground ignored
// H=height scale of exponential density function
float OpticalDepth(float H, float r, float mu, float d)
{
float a = sqrt((0.5/H)*r);
float2 a01 = a*float2(mu, mu + d / r);
float2 a01s = sign(a01);
float2 a01sq = a01*a01;
float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0;
float2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * float2(1.0, exp(-d/H*(d/(2.0*r)+mu)));
return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, float2(1.0, -1.0)));
}
// transmittance(=transparency) of atmosphere for ray (r,mu) of length d
// (mu=cos(view zenith angle)), intersections with ground ignored
// uses analytic formula instead of transmittance texture
float3 AnalyticTransmittance(float r, float mu, float d)
{
return exp(- betaR * OpticalDepth(HR * _experimentalAtmoScale, r, mu, d) - betaMEx * OpticalDepth(HM * _experimentalAtmoScale, r, mu, d));
}
//search algorithm to find approx distance from optical depth
float DistanceFromOpticalDepth(float H, float r, float mu, float targetOpticalDepth, float maxLength)
{
if (targetOpticalDepth == 0.0)
return 0.0;
int maxIterations = 12;
int iteration = 0;
float minDistance = 0; //maybe also init this with the targetOpticalDepth?
float maxDistance = maxLength;
float mid = 0.5 * (maxDistance + minDistance);
float depth = 0;
while ((iteration < maxIterations) && (depth != targetOpticalDepth))
{
depth = OpticalDepth(H, r, mu, mid);
if (depth >= targetOpticalDepth)
{
maxDistance = mid;
}
else
{
minDistance = mid;
}
mid = 0.5 * (maxDistance + minDistance);
iteration++;
}
return mid;
}
//the extinction part extracted from the inscattering function
//this is for objects in atmo, computed using analyticTransmittance (better precision and less artifacts) or the precomputed transmittance table
float3 getExtinction(float3 camera, float3 _point, float shaftWidth, float scaleCoeff, float irradianceFactor)
{
float3 extinction = float3(1, 1, 1);
float3 viewdir = _point - camera;
float d = length(viewdir) * scaleCoeff;
viewdir = viewdir / d;
/////////////////////experimental block begin
float RtResized = Rg + (Rt - Rg) * _experimentalAtmoScale;
// viewdir.x += _viewdirOffset;
viewdir = normalize(viewdir);
/////////////////////experimental block end
float r = length(camera) * scaleCoeff;
if (r < 0.9 * Rg) {
camera.y += Rg;
r = length(camera) * scaleCoeff;
}
float rMu = dot(camera, viewdir);
float mu = rMu / r;
float dSq = rMu * rMu - r * r + RtResized*RtResized;
float deltaSq = sqrt(dSq);
float din = max(-rMu - deltaSq, 0.0);
if (din > 0.0 && din < d)
{
rMu += din;
mu = rMu / RtResized;
r = RtResized;
d -= din;
}
if (r <= RtResized && dSq >= 0.0)
{
// if (r < Rg + 1600.0)
// {
// // avoids imprecision problems in aerial perspective near ground
// //Not sure if necessary with extinction
// float f = (Rg + 1600.0) / r;
// r = r * f;
// }
r = (r < Rg + 1600.0) ? (Rg + 1600.0) : r; //wtf is this?
//set to analyticTransmittance only atm
#if defined (useAnalyticTransmittance)
extinction = min(AnalyticTransmittance(r, mu, d), 1.0);
#endif
}
else
{ //if out of atmosphere
extinction = float3(1,1,1);
}
return extinction;
}
//Extinction for a ray going all the way to the end of the atmosphere
//i.e an infinite ray
//for clouds so no analyticTransmittance required, may change this to use analytic transmittance so that everything is consistent
float3 getSkyExtinction(float3 camera, float3 viewdir) //instead of camera this is the cloud position
{
float3 extinction = float3(1,1,1);
float RtResized=Rg+(Rt-Rg)*_experimentalAtmoScale;
float r = length(camera);
float rMu = dot(camera, viewdir);
float mu = rMu / r;
float dSq = rMu * rMu - r * r + RtResized*RtResized;
float deltaSq = sqrt(dSq);
float din = max(-rMu - deltaSq, 0.0);
if (din > 0.0)
{
camera += din * viewdir;
rMu += din;
mu = rMu / RtResized;
r = RtResized;
}
extinction = Transmittance(r, mu);
if (r > RtResized || dSq < 0.0)
{
extinction = float3(1,1,1);
}
// //return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? float3(0,0,0) : extinction; //why is this not needed?
//
// float terminatorAngle = -sqrt(1.0 - (Rg / r) * (Rg / r));
// //return mu < terminatorAngle ? float3(0,0,0) : extinction;
//
// float index= (mu - (terminatorAngle - cloudTerminatorSmooth)) / (cloudTerminatorSmooth);
//
// if (index>1)
// return extinction;
// else if (index < 0)
// return float3(0,0,0);
// else
// return lerp (float3(0,0,0),extinction,index);
return extinction;
}
float3 sunsetExtinction(float3 camera)
{
return(getSkyExtinction(camera,SUN_DIR));
}
//Extinction for a ray going all the way to the end of the atmosphere
//i.e an infinite ray
//with analyticTransmittance
//doesn't seem to be used
float3 getSkyExtinctionAnaLyticTransmittance(float3 camera, float3 viewdir) //instead of camera this is the cloud position
{
float3 extinction = float3(1,1,1);
float RtResized=Rg+(Rt-Rg)*_experimentalAtmoScale;
float r = length(camera);
float rMu = dot(camera, viewdir);
float mu = rMu / r;
float dSq = rMu * rMu - r * r + RtResized*RtResized;
float deltaSq = sqrt(dSq);
float din = max(-rMu - deltaSq, 0.0);
if (din > 0.0)
{
camera += din * viewdir;
rMu += din;
mu = rMu / RtResized;
r = RtResized;
}
//extinction = Transmittance(r, mu);
float distInAtmo = abs(intersectSphereInside(camera,viewdir,float3(0,0,0),RtResized));
extinction = AnalyticTransmittance(r, mu, distInAtmo);
if (r > RtResized || dSq < 0.0)
{
extinction = float3(1,1,1);
}
//return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? float3(0,0,0) : extinction; //why is this not needed?
// float terminatorAngle = -sqrt(1.0 - (Rg / r) * (Rg / r));
// //return mu < terminatorAngle ? float3(0,0,0) : extinction;
//
// float index= (mu - (terminatorAngle - cloudTerminatorSmooth)) / (cloudTerminatorSmooth);
//
// if (index>1)
// return extinction;
// else if (index < 0)
// return float3(0,0,0);
// else
// return lerp (float3(0,0,0),extinction,index);
return extinction;
}
float3 SkyRadiance2(float3 camera, float3 viewdir, float3 sundir, out float3 extinction)
{
extinction = float3(1,1,1);
float3 result = float3(0,0,0);
float RtResized=Rg+(Rt-Rg)*_experimentalAtmoScale;
//viewdir.x+=_viewdirOffset;
viewdir=normalize(viewdir);
//camera *= scale;
//camera += viewdir * max(shaftWidth, 0.0);
float r = length(camera);
float rMu = dot(camera, viewdir);
rMu+=_viewdirOffset * r;
float mu = rMu / r;
// float r0 = r;
// float mu0 = mu;
float dSq = rMu * rMu - r * r + RtResized*RtResized;
float deltaSq = sqrt(dSq);
float din = max(-rMu - deltaSq, 0.0);
if (din > 0.0)
{
camera += din * viewdir;
rMu += din;
mu = rMu / RtResized;
r = RtResized;
}
float nu = dot(viewdir, sundir);
float muS = dot(camera, sundir) / r;
// float4 inScatter = Texture4D(_Sky_Inscatter, r, rMu / r, muS, nu);
float4 inScatter = Texture4D(_Inscatter, r, rMu / r, muS, nu,RtResized);
extinction = Transmittance(r, mu);
if (r <= RtResized && dSq >= 0.0)
{
// if (shaftWidth > 0.0)
// {
// if (mu > 0.0) {
// inScatter *= min(Transmittance(r0, mu0) / Transmittance(r, mu), 1.0).rgbr;
// } else {
// inScatter *= min(Transmittance(r, -mu) / Transmittance(r0, -mu0), 1.0).rgbr;
// }
// }
float3 inScatterM = GetMie(inScatter);
float phase = PhaseFunctionR(nu);
float phaseM = PhaseFunctionM(nu);
result = inScatter.rgb * phase + inScatterM * phaseM;
}
else
{
result = float3(0,0,0);
extinction = float3(1,1,1);
}
result*=_sunColor;
return result * _Sun_Intensity;
}
//same as 2 but with no extinction
float3 SkyRadiance3(float3 camera, float3 viewdir, float3 sundir)//, out float3 extinction)//, float shaftWidth)
{
float3 result = float3(0,0,0);
float RtResized=Rg+(Rt-Rg)*_experimentalAtmoScale;
//viewdir.x+=_viewdirOffset;
viewdir=normalize(viewdir);
//camera *= scale;
//camera += viewdir * max(shaftWidth, 0.0);
float r = max(length(camera),Rg+100.0); //fixes artifacts when camera is crossing water surface
float rMu = dot(camera, viewdir);
rMu+=_viewdirOffset * r;
//float mu = rMu / r;
float dSq = rMu * rMu - r * r + RtResized*RtResized;
float deltaSq = sqrt(dSq);
float din = max(-rMu - deltaSq, 0.0);
if (din > 0.0)
{
camera += din * viewdir;
rMu += din;
//mu = rMu / RtResized;
r = RtResized;
}
float nu = dot(viewdir, sundir);
float muS = dot(camera, sundir) / r;
float4 inScatter = Texture4D(_Inscatter, r, rMu / r, muS, nu,RtResized);
//extinction = Transmittance(r, mu);
if (r <= RtResized && dSq >= 0.0)
{
// if (shaftWidth > 0.0)
// {
// if (mu > 0.0) {
// inScatter *= min(Transmittance(r0, mu0) / Transmittance(r, mu), 1.0).rgbr;
// } else {
// inScatter *= min(Transmittance(r, -mu) / Transmittance(r0, -mu0), 1.0).rgbr;
// }
// }
float3 inScatterM = GetMie(inScatter);
float phase = PhaseFunctionR(nu);
float phaseM = PhaseFunctionM(nu);
result = inScatter.rgb * phase + inScatterM * phaseM;
}
else
{
result = float3(0,0,0);
//extinction = float3(1,1,1);
}
result*=_sunColor;
return result * _Sun_Intensity;
}
float2 GetIrradianceUV(float r, float muS)
{
float uR = (r - Rg) / (Rt - Rg);
float uMuS = (muS + 0.2) / (1.0 + 0.2);
return float2(uMuS, uR);
}
float3 Irradiance(sampler2D samp, float r, float muS)
{
float2 uv = GetIrradianceUV(r, muS);
return tex2Dlod(samp,float4(uv,0.0,0.0)).rgb;
}
// incident sky light at given position, integrated over the hemisphere (irradiance)
// r=length(x)
// muS=dot(x,s) / r
float3 SkyIrradiance(float r, float muS)
{
return Irradiance(_Irradiance, r, muS) * _sunColor * _Sun_Intensity;
}
// transmittance(=transparency) of atmosphere for infinite ray (r,mu)
// (mu=cos(view zenith angle)), or zero if ray intersects ground
// Change to analytic?
float3 TransmittanceWithShadow(float r, float mu)
{
return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? float3(0,0,0) : Transmittance(r, mu);
}
// incident sun light at given position (radiance)
// r=length(x)
// muS=dot(x,s) / r
float3 SunRadiance(float r, float muS)
{
return TransmittanceWithShadow(r, muS) * _sunColor * _Sun_Intensity;
}
void SunRadianceAndSkyIrradiance(float3 worldP, float3 worldN, float3 worldS, out float3 sunL, out float3 skyE)
{
// worldP *= scale;
float r = length(worldP);
if (r < 0.9 * Rg) {
worldP.z += Rg;
r = length(worldP);
}
float3 worldV = worldP / r; // vertical vector
float muS = dot(worldV, worldS);
float sunOcclusion = 1.0;// - sunShadow;
//sunL = SunRadiance(r, muS) * sunOcclusion;
sunL = TransmittanceWithShadow(r, muS) * _sunColor * _Sun_Intensity;//removed _Sun_Intensity multiplier
// ambient occlusion due only to slope, does not take self shadowing into account
float skyOcclusion = (1.0 + dot(worldV, worldN)) * 0.5;
// factor 2.0 : hack to increase sky contribution (numerical simulation of
// "precompued atmospheric scattering" gives less luminance than in reality)
skyE = 2.0 * SkyIrradiance(r, muS) * skyOcclusion;
}
float3 SimpleSkyirradiance(float3 worldP, float3 worldN, float3 worldS)
{
float r = length(worldP);
if (r < 0.9 * Rg) {
worldP.z += Rg;
r = length(worldP);
}
float3 worldV = worldP / r; // vertical vector
float muS = dot(worldV, worldS);
// ambient occlusion due only to slope, does not take self shadowing into account
float skyOcclusion = (1.0 + dot(worldV, worldN)) * 0.5;
// factor 2.0 : hack to increase sky contribution (numerical simulation of
// "precompued atmospheric scattering" gives less luminance than in reality)
float3 skyE = 2.0 * SkyIrradiance(r, muS) * skyOcclusion;
return skyE;
}
//InScattering with modified atmo heights
float3 InScattering2(float3 camera, float3 _point, float3 sunDir, out float3 extinction) {
// single scattered sunlight between two points
// camera=observer
// point=point on the ground
// sundir=unit vector towards the sun
// return scattered light and extinction coefficient
float3 result = float3(0, 0, 0);
extinction=1.0;
float3 viewdir = _point - camera;
float d = length(viewdir);
viewdir = viewdir / d;
float RtResized = Rg + (Rt - Rg) * _experimentalAtmoScale;
viewdir = normalize(viewdir);
float r = length(camera);
if (r < 0.9 * Rg)
{
camera.y += Rg;
_point.y += Rg;
r = length(camera);
}
float rMu = dot(camera, viewdir);
float mu = rMu / r;
float r0 = r;
float mu0 = mu;
float muExtinction=mu;
_point -= viewdir * clamp(1.0, 0.0, d);
float dSq = rMu * rMu - r * r + RtResized*RtResized;
float deltaSq = sqrt(dSq);
float din = max(-rMu - deltaSq, 0.0);
if (din > 0.0 && din < d)
{
camera += din * viewdir;
rMu += din;
mu = rMu / RtResized;
r = RtResized;
d -= din;
}
if (r <= RtResized && dSq >= 0.0)
{
float nu = dot(viewdir, sunDir);
float muS = dot(camera, sunDir) / r;
float4 inScatter;
if (r < Rg + 1600.0) {
// avoids imprecision problems in aerial perspective near ground
float f = (Rg + 1600.0) / r;
r = r * f;
rMu = rMu * f;
_point = _point * f;
}
float r1 = length(_point);
float rMu1 = dot(_point, viewdir);
float mu1 = rMu1 / r1;
float muS1 = dot(_point, sunDir) / r1;
// #if defined (useAnalyticTransmittance)
extinction = min(AnalyticTransmittance(r, mu, d), 1.0);
//#else
// if (mu > 0.0)
// {
// extinction = min(Transmittance(r, mu, Rt) / Transmittance(r1, mu1, Rt), 1.0);
// }
// else
// {
// extinction = min(Transmittance(r1, -mu1, Rt) / Transmittance(r, -mu, Rt), 1.0);
// }
// #endif
// #ifdef useHorizonHack
//reduces it but doesn't fix it, have to try to get the other one
//const float EPS = 0.004;
const float EPS = 0.01;
float lim = -sqrt(1.0 - (Rg / r) * (Rg / r));
if (abs(mu - lim) < EPS)
{
//float a = ((mu - lim) + EPS) / (2.0 * EPS);
float a = saturate(2.0 * ((mu - lim) + EPS) / (2.0 * EPS));
//these make inScatterA black, let's try without and increase EPS to 0.01
//almost does it, still a faint outline of it visible, maybe debug if sqrt doesn't need to be 0 below?
//trying 0.04, nope, still a faint outline visible
//back to 0.01 with sqrt fix, doesn't work either, weird, maybe extinction is too strong?
// mu = lim - EPS;
// r1 = r * r + d * d + 2.0 * r * d * mu;
// r1 = r1 > 0.0 ? sqrt(r1) : 1e30;
// mu1 = (r * mu + d) / r1;
float4 inScatter0 = Texture4D(_Inscatter, r, mu, muS, nu, RtResized);
float4 inScatter1 = Texture4D(_Inscatter, r1, mu1, muS1, nu, RtResized);
float4 inScatterA = max(inScatter0 - inScatter1 * extinction.rgbr, 0.0);
mu = lim + EPS;
r1 = sqrt(r * r + d * d + 2.0 * r * d * mu);
mu1 = (r * mu + d) / r1;
inScatter0 = Texture4D(_Inscatter, r, mu, muS, nu, RtResized);
inScatter1 = Texture4D(_Inscatter, r1, mu1, muS1, nu, RtResized);
float4 inScatterB = max(inScatter0 - inScatter1 * extinction.rgbr, 0.0);
inScatter = lerp(inScatterA, inScatterB, a);
}
else
// #endif
{
float4 inScatter0 = Texture4D(_Inscatter, r, mu, muS, nu,RtResized);
float4 inScatter1 = Texture4D(_Inscatter, r1, mu1, muS1, nu,RtResized);
inScatter = max(inScatter0 - inScatter1 * extinction.rgbr, 0.0);
}
// avoids imprecision problems in Mie scattering when sun is below horizon
inScatter.w *= smoothstep(0.00, 0.02, muS);
float3 inScatterM = GetMie(inScatter);
float phase = PhaseFunctionR(nu);
float phaseM = PhaseFunctionM(nu);
result = inScatter.rgb * phase + inScatterM * phaseM;
}
else
{ //if out of atmosphere
result = float3(0,0,0);
// extinction = float3(1,1,1);
}
return result * _sunColor * _Sun_Intensity;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/CommonAtmosphere.cginc.meta
================================================
fileFormatVersion: 2
guid: ac742e1acf5f82f45b9d8ec53fe15b21
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DecodeEncode/DecodedToFloat.shader
================================================
Shader "EncodeFloat/DecodeToFloat"
{
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#include "UnityCG.cginc"
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _TexR, _TexG, _TexB, _TexA;
uniform float _Max, _Min;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
OUT.uv = v.texcoord.xy;
return OUT;
}
//This is a built in function but I like to see the code
float decodeFloatRGBA( float4 rgba )
{
return dot( rgba, float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) );
}
float4 frag(v2f IN) : COLOR
{
float R = decodeFloatRGBA(tex2D(_TexR, IN.uv.xy));
float G = decodeFloatRGBA(tex2D(_TexG, IN.uv.xy));
float B = decodeFloatRGBA(tex2D(_TexB, IN.uv.xy));
float A = decodeFloatRGBA(tex2D(_TexA, IN.uv.xy));
return (float4(R,G,B,A) * _Max) - _Min;
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DecodeEncode/DecodedToFloat.shader.meta
================================================
fileFormatVersion: 2
guid: 6aeb6a309c9b39647b273d5f92e593dd
timeCreated: 1459689856
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DecodeEncode/WriteToFloat.shader
================================================
Shader "EncodeFloat/WriteToFloat"
{
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#include "UnityCG.cginc"
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _TexR, _TexG, _TexB, _TexA;
uniform float _Max, _Min;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
OUT.uv = v.texcoord.xy;
return OUT;
}
//This is a built in function but I like to see the code
float decodeFloatRGBA( float4 rgba )
{
return dot( rgba, float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) );
}
float4 frag(v2f IN) : COLOR
{
float R = decodeFloatRGBA(tex2D(_TexR, IN.uv.xy));
float G = decodeFloatRGBA(tex2D(_TexG, IN.uv.xy));
float B = decodeFloatRGBA(tex2D(_TexB, IN.uv.xy));
float A = decodeFloatRGBA(tex2D(_TexA, IN.uv.xy));
return (float4(R,G,B,A) * _Max) - _Min;
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DecodeEncode/WriteToFloat.shader.meta
================================================
fileFormatVersion: 2
guid: 2c80ef0306e06ac4d8a4b0fe7e4536ac
timeCreated: 1459689856
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DecodeEncode.meta
================================================
fileFormatVersion: 2
guid: 8e6115ff67c8ba44ba8780322ca78ef8
folderAsset: yes
timeCreated: 1541842845
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth/CopyCameraDepth.shader
================================================
Shader "Scatterer/CopyCameraDepth"
{
SubShader
{
Pass //pass 0, simple copy from camera's depth texture
{
ZTest Always Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _CameraDepthTexture;
v2f vert( appdata_img v )
{
v2f o = (v2f)0;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
float frag(v2f IN) : SV_Depth
{
return float4(tex2Dlod(_CameraDepthTexture, float4(IN.uv,0.0,0.0)).rgb,1.0);
}
ENDCG
}
Pass //pass 1, same as 0 but with a small bias for depth pre-pass merging to screen
{
ZTest Always Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _CameraDepthTexture;
v2f vert( appdata_img v )
{
v2f o = (v2f)0;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
float frag(v2f IN) : SV_Depth
{
return float4(tex2Dlod(_CameraDepthTexture, float4(IN.uv,0.0,0.0)).r * 0.9999, 0.0, 0.0, 1.0);
}
ENDCG
}
Pass //pass 2, same as 0 but from _MainTex
{
ZTest Always Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
v2f vert( appdata_img v )
{
v2f o = (v2f)0;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
float frag(v2f IN) : SV_Depth
{
return float4(tex2Dlod(_MainTex, float4(IN.uv,0.0,0.0)).rgb,1.0);
}
ENDCG
}
}
Fallback off
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth/CopyCameraDepth.shader.meta
================================================
fileFormatVersion: 2
guid: 8db4dc37ed52fc24ba715aaa8e0fd20f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth/DepthToDistance.shader
================================================
Shader "Scatterer/DepthToDistance" {
SubShader {
Tags {"IgnoreProjector" = "True" "RenderType" = "Transparent"}
Pass {
Cull Off
ZTest Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha // Alpha blending
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
uniform sampler2D _CameraDepthTexture;
struct v2f
{
float4 pos: SV_POSITION;
float2 uv: TEXCOORD1;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = ComputeNonStereoScreenPos(o.pos);
return o;
}
half4 frag(v2f i) : SV_Target
{
float zdepth = tex2Dlod(_CameraDepthTexture, float4(i.uv,0,0));
#ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
float4 clipPos = float4(i.uv, zdepth, 1.0);
clipPos.xyz = 2.0f * clipPos.xyz - 1.0f;
float4 camPos = mul(unity_CameraInvProjection, clipPos);
camPos.xyz /= camPos.w;
camPos.z *= -1;
float fragDistance = length(camPos.xyz) / 750000.0;
return float4(fragDistance,fragDistance,fragDistance, (zdepth < 1.0) ? 1.0 : 0.0); //discard if zdepth is 1.0, ie nothing written to depth texture
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth/DepthToDistance.shader.meta
================================================
fileFormatVersion: 2
guid: 34fc60e2fe0cbfa4a87375cdfff9dc86
timeCreated: 1550493086
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth/DownscaleDepth.shader
================================================
Shader "Scatterer/DownscaleDepth"
{
SubShader
{
Pass //Pass 0, downscale default buffer to 1/4
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _CameraDepthTexture;
float4 _CameraDepthTexture_TexelSize; // (1.0/width, 1.0/height, width, height)
v2f vert( appdata_img v )
{
v2f o = (v2f)0;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
float4 frag(v2f input) : SV_Target
{
float2 texelSize = 0.5 * _CameraDepthTexture_TexelSize.xy;
float2 taps[4] = { float2(input.uv + float2(-1,-1)*texelSize),
float2(input.uv + float2(-1,1)*texelSize),
float2(input.uv + float2(1,-1)*texelSize),
float2(input.uv + float2(1,1)*texelSize) };
float depth1 = tex2D(_CameraDepthTexture, taps[0]).r;
float depth2 = tex2D(_CameraDepthTexture, taps[1]).r;
float depth3 = tex2D(_CameraDepthTexture, taps[2]).r;
float depth4 = tex2D(_CameraDepthTexture, taps[3]).r;
//float result = min(depth1, min(depth2, min(depth3, depth4))); //takes min depth, for reverse Z equivalent to taking farthest, may or may not be better for depth discontinuities, test both
//good but should eliminate samples with depth 0.0
// //Only return zero if all samples are zero, otherwise return the smallest which isn't zero
float result = depth4;
result = (result == 0.0) || (depth3 == 0.0) ? max(result, depth3) : min (result,depth3);
result = (result == 0.0) || (depth2 == 0.0) ? max(result, depth2) : min (result,depth2);
result = (result == 0.0) || (depth1 == 0.0) ? max(result, depth1) : min (result,depth1);
return result;
}
ENDCG
}
Pass //Pass 1, downscale other buffer to a further 1/4 (so 1/16 final)
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D ScattererDownscaledDepthIntermediate;
float4 ScattererDownscaledDepthIntermediate_TexelSize; // (1.0/width, 1.0/height, width, height)
v2f vert( appdata_img v )
{
v2f o = (v2f)0;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
float4 frag(v2f input) : SV_Target
{
float2 texelSize = 0.5 * ScattererDownscaledDepthIntermediate_TexelSize.xy;
float2 taps[4] = { float2(input.uv + float2(-1,-1)*texelSize),
float2(input.uv + float2(-1,1)*texelSize),
float2(input.uv + float2(1,-1)*texelSize),
float2(input.uv + float2(1,1)*texelSize) };
float depth1 = tex2D(ScattererDownscaledDepthIntermediate, taps[0]).r;
float depth2 = tex2D(ScattererDownscaledDepthIntermediate, taps[1]).r;
float depth3 = tex2D(ScattererDownscaledDepthIntermediate, taps[2]).r;
float depth4 = tex2D(ScattererDownscaledDepthIntermediate, taps[3]).r;
//Only return zero if all samples are zero, otherwise return the smalles which isn't zero
float result = depth4;
result = (result == 0.0) || (depth3 == 0.0) ? max(result, depth3) : min (result,depth3);
result = (result == 0.0) || (depth2 == 0.0) ? max(result, depth2) : min (result,depth2);
result = (result == 0.0) || (depth1 == 0.0) ? max(result, depth1) : min (result,depth1);
return result;
}
ENDCG
}
Pass //Pass 2, perform bilateral blurring
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D ScattererDownscaledDepth;
float4 ScattererDownscaledDepth_TexelSize; // (1.0/width, 1.0/height, width, height)
float2 BlurDir;
sampler2D TextureToBlur;
float4 TextureToBlur_TexelSize;
v2f vert( appdata_img v )
{
v2f o = (v2f)0;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
float4 frag(v2f input) : SV_Target
{
const float offset[4] = { 0, 1, 2, 3 };
const float weight[4] = { 0.266, 0.213, 0.1, 0.036 };
//linearise depth [0-1]
float centralDepth = Linear01Depth(tex2D(ScattererDownscaledDepth, input.uv));
float result = tex2D(TextureToBlur, input.uv).r * weight[0];
float totalWeight = weight[0];
//float BlurDepthFalloff = 0.01; //probably change this
//float BlurDepthFalloff = 1.0; //guess this is too much, try 0.1
float BlurDepthFalloff = 0.1; //seems ok but doesn't fix my issue though
[unroll]
for (int i = 1; i < 4; i++)
{
float depth = Linear01Depth(tex2D(ScattererDownscaledDepth, (input.uv + BlurDir * offset[i] * ScattererDownscaledDepth_TexelSize.xy )));
float w = abs(depth-centralDepth)* BlurDepthFalloff;
w = exp(-w*w);
result += tex2D(TextureToBlur, ( input.uv + BlurDir * offset[i] * TextureToBlur_TexelSize.xy )).r * w * weight[i];
totalWeight += w * weight[i];
depth = Linear01Depth(tex2D(ScattererDownscaledDepth, (input.uv - BlurDir * offset[i] * ScattererDownscaledDepth_TexelSize.xy )));
w = abs(depth-centralDepth)* BlurDepthFalloff;
w = exp(-w*w);
result += tex2D(TextureToBlur, ( input.uv - BlurDir * offset[i] * TextureToBlur_TexelSize.xy )).r * w* weight[i];
totalWeight += w * weight[i];
}
return float4(result,result,result,1.0);
}
ENDCG
}
Pass //Pass 3, downscale custom depth buffer to 1/4
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D ScattererDepthCopy;
float4 ScattererDepthCopy_TexelSize; // (1.0/width, 1.0/height, width, height)
v2f vert( appdata_img v )
{
v2f o = (v2f)0;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
float4 frag(v2f input) : SV_Target
{
float2 texelSize = 0.5 * ScattererDepthCopy_TexelSize.xy;
float2 taps[4] = { float2(input.uv + float2(-1,-1)*texelSize),
float2(input.uv + float2(-1,1)*texelSize),
float2(input.uv + float2(1,-1)*texelSize),
float2(input.uv + float2(1,1)*texelSize) };
float depth1 = tex2D(ScattererDepthCopy, taps[0]).r;
float depth2 = tex2D(ScattererDepthCopy, taps[1]).r;
float depth3 = tex2D(ScattererDepthCopy, taps[2]).r;
float depth4 = tex2D(ScattererDepthCopy, taps[3]).r;
//Only return zero if all samples are zero, otherwise return the smallest which isn't zero
float result = depth4;
result = (result == 0.0) || (depth3 == 0.0) ? max(result, depth3) : min (result,depth3);
result = (result == 0.0) || (depth2 == 0.0) ? max(result, depth2) : min (result,depth2);
result = (result == 0.0) || (depth1 == 0.0) ? max(result, depth1) : min (result,depth1);
return result;
}
ENDCG
}
}
Fallback off
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth/DownscaleDepth.shader.meta
================================================
fileFormatVersion: 2
guid: 2cb24b5a5793c654e899a06bf08ec3ae
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Depth.meta
================================================
fileFormatVersion: 2
guid: 230f3ac09b9ef234cba81ade9bd0e32a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DepthCommon.cginc
================================================
#include "UnityCG.cginc"
uniform sampler2D _CameraDepthTexture;
uniform sampler2D _customDepthTexture;
float3 getViewSpacePosFromDepth(float2 uv)
{
uv.y = 1.0 - uv.y;
float zdepth = tex2Dlod(_CameraDepthTexture, float4(uv,0,0));
#ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
float4 clipPos = float4(uv, zdepth, 1.0);
clipPos.xyz = 2.0f * clipPos.xyz - 1.0f;
float4 camPos = mul(unity_CameraInvProjection, clipPos);
camPos.xyz /= camPos.w;
camPos.z *= -1;
return camPos.xyz;
}
float3 getPreciseViewSpacePosFromDepth(float2 uv)
{
uv.y = 1.0 - uv.y;
float zdepth = tex2Dlod(_CameraDepthTexture, float4(uv,0,0));
float depth = Linear01Depth(zdepth);
#ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
float4 clipPos = float4(uv, zdepth, 1.0);
clipPos.xyz = 2.0f * clipPos.xyz - 1.0f;
float4 camPos = mul(unity_CameraInvProjection, clipPos);
camPos.xyz /= camPos.w;
camPos.z *= -1;
float3 rayDirection = normalize(camPos.xyz);
float3 cameraForwardDir = float3(0,0,1);
float aa = dot(rayDirection, cameraForwardDir);
float3 vposPersp = rayDirection * depth/aa * _ProjectionParams.z;
return vposPersp;
}
float getScattererFragDistance(float2 uv)
{
#if defined (SCATTERER_MERGED_DEPTH_ON)
return tex2Dlod(_customDepthTexture, float4(uv,0,0)).r* 750000;
#else
return length(getPreciseViewSpacePosFromDepth(uv).xyz);
#endif
}
//checks if we have anything in the depth buffer or is empty at coordinate
//used by sunflare to check if we should block the sun
fixed checkDepthBufferEmpty(float2 uv)
{
#if defined (SCATTERER_MERGED_DEPTH_ON)
float depth = tex2Dlod(_customDepthTexture,float4(uv,0.0,0.0)); //if there's something in the way don't render the flare
return (depth < 1.0) ? 0.0 : 1.0 ;
#else
float zdepth = tex2Dlod(_CameraDepthTexture, float4(uv,0,0));
#ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
return (zdepth < 1.0) ? 0.0 : 1.0 ;
#endif
}
//get WorldPos from depth using inaccurate invprojection method
float3 getWorldPosFromDepth(float2 uv, float zdepth, float4x4 CameraToWorld)
{
#ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
float4 clipPos = float4(uv, zdepth, 1.0);
clipPos.xyz = 2.0f * clipPos.xyz - 1.0f;
float4 camPos = mul(unity_CameraInvProjection, clipPos);
float4 worldPos = mul(CameraToWorld,camPos);
return (worldPos.xyz/worldPos.w);
}
//hybrid method using the depth from the ray method and the direction from the invprojection method
//seems to work pretty well
//could be optimized further by moving the raydirection calculation to the vertex shader
float3 getPreciseWorldPosFromDepth(float2 uv, float zdepth, float4x4 CameraToWorld)
{
float depth = Linear01Depth(zdepth);
#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
float4 clipPos = float4(uv, zdepth, 1.0);
clipPos.xyz = 2.0f * clipPos.xyz - 1.0f;
float4 camPos = mul(unity_CameraInvProjection, clipPos);
camPos.xyz /= camPos.w;
float3 rayDirection = normalize(camPos.xyz);
float3 cameraForwardDir = float3(0,0,-1);
float aa = dot(rayDirection, cameraForwardDir);
camPos.xyz = rayDirection * depth/aa * _ProjectionParams.z;
float4 worldPos = mul(CameraToWorld,float4(camPos.xyz,1.0));
return (worldPos.xyz/worldPos.w);
}
//Refines the inaccurate worldPos from invprojection with a search algorithm
//While this gives good results, it is no longer needed, the hybrid ray/projmatrix method is faster and gives similar precision
float getRefinedDistanceFromDepth(float unrefinedDistance, float zdepth, float3 worldViewDir)
{
//maybe scale these based on distance?
const int maxIterations = 10; //seems about perfect
int iteration = 0;
//This should considerably reduce the search space
float maxSearchDistance = unrefinedDistance * 1.30;
float minSearchDistance = unrefinedDistance * 0.70;
float mid = 0;
float3 worldPos0 = float3(0.0,0.0,0.0);
float4 clipPos = float4(0.0,0.0,0.0,1.0);
float depth = -10.0;
while ((iteration < maxIterations) && (depth != zdepth))
{
mid = 0.5 * (maxSearchDistance + minSearchDistance);
worldPos0 = _WorldSpaceCameraPos + worldViewDir * mid;
clipPos = mul(UNITY_MATRIX_VP, float4(worldPos0,1.0));
depth = clipPos.z/clipPos.w;
maxSearchDistance = (depth < zdepth) ? mid : maxSearchDistance;
minSearchDistance = (depth > zdepth) ? mid : minSearchDistance;
iteration++;
}
return mid;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/DepthCommon.cginc.meta
================================================
fileFormatVersion: 2
guid: 1b199a26663a15b4db765ffb1df401f2
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/CloudVolumeParticle.shader
================================================
Shader "Scatterer-EVE/CloudVolumeParticle" {
Properties {
_Tex("Particle Texture", 2D) = "white" {}
_MainTex("Main (RGB)", 2D) = "white" {}
_PerlinTex("Perlin (RGB)", 2D) = "white" {}
_BumpMap("Normalmap", 2D) = "bump" {}
_DetailTex("Detail (RGB)", 2D) = "white" {}
_DetailScale("Detail Scale", Range(0,1000)) = 100
_DistFade("Distance Fade Near", Float) = 1.0
_DistFadeVert("Distance Fade Vertical", Float) = 0.0004
_MinScatter("Min Scatter", Float) = 1.05
_Opacity("Opacity", Float) = 1.05
_Color("Color Tint", Color) = (1,1,1,1)
_InvFade("Soft Particles Factor", Range(0,1.0)) = .008
_Rotation("Rotation", Float) = 0
_MaxScale("Max Scale", Float) = 1
_MaxTrans("Max Translation", Vector) = (0,0,0)
_NoiseScale("Noise Scale", Vector) = (1,2,.0005,100)
_SunPos("_SunPos", Vector) = (0,0,0)
_SunRadius("_SunRadius", Float) = 1
}
Category {
Tags { "Queue"="Transparent-1" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True" }
Blend SrcAlpha OneMinusSrcAlpha
Fog { Mode Global}
AlphaTest Greater 0
ColorMask RGB
Cull Back Lighting On ZWrite Off
SubShader {
Pass {
Lighting On
Tags { "LightMode"="ForwardBase"}
CGPROGRAM
#include "EVEUtils.cginc"
#pragma target 3.0
#pragma glsl
#pragma vertex vert
#pragma fragment frag
#define MAG_ONE 1.4142135623730950488016887242097
#pragma fragmentoption ARB_precision_hint_fastest
// #pragma multi_compile_fwdbase
#pragma multi_compile SOFT_DEPTH_OFF SOFT_DEPTH_ON
#pragma multi_compile MAP_TYPE_1 MAP_TYPE_CUBE_1 MAP_TYPE_CUBE2_1 MAP_TYPE_CUBE6_1
#ifndef MAP_TYPE_CUBE2_1
#pragma multi_compile ALPHAMAP_N_1 ALPHAMAP_1
#endif
#include "noiseSimplex.cginc"
#include "alphaMap.cginc"
#include "cubeMap.cginc"
#pragma multi_compile SCATTERER_OFF SCATTERER_ON
#pragma multi_compile SCATTERER_USE_ORIG_DIR_COLOR_OFF SCATTERER_USE_ORIG_DIR_COLOR_ON
#ifdef SCATTERER_ON
#include "../CommonAtmosphere.cginc"
#endif
CUBEMAP_DEF_1(_MainTex)
sampler2D _Tex;
sampler2D _DetailTex;
sampler2D _BumpMap;
float4x4 _PosRotation;
float _DetailScale;
fixed4 _Color;
float _DistFade;
float _DistFadeVert;
float _MinScatter;
float _Opacity;
float _InvFade;
float _Rotation;
float _MaxScale;
float4 _NoiseScale;
float3 _MaxTrans;
sampler2D _CameraDepthTexture;
// float4x4 _CameraToWorld;
#ifdef SCATTERER_ON
uniform float cloudColorMultiplier;
uniform float cloudScatteringMultiplier;
uniform float cloudSkyIrradianceMultiplier;
uniform float3 _Sun_WorldSunDir;
uniform float3 _PlanetWorldPos;
uniform float3 scattererOrigDirectionalColor;
#endif
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
fixed4 color : COLOR;
half4 viewDir : TEXCOORD0;
// float2 texcoordZY : TEXCOORD1;
// float2 texcoordXZ : TEXCOORD2;
// float2 texcoordXY : TEXCOORD3;
// float2 uv : TEXCOORD4;
// float4 projPos : TEXCOORD5;
// float3 planetPos : TEXCOORD6;
// float3 viewDirT : TEXCOORD7;
// float3 lightDirT : TEXCOORD8;
//store ZY+XZ and XY+uv together in two float4 to free up 2 interpolators
float4 texcoordZYXZ : TEXCOORD1;
float4 texcoordXYuv : TEXCOORD2;
float4 projPos : TEXCOORD3;
float3 planetPos : TEXCOORD4;
float3 viewDirT : TEXCOORD5;
float3 lightDirT : TEXCOORD6;
// float3 inScattering : TEXCOORD7;
// float3 relWorldPos : TEXCOORD8;
// float3 sunExtinction : TEXCOORD8;
};
v2f vert (appdata_t v)
{
v2f o;
UNITY_INITIALIZE_OUTPUT(v2f, o);
float4 origin = mul(unity_ObjectToWorld, float4(0,0,0,1));
float4 planet_pos = mul(_PosRotation, origin);
float3 normalized = _NoiseScale.z*(planet_pos.xyz);
float3 hashVect = .5*(float3(snoise(normalized), snoise(_NoiseScale.x*normalized), snoise(_NoiseScale.y*normalized))+1);
float4 localOrigin;
localOrigin.xyz = (2*hashVect-1)*_MaxTrans;
localOrigin.w = 1;
float localScale = (hashVect.x*(_MaxScale - 1)) + 1;
origin = mul(unity_ObjectToWorld, localOrigin);
planet_pos = mul(_MainRotation, origin);
float3 detail_pos = mul(_DetailRotation, planet_pos).xyz;
o.planetPos = planet_pos.xyz;
o.color = VERT_GET_NO_LOD_CUBE_MAP_1(_MainTex, planet_pos.xyz);
o.color.rgba *= GetCubeDetailMapNoLOD(_DetailTex, detail_pos, _DetailScale);
o.viewDir.w = GetDistanceFade(distance(origin, _WorldSpaceCameraPos), _DistFade, _DistFadeVert);
o.color.a *= o.viewDir.w;
float4x4 M = rand_rotation(
(float3(frac(_Rotation),0,0))+hashVect,
localScale,
localOrigin.xyz);
float4x4 mvMatrix = mul(mul(UNITY_MATRIX_V, unity_ObjectToWorld), M);
float3 viewDir = normalize(mvMatrix[2].xyz);
o.viewDir.xyz = abs(viewDir).xyz;
float4 mvCenter = mul(UNITY_MATRIX_MV, localOrigin);
o.pos = mul(UNITY_MATRIX_P,mvCenter+float4(v.vertex.xyz*localScale,v.vertex.w));
o.pos = o.color.a > (1.0/255.0) ? o.pos : float4(2.0, 2.0, 2.0, 1.0); //outside clip space => cull vertex
float2 texcoodOffsetxy = ((2*v.texcoord)- 1);
float4 texcoordOffset = float4(texcoodOffsetxy.x, texcoodOffsetxy.y, 0, v.vertex.w);
float4 ZYv = texcoordOffset.zyxw;
float4 XZv = texcoordOffset.xzyw;
float4 XYv = texcoordOffset.xyzw;
ZYv.z*=sign(-viewDir.x);
XZv.x*=sign(-viewDir.y);
XYv.x*=sign(viewDir.z);
ZYv.x += sign(-viewDir.x)*sign(ZYv.z)*(viewDir.z);
XZv.y += sign(-viewDir.y)*sign(XZv.x)*(viewDir.x);
XYv.z += sign(-viewDir.z)*sign(XYv.x)*(viewDir.x);
ZYv.x += sign(-viewDir.x)*sign(ZYv.y)*(viewDir.y);
XZv.y += sign(-viewDir.y)*sign(XZv.z)*(viewDir.z);
XYv.z += sign(-viewDir.z)*sign(XYv.y)*(viewDir.y);
float2 ZY = mul(mvMatrix, ZYv).xy - mvCenter.xy;
float2 XZ = mul(mvMatrix, XZv).xy - mvCenter.xy;
float2 XY = mul(mvMatrix, XYv).xy - mvCenter.xy;
// o.texcoordZY = half2(.5 ,.5) + .6*(ZY);
// o.texcoordXZ = half2(.5 ,.5) + .6*(XZ);
// o.texcoordXY = half2(.5 ,.5) + .6*(XY);
//later store together in a float4 to free up 2 interpolators
float2 texcoordZY = half2(.5 ,.5) + .6*(ZY);
float2 texcoordXZ = half2(.5 ,.5) + .6*(XZ);
float2 texcoordXY = half2(.5 ,.5) + .6*(XY);
float3 worldNormal = normalize(mul( unity_ObjectToWorld, float4( v.normal, 0.0 ) ).xyz);
viewDir = normalize(origin - _WorldSpaceCameraPos);
//o.color.rgb *= MultiBodyShadow(origin, _SunRadius, _SunPos, _ShadowBodies);
//o.color.rgb *= Terminator(_WorldSpaceLightPos0, worldNormal);
#ifdef SCATTERER_ON
//float3 worldPos = mul(unity_ObjectToWorld, localOrigin);
float3 worldPos = origin;
float3 extinction = float3(0, 0, 0);
float3 WCP = _WorldSpaceCameraPos; //unity supplied, in local Space
// float3 worigin = mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz;
float3 worigin = _PlanetWorldPos;
float3 relWorldPos=worldPos-worigin;
float3 relCameraPos=WCP-worigin;
//relWorldPos=lerp(Rg*normalize(relWorldPos),relWorldPos,cloudExtinctionHeightMultiplier);
//extinction of light from sun to cloud
float3 sunExtinction = getSkyExtinction(relWorldPos,_Sun_WorldSunDir);
//extinction from cloud to observer
extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0);
o.color.rgb *= cloudColorMultiplier * extinction * sunExtinction;
// //skyLight
// float3 skyE = SimpleSkyirradiance(relWorldPos, viewDir.xyz, _Sun_WorldSunDir);
//
// o.color.rgb *= cloudColorMultiplier * extinction * sunExtinction + skyE*cloudSkyIrradianceMultiplier;
// o.relWorldPos = relWorldPos;
// //inScattering from cloud to observer
// float3 inscatter = InScattering2(relCameraPos, relWorldPos, extinction, _Sun_WorldSunDir, 1.0, 1.0, 1.0);
// o.inScattering = inscatter * cloudScatteringMultiplier;
//
// //extinction from cloud to observer
// extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0);
//
// o.color.rgb *= cloudColorMultiplier * extinction;
#endif
#ifdef SOFT_DEPTH_ON
o.projPos = ComputeScreenPos (o.pos);
COMPUTE_EYEDEPTH(o.projPos.z);
#endif
//WorldSpaceViewDir(origin).xyz
half3 normal = normalize(-viewDir);
float3 tangent = UNITY_MATRIX_V[0].xyz;
float3 binormal = -cross(normal, normalize(tangent));
float3x3 rotation = float3x3(tangent.xyz, binormal, normal);
o.lightDirT = normalize(mul(rotation, _WorldSpaceLightPos0.xyz));
o.viewDirT = normalize(mul(rotation, viewDir));
//
// o.uv = v.texcoord;
float2 uv = v.texcoord;
//store together in a float4 to free up 2 interpolators
o.texcoordZYXZ=float4(texcoordZY,texcoordXZ);
o.texcoordXYuv=float4(texcoordXY,uv);
return o;
}
fixed4 frag (v2f IN) : COLOR
{
half4 tex;
//extract from float4 interpolator
float2 texcoordZY = IN.texcoordZYXZ.xy;
float2 texcoordXZ = IN.texcoordZYXZ.zw;
float2 texcoordXY = IN.texcoordXYuv.xy;
float2 uv = IN.texcoordXYuv.zw;
// tex.r = tex2D(_Tex, IN.texcoordZY).r;
// tex.g = tex2D(_Tex, IN.texcoordXZ).g;
// tex.b = tex2D(_Tex, IN.texcoordXY).b;
tex.r = tex2D(_Tex, texcoordZY).r;
tex.g = tex2D(_Tex, texcoordXZ).g;
tex.b = tex2D(_Tex, texcoordXY).b;
tex.a = 0;
tex.rgb *= IN.viewDir.rgb;
half4 vect = half4( IN.viewDir.rgb, 0);
tex /= vectorSum(vect);
tex = half4(1, 1, 1, vectorSum(tex));
half4 color = FRAG_GET_NO_LOD_CUBE_MAP_1(_MainTex, IN.planetPos);
color = ALPHA_COLOR_1(color);
color *= _Color * IN.color;
//half3 normT = UnpackNormal(tex2D(_BumpMap, IN.uv));
half3 normT;
// normT.xy = ((2*IN.uv)-1);
normT.xy = ((2*uv)-1);
normT.z = sqrt(1 - saturate(dot(normT.xy, normT.xy)));
//normT.xy = 2 * INV_PI*asin((2 * IN.uv) - 1) ;
//normT.xy = sin(PI*(IN.uv-.5));
//normT.z = 1;
//color.rg = IN.uv;
color.a *= tex.a;
tex.a = IN.viewDir.w*tex.a;
#if (defined(SCATTERER_ON) && defined(SCATTERER_USE_ORIG_DIR_COLOR_ON))
_LightColor0.rgb = scattererOrigDirectionalColor;
#endif
color.rgb *= ScatterColorLight(IN.lightDirT, IN.viewDirT, normT, tex, _MinScatter, _Opacity, 1).rgb;
//#ifdef SCATTERER_ON
//
//
// //extinction of light from sun to cloud
// float3 sunExtinction = getSkyExtinction(IN.relWorldPos,_Sun_WorldSunDir);
//
// //skyLight
// float3 skyE = SimpleSkyirradiance(IN.relWorldPos, IN.viewDir.xyz, _Sun_WorldSunDir);
//
// color.rgb = hdrNoExposure(sunExtinction*color.rgb+IN.inScattering+skyE*cloudSkyIrradianceMultiplier); //color.rgb already has extinction to viewer and colorMultiplier pre-applied
//#endif
#ifdef SOFT_DEPTH_ON
float depth = UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(IN.projPos)));
depth = LinearEyeDepth (depth);
float partZ = IN.projPos.z;
float fade = saturate (_InvFade * (depth-partZ));
color.a *= fade;
#endif
// color.rgb = color.rgb + IN.inScattering * (1-color.rgb); //soft additive blending //maybe do if no hdr?
return color;
}
ENDCG
}
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/CloudVolumeParticle.shader.meta
================================================
fileFormatVersion: 2
guid: a331c23f613bfba4294059442ab01d4e
timeCreated: 1470912280
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/EVEUtils.cginc
================================================
#ifndef EVE_UTILS_CG_INCLUDED
#define EVE_UTILS_CG_INCLUDED
#include "UnityCG.cginc"
#include "AutoLight.cginc"
#include "Lighting.cginc"
#define PI 3.1415926535897932384626
#define INV_PI (1.0/PI)
#define TWOPI (2.0*PI)
#define INV_2PI (1.0/TWOPI)
#define SQRT_2 (1.41421356237)
#pragma fragmentoption ARB_precision_hint_fastest
#ifdef DIRLIGHT_ONLY
#define DIRECTIONAL 1
#define SHADOWS_OFF 1
#define LIGHTMAP_OFF 1
#define DIRLIGHTMAP_OFF 1
#endif
#pragma skip_variants DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE DYNAMICLIGHTMAP_ON LIGHTMAP_ON VERTEXLIGHT_ON
uniform float4x4 _MainRotation;
uniform float4x4 _DetailRotation;
uniform float4x4 _ShadowBodies = float4x4
( 0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0);
float _SunRadius = 1;
float3 _SunPos;
float4 _UniversalTime;
/*=========================================================================*
* R A N D _ R O T A T I O N Author: Jim Arvo, 1991 *
* *
* This routine maps three values (x[0], x[1], x[2]) in the range [0,1] *
* into a 3x3 rotation matrix, M. Uniformly distributed random variables *
* x0, x1, and x2 create uniformly distributed random rotation matrices. *
* To create small uniformly distributed "perturbations", supply *
* samples in the following ranges *
* *
* x[0] in [ 0, d ] *
* x[1] in [ 0, 1 ] *
* x[2] in [ 0, d ] *
* *
* where 0 < d < 1 controls the size of the perturbation. Any of the *
* random variables may be stratified (or "jittered") for a slightly more *
* even distribution. *
* *
*=========================================================================*/
float4x4 rand_rotation(float3 x, float scale, float3 trans)
{
float theta = x[0] * TWOPI; /* Rotation about the pole (Z). */
float phi = x[1] * TWOPI; /* For direction of pole deflection. */
float z = x[2] * 2.0; /* For magnitude of pole deflection. */
/* Compute a vector V used for distributing points over the sphere */
/* via the reflection I - V Transpose(V). This formulation of V */
/* will guarantee that if x[1] and x[2] are uniformly distributed, */
/* the reflected points will be uniform on the sphere. Note that V */
/* has length sqrt(2) to eliminate the 2 in the Householder matrix. */
float r = sqrt(z);
float Vx = sin(phi) * r;
float Vy = cos(phi) * r;
float Vz = sqrt(2.0 - z);
/* Compute the row vector S = Transpose(V) * R, where R is a simple */
/* rotation by theta about the z-axis. No need to compute Sz since */
/* it's just Vz. */
float st = sin(theta);
float ct = cos(theta);
float Sx = Vx * ct - Vy * st;
float Sy = Vx * st + Vy * ct;
/* Construct the rotation matrix ( V Transpose(V) - I ) R, which */
/* is equivalent to V S - R. */
float4x4 M = float4x4(
scale*(Vx * Sx - ct), Vy * Sx + st, Vz * Sx, trans.x,
Vx * Sy - st, scale*(Vy * Sy - ct), Vz * Sy, trans.y,
Vx * Vz, Vy * Vz, scale*(1.0 - z), trans.z,
0, 0, 0, 1);
return M;
}
inline float3 hash( float3 val )
{
return frac(sin(val)*1232.53);
}
inline float GetDistanceFade( float dist, float fade, float fadeVert )
{
float fadeDist = fade*dist;
float distVert = 1-(fadeVert*dist);
return saturate(fadeDist) * saturate(distVert);
}
inline half4 GetLighting(half3 worldNorm, half3 lightDir, fixed atten, fixed ambient)
{
half3 ambientLighting = ambient * UNITY_LIGHTMODEL_AMBIENT;
half NdotL = dot (worldNorm, lightDir);
half lightIntensity = saturate(_LightColor0.a * NdotL * 2 * atten);
half4 light;
light.rgb = max(ambientLighting + (_LightColor0.rgb * lightIntensity), 0);
light.a = max(ambientLighting + lightIntensity, 0);
return light;
}
// Calculates Blinn-Phong (specular) lighting model
inline half4 SpecularColorLight( half3 lightDir, half3 viewDir, half3 normal, half4 color, half4 specColor, float specK, half atten )
{
lightDir = normalize(lightDir);
viewDir = normalize(viewDir);
normal = normalize(normal);
half3 h = normalize( lightDir + viewDir );
half diffuse = dot( normal, lightDir );
float nh = saturate( dot( h, normal ) );
float spec = pow( nh, specK ) * specColor.a;
half4 c;
c.rgb = _LightColor0.rgb*((color.rgb * diffuse )+ (specColor.rgb * spec)) * (atten * 2);
c.a = diffuse*(atten * 2);//_LightColor0.a * specColor.a * spec * atten; // specular passes by default put highlights to overbright
return c;
}
inline half4 ScatterColorLight(half3 lightDir, half3 viewDir, half3 normal, half4 color, float min, float opacity, half atten)
{
lightDir = normalize(lightDir);
viewDir = normalize(viewDir);
normal = normalize(normal);
half diffuse = max( dot(normal, lightDir),0);
float h = .5+(.5*dot(viewDir, lightDir));
float scatter = (min-(opacity*color.a))*(1-(dot(normal,viewDir)))*h;
scatter = saturate(scatter);
half4 c;
c.rgb = _LightColor0*((color.rgb * diffuse) + scatter) * (atten * 2);
c.a = diffuse*(atten * 2);//_LightColor0.a * specColor.a * spec * atten; // specular passes by default put highlights to overbright
return c;
}
inline half Terminator(half3 lightDir, half3 normal)
{
half NdotL = dot( normal, lightDir );
half termlerp = saturate(10*-NdotL);
half terminator = lerp(1,saturate(floor(1.01+NdotL)), termlerp);
return terminator;
}
inline half BodyShadow(float3 v, float R, float r, float3 P, float3 p)
{
float3 D = P - v;
float a = PI*(r*r);
float3 d = p - v;
float tc = dot(d, normalize(D));
float tc2 = (tc*tc);
float L = sqrt(dot(d, d) - tc2);
float scale = tc / length(D); //Scaled Sun Area to match plane of intersecting body
float Rs = R * scale;
float A = PI*(Rs*Rs);
float s = saturate((r + Rs - L) / (2 * min(r, Rs)));
s = (INV_PI*asin((2 * s) - 1)) + .5;
return lerp(1, saturate((A - (s*a)) / A), step(r, tc)*saturate(a));
}
inline half MultiBodyShadow(float3 v, float R, float3 P, float4x4 m)
{
half a = BodyShadow(v, R, m[0].w, P, m[0].xyz);
half b = BodyShadow(v, R, m[1].w, P, m[1].xyz);
half c = BodyShadow(v, R, m[2].w, P, m[2].xyz);
half d = BodyShadow(v, R, m[3].w, P, m[3].xyz);
return min(min(a, b), min(c, d));
}
#endif
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/EVEUtils.cginc.meta
================================================
fileFormatVersion: 2
guid: e2392d942829c3b439a231d514e10321
timeCreated: 1470912310
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/GeometryCloudVolumeParticle.shader
================================================
Shader "Scatterer-EVE/GeometryCloudVolumeParticle" {
Properties {
_Tex("Particle Texture", 2D) = "white" {}
_MainTex("Main (RGB)", 2D) = "white" {}
_PerlinTex("Perlin (RGB)", 2D) = "white" {}
_BumpMap("Normalmap", 2D) = "bump" {}
_DetailTex("Detail (RGB)", 2D) = "white" {}
_DetailScale("Detail Scale", Range(0,1000)) = 100
_DistFade("Distance Fade Near", Float) = 1.0
_DistFadeVert("Distance Fade Vertical", Float) = 0.0004
_MinScatter("Min Scatter", Float) = 1.05
_Opacity("Opacity", Float) = 1.05
_Color("Color Tint", Color) = (1,1,1,1)
_InvFade("Soft Particles Factor", Range(0,1.0)) = .008
_Rotation("Rotation", Float) = 0
_MaxScale("Max Scale", Float) = 1
_MaxTrans("Max Translation", Vector) = (0,0,0)
_NoiseScale("Noise Scale", Vector) = (1,2,.0005,100)
_SunPos("_SunPos", Vector) = (0,0,0)
_SunRadius("_SunRadius", Float) = 1
}
Category {
Tags { "Queue"="Transparent-1" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True" }
Blend SrcAlpha OneMinusSrcAlpha
Fog { Mode Global}
AlphaTest Greater 0
ColorMask RGB
//Cull Back
Cull Off
Lighting On
ZWrite Off
SubShader {
Pass {
Lighting On
Tags { "LightMode"="ForwardBase"}
CGPROGRAM
#include "EVEUtils.cginc"
#pragma vertex vert
#pragma fragment frag
#pragma geometry geom
#define MAG_ONE 1.4142135623730950488016887242097
#pragma fragmentoption ARB_precision_hint_fastest
//#pragma multi_compile_fwdbase
#pragma multi_compile SOFT_DEPTH_OFF SOFT_DEPTH_ON
#pragma multi_compile MAP_TYPE_1 MAP_TYPE_CUBE_1 MAP_TYPE_CUBE2_1 MAP_TYPE_CUBE6_1
#ifndef MAP_TYPE_CUBE2_1
#pragma multi_compile ALPHAMAP_N_1 ALPHAMAP_1
#endif
#include "noiseSimplex.cginc"
#include "alphaMap.cginc"
#include "cubeMap.cginc"
#pragma multi_compile SCATTERER_OFF SCATTERER_ON
#pragma multi_compile SCATTERER_USE_ORIG_DIR_COLOR_OFF SCATTERER_USE_ORIG_DIR_COLOR_ON
#ifdef SCATTERER_ON
#include "../CommonAtmosphere.cginc"
#endif
CUBEMAP_DEF_1(_MainTex)
sampler2D _Tex;
sampler2D _DetailTex;
sampler2D _BumpMap;
float4x4 _PosRotation;
float _DetailScale;
fixed4 _Color;
float _DistFade;
float _DistFadeVert;
float _MinScatter;
float _Opacity;
float _InvFade;
float _Rotation;
float _QuadSize;
float _MaxScale;
float4 _NoiseScale;
float3 _MaxTrans;
sampler2D _CameraDepthTexture;
#ifdef SCATTERER_ON
uniform float cloudColorMultiplier;
uniform float cloudScatteringMultiplier;
uniform float cloudSkyIrradianceMultiplier;
uniform float3 _Sun_WorldSunDir;
uniform float3 _PlanetWorldPos;
uniform float3 scattererOrigDirectionalColor;
#endif
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 texcoord : TEXCOORD0;
};
struct v2g {
float4 pos : SV_POSITION;
fixed4 color : COLOR;
float3 hashVect : TEXCOORD0;
float4 localOrigin : TEXCOORD1;
float4 origin : TEXCOORD2;
float viewDirFade : TEXCOORD3;
float3 planetPos : TEXCOORD4;
float particleFade: TEXCOORD5;
};
//vertex function, called for every point on our hexSeg, each vertex corresponding to the origin of a particle/quad
v2g vert (appdata_t v)
{
v2g o;
UNITY_INITIALIZE_OUTPUT(v2g, o);
v.vertex.xyz/=v.vertex.w;
float4 origin = mul(unity_ObjectToWorld, v.vertex); //origin of the quad in worldSpace
float4 planet_pos = mul(_PosRotation, origin);
float3 normalized = _NoiseScale.z*(planet_pos.xyz);
float3 hashVect = .5*(float3(snoise(normalized), snoise(_NoiseScale.x*normalized), snoise(_NoiseScale.y*normalized))+1); //unique hash of the particle based on planet pos
o.hashVect = hashVect;
float4 localOrigin;
localOrigin.xyz = (2*hashVect-1)*_MaxTrans; //offset to localOrigin based on hash above
localOrigin.w = 1;
//localOrigin.xyz+=v.vertex.xyz; //here this is wrong, in the original shader, local origin is added to the quad in it's space and gets transformed with it'w own M matrix with no issues
//here as we add this to the space of the hex, transforming later with M matrix can cause additional rotation, we can add this in worldSpace instead
origin.xyz+=localOrigin; //the particle transforms are originally oriented same as in world space, therefore we can do this offset directly in worldSpace in our case
o.origin = origin;
localOrigin = mul (unity_WorldToObject, origin); //transform back to find the new localOrigin
o.localOrigin = localOrigin;
planet_pos = mul(_MainRotation, origin); //new planet pos based on offset origin
o.planetPos = planet_pos.xyz;
float3 detail_pos = mul(_DetailRotation, planet_pos).xyz;
o.color = VERT_GET_NO_LOD_CUBE_MAP_1(_MainTex, planet_pos.xyz);
o.color.rgba *= GetCubeDetailMapNoLOD(_DetailTex, detail_pos, _DetailScale);
o.viewDirFade = GetDistanceFade(distance(origin, _WorldSpaceCameraPos), _DistFade, _DistFadeVert);
o.color.a *= o.viewDirFade;
float4 mvCenter = mul(UNITY_MATRIX_MV, float4(localOrigin.xyz,1.0)); //offset quad origin in viewspace
o.pos=mvCenter;
o.pos = o.color.a > (1.0/255.0) ? o.pos : float4(2.0, 2.0, 2.0, 1.0); //cull vertex if low alpha, pos outside clipspace
float fadeOut = (-mvCenter.z/mvCenter.w) * 0.004;
o.particleFade = smoothstep(0.0,1.0,fadeOut);
#ifdef SCATTERER_ON
float3 worldPos = origin;
float3 extinction = float3(0, 0, 0);
float3 WCP = _WorldSpaceCameraPos; //unity supplied, in local Space
// float3 worigin = mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz;
float3 worigin = _PlanetWorldPos;
float3 relWorldPos=worldPos-worigin;
float3 relCameraPos=WCP-worigin;
//relWorldPos=lerp(Rg*normalize(relWorldPos),relWorldPos,cloudExtinctionHeightMultiplier);
//extinction of light from sun to cloud
float3 sunExtinction = getSkyExtinction(relWorldPos,_Sun_WorldSunDir);
//extinction from cloud to observer
extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0);
o.color.rgb *= cloudColorMultiplier * extinction * sunExtinction;
// //skyLight
// float3 skyE = SimpleSkyirradiance(relWorldPos, viewDir.xyz, _Sun_WorldSunDir);
//
// o.color.rgb *= cloudColorMultiplier * extinction * sunExtinction + skyE*cloudSkyIrradianceMultiplier;
// o.relWorldPos = relWorldPos;
// //inScattering from cloud to observer
// float3 inscatter = InScattering2(relCameraPos, relWorldPos, extinction, _Sun_WorldSunDir, 1.0, 1.0, 1.0);
// o.inScattering = inscatter * cloudScatteringMultiplier;
//
// //extinction from cloud to observer
// extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0);
//
// o.color.rgb *= cloudColorMultiplier * extinction;
#endif
return o;
}
struct g2f
{
float4 pos : SV_POSITION;
fixed4 color : COLOR;
half4 viewDir : TEXCOORD0;
float2 texcoordZY : TEXCOORD1;
float2 texcoordXZ : TEXCOORD2;
float2 texcoordXY : TEXCOORD3;
float3 uv : TEXCOORD4; //x and y UVs, z is particleFade
float4 projPos : TEXCOORD5;
float3 planetPos : TEXCOORD6;
float3 viewDirT : TEXCOORD7;
float3 lightDirT : TEXCOORD8;
float4 localOrigin : TEXCOORD9;
};
//this function builds a quad corner vertex from the data passed to it, it will be called by the geometry shader
g2f buildQuadVertex(v2g originPoint, float3 vertexPosition, float2 vertexUV, float3 viewDir, float4x4 mvMatrix, float localScale)
{
g2f tri;
UNITY_INITIALIZE_OUTPUT(g2f, tri);
float3 mvCenter = originPoint.pos.xyz/originPoint.pos.w;
tri.pos = float4(mvCenter + _QuadSize * localScale * vertexPosition,1.0); //position in view space of quad corner
#ifdef SOFT_DEPTH_ON
float eyedepth = -tri.pos.z;
#endif
tri.pos = mul (UNITY_MATRIX_P, tri.pos);
#ifdef SOFT_DEPTH_ON
tri.projPos = ComputeScreenPos (tri.pos);
//COMPUTE_EYEDEPTH(tri.projPos.z);
//we replace COMPUTE_EYEDEPTH with it's definition as it's only designed for the vertex shader input
//tri.projPos.z = -UnityObjectToViewPos( v.vertex ).z
tri.projPos.z = eyedepth;
#endif
//pass these values we need for the fragment shader
tri.viewDir.xyz = abs(viewDir).xyz;
tri.viewDir.w = originPoint.viewDirFade;
tri.planetPos = originPoint.planetPos;
tri.color = originPoint.color;
float2 texcoodOffsetxy = ((2*vertexUV)- 1);
float4 texcoordOffset = float4(texcoodOffsetxy.x, texcoodOffsetxy.y, 0, 1.0); //would 1.0 work here???? let's find out
float4 ZYv = texcoordOffset.zyxw;
float4 XZv = texcoordOffset.xzyw;
float4 XYv = texcoordOffset.xyzw;
ZYv.z*=sign(-viewDir.x);
XZv.x*=sign(-viewDir.y);
XYv.x*=sign(viewDir.z);
ZYv.x += sign(-viewDir.x)*sign(ZYv.z)*(viewDir.z);
XZv.y += sign(-viewDir.y)*sign(XZv.x)*(viewDir.x);
XYv.z += sign(-viewDir.z)*sign(XYv.x)*(viewDir.x);
ZYv.x += sign(-viewDir.x)*sign(ZYv.y)*(viewDir.y);
XZv.y += sign(-viewDir.y)*sign(XZv.z)*(viewDir.z);
XYv.z += sign(-viewDir.z)*sign(XYv.y)*(viewDir.y);
float2 ZY = mul(mvMatrix, ZYv).xy - mvCenter.xy;
float2 XZ = mul(mvMatrix, XZv).xy - mvCenter.xy;
float2 XY = mul(mvMatrix, XYv).xy - mvCenter.xy;
tri.texcoordZY = half2(.5 ,.5) + .6*(ZY);
tri.texcoordXZ = half2(.5 ,.5) + .6*(XZ);
tri.texcoordXY = half2(.5 ,.5) + .6*(XY);
viewDir = normalize(originPoint.origin - _WorldSpaceCameraPos); //worldSpaceView dir to center of quad not to fragment, why? maybe to frag would be better?
half3 normal = normalize(-viewDir);
float3 tangent = UNITY_MATRIX_V[0].xyz;
float3 binormal = -cross(normal, normalize(tangent));
float3x3 rotation = float3x3(tangent.xyz, binormal, normal);
tri.lightDirT = normalize(mul(rotation, _WorldSpaceLightPos0.xyz));
tri.viewDirT = normalize(mul(rotation, viewDir));
tri.uv = float3(vertexUV, originPoint.particleFade); //x and y quad UV, z particleFade
tri.localOrigin = originPoint.localOrigin;
return tri;
}
//geometry shader
//for every vertex from the vertex shader it will create a particle quad of 4 vertexes and 2 triangles
[maxvertexcount(4)]
void geom(point v2g input[1], inout TriangleStream outStream)
{
g2f tri;
//common values for all the quad
float localScale = (input[0].hashVect.x*(_MaxScale - 1)) + 1;
float4x4 M = rand_rotation(
(float3(frac(_Rotation),0,0))+input[0].hashVect,
localScale,
input[0].localOrigin.xyz/input[0].localOrigin.w);
float4x4 mvMatrix = mul(mul(UNITY_MATRIX_V, unity_ObjectToWorld), M);
float3 viewDir = normalize(mvMatrix[2].xyz); //cameraSpace viewDir I think
//build our quad
tri = buildQuadVertex(input[0],float3(-0.5,-0.5,0.0),float2(0.0,0.0),viewDir,mvMatrix,localScale);
outStream.Append(tri);
tri = buildQuadVertex(input[0],float3(-0.5,0.5,0.0),float2(0.0,1.0),viewDir,mvMatrix,localScale);
outStream.Append(tri);
tri = buildQuadVertex(input[0],float3(0.5,-0.5,0.0),float2(1.0,0.0),viewDir,mvMatrix,localScale);
outStream.Append(tri);
tri = buildQuadVertex(input[0],float3(0.5,0.5,0.0),float2(1.0,1.0),viewDir,mvMatrix,localScale);
outStream.Append(tri);
outStream.RestartStrip();
}
float4 frag (g2f IN) : COLOR
{
half4 tex;
tex.r = tex2D(_Tex, IN.texcoordZY).r;
tex.g = tex2D(_Tex, IN.texcoordXZ).g;
tex.b = tex2D(_Tex, IN.texcoordXY).b;
tex.a = 0;
tex.rgb *= IN.viewDir.rgb;
half4 vect = half4( IN.viewDir.rgb, 0);
tex /= vectorSum(vect);
tex = half4(1, 1, 1, vectorSum(tex));
half4 color = FRAG_GET_NO_LOD_CUBE_MAP_1(_MainTex, IN.planetPos);
color = ALPHA_COLOR_1(color);
color *= _Color * IN.color;
//half3 normT = UnpackNormal(tex2D(_BumpMap, IN.uv));
half3 normT;
normT.xy = ((2*IN.uv.xy)-1);
normT.z = sqrt(1 - saturate(dot(normT.xy, normT.xy)));
//normT.xy = 2 * INV_PI*asin((2 * IN.uv) - 1) ;
//normT.xy = sin(PI*(IN.uv-.5));
//normT.z = 1;
//color.rg = IN.uv;
color.a *= tex.a;
tex.a = IN.viewDir.w*tex.a;
#if (defined(SCATTERER_ON) && defined(SCATTERER_USE_ORIG_DIR_COLOR_ON))
_LightColor0.rgb = scattererOrigDirectionalColor;
#endif
color.rgb *= ScatterColorLight(IN.lightDirT, IN.viewDirT, normT, tex, _MinScatter, _Opacity, 1).rgb;
#ifdef SOFT_DEPTH_ON
float depth = UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(IN.projPos)));
depth = LinearEyeDepth (depth);
float partZ = IN.projPos.z;
float fade = depth >= (0.99 * _ProjectionParams.z) ? 1.0 : saturate (_InvFade * (depth-partZ)); //fade near objects but don't fade on far plane (max depth value)
color.a *= fade;
#endif
color.a *= IN.uv.z; //particle fade as they approach camera
return color;
}
ENDCG
}
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/GeometryCloudVolumeParticle.shader.meta
================================================
fileFormatVersion: 2
guid: 99744ed686e28004180091658ee4f5ae
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/GeometryCloudVolumeParticleToTexture.shader
================================================
Shader "Scatterer-EVE/GeometryCloudVolumeParticleToTexture" {
Properties {
_Tex("Particle Texture", 2D) = "white" {}
_MainTex("Main (RGB)", 2D) = "white" {}
_PerlinTex("Perlin (RGB)", 2D) = "white" {}
_BumpMap("Normalmap", 2D) = "bump" {}
_DetailTex("Detail (RGB)", 2D) = "white" {}
_DetailScale("Detail Scale", Range(0,1000)) = 100
_DistFade("Distance Fade Near", Float) = 1.0
_DistFadeVert("Distance Fade Vertical", Float) = 0.0004
_MinScatter("Min Scatter", Float) = 1.05
_Opacity("Opacity", Float) = 1.05
_Color("Color Tint", Color) = (1,1,1,1)
_InvFade("Soft Particles Factor", Range(0,1.0)) = .008
_Rotation("Rotation", Float) = 0
_MaxScale("Max Scale", Float) = 1
_MaxTrans("Max Translation", Vector) = (0,0,0)
_NoiseScale("Noise Scale", Vector) = (1,2,.0005,100)
_SunPos("_SunPos", Vector) = (0,0,0)
_SunRadius("_SunRadius", Float) = 1
}
Category {
Tags { "Queue"="Transparent-1" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True" }
Blend SrcAlpha OneMinusSrcAlpha, Zero OneMinusSrcAlpha //traditional alpha blending for colors, multiply by (1-alpha) for alpha to store in texture
Fog { Mode Global}
AlphaTest Greater 0
ColorMask RGBA
//Cull Back
Cull Off
Lighting On
ZWrite Off
SubShader {
Pass {
Lighting On
Tags { "LightMode"="ForwardBase"}
CGPROGRAM
#include "EVEUtils.cginc"
#pragma vertex vert
#pragma fragment frag
#pragma geometry geom
#define MAG_ONE 1.4142135623730950488016887242097
#pragma fragmentoption ARB_precision_hint_fastest
//#pragma multi_compile_fwdbase
#pragma multi_compile SOFT_DEPTH_OFF SOFT_DEPTH_ON
#pragma multi_compile MAP_TYPE_1 MAP_TYPE_CUBE_1 MAP_TYPE_CUBE2_1 MAP_TYPE_CUBE6_1
#ifndef MAP_TYPE_CUBE2_1
#pragma multi_compile ALPHAMAP_N_1 ALPHAMAP_1
#endif
#include "noiseSimplex.cginc"
#include "alphaMap.cginc"
#include "cubeMap.cginc"
#pragma multi_compile SCATTERER_OFF SCATTERER_ON
#pragma multi_compile SCATTERER_USE_ORIG_DIR_COLOR_OFF SCATTERER_USE_ORIG_DIR_COLOR_ON
#ifdef SCATTERER_ON
#include "../CommonAtmosphere.cginc"
#endif
CUBEMAP_DEF_1(_MainTex)
sampler2D _Tex;
sampler2D _DetailTex;
sampler2D _BumpMap;
float4x4 _PosRotation;
float _DetailScale;
fixed4 _Color;
float _DistFade;
float _DistFadeVert;
float _MinScatter;
float _Opacity;
float _InvFade;
float _Rotation;
float _QuadSize;
float _MaxScale;
float4 _NoiseScale;
float3 _MaxTrans;
sampler2D EVEDownscaledDepth;
#ifdef SCATTERER_ON
uniform float cloudColorMultiplier;
uniform float cloudScatteringMultiplier;
uniform float cloudSkyIrradianceMultiplier;
uniform float3 _Sun_WorldSunDir;
uniform float3 _PlanetWorldPos;
uniform float3 scattererOrigDirectionalColor;
#endif
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 texcoord : TEXCOORD0;
};
struct v2g {
float4 pos : SV_POSITION;
fixed4 color : COLOR;
float3 hashVect : TEXCOORD0;
float4 localOrigin : TEXCOORD1;
float4 origin : TEXCOORD2;
float viewDirFade : TEXCOORD3;
float3 planetPos : TEXCOORD4;
float particleFade: TEXCOORD5;
};
//vertex function, called for every point on our hexSeg, each vertex corresponding to the origin of a particle/quad
v2g vert (appdata_t v)
{
v2g o;
UNITY_INITIALIZE_OUTPUT(v2g, o);
v.vertex.xyz/=v.vertex.w;
float4 origin = mul(unity_ObjectToWorld, v.vertex); //origin of the quad in worldSpace
float4 planet_pos = mul(_PosRotation, origin);
float3 normalized = _NoiseScale.z*(planet_pos.xyz);
float3 hashVect = .5*(float3(snoise(normalized), snoise(_NoiseScale.x*normalized), snoise(_NoiseScale.y*normalized))+1); //unique hash of the particle based on planet pos
o.hashVect = hashVect;
float4 localOrigin;
localOrigin.xyz = (2*hashVect-1)*_MaxTrans; //offset to localOrigin based on hash above
localOrigin.w = 1;
//localOrigin.xyz+=v.vertex.xyz; //here this is wrong, in the original shader, local origin is added to the quad in it's space and gets transformed with it'w own M matrix with no issues
//here as we add this to the space of the hex, transforming later with M matrix can cause additional rotation, we can add this in worldSpace instead
origin.xyz+=localOrigin; //the particle transforms are originally oriented same as in world space, therefore we can do this offset directly in worldSpace in our case
o.origin = origin;
localOrigin = mul (unity_WorldToObject, origin); //transform back to find the new localOrigin
o.localOrigin = localOrigin;
planet_pos = mul(_MainRotation, origin); //new planet pos based on offset origin
o.planetPos = planet_pos.xyz;
float3 detail_pos = mul(_DetailRotation, planet_pos).xyz;
o.color = VERT_GET_NO_LOD_CUBE_MAP_1(_MainTex, planet_pos.xyz);
o.color.rgba *= GetCubeDetailMapNoLOD(_DetailTex, detail_pos, _DetailScale);
o.viewDirFade = GetDistanceFade(distance(origin, _WorldSpaceCameraPos), _DistFade, _DistFadeVert);
o.color.a *= o.viewDirFade;
float4 mvCenter = mul(UNITY_MATRIX_MV, float4(localOrigin.xyz,1.0)); //offset quad origin in viewspace
o.pos=mvCenter;
o.pos = o.color.a > (1.0/255.0) ? o.pos : float4(2.0, 2.0, 2.0, 1.0); //cull vertex if low alpha, pos outside clipspace
float fadeOut = (-mvCenter.z/mvCenter.w) * 0.004;
o.particleFade = smoothstep(0.0,1.0,fadeOut);
#ifdef SCATTERER_ON
float3 worldPos = origin;
float3 extinction = float3(0, 0, 0);
float3 WCP = _WorldSpaceCameraPos; //unity supplied, in local Space
// float3 worigin = mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz;
float3 worigin = _PlanetWorldPos;
float3 relWorldPos=worldPos-worigin;
float3 relCameraPos=WCP-worigin;
//relWorldPos=lerp(Rg*normalize(relWorldPos),relWorldPos,cloudExtinctionHeightMultiplier);
//extinction of light from sun to cloud
float3 sunExtinction = getSkyExtinction(relWorldPos,_Sun_WorldSunDir);
//extinction from cloud to observer
extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0);
o.color.rgb *= cloudColorMultiplier * extinction * sunExtinction;
// //skyLight
// float3 skyE = SimpleSkyirradiance(relWorldPos, viewDir.xyz, _Sun_WorldSunDir);
//
// o.color.rgb *= cloudColorMultiplier * extinction * sunExtinction + skyE*cloudSkyIrradianceMultiplier;
// o.relWorldPos = relWorldPos;
// //inScattering from cloud to observer
// float3 inscatter = InScattering2(relCameraPos, relWorldPos, extinction, _Sun_WorldSunDir, 1.0, 1.0, 1.0);
// o.inScattering = inscatter * cloudScatteringMultiplier;
//
// //extinction from cloud to observer
// extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0);
//
// o.color.rgb *= cloudColorMultiplier * extinction;
#endif
return o;
}
struct g2f
{
float4 pos : SV_POSITION;
fixed4 color : COLOR;
half4 viewDir : TEXCOORD0;
float2 texcoordZY : TEXCOORD1;
float2 texcoordXZ : TEXCOORD2;
float2 texcoordXY : TEXCOORD3;
float3 uv : TEXCOORD4; //x and y UVs, z is particleFade
float4 projPos : TEXCOORD5;
float3 planetPos : TEXCOORD6;
float3 viewDirT : TEXCOORD7;
float3 lightDirT : TEXCOORD8;
float4 localOrigin : TEXCOORD9;
};
//this function builds a quad corner vertex from the data passed to it, it will be called by the geometry shader
g2f buildQuadVertex(v2g originPoint, float3 vertexPosition, float2 vertexUV, float3 viewDir, float4x4 mvMatrix, float localScale)
{
g2f tri;
UNITY_INITIALIZE_OUTPUT(g2f, tri);
float3 mvCenter = originPoint.pos.xyz/originPoint.pos.w;
tri.pos = float4(mvCenter + _QuadSize * localScale * vertexPosition,1.0); //position in view space of quad corner
#ifdef SOFT_DEPTH_ON
float eyedepth = -tri.pos.z;
#endif
tri.pos = mul (UNITY_MATRIX_P, tri.pos);
#ifdef SOFT_DEPTH_ON
tri.projPos = ComputeScreenPos (tri.pos);
//COMPUTE_EYEDEPTH(tri.projPos.z);
//we replace COMPUTE_EYEDEPTH with it's definition as it's only designed for the vertex shader input
//tri.projPos.z = -UnityObjectToViewPos( v.vertex ).z
tri.projPos.z = eyedepth;
#endif
//pass these values we need for the fragment shader
tri.viewDir.xyz = abs(viewDir).xyz;
tri.viewDir.w = originPoint.viewDirFade;
tri.planetPos = originPoint.planetPos;
tri.color = originPoint.color;
float2 texcoodOffsetxy = ((2*vertexUV)- 1);
float4 texcoordOffset = float4(texcoodOffsetxy.x, texcoodOffsetxy.y, 0, 1.0); //would 1.0 work here???? let's find out
float4 ZYv = texcoordOffset.zyxw;
float4 XZv = texcoordOffset.xzyw;
float4 XYv = texcoordOffset.xyzw;
ZYv.z*=sign(-viewDir.x);
XZv.x*=sign(-viewDir.y);
XYv.x*=sign(viewDir.z);
ZYv.x += sign(-viewDir.x)*sign(ZYv.z)*(viewDir.z);
XZv.y += sign(-viewDir.y)*sign(XZv.x)*(viewDir.x);
XYv.z += sign(-viewDir.z)*sign(XYv.x)*(viewDir.x);
ZYv.x += sign(-viewDir.x)*sign(ZYv.y)*(viewDir.y);
XZv.y += sign(-viewDir.y)*sign(XZv.z)*(viewDir.z);
XYv.z += sign(-viewDir.z)*sign(XYv.y)*(viewDir.y);
float2 ZY = mul(mvMatrix, ZYv).xy - mvCenter.xy;
float2 XZ = mul(mvMatrix, XZv).xy - mvCenter.xy;
float2 XY = mul(mvMatrix, XYv).xy - mvCenter.xy;
tri.texcoordZY = half2(.5 ,.5) + .6*(ZY);
tri.texcoordXZ = half2(.5 ,.5) + .6*(XZ);
tri.texcoordXY = half2(.5 ,.5) + .6*(XY);
viewDir = normalize(originPoint.origin - _WorldSpaceCameraPos); //worldSpaceView dir to center of quad not to fragment, why? maybe to frag would be better?
half3 normal = normalize(-viewDir);
float3 tangent = UNITY_MATRIX_V[0].xyz;
float3 binormal = -cross(normal, normalize(tangent));
float3x3 rotation = float3x3(tangent.xyz, binormal, normal);
tri.lightDirT = normalize(mul(rotation, _WorldSpaceLightPos0.xyz));
tri.viewDirT = normalize(mul(rotation, viewDir));
tri.uv = float3(vertexUV, originPoint.particleFade); //x and y quad UV, z particleFade
tri.localOrigin = originPoint.localOrigin;
return tri;
}
//geometry shader
//for every vertex from the vertex shader it will create a particle quad of 4 vertexes and 2 triangles
[maxvertexcount(4)]
void geom(point v2g input[1], inout TriangleStream outStream)
{
g2f tri;
//common values for all the quad
float localScale = (input[0].hashVect.x*(_MaxScale - 1)) + 1;
float4x4 M = rand_rotation(
(float3(frac(_Rotation),0,0))+input[0].hashVect,
localScale,
input[0].localOrigin.xyz/input[0].localOrigin.w);
float4x4 mvMatrix = mul(mul(UNITY_MATRIX_V, unity_ObjectToWorld), M);
float3 viewDir = normalize(mvMatrix[2].xyz); //cameraSpace viewDir I think
//build our quad
tri = buildQuadVertex(input[0],float3(-0.5,-0.5,0.0),float2(0.0,0.0),viewDir,mvMatrix,localScale);
outStream.Append(tri);
tri = buildQuadVertex(input[0],float3(-0.5,0.5,0.0),float2(0.0,1.0),viewDir,mvMatrix,localScale);
outStream.Append(tri);
tri = buildQuadVertex(input[0],float3(0.5,-0.5,0.0),float2(1.0,0.0),viewDir,mvMatrix,localScale);
outStream.Append(tri);
tri = buildQuadVertex(input[0],float3(0.5,0.5,0.0),float2(1.0,1.0),viewDir,mvMatrix,localScale);
outStream.Append(tri);
outStream.RestartStrip();
}
float4 frag (g2f IN) : COLOR
{
half4 tex;
tex.r = tex2D(_Tex, IN.texcoordZY).r;
tex.g = tex2D(_Tex, IN.texcoordXZ).g;
tex.b = tex2D(_Tex, IN.texcoordXY).b;
tex.a = 0;
tex.rgb *= IN.viewDir.rgb;
half4 vect = half4( IN.viewDir.rgb, 0);
tex /= vectorSum(vect);
tex = half4(1, 1, 1, vectorSum(tex));
half4 color = FRAG_GET_NO_LOD_CUBE_MAP_1(_MainTex, IN.planetPos);
color = ALPHA_COLOR_1(color);
color *= _Color * IN.color;
color.a *= tex.a;
tex.a = IN.viewDir.w*tex.a;
//half3 normT = UnpackNormal(tex2D(_BumpMap, IN.uv));
half3 normT;
normT.xy = ((2*IN.uv.xy)-1);
normT.z = sqrt(1 - saturate(dot(normT.xy, normT.xy)));
//normT.xy = 2 * INV_PI*asin((2 * IN.uv) - 1) ;
//normT.xy = sin(PI*(IN.uv-.5));
//normT.z = 1;
//color.rg = IN.uv;
#if (defined(SCATTERER_ON) && defined(SCATTERER_USE_ORIG_DIR_COLOR_ON))
_LightColor0.rgb = scattererOrigDirectionalColor;
#endif
color.rgb *= ScatterColorLight(IN.lightDirT, IN.viewDirT, normT, tex, _MinScatter, _Opacity, 1).rgb;
#ifdef SOFT_DEPTH_ON
float depth = UNITY_SAMPLE_DEPTH(tex2Dlod(EVEDownscaledDepth, float4(IN.projPos.xy/IN.projPos.w,0.0,0.0))); //to be sure we are reading a single point/using point filtering
depth = LinearEyeDepth (depth);
float partZ = IN.projPos.z;
float fade = depth >= (0.99 * _ProjectionParams.z) ? 1.0 : saturate (_InvFade * (depth-partZ)); //fade near objects but don't fade on far plane (max depth value)
color.a *= fade;
#endif
color.a *= IN.uv.z; //particle fade as they approach camera
return color;
}
ENDCG
}
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/GeometryCloudVolumeParticleToTexture.shader.meta
================================================
fileFormatVersion: 2
guid: 1bbfba4363c8e1e4b8214b4004316ce5
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/SphereCloud.shader
================================================
Shader "Scatterer-EVE/Cloud" {
Properties{
_Color("Color Tint", Color) = (1,1,1,1)
_MainTex("Main (RGB)", 2D) = "white" {}
_DetailTex("Detail (RGB)", 2D) = "white" {}
_UVNoiseTex("UV Noise (RG)", 2D) = "black" {}
_FalloffPow("Falloff Power", Range(0,3)) = 2
_FalloffScale("Falloff Scale", Range(0,20)) = 3
_DetailScale("Detail Scale", Range(0,100)) = 100
_DetailDist("Detail Distance", Range(0,1)) = 0.00875
_UVNoiseScale("UV Noise Scale", Range(0,0.1)) = 0.01
_UVNoiseStrength("UV Noise Strength", Range(0,0.1)) = 0.002
_UVNoiseAnimation("UV Noise Animation", Vector) = (0.002,0.001,0)
_UniversalTime("Universal Time", Vector) = (0,0,0,0)
_MinLight("Minimum Light", Range(0,1)) = 0
_DistFade("Fade Distance", Range(0,100)) = 10
_DistFadeVert("Fade Scale", Range(0,1)) = .002
_RimDist("Rim Distance", Range(0,1)) = 1
_RimDistSub("Rim Distance Sub", Range(0,2)) = 1.01
_InvFade("Soft Particles Factor", Range(0.01,3.0)) = .01
_OceanRadius("Ocean Radius", Float) = 63000
_PlanetOrigin("Sphere Center", Vector) = (0,0,0,1)
_DepthPull("Depth Augment", Float) = .99
_SunPos("_SunPos", Vector) = (0,0,0)
_SunRadius("_SunRadius", Float) = 1
}
Category{
Tags { "Queue" = "Transparent-2" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
//Fog { Mode Global}
//AlphaTest Greater 0
//ColorMask RGB
Cull Off
ZWrite Off
Lighting On
SubShader {
Pass {
Lighting On
Tags { "LightMode" = "ForwardBase"}
CGPROGRAM
#include "EVEUtils.cginc"
#pragma target 3.0
#pragma glsl
#pragma vertex vert
#pragma fragment frag
#define MAG_ONE 1.4142135623730950488016887242097
#pragma multi_compile SOFT_DEPTH_OFF SOFT_DEPTH_ON
#pragma multi_compile WORLD_SPACE_OFF WORLD_SPACE_ON
#pragma multi_compile MAP_TYPE_1 MAP_TYPE_CUBE_1 MAP_TYPE_CUBE2_1 MAP_TYPE_CUBE6_1
#pragma multi_compile SCATTERER_OFF SCATTERER_ON
#ifdef SCATTERER_ON
#pragma multi_compile ECLIPSES_OFF ECLIPSES_ON
#pragma multi_compile RINGSHADOW_OFF RINGSHADOW_ON
#pragma multi_compile PRESERVECLOUDCOLORS_OFF PRESERVECLOUDCOLORS_ON
//#pragma multi_compile GODRAYS_OFF GODRAYS_ON
#define GODRAYS_OFF
#endif
#ifndef MAP_TYPE_CUBE2_1
#pragma multi_compile ALPHAMAP_N_1 ALPHAMAP_1
#endif
#include "alphaMap.cginc"
#include "cubeMap.cginc"
#ifdef SCATTERER_ON
#include "../CommonAtmosphere.cginc"
#include "../EclipseCommon.cginc"
#include "../Atmo/Godrays/GodraysCommon.cginc"
#include "../RingCommon.cginc"
#endif
CUBEMAP_DEF_1(_MainTex)
sampler2D _DetailTex;
sampler2D _UVNoiseTex;
fixed4 _Color;
float _FalloffPow;
float _FalloffScale;
float _DetailScale;
float _DetailDist;
float _UVNoiseScale;
float _UVNoiseStrength;
float2 _UVNoiseAnimation;
float _MinLight;
float _DistFade;
float _DistFadeVert;
float _RimDist;
float _RimDistSub;
float _OceanRadius;
float _InvFade;
float3 _PlanetOrigin;
sampler2D _CameraDepthTexture;
float _DepthPull;
#if defined (SCATTERER_ON)
uniform float cloudColorMultiplier;
uniform float cloudScatteringMultiplier;
uniform float cloudSkyIrradianceMultiplier;
uniform float3 _Sun_WorldSunDir;
uniform float extinctionThickness;
float _Radius;
#if defined (GODRAYS_ON)
uniform sampler2D _godrayDepthTexture;
uniform float _godrayStrength;
#endif
#endif
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float3 normal : NORMAL;
};
struct v2f {
float4 pos : SV_POSITION;
float3 worldVert : TEXCOORD0;
float3 L : TEXCOORD1;
float4 objDetail : TEXCOORD2;
float4 objMain : TEXCOORD3;
float3 worldNormal : TEXCOORD4;
float3 viewDir : TEXCOORD5;
LIGHTING_COORDS(6,7)
float4 projPos : TEXCOORD8;
#if defined (SCATTERER_ON)
float3 worldOrigin: TEXCOORD9;
#endif
};
v2f vert(appdata_t v)
{
v2f o;
UNITY_INITIALIZE_OUTPUT(v2f, o);
o.pos = UnityObjectToClipPos(v.vertex);
float4 vertexPos = mul(unity_ObjectToWorld, v.vertex);
float3 origin = mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz;
o.worldVert = vertexPos;
o.worldNormal = normalize(vertexPos - origin);
o.objMain = mul(_MainRotation, v.vertex);
o.objDetail = mul(_DetailRotation, o.objMain);
o.viewDir = normalize(WorldSpaceViewDir(v.vertex));
o.projPos = ComputeScreenPos(o.pos);
COMPUTE_EYEDEPTH(o.projPos.z);
TRANSFER_VERTEX_TO_FRAGMENT(o);
o.L = _PlanetOrigin - _WorldSpaceCameraPos.xyz;
#if defined (SCATTERER_ON)
o.worldOrigin = origin;
#endif
return o;
}
struct fout
{
float4 color : COLOR;
#if !(SHADER_API_D3D11 && WORLD_SPACE_ON)
float depth : DEPTH;
#endif
};
fout frag(v2f IN)
{
fout OUT;
float4 color;
float4 main;
main = GET_CUBE_MAP_P(_MainTex, IN.objMain.xyz, _UVNoiseTex, _UVNoiseScale, _UVNoiseStrength, _UVNoiseAnimation);
main = ALPHA_COLOR_1(main);
float4 detail = GetCubeDetailMap(_DetailTex, IN.objDetail, _DetailScale);
float viewDist = distance(IN.worldVert,_WorldSpaceCameraPos);
half detailLevel = saturate(2 * _DetailDist*viewDist);
color = _Color * main.rgba * lerp(detail.rgba, 1, detailLevel);
float rim = saturate(abs(dot(IN.viewDir, IN.worldNormal)));
rim = saturate(pow(_FalloffScale*rim,_FalloffPow));
float dist = distance(IN.worldVert,_WorldSpaceCameraPos);
float distLerp = saturate(_RimDist*(distance(_PlanetOrigin,_WorldSpaceCameraPos) - _RimDistSub*distance(IN.worldVert,_PlanetOrigin)));
float distFade = 1 - GetDistanceFade(dist, _DistFade, _DistFadeVert);
float distAlpha = lerp(distFade, rim, distLerp);
color.a = lerp(0, color.a, distAlpha);
#ifdef WORLD_SPACE_ON
float3 worldDir = normalize(IN.worldVert - _WorldSpaceCameraPos.xyz);
float tc = dot(IN.L, worldDir);
float d = sqrt(dot(IN.L,IN.L) - (tc*tc));
float3 norm = normalize(-IN.L);
float d2 = pow(d,2);
float td = sqrt(dot(IN.L,IN.L) - d2);
float tlc = sqrt((_OceanRadius*_OceanRadius) - d2);
half sphereCheck = saturate(step(d, _OceanRadius)*step(0.0, tc) + step(length(IN.L), _OceanRadius));
float sphereDist = lerp(tlc - td, tc - tlc, step(0.0, tc));
sphereCheck *= step(sphereDist, dist);
color.a *= 1 - sphereCheck;
#endif
////////////////////////////SCATTERER OFF
#if !defined (SCATTERER_ON)
//lighting
half transparency = color.a;
float4 scolor = SpecularColorLight(_WorldSpaceLightPos0, IN.viewDir, IN.worldNormal, color, 0, 0, LIGHT_ATTENUATION(IN));
scolor *= Terminator(normalize(_WorldSpaceLightPos0), IN.worldNormal);
scolor.a = transparency;
#ifdef SOFT_DEPTH_ON
float depth = UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(IN.projPos)));
depth = LinearEyeDepth(depth);
float partZ = IN.projPos.z;
float fade = saturate(_InvFade * (depth - partZ));
scolor.a *= fade;
#endif
//scolor.rgb *= MultiBodyShadow(IN.worldVert, _SunRadius, _SunPos, _ShadowBodies); //causes artifacts idk why
OUT.color = lerp(scolor, color, _MinLight);
////////////////////////////SCATTERER ON
#else
float4 texColor = color;
float3 extinction = float3(0, 0, 0);
#ifdef WORLD_SPACE_ON
float3 WCP = _WorldSpaceCameraPos; //unity supplied, in local Space
float3 worldPos = IN.worldVert;
float3 worldOrigin = IN.worldOrigin;
#else
float3 WCP = _WorldSpaceCameraPos * 6000; //unity supplied, converted from ScaledSpace to localSpace coords
float3 worldPos = IN.worldVert * 6000;
float3 worldOrigin = IN.worldOrigin * 6000;
#endif
float3 relWorldPos=worldPos-worldOrigin;
relWorldPos = _Radius * normalize(relWorldPos);
float alt = length(relWorldPos);
float threshold = Rg * 1.00333333;
relWorldPos = (alt < threshold) ? normalize(relWorldPos) * (threshold) : relWorldPos; //artifacts fix (black scattering and overbright skyirradiance) when cloud altitude < Rg *( 1 + 2000/600000)
float3 relCameraPos=WCP-worldOrigin;
float3 scatteringPos = relWorldPos;
#if defined (GODRAYS_ON) && defined(WORLD_SPACE_ON)
float2 depthUV = IN.projPos.xy/IN.projPos.w;
float godrayDepth = sampleGodrayDepth(_godrayDepthTexture, depthUV, _godrayStrength);
godrayDepth = min(godrayDepth, _godrayStrength * length(scatteringPos - relCameraPos));
scatteringPos -= godrayDepth * IN.viewDir; //this works but it looks suuuper wrong when outside the cloud layer, to be revised I guess
#endif
//inScattering from cloud to observer
float3 inscatter = InScattering2(relCameraPos, scatteringPos, _Sun_WorldSunDir,extinction);
//extinction from cloud to observer
extinction = getExtinction(relCameraPos, relWorldPos, 1.0, 1.0, 1.0);
//extinction of light from sun to cloud
extinction *= getSkyExtinction(relWorldPos,_Sun_WorldSunDir);
extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) );
extinction*= getEclipseShadow(relWorldPos, 20.0 * _Sun_WorldSunDir * Rg, 0.0, Rg, Rg); //just the terminator, extinction ignores ground intersection
//skyLight
float3 skyE = SimpleSkyirradiance(relWorldPos, IN.viewDir, _Sun_WorldSunDir);
#if defined (PRESERVECLOUDCOLORS_OFF)
color = float4(hdrNoExposure(color.rgb*cloudColorMultiplier*extinction+ inscatter*cloudScatteringMultiplier+skyE*cloudSkyIrradianceMultiplier), color.a); //not bad
#else
float3 cloudColor = color.rgb*cloudColorMultiplier*(extinction+hdrNoExposure(skyE * cloudSkyIrradianceMultiplier));
inscatter = hdrNoExposure(inscatter * cloudScatteringMultiplier);
color = float4(cloudColor + (float3(1.0,1.0,1.0)-cloudColor)*inscatter, color.a); //basically soft blend
#endif
#if defined (ECLIPSES_ON)
color.rgb*=getEclipseShadows(worldPos);
#endif
#if defined (RINGSHADOW_ON)
color.rgb *= getLinearRingColor(relWorldPos, _Sun_WorldSunDir, 0.0).a;
#endif
OUT.color = lerp(color, texColor, _MinLight);
#endif //endif SCATTERER_ON
float depthWithOffset = IN.projPos.z;
#ifndef WORLD_SPACE_ON
depthWithOffset *= _DepthPull;
OUT.color.a *= step(0, dot(IN.viewDir, IN.worldNormal));
#endif
#if !(SHADER_API_D3D11 && WORLD_SPACE_ON) //fixes clouds fading into the planet when zooming out
OUT.depth = (1.0 - depthWithOffset * _ZBufferParams.w) / (depthWithOffset * _ZBufferParams.z);
#endif
return OUT;
}
ENDCG
}
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/SphereCloud.shader.meta
================================================
fileFormatVersion: 2
guid: 7071adaea60f6124d9ab426b002d5afa
timeCreated: 1470912280
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/SphereCloudShadowMap.shader
================================================
Shader "Scatterer-EVE/CloudShadowMap"
{
Properties
{
_Color("Color Tint", Color) = (1,1,1,1)
_MainTex("Main (RGB)", 2D) = "white" {}
_DetailTex("Detail (RGB)", 2D) = "white" {}
_UVNoiseTex("UV Noise (RG)", 2D) = "black" {}
_FalloffPow("Falloff Power", Range(0,3)) = 2
_FalloffScale("Falloff Scale", Range(0,20)) = 3
_DetailScale("Detail Scale", Range(0,100)) = 100
_DetailDist("Detail Distance", Range(0,1)) = 0.00875
_UVNoiseScale("UV Noise Scale", Range(0,0.1)) = 0.01
_UVNoiseStrength("UV Noise Strength", Range(0,0.1)) = 0.002
_UVNoiseAnimation("UV Noise Animation", Vector) = (0.002,0.001,0)
_UniversalTime("Universal Time", Vector) = (0,0,0,0)
_MinLight("Minimum Light", Range(0,1)) = 0
_DistFade("Fade Distance", Range(0,100)) = 10
_DistFadeVert("Fade Scale", Range(0,1)) = .002
_RimDist("Rim Distance", Range(0,1)) = 1
_RimDistSub("Rim Distance Sub", Range(0,2)) = 1.01
_InvFade("Soft Particles Factor", Range(0.01,3.0)) = .01
_OceanRadius("Ocean Radius", Float) = 63000
_PlanetOrigin("Sphere Center", Vector) = (0,0,0,1)
_DepthPull("Depth Augment", Float) = .99
_SunPos("_SunPos", Vector) = (0,0,0)
_SunRadius("_SunRadius", Float) = 1
}
SubShader
{
Pass
{
Tags { "LightMode" = "ShadowCaster"}
BlendOp Max
Blend One One
CGPROGRAM
#include "EVEUtils.cginc"
#pragma target 3.0
#pragma glsl
#pragma vertex vert
#pragma fragment frag
#define MAG_ONE 1.4142135623730950488016887242097
#pragma multi_compile MAP_TYPE_1 MAP_TYPE_CUBE_1 MAP_TYPE_CUBE2_1 MAP_TYPE_CUBE6_1
#ifndef MAP_TYPE_CUBE2_1
#pragma multi_compile ALPHAMAP_N_1 ALPHAMAP_1
#endif
#include "alphaMap.cginc"
#include "cubeMap.cginc"
CUBEMAP_DEF_1(_MainTex)
fixed4 _Color;
uniform sampler2D _DetailTex;
uniform sampler2D _UVNoiseTex;
fixed4 _DetailOffset;
float _DetailScale;
float _DetailDist;
float _UVNoiseScale;
float _UVNoiseStrength;
float2 _UVNoiseAnimation;
float4 _SunDir;
float _Radius;
float _PlanetRadius;
float3 _PlanetOrigin;
float _godrayCloudThreshold;
struct appdata_t
{
float4 vertex : POSITION;
};
struct v2f
{
float4 pos : SV_POSITION;
//float4 objMain : TEXCOORD0;
float4 worldPos : TEXCOORD0;
};
v2f vert(appdata_t v)
{
v2f o;
o.worldPos = float4(_PlanetOrigin + _Radius * normalize(v.vertex.xyz),1.0);
o.pos = UnityWorldToClipPos(o.worldPos);
// o.worldPos = float4(_PlanetOrigin + v.vertex.xyz/v.vertex.w * _Radius, 1.0);
// o.pos = UnityWorldToClipPos(o.worldPos);
//#if defined(UNITY_REVERSED_Z)
float clamped = min(o.pos.z, o.pos.w*UNITY_NEAR_CLIP_VALUE);
//#else
// float clamped = max(clipPos.z, clipPos.w*UNITY_NEAR_CLIP_VALUE);
//#endif
o.pos.z = lerp(o.pos.z, clamped, unity_LightShadowBias.y);
// TRANSFER_SHADOW_CASTER_NORMALOFFSET(o);
// UnityApplyLinearShadowBias(o.pos);
return o;
}
float4 frag(v2f IN) : SV_Target
{
float4 worldPos = float4(IN.worldPos.xyz/IN.worldPos.w,1.0);
float4 mainPos = mul(_MainRotation, worldPos);
float4 color;
float4 main;
main = GET_CUBE_MAP_P(_MainTex, mainPos.xyz/mainPos.w, _UVNoiseTex, _UVNoiseScale, _UVNoiseStrength, _UVNoiseAnimation);
main = ALPHA_COLOR_1(main);
color = _Color * main.rgba;
if (color.a < _godrayCloudThreshold)
discard;
return float4(IN.pos.z/IN.pos.w,0.0,0.0,1.0);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/SphereCloudShadowMap.shader.meta
================================================
fileFormatVersion: 2
guid: 1389c6be1c6e80b4eb8604aabdda8255
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/alphaMap.cginc
================================================
#ifndef ALPHA_MAP_CG_INC
#define ALPHA_MAP_CG_INC
inline half vectorSum(half4 v)
{
return (v.x + v.y + v.z + v.w);
}
half4 alphaMask1;
#define ALPHA_VALUE_1(color) \
vectorSum( color * alphaMask1 )
#ifdef ALPHAMAP_1
#define ALPHA_COLOR_1(color) half4(1, 1, 1, ALPHA_VALUE_1(color))
#else
#define ALPHA_COLOR_1(color) color
#endif
#endif
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/alphaMap.cginc.meta
================================================
fileFormatVersion: 2
guid: 1852920dca83b454c8e49493d9ead74c
timeCreated: 1470912310
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/cubeMap.cginc
================================================
#ifndef CUBE_MAP_CG_INC
#define CUBE_MAP_CG_INC
#ifdef MAP_TYPE_CUBE_1
#define GET_CUBE_MAP_1(name, vect) GetCubeMap(cube ## name, vect)
#define GET_CUBE_MAP_P(name, vect, n, nsc, nst, na) GetCubeMapPerturbed(cube ## name, vect, n, nsc, nst, na)
#define GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(cube ## name, vect)
#define FRAG_GET_NO_LOD_CUBE_MAP_1(name, vect) half4(1,1,1,1)
#define VERT_GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(cube ## name, vect)
#define CUBEMAP_DEF_1(name) \
uniform samplerCUBE cube ## name;
#elif defined (MAP_TYPE_CUBE6_1)
#define GET_CUBE_MAP_1(name, vect) GetCubeMap(cube ## name ## xn, cube ## name ## xp, \
cube ## name ## yn, cube ## name ## yp, \
cube ## name ## zn, cube ## name ## zp, vect)
#define GET_CUBE_MAP_P(name, vect, n, nsc, nst, na) GetCubeMapPerturbed(cube ## name ## xn, cube ## name ## xp, \
cube ## name ## yn, cube ## name ## yp, \
cube ## name ## zn, cube ## name ## zp, vect, n, nsc, nst, na)
#define GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(cube ## name ## xn, cube ## name ## xp, \
cube ## name ## yn, cube ## name ## yp, \
cube ## name ## zn, cube ## name ## zp, vect)
#define FRAG_GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMap(cube ## name ## xn, cube ## name ## xp, \
cube ## name ## yn, cube ## name ## yp, \
cube ## name ## zn, cube ## name ## zp, vect)
#define VERT_GET_NO_LOD_CUBE_MAP_1(name, vect) half4(1,1,1,1)
#define CUBEMAP_DEF_1(name) \
sampler2D cube ## name ## xn, cube ## name ## xp; \
sampler2D cube ## name ## yn, cube ## name ## yp; \
sampler2D cube ## name ## zn, cube ## name ## zp;
#elif defined (MAP_TYPE_CUBE2_1)
#define GET_CUBE_MAP_1(name, vect) GetCubeMap(cube ## name ## POS, cube ## name ## NEG, vect)
#define GET_CUBE_MAP_P(name, vect, n, nsc, nst, na) GetCubeMapPerturbed(cube ## name ## POS, cube ## name ## NEG, vect, n, nsc, nst, na)
#define GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(cube ## name ## POS, cube ## name ## NEG, vect)
#define FRAG_GET_NO_LOD_CUBE_MAP_1(name, vect) half4(1,1,1,1)
#define VERT_GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(cube ## name ## POS, cube ## name ## NEG, vect)
#define CUBEMAP_DEF_1(name) \
sampler2D cube ## name ## POS; \
sampler2D cube ## name ## NEG;
#else
#define GET_CUBE_MAP_1(name, vect) GetCubeMap(name, vect)
#define GET_CUBE_MAP_P(name, vect, n, nsc, nst, na) GetCubeMapPerturbed(name, vect, n, nsc, nst, na)
#define GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(name, vect)
#define FRAG_GET_NO_LOD_CUBE_MAP_1(name, vect) half4(1,1,1,1)
#define VERT_GET_NO_LOD_CUBE_MAP_1(name, vect) GetCubeMapNoLOD(name, vect)
#define CUBEMAP_DEF_1(name) \
sampler2D name;
#endif
inline float4 CubeDerivatives(float2 uv, float scale)
{
//Make the UV continuous.
float2 uvS = abs(uv - (.5*scale));
float2 uvCont;
uvCont.x = max(uvS.x, uvS.y);
uvCont.y = min(uvS.x, uvS.y);
return float4(ddx(uvCont), ddy(uvCont));
}
inline float4 Derivatives(float2 uv)
{
float2 uvCont = uv;
//Make the UV continuous.
uvCont.x = abs(uvCont.x - .5);
return float4(ddx(uvCont), ddy(uvCont));
}
inline float2 GetCubeUV(float3 cubeVect, float2 uvOffset)
{
float2 uv;
uv.x = .5 + (INV_2PI*atan2(cubeVect.x, cubeVect.z));
uv.y = INV_PI*acos(cubeVect.y);
uv += uvOffset;
return uv;
}
#define GetCubeCubeUV(cubeVect) \
float3 cubeVectNorm = normalize(cubeVect); \
float3 cubeVectNormAbs = abs(cubeVectNorm);\
half zxlerp = step(cubeVectNormAbs.x, cubeVectNormAbs.z);\
half nylerp = step(cubeVectNormAbs.y, max(cubeVectNormAbs.x, cubeVectNormAbs.z));\
half s = lerp(cubeVectNorm.x, cubeVectNorm.z, zxlerp);\
s = sign(lerp(cubeVectNorm.y, s, nylerp));\
half3 detailCoords = lerp(half3(1, -s, -1)*cubeVectNorm.xzy, half3(1, s, -1)*cubeVectNorm.zxy, zxlerp);\
detailCoords = lerp(half3(1, 1, s)*cubeVectNorm.yxz, detailCoords, nylerp);\
half2 uv = ((.5*detailCoords.yz) / abs(detailCoords.x)) + .5;
inline half4 GetCubeMapNoLOD(sampler2D texSampler, float3 cubeVect)
{
float4 uv;
float3 cubeVectNorm = normalize(cubeVect);
uv.xy = GetCubeUV(cubeVectNorm, float2(0, 0));
uv.zw = float2(0, 0);
half4 tex = tex2Dlod(texSampler, uv);
return tex;
}
inline half4 GetCubeMap(sampler2D texSampler, float3 cubeVect)
{
float3 cubeVectNorm = normalize(cubeVect);
float2 uv = GetCubeUV(cubeVectNorm, float2(0, 0));
float4 uvdd = Derivatives(uv);
half4 tex = tex2D(texSampler, uv, uvdd.xy, uvdd.zw);
return tex;
}
inline half4 GetCubeMapPerturbed(sampler2D texSampler, float3 cubeVect, sampler2D uvNoiseSampler, float uvNoiseScale, float uvNoiseStrength, float2 uvNoiseAnimation)
{
float3 cubeVectNorm = normalize(cubeVect);
float2 uv = GetCubeUV(cubeVectNorm, float2(0, 0));
float2 uvd = fmod(uv, uvNoiseScale) / uvNoiseScale + uvNoiseAnimation*float2(_UniversalTime.x, _UniversalTime.x);
uv += (tex2D(uvNoiseSampler, uvd) - float2(0.5, 0.5))*uvNoiseStrength;
float4 uvdd = Derivatives(uv);
half4 tex = tex2D(texSampler, uv, uvdd.xy, uvdd.zw);
return tex;
}
inline half4 GetCubeMapNoLOD(samplerCUBE texSampler, float3 cubeVect)
{
half4 uv;
uv.xyz = normalize(cubeVect);
uv.w = 0;
half4 tex = texCUBElod(texSampler, uv);
return tex;
}
inline half4 GetCubeMap(samplerCUBE texSampler, float3 cubeVect)
{
half4 tex = texCUBE(texSampler, normalize(cubeVect));
return tex;
}
inline half4 GetCubeMapPerturbed(samplerCUBE texSampler, float3 cubeVect, sampler2D uvNoiseSampler, float uvNoiseScale, float uvNoiseStrength, float2 uvNoiseAnimation)
{
cubeVect = normalize(cubeVect);
float2 uv;
uv.x = .5 + (INV_2PI*atan2(cubeVect.x, cubeVect.z));
uv.y = INV_PI*acos(cubeVect.y);
float2 uvd = fmod(cubeVect, uvNoiseScale) / uvNoiseScale + uvNoiseAnimation*float2(_UniversalTime.x, _UniversalTime.x);
cubeVect.xy += (tex2D(uvNoiseSampler, uvd) - float2(0.5, 0.5))*uvNoiseStrength;
half4 tex = texCUBE(texSampler, cubeVect);
return tex;
}
inline half4 GetCubeMapNoLOD(sampler2D texXn, sampler2D texXp, sampler2D texYn, sampler2D texYp, sampler2D texZn, sampler2D texZp, float3 cubeVect)
{
float4 uv4;
uv4.zw = float2(0, 0);
GetCubeCubeUV(cubeVect);
uv4.xy = uv;
half4 sampxn = tex2Dlod(texXn, uv4);
half4 sampxp = tex2Dlod(texXp, uv4);
half4 sampyn = tex2Dlod(texYn, uv4);
half4 sampyp = tex2Dlod(texYp, uv4);
half4 sampzn = tex2Dlod(texZn, uv4);
half4 sampzp = tex2Dlod(texZp, uv4);
half4 sampx = lerp(sampxn, sampxp, step(0, s));
half4 sampy = lerp(sampyn, sampyp, step(0, s));
half4 sampz = lerp(sampzn, sampzp, step(0, s));
half4 samp = lerp(sampx, sampz, zxlerp);
samp = lerp(sampy, samp, nylerp);
return samp;
}
inline half4 GetCubeMap(sampler2D texXn, sampler2D texXp, sampler2D texYn, sampler2D texYp, sampler2D texZn, sampler2D texZp, float3 cubeVect)
{
GetCubeCubeUV(cubeVect);
//this fixes UV discontinuity on Y-X seam by swapping uv coords in derivative calcs when in the X quadrants.
float4 uvdd = CubeDerivatives(uv, 1);
half4 sampxn = tex2D(texXn, uv, uvdd.xy, uvdd.zw);
half4 sampxp = tex2D(texXp, uv, uvdd.xy, uvdd.zw);
half4 sampyn = tex2D(texYn, uv, uvdd.xy, uvdd.zw);
half4 sampyp = tex2D(texYp, uv, uvdd.xy, uvdd.zw);
half4 sampzn = tex2D(texZn, uv, uvdd.xy, uvdd.zw);
half4 sampzp = tex2D(texZp, uv, uvdd.xy, uvdd.zw);
half4 sampx = lerp(sampxn, sampxp, step(0, s));
half4 sampy = lerp(sampyn, sampyp, step(0, s));
half4 sampz = lerp(sampzn, sampzp, step(0, s));
half4 samp = lerp(sampx, sampz, zxlerp);
samp = lerp(sampy, samp, nylerp);
return samp;
}
inline half4 GetCubeMapPerturbed(sampler2D texXn, sampler2D texXp, sampler2D texYn, sampler2D texYp, sampler2D texZn, sampler2D texZp, float3 cubeVect, sampler2D uvNoiseSampler, float uvNoiseScale, float uvNoiseStrength, float2 uvNoiseAnimation)
{
GetCubeCubeUV(cubeVect);
float2 uvd = fmod(uv, uvNoiseScale) / uvNoiseScale + uvNoiseAnimation*float2(_UniversalTime.x, _UniversalTime.x);
uv += (tex2D(uvNoiseSampler, uvd) - float2(0.5, 0.5))*uvNoiseStrength;
//this fixes UV discontinuity on Y-X seam by swapping uv coords in derivative calcs when in the X quadrants.
float4 uvdd = CubeDerivatives(uv, 1);
half4 sampxn = tex2D(texXn, uv, uvdd.xy, uvdd.zw);
half4 sampxp = tex2D(texXp, uv, uvdd.xy, uvdd.zw);
half4 sampyn = tex2D(texYn, uv, uvdd.xy, uvdd.zw);
half4 sampyp = tex2D(texYp, uv, uvdd.xy, uvdd.zw);
half4 sampzn = tex2D(texZn, uv, uvdd.xy, uvdd.zw);
half4 sampzp = tex2D(texZp, uv, uvdd.xy, uvdd.zw);
half4 sampx = lerp(sampxn, sampxp, step(0, s));
half4 sampy = lerp(sampyn, sampyp, step(0, s));
half4 sampz = lerp(sampzn, sampzp, step(0, s));
half4 samp = lerp(sampx, sampz, zxlerp);
samp = lerp(sampy, samp, nylerp);
return samp;
}
inline half4 GetCubeMapNoLOD(sampler2D texSamplerPos, sampler2D texSamplerNeg, float3 cubeVect)
{
float4 uv4;
uv4.zw = float2(0, 0);
GetCubeCubeUV(cubeVect);
uv4.xy = uv;
half4 texPos = tex2Dlod(texSamplerPos, uv4);
half4 texNeg = tex2Dlod(texSamplerNeg, uv4);
half4 tex = lerp(texNeg, texPos, step(0, s));
half alpha = lerp(tex.x, tex.z, zxlerp);
alpha = lerp(tex.y, alpha, nylerp);
return half4(tex.a, tex.a, tex.a, alpha);
}
inline half4 GetCubeMap(sampler2D texSamplerPos, sampler2D texSamplerNeg, float3 cubeVect)
{
GetCubeCubeUV(cubeVect);
float4 uvdd = CubeDerivatives(uv, 1);
half4 texPos = tex2D(texSamplerPos, uv, uvdd.xy, uvdd.zw);
half4 texNeg = tex2D(texSamplerNeg, uv, uvdd.xy, uvdd.zw);
half4 tex = lerp(texNeg, texPos, step(0, s));
half alpha = lerp(tex.x, tex.z, zxlerp);
alpha = lerp(tex.y, alpha, nylerp);
return half4(tex.a, tex.a, tex.a, alpha);
}
inline half4 GetCubeMapPerturbed(sampler2D texSamplerPos, sampler2D texSamplerNeg, float3 cubeVect, sampler2D uvNoiseSampler, float uvNoiseScale, float uvNoiseStrength, float2 uvNoiseAnimation)
{
GetCubeCubeUV(cubeVect);
float2 uvd = fmod(uv, uvNoiseScale) / uvNoiseScale + uvNoiseAnimation*float2(_UniversalTime.x, _UniversalTime.x);
uv += (tex2D(uvNoiseSampler, uvd) - float2(0.5, 0.5))*uvNoiseStrength;
float4 uvdd = CubeDerivatives(uv, 1);
half4 texPos = tex2D(texSamplerPos, uv, uvdd.xy, uvdd.zw);
half4 texNeg = tex2D(texSamplerNeg, uv, uvdd.xy, uvdd.zw);
half4 tex = lerp(texNeg, texPos, step(0, s));
half alpha = lerp(tex.x, tex.z, zxlerp);
alpha = lerp(tex.y, alpha, nylerp);
return half4(tex.a, tex.a, tex.a, alpha);
}
inline half4 GetCubeDetailMapNoLOD(sampler2D texSampler, float3 cubeVect, float detailScale)
{
float4 uv4;
uv4.zw = float2(0, 0);
GetCubeCubeUV(cubeVect);
uv4.xy = uv;
half4 tex = tex2Dlod(texSampler, uv4);
return tex;
}
inline half4 GetCubeDetailMap(sampler2D texSampler, float3 cubeVect, float detailScale)
{
GetCubeCubeUV(cubeVect);
uv*=detailScale;
float4 uvdd = CubeDerivatives(uv, detailScale);
half4 tex = tex2D(texSampler, uv, uvdd.xy, uvdd.zw);
return tex;
}
#endif
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/cubeMap.cginc.meta
================================================
fileFormatVersion: 2
guid: 6a022d21eb285c143ae29fc2aca21e11
timeCreated: 1470912310
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/noiseSimplex.cginc
================================================
#ifndef NOISE_SIMPLEX_FUNC
#define NOISE_SIMPLEX_FUNC
/*
Description:
Array- and textureless CgFx/HLSL 2D, 3D and 4D simplex noise functions.
a.k.a. simplified and optimized Perlin noise.
The functions have very good performance
and no dependencies on external data.
2D - Very fast, very compact code.
3D - Fast, compact code.
4D - Reasonably fast, reasonably compact code.
------------------------------------------------------------------
Ported by:
Lex-DRL
I've ported the code from GLSL to CgFx/HLSL for Unity,
added a couple more optimisations (to speed it up even further)
and slightly reformatted the code to make it more readable.
Original GLSL functions:
https://github.com/ashima/webgl-noise
Credits from original glsl file are at the end of this cginc.
------------------------------------------------------------------
Usage:
float ns = snoise(v);
// v is any of: float2, float3, float4
Return type is float.
To generate 2 or more components of noise (colorful noise),
call these functions several times with different
constant offsets for the arguments.
E.g.:
float3 colorNs = float3(
snoise(v),
snoise(v + 17.0),
snoise(v - 43.0),
);
Remark about those offsets from the original author:
People have different opinions on whether these offsets should be integers
for the classic noise functions to match the spacing of the zeroes,
so we have left that for you to decide for yourself.
For most applications, the exact offsets don't really matter as long
as they are not too small or too close to the noise lattice period
(289 in this implementation).
*/
// 1 / 289
#define NOISE_SIMPLEX_1_DIV_289 0.00346020761245674740484429065744f
// ( x*34.0 + 1.0 )*x =
// x*x*34.0 + x
float permute(float x) {
return fmod(
x*x*34.0 + x,
289.0
);
}
float3 permute(float3 x) {
return fmod(
x*x*34.0 + x,
289.0
);
}
float4 permute(float4 x) {
return fmod(
x*x*34.0 + x,
289.0
);
}
float taylorInvSqrt(float r) {
return 1.79284291400159 - 0.85373472095314 * r;
}
float4 taylorInvSqrt(float4 r) {
return 1.79284291400159 - 0.85373472095314 * r;
}
float4 grad4(float j, float4 ip)
{
const float4 ones = float4(1.0, 1.0, 1.0, -1.0);
float4 p, s;
p.xyz = floor(frac(j * ip.xyz) * 7.0) * ip.z - 1.0;
p.w = 1.5 - dot(abs(p.xyz), ones.xyz);
// GLSL: lessThan(x, y) = x < y
// HLSL: 1 - step(y, x) = x < y
//s = float4(
// 1 - step(0.0, p)
//);
//p.xyz = p.xyz + (s.xyz * 2 - 1) * s.www;
p.xyz -= sign(p.xyz) * (p.w < 0);
return p;
}
// ----------------------------------- 2D -------------------------------------
float snoise(float2 v)
{
const float4 C = float4(
0.211324865405187, // (3.0-sqrt(3.0))/6.0
0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
-0.577350269189626, // -1.0 + 2.0 * C.x
0.024390243902439 // 1.0 / 41.0
);
// First corner
float2 i = floor(v + dot(v, C.yy));
float2 x0 = v - i + dot(i, C.xx);
// Other corners
// float2 i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0);
// Lex-DRL: afaik, step() in GPU is faster than if(), so:
// step(x, y) = x <= y
//int xLessEqual = step(x0.x, x0.y); // x <= y ?
//int2 i1 =
// int2(1, 0) * (1 - xLessEqual) // x > y
// + int2(0, 1) * xLessEqual // x <= y
//;
//float4 x12 = x0.xyxy + C.xxzz;
//x12.xy -= i1;
float4 x12 = x0.xyxy + C.xxzz;
int2 i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0);
x12.xy -= i1;
// Permutations
i = fmod(i, 289.0); // Avoid truncation effects in permutation
float3 p = permute(
permute(
i.y + float3(0.0, i1.y, 1.0)
) + i.x + float3(0.0, i1.x, 1.0)
);
float3 m = max(
0.5 - float3(
dot(x0, x0),
dot(x12.xy, x12.xy),
dot(x12.zw, x12.zw)
),
0.0
);
m = m*m;
m = m*m;
// Gradients: 41 points uniformly over a line, mapped onto a diamond.
// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
float3 x = 2.0 * frac(p * C.www) - 1.0;
float3 h = abs(x) - 0.5;
float3 ox = floor(x + 0.5);
float3 a0 = x - ox;
// Normalise gradients implicitly by scaling m
// Approximation of: m *= inversesqrt( a0*a0 + h*h );
m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);
// Compute final noise value at P
float3 g;
g.x = a0.x * x0.x + h.x * x0.y;
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
return 130.0 * dot(m, g);
}
// ----------------------------------- 3D -------------------------------------
float snoise(float3 v)
{
const float2 C = float2(
0.166666666666666667, // 1/6
0.333333333333333333 // 1/3
);
const float4 D = float4(0.0, 0.5, 1.0, 2.0);
// First corner
float3 i = floor(v + dot(v, C.yyy));
float3 x0 = v - i + dot(i, C.xxx);
// Other corners
float3 g = step(x0.yzx, x0.xyz);
float3 l = 1 - g;
float3 i1 = min(g.xyz, l.zxy);
float3 i2 = max(g.xyz, l.zxy);
float3 x1 = x0 - i1 + C.xxx;
float3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
float3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
// Permutations
i = fmod(i, 289.0);
float4 p = permute(
permute(
permute(
i.z + float4(0.0, i1.z, i2.z, 1.0)
) + i.y + float4(0.0, i1.y, i2.y, 1.0)
) + i.x + float4(0.0, i1.x, i2.x, 1.0)
);
// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
float n_ = 0.142857142857; // 1/7
float3 ns = n_ * D.wyz - D.xzx;
float4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
float4 x_ = floor(j * ns.z);
float4 y_ = floor(j - 7.0 * x_); // mod(j,N)
float4 x = x_ *ns.x + ns.yyyy;
float4 y = y_ *ns.x + ns.yyyy;
float4 h = 1.0 - abs(x) - abs(y);
float4 b0 = float4(x.xy, y.xy);
float4 b1 = float4(x.zw, y.zw);
//float4 s0 = float4(lessThan(b0,0.0))*2.0 - 1.0;
//float4 s1 = float4(lessThan(b1,0.0))*2.0 - 1.0;
float4 s0 = floor(b0)*2.0 + 1.0;
float4 s1 = floor(b1)*2.0 + 1.0;
float4 sh = -step(h, 0.0);
float4 a0 = b0.xzyw + s0.xzyw*sh.xxyy;
float4 a1 = b1.xzyw + s1.xzyw*sh.zzww;
float3 p0 = float3(a0.xy, h.x);
float3 p1 = float3(a0.zw, h.y);
float3 p2 = float3(a1.xy, h.z);
float3 p3 = float3(a1.zw, h.w);
//Normalise gradients
float4 norm = taylorInvSqrt(float4(
dot(p0, p0),
dot(p1, p1),
dot(p2, p2),
dot(p3, p3)
));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
float4 m = max(
0.6 - float4(
dot(x0, x0),
dot(x1, x1),
dot(x2, x2),
dot(x3, x3)
),
0.0
);
m = m * m;
return 42.0 * dot(
m*m,
float4(
dot(p0, x0),
dot(p1, x1),
dot(p2, x2),
dot(p3, x3)
)
);
}
// ----------------------------------- 4D -------------------------------------
float snoise(float4 v)
{
const float4 C = float4(
0.138196601125011, // (5 - sqrt(5))/20 G4
0.276393202250021, // 2 * G4
0.414589803375032, // 3 * G4
-0.447213595499958 // -1 + 4 * G4
);
// First corner
float4 i = floor(
v +
dot(
v,
0.309016994374947451 // (sqrt(5) - 1) / 4
)
);
float4 x0 = v - i + dot(i, C.xxxx);
// Other corners
// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
float4 i0;
float3 isX = step(x0.yzw, x0.xxx);
float3 isYZ = step(x0.zww, x0.yyz);
i0.x = isX.x + isX.y + isX.z;
i0.yzw = 1.0 - isX;
i0.y += isYZ.x + isYZ.y;
i0.zw += 1.0 - isYZ.xy;
i0.z += isYZ.z;
i0.w += 1.0 - isYZ.z;
// i0 now contains the unique values 0,1,2,3 in each channel
float4 i3 = saturate(i0);
float4 i2 = saturate(i0 - 1.0);
float4 i1 = saturate(i0 - 2.0);
// x0 = x0 - 0.0 + 0.0 * C.xxxx
// x1 = x0 - i1 + 1.0 * C.xxxx
// x2 = x0 - i2 + 2.0 * C.xxxx
// x3 = x0 - i3 + 3.0 * C.xxxx
// x4 = x0 - 1.0 + 4.0 * C.xxxx
float4 x1 = x0 - i1 + C.xxxx;
float4 x2 = x0 - i2 + C.yyyy;
float4 x3 = x0 - i3 + C.zzzz;
float4 x4 = x0 + C.wwww;
// Permutations
i = fmod(i, 289.0);
float j0 = permute(
permute(
permute(
permute(i.w) + i.z
) + i.y
) + i.x
);
float4 j1 = permute(
permute(
permute(
permute(
i.w + float4(i1.w, i2.w, i3.w, 1.0)
) + i.z + float4(i1.z, i2.z, i3.z, 1.0)
) + i.y + float4(i1.y, i2.y, i3.y, 1.0)
) + i.x + float4(i1.x, i2.x, i3.x, 1.0)
);
// Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
// 7*7*6 = 294, which is close to the ring size 17*17 = 289.
const float4 ip = float4(
0.003401360544217687075, // 1/294
0.020408163265306122449, // 1/49
0.142857142857142857143, // 1/7
0.0
);
float4 p0 = grad4(j0, ip);
float4 p1 = grad4(j1.x, ip);
float4 p2 = grad4(j1.y, ip);
float4 p3 = grad4(j1.z, ip);
float4 p4 = grad4(j1.w, ip);
// Normalise gradients
float4 norm = taylorInvSqrt(float4(
dot(p0, p0),
dot(p1, p1),
dot(p2, p2),
dot(p3, p3)
));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
p4 *= taylorInvSqrt(dot(p4, p4));
// Mix contributions from the five corners
float3 m0 = max(
0.6 - float3(
dot(x0, x0),
dot(x1, x1),
dot(x2, x2)
),
0.0
);
float2 m1 = max(
0.6 - float2(
dot(x3, x3),
dot(x4, x4)
),
0.0
);
m0 = m0 * m0;
m1 = m1 * m1;
return 49.0 * (
dot(
m0*m0,
float3(
dot(p0, x0),
dot(p1, x1),
dot(p2, x2)
)
) + dot(
m1*m1,
float2(
dot(p3, x3),
dot(p4, x4)
)
)
);
}
// Credits from source glsl file:
//
// Description : Array and textureless GLSL 2D/3D/4D simplex
// noise functions.
// Author : Ian McEwan, Ashima Arts.
// Maintainer : ijm
// Lastmod : 20110822 (ijm)
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the MIT License. See LICENSE file.
// https://github.com/ashima/webgl-noise
//
//
// The text from LICENSE file:
//
//
// Copyright (C) 2011 by Ashima Arts (Simplex noise)
// Copyright (C) 2011 by Stefan Gustavson (Classic noise)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#endif
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE/noiseSimplex.cginc.meta
================================================
fileFormatVersion: 2
guid: 9ce3cf11b8f74594bb7b1e1dba03122d
timeCreated: 1470912310
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EVE.meta
================================================
fileFormatVersion: 2
guid: 47d9eecc3df4a854eaabab84609abb27
folderAsset: yes
timeCreated: 1460382633
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EclipseCommon.cginc
================================================
uniform float4 sunPosAndRadius; //xyz sun pos w radius
uniform float4x4 lightOccluders1; //array of light occluders
uniform float4x4 lightOccluders2; //for each float4 xyz pos w radius
//Source: wikibooks.org/wiki/GLSL_Programming/Unity/Soft_Shadows_of_Spheres
//I believe space engine also uses the same approach because the eclipses look the same ;)
float getEclipseShadow(float3 worldPos, float3 worldLightPos,float3 occluderSpherePosition,
float3 occluderSphereRadius, float3 lightSourceRadius)
{
float3 lightDirection = float3(worldLightPos - worldPos);
float3 lightDistance = length(lightDirection);
lightDirection = lightDirection / lightDistance;
// computation of level of shadowing w
float3 sphereDirection = float3(occluderSpherePosition - worldPos); //occluder planet
float sphereDistance = length(sphereDirection);
sphereDirection = sphereDirection / sphereDistance;
float dd = lightDistance * (asin(min(1.0, length(cross(lightDirection, sphereDirection))))
- asin(min(1.0, occluderSphereRadius / sphereDistance)));
float w = smoothstep(-1.0, 1.0, -dd / lightSourceRadius);
w = w * smoothstep(0.0, 0.2, dot(lightDirection, sphereDirection));
return (1-w);
}
inline float getEclipseShadows(float3 worldPos, float4x4 lightOccludersmatrix)
{
float eclipseShadow = 1.0;
for (int i=0; i<4; ++i)
{
UNITY_BRANCH
if (lightOccludersmatrix[i].w > 0)
{
eclipseShadow*= getEclipseShadow(worldPos, sunPosAndRadius.xyz,lightOccludersmatrix[i].xyz,lightOccludersmatrix[i].w, sunPosAndRadius.w);
}
else
{
break;
}
}
return eclipseShadow;
}
inline float getEclipseShadows(float3 worldPos)
{
return (getEclipseShadows(worldPos, lightOccluders1) * getEclipseShadows(worldPos, lightOccluders2));
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/EclipseCommon.cginc.meta
================================================
fileFormatVersion: 2
guid: 97f2c862ef7ea1d4fa3423506b5cf0ff
timeCreated: 1552766346
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/IntersectCommon.cginc
================================================
#pragma once
float3 LinePlaneIntersection(float3 linePoint, float3 lineVec, float3 planeNormal, float3 planePoint, out float parallel)
{
float tlength;
float dotNumerator;
float dotDenominator;
float3 intersectVector;
float3 intersection = 0.0;
//calculate the distance between the linePoint and the line-plane intersection point
dotNumerator = dot((planePoint - linePoint), planeNormal);
dotDenominator = dot(lineVec, planeNormal);
//line and plane are not parallel
if(dotDenominator != 0.0f)
{
tlength = dotNumerator / dotDenominator;
intersection= (tlength > 0.0) ? linePoint + normalize(lineVec) * (tlength) : linePoint;
parallel = 0.0;
}
else
{
parallel = 1.0;
}
return intersection;
}
//works from outside only
//p1 starting point, d look direction, p3 is the sphere center
float intersectSphereOutside(float3 p1, float3 d, float3 p3, float r) {
float a = dot(d, d);
float b = 2.0 * dot(d, p1 - p3);
float c = dot(p3, p3) + dot(p1, p1) - 2.0 * dot(p3, p1) - r * r;
float test = b * b - 4.0 * a * c;
float u = (test < 0) ? -1.0 : (-b - sqrt(test)) / (2.0 * a);
return u;
}
//works from inside and outside
//p1 starting point, d look direction, p3 is the sphere center
float intersectSphereInside(float3 p1, float3 d, float3 p3, float r)
{
float a = dot(d, d);
float b = 2.0 * dot(d, p1 - p3);
float c = dot(p3, p3) + dot(p1, p1) - 2.0 * dot(p3, p1) - r*r;
float test = b*b - 4.0*a*c;
if (test<0)
{
return -1.0;
}
float u = (-b - sqrt(test)) / (2.0 * a);
u = (u < 0) ? (-b + sqrt(test)) / (2.0 * a) : u;
return u;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/IntersectCommon.cginc.meta
================================================
fileFormatVersion: 2
guid: b4c60b58ddb35c749ad94bd8b5b83168
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Misc.meta
================================================
fileFormatVersion: 2
guid: 24f430bcb0b5b8046adfc8065bffc5c9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/0042-underwater-beach-sand-texture-seamless.jpg.meta
================================================
fileFormatVersion: 2
guid: a9126848c43c4dd499da39a90664dd73
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 10
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsFinal.png.meta
================================================
fileFormatVersion: 2
guid: 3c731404613599947b4b4559797a5168
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 10
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsGodrays.mat.meta
================================================
fileFormatVersion: 2
guid: 89e0061781af2da4d938cac6c7381fdc
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsGodraysRaymarch.shader
================================================
Shader "Scatterer/CausticsGodraysRaymarch"
{
Properties
{
_CausticsTexture ("_CausticsTexture", 2D) = "" {}
layer1Scale ("Layer 1 scale", Vector) = (1.0101,1.0101,0)
layer1Speed ("Layer 1 speed", Vector) = (0.05123,0.05123,0)
layer2Scale ("Layer 2 scale", Vector) = (1.235487,1.235487,0)
layer2Speed ("Layer 2 speed", Vector) = (0.074872,0.074872,0)
}
SubShader
{
Pass
{
ZTest On
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#pragma multi_compile SPHERE_PLANET FLAT_PLANET
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
#include "../OceanShadows.cginc"
#include "../../CommonAtmosphere.cginc"
float4x4 CameraToWorld;
float4x4 WorldToLight;
float3 LightDir;
float3 PlanetOrigin;
float oceanRadius;
float transparencyDepth;
float lightRaysStrength;
sampler2D _CausticsTexture;
float2 layer1Scale;
float2 layer1Speed;
float2 layer2Scale;
float2 layer2Speed;
float causticsBlurDepth;
float warpTime;
sampler2D ScattererDownscaledDepth;
float4 ScattererDownscaledDepth_TexelSize;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 screenPos : TEXCOORD1;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = ComputeNonStereoScreenPos(o.pos);
o.screenPos = ComputeScreenPos(o.pos);
return o;
}
sampler2D _MainTex;
float4 frag (v2f IN) : SV_Target
{
// blur caustics the farther we are from surface
float blurFactor = 0.0;
float time = _Time.y;
time = (warpTime == 0.0) ? time : warpTime;
float totalCaustics = 0;
float currentDistance = 0;
float3 worldPosition = _WorldSpaceCameraPos;
float2 uv = IN.screenPos.xy/IN.screenPos.w;
float zdepth = tex2Dlod(ScattererDownscaledDepth, float4(uv,0.0,0.0));
#ifdef SHADER_API_D3D11 //#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
float4 clipPos = float4(uv, zdepth, 1.0);
clipPos.xyz = 2.0f * clipPos.xyz - 1.0f;
float4 camPos = mul(unity_CameraInvProjection, clipPos);
float4 fragWorldPos = mul(CameraToWorld,camPos);
fragWorldPos/=fragWorldPos.w;
float3 viewDir = normalize(fragWorldPos.xyz - worldPosition);
float maxDistance = intersectSphereInside (worldPosition, viewDir, PlanetOrigin, oceanRadius);
maxDistance = min(maxDistance, length(camPos.xyz / camPos.w));
maxDistance = min(maxDistance, transparencyDepth * 2.0);
float dotLight = dot(viewDir,-LightDir);
dotLight=pow(abs(dotLight),40) * sign(dotLight);
float boostFactor = (dotLight<0.0) ? -0.0085 : 0.005 ;
float GRID_SIZE = 8;
float GRID_SIZE_SQR_RCP = (1.0/(GRID_SIZE*GRID_SIZE));
float stepSize = 0.2; //maybe change this to 0.007?
// Calculate the offsets on the ray according to the interleaved sampling pattern
float2 interleavedPos = fmod( float2(IN.pos.x, ScattererDownscaledDepth_TexelSize.w - IN.pos.y), GRID_SIZE );
float rayStartOffset = ( interleavedPos.y * GRID_SIZE + interleavedPos.x ) * ( stepSize * GRID_SIZE_SQR_RCP ) ;
worldPosition+=(0.1+rayStartOffset)*viewDir;
float fadeOut = 1.0;
#ifdef SPHERE_PLANET
float underwaterDepth = max(oceanRadius - length(worldPosition - PlanetOrigin), 0.0);
blurFactor = lerp(0.0,5.0,underwaterDepth/causticsBlurDepth);
fadeOut = smoothstep(0.0,0.4,1.0-(underwaterDepth/causticsBlurDepth)); //fade them out starting from last 40% of causticsBlurDepth
#else
blurFactor = lerp(0.0,5.0,worldPosition.y/30.0);
#endif
float2 layer1Offset = layer1Speed * float2(time,time);
float2 layer2Offset = layer2Speed * float2(time,time);
for (int i=0;i<150;i++)
{
float2 uvCookie = mul(WorldToLight, float4(worldPosition, 1)).xy;
float2 uvSample1 = layer1Scale * uvCookie + layer1Offset;
float2 uvSample2 = layer2Scale * uvCookie + layer2Offset;
float causticsSample1 = tex2Dlod(_CausticsTexture,float4(uvSample1,0.0,blurFactor)).r;
float causticsSample2 = tex2Dlod(_CausticsTexture,float4(uvSample2,0.0,blurFactor)).r;
float caustics = 0.01*lightRaysStrength*min(causticsSample1,causticsSample2);
float4 clipPos = mul(UNITY_MATRIX_VP,float4(worldPosition,1.0));
float4 screenPos = ComputeScreenPos(clipPos);
float shadowTerm = getOceanHardShadow(float4(worldPosition,1.0),-screenPos.z);
totalCaustics+=(1.0-totalCaustics)*caustics*shadowTerm;
float increment = 0.2 + boostFactor*i*dotLight; //variable step size, boost when looking towards light source or direction to make it look like it's properly coming from infinity
currentDistance+=increment;
worldPosition+=viewDir*increment;
//
if (currentDistance > maxDistance)
{
break;
}
}
totalCaustics*=fadeOut;
return float4(totalCaustics,totalCaustics,totalCaustics,1.0);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsGodraysRaymarch.shader.meta
================================================
fileFormatVersion: 2
guid: 44df73535c7a760458518e95391dbfdc
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsOcclusion.shader
================================================
// Upgrade NOTE: replaced '_LightMatrix0' with 'unity_WorldToLight'
Shader "Scatterer/CausticsOcclusion"
{
Properties
{
_CausticsTexture ("_CausticsTexture", 2D) = "" {}
layer1Scale ("Layer 1 scale", Vector) = (1.0101,1.0101,0)
layer1Speed ("Layer 1 speed", Vector) = (0.05123,0.05123,0)
layer2Scale ("Layer 2 scale", Vector) = (1.235487,1.235487,0)
layer2Speed ("Layer 2 speed", Vector) = (0.074872,0.074872,0)
causticsMultiply ("causticsMultiply", Float) = 1
causticsMinBrightness ("causticsMinBrightness", Float) = 0.1
}
SubShader
{
Pass
{
Cull Back ZWrite Off ZTest Off
BlendOp Min //take the minimum so existing shadows that are not completely at zero are respected
CGPROGRAM
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "../../DepthCommon.cginc"
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#pragma multi_compile SPHERE_PLANET FLAT_PLANET
float4x4 CameraToWorld;
float4x4 WorldToLight;
float3 PlanetOrigin;
float oceanRadius;
sampler2D _CausticsTexture;
float2 layer1Scale;
float2 layer1Speed;
float2 layer2Scale;
float2 layer2Speed;
float causticsMultiply;
float causticsMinBrightness;
float causticsBlurDepth;
float warpTime;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
OUT.uv = ComputeScreenPos(OUT.pos);
return OUT;
}
fixed4 frag (v2f i) : SV_Target
{
float zdepth = tex2Dlod(_CameraDepthTexture, float4(i.uv,0,0));
#if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12
if (zdepth == 0.0) {discard;}
#else
if (zdepth == 1.0) {discard;}
#endif
float3 worldPos = getPreciseWorldPosFromDepth(i.uv, zdepth, CameraToWorld);
// blur caustics the farther we are from texture
float blurFactor = 0.0;
float time = _Time.y;
#ifdef SPHERE_PLANET
float underwaterDepth = max(oceanRadius - length(worldPos - PlanetOrigin), 0.0);
blurFactor = lerp(0.0,5.0,underwaterDepth/causticsBlurDepth);
time = (warpTime == 0.0) ? time : warpTime;
#else
blurFactor = lerp(0.0,5.0,-worldPos.y/30.0);
#endif
float2 uvCookie = mul(WorldToLight, float4(worldPos.xyz, 1)).xy;
float2 uvSample1 = layer1Scale * uvCookie + layer1Speed * float2(time,time);
float2 uvSample2 = layer2Scale * uvCookie + layer2Speed * float2(time,time);
float causticsSample1 = tex2Dbias(_CausticsTexture,float4(uvSample1,0.0,blurFactor)).r;
float causticsSample2 = tex2Dbias(_CausticsTexture,float4(uvSample2,0.0,blurFactor)).r;
float caustics = causticsMultiply*min(causticsSample1,causticsSample2)+causticsMinBrightness;
#ifdef SPHERE_PLANET
caustics = lerp (1.0, caustics, clamp(underwaterDepth/1.5f, 0.0, 1.0)); //fade caustics in over the first meter and half of depth
#endif
return float4(caustics,caustics,caustics,1.0);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsOcclusion.shader.meta
================================================
fileFormatVersion: 2
guid: 9c9e5198af35eb74d8c5d84a5194b184
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsScene.unity.meta
================================================
fileFormatVersion: 2
guid: a4cac3a64ff3a4540bbabd58e2d7c8b2
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CausticsShadowMask.mat.meta
================================================
fileFormatVersion: 2
guid: 43ad7f10b8cb01a4ca1b57eff53b024c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CompositeCausticsGodrays.shader
================================================
Shader "Scatterer/CompositeCausticsGodrays"
{
Properties{
}
SubShader{
Tags { "Queue"="Transparent+2" "IgnoreProjector"="True" "RenderType"="Transparent"}
Pass {
Blend OneMinusDstColor One //softAdditive
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#include"UnityCG.cginc"
uniform sampler2D LightRaysTexture;
uniform sampler2D _CameraDepthTexture;
float4 _CameraDepthTexture_TexelSize;
uniform sampler2D ScattererDownscaledDepth;
float4 ScattererDownscaledDepth_TexelSize;
uniform float3 _sunColor; //already calculated sun extinction or color
uniform float3 _Underwater_Color;
struct appdata_t {
float4 vertex : POSITION;
float2 uv: TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_t v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
float4 frag(v2f i) : COLOR
{
float color = tex2D(LightRaysTexture, i.uv).r;
return float4(_Underwater_Color * _sunColor * color,1.0);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/CompositeCausticsGodrays.shader.meta
================================================
fileFormatVersion: 2
guid: c91c0b6ea03975b419e4cb285a69a10d
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/ModulateShadowMask.cs
================================================
using UnityEngine;
using UnityEngine.Rendering;
using System.Collections.Generic;
using System;
public class ModulateShadowMask : MonoBehaviour
{
private CommandBuffer m_Buffer;
private Light m_Light;
private Camera fakeCamera;
[SerializeField]
private Material m_ShadowMaskModulateMaterial;
public ModulateShadowMask ()
{
}
public void Awake()
{
m_ShadowMaskModulateMaterial.DisableKeyword ("SPHERE_PLANET");
m_ShadowMaskModulateMaterial.EnableKeyword ("FLAT_PLANET");
m_Buffer = new CommandBuffer();
m_Buffer.name = "ScreenspaceShadowMaskmodulate";
m_Buffer.Blit (null, BuiltinRenderTextureType.CurrentActive, m_ShadowMaskModulateMaterial);
m_Light = GetComponent();
m_Light.AddCommandBuffer (LightEvent.AfterScreenspaceMask, m_Buffer);
}
public void Update()
{
m_ShadowMaskModulateMaterial.SetMatrix ("CameraToWorld", Camera.main.cameraToWorldMatrix);
m_ShadowMaskModulateMaterial.SetMatrix ("WorldToLight", m_Light.gameObject.transform.worldToLocalMatrix); //may look like it doesn't work in the editor, ie using the editor Camera
}
public void OnDestroy ()
{
m_Light.RemoveCommandBuffer (LightEvent.AfterScreenspaceMask, m_Buffer);
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/ModulateShadowMask.cs.meta
================================================
fileFormatVersion: 2
guid: eb1eda9941f181549a0b626e36a4dd26
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/SeaFloor.mat.meta
================================================
fileFormatVersion: 2
guid: 8cc83bff6b39f3d44af0de8320999144
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics/WhiteTexture.png.meta
================================================
fileFormatVersion: 2
guid: 6b152d671c864bf41bbcc096f5a7567c
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 10
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Caustics.meta
================================================
fileFormatVersion: 2
guid: 94412382cf909c843b9a46a8f6b364f4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/FindHeights.compute
================================================
#pragma kernel CSMain
float4 _Ocean_Choppyness;
float4 _Ocean_GridSizes;
sampler2D _Ocean_Map0;
sampler2D _Ocean_Map3;
sampler2D _Ocean_Map4;
RWStructuredBuffer positions;
RWStructuredBuffer result;
float SampleHeight(float2 oceanPos)
{
float height = 0;
height += tex2Dlod(_Ocean_Map0, float4(oceanPos / _Ocean_GridSizes.x,0.0, 0.0) ).x;
height += tex2Dlod(_Ocean_Map0, float4(oceanPos / _Ocean_GridSizes.y,0.0, 0.0) ).y;
height += tex2Dlod(_Ocean_Map0, float4(oceanPos / _Ocean_GridSizes.z,0.0, 0.0) ).z;
height += tex2Dlod(_Ocean_Map0, float4(oceanPos / _Ocean_GridSizes.w,0.0, 0.0) ).w;
return height;
}
float2 SampleDisplacement(float2 oceanPos)
{
float2 displacement = 0;
displacement += _Ocean_Choppyness.x * tex2Dlod(_Ocean_Map3, float4(oceanPos / _Ocean_GridSizes.x,0.0, 0.0) ).xy;
displacement += _Ocean_Choppyness.y * tex2Dlod(_Ocean_Map3, float4(oceanPos / _Ocean_GridSizes.y,0.0, 0.0) ).zw;
displacement += _Ocean_Choppyness.z * tex2Dlod(_Ocean_Map4, float4(oceanPos / _Ocean_GridSizes.z,0.0, 0.0) ).xy;
displacement += _Ocean_Choppyness.w * tex2Dlod(_Ocean_Map4, float4(oceanPos / _Ocean_GridSizes.w,0.0, 0.0) ).zw;
return displacement;
}
//Essentially a search method to find which point on the ocean is displaced sideways to end up at our part's position, so we can sample the correct height
//Thanks to Scrawk (Justin Hawkins) for the tip
//Original source: Water technology of uncharted p.126 https://www.gdcvault.com/play/1015309/Water-Technology-of
[numthreads(1,1,1)]
void CSMain (uint id : SV_DispatchThreadID)
{
float precisionRequired = 0.02;
float2 currentPosition = positions[id];
float2 displacement = SampleDisplacement (currentPosition);
float2 resultingPosition = currentPosition + displacement;
for (int i = 0; i < 40; i++)
{
if (length(resultingPosition - positions[id]) <= precisionRequired)
break;
float2 newPosition = currentPosition - (resultingPosition - positions[id]);
float2 newDisplacement = SampleDisplacement (newPosition);
float2 newResultingPosition = newPosition + newDisplacement;
currentPosition = newPosition;
resultingPosition = newResultingPosition;
}
result[id] = SampleHeight(currentPosition);
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/FindHeights.compute.meta
================================================
fileFormatVersion: 2
guid: 45322b284be6baf43a273a61abba527d
ComputeShaderImporter:
externalObjects: {}
currentAPIMask: 4
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Fourier.shader
================================================
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Scatterer/Fourier"
{
CGINCLUDE
#include "UnityCG.cginc"
uniform sampler2D _ReadBuffer0, _ReadBuffer1, _ReadBuffer2;
uniform sampler2D _ButterFlyLookUp;
uniform float _Size;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
struct f2a_1
{
float4 col0 : COLOR0;
};
struct f2a_2
{
float4 col0 : COLOR0;
float4 col1 : COLOR1;
};
struct f2a_3
{
float4 col0 : COLOR0;
float4 col1 : COLOR1;
float4 col2 : COLOR2;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
OUT.uv = v.texcoord;
return OUT;
}
//Performs two FFTs on two complex numbers packed in a vector4
float4 FFT(float2 w, float4 input1, float4 input2)
{
float rx = w.x * input2.x - w.y * input2.y;
float ry = w.y * input2.x + w.x * input2.y;
float rz = w.x * input2.z - w.y * input2.w;
float rw = w.y * input2.z + w.x * input2.w;
return input1 + float4(rx,ry,rz,rw);
}
f2a_1 fragX_1(v2f IN)
{
float4 lookUp = tex2D(_ButterFlyLookUp, float2(IN.uv.x, 0));
lookUp.xyz *= 255.0;
lookUp.xy /= _Size-1.0;
float PI = 3.1415926;
float2 w = float2(cos(2.0*PI*lookUp.z/_Size), sin(2.0*PI*lookUp.z/_Size));
if(lookUp.w > 0.5) w *= -1.0;
f2a_1 OUT;
float2 uv1 = float2(lookUp.x, IN.uv.y);
float2 uv2 = float2(lookUp.y, IN.uv.y);
OUT.col0 = FFT(w, tex2D(_ReadBuffer0, uv1), tex2D(_ReadBuffer0, uv2));
return OUT;
}
f2a_1 fragY_1(v2f IN)
{
float4 lookUp = tex2D(_ButterFlyLookUp, float2(IN.uv.y, 0));
lookUp.xyz *= 255.0;
lookUp.xy /= _Size-1.0;
float PI = 3.1415926;
float2 w = float2(cos(2.0*PI*lookUp.z/_Size), sin(2.0*PI*lookUp.z/_Size));
if(lookUp.w > 0.5) w *= -1.0;
f2a_1 OUT;
float2 uv1 = float2(IN.uv.x, lookUp.x);
float2 uv2 = float2(IN.uv.x, lookUp.y);
OUT.col0 = FFT(w, tex2D(_ReadBuffer0, uv1), tex2D(_ReadBuffer0, uv2));
return OUT;
}
f2a_2 fragX_2(v2f IN)
{
float4 lookUp = tex2D(_ButterFlyLookUp, float2(IN.uv.x, 0));
lookUp.xyz *= 255.0;
lookUp.xy /= _Size-1.0;
float PI = 3.1415926;
float2 w = float2(cos(2.0*PI*lookUp.z/_Size), sin(2.0*PI*lookUp.z/_Size));
if(lookUp.w > 0.5) w *= -1.0;
f2a_2 OUT;
float2 uv1 = float2(lookUp.x, IN.uv.y);
float2 uv2 = float2(lookUp.y, IN.uv.y);
OUT.col0 = FFT(w, tex2D(_ReadBuffer0, uv1), tex2D(_ReadBuffer0, uv2));
OUT.col1 = FFT(w, tex2D(_ReadBuffer1, uv1), tex2D(_ReadBuffer1, uv2));
return OUT;
}
f2a_2 fragY_2(v2f IN)
{
float4 lookUp = tex2D(_ButterFlyLookUp, float2(IN.uv.y, 0));
lookUp.xyz *= 255.0;
lookUp.xy /= _Size-1.0;
float PI = 3.1415926;
float2 w = float2(cos(2.0*PI*lookUp.z/_Size), sin(2.0*PI*lookUp.z/_Size));
if(lookUp.w > 0.5) w *= -1.0;
f2a_2 OUT;
float2 uv1 = float2(IN.uv.x, lookUp.x);
float2 uv2 = float2(IN.uv.x, lookUp.y);
OUT.col0 = FFT(w, tex2D(_ReadBuffer0, uv1), tex2D(_ReadBuffer0, uv2));
OUT.col1 = FFT(w, tex2D(_ReadBuffer1, uv1), tex2D(_ReadBuffer1, uv2));
return OUT;
}
f2a_3 fragX_3(v2f IN)
{
float4 lookUp = tex2D(_ButterFlyLookUp, float2(IN.uv.x, 0));
lookUp.xyz *= 255.0;
lookUp.xy /= _Size-1.0;
float PI = 3.1415926;
float2 w = float2(cos(2.0*PI*lookUp.z/_Size), sin(2.0*PI*lookUp.z/_Size));
if(lookUp.w > 0.5) w *= -1.0;
f2a_3 OUT;
float2 uv1 = float2(lookUp.x, IN.uv.y);
float2 uv2 = float2(lookUp.y, IN.uv.y);
OUT.col0 = FFT(w, tex2D(_ReadBuffer0, uv1), tex2D(_ReadBuffer0, uv2));
OUT.col1 = FFT(w, tex2D(_ReadBuffer1, uv1), tex2D(_ReadBuffer1, uv2));
OUT.col2 = FFT(w, tex2D(_ReadBuffer2, uv1), tex2D(_ReadBuffer2, uv2));
return OUT;
}
f2a_3 fragY_3(v2f IN)
{
float4 lookUp = tex2D(_ButterFlyLookUp, float2(IN.uv.y, 0));
lookUp.xyz *= 255.0;
lookUp.xy /= _Size-1.0;
float PI = 3.1415926;
float2 w = float2(cos(2.0*PI*lookUp.z/_Size), sin(2.0*PI*lookUp.z/_Size));
if(lookUp.w > 0.5) w *= -1.0;
f2a_3 OUT;
float2 uv1 = float2(IN.uv.x, lookUp.x);
float2 uv2 = float2(IN.uv.x, lookUp.y);
OUT.col0 = FFT(w, tex2D(_ReadBuffer0, uv1), tex2D(_ReadBuffer0, uv2));
OUT.col1 = FFT(w, tex2D(_ReadBuffer1, uv1), tex2D(_ReadBuffer1, uv2));
OUT.col2 = FFT(w, tex2D(_ReadBuffer2, uv1), tex2D(_ReadBuffer2, uv2));
return OUT;
}
ENDCG
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragX_1
ENDCG
}
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragY_1
ENDCG
}
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragX_2
ENDCG
}
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragY_2
ENDCG
}
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragX_3
ENDCG
}
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment fragY_3
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/Fourier.shader.meta
================================================
fileFormatVersion: 2
guid: 6a44d0f20e3f6cd45881a44134574169
timeCreated: 1459689856
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InitDisplacement.shader
================================================
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Proland/Ocean/InitDisplacement"
{
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#include "UnityCG.cginc"
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _Buffer1;
uniform sampler2D _Buffer2;
uniform float4 _InverseGridSizes;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
struct f2a
{
float4 col0 : COLOR0;
float4 col1 : COLOR1;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
OUT.uv = v.texcoord;
return OUT;
}
f2a frag(v2f IN)
{
float2 uv = IN.uv.xy;
float2 st;
st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x;
st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y;
float2 k1 = st * _InverseGridSizes.x;
float2 k2 = st * _InverseGridSizes.y;
float2 k3 = st * _InverseGridSizes.z;
float2 k4 = st * _InverseGridSizes.w;
float K1 = length(k1);
float K2 = length(k2);
float K3 = length(k3);
float K4 = length(k4);
float IK1 = K1 == 0.0 ? 0.0 : 1.0 / K1;
float IK2 = K2 == 0.0 ? 0.0 : 1.0 / K2;
float IK3 = K3 == 0.0 ? 0.0 : 1.0 / K3;
float IK4 = K4 == 0.0 ? 0.0 : 1.0 / K4;
f2a OUT;
OUT.col0 = tex2D(_Buffer1, IN.uv) * float4(IK1, IK1, IK2, IK2);
OUT.col1 = tex2D(_Buffer2, IN.uv) * float4(IK3, IK3, IK4, IK4);
return OUT;
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InitDisplacement.shader.meta
================================================
fileFormatVersion: 2
guid: 4f809c227a3cfde4bbb9482dc1814105
timeCreated: 1459689457
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InitJacobians.shader
================================================
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Proland/Ocean/InitJacobians"
{
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#include "UnityCG.cginc"
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _Spectrum01;
uniform sampler2D _Spectrum23;
uniform sampler2D _WTable;
uniform float4 _Offset;
uniform float4 _InverseGridSizes;
uniform float _T;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
struct f2a
{
float4 col0 : COLOR0;
float4 col1 : COLOR1;
float4 col2 : COLOR2;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
OUT.uv = v.texcoord;
return OUT;
}
float2 GetSpectrum(float w, float2 s0, float2 s0c)
{
float c = cos(w*_T);
float s = sin(w*_T);
return float2((s0.x + s0c.x) * c - (s0.y + s0c.y) * s, (s0.x - s0c.x) * s + (s0.y - s0c.y) * c);
}
float2 COMPLEX(float2 z)
{
return float2(-z.y, z.x); // returns i times z (complex number)
}
f2a frag(v2f IN)
{
float2 uv = IN.uv.xy;
float2 st;
st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x;
st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y;
float4 s12 = tex2D(_Spectrum01, uv);
float4 s12c = tex2D(_Spectrum01, _Offset.xy-uv);
float4 s34 = tex2D(_Spectrum23, uv);
float4 s34c = tex2D(_Spectrum23, _Offset.xy-uv);
float2 k1 = st * _InverseGridSizes.x;
float2 k2 = st * _InverseGridSizes.y;
float2 k3 = st * _InverseGridSizes.z;
float2 k4 = st * _InverseGridSizes.w;
float K1 = length(k1);
float K2 = length(k2);
float K3 = length(k3);
float K4 = length(k4);
float IK1 = K1 == 0.0 ? 0.0 : 1.0 / K1;
float IK2 = K2 == 0.0 ? 0.0 : 1.0 / K2;
float IK3 = K3 == 0.0 ? 0.0 : 1.0 / K3;
float IK4 = K4 == 0.0 ? 0.0 : 1.0 / K4;
float4 w = tex2D(_WTable, uv);
float2 h1 = GetSpectrum(w.x, s12.xy, s12c.xy);
float2 h2 = GetSpectrum(w.y, s12.zw, s12c.zw);
float2 h3 = GetSpectrum(w.z, s34.xy, s34c.xy);
float2 h4 = GetSpectrum(w.w, s34.zw, s34c.zw);
/// Jacobians
float4 IK = float4(IK1,IK2,IK3,IK4);
float2 k1Squared = k1*k1;
float2 k2Squared = k2*k2;
float2 k3Squared = k3*k3;
float2 k4Squared = k4*k4;
// 5: d(Dx(X,t))/dx Tes01 eq30
// 6: d(Dy(X,t))/dy Tes01 eq30
// 7: d(Dx(X,t))/dy Tes01 eq30
float4 tmp = float4(h1.x, h2.x, h3.x, h4.x);
f2a OUT;
OUT.col0 = -tmp * (float4(k1Squared.x, k2Squared.x, k3Squared.x, k4Squared.x) * IK);
OUT.col1 = -tmp * (float4(k1Squared.y, k2Squared.y, k3Squared.y, k4Squared.y) * IK);
OUT.col2 = -tmp * (float4(k1.x*k1.y, k2.x*k2.y, k3.x*k3.y, k4.x*k4.y) * IK);
return OUT;
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InitJacobians.shader.meta
================================================
fileFormatVersion: 2
guid: f8f889eee05c15349bc81eeb0883357d
timeCreated: 1459689457
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InitSpectrum.shader
================================================
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Proland/Ocean/InitSpectrum"
{
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#include "UnityCG.cginc"
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _Spectrum01;
uniform sampler2D _Spectrum23;
uniform sampler2D _WTable;
uniform float4 _Offset;
uniform float4 _InverseGridSizes;
uniform float _T;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
struct f2a
{
float4 col0 : COLOR0;
float4 col1 : COLOR1;
float4 col2 : COLOR2;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
OUT.uv = v.texcoord;
return OUT;
}
float2 GetSpectrum(float w, float2 s0, float2 s0c)
{
float c = cos(w*_T);
float s = sin(w*_T);
return float2((s0.x + s0c.x) * c - (s0.y + s0c.y) * s, (s0.x - s0c.x) * s + (s0.y - s0c.y) * c);
}
float2 COMPLEX(float2 z)
{
return float2(-z.y, z.x); // returns i times z (complex number)
}
f2a frag(v2f IN)
{
float2 uv = IN.uv.xy;
float2 st;
st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x;
st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y;
float4 s12 = tex2D(_Spectrum01, uv);
float4 s12c = tex2D(_Spectrum01, _Offset.xy-uv);
float4 s34 = tex2D(_Spectrum23, uv);
float4 s34c = tex2D(_Spectrum23, _Offset.xy-uv);
float2 k1 = st * _InverseGridSizes.x;
float2 k2 = st * _InverseGridSizes.y;
float2 k3 = st * _InverseGridSizes.z;
float2 k4 = st * _InverseGridSizes.w;
float4 w = tex2D(_WTable, uv);
float2 h1 = GetSpectrum(w.x, s12.xy, s12c.xy);
float2 h2 = GetSpectrum(w.y, s12.zw, s12c.zw);
float2 h3 = GetSpectrum(w.z, s34.xy, s34c.xy);
float2 h4 = GetSpectrum(w.w, s34.zw, s34c.zw);
float2 h12 = h1 + COMPLEX(h2);
float2 h34 = h3 + COMPLEX(h4);
float2 n1 = COMPLEX(k1.x * h1) - k1.y * h1;
float2 n2 = COMPLEX(k2.x * h2) - k2.y * h2;
float2 n3 = COMPLEX(k3.x * h3) - k3.y * h3;
float2 n4 = COMPLEX(k4.x * h4) - k4.y * h4;
f2a OUT;
OUT.col0 = float4(h12, h34);
OUT.col1 = float4(n1, n2);
OUT.col2 = float4(n3, n4);
return OUT;
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InitSpectrum.shader.meta
================================================
fileFormatVersion: 2
guid: 212a65848ed53294788b2731538c9d66
timeCreated: 1459689457
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InvisibleOcean.shader
================================================
Shader "Scatterer/invisible"
{
SubShader
{
Tags {"Queue" = "Transparent" "IgnoreProjector"="True" "RenderType"="InvOcean"}
Pass
{
ZWrite Off
ZTest on
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#include "UnityCG.cginc"
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#pragma glsl
struct v2f
{
float4 pos : SV_POSITION;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = float4(2.0, 2.0, 2.0, 1.0); //outside clip space => cull vertex
return OUT;
}
float4 frag(v2f IN) : COLOR
{
return float4(0.0,0.0,0.0,0.0);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/InvisibleOcean.shader.meta
================================================
fileFormatVersion: 2
guid: f32e959de7955be41a4af6dac2f75b09
timeCreated: 1499371576
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanBRDF.cginc
================================================
/*
* Proland: a procedural landscape rendering library.
* Copyright (c) 2008-2011 INRIA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* Proland is distributed under a dual-license scheme.
* You can obtain a specific license from Inria: proland-licensing@inria.fr.
*/
/*
* Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat.
* Modified and ported to Unity by Justin Hawkins 2014
*/
#if !defined (M_PI)
#define M_PI 3.141592657
#endif
float MeanFresnel(float cosThetaV, float sigmaV) {
return pow(1.0 - cosThetaV, 5.0 * exp(-2.69 * sigmaV)) / (1.0 + 22.7 * pow(sigmaV, 1.5));
}
float MeanFresnel(float3 V, float3 N, float sigmaSq) {
return MeanFresnel(dot(V, N), sqrt(sigmaSq));
}
// L, V, N in world space
float ReflectedSunRadiance(float3 L, float3 V, float3 N, float sigmaSq)
{
float3 H = normalize(L + V);
float hn = dot(H, N);
float p = exp(-2.0 * ((1.0 - hn * hn) / sigmaSq) / (1.0 + hn)) / (4.0 * M_PI * sigmaSq);
float c = 1.0 - dot(V, H);
float c2 = c * c;
float fresnel = 0.02 + 0.98 * c2 * c2 * c;
float zL = dot(L, N);
float zV = dot(V, N);
zL = max(zL,0.01);
zV = max(zV,0.01);
// brdf times cos(thetaL)
return zL <= 0.0 ? 0.0 : max(fresnel * p * sqrt(abs(zL / zV)), 0.0);
}
float2 U(float2 zeta, float3 V)
{
float3 F = normalize(float3(-zeta, 1.0));
float3 R = 2.0 * dot(F, V) * F - V;
return -R.xy / (1.0 + R.z);
}
// V, N, sunDir in world space
float3 ReflectedSkyRadiance(sampler2D skymap, float3 V, float3 N, float sigmaSq, float3 sunDir)
{
float3 result = float3(0,0,0);
float2 zeta0 = -N.xy / N.z;
float2 tau0 = U(zeta0, V);
const float n = 1.0 / 1.1;
float2 JX = (U(zeta0 + float2(0.01, 0.0), V) - tau0) / 0.01 * n * sqrt(sigmaSq);
float2 JY = (U(zeta0 + float2(0.0, 0.01), V) - tau0) / 0.01 * n * sqrt(sigmaSq);
result = tex2D(skymap, (tau0 * 0.5 / 1.1 + 0.5), JX, JY).rgb;
result *= 0.02 + 0.98 * MeanFresnel(V, N, sigmaSq);
return result;
}
float RefractedSeaRadiance(float3 V, float3 N, float sigmaSq) {
return 0.98 * (1.0 - MeanFresnel(V, N, sigmaSq));
}
float erf(float x)
{
float a = 0.140012;
float x2 = x*x;
float ax2 = a*x2;
return sign(x) * sqrt( 1.0 - exp(-x2*(4.0/M_PI + ax2)/(1.0 + ax2)) );
}
float WhitecapCoverage(float epsilon, float mu, float sigma2) {
return 0.5*erf((0.5*sqrt(2.0)*(epsilon-mu)*(1.0/sqrt(sigma2)))) + 0.5;
}
float3 OceanRadiance(float3 L, float3 V, float3 N, float sigmaSq, float3 sunL, float3 skyE, float3 seaColor)
{
float F = MeanFresnel(V, N, sigmaSq);
float3 Lsun = ReflectedSunRadiance(L, V, N, sigmaSq) * sunL;
float3 Lsky = skyE * F / M_PI;
float3 Lsea = (1.0 - F) * seaColor * skyE / M_PI;
return Lsun + Lsky + Lsea;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanBRDF.cginc.meta
================================================
fileFormatVersion: 2
guid: 907dff89ca8c76745b031725757e5f8b
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanDisplacement3.cginc
================================================
/*
* Proland: a procedural landscape rendering library.
* Copyright (c) 2008-2011 INRIA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* Proland is distributed under a dual-license scheme.
* You can obtain a specific license from Inria: proland-licensing@inria.fr.
*/
/*
* Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat.
* Modified and ported to Unity by Justin Hawkins 2014
*/
uniform float _Ocean_Radius;
//uniform float3 _Ocean_Horizon1;
//uniform float3 _Ocean_Horizon2;
uniform float _Ocean_HeightOffset;
uniform float3 _Ocean_CameraPos;
uniform float4x4 _Ocean_OceanToCamera;
uniform float4x4 _Ocean_CameraToOcean;
uniform float3 sphereDir;
uniform float cosTheta;
uniform float sinTheta;
// A glorified sphere intersect, with some code to snap above the horizon back to the horizon
// Returns Position in ocean space
float2 OceanPos(float4 vert, float4x4 stoc, out float t, out float3 cameraDir, out float3 oceanDir)
{
float h = _Ocean_CameraPos.z;
float4 v = float4(vert.x, vert.y, 0.0, 1.0);
cameraDir = normalize(mul(stoc, v).xyz); //Dir in camera space
float3 n1= cross (sphereDir, cameraDir); //Normal to plane containing dir to planet and vertex viewdir
float3 n2= normalize(cross (n1, sphereDir)); //upwards vector in plane space, plane containing CamO and cameraDir
float3 hor=cosTheta*sphereDir+sinTheta*n2;
cameraDir= ( (dot(n1,cross(hor,cameraDir)) >=0) && (h>=0)) ? hor : cameraDir ; //checking if viewdir is above horizon
//This could probably be optimized
oceanDir = mul(_Ocean_CameraToOcean, float4(cameraDir, 0.0)).xyz;
float cz = _Ocean_CameraPos.z;
float dz = oceanDir.z;
float radius = _Ocean_Radius;
float b = dz * (cz + radius);
float c = cz * (cz + 2.0 * radius);
#if !defined (UNDERWATER_ON)
float tSphere = - b - sqrt(max(b * b - c, 0.02));
#else
float tSphere = - b + sqrt(max(b * b - c, 0.02));
#endif
float tApprox = - cz / dz * (1.0 + cz / (2.0 * radius) * (1.0 - dz * dz));
t = abs((tApprox - tSphere) * dz) < 1.0 ? tApprox : tSphere;
return _Ocean_CameraPos.xy + t * oceanDir.xy;
}
float2 OceanPos(float4 vert, float4x4 stoc)
{
float t;
float3 cameraDir;
float3 oceanDir;
return OceanPos(vert, stoc, t, cameraDir, oceanDir);
}
float4 Tex2DGrad(sampler2D tex, float2 uv, float2 dx, float2 dy, float2 texSize)
{
//Sampling a texture by derivatives in unsupported in vert shaders in Unity but if you
//can manually calculate the derivates you can reproduce its effect using tex2Dlod
float2 px = texSize.x * dx;
float2 py = texSize.y * dy;
float lod = 0.5 * log2(max(dot(px, px), dot(py, py)));
return tex2Dlod(tex, float4(uv, 0, lod));
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanDisplacement3.cginc.meta
================================================
fileFormatVersion: 2
guid: 2ac6db96cd5bff048a79be0215503e16
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanLight.cginc
================================================
// Modified Light helpers for the ocean
// unlike in autolight.cginc, object2world can't be used in the case of the ocean
// the projection is instead done via other means
// the world position is passed instead of doing a mul(_Object2World, v.vertex) which gives the wrong result here
#ifdef POINT
//#define LIGHTING_COORDS(idx1,idx2) unityShadowCoord3 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2)
#define OCEAN_TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(unity_WorldToLight, worldPos).xyz; TRANSFER_SHADOW(a)
//#define LIGHT_ATTENUATION(a) (tex2D(_LightTexture0, dot(a._LightCoord,a._LightCoord).rr).UNITY_ATTEN_CHANNEL * SHADOW_ATTENUATION(a))
#endif
#ifdef SPOT
//#define LIGHTING_COORDS(idx1,idx2) unityShadowCoord4 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2)
#define OCEAN_TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(unity_WorldToLight, worldPos); TRANSFER_SHADOW(a)
//#define LIGHT_ATTENUATION(a) ( (a._LightCoord.z > 0) * UnitySpotCookie(a._LightCoord) * UnitySpotAttenuate(a._LightCoord.xyz) * SHADOW_ATTENUATION(a) )
#endif
#ifdef DIRECTIONAL
// #define LIGHTING_COORDS(idx1,idx2) SHADOW_COORDS(idx1)
#define OCEAN_TRANSFER_VERTEX_TO_FRAGMENT(a) TRANSFER_SHADOW(a)
// #define LIGHT_ATTENUATION(a) SHADOW_ATTENUATION(a)
#endif
#ifdef POINT_COOKIE
//#define LIGHTING_COORDS(idx1,idx2) unityShadowCoord3 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2)
#define OCEAN_TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(unity_WorldToLight, worldPos).xyz; TRANSFER_SHADOW(a)
//#define LIGHT_ATTENUATION(a) (tex2D(_LightTextureB0, dot(a._LightCoord,a._LightCoord).rr).UNITY_ATTEN_CHANNEL * texCUBE(_LightTexture0, a._LightCoord).w * SHADOW_ATTENUATION(a))
#endif
#ifdef DIRECTIONAL_COOKIE
//#define LIGHTING_COORDS(idx1,idx2) unityShadowCoord2 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2)
#define OCEAN_TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(unity_WorldToLight, worldPos).xy; TRANSFER_SHADOW(a)
//#define LIGHT_ATTENUATION(a) (tex2D(_LightTexture0, a._LightCoord).w * SHADOW_ATTENUATION(a))
#endif
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanLight.cginc.meta
================================================
fileFormatVersion: 2
guid: eafae18265a10964e97bb7c9c1601ef6
timeCreated: 1460511161
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanShadows.cginc
================================================
UNITY_DECLARE_SHADOWMAP(_ShadowMapTextureScatterer);
float4 _ShadowMapTextureScatterer_TexelSize;
#if SHADER_API_D3D11
#define SHADOWS_SPLIT_SPHERES
#endif
#include "../ShadowsCommon.cginc"
/**
* PCF tent shadowmap filtering based on a 7x7 kernel (optimized with 16 taps)
* Same as unity's but modified to use a different shadowmap identifier
*/
half ScattererSampleShadowmap_PCF7x7(float4 coord, float3 receiverPlaneDepthBias)
{
half shadow = 1;
#ifndef SHADOWS_NATIVE
// when we don't have hardware PCF sampling, fallback to a simple 3x3 sampling with averaged results.
return UnitySampleShadowmap_PCF3x3NoHardwareSupport(coord, receiverPlaneDepthBias);
#endif
// tent base is 7x7 base thus covering from 49 to 64 texels, thus we need 16 bilinear PCF fetches
float2 tentCenterInTexelSpace = coord.xy * _ShadowMapTextureScatterer_TexelSize.zw;
float2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);
float2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;
// find the weight of each texel based on the area of a 45 degree slop tent above each of them.
float4 texelsWeightsU_A, texelsWeightsU_B;
float4 texelsWeightsV_A, texelsWeightsV_B;
_UnityInternalGetWeightPerTexel_7TexelsWideTriangleFilter(offsetFromTentCenterToCenterOfFetches.x, texelsWeightsU_A, texelsWeightsU_B);
_UnityInternalGetWeightPerTexel_7TexelsWideTriangleFilter(offsetFromTentCenterToCenterOfFetches.y, texelsWeightsV_A, texelsWeightsV_B);
// each fetch will cover a group of 2x2 texels, the weight of each group is the sum of the weights of the texels
float4 fetchesWeightsU = float4(texelsWeightsU_A.xz, texelsWeightsU_B.xz) + float4(texelsWeightsU_A.yw, texelsWeightsU_B.yw);
float4 fetchesWeightsV = float4(texelsWeightsV_A.xz, texelsWeightsV_B.xz) + float4(texelsWeightsV_A.yw, texelsWeightsV_B.yw);
// move the PCF bilinear fetches to respect texels weights
float4 fetchesOffsetsU = float4(texelsWeightsU_A.yw, texelsWeightsU_B.yw) / fetchesWeightsU.xyzw + float4(-3.5,-1.5,0.5,2.5);
float4 fetchesOffsetsV = float4(texelsWeightsV_A.yw, texelsWeightsV_B.yw) / fetchesWeightsV.xyzw + float4(-3.5,-1.5,0.5,2.5);
fetchesOffsetsU *= _ShadowMapTextureScatterer_TexelSize.xxxx;
fetchesOffsetsV *= _ShadowMapTextureScatterer_TexelSize.yyyy;
// fetch !
float2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * _ShadowMapTextureScatterer_TexelSize.xy;
shadow = fetchesWeightsU.x * fetchesWeightsV.x * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.x, fetchesOffsetsV.x), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.y * fetchesWeightsV.x * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.y, fetchesOffsetsV.x), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.z * fetchesWeightsV.x * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.z, fetchesOffsetsV.x), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.w * fetchesWeightsV.x * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.w, fetchesOffsetsV.x), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.x * fetchesWeightsV.y * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.x, fetchesOffsetsV.y), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.y * fetchesWeightsV.y * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.y, fetchesOffsetsV.y), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.z * fetchesWeightsV.y * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.z, fetchesOffsetsV.y), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.w * fetchesWeightsV.y * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.w, fetchesOffsetsV.y), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.x * fetchesWeightsV.z * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.x, fetchesOffsetsV.z), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.y * fetchesWeightsV.z * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.y, fetchesOffsetsV.z), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.z * fetchesWeightsV.z * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.z, fetchesOffsetsV.z), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.w * fetchesWeightsV.z * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.w, fetchesOffsetsV.z), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.x * fetchesWeightsV.w * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.x, fetchesOffsetsV.w), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.y * fetchesWeightsV.w * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.y, fetchesOffsetsV.w), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.z * fetchesWeightsV.w * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.z, fetchesOffsetsV.w), coord.z, receiverPlaneDepthBias));
shadow += fetchesWeightsU.w * fetchesWeightsV.w * UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, UnityCombineShadowcoordComponents(bilinearFetchOrigin, float2(fetchesOffsetsU.w, fetchesOffsetsV.w), coord.z, receiverPlaneDepthBias));
return shadow;
}
/**
* Hard shadow
* Same as unity's, with the min strength/intensity removed
*/
half getOceanHardShadow(float4 worldPos, float viewPosZ)
{
fixed4 cascadeWeights = GET_CASCADE_WEIGHTS (worldPos, viewPosZ);
float4 shadowCoord = GET_SHADOW_COORDINATES(worldPos, cascadeWeights);
//1 tap hard shadow
fixed shadow = UNITY_SAMPLE_SHADOW(_ShadowMapTextureScatterer, shadowCoord);
//shadow = lerp(_LightShadowData.r, 1.0, shadow); //min strength/intensity, not used for ocean
fixed4 res = shadow;
return res;
}
/**
* Soft Shadow (SM 3.0)
* Same as unity's, but using a different shadowMap identifier
* And with the min strength/intensity removed
*/
half getOceanSoftShadow(float4 worldPos, float viewPosZ)
{
fixed4 cascadeWeights = GET_CASCADE_WEIGHTS (worldPos, viewPosZ);
float4 coord = GET_SHADOW_COORDINATES(worldPos, cascadeWeights);
#if SHADER_API_D3D11
float3 receiverPlaneDepthBias = float3(0.001,0.001,0.001); //custom bias to fix issue with jittering shadows on d3d11 in 1.9, probably not necessary for ocean though
#else
float3 receiverPlaneDepthBias = 0.0;
#endif
//why is this slower than the ragular shadow? maybe change this to 3x3?
half shadow = ScattererSampleShadowmap_PCF7x7(coord, receiverPlaneDepthBias);
//shadow = lerp(_LightShadowData.r, 1.0f, shadow); //min strength/intensity, not used for ocean
// Blend between shadow cascades if enabled
//
// Not working yet with split spheres, and no need when 1 cascade
#if UNITY_USE_CASCADE_BLENDING && !defined(SHADOWS_SPLIT_SPHERES) && !defined(SHADOWS_SINGLE_CASCADE)
half4 z4 = (float4(viewPosZ,viewPosZ,viewPosZ,viewPosZ) - _LightSplitsNear) / (_LightSplitsFar - _LightSplitsNear);
half alpha = dot(z4 * cascadeWeights, half4(1,1,1,1));
//why is it slow? maybe remove this?
UNITY_BRANCH
if (alpha > 1 - UNITY_CASCADE_BLEND_DISTANCE)
{
// get alpha to 0..1 range over the blend distance
alpha = (alpha - (1 - UNITY_CASCADE_BLEND_DISTANCE)) / UNITY_CASCADE_BLEND_DISTANCE;
// sample next cascade
cascadeWeights = fixed4(0, cascadeWeights.xyz);
coord = GET_SHADOW_COORDINATES(worldPos, cascadeWeights);
half shadowNextCascade = UnitySampleShadowmap_PCF3x3(coord, receiverPlaneDepthBias);
//shadowNextCascade = lerp(_LightShadowData.r, 1.0f, shadowNextCascade); //min strength/intensity, not used for ocean
shadow = lerp(shadow, shadowNextCascade, alpha);
}
#endif
return shadow;
}
half getOceanShadow(float4 worldPos, float viewPosZ)
{
//fade value
float zDist = dot(_WorldSpaceCameraPos - worldPos, UNITY_MATRIX_V[2].xyz);
float fadeDist = UnityComputeShadowFadeDistance(worldPos, zDist);
half shadowFade = UnityComputeShadowFade(fadeDist);
#if defined (OCEAN_SHADOWS_SOFT)
return lerp(getOceanSoftShadow(worldPos, viewPosZ),1.0,shadowFade);
#elif defined (OCEAN_SHADOWS_HARD)
return lerp(getOceanHardShadow(worldPos, viewPosZ),1.0,shadowFade);
#endif
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanShadows.cginc.meta
================================================
fileFormatVersion: 2
guid: e0cb37a014cdcb142af891772a27189c
timeCreated: 1545852000
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanUtils.cginc
================================================
uniform float refractionIndex;
uniform float3 _Underwater_Color;
uniform float3 _Ocean_Color;
uniform float transparencyDepth;
uniform float skyReflectionStrength;
float3 ReflectedSky(float3 V, float3 N, float3 sunDir, float3 earthP)
{
float3 result = float3(0,0,0);
float3 reflectedAngle=reflect(-V,N);
reflectedAngle.z=max(reflectedAngle.z,0.0); //hack to avoid unsightly black pixels from downwards reflections
result = SkyRadiance3(earthP,reflectedAngle, sunDir);
return result;
}
//TODO: check if can optimize/simplify
float3 refractVector(float3 I, float3 N, float ior)
{
float cosi = dot(I, N);
float3 n = N;
cosi = -cosi;
float eta = 1.0 / ior;
float k = 1 - eta * eta * (1 - cosi * cosi);
return k < 0 ? 0 : eta * I + (eta * cosi - sqrt(k)) * n;
}
float3 RefractedSky(float3 V, float3 N, float3 sunDir, float3 earthP)
{
float3 result = float3(0,0,0);
float3 refractedAngle = refractVector(-V, -N, 1/refractionIndex);
result = SkyRadiance3(earthP,refractedAngle, sunDir);
return result;
}
//TODO: check if can optimize/simplify
float fresnel_dielectric(float3 I, float3 N, float eta)
{
//compute fresnel reflectance without explicitly computing the refracted direction
float c = abs(dot(I, N));
float g = eta * eta - 1.0 + c * c;
float result;
float g2 =g;
g = sqrt(g);
float A =(g - c)/(g + c);
float B =(c *(g + c)- 1.0)/(c *(g - c)+ 1.0);
result = 0.5 * A * A *(1.0 + B * B);
result = (g2>0) ? result : 1.0; // TIR (no refracted component)
return result;
}
//underwater ocean color
float3 oceanColor(float3 viewDir, float3 lightDir, float3 surfaceDir)
{
float angleToLightDir = (dot(viewDir, surfaceDir) + 1 )* 0.5;
float3 waterColor = pow(_Underwater_Color, 4.0 *(-1.0 * angleToLightDir + 1.0));
return waterColor;
}
float getFresnel(float3 V, float3 N, float sigmaSq)
{
#if defined (UNDERWATER_ON)
float fresnel = 1.0 - fresnel_dielectric(V, N, 1/refractionIndex);
#else
float fresnel = MeanFresnel(V, N, sigmaSq);
#endif
fresnel = clamp(fresnel,0.0,1.0);
return fresnel;
}
float3 getSkyColor(float fresnel, float3 V, float3 N, float3 L, float3 earthP, float3 skyE, float shadowTerm, float radius)
{
#if defined (UNDERWATER_ON)
return (fresnel * RefractedSky(V, N, L, earthP));
#else
#if defined (SKY_REFLECTIONS_ON)
float3 skyColor = lerp(skyE / M_PI, ReflectedSky(V, N, L, earthP), skyReflectionStrength); //mix accurate sky reflection and sky irradiance
return (fresnel * (skyColor * lerp(0.5,1.0,shadowTerm) + (UNITY_LIGHTMODEL_AMBIENT.rgb*0.07)));
#else
return (fresnel * (skyE / M_PI * lerp(0.5,1.0,shadowTerm) + (UNITY_LIGHTMODEL_AMBIENT.rgb*0.07))); //sky irradiance only
#endif
#endif
}
float3 getOceanColor(float fresnel, float3 V, float3 N, float3 L, float3 earthP, float3 skyE, float shadowTerm)
{
#if defined (UNDERWATER_ON)
float3 ocColor = _sunColor * oceanColor(reflect(-V,N),L,float3(0.0,0.0,1.0)); //reflected ocean color from underwater
float waterLightExtinction = length(getSkyExtinction(earthP, L));
return(hdrNoExposure(waterLightExtinction * ocColor) * lerp(0.8,1.0,shadowTerm));
#else
return(0.98 * (1.0 - fresnel) * _Ocean_Color * (skyE / M_PI) * lerp(0.3,1.0,shadowTerm));
#endif
}
float2 getPerturbedUVsAndDepth(float2 depthUV, float3 N, float oceanDistance, out float fragDistance, out float depth)
{
float2 uv;
#if defined (UNDERWATER_ON)
uv = depthUV.xy + (N.xy)*0.025 * float2(1.0,10.0);
#else
uv = depthUV.xy + N.xy*0.025;
#endif
fragDistance = getScattererFragDistance(uv);
depth= fragDistance - oceanDistance; //water depth, ie viewing ray distance in water
uv = (depth < 0) ? depthUV.xy : uv; //for refractions, use the normal fragment uv instead the perturbed one if the perturbed one is closer
fragDistance = getScattererFragDistance(uv);
depth= fragDistance - oceanDistance;
#if !defined (UNDERWATER_ON)
depth=lerp(depth,transparencyDepth,clamp((oceanDistance-1000.0)/5000.0,0.0,1.0)); //fade out refractions and transparency at distance, to hide swirly artifacts of low precision
#endif
return uv;
}
float getTransparencyAlpha(float depth)
{
float transparencyAlpha=lerp(0.0,1.0,depth/transparencyDepth);
transparencyAlpha = (depth < -0.5) ? 1.0 : transparencyAlpha; //fix black edge around antialiased terrain in front of ocean
return transparencyAlpha;
}
float adjustWhiteCapStrengthWithDepth(float _Ocean_WhiteCapStr, float shoreFoam, float depth)
{
_Ocean_WhiteCapStr = lerp(shoreFoam,_Ocean_WhiteCapStr, clamp(depth*0.2,0.0,1.0));
return ((depth <= 0.0) ? 0.0 : _Ocean_WhiteCapStr); //fixes white outline around objects in front of the ocean
}
float applyFarWhiteCapStrength(float oceanDistance, float alphaRadius, float _Ocean_WhiteCapStr, float farWhiteCapStr)
{
float clampFactor= clamp(oceanDistance/alphaRadius,0.0,1.0); //factor to clamp whitecaps
return(lerp(_Ocean_WhiteCapStr,farWhiteCapStr,clampFactor));
}
float3 getTotalWhiteCapRadiance(float outWhiteCapStr, float jmx, float jSigma2, float3 sunL, float3 N, float3 L, float3 skyE, float shadowTerm)
{
// get coverage
float W = WhitecapCoverage(outWhiteCapStr,jmx,jSigma2);
// compute and add whitecap radiance
float3 l = (sunL * (max(dot(N, L), 0.0)) + skyE + UNITY_LIGHTMODEL_AMBIENT.rgb * 30) / M_PI;
return (float3(W * l * 0.4)* lerp(0.5,1.0,shadowTerm));
}
void getPlanetShineContribution(out float3 LsunTotal, out float3 R_ftotTotal, out float3 LseaTotal, out float3 LskyTotal)
{
// for (int i=0; i<4; ++i)
// {
// if (planetShineRGB[i].w == 0) break;
//
// L=normalize(planetShineSources[i].xyz);
// SunRadianceAndSkyIrradiance(earthP, N, L, sunL, skyE);
//
// #if defined (SKY_REFLECTIONS_ON)
// Lsky = fresnel * ReflectedSky(V, N, L, earthP); //planet, accurate sky reflections
// #else
// Lsky = fresnel * skyE / M_PI; //planet, sky irradiance only
// #endif
//
// Lsun = ReflectedSunRadiance(L, V, N, sigmaSq) * sunL;
// Lsea = RefractedSeaRadiance(V, N, sigmaSq) * _Ocean_Color * skyE / M_PI;
// l = (sunL * (max(dot(N, L), 0.0)) + skyE) / M_PI;
// R_ftot = float3(W * l * 0.4);
//
// //if source is not a sun compute intensity of light from angle to light source
// float intensity=1;
// if (planetShineSources[i].w != 1.0f)
// {
// intensity = 0.57f*max((0.75-dot(normalize(planetShineSources[i].xyz - earthP),_Ocean_SunDir)),0);
// }
//
// surfaceColor+= abs((Lsun + Lsky + Lsea + R_ftot)*planetShineRGB[i].xyz*planetShineRGB[i].w*intensity);
// LsunTotal += Lsun;
// R_ftotTotal += R_ftot;
// LseaTotal += Lsea;
// LskyTotal += Lsky;
// }
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanUtils.cginc.meta
================================================
fileFormatVersion: 2
guid: a2cc3e5914c2bb345a87c15d0b894ee8
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanWhiteCapsModProj3.shader
================================================
/*
* Proland: a procedural landscape rendering library.
* Copyright (c) 2008-2011 INRIA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* Proland is distributed under a dual-license scheme.
* You can obtain a specific license from Inria: proland-licensing@inria.fr.
*/
/*
* Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat.
*/
/**
* Real-time Realistic Ocean Lighting using Seamless Transitions from Geometry to BRDF
* Copyright (c) 2009 INRIA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Author: Eric Bruneton
* Modified and ported to Unity by Justin Hawkins 2014
* Modified and adapted for use with Kerbal Space Program by Ghassen Lahmar 2015-2020
*/
Shader "Scatterer/OceanWhiteCaps"
{
SubShader
{
Tags { "Queue" = "Geometry+100"
"RenderType"="Transparent"
"IgnoreProjector"="True"}
Pass
{
Tags { "LightMode" = "MainPass"
"Queue" = "Geometry+100"
"RenderType"="Transparent"
"IgnoreProjector"="True"}
Blend SrcAlpha OneMinusSrcAlpha
Offset 0.0, -0.14
Cull Back
ZWrite [_ZwriteVariable]
CGPROGRAM
#include "UnityCG.cginc"
#pragma glsl
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
//#pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON
#pragma multi_compile SKY_REFLECTIONS_OFF SKY_REFLECTIONS_ON
#pragma multi_compile UNDERWATER_OFF UNDERWATER_ON
#pragma multi_compile OCEAN_SHADOWS_OFF OCEAN_SHADOWS_HARD OCEAN_SHADOWS_SOFT
#pragma multi_compile REFRACTIONS_AND_TRANSPARENCY_OFF REFRACTIONS_AND_TRANSPARENCY_ON
#pragma multi_compile SCATTERER_MERGED_DEPTH_ON SCATTERER_MERGED_DEPTH_OFF
#pragma multi_compile DITHERING_OFF DITHERING_ON
#pragma multi_compile GODRAYS_OFF GODRAYS_ON
#pragma multi_compile DEPTH_BUFFER_MODE_OFF DEPTH_BUFFER_MODE_ON
#pragma multi_compile FOAM_OFF FOAM_ON
//#pragma multi_compile SCATTERING_ON SCATTERING_OFF
#include "../CommonAtmosphere.cginc"
#include "../DepthCommon.cginc"
#if defined (OCEAN_SHADOWS_HARD) || defined (OCEAN_SHADOWS_SOFT)
#include "OceanShadows.cginc"
#endif
#include "OceanBRDF.cginc"
#include "OceanDisplacement3.cginc"
#include "OceanUtils.cginc"
#include "../ClippingUtils.cginc"
#include "../Atmo/Godrays/GodraysCommon.cginc"
uniform float offScreenVertexStretch;
uniform float4x4 _Globals_ScreenToCamera;
uniform float4x4 _Globals_CameraToWorld;
uniform float4x4 _Globals_WorldToScreen;
uniform float4x4 _Globals_CameraToScreen;
uniform float3 _Globals_WorldCameraPos;
uniform float4x4 _Globals_WorldToOcean;
uniform float4x4 _Globals_OceanToWorld;
uniform float3 _Sun_WorldSunDir;
uniform float2 _Ocean_MapSize;
uniform float4 _Ocean_Choppyness;
uniform float3 _Ocean_SunDir;
uniform float4 _Ocean_GridSizes;
uniform float2 _Ocean_ScreenGridSize;
uniform float _Ocean_WhiteCapStr;
uniform float farWhiteCapStr;
uniform float shoreFoam;
uniform sampler3D _Ocean_Variance;
uniform sampler2D _Ocean_Map0;
uniform sampler2D _Ocean_Map1;
uniform sampler2D _Ocean_Map2;
uniform sampler2D _Ocean_Map3;
uniform sampler2D _Ocean_Map4;
uniform sampler2D _Ocean_Foam0;
uniform sampler2D _Ocean_Foam1;
uniform float alphaRadius;
uniform float _PlanetOpacity; //to fade out the ocean when PQS is fading out
uniform float _ScatteringExposure;
uniform float _Alpha_Global;
uniform float _SkyExposure;
uniform float2 _VarianceMax;
uniform float darknessDepth;
uniform float3 _planetPos;
uniform float _openglThreshold;
uniform float _global_depth;
uniform float _global_alpha;
uniform float _Post_Extinction_Tint;
uniform float extinctionThickness;
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
uniform sampler2D ScattererScreenCopyBeforeOcean; //background texture used for refraction
#endif
#if defined (GODRAYS_ON)
uniform sampler2D _godrayDepthTexture;
uniform float _godrayStrength;
#endif
#if defined (PLANETSHINE_ON)
uniform float4x4 planetShineSources;
uniform float4x4 planetShineRGB;
#endif
struct v2f
{
float4 pos : SV_POSITION;
float2 oceanU : TEXCOORD0;
float3 oceanP : TEXCOORD1;
float4 screenPos: TEXCOORD2;
float4 worldPos : TEXCOORD3;
float4 viewPos : TEXCOORD4;
float3 sunL : TEXCOORD5;
float3 skyE : TEXCOORD6;
};
v2f vert(appdata_base v)
{
float t;
float3 cameraDir, oceanDir;
float4 vert = v.vertex;
vert.xy *= offScreenVertexStretch;
float2 u = OceanPos(vert, _Globals_ScreenToCamera, t, cameraDir, oceanDir); //camera dir is viewing direction in camera space
float2 dux = OceanPos(vert + float4(_Ocean_ScreenGridSize.x, 0.0, 0.0, 0.0), _Globals_ScreenToCamera) - u;
float2 duy = OceanPos(vert + float4(0.0, _Ocean_ScreenGridSize.y, 0.0, 0.0), _Globals_ScreenToCamera) - u;
float3 dP = float3(0, 0, _Ocean_HeightOffset);
if(duy.x != 0.0 || duy.y != 0.0)
{
dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).x;
dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).y;
dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).z;
dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).w;
//
dP.xy += _Ocean_Choppyness.x * Tex2DGrad(_Ocean_Map3, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).xy;
dP.xy += _Ocean_Choppyness.y * Tex2DGrad(_Ocean_Map3, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).zw;
dP.xy += _Ocean_Choppyness.z * Tex2DGrad(_Ocean_Map4, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).xy;
dP.xy += _Ocean_Choppyness.w * Tex2DGrad(_Ocean_Map4, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).zw;
}
v2f OUT;
float3x3 otoc = _Ocean_OceanToCamera;
float tClamped = clamp(t*0.25, 0.0, 1.0);
#if defined (UNDERWATER_ON)
dP = lerp(float3(0.0,0.0,0.1),dP,tClamped); //prevents projected grid intersecting near plane
#else
dP = lerp(float3(0.0,0.0,-0.1),dP,tClamped); //prevents projected grid intersecting near plane
#endif
float4 screenP = float4(t * cameraDir + mul(otoc, dP), 1.0); //position in camera space
float3 oceanP = t * oceanDir + dP + float3(0.0, 0.0, _Ocean_CameraPos.z);
OUT.pos = mul(UNITY_MATRIX_P, screenP);
OUT.oceanU = u;
OUT.oceanP = oceanP;
OUT.screenPos = ComputeScreenPos(OUT.pos);
OUT.worldPos=mul(_Globals_CameraToWorld , screenP);
OUT.viewPos = screenP;
#if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12
OUT.pos = (_PlanetOpacity == 0.0) ? float4(2.0, 2.0, 2.0, 1.0) : OUT.pos; //cull when completely transparent
#else
OUT.pos = lerp(float4(2.0, 2.0, 2.0, 1.0), OUT.pos, step(0.001,_PlanetOpacity)); //stupid opengl
#endif
float3 earthP = normalize(oceanP + float3(0.0, 0.0, _Ocean_Radius)) * (_Ocean_Radius + 10.0);
float3 sunL, skyE;
SunRadianceAndSkyIrradiance(earthP, float3(0.0,0.0,1.0), _Ocean_SunDir, sunL, skyE);
OUT.sunL = sunL;
OUT.skyE = skyE;
return OUT;
}
float4 frag(v2f IN) : SV_Target
{
float2 u = IN.oceanU;
float3 oceanP = IN.oceanP;
float3 oceanCamera = float3(0.0, 0.0, _Ocean_CameraPos.z);
float3 V = normalize(oceanCamera - oceanP);
float2 slopes = float2(0,0);
slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.x).xy;
slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.y).zw;
slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.z).xy;
slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.w).zw;
slopes -= oceanP.xy / (_Ocean_Radius + oceanP.z);
float3 N = normalize(float3(-slopes.x, -slopes.y, 1.0));
float Jxx = ddx(u.x);
float Jxy = ddy(u.x);
float Jyx = ddx(u.y);
float Jyy = ddy(u.y);
float A = Jxx * Jxx + Jyx * Jyx;
float B = Jxx * Jxy + Jyx * Jyy;
float C = Jxy * Jxy + Jyy * Jyy;
const float SCALE = 10.0;
float ua = pow(A / SCALE, 0.25);
float ub = 0.5 + 0.5 * B / sqrt(A * C);
float uc = pow(C / SCALE, 0.25);
float sigmaSq = tex3D(_Ocean_Variance, float3(ua, ub, uc)).x * _VarianceMax.x;
sigmaSq = max(sigmaSq, 2e-5);
#if defined (FOAM_ON)
// extract mean and variance of the jacobian matrix determinant
float2 jm1 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.x).xy;
float2 jm2 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.y).zw;
float2 jm3 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.z).xy;
float2 jm4 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.w).zw;
float2 jm = jm1+jm2+jm3+jm4;
float jSigma2 = max(jm.y - (jm1.x*jm1.x + jm2.x*jm2.x + jm3.x*jm3.x + jm4.x*jm4.x), 0.0);
#endif
float3 earthP = normalize(oceanP + float3(0.0, 0.0, _Ocean_Radius)) * (_Ocean_Radius + 10.0);
float3 sunL = IN.sunL;
float3 skyE = IN.skyE;
half shadowTerm = 1.0;
#if defined (OCEAN_SHADOWS_HARD) || defined (OCEAN_SHADOWS_SOFT)
shadowTerm = getOceanShadow (IN.worldPos, -IN.viewPos.z);
#endif
float fresnel = getFresnel(V, N, sigmaSq);
float3 Lsky = getSkyColor(fresnel, V, N, _Ocean_SunDir, earthP, skyE, shadowTerm, _Ocean_Radius);
float3 Lsea = getOceanColor(fresnel, V, N, _Ocean_SunDir, earthP, skyE, shadowTerm);
float oceanDistance = length(IN.viewPos);
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
float fragDistance, depth;
float2 uv = IN.screenPos.xy / IN.screenPos.w;
#if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12
uv.y = 1.0 - uv.y;
#endif
uv = getPerturbedUVsAndDepth(uv, N, oceanDistance, fragDistance, depth);
_Ocean_WhiteCapStr = adjustWhiteCapStrengthWithDepth(_Ocean_WhiteCapStr, shoreFoam, depth);
float transparencyAlpha = getTransparencyAlpha(depth);
#else
float transparencyAlpha=1.0;
#endif
float3 R_ftot = float3(0.0,0.0,0.0);
#if defined (FOAM_ON)
float outWhiteCapStr=applyFarWhiteCapStrength(oceanDistance, alphaRadius, _Ocean_WhiteCapStr, farWhiteCapStr);
R_ftot = getTotalWhiteCapRadiance(outWhiteCapStr, jm.x, jSigma2, sunL, N, _Ocean_SunDir, skyE, shadowTerm);
#endif
float3 Lsun = ReflectedSunRadiance(_Ocean_SunDir, V, N, sigmaSq) * sunL * shadowTerm;
#if defined (UNDERWATER_ON)
float3 surfaceColor = hdr(abs(Lsea + R_ftot),_ScatteringExposure);
#else
float3 surfaceColor = hdr(abs(Lsun + Lsea + R_ftot),_ScatteringExposure);
Lsky = _Alpha_Global*hdr(Lsky,_SkyExposure);
surfaceColor = surfaceColor + (1.0-surfaceColor) * Lsky;
#endif
float3 LsunTotal = Lsun; float3 R_ftotTotal = R_ftot; float3 LseaTotal = Lsea; float3 LskyTotal = Lsky;
#if defined (PLANETSHINE_ON)
getPlanetShineContribution(LsunTotal, R_ftotTotal, LseaTotal, LskyTotal);
#endif
#if SHADER_API_D3D11
bool insideClippingRange = true;
#else
bool insideClippingRange = oceanFragmentInsideOfClippingRange(-IN.viewPos.z/IN.viewPos.w);
#endif
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
transparencyAlpha = max(hdr(LsunTotal + R_ftotTotal,_ScatteringExposure), fresnel+transparencyAlpha) ; //seems about perfect
transparencyAlpha = min(transparencyAlpha, 1.0);
float3 backGrnd = 0.0;
#if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12
backGrnd = tex2D(ScattererScreenCopyBeforeOcean, (_ProjectionParams.x == 1.0) ? uv : float2(uv.x,1.0-uv.y) );
#else
backGrnd = tex2D(ScattererScreenCopyBeforeOcean, uv );
#endif
#endif
#if defined (UNDERWATER_ON)
Lsky = _Alpha_Global*hdr(Lsky,_SkyExposure);
float3 transmittance = hdr(R_ftot, _ScatteringExposure);
transmittance = clamp(transmittance, float3(0.0,0.0,0.0), float3(1.0,1.0,1.0));
transmittance = transmittance + (1.0-transmittance) * Lsky; //consider not using transmittance but instead background texture, change the refraction angle to have something matching what you would see from underwater
float3 finalColor = (1.0 - fresnel) * Lsea;
finalColor+=clamp(transmittance * fresnel,float3(0.0,0.0,0.0),float3(1.0,1.0,1.0)); //somehow doing lerp directly breaks opengl
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
backGrnd+=hdr(R_ftotTotal,_ScatteringExposure)*(1-backGrnd); //make foam visible from below as well
finalColor = (fragDistance < 750000.0) ? backGrnd : finalColor;
#endif
float3 Vworld = mul ( _Globals_OceanToWorld, float4(V,0.0));
float3 Lworld = mul ( _Globals_OceanToWorld, float4(_Ocean_SunDir,0.0));
float3 earthCamPos = normalize(float3(_Ocean_CameraPos.xy,0.0) + float3(0.0, 0.0, _Ocean_Radius)) * (_Ocean_Radius + 10.0);
float underwaterDepth = lerp(1.0,0.0,-_Ocean_CameraPos.z / darknessDepth);
float waterLightExtinction = length(getSkyExtinction(earthCamPos, _Ocean_SunDir));
float3 _camPos = _WorldSpaceCameraPos - _planetPos;
float3 oceanCol = underwaterDepth * hdrNoExposure(waterLightExtinction * _sunColor * oceanColor(-Vworld,Lworld,normalize(_camPos))); //add planetshine loop here over Ls
finalColor= clamp(finalColor, float3(0.0,0.0,0.0),float3(1.0,1.0,1.0));
finalColor= lerp(finalColor, oceanCol, min(length(oceanCamera - oceanP)/transparencyDepth,1.0));
return float4(dither(finalColor, IN.pos),insideClippingRange);
#else
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
float3 finalColor = lerp(backGrnd, surfaceColor, transparencyAlpha); //refraction on and not underwater
#else
float3 finalColor = surfaceColor; //refraction off and not underwater
#endif
#if defined (DEPTH_BUFFER_MODE_OFF)
if (_PlanetOpacity == 1.0)
{
float3 worldPos= IN.worldPos - _planetPos;
worldPos = (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix
float3 _camPos = _WorldSpaceCameraPos - _planetPos;
float minDistance = length(worldPos-_camPos);
#if defined (GODRAYS_ON)
float2 godrayUV = IN.screenPos.xy / IN.screenPos.w;
float godrayDepth = 0.0;
godrayDepth = sampleGodrayDepth(_godrayDepthTexture, godrayUV, 1.0);
//trying to find the optical depth from the terrain level
float muTerrain = dot(normalize(worldPos), normalize(_camPos - worldPos));
godrayDepth = _godrayStrength * DistanceFromOpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(worldPos), muTerrain, godrayDepth, minDistance);
worldPos = worldPos - godrayDepth * normalize(worldPos-_camPos);
#endif
float3 inscatter=0.0;float3 extinction=1.0;
inscatter = InScattering2(_camPos, worldPos,SUN_DIR,extinction);
inscatter*= (minDistance <= _global_depth) ? (1 - exp(-1 * (4 * minDistance / _global_depth))) : 1.0 ; //somehow the shader compiler for OpenGL behaves differently around braces
inscatter = hdr(inscatter,_ScatteringExposure) *_global_alpha;
float average=(extinction.r+extinction.g+extinction.b)/3;
//lerped manually because of an issue with opengl or whatever
extinction = _Post_Extinction_Tint * extinction + (1-_Post_Extinction_Tint) * float3(average,average,average);
extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) );
finalColor*= extinction;
finalColor = inscatter*(1-finalColor) + finalColor;
}
#endif
insideClippingRange = (transparencyAlpha == 1.0) ? 1.0 : insideClippingRange; //if no transparency -> render normally, if transparency play with the overlap to hide seams between cameras
return float4(dither(finalColor,IN.pos), _PlanetOpacity*insideClippingRange);
#endif
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanWhiteCapsModProj3.shader.meta
================================================
fileFormatVersion: 2
guid: a0fba9bd62d2b5c4bb89c81f58569c58
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanWhiteCapsModProj3PixelLights.shader
================================================
/*
* Proland: a procedural landscape rendering library.
* Copyright (c) 2008-2011 INRIA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* Proland is distributed under a dual-license scheme.
* You can obtain a specific license from Inria: proland-licensing@inria.fr.
*/
/*
* Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat.
*/
/**
* Real-time Realistic Ocean Lighting using Seamless Transitions from Geometry to BRDF
* Copyright (c) 2009 INRIA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Author: Eric Bruneton
* Modified and ported to Unity by Justin Hawkins 2014
* Modified and adapted for use with Kerbal Space Program by Ghassen Lahmar 2015-2020
*/
Shader "Scatterer/OceanWhiteCapsPixelLights"
{
SubShader
{
Tags { "Queue" = "Geometry+100"
"RenderType"="Transparent"
"IgnoreProjector"="True"}
Pass
{
Tags { "LightMode" = "MainPass"
"Queue" = "Geometry+100"
"RenderType"="Transparent"
"IgnoreProjector"="True"}
Blend SrcAlpha OneMinusSrcAlpha
Offset 0.0, -0.14
Cull Back
ZWrite [_ZwriteVariable]
CGPROGRAM
#include "UnityCG.cginc"
#pragma glsl
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
//#pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON
#pragma multi_compile SKY_REFLECTIONS_OFF SKY_REFLECTIONS_ON
#pragma multi_compile UNDERWATER_OFF UNDERWATER_ON
#pragma multi_compile OCEAN_SHADOWS_OFF OCEAN_SHADOWS_HARD OCEAN_SHADOWS_SOFT
#pragma multi_compile REFRACTIONS_AND_TRANSPARENCY_OFF REFRACTIONS_AND_TRANSPARENCY_ON
#pragma multi_compile SCATTERER_MERGED_DEPTH_ON SCATTERER_MERGED_DEPTH_OFF
#pragma multi_compile DITHERING_OFF DITHERING_ON
#pragma multi_compile GODRAYS_OFF GODRAYS_ON
#pragma multi_compile DEPTH_BUFFER_MODE_OFF DEPTH_BUFFER_MODE_ON
#pragma multi_compile FOAM_OFF FOAM_ON
//#pragma multi_compile SCATTERING_ON SCATTERING_OFF
#include "../CommonAtmosphere.cginc"
#include "../DepthCommon.cginc"
#if defined (OCEAN_SHADOWS_HARD) || defined (OCEAN_SHADOWS_SOFT)
#include "OceanShadows.cginc"
#endif
#include "OceanBRDF.cginc"
#include "OceanDisplacement3.cginc"
#include "OceanUtils.cginc"
#include "../ClippingUtils.cginc"
#include "../Atmo/Godrays/GodraysCommon.cginc"
uniform float offScreenVertexStretch;
uniform float4x4 _Globals_ScreenToCamera;
uniform float4x4 _Globals_CameraToWorld;
uniform float4x4 _Globals_WorldToScreen;
uniform float4x4 _Globals_CameraToScreen;
uniform float3 _Globals_WorldCameraPos;
uniform float4x4 _Globals_WorldToOcean;
uniform float4x4 _Globals_OceanToWorld;
uniform float3 _Sun_WorldSunDir;
uniform float2 _Ocean_MapSize;
uniform float4 _Ocean_Choppyness;
uniform float3 _Ocean_SunDir;
uniform float4 _Ocean_GridSizes;
uniform float2 _Ocean_ScreenGridSize;
uniform float _Ocean_WhiteCapStr;
uniform float farWhiteCapStr;
uniform float shoreFoam;
uniform sampler3D _Ocean_Variance;
uniform sampler2D _Ocean_Map0;
uniform sampler2D _Ocean_Map1;
uniform sampler2D _Ocean_Map2;
uniform sampler2D _Ocean_Map3;
uniform sampler2D _Ocean_Map4;
uniform sampler2D _Ocean_Foam0;
uniform sampler2D _Ocean_Foam1;
uniform float alphaRadius;
uniform float _PlanetOpacity; //to fade out the ocean when PQS is fading out
uniform float _ScatteringExposure;
uniform float _Alpha_Global;
uniform float _SkyExposure;
uniform float2 _VarianceMax;
uniform float darknessDepth;
uniform float3 _planetPos;
uniform float _openglThreshold;
uniform float _global_depth;
uniform float _global_alpha;
uniform float _Post_Extinction_Tint;
uniform float extinctionThickness;
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
uniform sampler2D ScattererScreenCopyBeforeOcean; //background texture used for refraction
#endif
#if defined (GODRAYS_ON)
uniform sampler2D _godrayDepthTexture;
uniform float _godrayStrength;
#endif
#if defined (PLANETSHINE_ON)
uniform float4x4 planetShineSources;
uniform float4x4 planetShineRGB;
#endif
struct v2f
{
float4 pos : SV_POSITION;
float2 oceanU : TEXCOORD0;
float3 oceanP : TEXCOORD1;
float4 screenPos: TEXCOORD2;
float4 worldPos : TEXCOORD3;
float4 viewPos : TEXCOORD4;
float3 sunL : TEXCOORD5;
float3 skyE : TEXCOORD6;
};
v2f vert(appdata_base v)
{
float t;
float3 cameraDir, oceanDir;
float4 vert = v.vertex;
vert.xy *= offScreenVertexStretch;
float2 u = OceanPos(vert, _Globals_ScreenToCamera, t, cameraDir, oceanDir); //camera dir is viewing direction in camera space
float2 dux = OceanPos(vert + float4(_Ocean_ScreenGridSize.x, 0.0, 0.0, 0.0), _Globals_ScreenToCamera) - u;
float2 duy = OceanPos(vert + float4(0.0, _Ocean_ScreenGridSize.y, 0.0, 0.0), _Globals_ScreenToCamera) - u;
float3 dP = float3(0, 0, _Ocean_HeightOffset);
if(duy.x != 0.0 || duy.y != 0.0)
{
dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).x;
dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).y;
dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).z;
dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).w;
//
dP.xy += _Ocean_Choppyness.x * Tex2DGrad(_Ocean_Map3, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).xy;
dP.xy += _Ocean_Choppyness.y * Tex2DGrad(_Ocean_Map3, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).zw;
dP.xy += _Ocean_Choppyness.z * Tex2DGrad(_Ocean_Map4, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).xy;
dP.xy += _Ocean_Choppyness.w * Tex2DGrad(_Ocean_Map4, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).zw;
}
v2f OUT;
float3x3 otoc = _Ocean_OceanToCamera;
float tClamped = clamp(t*0.25, 0.0, 1.0);
#if defined (UNDERWATER_ON)
dP = lerp(float3(0.0,0.0,0.1),dP,tClamped); //prevents projected grid intersecting near plane
#else
dP = lerp(float3(0.0,0.0,-0.1),dP,tClamped); //prevents projected grid intersecting near plane
#endif
float4 screenP = float4(t * cameraDir + mul(otoc, dP), 1.0); //position in camera space
float3 oceanP = t * oceanDir + dP + float3(0.0, 0.0, _Ocean_CameraPos.z);
OUT.pos = mul(UNITY_MATRIX_P, screenP);
OUT.oceanU = u;
OUT.oceanP = oceanP;
OUT.screenPos = ComputeScreenPos(OUT.pos);
OUT.worldPos=mul(_Globals_CameraToWorld , screenP);
OUT.viewPos = screenP;
#if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12
OUT.pos = (_PlanetOpacity == 0.0) ? float4(2.0, 2.0, 2.0, 1.0) : OUT.pos; //cull when completely transparent
#else
OUT.pos = lerp(float4(2.0, 2.0, 2.0, 1.0), OUT.pos, step(0.001,_PlanetOpacity)); //stupid opengl
#endif
float3 earthP = normalize(oceanP + float3(0.0, 0.0, _Ocean_Radius)) * (_Ocean_Radius + 10.0);
float3 sunL, skyE;
SunRadianceAndSkyIrradiance(earthP, float3(0.0,0.0,1.0), _Ocean_SunDir, sunL, skyE);
OUT.sunL = sunL;
OUT.skyE = skyE;
return OUT;
}
float4 frag(v2f IN) : SV_Target
{
float2 u = IN.oceanU;
float3 oceanP = IN.oceanP;
float3 oceanCamera = float3(0.0, 0.0, _Ocean_CameraPos.z);
float3 V = normalize(oceanCamera - oceanP);
float2 slopes = float2(0,0);
slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.x).xy;
slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.y).zw;
slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.z).xy;
slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.w).zw;
slopes -= oceanP.xy / (_Ocean_Radius + oceanP.z);
float3 N = normalize(float3(-slopes.x, -slopes.y, 1.0));
float Jxx = ddx(u.x);
float Jxy = ddy(u.x);
float Jyx = ddx(u.y);
float Jyy = ddy(u.y);
float A = Jxx * Jxx + Jyx * Jyx;
float B = Jxx * Jxy + Jyx * Jyy;
float C = Jxy * Jxy + Jyy * Jyy;
const float SCALE = 10.0;
float ua = pow(A / SCALE, 0.25);
float ub = 0.5 + 0.5 * B / sqrt(A * C);
float uc = pow(C / SCALE, 0.25);
float sigmaSq = tex3D(_Ocean_Variance, float3(ua, ub, uc)).x * _VarianceMax.x;
sigmaSq = max(sigmaSq, 2e-5);
#if defined (FOAM_ON)
// extract mean and variance of the jacobian matrix determinant
float2 jm1 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.x).xy;
float2 jm2 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.y).zw;
float2 jm3 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.z).xy;
float2 jm4 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.w).zw;
float2 jm = jm1+jm2+jm3+jm4;
float jSigma2 = max(jm.y - (jm1.x*jm1.x + jm2.x*jm2.x + jm3.x*jm3.x + jm4.x*jm4.x), 0.0);
#endif
float3 earthP = normalize(oceanP + float3(0.0, 0.0, _Ocean_Radius)) * (_Ocean_Radius + 10.0);
float3 sunL = IN.sunL;
float3 skyE = IN.skyE;
half shadowTerm = 1.0;
#if defined (OCEAN_SHADOWS_HARD) || defined (OCEAN_SHADOWS_SOFT)
shadowTerm = getOceanShadow (IN.worldPos, -IN.viewPos.z);
#endif
float fresnel = getFresnel(V, N, sigmaSq);
float3 Lsky = getSkyColor(fresnel, V, N, _Ocean_SunDir, earthP, skyE, shadowTerm, _Ocean_Radius);
float3 Lsea = getOceanColor(fresnel, V, N, _Ocean_SunDir, earthP, skyE, shadowTerm);
float oceanDistance = length(IN.viewPos);
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
float fragDistance, depth;
float2 uv = IN.screenPos.xy / IN.screenPos.w;
#if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12
uv.y = 1.0 - uv.y;
#endif
uv = getPerturbedUVsAndDepth(uv, N, oceanDistance, fragDistance, depth);
_Ocean_WhiteCapStr = adjustWhiteCapStrengthWithDepth(_Ocean_WhiteCapStr, shoreFoam, depth);
float transparencyAlpha = getTransparencyAlpha(depth);
#else
float transparencyAlpha=1.0;
#endif
float3 R_ftot = float3(0.0,0.0,0.0);
#if defined (FOAM_ON)
float outWhiteCapStr=applyFarWhiteCapStrength(oceanDistance, alphaRadius, _Ocean_WhiteCapStr, farWhiteCapStr);
R_ftot = getTotalWhiteCapRadiance(outWhiteCapStr, jm.x, jSigma2, sunL, N, _Ocean_SunDir, skyE, shadowTerm);
#endif
float3 Lsun = ReflectedSunRadiance(_Ocean_SunDir, V, N, sigmaSq) * sunL * shadowTerm;
#if defined (UNDERWATER_ON)
float3 surfaceColor = hdr(abs(Lsea + R_ftot),_ScatteringExposure);
#else
float3 surfaceColor = hdr(abs(Lsun + Lsea + R_ftot),_ScatteringExposure);
Lsky = _Alpha_Global*hdr(Lsky,_SkyExposure);
surfaceColor = surfaceColor + (1.0-surfaceColor) * Lsky;
#endif
float3 LsunTotal = Lsun; float3 R_ftotTotal = R_ftot; float3 LseaTotal = Lsea; float3 LskyTotal = Lsky;
#if defined (PLANETSHINE_ON)
getPlanetShineContribution(LsunTotal, R_ftotTotal, LseaTotal, LskyTotal);
#endif
#if SHADER_API_D3D11
bool insideClippingRange = true;
#else
bool insideClippingRange = oceanFragmentInsideOfClippingRange(-IN.viewPos.z/IN.viewPos.w);
#endif
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
transparencyAlpha = max(hdr(LsunTotal + R_ftotTotal,_ScatteringExposure), fresnel+transparencyAlpha) ; //seems about perfect
transparencyAlpha = min(transparencyAlpha, 1.0);
float3 backGrnd = 0.0;
// #if defined (DEPTH_BUFFER_MODE_ON)
// backGrnd = tex2D(ScattererScreenCopyBeforeOcean, uv );
// #else
#if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12
backGrnd = tex2D(ScattererScreenCopyBeforeOcean, (_ProjectionParams.x == 1.0) ? uv : float2(uv.x,1.0-uv.y) );
#else
backGrnd = tex2D(ScattererScreenCopyBeforeOcean, uv );
#endif
// #endif
#endif
#if defined (UNDERWATER_ON)
Lsky = _Alpha_Global*hdr(Lsky,_SkyExposure);
float3 transmittance = hdr(R_ftot, _ScatteringExposure);
transmittance = clamp(transmittance, float3(0.0,0.0,0.0), float3(1.0,1.0,1.0));
transmittance = transmittance + (1.0-transmittance) * Lsky;
float3 finalColor = lerp(transmittance,Lsea, 1-fresnel); //consider not using transmittance but instead background texture, change the refraction angle to have something matching what you would see from underwater
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
backGrnd+=hdr(R_ftotTotal,_ScatteringExposure)*(1-backGrnd); //make foam visible from below as well
finalColor = (fragDistance < 750000.0) ? backGrnd : finalColor;
#endif
float3 Vworld = mul ( _Globals_OceanToWorld, float4(V,0.0));
float3 Lworld = mul ( _Globals_OceanToWorld, float4(_Ocean_SunDir,0.0));
float3 earthCamPos = normalize(float3(_Ocean_CameraPos.xy,0.0) + float3(0.0, 0.0, _Ocean_Radius)) * (_Ocean_Radius + 10.0);
float underwaterDepth = lerp(1.0,0.0,-_Ocean_CameraPos.z / darknessDepth);
float waterLightExtinction = length(getSkyExtinction(earthCamPos, _Ocean_SunDir));
float3 _camPos = _WorldSpaceCameraPos - _planetPos;
float3 oceanCol = underwaterDepth * hdrNoExposure(waterLightExtinction * _sunColor * oceanColor(-Vworld,Lworld,normalize(_camPos))); //add planetshine loop here over Ls
finalColor= clamp(finalColor, float3(0.0,0.0,0.0),float3(1.0,1.0,1.0));
finalColor= lerp(finalColor, oceanCol, min(length(oceanCamera - oceanP)/transparencyDepth,1.0));
return float4(dither(finalColor, IN.pos),insideClippingRange);
#else
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
float3 finalColor = lerp(backGrnd, surfaceColor, transparencyAlpha); //refraction on and not underwater
#else
float3 finalColor = surfaceColor; //refraction off and not underwater
#endif
#if defined (DEPTH_BUFFER_MODE_OFF)
if (_PlanetOpacity == 1.0)
{
float3 worldPos= IN.worldPos - _planetPos;
worldPos = (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix
float3 _camPos = _WorldSpaceCameraPos - _planetPos;
float minDistance = length(worldPos-_camPos);
#if defined (GODRAYS_ON)
float2 godrayUV = IN.screenPos.xy / IN.screenPos.w;
float godrayDepth = 0.0;
godrayDepth = sampleGodrayDepth(_godrayDepthTexture, godrayUV, 1.0);
//trying to find the optical depth from the terrain level
float muTerrain = dot(normalize(worldPos), normalize(_camPos - worldPos));
godrayDepth = _godrayStrength * DistanceFromOpticalDepth(_experimentalAtmoScale * (Rt-Rg) * 0.5, length(worldPos), muTerrain, godrayDepth, minDistance);
worldPos = worldPos - godrayDepth * normalize(worldPos-_camPos);
#endif
float3 inscatter=0.0;float3 extinction=1.0;
inscatter = InScattering2(_camPos, worldPos,SUN_DIR,extinction);
inscatter*= (minDistance <= _global_depth) ? (1 - exp(-1 * (4 * minDistance / _global_depth))) : 1.0 ; //somehow the shader compiler for OpenGL behaves differently around braces
inscatter = hdr(inscatter,_ScatteringExposure) *_global_alpha;
float average=(extinction.r+extinction.g+extinction.b)/3;
//lerped manually because of an issue with opengl or whatever
extinction = _Post_Extinction_Tint * extinction + (1-_Post_Extinction_Tint) * float3(average,average,average);
extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) );
finalColor*= extinction;
finalColor = inscatter*(1-finalColor) + finalColor;
}
#endif
insideClippingRange = (transparencyAlpha == 1.0) ? 1.0 : insideClippingRange; //if no transparency -> render normally, if transparency play with the overlap to hide seams between cameras
return float4(dither(finalColor,IN.pos), _PlanetOpacity*insideClippingRange);
#endif
}
ENDCG
}
Pass //forward Add
{
Tags { "LightMode" = "ForwardAdd" }
Blend One OneMinusSrcColor //"reverse" soft-additive
Offset 0.0, -0.14 //give a superior depth offset to that of localScattering to prevent scattering that should be behind ocean from appearing in front
CGPROGRAM
#include "UnityCG.cginc"
#pragma glsl
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdadd
// #pragma multi_compile FOAM_OFF FOAM_ON
#include "../Utility.cginc"
//#include "AtmosphereNew.cginc"
#include "OceanBRDF.cginc"
#include "OceanDisplacement3.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
#include "OceanLight.cginc"
uniform float offScreenVertexStretch;
uniform float4x4 _Globals_ScreenToCamera;
uniform float4x4 _Globals_CameraToWorld;
uniform float4x4 _Globals_WorldToScreen;
uniform float4x4 _Globals_CameraToScreen;
uniform float4x4 _Globals_WorldToOcean;
uniform float4x4 _Globals_OceanToWorld;
uniform float3 _Globals_WorldCameraPos;
uniform float2 _Ocean_MapSize;
uniform float4 _Ocean_Choppyness;
uniform float3 _Ocean_SunDir;
uniform float3 _Ocean_Color;
uniform float4 _Ocean_GridSizes;
uniform float2 _Ocean_ScreenGridSize;
uniform float _Ocean_WhiteCapStr;
uniform float farWhiteCapStr;
uniform sampler3D _Ocean_Variance;
uniform sampler2D _Ocean_Map0;
uniform sampler2D _Ocean_Map1;
uniform sampler2D _Ocean_Map2;
uniform sampler2D _Ocean_Map3;
uniform sampler2D _Ocean_Map4;
uniform sampler2D _Ocean_Foam0;
uniform sampler2D _Ocean_Foam1;
uniform float alphaRadius;
uniform float _ScatteringExposure;
uniform float _PlanetOpacity; //to fade out the ocean when PQS is fading out
uniform float2 _VarianceMax;
uniform sampler2D _Sky_Map;
struct v2f
{
float4 pos : SV_POSITION;
float2 oceanU : TEXCOORD0;
float3 oceanP : TEXCOORD1;
LIGHTING_COORDS(2,3)
};
v2f vert(appdata_base v)
{
float t;
float3 cameraDir, oceanDir;
float4 vert = v.vertex;
vert.xy *= offScreenVertexStretch;
float2 u = OceanPos(vert, _Globals_ScreenToCamera, t, cameraDir, oceanDir); //camera dir is viewing direction in camera space
float2 dux = OceanPos(vert + float4(_Ocean_ScreenGridSize.x, 0.0, 0.0, 0.0), _Globals_ScreenToCamera) - u;
float2 duy = OceanPos(vert + float4(0.0, _Ocean_ScreenGridSize.y, 0.0, 0.0), _Globals_ScreenToCamera) - u;
float3 dP = float3(0, 0, _Ocean_HeightOffset);
if(duy.x != 0.0 || duy.y != 0.0)
{
float4 GRID_SIZES = _Ocean_GridSizes;
float4 CHOPPYNESS = _Ocean_Choppyness;
dP.z += Tex2DGrad(_Ocean_Map0, u / GRID_SIZES.x, dux / GRID_SIZES.x, duy / GRID_SIZES.x, _Ocean_MapSize).x;
dP.z += Tex2DGrad(_Ocean_Map0, u / GRID_SIZES.y, dux / GRID_SIZES.y, duy / GRID_SIZES.y, _Ocean_MapSize).y;
dP.z += Tex2DGrad(_Ocean_Map0, u / GRID_SIZES.z, dux / GRID_SIZES.z, duy / GRID_SIZES.z, _Ocean_MapSize).z;
dP.z += Tex2DGrad(_Ocean_Map0, u / GRID_SIZES.w, dux / GRID_SIZES.w, duy / GRID_SIZES.w, _Ocean_MapSize).w;
dP.xy += CHOPPYNESS.x * Tex2DGrad(_Ocean_Map3, u / GRID_SIZES.x, dux / GRID_SIZES.x, duy / GRID_SIZES.x, _Ocean_MapSize).xy;
dP.xy += CHOPPYNESS.y * Tex2DGrad(_Ocean_Map3, u / GRID_SIZES.y, dux / GRID_SIZES.y, duy / GRID_SIZES.y, _Ocean_MapSize).zw;
dP.xy += CHOPPYNESS.z * Tex2DGrad(_Ocean_Map4, u / GRID_SIZES.z, dux / GRID_SIZES.z, duy / GRID_SIZES.z, _Ocean_MapSize).xy;
dP.xy += CHOPPYNESS.w * Tex2DGrad(_Ocean_Map4, u / GRID_SIZES.w, dux / GRID_SIZES.w, duy / GRID_SIZES.w, _Ocean_MapSize).zw;
}
v2f OUT;
float3x3 otoc = _Ocean_OceanToCamera;
float tClamped = clamp(t*0.25, 0.0, 1.0);
dP = lerp(float3(0.0,0.0,-0.1),dP,tClamped); //prevents projected grid intersecting near plane
float4 screenP = float4(t * cameraDir + mul(otoc, dP), 1.0); //position in camera space?
float3 oceanP = t * oceanDir + dP + float3(0.0, 0.0, _Ocean_CameraPos.z);
OUT.pos = mul(_Globals_CameraToScreen, screenP);
OUT.pos.y = OUT.pos.y *_ProjectionParams.x;
OUT.oceanU = u;
OUT.oceanP = oceanP;
float4 worldPos=mul(_Globals_CameraToWorld , screenP);
OCEAN_TRANSFER_VERTEX_TO_FRAGMENT(OUT);
OUT.pos = (_PlanetOpacity == 1.0) ? OUT.pos : float4(2.0, 2.0, 2.0, 1.0) ; //cull when planet starts fading out
return OUT;
}
float4 frag(v2f IN) : COLOR
{
float radius = _Ocean_Radius;
float2 u = IN.oceanU;
float3 oceanP = IN.oceanP;
float3 earthCamera = float3(0.0, 0.0, _Ocean_CameraPos.z + radius);
float3 earthP = normalize(oceanP + float3(0.0, 0.0, radius)) * (radius + 10.0);
float dist=length(earthP-earthCamera);
float clampFactor= clamp(dist/alphaRadius,0.0,1.0);
float outWhiteCapStr=lerp(_Ocean_WhiteCapStr,farWhiteCapStr,clampFactor);
float3 oceanCamera = float3(0.0, 0.0, _Ocean_CameraPos.z);
float3 V = normalize(oceanCamera - oceanP);
float2 slopes = float2(0,0);
slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.x).xy;
slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.y).zw;
slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.z).xy;
slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.w).zw;
slopes -= oceanP.xy / (radius + oceanP.z);
float3 N = normalize(float3(-slopes.x, -slopes.y, 1.0));
if (dot(V, N) < 0.0) {
N = reflect(N, V); // reflects backfacing normals
}
float Jxx = ddx(u.x);
float Jxy = ddy(u.x);
float Jyx = ddx(u.y);
float Jyy = ddy(u.y);
float A = Jxx * Jxx + Jyx * Jyx;
float B = Jxx * Jxy + Jyx * Jyy;
float C = Jxy * Jxy + Jyy * Jyy;
const float SCALE = 10.0;
float ua = pow(A / SCALE, 0.25);
float ub = 0.5 + 0.5 * B / sqrt(A * C);
float uc = pow(C / SCALE, 0.25);
// float sigmaSq = tex3D(_Ocean_Variance, float3(ua, ub, uc)).x;
float2 sigmaSq = tex3D(_Ocean_Variance, float3(ua, ub, uc)).xy * _VarianceMax;
sigmaSq = max(sigmaSq, 2e-5);
float atten=LIGHT_ATTENUATION(IN)*15;
float3 Lsky;
Lsky = MeanFresnel(V, N, sigmaSq) * atten / M_PI;
float3 oceanL= mul(_Globals_WorldToOcean, _WorldSpaceLightPos0);
float3 L = normalize(oceanL - oceanP); //light dir in ocean space, find it
float3 Lsun = ReflectedSunRadiance(L, V, N, sigmaSq) * atten;
float3 Lsea = RefractedSeaRadiance(V, N, sigmaSq) * _Ocean_Color * atten;
//#if defined (FOAM_ON)
// // extract mean and variance of the jacobian matrix determinant
// float2 jm1 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.x).xy;
// float2 jm2 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.y).zw;
// float2 jm3 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.z).xy;
// float2 jm4 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.w).zw;
// float2 jm = jm1+jm2+jm3+jm4;
// float jSigma2 = max(jm.y - (jm1.x*jm1.x + jm2.x*jm2.x + jm3.x*jm3.x + jm4.x*jm4.x), 0.0);
//
// // get coverage
// float W = WhitecapCoverage(outWhiteCapStr,jm.x,jSigma2);
//
// // compute and add whitecap radiance
// // float3 l = (atten * (max(dot(N, L), 0.0))) / M_PI;
// // float3 R_ftot = float3(W * l * 0.4);
//#endif
//float3 surfaceColor = (Lsun + Lsky + Lsea + R_ftot) * _LightColor0.rgb;
float3 surfaceColor = (Lsun + Lsky + Lsea) * _LightColor0.rgb;
float3 finalColor= surfaceColor;
return float4(hdr(finalColor,_ScatteringExposure), 1.0);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanWhiteCapsModProj3PixelLights.shader.meta
================================================
fileFormatVersion: 2
guid: 8a653817be39efa48bd2461f691b7249
timeCreated: 1474705423
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanWhiteCapsModProj3VertexSearch.shader
================================================
/*
* Proland: a procedural landscape rendering library.
* Copyright (c) 2008-2011 INRIA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* Proland is distributed under a dual-license scheme.
* You can obtain a specific license from Inria: proland-licensing@inria.fr.
*/
/*
* Authors: Eric Bruneton, Antoine Begault, Guillaume Piolat.
*/
/**
* Real-time Realistic Ocean Lighting using Seamless Transitions from Geometry to BRDF
* Copyright (c) 2009 INRIA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Author: Eric Bruneton
* Modified and ported to Unity by Justin Hawkins 2014
* Modified and adapted for use with Kerbal Space Program by Ghassen Lahmar 2015-2020
*/
Shader "Scatterer/OceanWhiteCapsVertexSearch"
{
SubShader
{
Tags { "Queue" = "Geometry+100"
"RenderType"="Transparent"
"IgnoreProjector"="True"}
Pass
{
Tags { "Queue" = "Geometry+100"
"RenderType"="Transparent"
"IgnoreProjector"="True"}
Blend SrcAlpha OneMinusSrcAlpha
Offset 0.0, -0.14
Cull Back
ZWrite [_ZwriteVariable]
CGPROGRAM
#include "UnityCG.cginc"
#pragma glsl
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
//#pragma multi_compile PLANETSHINE_OFF PLANETSHINE_ON
#pragma multi_compile SKY_REFLECTIONS_OFF SKY_REFLECTIONS_ON
#pragma multi_compile UNDERWATER_OFF UNDERWATER_ON
#pragma multi_compile OCEAN_SHADOWS_OFF OCEAN_SHADOWS_HARD OCEAN_SHADOWS_SOFT
#pragma multi_compile REFRACTIONS_AND_TRANSPARENCY_OFF REFRACTIONS_AND_TRANSPARENCY_ON
#pragma multi_compile SCATTERER_MERGED_DEPTH_ON SCATTERER_MERGED_DEPTH_OFF
#pragma multi_compile DITHERING_OFF DITHERING_ON
#pragma multi_compile GODRAYS_OFF GODRAYS_ON
//#pragma multi_compile SCATTERING_ON SCATTERING_OFF
#include "../CommonAtmosphere.cginc"
#include "../DepthCommon.cginc"
#if defined (OCEAN_SHADOWS_HARD) || defined (OCEAN_SHADOWS_SOFT)
#include "OceanShadows.cginc"
#endif
#include "OceanBRDF.cginc"
#include "OceanDisplacement3.cginc"
#include "OceanUtils.cginc"
#include "../ClippingUtils.cginc"
#include "../Atmo/Godrays/GodraysCommon.cginc"
uniform float offScreenVertexStretch;
uniform float4x4 _Globals_ScreenToCamera;
uniform float4x4 _Globals_CameraToWorld;
uniform float4x4 _Globals_WorldToScreen;
uniform float4x4 _Globals_CameraToScreen;
uniform float3 _Globals_WorldCameraPos;
uniform float4x4 _Globals_WorldToOcean;
uniform float4x4 _Globals_OceanToWorld;
uniform float3 _Sun_WorldSunDir;
uniform float2 _Ocean_MapSize;
uniform float4 _Ocean_Choppyness;
uniform float3 _Ocean_SunDir;
uniform float4 _Ocean_GridSizes;
uniform float2 _Ocean_ScreenGridSize;
uniform float _Ocean_WhiteCapStr;
uniform float farWhiteCapStr;
uniform float shoreFoam;
uniform sampler3D _Ocean_Variance;
uniform sampler2D _Ocean_Map0;
uniform sampler2D _Ocean_Map1;
uniform sampler2D _Ocean_Map2;
uniform sampler2D _Ocean_Map3;
uniform sampler2D _Ocean_Map4;
uniform sampler2D _Ocean_Foam0;
uniform sampler2D _Ocean_Foam1;
uniform float alphaRadius;
uniform float _PlanetOpacity; //to fade out the ocean when PQS is fading out
uniform float _ScatteringExposure;
uniform float _Alpha_Global;
uniform float _SkyExposure;
uniform float2 _VarianceMax;
uniform float darknessDepth;
uniform float3 _planetPos;
uniform float _openglThreshold;
uniform float _global_depth;
uniform float _global_alpha;
uniform float _Post_Extinction_Tint;
uniform float extinctionThickness;
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
uniform sampler2D ScattererScreenCopy; //background texture used for refraction
#endif
#if defined (GODRAYS_ON)
uniform sampler2D _godrayDepthTexture;
uniform float _godrayStrength;
#endif
#if defined (PLANETSHINE_ON)
uniform float4x4 planetShineSources;
uniform float4x4 planetShineRGB;
#endif
struct v2f
{
//float4 pos : SV_POSITION;
float2 oceanU : TEXCOORD0;
float3 oceanP : TEXCOORD1;
float4 screenPos : TEXCOORD2;
float4 worldPos : TEXCOORD3;
float4 viewPos :TEXCOORD4;
};
float2 SampleDisplacement(float2 oceanPos)
{
float2 displacement = 0;
displacement += _Ocean_Choppyness.x * tex2Dlod(_Ocean_Map3, float4(oceanPos / _Ocean_GridSizes.x,0.0, 0.0) ).xy;
displacement += _Ocean_Choppyness.y * tex2Dlod(_Ocean_Map3, float4(oceanPos / _Ocean_GridSizes.y,0.0, 0.0) ).zw;
displacement += _Ocean_Choppyness.z * tex2Dlod(_Ocean_Map4, float4(oceanPos / _Ocean_GridSizes.z,0.0, 0.0) ).xy;
displacement += _Ocean_Choppyness.w * tex2Dlod(_Ocean_Map4, float4(oceanPos / _Ocean_GridSizes.w,0.0, 0.0) ).zw;
return displacement;
}
v2f vert(appdata_base v, out float4 outpos: SV_POSITION)
{
float t;
float3 cameraDir, oceanDir;
float4 vert = v.vertex;
vert.xy *= offScreenVertexStretch;
float2 u = OceanPos(vert, _Globals_ScreenToCamera, t, cameraDir, oceanDir); //camera dir is viewing direction in camera space
float2 dux = OceanPos(vert + float4(_Ocean_ScreenGridSize.x, 0.0, 0.0, 0.0), _Globals_ScreenToCamera) - u;
float2 duy = OceanPos(vert + float4(0.0, _Ocean_ScreenGridSize.y, 0.0, 0.0), _Globals_ScreenToCamera) - u;
//instead of using this u, t and oceanDir, need to do a search for the oceanPos that when displaced gives me this position, then apply no displacement here only up
//knowing that you need dux and duy for every search step though is depressing
float3 dP = float3(0, 0, _Ocean_HeightOffset);
if(duy.x != 0.0 || duy.y != 0.0) //wtf is this condition even
{
//test all of these without tex2dgrad? I don't remember if they make a difference
//yep they do, a lot more shimmering without them
// dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).x;
// dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).y;
// dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).z;
// dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).w;
// //
// dP.xy += _Ocean_Choppyness.x * Tex2DGrad(_Ocean_Map3, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).xy;
// dP.xy += _Ocean_Choppyness.y * Tex2DGrad(_Ocean_Map3, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).zw;
// dP.xy += _Ocean_Choppyness.z * Tex2DGrad(_Ocean_Map4, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).xy;
// dP.xy += _Ocean_Choppyness.w * Tex2DGrad(_Ocean_Map4, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).zw;
// dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.x, 0.0, 0.0)).x;
// dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.y, 0.0, 0.0)).y;
// dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.z, 0.0, 0.0)).z;
// dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.w, 0.0, 0.0)).w;
//
// dP.xy += _Ocean_Choppyness.x * tex2Dlod(_Ocean_Map3, float4( u / _Ocean_GridSizes.x, 0.0, 0.0)).xy;
// dP.xy += _Ocean_Choppyness.y * tex2Dlod(_Ocean_Map3, float4( u / _Ocean_GridSizes.y, 0.0, 0.0)).zw;
// dP.xy += _Ocean_Choppyness.z * tex2Dlod(_Ocean_Map4, float4( u / _Ocean_GridSizes.z, 0.0, 0.0)).xy;
// dP.xy += _Ocean_Choppyness.w * tex2Dlod(_Ocean_Map4, float4( u / _Ocean_GridSizes.w, 0.0, 0.0)).zw;
}
float precisionRequired = 0.00;
float2 currentPosition = u;
float2 displacement = SampleDisplacement (currentPosition);
float2 resultingPosition = currentPosition + displacement;
for (int i = 0; i < 50; i++)
{
if (length(resultingPosition - u) <= precisionRequired)
break;
float2 newPosition = currentPosition - (resultingPosition - u);
float2 newDisplacement = SampleDisplacement (newPosition);
float2 newResultingPosition = newPosition + newDisplacement;
currentPosition = newPosition;
resultingPosition = newResultingPosition;
}
u = currentPosition; //t, cameraDir and oceanDir need to be recalculated here
// dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.x, 0.0, 0.0)).x;
// dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.y, 0.0, 0.0)).y;
// dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.z, 0.0, 0.0)).z;
// dP.z += tex2Dlod(_Ocean_Map0, float4( u / _Ocean_GridSizes.w, 0.0, 0.0)).w;
//HACK, dux and duy no longer match u but might end up looking ok still
dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.x, dux / _Ocean_GridSizes.x, duy / _Ocean_GridSizes.x, _Ocean_MapSize).x;
dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.y, dux / _Ocean_GridSizes.y, duy / _Ocean_GridSizes.y, _Ocean_MapSize).y;
dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.z, dux / _Ocean_GridSizes.z, duy / _Ocean_GridSizes.z, _Ocean_MapSize).z;
dP.z += Tex2DGrad(_Ocean_Map0, u / _Ocean_GridSizes.w, dux / _Ocean_GridSizes.w, duy / _Ocean_GridSizes.w, _Ocean_MapSize).w;
//still can see edges somehow?
//even though only displacing up can still see edges, need the stuff that is behind the camera to be displaced up to come into view when tilted
//need the projector to cover from the camera position to where it's far plane intersects the horizon (you know what I mean)
//then combine that with my search method (though it seems buggy here somehow?)
v2f OUT;
float3x3 otoc = _Ocean_OceanToCamera;
float tClamped = clamp(t*0.25, 0.0, 1.0);
#if defined (UNDERWATER_ON)
dP = lerp(float3(0.0,0.0,0.1),dP,tClamped); //prevents projected grid intersecting near plane
#else
dP = lerp(float3(0.0,0.0,-0.1),dP,tClamped); //prevents projected grid intersecting near plane
#endif
// float4 screenP = float4(t * cameraDir + mul(otoc, dP), 1.0); //position in camera space
// float3 oceanP = t * oceanDir + dP + float3(0.0, 0.0, _Ocean_CameraPos.z);
float3 oceanP = float3(u-_Ocean_CameraPos.xy, dP.z);
float4 screenP = mul(_Ocean_OceanToCamera, float4(oceanP,1.0)); //position in camera space
outpos = mul(UNITY_MATRIX_P, screenP);
OUT.oceanU = u;
OUT.oceanP = oceanP;
OUT.screenPos = ComputeScreenPos(outpos);
OUT.worldPos=mul(_Globals_CameraToWorld , screenP);
OUT.viewPos = screenP;
outpos = (_PlanetOpacity == 0.0) ? float4(2.0, 2.0, 2.0, 1.0) : outpos; //cull when completely transparent
return OUT;
}
float4 frag(v2f IN, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target
{
float3 L = _Ocean_SunDir;
float radius = _Ocean_Radius;
float2 u = IN.oceanU;
float3 oceanP = IN.oceanP;
float3 oceanCamera = float3(0.0, 0.0, _Ocean_CameraPos.z);
float3 V = normalize(oceanCamera - oceanP);
float2 slopes = float2(0,0);
slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.x).xy;
slopes += tex2D(_Ocean_Map1, u / _Ocean_GridSizes.y).zw;
slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.z).xy;
slopes += tex2D(_Ocean_Map2, u / _Ocean_GridSizes.w).zw;
slopes -= oceanP.xy / (radius + oceanP.z);
float3 N = normalize(float3(-slopes.x, -slopes.y, 1.0));
float Jxx = ddx(u.x);
float Jxy = ddy(u.x);
float Jyx = ddx(u.y);
float Jyy = ddy(u.y);
float A = Jxx * Jxx + Jyx * Jyx;
float B = Jxx * Jxy + Jyx * Jyy;
float C = Jxy * Jxy + Jyy * Jyy;
const float SCALE = 10.0;
float ua = pow(A / SCALE, 0.25);
float ub = 0.5 + 0.5 * B / sqrt(A * C);
float uc = pow(C / SCALE, 0.25);
float sigmaSq = tex3D(_Ocean_Variance, float3(ua, ub, uc)).x * _VarianceMax.x;
sigmaSq = max(sigmaSq, 2e-5);
// extract mean and variance of the jacobian matrix determinant
float2 jm1 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.x).xy;
float2 jm2 = tex2D(_Ocean_Foam0, u / _Ocean_GridSizes.y).zw;
float2 jm3 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.z).xy;
float2 jm4 = tex2D(_Ocean_Foam1, u / _Ocean_GridSizes.w).zw;
float2 jm = jm1+jm2+jm3+jm4;
float jSigma2 = max(jm.y - (jm1.x*jm1.x + jm2.x*jm2.x + jm3.x*jm3.x + jm4.x*jm4.x), 0.0);
float3 earthP = normalize(oceanP + float3(0.0, 0.0, radius)) * (radius + 10.0);
float3 sunL, skyE, Lsky;
SunRadianceAndSkyIrradiance(earthP, N, L, _sunColor, sunL, skyE); //only thing I can think of that could potebtially be moved to vertex shader without a significant loss of quality?
half shadowTerm = 1.0;
#if defined (OCEAN_SHADOWS_HARD) || defined (OCEAN_SHADOWS_SOFT)
shadowTerm = getOceanShadow (IN.worldPos, -IN.viewPos.z);
#endif
float fresnel = getFresnel(V, N, sigmaSq);
Lsky = getSkyColor(fresnel, V, N, L, earthP, skyE, shadowTerm, radius, _sunColor, 1.0);
float3 Lsea = getOceanColor(fresnel, V, N, L, earthP, skyE, shadowTerm, _sunColor);
float oceanDistance = length(IN.viewPos);
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
float fragDistance, depth;
float2 uv = getPerturbedUVsAndDepth(IN.screenPos.xy / IN.screenPos.w, N, oceanDistance, fragDistance, depth);
_Ocean_WhiteCapStr = adjustWhiteCapStrengthWithDepth(_Ocean_WhiteCapStr, shoreFoam, depth);
float transparencyAlpha = getTransparencyAlpha(depth);
#else
float transparencyAlpha=1.0;
#endif
float outWhiteCapStr=applyFarWhiteCapStrength(oceanDistance, alphaRadius, _Ocean_WhiteCapStr, farWhiteCapStr);
float3 R_ftot = getTotalWhiteCapRadiance(outWhiteCapStr, jm.x, jSigma2, sunL, N, L, skyE, shadowTerm, 1.0);
float3 Lsun = ReflectedSunRadiance(L, V, N, sigmaSq) * sunL * shadowTerm;
#if defined (UNDERWATER_ON)
float3 surfaceColor = hdr(abs(Lsea + R_ftot),_ScatteringExposure);
#else
float3 surfaceColor = hdr(abs(Lsun + Lsea + R_ftot),_ScatteringExposure);
Lsky = _Alpha_Global*hdr(Lsky,_SkyExposure);
surfaceColor = surfaceColor + (1.0-surfaceColor) * Lsky;
#endif
float3 LsunTotal = Lsun; float3 R_ftotTotal = R_ftot; float3 LseaTotal = Lsea; float3 LskyTotal = Lsky;
// #if defined (PLANETSHINE_ON)
//
// getPlanetShineContribution(LsunTotal, R_ftotTotal, LseaTotal, LskyTotal);
// #endif
bool insideClippingRange = oceanFragmentInsideOfClippingRange(-IN.viewPos.z/IN.viewPos.w);
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
transparencyAlpha = max(hdr(LsunTotal + R_ftotTotal,_ScatteringExposure), fresnel+transparencyAlpha) ; //seems about perfect
transparencyAlpha = min(transparencyAlpha, 1.0);
#if SHADER_API_D3D11 || SHADER_API_D3D9 || SHADER_API_D3D || SHADER_API_D3D12
float3 backGrnd = tex2D(ScattererScreenCopy, (_ProjectionParams.x == 1.0) ? float2(uv.x,1.0-uv.y): uv );
#else
float3 backGrnd = tex2D(ScattererScreenCopy, uv );
#endif
#endif
#if defined (UNDERWATER_ON)
Lsky = _Alpha_Global*hdr(Lsky,_SkyExposure);
float3 transmittance = hdr(R_ftot, _ScatteringExposure);
transmittance = clamp(transmittance, float3(0.0,0.0,0.0), float3(1.0,1.0,1.0));
transmittance = transmittance + (1.0-transmittance) * Lsky;
float3 finalColor = lerp(transmittance,Lsea, 1-fresnel); //consider not using transmittance but instead background texture, change the refraction angle to have something matching what you would see from underwater
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
backGrnd+=hdr(R_ftotTotal,_ScatteringExposure)*(1-backGrnd); //make foam visible from below as well
finalColor = (fragDistance < 750000.0) ? backGrnd : finalColor;
#endif
float3 Vworld = mul ( _Globals_OceanToWorld, float4(V,0.0));
float3 Lworld = mul ( _Globals_OceanToWorld, float4(L,0.0));
float3 earthCamPos = normalize(float3(_Ocean_CameraPos.xy,0.0) + float3(0.0, 0.0, radius)) * (radius + 10.0);
float underwaterDepth = lerp(1.0,0.0,-_Ocean_CameraPos.z / darknessDepth);
float waterLightExtinction = length(getSkyExtinction(earthCamPos, L));
float3 _camPos = _WorldSpaceCameraPos - _planetPos;
float3 oceanCol = underwaterDepth * hdrNoExposure(waterLightExtinction * _sunColor * oceanColor(-Vworld,Lworld,normalize(_camPos))); //add planetshine loop here over Ls
finalColor= clamp(finalColor, float3(0.0,0.0,0.0),float3(1.0,1.0,1.0));
finalColor= lerp(finalColor, oceanCol, min(length(oceanCamera - oceanP)/transparencyDepth,1.0));
return float4(dither(finalColor, screenPos),insideClippingRange);
#else
#if defined (REFRACTIONS_AND_TRANSPARENCY_ON)
float3 finalColor = lerp(backGrnd, surfaceColor, transparencyAlpha); //refraction on and not underwater
#else
float3 finalColor = surfaceColor; //refraction off and not underwater
#endif
if (_PlanetOpacity == 1.0)
{
float3 worldPos= IN.worldPos - _planetPos;
worldPos = (length(worldPos) < (Rg + _openglThreshold)) ? (Rg + _openglThreshold) * normalize(worldPos) : worldPos ; //artifacts fix
float3 _camPos = _WorldSpaceCameraPos - _planetPos;
float minDistance = length(worldPos-_camPos);
#if defined (GODRAYS_ON)
float2 godrayUV = IN.screenPos.xy / IN.screenPos.w;
float godrayDepth = 0.0;
godrayDepth = sampleGodrayDepth(_godrayDepthTexture, godrayUV, 1.0);
//trying to find the optical depth from the terrain level
float muTerrain = dot(normalize(worldPos), normalize(_camPos - worldPos));
godrayDepth = _godrayStrength * DistanceFromOpticalDepth((Rt-Rg) * 0.5, length(worldPos), muTerrain, godrayDepth, minDistance);
worldPos = worldPos - godrayDepth * normalize(worldPos-_camPos);
#endif
float3 inscatter=0.0;float3 extinction=1.0;
inscatter = InScattering(_camPos, worldPos, SUN_DIR, _sunColor, extinction);
inscatter*= (minDistance <= _global_depth) ? (1 - exp(-1 * (4 * minDistance / _global_depth))) : 1.0 ; //somehow the shader compiler for OpenGL behaves differently around braces
inscatter = hdr(inscatter,_ScatteringExposure) *_global_alpha;
float average=(extinction.r+extinction.g+extinction.b)/3;
//lerped manually because of an issue with opengl or whatever
extinction = _Post_Extinction_Tint * extinction + (1-_Post_Extinction_Tint) * float3(average,average,average);
extinction= max(float3(0.0,0.0,0.0), (float3(1.0,1.0,1.0)*(1-extinctionThickness) + extinctionThickness*extinction) );
finalColor*= extinction;
finalColor = inscatter*(1-finalColor) + finalColor;
}
insideClippingRange = (transparencyAlpha == 1.0) ? 1.0 : insideClippingRange; //if no transparency -> render normally, if transparency play with the overlap to hide seams between cameras
return float4(dither(finalColor,screenPos), _PlanetOpacity*insideClippingRange);
#endif
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/OceanWhiteCapsModProj3VertexSearch.shader.meta
================================================
fileFormatVersion: 2
guid: 1a7a541ac0259ac4e8570ac8c3510dfe
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/ReadData.compute
================================================
//NOTE - Not every kernel has been tested
uint _Width;
uint _Height;
uint _Depth;
uint _IdxX;
uint _IdxY;
uint _IdxZ;
float4 _UV;
Texture2D _Tex2D;
Texture3D _Tex3D;
SamplerState _LinearClamp;
//-----------------------------------------------------------------------//
//-- read from 1 channel 2D render texture --//
#pragma kernel read2DC1
RWStructuredBuffer _Buffer2DC1;
[numthreads(8,8,1)]
void read2DC1(uint3 id : SV_DispatchThreadID)
{
int idx = id.x + id.y * _Width;
if(id.x < _Width && id.y < _Height)
_Buffer2DC1[idx] = _Tex2D[id.xy].x;
}
//-- read from 2 channel 2D render texture --//
#pragma kernel read2DC2
RWStructuredBuffer _Buffer2DC2;
[numthreads(8,8,1)]
void read2DC2(uint3 id : SV_DispatchThreadID)
{
int idx = id.x + id.y * _Width;
if(id.x < _Width && id.y < _Height)
_Buffer2DC2[idx] = _Tex2D[id.xy].xy;
}
//-- read from 3 channel 2D render texture --//
#pragma kernel read2DC3
RWStructuredBuffer _Buffer2DC3;
[numthreads(8,8,1)]
void read2DC3(uint3 id : SV_DispatchThreadID)
{
int idx = id.x + id.y * _Width;
if(id.x < _Width && id.y < _Height)
_Buffer2DC3[idx] = _Tex2D[id.xy].xyz;
}
//-- read from 4 channel 2D render texture --//
#pragma kernel read2DC4
RWStructuredBuffer _Buffer2DC4;
[numthreads(8,8,1)]
void read2DC4(uint3 id : SV_DispatchThreadID)
{
int idx = id.x + id.y * _Width;
if(id.x < _Width && id.y < _Height)
_Buffer2DC4[idx] = _Tex2D[id.xy];
}
//-- read single pixel from 2D render texure. Always reads all 4 channes --//
#pragma kernel readSingle2D
RWStructuredBuffer _BufferSingle2D;
[numthreads(1,1,1)]
void readSingle2D(uint3 id : SV_DispatchThreadID)
{
_BufferSingle2D[0] = _Tex2D[uint2(_IdxX,_IdxY)];
}
//-- read single pixel from 2D render texure using bilinear filtering. Always reads all 4 channes --//
#pragma kernel readSingleBilinear2D
[numthreads(1,1,1)]
void readSingleBilinear2D(uint3 id : SV_DispatchThreadID)
{
_BufferSingle2D[0] = _Tex2D.SampleLevel(_LinearClamp, _UV.xy, 0);
}
//-----------------------------------------------------------------------//
//-- read from 1 channel 3D render texture --//
#pragma kernel read3DC1
RWStructuredBuffer _Buffer3DC1;
[numthreads(8,8,8)]
void read3DC1(uint3 id : SV_DispatchThreadID)
{
int idx = id.x + id.y * _Width + id.z * _Width * _Height;
if(id.x < _Width && id.y < _Height && id.z < _Depth)
_Buffer3DC1[idx] = _Tex3D[id].x;
}
//-- read from 2 channel 3D render texture --//
#pragma kernel read3DC2
RWStructuredBuffer _Buffer3DC2;
[numthreads(8,8,8)]
void read3DC2(uint3 id : SV_DispatchThreadID)
{
int idx = id.x + id.y * _Width + id.z * _Width * _Height;
if(id.x < _Width && id.y < _Height && id.z < _Depth)
_Buffer3DC2[idx] = _Tex3D[id].xy;
}
//-- read from 3 channel 3D render texture --//
#pragma kernel read3DC3
RWStructuredBuffer _Buffer3DC3;
[numthreads(8,8,8)]
void read3DC3(uint3 id : SV_DispatchThreadID)
{
int idx = id.x + id.y * _Width + id.z * _Width * _Height;
if(id.x < _Width && id.y < _Height && id.z < _Depth)
_Buffer3DC3[idx] = _Tex3D[id].xyz;
}
//-- read from 4 channel 3D render texture --//
#pragma kernel read3DC4
RWStructuredBuffer _Buffer3DC4;
[numthreads(8,8,8)]
void read3DC4(uint3 id : SV_DispatchThreadID)
{
int idx = id.x + id.y * _Width + id.z * _Width * _Height;
if(id.x < _Width && id.y < _Height && id.z < _Depth)
_Buffer3DC4[idx] = _Tex3D[id];
}
//-- read single pixel from 3D render texure. Always reads all 4 channes --//
#pragma kernel readSingle3D
RWStructuredBuffer _BufferSingle3D;
[numthreads(1,1,1)]
void readSingle3D(uint3 id : SV_DispatchThreadID)
{
_BufferSingle3D[0] = _Tex3D[uint3(_IdxX,_IdxY,_IdxZ)];
}
//-- read single pixel from 3D render texure using bilinear filtering. Always reads all 4 channes --//
#pragma kernel readSingleBilinear3D
[numthreads(1,1,1)]
void readSingleBilinear3D(uint3 id : SV_DispatchThreadID)
{
_BufferSingle3D[0] = _Tex3D.SampleLevel(_LinearClamp, _UV.xyz, 0);
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/ReadData.compute.meta
================================================
fileFormatVersion: 2
guid: ecc396d20671d454e8020aa864197779
ComputeShaderImporter:
externalObjects: {}
currentAPIMask: 4
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/SlopeVariance.compute
================================================
#pragma kernel CSMain
Texture2D _Spectrum01;
Texture2D _Spectrum23;
float4 _GridSizes;
float _SlopeVarianceDelta;
float _Size;
float _VarianceSize;
RWTexture3D des;
float getSlopeVariances(float2 k, float A, float B, float C, float2 spectrumSample)
{
float w = 1.0 - exp(A * k.x * k.x + B * k.x * k.y + C * k.y * k.y);
float2 kw = k * w;
return dot(kw, kw) * dot(spectrumSample, spectrumSample) * 2.0;
}
[numthreads(4,4,4)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
const float SCALE = 10.0;
const float M_PI = 3.14159265;
float a = id.x;
float b = id.y;
float c = id.z;
float A = pow(a / (_VarianceSize - 1.0), 4.0) * SCALE;
float C = pow(c / (_VarianceSize - 1.0), 4.0) * SCALE;
float B = (2.0 * b / (_VarianceSize - 1.0) - 1.0) * sqrt(A * C);
A = -0.5 * A;
B = -B;
C = -0.5 * C;
float slopeVariances = _SlopeVarianceDelta;
int size = _Size;
for (int x = 0; x < size; x++)
{
for (int y = 0; y < size; y++)
{
int i = x >= _Size / 2.0 ? x - size : x;
int j = y >= _Size / 2.0 ? y - size : y;
float2 k = 2.0 * M_PI * float2(i, j);
float4 spectrum01 = _Spectrum01[uint2(x,y)];
float4 spectrum23 = _Spectrum23[uint2(x,y)];
slopeVariances += getSlopeVariances(k / _GridSizes.x, A, B, C, spectrum01.xy);
slopeVariances += getSlopeVariances(k / _GridSizes.y, A, B, C, spectrum01.zw);
slopeVariances += getSlopeVariances(k / _GridSizes.z, A, B, C, spectrum23.xy);
slopeVariances += getSlopeVariances(k / _GridSizes.w, A, B, C, spectrum23.zw);
}
}
des[id] = slopeVariances;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/SlopeVariance.compute.meta
================================================
fileFormatVersion: 2
guid: 7004c8cc6d477784e8d85fbad56de5f8
ComputeShaderImporter:
externalObjects: {}
currentAPIMask: 131076
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/UnderwaterDepthBuffer.shader
================================================
Shader "Scatterer/UnderwaterScatterDepthBuffer" {
SubShader {
Tags {"Queue" = "Transparent-499" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
Pass {
Cull Off
ZTest Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
#include "../CommonAtmosphere.cginc"
#include "../DepthCommon.cginc"
uniform sampler2D ScattererScreenCopy;
uniform sampler2D ScattererDepthCopy;
float4x4 CameraToWorld;
#pragma multi_compile DITHERING_OFF DITHERING_ON
uniform float3 _planetPos;
uniform float3 _Underwater_Color;
uniform float transparencyDepth;
uniform float darknessDepth;
struct v2f
{
float4 screenPos : TEXCOORD0;
float waterLightExtinction : TEXCOORD1;
};
v2f vert(appdata_base v, out float4 outpos: SV_POSITION)
{
v2f o;
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)
outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y *_ProjectionParams.x, -1.0 , 1.0);
#else
outpos = float4(2.0 * v.vertex.x, 2.0 * v.vertex.y, 0.0 , 1.0);
#endif
o.screenPos = ComputeScreenPos(outpos);
float3 _camPos = _WorldSpaceCameraPos - _planetPos;
o.waterLightExtinction = length(getSkyExtinction(normalize(_camPos + 10.0) * Rg , SUN_DIR));
return o;
}
float3 oceanColor(float3 viewDir, float3 lightDir, float3 surfaceDir)
{
float angleToLightDir = (dot(viewDir, surfaceDir) + 1 )* 0.5;
float3 waterColor = pow(_Underwater_Color, 4.0 *(-1.0 * angleToLightDir + 1.0));
return waterColor;
}
struct fout
{
float4 color : COLOR;
float depth : DEPTH;
};
fout frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS)
{
float2 uv = i.screenPos.xy / i.screenPos.w;
#if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12
if (_ProjectionParams.x > 0) {uv.y = 1.0 - uv.y;}
#endif
float zdepth = tex2Dlod(ScattererDepthCopy, float4(uv,0,0));
float3 worldPosRelCam = getPreciseWorldPosFromDepth(i.screenPos.xy / i.screenPos.w, zdepth, CameraToWorld) - _WorldSpaceCameraPos;
float fragDistance = length(worldPosRelCam);
float3 worldViewDir = worldPosRelCam / fragDistance;
float3 _camPos = _WorldSpaceCameraPos - _planetPos;
float underwaterDepth = Rg - length(_camPos);
underwaterDepth = lerp(1.0,0.0,underwaterDepth / darknessDepth);
float3 waterColor= underwaterDepth * hdrNoExposure(i.waterLightExtinction * _sunColor * oceanColor(worldViewDir,SUN_DIR,normalize(_camPos)));
float alpha = min(fragDistance/transparencyDepth,1.0);
float3 backGrnd = tex2Dlod(ScattererScreenCopy, float4(uv.x, uv.y,0.0,0.0));
backGrnd = dither(waterColor, screenPos) * alpha + (1.0 - alpha) * backGrnd;
fout output;
output.color = float4(backGrnd,1.0);
output.depth = zdepth;
return output;
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/UnderwaterDepthBuffer.shader.meta
================================================
fileFormatVersion: 2
guid: a132bd53f9677ee489dac2f1da2b05ea
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/UnderwaterProjector.shader
================================================
Shader "Scatterer/UnderwaterScatterProjector" {
SubShader {
Tags {"Queue" = "Transparent-5" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
Pass {
//Cull Front
Cull Back
ZTest LEqual
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
#include "../CommonAtmosphere.cginc"
#pragma multi_compile DITHERING_OFF DITHERING_ON
uniform float3 _planetPos;
uniform float3 _Underwater_Color;
uniform float transparencyDepth;
uniform float darknessDepth;
struct v2f
{
float3 viewPos:TEXCOORD0;
float3 viewDir:TEXCOORD1;
float3 worldPos:TEXCOORD2;
};
v2f vert(appdata_base v, out float4 outpos: SV_POSITION)
{
v2f o;
outpos = UnityObjectToClipPos(v.vertex);
o.viewPos = UnityObjectToViewPos(v.vertex.xyz);
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
o.viewDir = o.worldPos - _WorldSpaceCameraPos;
o.worldPos = o.worldPos - _planetPos;
return o;
}
float3 oceanColor(float3 viewDir, float3 lightDir, float3 surfaceDir)
{
float angleToLightDir = (dot(viewDir, surfaceDir) + 1 )* 0.5;
float3 waterColor = pow(_Underwater_Color, 4.0 *(-1.0 * angleToLightDir + 1.0));
return waterColor;
}
half4 frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target
{
float fragDistance = length(i.viewPos);
float3 rayDir=normalize(i.viewDir);
float3 _camPos = _WorldSpaceCameraPos - _planetPos;
float waterLightExtinction = length(getSkyExtinction(normalize(_camPos + 10.0) * Rg , SUN_DIR));
float underwaterDepth = Rg - length(_camPos);
underwaterDepth = lerp(1.0,0.0,underwaterDepth / darknessDepth);
float3 waterColor= underwaterDepth * hdrNoExposure( waterLightExtinction * _sunColor * oceanColor(rayDir,SUN_DIR,normalize(_camPos)));
float alpha = min(fragDistance/transparencyDepth,1.0);
return float4(dither(waterColor, screenPos), alpha);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/UnderwaterProjector.shader.meta
================================================
fileFormatVersion: 2
guid: f1c6f7ed858be004eb1c56dada7ee838
timeCreated: 1550574813
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/WhiteCapsPrecompute0.shader
================================================
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Proland/Ocean/WhiteCapsPrecompute0"
{
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#include "UnityCG.cginc"
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _Map5, _Map6, _Map7;
uniform float4 _Choppyness;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
OUT.uv = v.texcoord;
return OUT;
}
float4 frag(v2f IN): COLOR
{
float2 uv = IN.uv;
// store Jacobian coeff value and variance
float4 Jxx = _Choppyness*tex2D(_Map5, uv);
float4 Jyy = _Choppyness*tex2D(_Map6, uv);
float4 Jxy = _Choppyness*_Choppyness*tex2D(_Map7, uv);
// Store partial jacobians
float4 res = 0.25 + Jxx + Jyy + _Choppyness*Jxx*Jyy - Jxy*Jxy;
float4 res2 = res*res;
float4 col0 = float4(res.x, res2.x, res.y, res2.y);
// OUT.col1 = float4(res.z, res2.z, res.w, res2.w);
return col0;
}
ENDCG
}
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#include "UnityCG.cginc"
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _Map5, _Map6, _Map7;
uniform float4 _Choppyness;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
OUT.uv = v.texcoord;
return OUT;
}
float4 frag(v2f IN): COLOR
{
float2 uv = IN.uv;
// store Jacobian coeff value and variance
float4 Jxx = _Choppyness*tex2D(_Map5, uv);
float4 Jyy = _Choppyness*tex2D(_Map6, uv);
float4 Jxy = _Choppyness*_Choppyness*tex2D(_Map7, uv);
// Store partial jacobians
float4 res = 0.25 + Jxx + Jyy + _Choppyness*Jxx*Jyy - Jxy*Jxy;
float4 res2 = res*res;
// float4 col0 = float4(res.x, res2.x, res.y, res2.y);
float4 col1 = float4(res.z, res2.z, res.w, res2.w);
return col1;
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean/WhiteCapsPrecompute0.shader.meta
================================================
fileFormatVersion: 2
guid: 725600e98a048ad46aacb96a8bb155cd
timeCreated: 1459689357
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Ocean.meta
================================================
fileFormatVersion: 2
guid: 1cd98b0d17936ed43bed805e1a150a88
folderAsset: yes
timeCreated: 1541842604
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/RingCommon.cginc
================================================
uniform sampler2D ringTexture;
uniform float ringInnerRadius;
uniform float ringOuterRadius;
uniform float3 ringNormal;
//only supporting Kopernicus linear rings for now (no support for tiled rings or rings with thickness)
//rgb channels are returned modulated by alpha value (used for sunflare)
//alpha value returned is actually 1-alpha (used for ring shadow on atmosphere/planet)
inline float4 getLinearRingColor(float3 worldPos, float3 sunDir, float3 planetAndRingOrigin)
{
float parallel = 0.0;
float3 ringIntersectPt = LinePlaneIntersection(worldPos, sunDir, ringNormal, planetAndRingOrigin, parallel);
//calculate ring texture position on intersect
float distance = length (ringIntersectPt - planetAndRingOrigin);
float ringTexturePosition = (distance - ringInnerRadius) / (ringOuterRadius - ringInnerRadius); //inner and outer radiuses are converted to local space coords on plugin side
ringTexturePosition = 1 - ringTexturePosition; //flip to match UVs
float4 ringColor = tex2D(ringTexture, float2(ringTexturePosition,ringTexturePosition));
ringColor.a = 1-ringColor.a;
ringColor.xyz*=ringColor.a;
//don't apply any shadows if intersect point is not between inner and outer radius or line and plane are parallel
ringColor = (ringTexturePosition > 1 || ringTexturePosition < 0 || parallel == 1.0 ) ? float4(1.0,1.0,1.0,1.0) : ringColor;
return ringColor;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/RingCommon.cginc.meta
================================================
fileFormatVersion: 2
guid: 29b7e99efaf64b949afd3d5b830c72aa
timeCreated: 1542896604
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/RingCommon.cgincBAK
================================================
uniform sampler2D ringTexture;
uniform float ringInnerRadius;
uniform float ringOuterRadius;
uniform float3 ringNormal;
//only supporting Kopernicus linear rings for now (no support for tiled rings or rings with thickness)
//rgb channels are returned modulated by alpha value (used for sunflare)
//alpha value returned is actually 1-alpha (used for ring shadow on atmosphere/planet)
inline float4 getLinearRingColor(float3 worldPos, float3 sunDir, float3 planetAndRingOrigin)
{
float parallel = 0.0;
float3 ringIntersectPt = LinePlaneIntersection(worldPos, sunDir, ringNormal, planetAndRingOrigin, parallel);
//calculate ring texture position on intersect
float distance = length (ringIntersectPt - planetAndRingOrigin);
float ringTexturePosition = (distance - ringInnerRadius) / (ringOuterRadius - ringInnerRadius); //inner and outer radiuses are converted to local space coords on plugin side
ringTexturePosition = 1 - ringTexturePosition; //flip to match UVs
float4 ringColor = tex2D(ringTexture, float2(ringTexturePosition,ringTexturePosition));
ringColor.a = 1-ringColor.a;
ringColor.xyz*=ringColor.a;
//don't apply any shadows if intersect point is not between inner and outer radius or line and plane are parallel
ringColor = (ringTexturePosition > 1 || ringTexturePosition < 0 || parallel == 1.0 ) ? float4(1.0,1.0,1.0,1.0) : ringColor;
return ringColor;
}
inline float4 getLinearRingColorLod0(float3 worldPos, float3 sunDir, float3 planetAndRingOrigin)
{
float parallel = 0.0;
float3 ringIntersectPt = LinePlaneIntersection(worldPos, sunDir, ringNormal, planetAndRingOrigin, parallel);
//calculate ring texture position on intersect
float distance = length (ringIntersectPt - planetAndRingOrigin);
float ringTexturePosition = (distance - ringInnerRadius) / (ringOuterRadius - ringInnerRadius); //inner and outer radiuses are converted to local space coords on plugin side
ringTexturePosition = 1 - ringTexturePosition; //flip to match UVs
float4 ringColor = tex2Dlod(ringTexture, float4(ringTexturePosition,ringTexturePosition,0.0,0.0));
ringColor.a = 1-ringColor.a;
ringColor.xyz*=ringColor.a;
//don't apply any shadows if intersect point is not between inner and outer radius or line and plane are parallel
ringColor = (ringTexturePosition > 1 || ringTexturePosition < 0 || parallel == 1.0 ) ? float4(1.0,1.0,1.0,1.0) : ringColor;
return ringColor;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/RingCommon.cgincBAK.meta
================================================
fileFormatVersion: 2
guid: 5b60206b4b7ac1043ba19efe7ecfd5be
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/DoublePrecisionEmulation.cginc
================================================
float times_frc(float a, float b) {
return lerp(0.0, a * b, b != 0.0 ? 1.0 : 0.0);
}
float div_frc(float a, float b) {
return lerp(0.0, a / b, b != 0.0 ? 1.0 : 0.0);
}
float plus_frc(float a, float b) {
return lerp(a, a + b, b != 0.0 ? 1.0 : 0.0);
}
float minus_frc(float a, float b) {
return lerp(a, a - b, b != 0.0 ? 1.0 : 0.0);
}
// create double-single number from float
float2 ds_set(float a) {
return float2(a, 0.0);
}
// Double emulation based on GLSL Mandelbrot Shader by Henry Thasler (www.thasler.org/blog)
//
// Emulation based on Fortran-90 double-single package. See http://crd.lbl.gov/~dhbailey/mpdist/
// Substract: res = ds_add(a, b) => res = a + b
float2 ds_add (float2 dsa, float2 dsb) {
float2 dsc;
float t1, t2, e;
t1 = plus_frc(dsa.x, dsb.x);
e = minus_frc(t1, dsa.x);
t2 = plus_frc(plus_frc(plus_frc(minus_frc(dsb.x, e), minus_frc(dsa.x, minus_frc(t1, e))), dsa.y), dsb.y);
dsc.x = plus_frc(t1, t2);
dsc.y = minus_frc(t2, minus_frc(dsc.x, t1));
return dsc;
}
// Substract: res = ds_sub(a, b) => res = a - b
float2 ds_sub (float2 dsa, float2 dsb) {
float2 dsc;
float e, t1, t2;
t1 = minus_frc(dsa.x, dsb.x);
e = minus_frc(t1, dsa.x);
t2 = minus_frc(plus_frc(plus_frc(minus_frc(minus_frc(0.0, dsb.x), e), minus_frc(dsa.x, minus_frc(t1, e))), dsa.y), dsb.y);
dsc.x = plus_frc(t1, t2);
dsc.y = minus_frc(t2, minus_frc(dsc.x, t1));
return dsc;
}
// Compare: res = -1 if a < b
// = 0 if a == b
// = 1 if a > b
float ds_cmp(float2 dsa, float2 dsb) {
if (dsa.x < dsb.x) {
return -1.;
}
if (dsa.x > dsb.x) {
return 1.;
}
if (dsa.y < dsb.y) {
return -1.;
}
if (dsa.y > dsb.y) {
return 1.;
}
return 0.;
}
// Multiply: res = ds_mul(a, b) => res = a * b
float2 ds_mul (float2 dsa, float2 dsb) {
float2 dsc;
float c11, c21, c2, e, t1, t2;
float a1, a2, b1, b2, cona, conb, split = 8193.;
cona = times_frc(dsa.x, split);
conb = times_frc(dsb.x, split);
a1 = minus_frc(cona, minus_frc(cona, dsa.x));
b1 = minus_frc(conb, minus_frc(conb, dsb.x));
a2 = minus_frc(dsa.x, a1);
b2 = minus_frc(dsb.x, b1);
c11 = times_frc(dsa.x, dsb.x);
c21 = plus_frc(times_frc(a2, b2), plus_frc(times_frc(a2, b1), plus_frc(times_frc(a1, b2), minus_frc(times_frc(a1, b1), c11))));
c2 = plus_frc(times_frc(dsa.x, dsb.y), times_frc(dsa.y, dsb.x));
t1 = plus_frc(c11, c2);
e = minus_frc(t1, c11);
t2 = plus_frc(plus_frc(times_frc(dsa.y, dsb.y), plus_frc(minus_frc(c2, e), minus_frc(c11, minus_frc(t1, e)))), c21);
dsc.x = plus_frc(t1, t2);
dsc.y = minus_frc(t2, minus_frc(dsc.x, t1));
return dsc;
}
// Divide: res = ds_div(a, b) => res = a / b
float2 ds_div (float2 dsa, float2 dsb) {
float2 dsc;
float a1, a2, b1, b2, cona, conb, split = 8193.;
float c11, c2, c21, e, s1, s2, t1, t2, t11, t12, t21, t22;
s1 = div_frc(dsa.x,dsb.x);
cona = times_frc(s1, split);
conb = times_frc(dsb.x, split);
a1 = minus_frc(cona, minus_frc(cona, s1));
b1 = minus_frc(conb, minus_frc(conb, dsb.x));
a2 = minus_frc(s1, a1);
b2 = minus_frc(dsb.x, b1);
c11 = times_frc(s1, dsb.x);
c21 = plus_frc(times_frc(a2, b2), plus_frc(times_frc(a2, b1), plus_frc(times_frc(a1, b2), minus_frc(times_frc(a1, b1), c11))));
c2 = times_frc(s1, dsb.y);
t1 = plus_frc(c11, c2);
e = minus_frc(t1, c11);
t2 = plus_frc(plus_frc(minus_frc(c2, e), minus_frc(c11, minus_frc(t1, e))), c21);
t12 = plus_frc(t1,t2);
t22 = minus_frc(t2,minus_frc(t12,t1));
t11 = minus_frc(dsa.x, t12);
e = minus_frc(t11, dsa.x);
t21 = minus_frc(plus_frc( plus_frc(minus_frc(-t12,e),minus_frc(dsa.x,minus_frc(t11,e))) ,dsa.y),t22);
s2 = div_frc(plus_frc(t11,t21), dsb.x);
dsc.x = plus_frc(s1, s2);
dsc.y = minus_frc(s2, minus_frc(dsc.x, s1));
return dsc;
}
float2 ds_sqrt (float2 dsa) {
float2 dsb;
float t1, t2, t3;
float2 f, s0, s1;
if (dsa.x == 0.0)
{
return float2(0.0,0.0);
}
t1 = div_frc(1.0, sqrt(dsa.x));
t2 = times_frc(dsa.x, t1);
s0 = ds_mul(ds_set(t2),ds_set(t2));
s1 = ds_sub(dsa, s0);
t3 = times_frc(0.5, times_frc(s1.x,t1));
s0.x = t2;
s0.y = 0.0;
s1.x = t3;
s1.y = 0.0;
dsb = ds_add(s0, s1);
return dsb;
}
// Couldn't get this to work
// Sets B to the integer part of the DS number A and sets C equal to the
// fractional part of A. Note that if A = -3.3, then B = -3 and C = -0.3.
float4 ds_infr(float2 dsa) {
int ic;
float2 dsb, dsc, con, f, s0, s1;
float t47, t23;
t47 = pow(2,47);
t23 = pow(2,23);
con = float2(t47, t23); //not sure about this, data operator
if (dsa.x == 0.0)
return 0.0;
//omitted dsa < 2^47 check here, should be fine
f = float2(1.0,0.0);
if (dsa.x > 0.0)
{
s0 = ds_add(dsa, con);
dsb = ds_sub(s0,con);
ic = ds_cmp(dsa, dsb);
if (ic >= 0.0)
{
dsc = ds_sub(dsa,dsb);
}
else
{
s1 = ds_sub(dsb,f);
dsb = s1;
dsc = ds_sub(dsa,dsb);
}
}
else
{
s0 = ds_sub(dsa,con);
dsb = ds_add(s0,con);
ic = ds_cmp(dsa,dsb);
if (ic <= 0.0)
{
dsc = ds_sub(dsa,dsb);
}
else
{
s1 = ds_add(dsb,f);
dsb = s1;
dsc = ds_sub(dsa,dsb);
}
}
return float4(dsb, dsc);
}
//Couldn't get this to work either, maybe something wrong with t47 and t23?
// This sets B equal to the integer nearest to the DS number A.
float2 dsn_int (float2 dsa)
{
float2 dsb, con, s0;
float t47, t23;
t47 = pow(2,47);
t23 = pow(2,23);
con = float2(t47, t23); //not sure about this, data operator, it may do something low-level, in which case this is screwed
if (dsa.x == 0.0)
{
return float2(0.0,0.0);
}
if (dsa.x > 0.0)
{
s0 = ds_add(dsa, con);
dsb = ds_sub(s0, con);
}
else
{
s0 = ds_sub(dsa,con);
dsb = ds_add(s0,con);
}
return dsb;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/DoublePrecisionEmulation.cginc.meta
================================================
fileFormatVersion: 2
guid: 1a34c77a67cf21c4b8523a435293645b
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/FixedScreenSpaceShadows.cginc
================================================
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
// Essentially a modified version of the unity screenSpace shadow collector shader
// 1) Always use INV_PROJECTION because it offers better precision than the ray method when far/near ratio is very high
// 2) Add a very small receiverPlaneDepthBias based on z value, to avoid shadow acne, jittering and other artifacts
UNITY_DECLARE_SHADOWMAP(_ShadowMapTexture);
float4 _ShadowMapTexture_TexelSize;
#define SHADOWMAPSAMPLER_AND_TEXELSIZE_DEFINED
sampler2D _ODSWorldTexture;
// ------------------------------------------------------------------
// Helpers
// ------------------------------------------------------------------
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
#include "../ShadowsCommon.cginc"
struct appdata {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
#ifdef UNITY_STEREO_INSTANCING_ENABLED
float3 ray0 : TEXCOORD1;
float3 ray1 : TEXCOORD2;
#else
float3 ray : TEXCOORD1;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 pos : SV_POSITION;
// xy uv / zw screenpos
float4 uv : TEXCOORD0;
// View space ray, for perspective case
float3 ray : TEXCOORD1;
// Orthographic view space positions (need xy as well for oblique matrices)
float3 orthoPosNear : TEXCOORD2;
float3 orthoPosFar : TEXCOORD3;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert (appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
float4 clipPos;
#if defined(STEREO_CUBEMAP_RENDER_ON)
clipPos = mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, v.vertex));
#else
clipPos = UnityObjectToClipPos(v.vertex);
#endif
o.pos = clipPos;
o.uv.xy = v.texcoord;
// unity_CameraInvProjection at the PS level.
o.uv.zw = ComputeNonStereoScreenPos(clipPos);
// Perspective case
#ifdef UNITY_STEREO_INSTANCING_ENABLED
o.ray = unity_StereoEyeIndex == 0 ? v.ray0 : v.ray1;
#else
o.ray = v.ray;
#endif
// To compute view space position from Z buffer for orthographic case,
// we need different code than for perspective case. We want to avoid
// doing matrix multiply in the pixel shader: less operations, and less
// constant registers used. Particularly with constant registers, having
// unity_CameraInvProjection in the pixel shader would push the PS over SM2.0
// limits.
clipPos.y *= _ProjectionParams.x;
float3 orthoPosNear = mul(unity_CameraInvProjection, float4(clipPos.x,clipPos.y,-1,1)).xyz;
float3 orthoPosFar = mul(unity_CameraInvProjection, float4(clipPos.x,clipPos.y, 1,1)).xyz;
orthoPosNear.z *= -1;
orthoPosFar.z *= -1;
o.orthoPosNear = orthoPosNear;
o.orthoPosFar = orthoPosFar;
return o;
}
/**
* Get camera space coord from depth and inv projection matrices
*/
inline float3 computeCameraSpacePosFromDepthAndInvProjMat(v2f i)
{
float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
// View position calculation for oblique clipped projection case.
// this will not be as precise nor as fast as the other method
// (which computes it from interpolated ray & depth) but will work
// with funky projections.
float4 clipPos = float4(i.uv.zw, zdepth, 1.0);
clipPos.xyz = 2.0f * clipPos.xyz - 1.0f;
float4 camPos = mul(unity_CameraInvProjection, clipPos);
camPos.xyz /= camPos.w;
camPos.z *= -1;
return camPos.xyz;
}
/**
* Get camera space coord from depth and info from VS
*/
inline float3 computeCameraSpacePosFromDepthAndVSInfo(v2f i)
{
float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
// 0..1 linear depth, 0 at camera, 1 at far plane.
float depth = Linear01Depth(zdepth);
#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
float3 adjustedRay = i.ray;
float3 vposPersp = adjustedRay * depth;
float3 camPos = vposPersp;
return camPos.xyz;
}
inline float3 computeCameraSpacePosFromDepth(v2f i);
/**
* Hard shadow
*/
fixed4 frag_hard (v2f i) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); // required for sampling the correct slice of the shadow map render texture array
float4 wpos;
float3 vpos;
#if defined(STEREO_CUBEMAP_RENDER_ON)
wpos.xyz = tex2D(_ODSWorldTexture, i.uv.xy).xyz;
wpos.w = 1.0f;
vpos = mul(unity_WorldToCamera, wpos).xyz;
#else
vpos = computeCameraSpacePosFromDepth(i);
wpos = mul (unity_CameraToWorld, float4(vpos,1));
#endif
fixed4 cascadeWeights = GET_CASCADE_WEIGHTS (wpos, vpos.z);
float4 shadowCoord = GET_SHADOW_COORDINATES(wpos, cascadeWeights);
//1 tap hard shadow
fixed shadow = UNITY_SAMPLE_SHADOW(_ShadowMapTexture, shadowCoord);
shadow = lerp(_LightShadowData.r, 1.0, shadow);
fixed4 res = shadow;
return res;
}
/**
* Soft Shadow (SM 3.0)
*/
fixed4 frag_pcfSoft(v2f i) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); // required for sampling the correct slice of the shadow map render texture array
float4 wpos;
float3 vpos;
#if defined(STEREO_CUBEMAP_RENDER_ON)
wpos.xyz = tex2D(_ODSWorldTexture, i.uv.xy).xyz;
wpos.w = 1.0f;
vpos = mul(unity_WorldToCamera, wpos).xyz;
#else
vpos = computeCameraSpacePosFromDepth(i);
// sample the cascade the pixel belongs to
wpos = mul(unity_CameraToWorld, float4(vpos,1));
#endif
fixed4 cascadeWeights = GET_CASCADE_WEIGHTS(wpos, vpos.z);
float4 coord = GET_SHADOW_COORDINATES(wpos, cascadeWeights);
float zdepth2 = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
// float3 receiverPlaneDepthBias = float3(0.0,0.0,0.5*Linear01Depth(zdepth2)); //my best or worst hack yet?
//seems to fix all issues, no peter-panning either
//perfect for 5000 shadowDistance
//Holds up to 8000-9000 shadow distance and gets swimmy after
float3 receiverPlaneDepthBias = float3(0.0,0.0,2.0 * Linear01Depth(zdepth2)); //With the new hybrid reconstruction method this isn't needed anymore but what Parallax renders to depth buffer is slightly offset so use agressive bias
#ifdef UNITY_USE_RECEIVER_PLANE_BIAS
// Reveiver plane depth bias: need to calculate it based on shadow coordinate
// as it would be in first cascade; otherwise derivatives
// at cascade boundaries will be all wrong. So compute
// it from cascade 0 UV, and scale based on which cascade we're in.
float3 coordCascade0 = getShadowCoord_SingleCascade(wpos);
float biasMultiply = dot(cascadeWeights,unity_ShadowCascadeScales);
receiverPlaneDepthBias = UnityGetReceiverPlaneDepthBias(coordCascade0.xyz, biasMultiply);
#endif
#if defined(SHADER_API_MOBILE)
half shadow = UnitySampleShadowmap_PCF5x5(coord, receiverPlaneDepthBias);
#else
half shadow = UnitySampleShadowmap_PCF7x7(coord, receiverPlaneDepthBias);
#endif
shadow = lerp(_LightShadowData.r, 1.0f, shadow);
// Blend between shadow cascades if enabled
//
// Not working yet with split spheres, and no need when 1 cascade
#if UNITY_USE_CASCADE_BLENDING && !defined(SHADOWS_SPLIT_SPHERES) && !defined(SHADOWS_SINGLE_CASCADE)
half4 z4 = (float4(vpos.z,vpos.z,vpos.z,vpos.z) - _LightSplitsNear) / (_LightSplitsFar - _LightSplitsNear);
half alpha = dot(z4 * cascadeWeights, half4(1,1,1,1));
UNITY_BRANCH
if (alpha > 1 - UNITY_CASCADE_BLEND_DISTANCE)
{
// get alpha to 0..1 range over the blend distance
alpha = (alpha - (1 - UNITY_CASCADE_BLEND_DISTANCE)) / UNITY_CASCADE_BLEND_DISTANCE;
// sample next cascade
cascadeWeights = fixed4(0, cascadeWeights.xyz);
coord = GET_SHADOW_COORDINATES(wpos, cascadeWeights);
#ifdef UNITY_USE_RECEIVER_PLANE_BIAS
biasMultiply = dot(cascadeWeights,unity_ShadowCascadeScales);
receiverPlaneDepthBias = UnityGetReceiverPlaneDepthBias(coordCascade0.xyz, biasMultiply);
#endif
half shadowNextCascade = UnitySampleShadowmap_PCF3x3(coord, receiverPlaneDepthBias);
shadowNextCascade = lerp(_LightShadowData.r, 1.0f, shadowNextCascade);
shadow = lerp(shadow, shadowNextCascade, alpha);
}
#endif
return shadow;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/FixedScreenSpaceShadows.cginc.meta
================================================
fileFormatVersion: 2
guid: 7895e41fc42ee304cbd33be552917a5a
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/FixedScreenSpaceShadows.shader
================================================
// This shader is now deprecated as the long distance version is now better in every way without adding a performance hit
// Essentially a modified version of the unity screenSpace shadow collector shader
// 1) Always use INV_PROJECTION because it offers better precision than the ray method when far/near ratio is very high
// 2) Add a very small receiverPlaneDepthBias based on z value, to avoid shadow acne, jittering and other artifacts
Shader "Scatterer/fixedScreenSpaceShadows" {
Properties {
_ShadowMapTexture ("", any) = "" {}
_ODSWorldTexture("", 2D) = "" {}
}
CGINCLUDE
#include "FixedScreenSpaceShadows.cginc"
ENDCG
//// ----------------------------------------------------------------------------------------
//// Subshader for hard shadows:
//// Just collect shadows into the buffer. Used on pre-SM3 GPUs and when hard shadows are picked.
//
//SubShader {
// Tags{ "ShadowmapFilter" = "HardShadow" }
// Pass {
// ZWrite Off ZTest Always Cull Off
//
// CGPROGRAM
// #pragma vertex vert
// #pragma fragment frag_hard
// #pragma multi_compile_shadowcollector
//
// inline float3 computeCameraSpacePosFromDepth(v2f i)
// {
// return computeCameraSpacePosFromDepthAndVSInfo(i);
// }
// ENDCG
// }
//}
// ----------------------------------------------------------------------------------------
// Subshader for hard shadows:
// Just collect shadows into the buffer. Used on pre-SM3 GPUs and when hard shadows are picked.
// This version does inv projection at the PS level, slower and less precise however more general.
SubShader {
// Tags{ "ShadowmapFilter" = "HardShadow_FORCE_INV_PROJECTION_IN_PS" }
Tags{ "ShadowmapFilter" = "HardShadow" }
Pass{
ZWrite Off ZTest Always Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag_hard
#pragma multi_compile_shadowcollector
inline float3 computeCameraSpacePosFromDepth(v2f i)
{
return computeCameraSpacePosFromDepthAndInvProjMat(i);
}
ENDCG
}
}
//// ----------------------------------------------------------------------------------------
//// Subshader that does soft PCF filtering while collecting shadows.
//// Requires SM3 GPU.
//
//Subshader {
// Tags {"ShadowmapFilter" = "PCF_SOFT"}
// Pass {
// ZWrite Off ZTest Always Cull Off
//
// CGPROGRAM
// #pragma vertex vert
// #pragma fragment frag_pcfSoft
// #pragma multi_compile_shadowcollector
// #pragma target 3.0
//
// inline float3 computeCameraSpacePosFromDepth(v2f i)
// {
// return computeCameraSpacePosFromDepthAndVSInfo(i);
// }
// ENDCG
// }
//}
// ----------------------------------------------------------------------------------------
// Subshader that does soft PCF filtering while collecting shadows.
// Requires SM3 GPU.
// This version does inv projection at the PS level, slower and less precise however more general.
//
Subshader{
//Tags{ "ShadowmapFilter" = "PCF_SOFT_FORCE_INV_PROJECTION_IN_PS" }
Tags {"ShadowmapFilter" = "PCF_SOFT"}
Pass{
ZWrite Off ZTest Always Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag_pcfSoft
#pragma multi_compile_shadowcollector
#pragma target 3.0
inline float3 computeCameraSpacePosFromDepth(v2f i)
{
return computeCameraSpacePosFromDepthAndInvProjMat(i);
}
ENDCG
}
}
Fallback Off
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/FixedScreenSpaceShadows.shader.meta
================================================
fileFormatVersion: 2
guid: e7719e74d14c6ca45a8d38ed1a32e5d9
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/LongDistanceScreenSpaceShadows.shader
================================================
// Same as fixedScreenSpaceShadows shader but uses the enhanced ray/projection method to calculate accurate position
// Some other experimentes are kept in this file but no longer used: Including dual-depth method, binary search method, double precision method
Shader "Scatterer/customScreenSpaceShadows" {
Properties {
_ShadowMapTexture ("", any) = "" {}
_ODSWorldTexture("", 2D) = "" {}
}
CGINCLUDE
#include "FixedScreenSpaceShadows.cginc"
#include "DoublePrecisionEmulation.cginc"
UNITY_DECLARE_DEPTH_TEXTURE(AdditionalDepthBuffer);
float4x4 ScattererAdditionalInvProjection;
/**
* Get camera space coord from depth and inv projection matrices
* No longer needed, deprecated in favor of hybrid ray/matrix method below
*/
inline float3 computeCameraSpacePosFromDualDepthAndInvProjMat(v2f i)
{
float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
float zdepth2 = SAMPLE_DEPTH_TEXTURE(AdditionalDepthBuffer, i.uv.xy);
#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
zdepth2 = 1 - zdepth2;
#endif
float4 clipPos = float4(i.uv.zw, zdepth, 1.0);
clipPos.xyz = 2.0f * clipPos.xyz - 1.0f;
float4 camPos = mul(unity_CameraInvProjection, clipPos);
camPos.xyz /= camPos.w;
camPos.z *= -1;
float4 clipPos2 = float4(i.uv.zw, zdepth2, 1.0);
clipPos2.xyz = 2.0f * clipPos2.xyz - 1.0f;
float4 camPos2 = mul(ScattererAdditionalInvProjection, clipPos2);
camPos2.xyz /= camPos2.w;
camPos2.z *= -1;
return length(camPos.xyz) < 8000 ? camPos.xyz : camPos2.xyz ;
}
//Refines the inaccurate worldPos from invprojection with a search algorithm
//Apparently overshoots here even though it worked well for scattering shader
float getRefinedDistanceFromDepth(float unrefinedDistance, float zdepth, float3 viewDir)
{
const int maxIterations = 30; //seems about perfect
int iteration = 0;
float maxSearchDistance = unrefinedDistance * 1.30;
float minSearchDistance = unrefinedDistance * 0.70;
float mid = 0;
float3 camPos0 = float3(0.0,0.0,0.0);
float4 clipPos = float4(0.0,0.0,0.0,1.0);
float depth = -10.0;
while ((iteration < maxIterations) && (depth != zdepth))
{
mid = 0.5 * (maxSearchDistance + minSearchDistance);
camPos0 = viewDir * mid;
clipPos = mul(UNITY_MATRIX_P, float4(camPos0,1.0));
depth = clipPos.z/clipPos.w;
maxSearchDistance = (depth < zdepth) ? mid : maxSearchDistance;
minSearchDistance = (depth > zdepth) ? mid : minSearchDistance;
iteration++;
}
return mid;
}
// Binary search method, worked well for the scattering shader but seems to overshoot here
inline float3 computeEnhancedCameraSpacePosFromDepthAndInvProjMat(v2f i)
{
float textureZdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
float zdepth = textureZdepth;
#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
float4 clipPos = float4(i.uv.zw, zdepth, 1.0);
clipPos.xyz = 2.0f * clipPos.xyz - 1.0f;
float4 camPos = mul(unity_CameraInvProjection, clipPos);
camPos.xyz /= camPos.w;
camPos.z *= -1;
float invDepthLength = length(camPos.xyz);
float3 viewDir = camPos.xyz / invDepthLength;
//now refine the inaccurate distance
float distance = invDepthLength;
// if (distance > 8000.0)
{
distance = getRefinedDistanceFromDepth(distance, textureZdepth, viewDir); //seems like my method is overshooting actually, or something else is wrong with these params, to investigate, maybe the projection matrix, maybe the direction is flipped
}
camPos.xyz = distance * viewDir;
return camPos.xyz;
}
//after implementing this it seems like this isn't even the source of the issue, but rather the ray direction that unity passes, good job unity wtf
inline float2 Linear01DepthDoublePrecision( float z )
{
//return 1.0 / (_ZBufferParams.x * z + _ZBufferParams.y);
float2 doubleZBufferParamsY = ds_sub(ds_set(1.0), ds_div(ds_set(_ProjectionParams.y), ds_set(_ProjectionParams.z)));
float2 doubleWhateverElse = ds_mul(ds_div(ds_set(_ProjectionParams.z), ds_set(_ProjectionParams.y)), ds_set(z));
float2 doubleResultLower = ds_add(doubleZBufferParamsY, doubleWhateverElse);
float2 doubleResult = ds_div(ds_set(1.0), doubleResultLower);
return doubleResult;
}
//This is the same ray method but calculations are done in emulated double precision
//This ended up being useless, the source of the problem is the ray direction passed by unity
inline float3 computeCameraSpacePosFromDepthAndVSInfoDoublePrecision(v2f i)
{
float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
// 0..1 linear depth, 0 at camera, 1 at far plane.
float2 doublePrecisionDepth = Linear01DepthDoublePrecision(zdepth);
float3 adjustedRay = i.ray;
float3 rayDirection = normalize(i.ray);
float3 vposPersp = adjustedRay * doublePrecisionDepth.x;
return vposPersp;
}
/**
* Use the ray method to find position, except use the ray direction calculated with the invProj method because it's more accurate
* Kind of a hybrid of the two methods
*/
inline float3 computeCameraSpacePosFromLinearDepthAndInvProjMat(v2f i)
{
float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
#if SHADER_API_D3D11 || SHADER_API_D3D || SHADER_API_D3D12
if (zdepth == 0.0) {discard;}
#else
if (zdepth == 1.0) {discard;}
#endif
float depth = Linear01Depth(zdepth);
//float3 rayDirection = normalize(i.ray); //this ray is imprecise and can't be trusted
//calculate our own ray direction using the inverse projection matrix method
#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
float4 clipPos = float4(i.uv.zw, zdepth, 1.0);
clipPos.xyz = 2.0f * clipPos.xyz - 1.0f;
float4 camPos = mul(unity_CameraInvProjection, clipPos);
camPos.xyz /= camPos.w;
camPos.z *= -1;
float3 rayDirection = normalize(camPos.xyz);
float3 cameraForwardDir = float3(0,0,1);
float aa = dot(rayDirection, cameraForwardDir);
float3 vposPersp = rayDirection * depth/aa * _ProjectionParams.z;
return vposPersp;
}
ENDCG
// ----------------------------------------------------------------------------------------
// Subshader for hard shadows:
// Just collect shadows into the buffer. Used on pre-SM3 GPUs and when hard shadows are picked.
// This version does inv projection at the PS level, slower and less precise however more general.
SubShader {
Tags{ "ShadowmapFilter" = "HardShadow" }
Pass{
ZWrite Off ZTest Always Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag_hard
#pragma multi_compile_shadowcollector
inline float3 computeCameraSpacePosFromDepth(v2f i)
{
return computeCameraSpacePosFromLinearDepthAndInvProjMat(i);
}
ENDCG
}
}
// ----------------------------------------------------------------------------------------
// Subshader that does soft PCF filtering while collecting shadows.
// Requires SM3 GPU.
// This version does inv projection at the PS level, slower and less precise however more general.
//
Subshader{
Tags {"ShadowmapFilter" = "PCF_SOFT"}
Pass{
ZWrite Off ZTest Always Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag_pcfSoft
#pragma multi_compile_shadowcollector
#pragma target 3.0
inline float3 computeCameraSpacePosFromDepth(v2f i)
{
return computeCameraSpacePosFromLinearDepthAndInvProjMat(i);
}
ENDCG
}
}
Fallback Off
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows/LongDistanceScreenSpaceShadows.shader.meta
================================================
fileFormatVersion: 2
guid: 02e622e7baa59ac449d2c5f5bc992795
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Shadows.meta
================================================
fileFormatVersion: 2
guid: 5bcb408b7b5e4d346aeb4860ab1d9d9b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/ShadowsCommon.cginc
================================================
#include "UnityCG.cginc"
#include "UnityShadowLibrary.cginc"
// Configuration
// Should receiver plane bias be used? This estimates receiver slope using derivatives,
// and tries to tilt the PCF kernel along it. However, since we're doing it in screenspace
// from the depth texture, the derivatives are wrong on edges or intersections of objects,
// leading to possible shadow artifacts. So it's disabled by default.
// See also UnityGetReceiverPlaneDepthBias in UnityShadowLibrary.cginc.
//#define UNITY_USE_RECEIVER_PLANE_BIAS
// Blend between shadow cascades to hide the transition seams?
#define UNITY_USE_CASCADE_BLENDING 0
#define UNITY_CASCADE_BLEND_DISTANCE 0.1
// sizes of cascade projections, relative to first one
float4 unity_ShadowCascadeScales;
//
// Keywords based defines
//
#if defined (SHADOWS_SPLIT_SPHERES)
#define GET_CASCADE_WEIGHTS(wpos, z) getCascadeWeights_splitSpheres(wpos)
#else
#define GET_CASCADE_WEIGHTS(wpos, z) getCascadeWeights( wpos, z )
#endif
#if defined (SHADOWS_SINGLE_CASCADE)
#define GET_SHADOW_COORDINATES(wpos,cascadeWeights) getShadowCoord_SingleCascade(wpos)
#else
#define GET_SHADOW_COORDINATES(wpos,cascadeWeights) getShadowCoord(wpos,cascadeWeights)
#endif
/**
* Gets the cascade weights based on the world position of the fragment.
* Returns a float4 with only one component set that corresponds to the appropriate cascade.
*/
inline fixed4 getCascadeWeights(float3 wpos, float z)
{
fixed4 zNear = float4( z >= _LightSplitsNear );
fixed4 zFar = float4( z < _LightSplitsFar );
fixed4 weights = zNear * zFar;
return weights;
}
/**
* Gets the cascade weights based on the world position of the fragment and the poisitions of the split spheres for each cascade.
* Returns a float4 with only one component set that corresponds to the appropriate cascade.
*/
inline fixed4 getCascadeWeights_splitSpheres(float3 wpos)
{
float3 fromCenter0 = wpos.xyz - unity_ShadowSplitSpheres[0].xyz;
float3 fromCenter1 = wpos.xyz - unity_ShadowSplitSpheres[1].xyz;
float3 fromCenter2 = wpos.xyz - unity_ShadowSplitSpheres[2].xyz;
float3 fromCenter3 = wpos.xyz - unity_ShadowSplitSpheres[3].xyz;
float4 distances2 = float4(dot(fromCenter0,fromCenter0), dot(fromCenter1,fromCenter1), dot(fromCenter2,fromCenter2), dot(fromCenter3,fromCenter3));
fixed4 weights = float4(distances2 < unity_ShadowSplitSqRadii);
weights.yzw = saturate(weights.yzw - weights.xyz);
return weights;
}
/**
* Returns the shadowmap coordinates for the given fragment based on the world position and z-depth.
* These coordinates belong to the shadowmap atlas that contains the maps for all cascades.
*/
inline float4 getShadowCoord( float4 wpos, fixed4 cascadeWeights )
{
float3 sc0 = mul (unity_WorldToShadow[0], wpos).xyz;
float3 sc1 = mul (unity_WorldToShadow[1], wpos).xyz;
float3 sc2 = mul (unity_WorldToShadow[2], wpos).xyz;
float3 sc3 = mul (unity_WorldToShadow[3], wpos).xyz;
float4 shadowMapCoordinate = float4(sc0 * cascadeWeights[0] + sc1 * cascadeWeights[1] + sc2 * cascadeWeights[2] + sc3 * cascadeWeights[3], 1);
#if defined(UNITY_REVERSED_Z)
float noCascadeWeights = 1 - dot(cascadeWeights, float4(1, 1, 1, 1));
shadowMapCoordinate.z += noCascadeWeights;
#endif
return shadowMapCoordinate;
}
/**
* Same as the getShadowCoord; but optimized for single cascade
*/
inline float4 getShadowCoord_SingleCascade( float4 wpos )
{
return float4( mul (unity_WorldToShadow[0], wpos).xyz, 0);
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/ShadowsCommon.cginc.meta
================================================
fileFormatVersion: 2
guid: 06bfdc59aae5325499d5beef3aa3d013
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/SunFlare/SunFlare.shader
================================================
Shader "Scatterer/sunFlare"
{
CGINCLUDE
#include "UnityCG.cginc"
#include "../CommonAtmosphere.cginc"
#include "../DepthCommon.cginc"
uniform float sunGlareScale;
uniform float sunGlareFade;
uniform sampler2D sunSpikes;
uniform sampler2D sunFlare;
uniform sampler2D sunGhost1;
uniform sampler2D sunGhost2;
uniform sampler2D sunGhost3;
uniform float3 flareColor;
uniform sampler2D extinctionTexture;
uniform float3 flareSettings; //intensity, aspect ratio, scale
uniform float3 spikesSettings;
uniform float4x4 ghost1Settings1; //each row is an instance of a ghost
uniform float4x4 ghost1Settings2; //for each row: intensity, aspect ratio, scale, position on sun-screenCenter line. Intensity of 0 means nothing defined
uniform float4x4 ghost2Settings1;
uniform float4x4 ghost2Settings2;
uniform float4x4 ghost3Settings1;
uniform float4x4 ghost3Settings2;
uniform float3 sunViewPortPos;
uniform float aspectRatio;
uniform float renderSunFlare;
uniform float renderOnCurrentCamera;
uniform float useDbufferOnCamera;
struct v2f
{
float4 pos: SV_POSITION;
float2 uv : TEXCOORD0;
float3 color : TEXCOORD1;
};
v2f flareVertexShader(appdata_base v, float3 sunViewPortPos, float3 settings)
{
v2f OUT;
float drawFlare = (useDbufferOnCamera < 1.0) ? 1.0 : checkDepthBufferEmpty(sunViewPortPos.xy); //if there's something in the way don't render the flare
sunViewPortPos.xy = 2.0 * sunViewPortPos.xy - float2(1.0,1.0);
sunViewPortPos.y *= _ProjectionParams.x;
v.vertex.xy = sunViewPortPos.xy + v.vertex.xy / (settings.z * sunGlareScale * float2(aspectRatio * settings.y, 1.0)); //change this so it no longer has to do a division
OUT.pos = float4(v.vertex.xy, 1.0, 1.0);
OUT.pos = (settings.x > 0.0) && (renderSunFlare == 1.0) && (_ProjectionParams.y < 200.0) && (renderOnCurrentCamera == 1.0) && (drawFlare ==1.0) ? OUT.pos : float4(2.0,2.0,2.0,1.0); //if we don't need to render the sunflare, cull vertexes by placing them outside clip space
//also use near plane to not render on far camera
OUT.uv = v.texcoord.xy;
OUT.color = settings.x * sunGlareFade * flareColor * tex2Dlod(extinctionTexture,float4(0.0,0.0,0.0,0.0)).rgb;
return OUT;
}
struct v2g
{
float4 pos: SV_POSITION;
float2 uv : TEXCOORD0;
float3 color : TEXCOORD1;
};
struct g2f
{
float4 pos: SV_POSITION;
float2 uv : TEXCOORD0;
float3 color : TEXCOORD1;
};
v2g ghostVertexShader (appdata_base v, float3 sunViewPortPos, float ghostFade)
{
v2g OUT;
OUT.pos = float4(v.vertex.xy, 1.0, 1.0);
OUT.uv = v.texcoord.xy;
float2 toScreenCenter=sunViewPortPos.xy-0.5;
OUT.color = ghostFade * smoothstep(0,1.0,1.0-length(toScreenCenter)) * sunGlareFade * flareColor * tex2Dlod(extinctionTexture,float4(0.0,0.0,0.0,0.0)).rgb;
return OUT;
}
g2f buildGhostVertex(v2g input, float4 ghostSettings, float3 sunViewPortPos)
{
g2f tri;
tri.pos = input.pos;
tri.pos.xy = sunViewPortPos.xy - sunViewPortPos.xy * ghostSettings.w + tri.pos.xy / (ghostSettings.z * float2(aspectRatio * ghostSettings.y, 1.0)); //change this so it no longer has to do a division
tri.uv = input.uv;
tri.color = input.color * ghostSettings.x ;
return tri;
}
//geometry shader
//for every triangle of the input, create a max of 8 triangles, (max 8 possible instances of each ghost)
inline void ghostGeometryShader(v2g input[3], inout TriangleStream outStream, float4x4 settings1, float4x4 settings2, float3 sunViewPortPos)
{
float drawFlare = (useDbufferOnCamera < 1.0) ? 1.0 : checkDepthBufferEmpty(sunViewPortPos.xy);
drawFlare = (renderSunFlare == 1.0) && (_ProjectionParams.y < 200.0) && (renderOnCurrentCamera == 1.0) && (drawFlare ==1.0) ? 1.0 : 0.0;
sunViewPortPos.xy = 2.0 * sunViewPortPos.xy - float2(1.0,1.0);
sunViewPortPos.y *= _ProjectionParams.x;
for (int i=0; i<4; ++i)
{
if ((settings1[i].x == 0) || (drawFlare < 1.0))
break;
outStream.Append(buildGhostVertex(input[0], settings1[i], sunViewPortPos));
outStream.Append(buildGhostVertex(input[1], settings1[i], sunViewPortPos));
outStream.Append(buildGhostVertex(input[2], settings1[i], sunViewPortPos));
outStream.RestartStrip();
}
for (i=0; i<4; ++i)
{
if ((settings2[i].x == 0) || (drawFlare < 1.0))
break;
outStream.Append(buildGhostVertex(input[0], settings2[i], sunViewPortPos));
outStream.Append(buildGhostVertex(input[1], settings2[i], sunViewPortPos));
outStream.Append(buildGhostVertex(input[2], settings2[i], sunViewPortPos));
outStream.RestartStrip();
}
}
ENDCG
SubShader
{
Tags {"Queue" = "Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
//Pass 0: flare 1
Pass
{
ZWrite Off
ZTest Off
cull off
Blend One OneMinusSrcColor //"reverse" soft-additive
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#pragma glsl
v2f vert(appdata_base v)
{
return flareVertexShader(v, sunViewPortPos, flareSettings);
}
float4 frag(v2f IN) : SV_Target
{
float3 sunColor= IN.color * tex2Dlod (sunFlare,float4(IN.uv.xy,0,0)).rgb;
return float4(sunColor,1.0);
}
ENDCG
}
//Pass 1: flare2
Pass
{
ZWrite Off
ZTest Off
cull off
Blend One OneMinusSrcColor
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#pragma glsl
v2f vert(appdata_base v)
{
return flareVertexShader(v, sunViewPortPos, spikesSettings);
}
float4 frag(v2f IN) : SV_Target
{
float3 sunColor= IN.color * tex2Dlod (sunSpikes,float4(IN.uv.xy,0,0)).rgb;
return float4(sunColor,1.0);
}
ENDCG
}
//Pass 2: ghost 1
Pass
{
ZWrite Off
ZTest Off
cull off
Blend One OneMinusSrcColor
CGPROGRAM
#pragma vertex vert
#pragma geometry geom
#pragma fragment frag
#pragma glsl
uniform float ghost1Fade;
v2g vert(appdata_base v)
{
return ghostVertexShader(v, sunViewPortPos, ghost1Fade);
}
[maxvertexcount(24)]
void geom(triangle v2g input[3], inout TriangleStream outStream)
{
ghostGeometryShader(input, outStream, ghost1Settings1, ghost1Settings2, sunViewPortPos);
}
float4 frag(g2f IN) : SV_Target
{
float3 sunColor= IN.color * tex2Dlod (sunGhost1,float4(IN.uv.xy,0,0)).rgb;
return float4(sunColor,1.0);
}
ENDCG
}
//Pass 3: ghost 2
Pass
{
ZWrite Off
ZTest Off
cull off
Blend One OneMinusSrcColor
CGPROGRAM
#pragma vertex vert
#pragma geometry geom
#pragma fragment frag
#pragma glsl
uniform float ghost2Fade;
v2g vert(appdata_base v)
{
return ghostVertexShader(v, sunViewPortPos, ghost2Fade);
}
[maxvertexcount(24)]
void geom(triangle v2g input[3], inout TriangleStream outStream)
{
ghostGeometryShader(input, outStream, ghost2Settings1, ghost2Settings2, sunViewPortPos);
}
float4 frag(g2f IN) : SV_Target
{
float3 sunColor= IN.color * tex2Dlod (sunGhost2,float4(IN.uv.xy,0,0)).rgb;
return float4(sunColor,1.0);
}
ENDCG
}
//Pass 4: ghost 3
Pass
{
ZWrite Off
ZTest Off
cull off
Blend One OneMinusSrcColor
CGPROGRAM
#pragma vertex vert
#pragma geometry geom
#pragma fragment frag
#pragma glsl
uniform float ghost3Fade;
v2g vert(appdata_base v)
{
return ghostVertexShader(v, sunViewPortPos, ghost3Fade);
}
[maxvertexcount(24)]
void geom(triangle v2g input[3], inout TriangleStream outStream)
{
ghostGeometryShader(input, outStream, ghost3Settings1, ghost3Settings2, sunViewPortPos);
}
float4 frag(g2f IN) : SV_Target
{
float3 sunColor= IN.color * tex2Dlod (sunGhost3,float4(IN.uv.xy,0,0)).rgb;
return float4(sunColor,1.0);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/SunFlare/SunFlare.shader.meta
================================================
fileFormatVersion: 2
guid: 34f9419ac53fdb44fa9676a451481931
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/SunFlare/SunFlareExtinction.shader
================================================
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Scatterer/sunFlareExtinction"
{
SubShader
{
Pass //pass 0 - atmospheric extinction
{
ZWrite Off
ZTest Off
cull off
Blend DstColor Zero //multiplicative blending
CGPROGRAM
#include "UnityCG.cginc"
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile DISABLE_UNDERWATER_OFF DISABLE_UNDERWATER_ON
uniform float Rg;
uniform float Rt;
uniform sampler2D _Sky_Transmittance;
uniform float3 _Sun_WorldSunDir;
uniform float3 _Globals_WorldCameraPos;
uniform float _experimentalAtmoScale;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
OUT.uv = v.texcoord;
return OUT;
}
float2 GetTransmittanceUV(float r, float mu)
{
float uR, uMu;
uR = sqrt((r - Rg) / (Rt - Rg));
uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
return float2(uMu, uR);
}
float3 Transmittance(float r, float mu)
{
float2 uv = GetTransmittanceUV(r, mu);
return tex2Dlod(_Sky_Transmittance, float4(uv,0,0)).rgb;
}
float SQRT(float f, float err)
{
return f >= 0.0 ? sqrt(f) : err;
}
float3 getExtinction(float3 camera, float3 viewdir)
{
float3 extinction = float3(1,1,1);
Rt=Rg+(Rt-Rg)*_experimentalAtmoScale;
float r = length(camera);
float rMu = dot(camera, viewdir);
float mu = rMu / r;
//float deltaSq = sqrt(rMu * rMu - r * r + Rt*Rt);
float deltaSq = SQRT(rMu * rMu - r * r + Rt*Rt,0.000001);
float din = max(-rMu - deltaSq, 0.0);
if (din > 0.0)
{
camera += din * viewdir;
rMu += din;
mu = rMu / Rt;
r = Rt;
}
extinction = (r > Rt) ? float3(1,1,1) : Transmittance(r, mu);
return extinction;
}
float4 frag(v2f IN): COLOR
{
float3 WSD = _Sun_WorldSunDir;
float3 WCP = _Globals_WorldCameraPos;
float3 extinction = getExtinction(WCP,WSD);
#if defined (DISABLE_UNDERWATER_ON) //disable when underwater
extinction = (length(WCP) >= Rg ) ? extinction : float4(0.0,0.0,0.0,1.0);
#endif
return float4(extinction,1.0);
}
ENDCG
}
Pass //pass 1 - ring extinction
{
ZWrite Off
ZTest Off
cull off
Blend DstColor Zero //multiplicative blending
CGPROGRAM
#include "UnityCG.cginc"
#include "../IntersectCommon.cginc"
#include "../RingCommon.cginc"
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
uniform float3 _Sun_WorldSunDir;
uniform float3 _Globals_WorldCameraPos;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f OUT;
OUT.pos = UnityObjectToClipPos(v.vertex);
OUT.uv = v.texcoord;
return OUT;
}
float4 frag(v2f IN): COLOR
{
float3 WCP = _Globals_WorldCameraPos;
float4 ringColor = getLinearRingColor(WCP,_Sun_WorldSunDir,float3(0,0,0));
return float4(ringColor.xyz,1.0);
}
ENDCG
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/SunFlare/SunFlareExtinction.shader.meta
================================================
fileFormatVersion: 2
guid: 357e9aeae0d19c148b2437b05c8b3361
timeCreated: 1485103617
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName: scatterershaders
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/SunFlare.meta
================================================
fileFormatVersion: 2
guid: 1b0a41d64d4e9534481f804049080fbb
folderAsset: yes
timeCreated: 1541842621
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Utility.cginc
================================================
float mod(float x, float y) { return x - y * floor(x/y); }
float3 hdr(float3 L, float exposure)
{
L = L * exposure;
L.r = L.r < 1.413 ? pow(L.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.r);
L.g = L.g < 1.413 ? pow(L.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.g);
L.b = L.b < 1.413 ? pow(L.b * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.b);
return L;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/Shaders/Utility.cginc.meta
================================================
fileFormatVersion: 2
guid: cb5112bfbee0a8545af567d810945a2a
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/TestScenes.meta
================================================
fileFormatVersion: 2
guid: 15225778e2107e44bb700adf9df97a60
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Assets/shaders.meta
================================================
fileFormatVersion: 2
guid: 980daac0955b74442b91df43f0f1b776
folderAsset: yes
timeCreated: 1459687924
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/AssetImportState
================================================
19;0;4;0;0
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/BuildPlayer.prefs
================================================
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/CurrentLayout-default.dwlt
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_PixelRect:
serializedVersion: 2
x: 0
y: 43
width: 2560
height: 1357
m_ShowMode: 4
m_Title:
m_RootView: {fileID: 6}
m_MinSize: {x: 950, y: 300}
m_MaxSize: {x: 10000, y: 10000}
--- !u!114 &2
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 9}
- {fileID: 3}
m_Position:
serializedVersion: 2
x: 0
y: 30
width: 2560
height: 1307
m_MinSize: {x: 683, y: 494}
m_MaxSize: {x: 14004, y: 14044}
vertical: 0
controlID: 61
--- !u!114 &3
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 1957
y: 0
width: 603
height: 1307
m_MinSize: {x: 277, y: 72}
m_MaxSize: {x: 4002, y: 4022}
m_ActualView: {fileID: 14}
m_Panes:
- {fileID: 14}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &4
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 539
height: 702
m_MinSize: {x: 202, y: 222}
m_MaxSize: {x: 4002, y: 4022}
m_ActualView: {fileID: 15}
m_Panes:
- {fileID: 15}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &5
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name: ConsoleWindow
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 702
width: 1957
height: 605
m_MinSize: {x: 232, y: 272}
m_MaxSize: {x: 10002, y: 10022}
m_ActualView: {fileID: 13}
m_Panes:
- {fileID: 13}
- {fileID: 18}
m_Selected: 0
m_LastSelected: 1
--- !u!114 &6
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12008, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 7}
- {fileID: 2}
- {fileID: 8}
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 2560
height: 1357
m_MinSize: {x: 950, y: 300}
m_MaxSize: {x: 10000, y: 10000}
--- !u!114 &7
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12011, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 2560
height: 30
m_MinSize: {x: 0, y: 0}
m_MaxSize: {x: 0, y: 0}
m_LastLoadedLayoutName:
--- !u!114 &8
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12042, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 1337
width: 2560
height: 20
m_MinSize: {x: 0, y: 0}
m_MaxSize: {x: 0, y: 0}
--- !u!114 &9
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 10}
- {fileID: 5}
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 1957
height: 1307
m_MinSize: {x: 406, y: 494}
m_MaxSize: {x: 10002, y: 14044}
vertical: 1
controlID: 105
--- !u!114 &10
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 4}
- {fileID: 11}
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 1957
height: 702
m_MinSize: {x: 406, y: 222}
m_MaxSize: {x: 8006, y: 4022}
vertical: 0
controlID: 106
--- !u!114 &11
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 539
y: 0
width: 1418
height: 702
m_MinSize: {x: 204, y: 222}
m_MaxSize: {x: 4004, y: 4022}
m_ActualView: {fileID: 17}
m_Panes:
- {fileID: 16}
- {fileID: 17}
- {fileID: 12}
m_Selected: 1
m_LastSelected: 0
--- !u!114 &12
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12111, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_MinSize: {x: 400, y: 100}
m_MaxSize: {x: 2048, y: 2048}
m_TitleContent:
m_Text: Asset Store
m_Image: {fileID: 357073275683767465, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 468
y: 181
width: 973
height: 501
m_ViewDataDictionary: {fileID: 0}
--- !u!114 &13
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_MinSize: {x: 230, y: 250}
m_MaxSize: {x: 10000, y: 10000}
m_TitleContent:
m_Text: Project
m_Image: {fileID: -7501376956915960154, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 0
y: 775
width: 1957
height: 586
m_ViewDataDictionary: {fileID: 0}
m_SearchFilter:
m_NameFilter:
m_ClassNames: []
m_AssetLabels: []
m_AssetBundleNames: []
m_VersionControlStates: []
m_SoftLockControlStates: []
m_ReferencingInstanceIDs:
m_SceneHandles:
m_ShowAllHits: 0
m_SkipHidden: 0
m_SearchArea: 1
m_Folders:
- Assets/Shaders/AA
m_ViewMode: 1
m_StartGridSize: 64
m_LastFolders:
- Assets/Shaders/AA
m_LastFoldersGridSize: -1
m_LastProjectPath: C:\gh\scattererGithub\Scatterer\scatterer\Shaders\scattererShaders
m_LockTracker:
m_IsLocked: 0
m_FolderTreeState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: 942e0000
m_LastClickedID: 11924
m_ExpandedIDs: 00000000fe2c0000302d000000ca9a3b
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name: SunFlare
m_OriginalName: SunFlare
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 11838
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 0
m_IsRenamingFilename: 1
m_ClientGUIView: {fileID: 5}
m_SearchString:
m_CreateAssetUtility:
m_EndAction: {fileID: 0}
m_InstanceID: 0
m_Path:
m_Icon: {fileID: 0}
m_ResourceFile:
m_AssetTreeState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs:
m_LastClickedID: 0
m_ExpandedIDs: 00000000fe2c0000302d0000ba2d0000
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 1
m_ClientGUIView: {fileID: 0}
m_SearchString:
m_CreateAssetUtility:
m_EndAction: {fileID: 0}
m_InstanceID: 0
m_Path:
m_Icon: {fileID: 0}
m_ResourceFile:
m_ListAreaState:
m_SelectedInstanceIDs:
m_LastClickedInstanceID: 0
m_HadKeyboardFocusLastEvent: 1
m_ExpandedInstanceIDs: c623000000000000
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 1
m_ClientGUIView: {fileID: 5}
m_CreateAssetUtility:
m_EndAction: {fileID: 0}
m_InstanceID: 0
m_Path:
m_Icon: {fileID: 0}
m_ResourceFile:
m_NewAssetIndexInList: -1
m_ScrollPosition: {x: 0, y: 0}
m_GridSize: 64
m_SkipHiddenPackages: 0
m_DirectoriesAreaWidth: 283
--- !u!114 &14
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_MinSize: {x: 275, y: 50}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Inspector
m_Image: {fileID: -6905738622615590433, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 1957
y: 73
width: 601
height: 1288
m_ViewDataDictionary: {fileID: 0}
m_OpenAddComponentMenu: 0
m_ObjectsLockedBeforeSerialization: []
m_InstanceIDsLockedBeforeSerialization:
m_LockTracker:
m_IsLocked: 0
m_PreviewResizer:
m_CachedPref: 160
m_ControlHash: -371814159
m_PrefName: Preview_InspectorPreview
m_PreviewWindow: {fileID: 0}
m_LastInspectedObjectInstanceID: -1
m_LastVerticalScrollValue: 0
--- !u!114 &15
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Hierarchy
m_Image: {fileID: -590624980919486359, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 0
y: 73
width: 539
height: 683
m_ViewDataDictionary: {fileID: 0}
m_SceneHierarchy:
m_TreeViewState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: b0010000
m_LastClickedID: 0
m_ExpandedIDs: 76fbffff
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 0
m_ClientGUIView: {fileID: 4}
m_SearchString:
m_ExpandedScenes: []
m_CurrenRootInstanceID: 0
m_LockTracker:
m_IsLocked: 0
m_CurrentSortingName: TransformSorting
m_WindowGUID: d2da7c7f6b6a12f4db008859d58f4b06
--- !u!114 &16
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Scene
m_Image: {fileID: 2318424515335265636, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 407
y: 73
width: 1216
height: 777
m_ViewDataDictionary: {fileID: 0}
m_ShowContextualTools: 0
m_WindowGUID: e16c040b0f7d1444f814c10b57524ecd
m_Gizmos: 1
m_SceneIsLit: 1
m_SceneLighting: 1
m_2DMode: 0
m_isRotationLocked: 0
m_PlayAudio: 0
m_AudioPlay: 0
m_Position:
m_Target: {x: 2.5099688, y: 2.2473466, z: -3.8579397}
speed: 2
m_Value: {x: 2.5099688, y: 2.2473466, z: -3.8579397}
m_RenderMode: 0
m_CameraMode:
drawMode: 0
name: Shaded
section: Shading Mode
m_ValidateTrueMetals: 0
m_DoValidateTrueMetals: 0
m_SceneViewState:
showFog: 1
showMaterialUpdate: 0
showSkybox: 1
showFlares: 1
showImageEffects: 1
showParticleSystems: 1
grid:
xGrid:
m_Target: 0
speed: 2
m_Value: 0
yGrid:
m_Target: 0
speed: 2
m_Value: 0
zGrid:
m_Target: 0
speed: 2
m_Value: 0
m_Rotation:
m_Target: {x: -0.09469341, y: 0.6731113, z: -0.08752819, w: -0.72821313}
speed: 2
m_Value: {x: -0.09469341, y: 0.6731113, z: -0.0875282, w: -0.72821313}
m_Size:
m_Target: 15.153814
speed: 2
m_Value: 15.153814
m_Ortho:
m_Target: 0
speed: 2
m_Value: 0
m_CameraSettings:
m_Speed: 1
m_SpeedNormalized: 0.5
m_SpeedMin: 0.01
m_SpeedMax: 2
m_EasingEnabled: 1
m_EasingDuration: 0.4
m_AccelerationEnabled: 1
m_FieldOfView: 90
m_NearClip: 0.03
m_FarClip: 10000
m_DynamicClip: 1
m_OcclusionCulling: 0
m_ShowGlobalGrid: 1
m_LastSceneViewRotation: {x: 0, y: 0, z: 0, w: 0}
m_LastSceneViewOrtho: 0
m_ReplacementShader: {fileID: 0}
m_ReplacementString:
m_SceneVisActive: 1
m_LastLockedObject: {fileID: 0}
m_ViewIsLockedToObject: 0
--- !u!114 &17
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Game
m_Image: {fileID: -2087823869225018852, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 539
y: 73
width: 1416
height: 683
m_ViewDataDictionary: {fileID: 0}
m_VSyncEnabled: 0
m_MaximizeOnPlay: 0
m_Gizmos: 0
m_Stats: 0
m_SelectedSizes: 00000000000000000000000000000000000000000000000000000000000000000000000000000000
m_TargetDisplay: 0
m_ZoomArea:
m_HRangeLocked: 0
m_VRangeLocked: 0
hZoomLockedByDefault: 0
vZoomLockedByDefault: 0
m_HBaseRangeMin: -708
m_HBaseRangeMax: 708
m_VBaseRangeMin: -333
m_VBaseRangeMax: 333
m_HAllowExceedBaseRangeMin: 1
m_HAllowExceedBaseRangeMax: 1
m_VAllowExceedBaseRangeMin: 1
m_VAllowExceedBaseRangeMax: 1
m_ScaleWithWindow: 0
m_HSlider: 0
m_VSlider: 0
m_IgnoreScrollWheelUntilClicked: 0
m_EnableMouseInput: 1
m_EnableSliderZoomHorizontal: 0
m_EnableSliderZoomVertical: 0
m_UniformScale: 1
m_UpDirection: 1
m_DrawArea:
serializedVersion: 2
x: 0
y: 17
width: 1416
height: 666
m_Scale: {x: 1, y: 1}
m_Translation: {x: 708, y: 333}
m_MarginLeft: 0
m_MarginRight: 0
m_MarginTop: 0
m_MarginBottom: 0
m_LastShownAreaInsideMargins:
serializedVersion: 2
x: -708
y: -333
width: 1416
height: 666
m_MinimalGUI: 1
m_defaultScale: 1
m_TargetTexture: {fileID: 0}
m_CurrentColorSpace: 0
m_LastWindowPixelSize: {x: 1416, y: 683}
m_ClearInEditMode: 1
m_NoCameraWarning: 1
m_LowResolutionForAspectRatios: 00000000000000000000
m_XRRenderMode: 0
--- !u!114 &18
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12003, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_MinSize: {x: 100, y: 100}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Console
m_Image: {fileID: 111653112392082826, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 0
y: 776
width: 1957
height: 585
m_ViewDataDictionary: {fileID: 0}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/CurrentLayout.dwlt
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_PixelRect:
serializedVersion: 2
x: 0
y: 43
width: 1920
height: 997
m_ShowMode: 4
m_Title:
m_RootView: {fileID: 6}
m_MinSize: {x: 950, y: 300}
m_MaxSize: {x: 10000, y: 10000}
--- !u!114 &2
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 9}
- {fileID: 3}
m_Position:
serializedVersion: 2
x: 0
y: 30
width: 1920
height: 947
m_MinSize: {x: 683, y: 492}
m_MaxSize: {x: 14004, y: 14042}
vertical: 0
controlID: 112
--- !u!114 &3
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 1146
y: 0
width: 774
height: 947
m_MinSize: {x: 275, y: 50}
m_MaxSize: {x: 4000, y: 4000}
m_ActualView: {fileID: 13}
m_Panes:
- {fileID: 13}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &4
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 285
height: 560
m_MinSize: {x: 202, y: 221}
m_MaxSize: {x: 4002, y: 4021}
m_ActualView: {fileID: 14}
m_Panes:
- {fileID: 14}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &5
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 560
width: 1146
height: 387
m_MinSize: {x: 232, y: 271}
m_MaxSize: {x: 10002, y: 10021}
m_ActualView: {fileID: 12}
m_Panes:
- {fileID: 12}
- {fileID: 17}
m_Selected: 0
m_LastSelected: 1
--- !u!114 &6
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12008, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 7}
- {fileID: 2}
- {fileID: 8}
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 1920
height: 997
m_MinSize: {x: 950, y: 300}
m_MaxSize: {x: 10000, y: 10000}
--- !u!114 &7
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12011, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 1920
height: 30
m_MinSize: {x: 0, y: 0}
m_MaxSize: {x: 0, y: 0}
m_LastLoadedLayoutName:
--- !u!114 &8
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12042, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 977
width: 1920
height: 20
m_MinSize: {x: 0, y: 0}
m_MaxSize: {x: 0, y: 0}
--- !u!114 &9
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 10}
- {fileID: 5}
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 1146
height: 947
m_MinSize: {x: 406, y: 492}
m_MaxSize: {x: 10002, y: 14042}
vertical: 1
controlID: 69
--- !u!114 &10
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 4}
- {fileID: 11}
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 1146
height: 560
m_MinSize: {x: 406, y: 221}
m_MaxSize: {x: 8006, y: 4021}
vertical: 0
controlID: 45
--- !u!114 &11
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 285
y: 0
width: 861
height: 560
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_ActualView: {fileID: 15}
m_Panes:
- {fileID: 15}
- {fileID: 16}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &12
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_AutoRepaintOnSceneChange: 0
m_MinSize: {x: 230, y: 250}
m_MaxSize: {x: 10000, y: 10000}
m_TitleContent:
m_Text: Project
m_Image: {fileID: -7501376956915960154, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_DepthBufferBits: 0
m_Pos:
serializedVersion: 2
x: 0
y: 652
width: 1144
height: 366
m_SearchFilter:
m_NameFilter:
m_ClassNames: []
m_AssetLabels: []
m_AssetBundleNames: []
m_VersionControlStates: []
m_SoftLockControlStates: []
m_ReferencingInstanceIDs:
m_ScenePaths: []
m_ShowAllHits: 0
m_SearchArea: 0
m_Folders:
- Assets/shaders/Instancing
m_ViewMode: 1
m_StartGridSize: 64
m_LastFolders:
- Assets/shaders/Instancing
m_LastFoldersGridSize: -1
m_LastProjectPath: E:\gh\scattererGithub\Scatterer\scatterer\Shaders\scattererShaders
m_IsLocked: 0
m_FolderTreeState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: 02270000
m_LastClickedID: 9986
m_ExpandedIDs: 00000000aa260000b826000000ca9a3bffffff7f
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 1
m_ClientGUIView: {fileID: 5}
m_SearchString:
m_CreateAssetUtility:
m_EndAction: {fileID: 0}
m_InstanceID: 0
m_Path:
m_Icon: {fileID: 0}
m_ResourceFile:
m_AssetTreeState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs:
m_LastClickedID: 0
m_ExpandedIDs: 00000000aa260000b8260000
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 1
m_ClientGUIView: {fileID: 0}
m_SearchString:
m_CreateAssetUtility:
m_EndAction: {fileID: 0}
m_InstanceID: 0
m_Path:
m_Icon: {fileID: 0}
m_ResourceFile:
m_ListAreaState:
m_SelectedInstanceIDs:
m_LastClickedInstanceID: 0
m_HadKeyboardFocusLastEvent: 1
m_ExpandedInstanceIDs: 76230000602300004a22000060220000542200005e220000322200001c22000000000000
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 1
m_ClientGUIView: {fileID: 5}
m_CreateAssetUtility:
m_EndAction: {fileID: 0}
m_InstanceID: 0
m_Path:
m_Icon: {fileID: 0}
m_ResourceFile:
m_NewAssetIndexInList: -1
m_ScrollPosition: {x: 0, y: 0}
m_GridSize: 64
m_DirectoriesAreaWidth: 305
--- !u!114 &13
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_AutoRepaintOnSceneChange: 0
m_MinSize: {x: 275, y: 50}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Inspector
m_Image: {fileID: -6905738622615590433, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_DepthBufferBits: 0
m_Pos:
serializedVersion: 2
x: 1148
y: 92
width: 772
height: 926
m_ScrollPosition: {x: 0, y: 822.9551}
m_InspectorMode: 0
m_PreviewResizer:
m_CachedPref: 160
m_ControlHash: -371814159
m_PrefName: Preview_InspectorPreview
m_PreviewWindow: {fileID: 0}
--- !u!114 &14
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_AutoRepaintOnSceneChange: 0
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Hierarchy
m_Image: {fileID: -590624980919486359, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_DepthBufferBits: 0
m_Pos:
serializedVersion: 2
x: 0
y: 92
width: 283
height: 539
m_TreeViewState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: ea010000
m_LastClickedID: 0
m_ExpandedIDs: 1afcffff00000000
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 0
m_ClientGUIView: {fileID: 0}
m_SearchString:
m_ExpandedScenes:
-
m_CurrenRootInstanceID: 0
m_Locked: 0
m_CurrentSortingName: TransformSorting
--- !u!114 &15
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_AutoRepaintOnSceneChange: 1
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Scene
m_Image: {fileID: 2318424515335265636, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_DepthBufferBits: 32
m_Pos:
serializedVersion: 2
x: 287
y: 92
width: 857
height: 539
m_SceneLighting: 0
lastFramingTime: 0
m_2DMode: 0
m_isRotationLocked: 0
m_AudioPlay: 0
m_Position:
m_Target: {x: 0, y: 0, z: 0}
speed: 2
m_Value: {x: 0, y: 0, z: 0}
m_RenderMode: 0
m_ValidateTrueMetals: 0
m_SceneViewState:
showFog: 1
showMaterialUpdate: 0
showSkybox: 1
showFlares: 1
showImageEffects: 1
grid:
xGrid:
m_Target: 0
speed: 2
m_Value: 0
yGrid:
m_Target: 1
speed: 2
m_Value: 1
zGrid:
m_Target: 0
speed: 2
m_Value: 0
m_Rotation:
m_Target: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226}
speed: 2
m_Value: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226}
m_Size:
m_Target: 8.301052
speed: 2
m_Value: 8.301052
m_Ortho:
m_Target: 0
speed: 2
m_Value: 0
m_LastSceneViewRotation: {x: 0, y: 0, z: 0, w: 0}
m_LastSceneViewOrtho: 0
m_ReplacementShader: {fileID: 0}
m_ReplacementString:
m_LastLockedObject: {fileID: 0}
m_ViewIsLockedToObject: 0
--- !u!114 &16
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_AutoRepaintOnSceneChange: 1
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Game
m_Image: {fileID: -2087823869225018852, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_DepthBufferBits: 32
m_Pos:
serializedVersion: 2
x: 366
y: 17
width: 518
height: 205
m_MaximizeOnPlay: 0
m_Gizmos: 0
m_Stats: 0
m_SelectedSizes: 00000000000000000000000000000000000000000000000000000000000000000000000000000000
m_TargetDisplay: 0
m_ZoomArea:
m_HRangeLocked: 0
m_VRangeLocked: 0
m_HBaseRangeMin: -259
m_HBaseRangeMax: 259
m_VBaseRangeMin: -94
m_VBaseRangeMax: 94
m_HAllowExceedBaseRangeMin: 1
m_HAllowExceedBaseRangeMax: 1
m_VAllowExceedBaseRangeMin: 1
m_VAllowExceedBaseRangeMax: 1
m_ScaleWithWindow: 0
m_HSlider: 1
m_VSlider: 1
m_IgnoreScrollWheelUntilClicked: 0
m_EnableMouseInput: 1
m_EnableSliderZoom: 0
m_UniformScale: 1
m_UpDirection: 1
m_DrawArea:
serializedVersion: 2
x: 0
y: 17
width: 518
height: 188
m_Scale: {x: 1, y: 1}
m_Translation: {x: 259, y: 94}
m_MarginLeft: 0
m_MarginRight: 0
m_MarginTop: 0
m_MarginBottom: 0
m_LastShownAreaInsideMargins:
serializedVersion: 2
x: -259
y: -94
width: 518
height: 188
m_MinimalGUI: 1
m_defaultScale: 1
m_TargetTexture: {fileID: 0}
m_CurrentColorSpace: -1
m_LastWindowPixelSize: {x: 518, y: 205}
m_ClearInEditMode: 1
m_NoCameraWarning: 1
m_LowResolutionForAspectRatios: 01000000000100000100
--- !u!114 &17
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12003, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_AutoRepaintOnSceneChange: 0
m_MinSize: {x: 100, y: 100}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Console
m_Image: {fileID: 111653112392082826, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_DepthBufferBits: 0
m_Pos:
serializedVersion: 2
x: 0
y: 652
width: 1496
height: 366
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/CurrentMaximizeLayout.dwlt
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 3}
- {fileID: 7}
- {fileID: 9}
- {fileID: 11}
m_Position:
serializedVersion: 2
x: 0
y: 30
width: 1920
height: 987
m_MinSize: {x: 911, y: 422}
m_MaxSize: {x: 22006, y: 10022}
vertical: 0
controlID: 9359
--- !u!114 &2
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Game
m_Image: {fileID: -2087823869225018852, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 0
y: 579
width: 1118
height: 462
m_ViewDataDictionary: {fileID: 0}
m_VSyncEnabled: 0
m_MaximizeOnPlay: 1
m_Gizmos: 0
m_Stats: 0
m_SelectedSizes: 00000000000000000000000000000000000000000000000000000000000000000000000000000000
m_TargetDisplay: 0
m_ZoomArea:
m_HRangeLocked: 0
m_VRangeLocked: 0
hZoomLockedByDefault: 0
vZoomLockedByDefault: 0
m_HBaseRangeMin: -559
m_HBaseRangeMax: 559
m_VBaseRangeMin: -222.5
m_VBaseRangeMax: 222.5
m_HAllowExceedBaseRangeMin: 1
m_HAllowExceedBaseRangeMax: 1
m_VAllowExceedBaseRangeMin: 1
m_VAllowExceedBaseRangeMax: 1
m_ScaleWithWindow: 0
m_HSlider: 0
m_VSlider: 0
m_IgnoreScrollWheelUntilClicked: 0
m_EnableMouseInput: 1
m_EnableSliderZoomHorizontal: 0
m_EnableSliderZoomVertical: 0
m_UniformScale: 1
m_UpDirection: 1
m_DrawArea:
serializedVersion: 2
x: 0
y: 17
width: 1118
height: 445
m_Scale: {x: 1, y: 1}
m_Translation: {x: 559, y: 222.5}
m_MarginLeft: 0
m_MarginRight: 0
m_MarginTop: 0
m_MarginBottom: 0
m_LastShownAreaInsideMargins:
serializedVersion: 2
x: -559
y: -222.5
width: 1118
height: 445
m_MinimalGUI: 1
m_defaultScale: 1
m_TargetTexture: {fileID: 0}
m_CurrentColorSpace: 0
m_LastWindowPixelSize: {x: 1118, y: 462}
m_ClearInEditMode: 1
m_NoCameraWarning: 1
m_LowResolutionForAspectRatios: 00000000000000000000
m_XRRenderMode: 0
--- !u!114 &3
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 4}
- {fileID: 6}
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 1118
height: 987
m_MinSize: {x: 202, y: 422}
m_MaxSize: {x: 4002, y: 8022}
vertical: 1
controlID: 9339
--- !u!114 &4
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 1118
height: 506
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_ActualView: {fileID: 5}
m_Panes:
- {fileID: 5}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &5
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Scene
m_Image: {fileID: 2318424515335265636, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 0
y: 73
width: 1118
height: 487
m_ViewDataDictionary: {fileID: 0}
m_ShowContextualTools: 0
m_WindowGUID: 417d2720dfd54b04e8c7f277f5480c5b
m_Gizmos: 1
m_SceneIsLit: 1
m_SceneLighting: 1
m_2DMode: 0
m_isRotationLocked: 0
m_PlayAudio: 0
m_AudioPlay: 0
m_Position:
m_Target: {x: 0, y: 0, z: 0}
speed: 2
m_Value: {x: 0, y: 0, z: 0}
m_RenderMode: 0
m_CameraMode:
drawMode: 0
name: Shaded
section: Shading Mode
m_ValidateTrueMetals: 0
m_DoValidateTrueMetals: 0
m_SceneViewState:
showFog: 1
showMaterialUpdate: 0
showSkybox: 1
showFlares: 1
showImageEffects: 1
showParticleSystems: 1
grid:
xGrid:
m_Target: 0
speed: 2
m_Value: 0
yGrid:
m_Target: 1
speed: 2
m_Value: 1
zGrid:
m_Target: 0
speed: 2
m_Value: 0
m_Rotation:
m_Target: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226}
speed: 2
m_Value: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226}
m_Size:
m_Target: 24.136803
speed: 2
m_Value: 24.136803
m_Ortho:
m_Target: 0
speed: 2
m_Value: 0
m_CameraSettings:
m_Speed: 1
m_SpeedNormalized: 0.5
m_SpeedMin: 0.01
m_SpeedMax: 2
m_EasingEnabled: 1
m_EasingDuration: 0.4
m_AccelerationEnabled: 1
m_FieldOfView: 90
m_NearClip: 0.03
m_FarClip: 10000
m_DynamicClip: 1
m_OcclusionCulling: 0
m_ShowGlobalGrid: 1
m_LastSceneViewRotation: {x: 0, y: 0, z: 0, w: 0}
m_LastSceneViewOrtho: 0
m_ReplacementShader: {fileID: 0}
m_ReplacementString:
m_SceneVisActive: 1
m_LastLockedObject: {fileID: 0}
m_ViewIsLockedToObject: 0
--- !u!114 &6
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 506
width: 1118
height: 481
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_ActualView: {fileID: 2}
m_Panes:
- {fileID: 2}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &7
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 1118
y: 0
width: 291
height: 987
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_ActualView: {fileID: 8}
m_Panes:
- {fileID: 8}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &8
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Hierarchy
m_Image: {fileID: -590624980919486359, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 1118
y: 73
width: 289
height: 968
m_ViewDataDictionary: {fileID: 0}
m_SceneHierarchy:
m_TreeViewState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs:
m_LastClickedID: 0
m_ExpandedIDs: 76fbffff
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 0
m_ClientGUIView: {fileID: 0}
m_SearchString:
m_ExpandedScenes: []
m_CurrenRootInstanceID: 0
m_LockTracker:
m_IsLocked: 0
m_CurrentSortingName: TransformSorting
m_WindowGUID: df32a1043b8c1ff428dc088186916235
--- !u!114 &9
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 1409
y: 0
width: 234
height: 987
m_MinSize: {x: 230, y: 250}
m_MaxSize: {x: 10000, y: 10000}
m_ActualView: {fileID: 10}
m_Panes:
- {fileID: 10}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &10
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_MinSize: {x: 230, y: 250}
m_MaxSize: {x: 10000, y: 10000}
m_TitleContent:
m_Text: Project
m_Image: {fileID: -7501376956915960154, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 1409
y: 73
width: 232
height: 968
m_ViewDataDictionary: {fileID: 0}
m_SearchFilter:
m_NameFilter:
m_ClassNames: []
m_AssetLabels: []
m_AssetBundleNames: []
m_VersionControlStates: []
m_SoftLockControlStates: []
m_ReferencingInstanceIDs:
m_SceneHandles:
m_ShowAllHits: 0
m_SkipHidden: 0
m_SearchArea: 1
m_Folders:
- Assets/Shaders/Ocean/Caustics
m_ViewMode: 1
m_StartGridSize: 64
m_LastFolders:
- Assets/Shaders/Ocean/Caustics
m_LastFoldersGridSize: -1
m_LastProjectPath: E:\gh\scattererGithub\Scatterer\scatterer\Shaders\scattererShaders
m_LockTracker:
m_IsLocked: 0
m_FolderTreeState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: c22d0000
m_LastClickedID: 11714
m_ExpandedIDs: 000000003a2d00006e2d0000cc2f0000d42f000000ca9a3b
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 1
m_ClientGUIView: {fileID: 0}
m_SearchString:
m_CreateAssetUtility:
m_EndAction: {fileID: 0}
m_InstanceID: 0
m_Path:
m_Icon: {fileID: 0}
m_ResourceFile:
m_AssetTreeState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs:
m_LastClickedID: 0
m_ExpandedIDs: 000000003a2d00006e2d0000cc2f0000d42f000000ca9a3b
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 1
m_ClientGUIView: {fileID: 0}
m_SearchString:
m_CreateAssetUtility:
m_EndAction: {fileID: 0}
m_InstanceID: 0
m_Path:
m_Icon: {fileID: 0}
m_ResourceFile:
m_ListAreaState:
m_SelectedInstanceIDs: 2a310000
m_LastClickedInstanceID: 12586
m_HadKeyboardFocusLastEvent: 0
m_ExpandedInstanceIDs:
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 1
m_ClientGUIView: {fileID: 0}
m_CreateAssetUtility:
m_EndAction: {fileID: 0}
m_InstanceID: 0
m_Path:
m_Icon: {fileID: 0}
m_ResourceFile:
m_NewAssetIndexInList: -1
m_ScrollPosition: {x: 0, y: 298}
m_GridSize: 64
m_SkipHiddenPackages: 0
m_DirectoriesAreaWidth: 112
--- !u!114 &11
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 1643
y: 0
width: 277
height: 987
m_MinSize: {x: 275, y: 50}
m_MaxSize: {x: 4000, y: 4000}
m_ActualView: {fileID: 12}
m_Panes:
- {fileID: 12}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &12
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_MinSize: {x: 275, y: 50}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Inspector
m_Image: {fileID: -6905738622615590433, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_Pos:
serializedVersion: 2
x: 1643
y: 73
width: 275
height: 968
m_ViewDataDictionary: {fileID: 0}
m_OpenAddComponentMenu: 0
m_ObjectsLockedBeforeSerialization: []
m_InstanceIDsLockedBeforeSerialization:
m_LockTracker:
m_IsLocked: 0
m_PreviewResizer:
m_CachedPref: -160
m_ControlHash: -371814159
m_PrefName: Preview_InspectorPreview
m_PreviewWindow: {fileID: 0}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/EditorOnlyScriptingSettings.json
================================================
{"m_DefineSymbols":[{"first":1,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":7,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":13,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":19,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":21,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":25,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":26,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":27,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":28,"second":"UNITY_POST_PROCESSING_STACK_V2"},{"first":29,"second":"UNITY_POST_PROCESSING_STACK_V2"}],"m_AllowUnsafeCode":false}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/EditorOnlyScriptingUserSettings.json
================================================
{"m_ScriptingRuntimeVersion":1,"m_DefineSymbols":[],"m_AllowUnsafeCode":false}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/EditorSnapSettings.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 61
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 13954, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_SnapEnabled: 0
m_SnapSettings:
m_SnapValue: {x: 0.25, y: 0.25, z: 0.25}
m_SnapMultiplier: {x: 2048, y: 2048, z: 2048}
m_Rotation: 15
m_Scale: 1
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/LastSceneManagerSetup.txt
================================================
sceneSetups:
- path: Assets/Shaders/Ocean/Caustics/CausticsScene.unity
isLoaded: 1
isActive: 1
isSubScene: 0
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/LibraryFormatVersion.txt
================================================
unityRebuildLibraryVersion: 11
unityForwardCompatibleVersion: 40
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/.npmignore
================================================
automation/**
utr_output/**
.Editor/**
.yamato/**
*.zip*
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/CHANGELOG.md
================================================
# Changelog
All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [1.2.16] - 2019-02-11
Update stylesheet to pass USS validation
## [1.2.15] - 2018-11-16
Added support for non-experimental UIElements.
## [1.2.11] - 2018-09-04
Made some performance improvements to reduce impact on ReloadAssemblies.
## [1.2.9] - 2018-08-13
Test issues for the Collab History Window are now fixed.
## [1.2.7] - 2018-08-07
Toolbar drop-down will no longer show up when package is uninstalled.
## [1.2.6] - 2018-06-15
Fixed an issue where Collab's History window wouldn't load properly.
## [1.2.5] - 2018-05-21
This is the first release of *Unity Package CollabProxy*.
### Added
- Collab history and toolbar windows
- Collab view and presenter classes
- Collab Editor tests for view and presenter
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/CHANGELOG.md.meta
================================================
fileFormatVersion: 2
guid: 782c49e6e68074dc7ba12c95537825ce
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/DEPENDENCIES.md
================================================
Unity.CollabProxy.Dependencies
1.1.0-experimental
Rohit Garg
Dependencies for the CollabProxy package
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/DEPENDENCIES.md.meta
================================================
fileFormatVersion: 2
guid: 470530e667ad4475786b28fa3187ce95
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Documentation~/collab-proxy.md
================================================
# About Unity Collaborate
Collaborate is a simple way for teams to save, share, and sync their Unity project.
Please refer to the online documentation [here.](https://docs.unity3d.com/Manual/UnityCollaborate.html)
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/AssemblyInfo.cs
================================================
using System.Runtime.CompilerServices;
using UnityEngine;
[assembly: InternalsVisibleTo("Unity.CollabProxy.EditorTests")]
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/AssemblyInfo.cs.meta
================================================
fileFormatVersion: 2
guid: d4ef26aa386b44923b61c9c4b505a67c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Bootstrap.cs
================================================
using UnityEditor;
using UnityEditor.Collaboration;
using UnityEngine;
namespace CollabProxy.UI
{
[InitializeOnLoad]
public class Bootstrap
{
private const float kCollabToolbarButtonWidth = 78.0f;
static Bootstrap()
{
Collab.ShowHistoryWindow = CollabHistoryWindow.ShowHistoryWindow;
Collab.ShowToolbarAtPosition = CollabToolbarWindow.ShowCenteredAtPosition;
Collab.IsToolbarVisible = CollabToolbarWindow.IsVisible;
Collab.CloseToolbar = CollabToolbarWindow.CloseToolbar;
Toolbar.AddSubToolbar(new CollabToolbarButton
{
Width = kCollabToolbarButtonWidth
});
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Bootstrap.cs.meta
================================================
fileFormatVersion: 2
guid: 8aa8171e088f94069bbd1978a053f7dd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabAnalytics.cs
================================================
using System;
namespace UnityEditor.Collaboration
{
internal static class CollabAnalytics
{
[Serializable]
private struct CollabUserActionAnalyticsEvent
{
public string category;
public string action;
}
public static void SendUserAction(string category, string action)
{
EditorAnalytics.SendCollabUserAction(new CollabUserActionAnalyticsEvent() { category = category, action = action });
}
public static readonly string historyCategoryString = "History";
};
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabAnalytics.cs.meta
================================================
fileFormatVersion: 2
guid: f944311c8fff2479fa3ba741f6039fc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabHistoryWindow.cs
================================================
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEditor.Collaboration;
#if UNITY_2019_1_OR_NEWER
using UnityEditor.UIElements;
using UnityEngine.UIElements;
#else
using UnityEditor.Experimental.UIElements;
using UnityEngine.Experimental.UIElements;
using UnityEngine.Experimental.UIElements.StyleEnums;
#endif
using UnityEngine;
using UnityEditor.Connect;
namespace UnityEditor
{
internal class CollabHistoryWindow : EditorWindow, ICollabHistoryWindow
{
#if UNITY_2019_1_OR_NEWER
private const string ResourcesPath = "Packages/com.unity.collab-proxy/Editor/Resources/Styles/";
#else
private const string ResourcesPath = "StyleSheets/";
#endif
const string kWindowTitle = "Collab History";
const string kServiceUrl = "developer.cloud.unity3d.com";
[MenuItem("Window/Asset Management/Collab History", false, 1)]
public static void ShowHistoryWindow()
{
EditorWindow.GetWindow(kWindowTitle);
}
[MenuItem("Window/Asset Management/Collab History", true)]
public static bool ValidateShowHistoryWindow()
{
return Collab.instance.IsCollabEnabledForCurrentProject();
}
CollabHistoryPresenter m_Presenter;
Dictionary m_Views;
List m_HistoryItems = new List();
HistoryState m_State;
VisualElement m_Container;
PagedListView m_Pager;
ScrollView m_HistoryView;
int m_ItemsPerPage = 5;
string m_InProgressRev;
bool m_RevisionActionsEnabled;
public CollabHistoryWindow()
{
minSize = new Vector2(275, 50);
}
public void OnEnable()
{
SetupGUI();
name = "CollabHistory";
if (m_Presenter == null)
{
m_Presenter = new CollabHistoryPresenter(this, new CollabHistoryItemFactory(), new RevisionsService(Collab.instance, UnityConnect.instance));
}
m_Presenter.OnWindowEnabled();
}
public void OnDisable()
{
m_Presenter.OnWindowDisabled();
}
public bool revisionActionsEnabled
{
get { return m_RevisionActionsEnabled; }
set
{
if (m_RevisionActionsEnabled == value)
return;
m_RevisionActionsEnabled = value;
foreach (var historyItem in m_HistoryItems)
{
historyItem.RevisionActionsEnabled = value;
}
}
}
private void AddStyleSheetPath(VisualElement root, string path)
{
#if UNITY_2019_1_OR_NEWER
root.styleSheets.Add(EditorGUIUtility.Load(path) as StyleSheet);
#else
root.AddStyleSheetPath(path);
#endif
}
public void SetupGUI()
{
#if UNITY_2019_1_OR_NEWER
var root = this.rootVisualElement;
#else
var root = this.GetRootVisualContainer();
#endif
AddStyleSheetPath(root, ResourcesPath + "CollabHistoryCommon.uss");
if (EditorGUIUtility.isProSkin)
{
AddStyleSheetPath(root, ResourcesPath + "CollabHistoryDark.uss");
}
else
{
AddStyleSheetPath(root, ResourcesPath + "CollabHistoryLight.uss");
}
m_Container = new VisualElement();
m_Container.StretchToParentSize();
root.Add(m_Container);
m_Pager = new PagedListView()
{
name = "PagedElement",
pageSize = m_ItemsPerPage
};
var errorView = new StatusView()
{
message = "An Error Occurred",
icon = EditorGUIUtility.LoadIconRequired("Collab.Warning") as Texture,
};
var noInternetView = new StatusView()
{
message = "No Internet Connection",
icon = EditorGUIUtility.LoadIconRequired("Collab.NoInternet") as Texture,
};
var maintenanceView = new StatusView()
{
message = "Maintenance",
};
var loginView = new StatusView()
{
message = "Sign in to access Collaborate",
buttonText = "Sign in...",
callback = SignInClick,
};
var noSeatView = new StatusView()
{
message = "Ask your project owner for access to Unity Teams",
buttonText = "Learn More",
callback = NoSeatClick,
};
var waitingView = new StatusView()
{
message = "Updating...",
};
m_HistoryView = new ScrollView() { name = "HistoryContainer", showHorizontal = false};
m_HistoryView.contentContainer.StretchToParentWidth();
m_HistoryView.Add(m_Pager);
m_Views = new Dictionary()
{
{HistoryState.Error, errorView},
{HistoryState.Offline, noInternetView},
{HistoryState.Maintenance, maintenanceView},
{HistoryState.LoggedOut, loginView},
{HistoryState.NoSeat, noSeatView},
{HistoryState.Waiting, waitingView},
{HistoryState.Ready, m_HistoryView}
};
}
public void UpdateState(HistoryState state, bool force)
{
if (state == m_State && !force)
return;
m_State = state;
switch (state)
{
case HistoryState.Ready:
UpdateHistoryView(m_Pager);
break;
case HistoryState.Disabled:
Close();
return;
}
m_Container.Clear();
m_Container.Add(m_Views[m_State]);
}
public void UpdateRevisions(IEnumerable datas, string tip, int totalRevisions, int currentPage)
{
var elements = new List();
var isFullDateObtained = false; // Has everything from this date been obtained?
m_HistoryItems.Clear();
if (datas != null)
{
DateTime currentDate = DateTime.MinValue;
foreach (var data in datas)
{
if (data.timeStamp.Date != currentDate.Date)
{
elements.Add(new CollabHistoryRevisionLine(data.timeStamp, isFullDateObtained));
currentDate = data.timeStamp;
}
var item = new CollabHistoryItem(data);
m_HistoryItems.Add(item);
var container = new VisualElement();
container.style.flexDirection = FlexDirection.Row;
if (data.current)
{
isFullDateObtained = true;
container.AddToClassList("currentRevision");
container.AddToClassList("obtainedRevision");
}
else if (data.obtained)
{
container.AddToClassList("obtainedRevision");
}
else
{
container.AddToClassList("absentRevision");
}
// If we use the index as-is, the latest commit will become #1, but we want it to be last
container.Add(new CollabHistoryRevisionLine(data.index));
container.Add(item);
elements.Add(container);
}
}
m_HistoryView.scrollOffset = new Vector2(0, 0);
m_Pager.totalItems = totalRevisions;
m_Pager.curPage = currentPage;
m_Pager.items = elements;
}
public string inProgressRevision
{
get { return m_InProgressRev; }
set
{
m_InProgressRev = value;
foreach (var historyItem in m_HistoryItems)
{
historyItem.SetInProgressStatus(value);
}
}
}
public int itemsPerPage
{
set
{
if (m_ItemsPerPage == value)
return;
m_Pager.pageSize = m_ItemsPerPage;
}
}
public PageChangeAction OnPageChangeAction
{
set { m_Pager.OnPageChanged = value; }
}
public RevisionAction OnGoBackAction
{
set { CollabHistoryItem.s_OnGoBack = value; }
}
public RevisionAction OnUpdateAction
{
set { CollabHistoryItem.s_OnUpdate = value; }
}
public RevisionAction OnRestoreAction
{
set { CollabHistoryItem.s_OnRestore = value; }
}
public ShowBuildAction OnShowBuildAction
{
set { CollabHistoryItem.s_OnShowBuild = value; }
}
public Action OnShowServicesAction
{
set { CollabHistoryItem.s_OnShowServices = value; }
}
void UpdateHistoryView(VisualElement history)
{
}
void NoSeatClick()
{
var connection = UnityConnect.instance;
var env = connection.GetEnvironment();
// Map environment to url - prod is special
if (env == "production")
env = "";
else
env += "-";
var url = "https://" + env + kServiceUrl
+ "/orgs/" + connection.GetOrganizationId()
+ "/projects/" + connection.GetProjectName()
+ "/unity-teams/";
Application.OpenURL(url);
}
void SignInClick()
{
UnityConnect.instance.ShowLogin();
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabHistoryWindow.cs.meta
================================================
fileFormatVersion: 2
guid: fed9dda667cab45d398d06402bba03f4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabToolbarButton.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Collaboration;
using UnityEditor.Connect;
using UnityEditor.Web;
using UnityEngine;
namespace UnityEditor
{
internal class CollabToolbarButton : SubToolbar, IDisposable
{
// Must match s_CollabIcon array
enum CollabToolbarState
{
NeedToEnableCollab,
UpToDate,
Conflict,
OperationError,
ServerHasChanges,
FilesToPush,
InProgress,
Disabled,
Offline
}
private class CollabToolbarContent
{
readonly string m_iconName;
readonly string m_toolTip;
readonly CollabToolbarState m_state;
static Dictionary m_CollabIcons;
public CollabToolbarState RegisteredForState
{
get { return m_state; }
}
public GUIContent GuiContent
{
get
{
if (m_CollabIcons == null)
{
m_CollabIcons = new Dictionary();
}
if (!m_CollabIcons.ContainsKey(this))
{
m_CollabIcons.Add(this, EditorGUIUtility.TrTextContentWithIcon("Collab", m_toolTip, m_iconName));
}
return m_CollabIcons[this];
}
}
public CollabToolbarContent(CollabToolbarState state, string iconName, string toolTip)
{
m_state = state;
m_iconName = iconName;
m_toolTip = toolTip;
}
}
CollabToolbarContent[] m_toolbarContents;
CollabToolbarState m_CollabToolbarState = CollabToolbarState.UpToDate;
const float kCollabButtonWidth = 78.0f;
ButtonWithAnimatedIconRotation m_CollabButton;
string m_DynamicTooltip;
static bool m_ShowCollabTooltip = false;
private GUIContent currentCollabContent
{
get
{
CollabToolbarContent toolbarContent =
m_toolbarContents.FirstOrDefault(c => c.RegisteredForState.Equals(m_CollabToolbarState));
GUIContent content = new GUIContent(toolbarContent == null? m_toolbarContents.First().GuiContent : toolbarContent.GuiContent);
if (!m_ShowCollabTooltip)
{
content.tooltip = null;
}
else if (m_DynamicTooltip != "")
{
content.tooltip = m_DynamicTooltip;
}
if (Collab.instance.AreTestsRunning())
{
content.text = "CTF";
}
return content;
}
}
public CollabToolbarButton()
{
m_toolbarContents = new[]
{
new CollabToolbarContent(CollabToolbarState.NeedToEnableCollab, "CollabNew", " You need to enable collab."),
new CollabToolbarContent(CollabToolbarState.UpToDate, "Collab", " You are up to date."),
new CollabToolbarContent(CollabToolbarState.Conflict, "CollabConflict", " Please fix your conflicts prior to publishing."),
new CollabToolbarContent(CollabToolbarState.OperationError, "CollabError", " Last operation failed. Please retry later."),
new CollabToolbarContent(CollabToolbarState.ServerHasChanges, "CollabPull", " Please update, there are server changes."),
new CollabToolbarContent(CollabToolbarState.FilesToPush, "CollabPush", " You have files to publish."),
new CollabToolbarContent(CollabToolbarState.InProgress, "CollabProgress", " Operation in progress."),
new CollabToolbarContent(CollabToolbarState.Disabled, "CollabNew", " Collab is disabled."),
new CollabToolbarContent(CollabToolbarState.Offline, "CollabNew", " Please check your network connection.")
};
Collab.instance.StateChanged += OnCollabStateChanged;
UnityConnect.instance.StateChanged += OnUnityConnectStateChanged;
UnityConnect.instance.UserStateChanged += OnUnityConnectUserStateChanged;
}
void OnUnityConnectUserStateChanged(UserInfo state)
{
UpdateCollabToolbarState();
}
void OnUnityConnectStateChanged(ConnectInfo state)
{
UpdateCollabToolbarState();
}
public override void OnGUI(Rect rect)
{
DoCollabDropDown(rect);
}
Rect GUIToScreenRect(Rect guiRect)
{
Vector2 screenPoint = GUIUtility.GUIToScreenPoint(new Vector2(guiRect.x, guiRect.y));
guiRect.x = screenPoint.x;
guiRect.y = screenPoint.y;
return guiRect;
}
void ShowPopup(Rect rect)
{
// window should be centered on the button
ReserveRight(kCollabButtonWidth / 2, ref rect);
ReserveBottom(5, ref rect);
// calculate screen rect before saving assets since it might open the AssetSaveDialog window
var screenRect = GUIToScreenRect(rect);
// save all the assets
AssetDatabase.SaveAssets();
if (Collab.ShowToolbarAtPosition != null && Collab.ShowToolbarAtPosition(screenRect))
{
GUIUtility.ExitGUI();
}
}
void DoCollabDropDown(Rect rect)
{
UpdateCollabToolbarState();
GUIStyle collabButtonStyle = "OffsetDropDown";
bool showPopup = Toolbar.requestShowCollabToolbar;
Toolbar.requestShowCollabToolbar = false;
bool enable = !EditorApplication.isPlaying;
using (new EditorGUI.DisabledScope(!enable))
{
bool animate = m_CollabToolbarState == CollabToolbarState.InProgress;
EditorGUIUtility.SetIconSize(new Vector2(12, 12));
if (GetCollabButton().OnGUI(rect, currentCollabContent, animate, collabButtonStyle))
{
showPopup = true;
}
EditorGUIUtility.SetIconSize(Vector2.zero);
}
if (m_CollabToolbarState == CollabToolbarState.Disabled)
return;
if (showPopup)
{
ShowPopup(rect);
}
}
public void OnCollabStateChanged(CollabInfo info)
{
UpdateCollabToolbarState();
}
public void UpdateCollabToolbarState()
{
var currentCollabState = CollabToolbarState.UpToDate;
bool networkAvailable = UnityConnect.instance.connectInfo.online && UnityConnect.instance.connectInfo.loggedIn;
m_DynamicTooltip = "";
if (UnityConnect.instance.isDisableCollabWindow)
{
currentCollabState = CollabToolbarState.Disabled;
}
else if (networkAvailable)
{
Collab collab = Collab.instance;
CollabInfo currentInfo = collab.collabInfo;
UnityErrorInfo errInfo;
bool error = false;
if (collab.GetError((UnityConnect.UnityErrorFilter.ByContext | UnityConnect.UnityErrorFilter.ByChild), out errInfo))
{
error = (errInfo.priority <= (int)UnityConnect.UnityErrorPriority.Error);
m_DynamicTooltip = errInfo.shortMsg;
}
if (!currentInfo.ready)
{
currentCollabState = CollabToolbarState.InProgress;
}
else if (error)
{
currentCollabState = CollabToolbarState.OperationError;
}
else if (currentInfo.inProgress)
{
currentCollabState = CollabToolbarState.InProgress;
}
else
{
bool collabEnable = Collab.instance.IsCollabEnabledForCurrentProject();
if (UnityConnect.instance.projectInfo.projectBound == false || !collabEnable)
{
currentCollabState = CollabToolbarState.NeedToEnableCollab;
}
else if (currentInfo.update)
{
currentCollabState = CollabToolbarState.ServerHasChanges;
}
else if (currentInfo.conflict)
{
currentCollabState = CollabToolbarState.Conflict;
}
else if (currentInfo.publish)
{
currentCollabState = CollabToolbarState.FilesToPush;
}
}
}
else
{
currentCollabState = CollabToolbarState.Offline;
}
if (Collab.IsToolbarVisible != null)
{
if (currentCollabState != m_CollabToolbarState ||
Collab.IsToolbarVisible() == m_ShowCollabTooltip)
{
m_CollabToolbarState = currentCollabState;
m_ShowCollabTooltip = !Collab.IsToolbarVisible();
Toolbar.RepaintToolbar();
}
}
}
void ReserveRight(float width, ref Rect pos)
{
pos.x += width;
}
void ReserveBottom(float height, ref Rect pos)
{
pos.y += height;
}
ButtonWithAnimatedIconRotation GetCollabButton()
{
if (m_CollabButton == null)
{
const int repaintsPerSecond = 20;
const float animSpeed = 500f;
const bool mouseDownButton = true;
m_CollabButton = new ButtonWithAnimatedIconRotation(() => (float)EditorApplication.timeSinceStartup * animSpeed, Toolbar.RepaintToolbar, repaintsPerSecond, mouseDownButton);
}
return m_CollabButton;
}
public void Dispose()
{
Collab.instance.StateChanged -= OnCollabStateChanged;
UnityConnect.instance.StateChanged -= OnUnityConnectStateChanged;
UnityConnect.instance.UserStateChanged -= OnUnityConnectUserStateChanged;
if (m_CollabButton != null)
m_CollabButton.Clear();
}
}
} // namespace
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabToolbarButton.cs.meta
================================================
fileFormatVersion: 2
guid: 882f1a4147a284f028899b9c018e63eb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabToolbarWindow.cs
================================================
using UnityEngine;
using UnityEditor.Collaboration;
using UnityEditor.Web;
using UnityEditor.Connect;
namespace UnityEditor
{
[InitializeOnLoad]
internal class WebViewStatic : ScriptableSingleton
{
[SerializeField]
WebView m_WebView;
static public WebView GetWebView()
{
return instance.m_WebView;
}
static public void SetWebView(WebView webView)
{
instance.m_WebView = webView;
}
}
[InitializeOnLoad]
internal class CollabToolbarWindow : WebViewEditorStaticWindow, IHasCustomMenu
{
internal override WebView webView
{
get {return WebViewStatic.GetWebView(); }
set {WebViewStatic.SetWebView(value); }
}
private const string kWindowName = "Unity Collab Toolbar";
private static long s_LastClosedTime;
private static CollabToolbarWindow s_CollabToolbarWindow;
public static bool s_ToolbarIsVisible = false;
const int kWindowWidth = 320;
const int kWindowHeight = 350;
public static void CloseToolbar()
{
foreach (CollabToolbarWindow window in Resources.FindObjectsOfTypeAll())
window.Close();
}
[MenuItem("Window/Asset Management/Collab Toolbar", false /*IsValidateFunction*/, 2, true /* IsInternalMenu */)]
public static CollabToolbarWindow ShowToolbarWindow()
{
//Create a new window if it does not exist
if (s_CollabToolbarWindow == null)
{
s_CollabToolbarWindow = GetWindow(false, kWindowName) as CollabToolbarWindow;
}
return s_CollabToolbarWindow;
}
[MenuItem("Window/Asset Management/Collab Toolbar", true /*IsValidateFunction*/)]
public static bool ValidateShowToolbarWindow()
{
return true;
}
public static bool IsVisible()
{
return s_ToolbarIsVisible;
}
public static bool ShowCenteredAtPosition(Rect buttonRect)
{
buttonRect.x -= kWindowWidth / 2;
// We could not use realtimeSinceStartUp since it is set to 0 when entering/exitting playmode, we assume an increasing time when comparing time.
long nowMilliSeconds = System.DateTime.Now.Ticks / System.TimeSpan.TicksPerMillisecond;
bool justClosed = nowMilliSeconds < s_LastClosedTime + 50;
if (!justClosed)
{
// Method may have been triggered programmatically, without a user event to consume.
if (Event.current.type != EventType.Layout)
{
Event.current.Use();
}
if (s_CollabToolbarWindow == null)
s_CollabToolbarWindow = CreateInstance() as CollabToolbarWindow;
var windowSize = new Vector2(kWindowWidth, kWindowHeight);
s_CollabToolbarWindow.initialOpenUrl = "file:///" + EditorApplication.userJavascriptPackagesPath + "unityeditor-collab-toolbar/dist/index.html";
s_CollabToolbarWindow.Init();
s_CollabToolbarWindow.ShowAsDropDown(buttonRect, windowSize);
s_CollabToolbarWindow.OnFocus();
return true;
}
return false;
}
// Receives HTML title
public void OnReceiveTitle(string title)
{
titleContent.text = title;
}
public new void OnInitScripting()
{
base.OnInitScripting();
}
public override void OnEnable()
{
minSize = new Vector2(kWindowWidth, kWindowHeight);
maxSize = new Vector2(kWindowWidth, kWindowHeight);
initialOpenUrl = "file:///" + EditorApplication.userJavascriptPackagesPath + "unityeditor-collab-toolbar/dist/index.html";
base.OnEnable();
s_ToolbarIsVisible = true;
}
internal new void OnDisable()
{
s_LastClosedTime = System.DateTime.Now.Ticks / System.TimeSpan.TicksPerMillisecond;
if (s_CollabToolbarWindow)
{
s_ToolbarIsVisible = false;
NotifyVisibility(s_ToolbarIsVisible);
}
s_CollabToolbarWindow = null;
base.OnDisable();
}
public new void OnDestroy()
{
OnLostFocus();
base.OnDestroy();
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/CollabToolbarWindow.cs.meta
================================================
fileFormatVersion: 2
guid: 6f516f1ec21a54a59a92bf99db2d9535
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Presenters/CollabHistoryPresenter.cs
================================================
using System.Collections.Generic;
using UnityEditor.Connect;
using UnityEditor.Web;
namespace UnityEditor.Collaboration
{
internal class CollabHistoryPresenter
{
public const int ItemsPerPage = 5;
ICollabHistoryWindow m_Window;
ICollabHistoryItemFactory m_Factory;
IRevisionsService m_Service;
ConnectInfo m_ConnectState;
CollabInfo m_CollabState;
bool m_IsCollabError;
int m_TotalRevisions;
int m_CurrentPage;
int m_RequestedPage;
bool m_FetchInProgress;
BuildAccess m_BuildAccess;
string m_ProgressRevision;
public bool BuildServiceEnabled {get; set; }
public CollabHistoryPresenter(ICollabHistoryWindow window, ICollabHistoryItemFactory factory, IRevisionsService service)
{
m_Window = window;
m_Factory = factory;
m_Service = service;
m_CurrentPage = 0;
m_BuildAccess = new BuildAccess();
m_Service.FetchRevisionsCallback += OnFetchRevisions;
}
public void OnWindowEnabled()
{
UnityConnect.instance.StateChanged += OnConnectStateChanged;
Collab.instance.StateChanged += OnCollabStateChanged;
Collab.instance.RevisionUpdated += OnCollabRevisionUpdated;
Collab.instance.JobsCompleted += OnCollabJobsCompleted;
Collab.instance.ErrorOccurred += OnCollabError;
Collab.instance.ErrorCleared += OnCollabErrorCleared;
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
m_ConnectState = UnityConnect.instance.GetConnectInfo();
m_CollabState = Collab.instance.GetCollabInfo();
m_Window.revisionActionsEnabled = !EditorApplication.isPlayingOrWillChangePlaymode;
// Setup window callbacks
m_Window.OnPageChangeAction = OnUpdatePage;
m_Window.OnUpdateAction = OnUpdate;
m_Window.OnRestoreAction = OnRestore;
m_Window.OnGoBackAction = OnGoBack;
m_Window.OnShowBuildAction = ShowBuildForCommit;
m_Window.OnShowServicesAction = ShowServicePage;
m_Window.itemsPerPage = ItemsPerPage;
// Initialize data
UpdateBuildServiceStatus();
var state = RecalculateState();
// Only try to load the page if we're ready
if (state == HistoryState.Ready)
OnUpdatePage(m_CurrentPage);
m_Window.UpdateState(state, true);
}
public void OnWindowDisabled()
{
UnityConnect.instance.StateChanged -= OnConnectStateChanged;
Collab.instance.StateChanged -= OnCollabStateChanged;
Collab.instance.RevisionUpdated -= OnCollabRevisionUpdated;
Collab.instance.JobsCompleted -= OnCollabJobsCompleted;
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
}
private void OnConnectStateChanged(ConnectInfo state)
{
m_ConnectState = state;
m_Window.UpdateState(RecalculateState(), false);
}
private void OnCollabStateChanged(CollabInfo state)
{
// Sometimes a collab state change will trigger even though everything is the same
if (m_CollabState.Equals(state))
return;
if (m_CollabState.tip != state.tip)
OnUpdatePage(m_CurrentPage);
m_CollabState = state;
m_Window.UpdateState(RecalculateState(), false);
if (state.inProgress)
{
m_Window.inProgressRevision = m_ProgressRevision;
}
else
{
m_Window.inProgressRevision = null;
}
}
private void OnCollabRevisionUpdated(CollabInfo state)
{
OnUpdatePage(m_CurrentPage);
}
private void OnCollabJobsCompleted(CollabInfo state)
{
m_ProgressRevision = null;
}
private void OnCollabError()
{
m_IsCollabError = true;
m_Window.UpdateState(RecalculateState(), false);
}
private void OnCollabErrorCleared()
{
m_IsCollabError = false;
m_FetchInProgress = true;
m_Service.GetRevisions(m_CurrentPage * ItemsPerPage, ItemsPerPage);
m_Window.UpdateState(RecalculateState(), false);
}
private void OnPlayModeStateChanged(PlayModeStateChange stateChange)
{
// If entering play mode, disable
if (stateChange == PlayModeStateChange.ExitingEditMode ||
stateChange == PlayModeStateChange.EnteredPlayMode)
{
m_Window.revisionActionsEnabled = false;
}
// If exiting play mode, enable!
else if (stateChange == PlayModeStateChange.EnteredEditMode ||
stateChange == PlayModeStateChange.ExitingPlayMode)
{
m_Window.revisionActionsEnabled = true;
}
}
private HistoryState RecalculateState()
{
if (!m_ConnectState.online)
return HistoryState.Offline;
if (m_ConnectState.maintenance || m_CollabState.maintenance)
return HistoryState.Maintenance;
if (!m_ConnectState.loggedIn)
return HistoryState.LoggedOut;
if (!m_CollabState.seat)
return HistoryState.NoSeat;
if (!Collab.instance.IsCollabEnabledForCurrentProject())
return HistoryState.Disabled;
if (!Collab.instance.IsConnected() || !m_CollabState.ready || m_FetchInProgress)
return HistoryState.Waiting;
if (m_ConnectState.error || m_IsCollabError)
return HistoryState.Error;
return HistoryState.Ready;
}
// TODO: Eventually this can be a listener on the build service status
public void UpdateBuildServiceStatus()
{
foreach (var service in UnityConnectServiceCollection.instance.GetAllServiceInfos())
{
if (service.name.Equals("Build"))
{
BuildServiceEnabled = service.enabled;
}
}
}
public void ShowBuildForCommit(string revisionID)
{
m_BuildAccess.ShowBuildForCommit(revisionID);
}
public void ShowServicePage()
{
m_BuildAccess.ShowServicePage();
}
public void OnUpdatePage(int page)
{
m_FetchInProgress = true;
m_Service.GetRevisions(page * ItemsPerPage, ItemsPerPage);
m_Window.UpdateState(RecalculateState(), false);
m_RequestedPage = page;
}
private void OnFetchRevisions(RevisionsResult data)
{
m_FetchInProgress = false;
IEnumerable items = null;
if (data != null)
{
m_CurrentPage = m_RequestedPage;
m_TotalRevisions = data.RevisionsInRepo;
items = m_Factory.GenerateElements(data.Revisions, m_TotalRevisions, m_CurrentPage * ItemsPerPage, m_Service.tipRevision, m_Window.inProgressRevision, m_Window.revisionActionsEnabled, BuildServiceEnabled, m_Service.currentUser);
}
// State must be recalculated prior to inserting items
m_Window.UpdateState(RecalculateState(), false);
m_Window.UpdateRevisions(items, m_Service.tipRevision, m_TotalRevisions, m_CurrentPage);
}
private void OnRestore(string revisionId, bool updatetorevision)
{
m_ProgressRevision = revisionId;
Collab.instance.ResyncToRevision(revisionId);
}
private void OnGoBack(string revisionId, bool updatetorevision)
{
m_ProgressRevision = revisionId;
Collab.instance.GoBackToRevision(revisionId, false);
}
private void OnUpdate(string revisionId, bool updatetorevision)
{
m_ProgressRevision = revisionId;
Collab.instance.Update(revisionId, updatetorevision);
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Presenters/CollabHistoryPresenter.cs.meta
================================================
fileFormatVersion: 2
guid: a7c91a123806d41a0873fcdcb629b1c4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Presenters.meta
================================================
fileFormatVersion: 2
guid: d437fe60bb34f45728664a5d930c1635
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/BuildStatusButton.cs
================================================
using System;
using UnityEditor;
using UnityEditor.Collaboration;
using UnityEngine;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
#endif
namespace UnityEditor.Collaboration
{
internal class BuildStatusButton : Button
{
private readonly string iconPrefix = "Icons/Collab.Build";
private readonly string iconSuffix = ".png";
Label labelElement = new Label();
Image iconElement = new Image() {name = "BuildIcon"};
public BuildStatusButton(Action clickEvent) : base(clickEvent)
{
iconElement.image = EditorGUIUtility.Load(iconPrefix + iconSuffix) as Texture;
labelElement.text = "Build Now";
Add(iconElement);
Add(labelElement);
}
public BuildStatusButton(Action clickEvent, BuildState state, int failures) : base(clickEvent)
{
switch (state)
{
case BuildState.InProgress:
iconElement.image = EditorGUIUtility.Load(iconPrefix + iconSuffix) as Texture;
labelElement.text = "In progress";
break;
case BuildState.Failed:
iconElement.image = EditorGUIUtility.Load(iconPrefix + "Failed" + iconSuffix) as Texture;
labelElement.text = failures + ((failures == 1) ? " failure" : " failures");
break;
case BuildState.Success:
iconElement.image = EditorGUIUtility.Load(iconPrefix + "Succeeded" + iconSuffix) as Texture;
labelElement.text = "success";
break;
}
Add(iconElement);
Add(labelElement);
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/BuildStatusButton.cs.meta
================================================
fileFormatVersion: 2
guid: 0217a80286f79419daa202f69409f19b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryDropDown.cs
================================================
using UnityEngine;
using System.Collections.Generic;
using UnityEditor.Connect;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
#endif
namespace UnityEditor.Collaboration
{
internal class CollabHistoryDropDown : VisualElement
{
private readonly VisualElement m_FilesContainer;
private readonly Label m_ToggleLabel;
private int m_ChangesTotal;
private string m_RevisionId;
public CollabHistoryDropDown(ICollection changes, int changesTotal, bool changesTruncated, string revisionId)
{
m_FilesContainer = new VisualElement();
m_ChangesTotal = changesTotal;
m_RevisionId = revisionId;
m_ToggleLabel = new Label(ToggleText(false));
m_ToggleLabel.AddManipulator(new Clickable(ToggleDropdown));
Add(m_ToggleLabel);
foreach (ChangeData change in changes)
{
m_FilesContainer.Add(new CollabHistoryDropDownItem(change.path, change.action));
}
if (changesTruncated)
{
m_FilesContainer.Add(new Button(ShowAllClick)
{
text = "Show all on dashboard"
});
}
}
private void ToggleDropdown()
{
if (Contains(m_FilesContainer))
{
CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "CollapseAssets");
Remove(m_FilesContainer);
m_ToggleLabel.text = ToggleText(false);
}
else
{
CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "ExpandAssets");
Add(m_FilesContainer);
m_ToggleLabel.text = ToggleText(true);
}
}
private string ToggleText(bool open)
{
var icon = open ? "\u25bc" : "\u25b6";
var change = m_ChangesTotal == 1 ? "Change" : "Changes";
return string.Format("{0} {1} Asset {2}", icon, m_ChangesTotal, change);
}
private void ShowAllClick()
{
var host = UnityConnect.instance.GetConfigurationURL(CloudConfigUrl.CloudServicesDashboard);
var org = UnityConnect.instance.GetOrganizationId();
var proj = UnityConnect.instance.GetProjectGUID();
var url = string.Format("{0}/collab/orgs/{1}/projects/{2}/commits?commit={3}", host, org, proj, m_RevisionId);
CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "ShowAllOnDashboard");
Application.OpenURL(url);
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryDropDown.cs.meta
================================================
fileFormatVersion: 2
guid: a483595b0257945278dc75c5ff7d82ee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryDropDownItem.cs
================================================
using System;
using System.IO;
using System.Linq;
using UnityEngine;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
#endif
namespace UnityEditor.Collaboration
{
internal class CollabHistoryDropDownItem : VisualElement
{
public CollabHistoryDropDownItem(string path, string action)
{
var fileName = Path.GetFileName(path);
var isFolder = Path.GetFileNameWithoutExtension(path).Equals(fileName);
var fileIcon = GetIconElement(action, fileName, isFolder);
var metaContainer = new VisualElement();
var fileNameLabel = new Label
{
name = "FileName",
text = fileName
};
var filePathLabel = new Label
{
name = "FilePath",
text = path
};
metaContainer.Add(fileNameLabel);
metaContainer.Add(filePathLabel);
Add(fileIcon);
Add(metaContainer);
}
private Image GetIconElement(string action, string fileName, bool isFolder)
{
var prefix = isFolder ? "Folder" : "File";
var actionName = action.First().ToString().ToUpper() + action.Substring(1);
// Use the same icon for renamed and moved files
actionName = actionName.Equals("Renamed") ? "Moved" : actionName;
var iconElement = new Image
{
name = "FileIcon",
image = EditorGUIUtility.LoadIcon("Icons/Collab." + prefix + actionName + ".png")
};
return iconElement;
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryDropDownItem.cs.meta
================================================
fileFormatVersion: 2
guid: d912d4873af534bd4a9d44bf1b52f14e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryItem.cs
================================================
using System;
using System.Linq;
using System.Security.Cryptography;
using UnityEditor.Connect;
using UnityEditor.Web;
using UnityEngine;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
using UnityEngine.Experimental.UIElements.StyleEnums;
#endif
namespace UnityEditor.Collaboration
{
internal class CollabHistoryItem : VisualElement
{
public static RevisionAction s_OnRestore;
public static RevisionAction s_OnGoBack;
public static RevisionAction s_OnUpdate;
public static ShowBuildAction s_OnShowBuild;
public static Action s_OnShowServices;
private readonly string m_RevisionId;
private readonly string m_FullDescription;
private readonly DateTime m_TimeStamp;
private readonly Button m_Button;
private readonly HistoryProgressSpinner m_ProgressSpinner;
private VisualElement m_ActionsTray;
private VisualElement m_Details;
private Label m_Description;
private Label m_TimeAgo;
private readonly Button m_ExpandCollapseButton;
private bool m_Expanded;
private const int kMaxDescriptionChars = 500;
public bool RevisionActionsEnabled
{
set
{
m_Button.SetEnabled(value);
}
}
public DateTime timeStamp
{
get { return m_TimeStamp; }
}
public CollabHistoryItem(RevisionData data)
{
m_RevisionId = data.id;
m_TimeStamp = data.timeStamp;
name = "HistoryItem";
m_ActionsTray = new VisualElement {name = "HistoryItemActionsTray"};
m_ProgressSpinner = new HistoryProgressSpinner();
m_Details = new VisualElement {name = "HistoryDetail"};
var author = new Label(data.authorName) {name = "Author"};
m_TimeAgo = new Label(TimeAgo.GetString(m_TimeStamp));
m_FullDescription = data.comment;
var shouldTruncate = ShouldTruncateDescription(m_FullDescription);
if (shouldTruncate)
{
m_Description = new Label(GetTruncatedDescription(m_FullDescription));
}
else
{
m_Description = new Label(m_FullDescription);
}
m_Description.name = "RevisionDescription";
var dropdown = new CollabHistoryDropDown(data.changes, data.changesTotal, data.changesTruncated, data.id);
if (data.current)
{
m_Button = new Button(Restore) {name = "ActionButton", text = "Restore"};
}
else if (data.obtained)
{
m_Button = new Button(GoBackTo) {name = "ActionButton", text = "Go back to..."};
}
else
{
m_Button = new Button(UpdateTo) {name = "ActionButton", text = "Update"};
}
m_Button.SetEnabled(data.enabled);
m_ProgressSpinner.ProgressEnabled = data.inProgress;
m_ActionsTray.Add(m_ProgressSpinner);
m_ActionsTray.Add(m_Button);
m_Details.Add(author);
m_Details.Add(m_TimeAgo);
m_Details.Add(m_Description);
if (shouldTruncate)
{
m_ExpandCollapseButton = new Button(ToggleDescription) { name = "ToggleDescription", text = "Show More" };
m_Details.Add(m_ExpandCollapseButton);
}
if (data.buildState != BuildState.None)
{
BuildStatusButton buildButton;
if (data.buildState == BuildState.Configure)
buildButton = new BuildStatusButton(ShowServicePage);
else
buildButton = new BuildStatusButton(ShowBuildForCommit, data.buildState, data.buildFailures);
m_Details.Add(buildButton);
}
m_Details.Add(m_ActionsTray);
m_Details.Add(dropdown);
Add(m_Details);
this.schedule.Execute(UpdateTimeAgo).Every(1000 * 20);
}
public static void SetUpCallbacks(RevisionAction Restore, RevisionAction GoBack, RevisionAction Update)
{
s_OnRestore = Restore;
s_OnGoBack = GoBack;
s_OnUpdate = Update;
}
public void SetInProgressStatus(string revisionIdInProgress)
{
if (String.IsNullOrEmpty(revisionIdInProgress))
{
m_Button.SetEnabled(true);
m_ProgressSpinner.ProgressEnabled = false;
}
else
{
m_Button.SetEnabled(false);
if (m_RevisionId.Equals(revisionIdInProgress))
{
m_ProgressSpinner.ProgressEnabled = true;
}
}
}
void ShowBuildForCommit()
{
CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "ShowBuild");
if (s_OnShowBuild != null)
{
s_OnShowBuild(m_RevisionId);
}
}
void ShowServicePage()
{
CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "ShowServices");
if (s_OnShowServices != null)
{
s_OnShowServices();
}
}
void Restore()
{
CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "Restore");
if (s_OnRestore != null)
{
s_OnRestore(m_RevisionId, false);
}
}
void GoBackTo()
{
CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "GoBackTo");
if (s_OnGoBack != null)
{
s_OnGoBack(m_RevisionId, false);
}
}
void UpdateTo()
{
CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "Update");
if (s_OnUpdate != null)
{
s_OnUpdate(m_RevisionId, true);
}
}
void UpdateTimeAgo()
{
m_TimeAgo.text = TimeAgo.GetString(m_TimeStamp);
}
bool ShouldTruncateDescription(string description)
{
return description.Contains(Environment.NewLine) || description.Length > kMaxDescriptionChars;
}
string GetTruncatedDescription(string description)
{
string result = description.Contains(Environment.NewLine) ?
description.Substring(0, description.IndexOf(Environment.NewLine)) : description;
if (result.Length > kMaxDescriptionChars)
{
result = result.Substring(0, kMaxDescriptionChars) + "...";
}
return result;
}
void ToggleDescription()
{
if (m_Expanded)
{
CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "CollapseDescription");
m_Expanded = false;
m_ExpandCollapseButton.text = "Show More";
m_Description.text = GetTruncatedDescription(m_FullDescription);
}
else
{
CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "ExpandDescription");
m_Expanded = true;
m_ExpandCollapseButton.text = "Show Less";
m_Description.text = m_FullDescription;
}
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryItem.cs.meta
================================================
fileFormatVersion: 2
guid: c4c1445ee948a4124bfa9fb818a17e36
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryItemFactory.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Collaboration;
using UnityEngine;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
using UnityEngine.Experimental.UIElements.StyleEnums;
#endif
namespace UnityEditor.Collaboration
{
internal class CollabHistoryItemFactory : ICollabHistoryItemFactory
{
const int k_MaxChangesPerRevision = 10;
public IEnumerable GenerateElements(IEnumerable revisions, int totalRevisions, int startIndex, string tipRev, string inProgressRevision, bool revisionActionsEnabled, bool buildServiceEnabled, string currentUser)
{
int index = startIndex;
foreach (var rev in revisions)
{
index++;
var current = rev.revisionID == tipRev;
// Calculate build status
BuildState buildState = BuildState.None;
int buildFailures = 0;
if (rev.buildStatuses != null && rev.buildStatuses.Length > 0)
{
bool inProgress = false;
foreach (CloudBuildStatus buildStatus in rev.buildStatuses)
{
if (buildStatus.complete)
{
if (!buildStatus.success)
{
buildFailures++;
}
}
else
{
inProgress = true;
break;
}
}
if (inProgress)
{
buildState = BuildState.InProgress;
}
else if (buildFailures > 0)
{
buildState = BuildState.Failed;
}
else
{
buildState = BuildState.Success;
}
}
else if (current && !buildServiceEnabled)
{
buildState = BuildState.Configure;
}
// Calculate the number of changes performed on files and folders (not meta files)
var paths = new Dictionary();
foreach (ChangeAction change in rev.entries)
{
if (change.path.EndsWith(".meta"))
{
var path = change.path.Substring(0, change.path.Length - 5);
// Actions taken on meta files are secondary to any actions taken on the main file
if (!paths.ContainsKey(path))
paths[path] = new ChangeData() {path = path, action = change.action};
}
else
{
paths[change.path] = new ChangeData() {path = change.path, action = change.action};
}
}
var displayName = (rev.author != currentUser) ? rev.authorName : "You";
var item = new RevisionData
{
id = rev.revisionID,
index = totalRevisions - index + 1,
timeStamp = TimeStampToDateTime(rev.timeStamp),
authorName = displayName,
comment = rev.comment,
obtained = rev.isObtained,
current = current,
inProgress = (rev.revisionID == inProgressRevision),
enabled = revisionActionsEnabled,
buildState = buildState,
buildFailures = buildFailures,
changes = paths.Values.Take(k_MaxChangesPerRevision).ToList(),
changesTotal = paths.Values.Count,
changesTruncated = paths.Values.Count > k_MaxChangesPerRevision,
};
yield return item;
}
}
private static DateTime TimeStampToDateTime(double timeStamp)
{
DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
dateTime = dateTime.AddSeconds(timeStamp).ToLocalTime();
return dateTime;
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryItemFactory.cs.meta
================================================
fileFormatVersion: 2
guid: fc46f91ea1e8e4ca2ab693fef9156dbe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryRevisionLine.cs
================================================
using System;
using UnityEditor;
using UnityEditor.Collaboration;
using UnityEngine;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
#endif
namespace UnityEditor.Collaboration
{
internal class CollabHistoryRevisionLine : VisualElement
{
public CollabHistoryRevisionLine(int number)
{
AddNumber(number);
AddLine("topLine");
AddLine("bottomLine");
AddIndicator();
}
public CollabHistoryRevisionLine(DateTime date, bool isFullDateObtained)
{
AddLine(isFullDateObtained ? "obtainedDateLine" : "absentDateLine");
AddHeader(GetFormattedHeader(date));
AddToClassList("revisionLineHeader");
}
private void AddHeader(string content)
{
Add(new Label
{
text = content
});
}
private void AddIndicator()
{
Add(new VisualElement
{
name = "RevisionIndicator"
});
}
private void AddLine(string className = null)
{
var line = new VisualElement
{
name = "RevisionLine"
};
if (!String.IsNullOrEmpty(className))
{
line.AddToClassList(className);
}
Add(line);
}
private void AddNumber(int number)
{
Add(new Label
{
text = number.ToString(),
name = "RevisionIndex"
});
}
private string GetFormattedHeader(DateTime date)
{
string result = "Commits on " + date.ToString("MMM d");
switch (date.Day)
{
case 1:
case 21:
case 31:
result += "st";
break;
case 2:
case 22:
result += "nd";
break;
case 3:
case 23:
result += "rd";
break;
default:
result += "th";
break;
}
return result;
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/CollabHistoryRevisionLine.cs.meta
================================================
fileFormatVersion: 2
guid: 3c737f7a9d78541d1ab25f28f045dd32
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/HistoryProgressSpinner.cs
================================================
using UnityEngine;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
#endif
namespace UnityEditor.Collaboration
{
internal class HistoryProgressSpinner : Image
{
private readonly Texture2D[] m_StatusWheelTextures;
private bool m_ProgressEnabled;
private IVisualElementScheduledItem m_Animation;
public bool ProgressEnabled
{
set
{
if (m_ProgressEnabled == value)
return;
m_ProgressEnabled = value;
visible = value;
if (value)
{
if (m_Animation == null)
{
m_Animation = this.schedule.Execute(AnimateProgress).Every(33);
}
else
{
m_Animation.Resume();
}
}
else
{
if (m_Animation != null)
{
m_Animation.Pause();
}
}
}
}
public HistoryProgressSpinner()
{
m_StatusWheelTextures = new Texture2D[12];
for (int i = 0; i < 12; i++)
{
m_StatusWheelTextures[i] = EditorGUIUtility.LoadIcon("WaitSpin" + i.ToString("00"));
}
image = m_StatusWheelTextures[0];
style.width = m_StatusWheelTextures[0].width;
style.height = m_StatusWheelTextures[0].height;
visible = false;
}
private void AnimateProgress(TimerState obj)
{
int frame = (int)Mathf.Repeat(Time.realtimeSinceStartup * 10, 11.99f);
image = m_StatusWheelTextures[frame];
MarkDirtyRepaint();
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/HistoryProgressSpinner.cs.meta
================================================
fileFormatVersion: 2
guid: cf6aca931950a4a6a886e214e9e649c4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/ICollabHistoryItemFactory.cs
================================================
using System;
using System.Collections.Generic;
using UnityEditor.Collaboration;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
#endif
namespace UnityEditor.Collaboration
{
internal interface ICollabHistoryItemFactory
{
IEnumerable GenerateElements(IEnumerable revsRevisions, int mTotalRevisions, int startIndex, string tipRev, string inProgressRevision, bool revisionActionsEnabled, bool buildServiceEnabled, string currentUser);
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/ICollabHistoryItemFactory.cs.meta
================================================
fileFormatVersion: 2
guid: 821f5482c5a3f4389885f4432433f56f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/PagedListView.cs
================================================
using System;
using System.Collections.Generic;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
using UnityEngine.Experimental.UIElements.StyleEnums;
#endif
namespace UnityEditor.Collaboration
{
internal interface IPagerData
{
int curPage { get; }
int totalPages { get; }
PageChangeAction OnPageChanged { get; }
}
internal class PagerElement : VisualElement
{
IPagerData m_Data;
readonly Label m_PageText;
readonly Button m_DownButton;
readonly Button m_UpButton;
public PagerElement(IPagerData dataSource)
{
m_Data = dataSource;
this.style.flexDirection = FlexDirection.Row;
this.style.alignSelf = Align.Center;
Add(m_DownButton = new Button(OnPageDownClicked) {text = "\u25c5 Newer"});
m_DownButton.AddToClassList("PagerDown");
m_PageText = new Label();
m_PageText.AddToClassList("PagerLabel");
Add(m_PageText);
Add(m_UpButton = new Button(OnPageUpClicked) {text = "Older \u25bb"});
m_UpButton.AddToClassList("PagerUp");
UpdateControls();
}
void OnPageDownClicked()
{
CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "NewerPage");
m_Data.OnPageChanged(m_Data.curPage - 1);
}
void OnPageUpClicked()
{
CollabAnalytics.SendUserAction(CollabAnalytics.historyCategoryString, "OlderPage");
m_Data.OnPageChanged(m_Data.curPage + 1);
}
public void Refresh()
{
UpdateControls();
}
void UpdateControls()
{
var curPage = m_Data.curPage;
var totalPages = m_Data.totalPages;
m_PageText.text = (curPage + 1) + " / " + totalPages;
m_DownButton.SetEnabled(curPage > 0);
m_UpButton.SetEnabled(curPage < totalPages - 1);
}
}
internal enum PagerLocation
{
Top,
Bottom,
}
internal class PagedListView : VisualElement, IPagerData
{
public const int DefaultItemsPerPage = 10;
readonly VisualElement m_ItemContainer;
readonly PagerElement m_PagerTop, m_PagerBottom;
int m_PageSize = DefaultItemsPerPage;
IEnumerable m_Items;
int m_TotalItems;
int m_CurPage;
public int pageSize
{
set { m_PageSize = value; }
}
public IEnumerable items
{
set
{
m_Items = value;
LayoutItems();
}
}
public int totalItems
{
set
{
if (m_TotalItems == value)
return;
m_TotalItems = value;
UpdatePager();
}
}
public PageChangeAction OnPageChanged { get; set; }
public PagedListView()
{
m_PagerTop = new PagerElement(this);
m_ItemContainer = new VisualElement()
{
name = "PagerItems",
};
Add(m_ItemContainer);
m_Items = new List();
m_PagerBottom = new PagerElement(this);
}
void LayoutItems()
{
m_ItemContainer.Clear();
foreach (var item in m_Items)
{
m_ItemContainer.Add(item);
}
}
void UpdatePager()
{
if (m_PagerTop.parent != this && totalPages > 1 && curPage > 0)
Insert(0, m_PagerTop);
if (m_PagerTop.parent == this && (totalPages <= 1 || curPage == 0))
Remove(m_PagerTop);
if (m_PagerBottom.parent != this && totalPages > 1)
Add(m_PagerBottom);
if (m_PagerBottom.parent == this && totalPages <= 1)
Remove(m_PagerBottom);
m_PagerTop.Refresh();
m_PagerBottom.Refresh();
}
int pageCount
{
get
{
var pages = m_TotalItems / m_PageSize;
if (m_TotalItems % m_PageSize > 0)
pages++;
return pages;
}
}
public int curPage
{
get { return m_CurPage; }
set
{
m_CurPage = value;
UpdatePager();
}
}
public int totalPages
{
get
{
var extraPage = 0;
if (m_TotalItems % m_PageSize > 0)
extraPage = 1;
return m_TotalItems / m_PageSize + extraPage;
}
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/PagedListView.cs.meta
================================================
fileFormatVersion: 2
guid: 50de529b6a28f4a7093045e08810a5df
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/StatusView.cs
================================================
using System;
using UnityEditor;
using UnityEngine;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
using UnityEngine.Experimental.UIElements.StyleEnums;
#endif
namespace UnityEditor.Collaboration
{
internal class StatusView : VisualElement
{
Image m_Image;
Label m_Message;
Button m_Button;
Action m_Callback;
public Texture icon
{
get { return m_Image.image; }
set
{
m_Image.image = value;
m_Image.visible = value != null;
// Until "display: hidden" is added, this is the only way to hide an element
m_Image.style.height = value != null ? 150 : 0;
}
}
public string message
{
get { return m_Message.text; }
set
{
m_Message.text = value;
m_Message.visible = value != null;
}
}
public string buttonText
{
get { return m_Button.text; }
set
{
m_Button.text = value;
UpdateButton();
}
}
public Action callback
{
get { return m_Callback; }
set
{
m_Callback = value;
UpdateButton();
}
}
public StatusView()
{
name = "StatusView";
this.StretchToParentSize();
m_Image = new Image() { name = "StatusIcon", visible = false, style = { height = 0f }};
m_Message = new Label() { name = "StatusMessage", visible = false};
m_Button = new Button(InternalCallaback) { name = "StatusButton", visible = false};
Add(m_Image);
Add(m_Message);
Add(m_Button);
}
private void UpdateButton()
{
m_Button.visible = m_Button.text != null && m_Callback != null;
}
private void InternalCallaback()
{
m_Callback();
}
}
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views/StatusView.cs.meta
================================================
fileFormatVersion: 2
guid: 08e9894bdf0834710b22d3c0aa245ac0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab/Views.meta
================================================
fileFormatVersion: 2
guid: fd0a39b4d296d4d509b4f1dbd08d0630
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Collab.meta
================================================
fileFormatVersion: 2
guid: c18cb9388313e4287ad5895ee735c47d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles/CollabHistoryCommon.uss
================================================
.unity-button {
min-height:0;
-unity-text-align:middle-center;
margin-left:4px;
margin-top:3px;
margin-right:4px;
margin-bottom:3px;
border-left-width:6px;
border-top-width:4px;
border-right-width:6px;
border-bottom-width:4px;
padding-left:6px;
padding-top:2px;
padding-right:6px;
padding-bottom:3px;
}
.unity-label {
overflow: hidden;
margin-left:4px;
margin-top:2px;
margin-right:4px;
margin-bottom:2px;
padding-left:2px;
padding-top:1px;
min-height: 0;
}
#HistoryContainer {
flex: 1 0 0;
}
#HistoryItem {
flex: 1 0 0;
flex-direction: row;
}
#HistoryDetail {
margin-top: 10px;
margin-left: 10px;
margin-bottom: 10px;
margin-right: 10px;
padding-top: 4px;
flex: 1 0 0;
}
#Author {
-unity-font-style: bold;
font-size: 12px;
}
#HistoryDetail > Button {
align-self: flex-end;
}
CollabHistoryRevisionLine {
width: 40px;
}
#RevisionLine {
flex: 1 0 0;
margin-left: 35px;
width: 1.5px;
}
#RevisionLine.topLine {
height: 20px;
flex: 0 0 auto;
}
#RevisionLine.absentDateLine {
background-color: #797676;
}
.absentRevision #RevisionLine {
background-color: #797676;
}
.currentRevision #RevisionLine.topLine {
background-color: #797676;
}
#RevisionIndex {
position: absolute;
min-width: 23px;
-unity-text-align: middle-right;
top: 15.8px;
font-size: 9px;
}
#RevisionIndicator {
position: absolute;
background-color: #000;
border-radius: 3px;
width: 8px;
height: 8px;
border-bottom-width: 2px;
border-left-width: 2px;
border-right-width: 2px;
border-top-width: 2px;
top: 20px;
left: 32px;
}
.revisionLineHeader {
width: 200px;
height: 20px;
}
.revisionLineHeader > .unity-label {
position: absolute;
margin-left: 47px;
margin-top: 3px;
}
#PagerItems {
flex-direction: column;
}
PagerElement > .unity-label {
margin-top: 8px;
}
.absentRevision #RevisionIndicator {
border-color: #797676;
}
.absentRevision #RevisionIndex {
color: #797676;
}
.currentRevision #HistoryDetail {
border-top-width: 2px;
}
#HistoryItem #RevisionDescription {
white-space: normal;
}
#HistoryItem #ToggleDescription {
align-self: flex-start;
padding-top: 0;
padding-left: 0;
padding-right: 0;
padding-bottom: 2px;
}
#HistoryItem #ActionButton {
position: absolute;
right: 0;
}
#HistoryItem #BuildIcon {
width: 16px;
height: 13px;
}
#HistoryItemActionsTray {
flex: 1 0 0;
flex-direction: row;
align-items: center;
height: 38px;
margin-left: 10px;
margin-right: 10px;
}
CollabHistoryDropDown {
border-top-width: 1px;
}
CollabHistoryDropDown > .unity-label {
padding-top: 10px;
padding-bottom: 10px;
}
CollabHistoryDropDownItem {
flex-direction: row;
border-top-width: 1px;
overflow: hidden;
}
#FileIcon {
align-self: center;
width: 26px;
height: 26px;
}
#FileName {
-unity-font-style: bold;
padding-bottom: 0;
margin-bottom: 0;
}
#FileIcon {
padding-top: 0;
margin-top: 0;
}
#ErrorBar {
height: 24px;
background-color: #ff0000;
color: #000;
font-size: 12px;
}
#ErrorBar > #CloseButton {
position: absolute;
right: 0;
top: 0;
width: 24px;
height: 24px;
color: #000;
font-size: 18px;
-unity-font-style: bold;
}
#StatusView {
flex-direction: column;
justify-content: center;
align-self: center;
align-items: center;
flex: 1 0 0;
}
#StatusView > #StatusIcon {
width: 115px;
height: 150px;
}
#StatusView > #StatusMessage {
font-size: 22px;
width: 230px;
white-space: normal;
-unity-text-align: middle-center;
}
#StatusView > #StatusButton {
font-size: 12px;
margin-top: 20px;
background-image: none;
width: 108px;
height: 29px;
}
BuildStatusButton.unity-button {
flex-direction: row;
align-self: flex-end;
align-items: center;
margin-right: 10px;
padding-left:0;
padding-top:0;
padding-right:0;
padding-bottom:0;
}
BuildStatusButton.unity-button .unity-label {
padding-left: 2px;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles/CollabHistoryCommon.uss.meta
================================================
fileFormatVersion: 2
guid: 3a2d94c8977984b67984caeff9fa666e
ScriptedImporter:
fileIDToRecycleName:
11400000: stylesheet
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles/CollabHistoryDark.uss
================================================
#HistoryContainer {
background-color: #292929;
}
.obtainedRevision #HistoryDetail {
background-color: #333;
}
.absentRevision #HistoryDetail {
background-color: #595959;
}
#StatusView {
background-color: #292929;
}
#StatusView > #StatusMessage {
color: #959995;
}
BuildStatusButton.unity-button {
color: #B4B4B4;
background-image: resource("Builtin Skins/DarkSkin/Images/btn.png");
}
BuildStatusButton.unity-button:hover {
color: #FFF;
}
BuildStatusButton.unity-button:hover:active {
background-image: resource("Builtin Skins/DarkSkin/Images/btn act.png");
}
BuildStatusButton.unity-button:checked {
color: #F0F0F0;
background-image: resource("Builtin Skins/DarkSkin/Images/btn on.png");
}
BuildStatusButton.unity-button:hover:checked {
color: #FFF;
}
BuildStatusButton.unity-button:hover:active:checked {
background-image: resource("Builtin Skins/DarkSkin/Images/btn onact.png");
}
BuildStatusButton.unity-button:focus:checked {
background-image: resource("Builtin Skins/DarkSkin/Images/btn on focus.png");
}
CollabHistoryDropDown {
border-color: #292929;
}
CollabHistoryDropDownItem {
border-color: #292929;
}
#RevisionLine.obtainedDateLine {
background-color: #0cb4cc;
}
.obtainedRevision #RevisionLine {
background-color: #0cb4cc;
}
#RevisionIndex {
color: #0cb4cc;
}
#RevisionIndicator {
border-color: #0cb4cc;
}
.currentRevision #RevisionIndicator {
background-color: #0cb4cc;
}
.currentRevision #HistoryDetail {
border-color: #0cb4cc;
}
#StatusView > #StatusButton {
background-color: #0cb4cc;
border-color: #0cb4cc;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles/CollabHistoryDark.uss.meta
================================================
fileFormatVersion: 2
guid: 70d4d75a2877243758b0750cbc75b6eb
ScriptedImporter:
fileIDToRecycleName:
11400000: stylesheet
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles/CollabHistoryLight.uss
================================================
#HistoryContainer {
background-color: #a2a2a2;
}
.obtainedRevision #HistoryDetail {
background-color: #c2c2c2;
}
.absentRevision #HistoryDetail {
background-color: #dedede;
}
#StatusView {
background-color: #a2a2a3;
}
#StatusView > #StatusMessage {
color: #000;
}
BuildStatusButton.unity-button {
color: #111;
background-image: resource("Builtin Skins/LightSkin/Images/btn.png");
}
BuildStatusButton.unity-button:hover {
color: #000;
}
BuildStatusButton.unity-button:hover:active {
background-image: resource("Builtin Skins/LightSkin/Images/btn act.png");
}
BuildStatusButton.unity-button:checked {
color: #F0F0F0;
background-image: resource("Builtin Skins/LightSkin/Images/btn on.png");
}
BuildStatusButton.unity-button:hover:checked {
color: #000;
}
BuildStatusButton.unity-button:hover:active:checked {
background-image: resource("Builtin Skins/LightSkin/Images/btn onact.png");
}
BuildStatusButton.unity-button:focus:checked {
background-image: resource("Builtin Skins/LightSkin/Images/btn on focus.png");
}
CollabHistoryDropDown {
border-color: #a2a2a2;
}
CollabHistoryDropDownItem {
border-color: #a2a2a2;
}
#RevisionLine.obtainedDateLine {
background-color: #018d98;
}
.obtainedRevision #RevisionLine {
background-color: #018d98;
}
#RevisionIndex {
color: #018d98;
}
#RevisionIndicator {
border-color: #018d98;
}
.currentRevision #RevisionIndicator {
background-color: #018d98;
}
.currentRevision #HistoryDetail {
border-color: #018d98;
}
#StatusView > #StatusButton {
background-color: #018d98;
border-color: #018d98;
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles/CollabHistoryLight.uss.meta
================================================
fileFormatVersion: 2
guid: b52bde26a83564960bcb90217f72b910
ScriptedImporter:
fileIDToRecycleName:
11400000: stylesheet
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources/Styles.meta
================================================
fileFormatVersion: 2
guid: 6b1ae1e78552c459d9ce27048ff51c7f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Resources.meta
================================================
fileFormatVersion: 2
guid: a6ab6fd2b91214e8a9c8ec2224a528de
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Unity.CollabProxy.Editor.asmdef
================================================
{
"name": "Unity.CollabProxy.Editor",
"includePlatforms": [
"Editor"
],
"excludePlatforms": []
}
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor/Unity.CollabProxy.Editor.asmdef.meta
================================================
fileFormatVersion: 2
guid: 645165c8169474bfbbeb8fb0bcfd26f5
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Editor.meta
================================================
fileFormatVersion: 2
guid: d31e5d760880a4e52a3a75322481d0d2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/LICENSE.md
================================================
**Unity Companion Package License v1.0 ("_License_")**
Copyright © 2017 Unity Technologies ApS ("**_Unity_**")
Unity hereby grants to you a worldwide, non-exclusive, no-charge, and royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute the software that is made available with this License ("**_Software_**"), subject to the following terms and conditions:
1. *Unity Companion Use Only*. Exercise of the license granted herein is limited to exercise for the creation, use, and/or distribution of applications, software, or other content pursuant to a valid Unity development engine software license ("**_Engine License_**"). That means while use of the Software is not limited to use in the software licensed under the Engine License, the Software may not be used for any purpose other than the creation, use, and/or distribution of Engine License-dependent applications, software, or other content. No other exercise of the license granted herein is permitted.
1. *No Modification of Engine License*. Neither this License nor any exercise of the license granted herein modifies the Engine License in any way.
1. *Ownership & Grant Back to You*.
3.1. You own your content. In this License, "derivative works" means derivatives of the Software itself--works derived only from the Software by you under this License (for example, modifying the code of the Software itself to improve its efficacy); “derivative works” of the Software do not include, for example, games, apps, or content that you create using the Software. You keep all right, title, and interest to your own content.
3.2. Unity owns its content. While you keep all right, title, and interest to your own content per the above, as between Unity and you, Unity will own all right, title, and interest to all intellectual property rights (including patent, trademark, and copyright) in the Software and derivative works of the Software, and you hereby assign and agree to assign all such rights in those derivative works to Unity.
3.3. You have a license to those derivative works. Subject to this License, Unity grants to you the same worldwide, non-exclusive, no-charge, and royalty-free copyright license to derivative works of the Software you create as is granted to you for the Software under this License.
1. *Trademarks*. You are not granted any right or license under this License to use any trademarks, service marks, trade names, products names, or branding of Unity or its affiliates ("**_Trademarks_**"). Descriptive uses of Trademarks are permitted; see, for example, Unity’s Branding Usage Guidelines at [https://unity3d.com/public-relations/brand](https://unity3d.com/public-relations/brand).
1. *Notices & Third-Party Rights*. This License, including the copyright notice above, must be provided in all substantial portions of the Software and derivative works thereof (or, if that is impracticable, in any other location where such notices are customarily placed). Further, if the Software is accompanied by a Unity "third-party notices" or similar file, you acknowledge and agree that software identified in that file is governed by those separate license terms.
1. *DISCLAIMER, LIMITATION OF LIABILITY*. THE SOFTWARE AND ANY DERIVATIVE WORKS THEREOF IS PROVIDED ON AN "AS IS" BASIS, AND IS PROVIDED WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR NONINFRINGEMENT. IN NO EVENT SHALL ANY COPYRIGHT HOLDER OR AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES (WHETHER DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL, INCLUDING PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS, AND BUSINESS INTERRUPTION), OR OTHER LIABILITY WHATSOEVER, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM OR OUT OF, OR IN CONNECTION WITH, THE SOFTWARE OR ANY DERIVATIVE WORKS THEREOF OR THE USE OF OR OTHER DEALINGS IN SAME, EVEN WHERE ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1. *USE IS ACCEPTANCE and License Versions*. Your receipt and use of the Software constitutes your acceptance of this License and its terms and conditions. Software released by Unity under this License may be modified or updated and the License with it; upon any such modification or update, you will comply with the terms of the updated License for any use of any of the Software under the updated License.
1. *Use in Compliance with Law and Termination*. Your exercise of the license granted herein will at all times be in compliance with applicable law and will not infringe any proprietary rights (including intellectual property rights); this License will terminate immediately on any breach by you of this License.
1. *Severability*. If any provision of this License is held to be unenforceable or invalid, that provision will be enforced to the maximum extent possible and the other provisions will remain in full force and effect.
1. *Governing Law and Venue*. This License is governed by and construed in accordance with the laws of Denmark, except for its conflict of laws rules; the United Nations Convention on Contracts for the International Sale of Goods will not apply. If you reside (or your principal place of business is) within the United States, you and Unity agree to submit to the personal and exclusive jurisdiction of and venue in the state and federal courts located in San Francisco County, California concerning any dispute arising out of this License ("**_Dispute_**"). If you reside (or your principal place of business is) outside the United States, you and Unity agree to submit to the personal and exclusive jurisdiction of and venue in the courts located in Copenhagen, Denmark concerning any Dispute.
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/LICENSE.md.meta
================================================
fileFormatVersion: 2
guid: c754112a02f354a6696fa4f2b99e95a5
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/README.md
================================================
# Collab Proxy UPM Package
This is the packaged version of Collab, currently limited to containing the History and Toolbar windows, along with supporting classes.
## Development
Check this repository out in your {$PROJECT}/Packages/ folder, under the name com.unity.collab-proxy. The classes will be built by Unity.
## Testing
In order to run the tests, you will need to add this project to the testables key in your manifest.json - once you have done this, the tests will be picked up by the Unity Test Runner window.
## Building
You may build this project using msbuild. The commands to do so can be seen under .gitlab-ci.yml.
## Deploying
Gitlab will automatically build your project when you deploy. You can download the resulting artifact, which will be a dll, and place it in your Editor/bin/ folder. Open the package in Unity to generate the meta files, and then you will be able to publish.
We're currently looking into a way to avoid this manual process.
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/README.md.meta
================================================
fileFormatVersion: 2
guid: ac281230df7b14becb40b3c479f1b429
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: scatterer/OldShaders/scattererShaders/Library/PackageCache/com.unity.collab-proxy@1.2.16/Tests/Editor/HistoryTests.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor.Collaboration;
using UnityEngine.TestTools;
using NUnit.Framework;
namespace UnityEditor.Collaboration.Tests
{
[TestFixture]
internal class HistoryTests
{
private TestHistoryWindow _window;
private TestRevisionsService _service;
private CollabHistoryPresenter _presenter;
[SetUp]
public void SetUp()
{
_window = new TestHistoryWindow();
_service = new TestRevisionsService();
_presenter = new CollabHistoryPresenter(_window, new CollabHistoryItemFactory(), _service);
}
[TearDown]
public void TearDown()
{
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__PropagatesRevisionResult()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision(authorName: "authorName", comment: "comment", revisionID: "revisionID"),
}
};
_presenter.OnUpdatePage(0);
var item = _window.items.First();
Assert.AreEqual("revisionID", item.id);
Assert.AreEqual("authorName", item.authorName);
Assert.AreEqual("comment", item.comment);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__RevisionNumberingIsInOrder()
{
_service.result = new RevisionsResult()
{
RevisionsInRepo = 4,
Revisions = new List()
{
new Revision(revisionID: "0"),
new Revision(revisionID: "1"),
new Revision(revisionID: "2"),
new Revision(revisionID: "3"),
}
};
_presenter.OnUpdatePage(0);
var items = _window.items.ToArray();
Assert.AreEqual(4, items[0].index);
Assert.AreEqual(3, items[1].index);
Assert.AreEqual(2, items[2].index);
Assert.AreEqual(1, items[3].index);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__RevisionNumberingChangesForMorePages()
{
_service.result = new RevisionsResult()
{
RevisionsInRepo = 12,
Revisions = new List()
{
new Revision(revisionID: "0"),
new Revision(revisionID: "1"),
new Revision(revisionID: "2"),
new Revision(revisionID: "3"),
new Revision(revisionID: "4"),
}
};
_presenter.OnUpdatePage(1);
var items = _window.items.ToArray();
Assert.AreEqual(12, items[0].index);
Assert.AreEqual(11, items[1].index);
Assert.AreEqual(10, items[2].index);
Assert.AreEqual(9, items[3].index);
Assert.AreEqual(8, items[4].index);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__ObtainedIsCalculated()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision(isObtained: false),
new Revision(isObtained: true),
}
};
_presenter.OnUpdatePage(0);
var items = _window.items.ToArray();
Assert.IsFalse(items[0].obtained);
Assert.IsTrue(items[1].obtained);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__CurrentIsCalculated()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision(revisionID: "1"),
new Revision(revisionID: "2"),
new Revision(revisionID: "3"),
}
};
_service.tipRevision = "2";
_presenter.OnUpdatePage(0);
var items = _window.items.ToArray();
Assert.AreEqual(false, items[0].current);
Assert.AreEqual(true, items[1].current);
Assert.AreEqual(false, items[2].current);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__InProgressIsCalculated()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision(revisionID: "1"),
new Revision(revisionID: "2"),
new Revision(revisionID: "3"),
}
};
_window.inProgressRevision = "2";
_presenter.OnUpdatePage(0);
var items = _window.items.ToArray();
Assert.IsFalse(items[0].inProgress);
Assert.IsTrue(items[1].inProgress);
Assert.IsFalse(items[2].inProgress);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__EnabledIsCalculated()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision(revisionID: "0"),
}
};
_window.revisionActionsEnabled = true;
_presenter.OnUpdatePage(0);
var item = _window.items.First();
Assert.AreEqual(true, item.enabled);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__DisabledIsCalculated()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision(revisionID: "0"),
}
};
_window.revisionActionsEnabled = false;
_presenter.OnUpdatePage(0);
var item = _window.items.First();
Assert.AreEqual(false, item.enabled);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasNoneWhenNotTip()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision(revisionID: "1"),
}
};
_service.tipRevision = "0";
_presenter.BuildServiceEnabled = false;
_presenter.OnUpdatePage(0);
var item = _window.items.First();
Assert.AreEqual(BuildState.None, item.buildState);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__BuildStateTipHasNoneWhenEnabled()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision(revisionID: "0"),
}
};
_service.tipRevision = "0";
_presenter.BuildServiceEnabled = true;
_presenter.OnUpdatePage(0);
var item = _window.items.First();
Assert.AreEqual(BuildState.None, item.buildState);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasConfigureWhenTip()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision(revisionID: "0"),
}
};
_service.tipRevision = "0";
_presenter.BuildServiceEnabled = false;
_presenter.OnUpdatePage(0);
var item = _window.items.First();
Assert.AreEqual(BuildState.Configure, item.buildState);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasConfigureWhenZeroBuildStatus()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision(revisionID: "0"),
}
};
_service.tipRevision = "0";
_presenter.BuildServiceEnabled = false;
_presenter.OnUpdatePage(0);
var item = _window.items.First();
Assert.AreEqual(BuildState.Configure, item.buildState);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasNoneWhenZeroBuildStatuses()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision(revisionID: "0"),
}
};
_service.tipRevision = "0";
_presenter.BuildServiceEnabled = true;
_presenter.OnUpdatePage(0);
var item = _window.items.First();
Assert.AreEqual(BuildState.None, item.buildState);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasSuccessWhenCompleteAndSucceeded()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision
(
revisionID: "0",
buildStatuses: new CloudBuildStatus[1]
{
new CloudBuildStatus(complete: true, success: true),
}
),
}
};
_service.tipRevision = "0";
_presenter.BuildServiceEnabled = true;
_presenter.OnUpdatePage(0);
var item = _window.items.First();
Assert.AreEqual(BuildState.Success, item.buildState);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasInProgress()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision
(
revisionID: "0",
buildStatuses: new CloudBuildStatus[1]
{
new CloudBuildStatus(complete: false),
}
),
}
};
_service.tipRevision = "0";
_presenter.BuildServiceEnabled = true;
_presenter.OnUpdatePage(0);
var item = _window.items.First();
Assert.AreEqual(BuildState.InProgress, item.buildState);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasFailure()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision
(
revisionID: "0",
buildStatuses: new CloudBuildStatus[1]
{
new CloudBuildStatus(complete: true, success: false),
}
),
}
};
_service.tipRevision = "0";
_presenter.BuildServiceEnabled = true;
_presenter.OnUpdatePage(0);
var item = _window.items.First();
Assert.AreEqual(BuildState.Failed, item.buildState);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__BuildStateHasFailureWhenAnyBuildsFail()
{
_service.result = new RevisionsResult()
{
Revisions = new List()
{
new Revision
(
revisionID: "0",
buildStatuses: new CloudBuildStatus[3]
{
new CloudBuildStatus(complete: true, success: false),
new CloudBuildStatus(complete: true, success: false),
new CloudBuildStatus(complete: true, success: true),
}
),
}
};
_service.tipRevision = "0";
_presenter.BuildServiceEnabled = true;
_presenter.OnUpdatePage(0);
var item = _window.items.First();
Assert.AreEqual(BuildState.Failed, item.buildState);
}
[Test]
public void CollabHistoryPresenter_OnUpdatePage__ChangesPropagateThrough()
{
_service.result = new RevisionsResult()
{
Revisions = new List