diff --git a/TrueTrace.unitypackage b/TrueTrace.unitypackage index d605571e..e59532e7 100644 Binary files a/TrueTrace.unitypackage and b/TrueTrace.unitypackage differ diff --git a/TrueTrace/DemoScene.asset b/TrueTrace/DemoScene.asset index 978e6ad7..a38913c1 100644 --- a/TrueTrace/DemoScene.asset +++ b/TrueTrace/DemoScene.asset @@ -19,41 +19,41 @@ MonoBehaviour: UseRussianRoulette: 1 UseNEE: 1 DoTLASUpdates: 1 - Accumulate: 1 + Accumulate: 0 PPBloom: 0 - BloomStrength: 0.372 + BloomStrength: 0.5 PPDoF: 0 - DoFAperature: 0.09010013 + DoFAperature: 0.2 DoFAperatureScale: 1 - DoFFocal: 2.6470158 + DoFFocal: 5.2216897 PPExposure: 0 ExposureAuto: 1 - PPToneMap: 1 + PPToneMap: 0 PPTAA: 0 RenderScale: 1 - DenoiserMethod: 0 - UpscalerMethod: 0 + DenoiserMethod: 1 + UpscalerMethod: 2 UseReSTIRGITemporal: 1 UseReSTIRGISpatial: 1 UseReSTIRGI: 1 ReSTIRGISpatialCount: 24 ReSTIRGISpatialRadius: 50 - ReSTIRGITemporalMCap: 60 + ReSTIRGITemporalMCap: 20 ReSTIRGIUpdateRate: 0 DoReSTIRGIConnectionValidation: 1 - Exposure: 0.01 + Exposure: 41.7 DoPartialRendering: 0 - PartialRenderingFactor: 2 - DoFirefly: 1 + PartialRenderingFactor: 1 + DoFirefly: 0 ImprovedPrimaryHit: 1 RISCount: 12 ToneMapper: 0 SkyDesaturate: 0 - ClayColor: {x: 1, y: 1, z: 1} - GroundColor: {x: 0.0754717, y: 0.0754717, z: 0.0754717} - FireflyFrameCount: 24 + ClayColor: {x: 0.5, y: 0.5, z: 0.5} + GroundColor: {x: 0.11320752, y: 0.11320752, z: 0.11320752} + FireflyFrameCount: 0 FireflyFrameInterval: 1 - FireflyStrength: 0.18 + FireflyStrength: 1 FireflyOffset: 0 OIDNFrameCount: 0 DoSharpen: 0 @@ -63,9 +63,9 @@ MonoBehaviour: LightEnergyScale: 1 BackgroundType: 0 BackgroundIntensity: {x: 1, y: 1} - SceneBackgroundColor: {x: 0, y: 0, z: 0} + SceneBackgroundColor: {x: 1, y: 1, z: 1} SecondaryBackgroundType: 0 - SecondarySceneBackgroundColor: {x: 0, y: 0, z: 0} + SecondarySceneBackgroundColor: {x: 1, y: 1, z: 1} HDRILongLat: {x: 0, y: 0} HDRIScale: {x: 1, y: 1} LEMEnergyScale: 1 @@ -73,17 +73,29 @@ MonoBehaviour: SecondarySkyDesaturate: 0 MatChangeResetsAccum: 1 PPFXAA: 0 - OIDNBlendRatio: 0.59 + OIDNBlendRatio: 1 ConvBloom: 1 - ConvStrength: 0.13 + ConvStrength: 0.3 ConvBloomThreshold: 0 ConvBloomSize: {x: 1, y: 1} ConvBloomDistExp: 0 ConvBloomDistExpClampMin: 1 ConvBloomDistExpScale: 1 - PrimaryBackgroundTintColor: {x: 0.32200065, y: 0.764151, z: 0.6593174} + PrimaryBackgroundTintColor: {x: 1, y: 1, z: 1} PrimaryBackgroundTint: 0 PrimaryBackgroundContrast: 1 - FogDensity: 0.001 + FogDensity: 0.2 + FogHeight: 80 FogColor: {x: 1, y: 1, z: 1} MaxSampCount: 99999999 + DoChromaAber: 0 + ChromaDistort: 0.14 + DoBCS: 0 + Saturation: 1 + Contrast: 1 + DoVignette: 0 + innerVignette: 0.5 + outerVignette: 1.2 + strengthVignette: 0.8 + curveVignette: 0.5 + ColorVignette: {x: 0, y: 0, z: 0} diff --git a/TrueTrace/DemoScene.asset.meta b/TrueTrace/DemoScene.asset.meta index 20e5204a..b30aa756 100644 --- a/TrueTrace/DemoScene.asset.meta +++ b/TrueTrace/DemoScene.asset.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: f713a0b44e81ebd429d4ffe701492e4b +guid: 39f2ad3368c9a444db0e1875dbc664be NativeFormatImporter: externalObjects: {} - mainObjectFileID: 0 + mainObjectFileID: 11400000 userData: assetBundleName: assetBundleVariant: diff --git a/TrueTrace/DemoScene.unity b/TrueTrace/DemoScene.unity index ba637171..2301abc5 100644 --- a/TrueTrace/DemoScene.unity +++ b/TrueTrace/DemoScene.unity @@ -3461,7 +3461,7 @@ MonoBehaviour: SpecTrans: - 0 - 0 - FollowMaterial: 0101 + FollowMaterial: 0000 ScatterDist: - 0 - 0 @@ -3472,7 +3472,7 @@ MonoBehaviour: - 0.1 - 0.1 NormalStrength: - - 1 + - 0.62 - 1 Hue: - 0 @@ -11229,7 +11229,7 @@ MonoBehaviour: LightBLASRefitKernel: 9 CompactedMeshData: 0 InstanceReferences: 0 - NeedsToUpdate: 0 + NeedsToUpdate: 1 FailureCount: 0 TotalTriangles: 0 IsSkinnedGroup: 0 @@ -13479,12 +13479,12 @@ MonoBehaviour: m_EditorClassIdentifier: ThisLight: {fileID: 610660759} ThisLightData: - Radiance: {x: 0, y: 0, z: 0} - Position: {x: 0, y: 0, z: 0} - Direction: {x: 0, y: 0, z: 0} - Type: 0 + Radiance: {x: 32, y: 32, z: 32} + Position: {x: -1.4816499, y: 5.724826, z: -1.1294421} + Direction: {x: -0.40884805, y: 0.8689685, z: -0.2788136} + Type: 1 SpotAngle: {x: 0, y: 0} - ZAxisRotation: 0 + ZAxisRotation: 0.066060774 Softness: 0 IESTex: {x: 0, y: 0} ArrayIndex: 0 @@ -20109,7 +20109,7 @@ MonoBehaviour: LightBLASRefitKernel: 9 CompactedMeshData: 0 InstanceReferences: 0 - NeedsToUpdate: 0 + NeedsToUpdate: 1 FailureCount: 0 TotalTriangles: 0 IsSkinnedGroup: 0 @@ -26765,7 +26765,7 @@ MonoBehaviour: m_EditorClassIdentifier: MaterialOptions: 0000000000000000 TransmissionColor: - - {x: 0, y: 0, z: 0} + - {x: 1, y: 1, z: 1} - {x: 0, y: 0, z: 0} BaseColor: - {x: 1, y: 1, z: 1} @@ -26818,7 +26818,7 @@ MonoBehaviour: SpecTrans: - 0 - 0 - FollowMaterial: 0101 + FollowMaterial: 0100 ScatterDist: - 0 - 0 @@ -29101,7 +29101,7 @@ MonoBehaviour: LightBLASRefitKernel: 9 CompactedMeshData: 0 InstanceReferences: 0 - NeedsToUpdate: 0 + NeedsToUpdate: 1 FailureCount: 0 TotalTriangles: 0 IsSkinnedGroup: 0 @@ -29167,7 +29167,7 @@ MonoBehaviour: Roughness: - 0 IOR: - - 1.35 + - 2.18 Metallic: - 0 SpecularTint: @@ -33735,11 +33735,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: e9c10216ea5531c4d82893474778943b, type: 3} m_Name: m_EditorClassIdentifier: + LocalTTSettingsName: DemoSceneMain HDRPorURPRenderInScene: 0 Atmo: _TransmittanceLUT: {fileID: 0} MultiScatterTex: {fileID: 0} IrradianceTex: {fileID: 0} + CloudShapeTex: {fileID: 0} + CloudShapeDetailTex: {fileID: 0} + WeatherTex: {fileID: 0} Assets: {fileID: 0} ShadingShader: {fileID: 0} ScreenSpaceInfo: {fileID: 0} @@ -33751,7 +33755,7 @@ MonoBehaviour: PrevReSTIRGI: 0 DoPanorama: 0 DoChainedImages: 0 - LocalTTSettings: {fileID: 11400000, guid: f713a0b44e81ebd429d4ffe701492e4b, type: 2} + LocalTTSettings: {fileID: 11400000, guid: 39f2ad3368c9a444db0e1875dbc664be, type: 2} SkyboxTexture: {fileID: 0} AtmoNumLayers: 4 FramesSinceStart: 0 @@ -49922,7 +49926,7 @@ MonoBehaviour: LightBLASRefitKernel: 9 CompactedMeshData: 0 InstanceReferences: 0 - NeedsToUpdate: 0 + NeedsToUpdate: 1 FailureCount: 0 TotalTriangles: 0 IsSkinnedGroup: 0 @@ -2156412,9 +2156416,9 @@ MonoBehaviour: - {fileID: 2800000, guid: 6e15f02feebc6ba44bae8089381dd33e, type: 3} - {fileID: 2800000, guid: 7b87e3c0b539e4e409a7fda079a40320, type: 3} - {fileID: 2800000, guid: 31be800b72cfa1a40bfe519f1ab8a4e6, type: 3} - - {fileID: 2800000, guid: b73406b81b6cd484181dedc3f25e648f, type: 3} - - {fileID: 2800000, guid: 485233ca597afda4fb7d18c571b6a801, type: 3} - - {fileID: 2800000, guid: 2fd9297c087b1334195e475b89ed03cf, type: 3} + - {fileID: 2800000, guid: 180cd58a9e745954f9f78d8b15b59cca, type: 3} + - {fileID: 2800000, guid: edfe82195fdbf7f4d8fa7a59282650a3, type: 3} + - {fileID: 2800000, guid: 64ec855af9265d74fa3d391fbf0516cd, type: 3} - {fileID: 2800000, guid: 0f9d9bc0a5e565c45b3ec4eeb84952a6, type: 3} - {fileID: 2800000, guid: 29609964099711e45a99687857e420f5, type: 3} - {fileID: 2800000, guid: 59064697770591343a2192c9fcacab77, type: 3} @@ -2156444,9 +2156448,9 @@ MonoBehaviour: - {fileID: 2800000, guid: 6e15f02feebc6ba44bae8089381dd33e, type: 3} - {fileID: 2800000, guid: 7b87e3c0b539e4e409a7fda079a40320, type: 3} - {fileID: 2800000, guid: 31be800b72cfa1a40bfe519f1ab8a4e6, type: 3} - - {fileID: 2800000, guid: b73406b81b6cd484181dedc3f25e648f, type: 3} - - {fileID: 2800000, guid: 485233ca597afda4fb7d18c571b6a801, type: 3} - - {fileID: 2800000, guid: 2fd9297c087b1334195e475b89ed03cf, type: 3} + - {fileID: 2800000, guid: 180cd58a9e745954f9f78d8b15b59cca, type: 3} + - {fileID: 2800000, guid: edfe82195fdbf7f4d8fa7a59282650a3, type: 3} + - {fileID: 2800000, guid: 64ec855af9265d74fa3d391fbf0516cd, type: 3} - {fileID: 2800000, guid: 0f9d9bc0a5e565c45b3ec4eeb84952a6, type: 3} - {fileID: 2800000, guid: 29609964099711e45a99687857e420f5, type: 3} - {fileID: 2800000, guid: 59064697770591343a2192c9fcacab77, type: 3} @@ -2162362,7 +2162366,7 @@ MonoBehaviour: LightBLASRefitKernel: 9 CompactedMeshData: 3 InstanceReferences: 0 - NeedsToUpdate: 0 + NeedsToUpdate: 1 FailureCount: 0 TotalTriangles: 0 IsSkinnedGroup: 0 diff --git a/TrueTrace/Editor/PathTracerSettings.cs b/TrueTrace/Editor/PathTracerSettings.cs index 169c2caf..80bfed49 100644 --- a/TrueTrace/Editor/PathTracerSettings.cs +++ b/TrueTrace/Editor/PathTracerSettings.cs @@ -27,7 +27,6 @@ public static void ShowWindow() { } public Toggle NEEToggle; - public Toggle DingToggle; public Button BVHBuild; public Button ScreenShotButton; public Button StaticButton; @@ -38,7 +37,6 @@ public static void ShowWindow() { public AssetManager Assets; public InstancedManager Instancer; private bool Cleared; - private AudioClip DingNoise; [SerializeField] public Camera SelectedCamera; [SerializeField] public bool ClayMode = false; [SerializeField] public Vector3 ClayColor = new Vector3(0.5f,0.5f,0.5f); @@ -94,7 +92,6 @@ public static void ShowWindow() { [SerializeField] public float IndirectBoost = 1; [SerializeField] public int BackgroundType = 0; [SerializeField] public int SecondaryBackgroundType = 0; - [SerializeField] public bool DoDing = true; [SerializeField] public bool DoSaving = true; [SerializeField] public float SkyDesaturate = 0; [SerializeField] public float SecondarySkyDesaturate = 0; @@ -111,6 +108,7 @@ public static void ShowWindow() { [SerializeField] public bool MatChangeResetsAccum = false; [SerializeField] public float OIDNBlendRatio = 1.0f; [SerializeField] public float FogDensity = 0.0002f; + [SerializeField] public float FogHeight = 80.0f; [SerializeField] public bool ConvBloom = false; [SerializeField] public float ConvStrength = 1.37f; [SerializeField] public float ConvBloomThreshold = 13.23f; @@ -118,6 +116,18 @@ public static void ShowWindow() { [SerializeField] public float ConvBloomDistExp = 0; [SerializeField] public float ConvBloomDistExpClampMin = 1; [SerializeField] public float ConvBloomDistExpScale = 1; + [SerializeField] public bool DoChromaAber = false; + [SerializeField] public float ChromaDistort = 0.3f; + [SerializeField] public bool DoBCS = false; + [SerializeField] public float Saturation = 1.0f; + [SerializeField] public float Contrast = 1.0f; + [SerializeField] public bool DoVignette = false; + [SerializeField] public float innerVignette = 0.5f; + [SerializeField] public float outerVignette = 1.2f; + [SerializeField] public float strengthVignette = 0.8f; + [SerializeField] public float curveVignette = 0.5f; + [SerializeField] public Color ColorVignette = Color.black; + [SerializeField] public bool ShowPostProcessMenu = true; public bool GetGlobalDefine(string DefineToGet) { string globalDefinesPath = TTPathFinder.GetGlobalDefinesPath(); @@ -205,6 +215,7 @@ void OnDisable() { private void OnStartAsyncCombined() { EditorUtility.SetDirty(GameObject.Find("Scene").GetComponent()); BuildWatch.Start(); + GameObject.Find("Scene").GetComponent().ClearAll(); GameObject.Find("Scene").GetComponent().EditorBuild(); } @@ -267,6 +278,57 @@ private void ConstructInstances() { } } + + private void ConstructInstancesSelective(Mesh SelectedMesh) { + SourceMeshes = new List(); + SourceMeshes.Add(SelectedMesh); + Objects = new List>(); + Objects.Add(new List()); + ChildObjects = new List(); + Transform Source = GameObject.Find("Scene").transform; + Transform InstanceStorage = GameObject.Find("InstancedStorage").transform; + int ChildrenLeft = Source.childCount; + int CurrentChild = 0; + while(CurrentChild < ChildrenLeft) { + Transform CurrentObject = Source.GetChild(CurrentChild++); + if(CurrentObject.gameObject.activeInHierarchy) GrabChildren(CurrentObject); + } + + int ChildCount = ChildObjects.Count; + for(int i = ChildCount - 1; i >= 0; i--) { + if(ChildObjects[i].GetComponent() != null) { + continue; + } + if(ChildObjects[i].GetComponent() != null && ChildObjects[i].GetComponent() != null) { + var mesh = ChildObjects[i].GetComponent().sharedMesh; + if(SourceMeshes.Contains(mesh)) { + int Index = SourceMeshes.IndexOf(mesh); + Objects[Index].Add(ChildObjects[i].gameObject); + } else { + // SourceMeshes.Add(mesh); + // Objects.Add(new List()); + // Objects[Objects.Count - 1].Add(ChildObjects[i].gameObject); + } + } + } + int UniqueMeshCounts = SourceMeshes.Count; + for(int i = 0; i < UniqueMeshCounts; i++) { + if(Objects[i].Count > 1) { + int Count = Objects[i].Count; + GameObject InstancedParent = Instantiate(Objects[i][0], new Vector3(0,-100,0), Quaternion.identity, InstanceStorage); + if(InstancedParent.GetComponent() == null) InstancedParent.AddComponent(); + for(int i2 = Count - 1; i2 >= 0; i2--) { + DestroyImmediate(Objects[i][i2].GetComponent()); + DestroyImmediate(Objects[i][i2].GetComponent()); + DestroyImmediate(Objects[i][i2].GetComponent()); + if(InstancedParent.GetComponent()) DestroyImmediate(Objects[i][i2].GetComponent()); + (Objects[i][i2].AddComponent()).InstanceParent = InstancedParent.GetComponent(); + // Objects[i][i2].GetComponent().InstanceParent = InstancedParent.GetComponent(); + } + } + } + } + private void OptimizeForStatic() { GameObject[] AllObjects = GameObject.FindObjectsOfType();//("Untagged"); foreach(GameObject obj in AllObjects) { @@ -551,13 +613,14 @@ public void ConfirmPopup() { OnFocus(); if(Camera.main != null && Camera.main.gameObject.GetComponent() == null) Camera.main.gameObject.AddComponent(); - rootVisualElement.Remove(RearrangeElement); + MainSource.Remove(RearrangeElement); CreateGUI(); rootVisualElement.Add(MainSource); Assets.UpdateMaterialDefinition(); } VisualElement HardSettingsMenu; + VisualElement PostProcessingMenu; VisualElement SceneSettingsMenu; PopupField BackgroundSettingsField; PopupField SecondaryBackgroundSettingsField; @@ -1621,6 +1684,13 @@ void AddHardSettingsToMenu() { Toggle NonAccurateLightTriToggle = new Toggle() {value = (definesList.Contains("AccurateLightTris")), text = "Enable Emissive Texture Aware Light BVH"}; NonAccurateLightTriToggle.RegisterValueChangedCallback(evt => {if(evt.newValue) AddDefine("AccurateLightTris"); else RemoveDefine("AccurateLightTris");}); + + Toggle LoadTTSettingsFromResourcesToggle = new Toggle() {value = (definesList.Contains("LoadTTSettingsFromResources")), text = "Load TTSettings from Global File"}; + LoadTTSettingsFromResourcesToggle.RegisterValueChangedCallback(evt => {if(evt.newValue) AddDefine("LoadTTSettingsFromResources"); else RemoveDefine("LoadTTSettingsFromResources");}); + + Toggle VerboseToggle = new Toggle() {value = (definesList.Contains("TTVerbose")), text = "Enable Verbose Logging"}; + VerboseToggle.RegisterValueChangedCallback(evt => {if(evt.newValue) AddDefine("TTVerbose"); else RemoveDefine("TTVerbose");}); + VisualElement ClayColorBox = new VisualElement(); @@ -1653,6 +1723,8 @@ void AddHardSettingsToMenu() { OIDNToggle.SetEnabled(false); RadCacheToggle.SetEnabled(false); NonAccurateLightTriToggle.SetEnabled(false); + LoadTTSettingsFromResourcesToggle.SetEnabled(false); + VerboseToggle.SetEnabled(false); } else { HardwareRTToggle.SetEnabled(true); BindlessToggle.SetEnabled(true); @@ -1660,6 +1732,8 @@ void AddHardSettingsToMenu() { OIDNToggle.SetEnabled(true); RadCacheToggle.SetEnabled(true); NonAccurateLightTriToggle.SetEnabled(true); + LoadTTSettingsFromResourcesToggle.SetEnabled(true); + VerboseToggle.SetEnabled(true); } @@ -1707,6 +1781,8 @@ void AddHardSettingsToMenu() { NonPlayContainer.Add(OIDNToggle); NonPlayContainer.Add(RadCacheToggle); NonPlayContainer.Add(NonAccurateLightTriToggle); + NonPlayContainer.Add(LoadTTSettingsFromResourcesToggle); + NonPlayContainer.Add(VerboseToggle); NonPlayContainer.Add(new Label("-------------")); Label PlayLabel = new Label("-- THESE CAN BE MODIFIED ON THE FLY/DURING PLAY --"); @@ -1732,6 +1808,13 @@ void AddHardSettingsToMenu() { FogSlider.style.width = 200; FogSlider.ElementAt(0).style.minWidth = 65; FogSlider.RegisterValueChangedCallback(evt => {FogDensity = evt.newValue; RayMaster.LocalTTSettings.FogDensity = FogDensity;}); + + Slider FogHeightSlider = new Slider() {label = "Fog Height: ", value = FogHeight, highValue = 80.0f, lowValue = 0.00001f}; + FogHeightSlider.showInputField = true; + FogHeightSlider.style.width = 200; + FogHeightSlider.ElementAt(0).style.minWidth = 65; + FogHeightSlider.value = FogHeight; + FogHeightSlider.RegisterValueChangedCallback(evt => {FogHeight = evt.newValue; RayMaster.LocalTTSettings.FogHeight = FogHeight;}); ColorField FogColorField = new ColorField(); FogColorField.value = FogColor; @@ -1739,13 +1822,12 @@ void AddHardSettingsToMenu() { FogColorField.RegisterValueChangedCallback(evt => {FogColor = evt.newValue; RayMaster.LocalTTSettings.FogColor = new Vector3(FogColor.r,FogColor.g,FogColor.b);}); PlayContainer.Add(FogSlider); + PlayContainer.Add(FogHeightSlider); PlayContainer.Add(FogColorField); PlayContainer.Add(new Label("-------------")); - DingToggle = new Toggle() {value = DoDing, text = "Play Ding When Build Finishes"}; - DingToggle.RegisterValueChangedCallback(evt => {DoDing = evt.newValue; RayTracingMaster.DoDing = DoDing;}); MaterialHelperToggle = new Toggle() {value = !(definesList.Contains("HIDEMATERIALREATIONS")), text = "Show Material Helper Lines"}; MaterialHelperToggle.RegisterValueChangedCallback(evt => {if(evt.newValue) RemoveDefine("HIDEMATERIALREATIONS"); else AddDefine("HIDEMATERIALREATIONS");}); @@ -1820,7 +1902,6 @@ void AddHardSettingsToMenu() { HardSettingsMenu.Add(PlayLabel); HardSettingsMenu.Add(PlayContainer); HardSettingsMenu.Add(ClayModeToggle); - HardSettingsMenu.Add(DingToggle); HardSettingsMenu.Add(MaterialHelperToggle); HardSettingsMenu.Add(MatChangeResetsAccumToggle); if(ClayMode) HardSettingsMenu.Add(ClayColorBox); @@ -1841,10 +1922,270 @@ void AddHardSettingsToMenu() { // HardSettingsMenu.Add(CorrectMatOptionsButton); + } + public class FloatSliderPair { + public VisualElement DynamicContainer; + public Label DynamicLabel; + public Slider DynamicSlider; + public FloatField DynamicField; + } + FloatSliderPair CreatePairedFloatSlider(string Name, float LowValue, float HighValue, ref float InitialValue, float SliderWidth = 100) { + FloatSliderPair NewPair = new FloatSliderPair(); + NewPair.DynamicContainer = CreateHorizontalBox(Name + " Container"); + NewPair.DynamicLabel = new Label(Name); + NewPair.DynamicSlider = new Slider() {value = InitialValue, highValue = HighValue, lowValue = LowValue}; + NewPair.DynamicField = new FloatField() {value = InitialValue}; + NewPair.DynamicSlider.style.width = SliderWidth; + NewPair.DynamicContainer.Add(NewPair.DynamicLabel); + NewPair.DynamicContainer.Add(NewPair.DynamicSlider); + NewPair.DynamicContainer.Add(NewPair.DynamicField); + return NewPair; + } + + void AddPostProcessingToMenu() { + + List TonemapSettings = new List(); + TonemapSettings.Add("TonyMcToneFace"); + TonemapSettings.Add("ACES Filmic"); + TonemapSettings.Add("Uchimura"); + TonemapSettings.Add("Reinhard"); + TonemapSettings.Add("Uncharted 2"); + TonemapSettings.Add("AgX"); + PopupField ToneMapField = new PopupField("Tonemapper"); + ToneMapField.ElementAt(0).style.minWidth = 65; + ToneMapField.choices = TonemapSettings; + ToneMapField.index = ToneMapIndex; + ToneMapField.RegisterValueChangedCallback(evt => {ToneMapIndex = ToneMapField.index; RayMaster.LocalTTSettings.ToneMapper = ToneMapIndex;}); + + Toggle ToneMapToggle = new Toggle() {value = ToneMap, text = "Enable Tonemapping"}; + VisualElement ToneMapFoldout = new VisualElement() {}; + ToneMapFoldout.style.flexDirection = FlexDirection.Row; + ToneMapFoldout.Add(ToneMapField); + PostProcessingMenu.Add(ToneMapToggle); + ToneMapToggle.RegisterValueChangedCallback(evt => {ToneMap = evt.newValue; RayMaster.LocalTTSettings.PPToneMap = ToneMap; if(evt.newValue) PostProcessingMenu.Insert(PostProcessingMenu.IndexOf(ToneMapToggle) + 1, ToneMapFoldout); else PostProcessingMenu.Remove(ToneMapFoldout);}); + if(ToneMap) PostProcessingMenu.Add(ToneMapFoldout); + + VisualElement SharpenFoldout = new VisualElement() {}; + Slider SharpnessSlider = new Slider() {label = "Sharpness: ", value = Sharpness, highValue = 1.0f, lowValue = 0.0f}; + SharpnessSlider.style.width = 200; + SharpnessSlider.RegisterValueChangedCallback(evt => {Sharpness = evt.newValue; RayMaster.LocalTTSettings.Sharpness = Sharpness;}); + SharpenFoldout.Add(SharpnessSlider); + SharpnessSlider.ElementAt(0).style.minWidth = 65; + + + Toggle SharpenToggle = new Toggle() {value = DoSharpen, text = "Use Sharpness Filter"}; + PostProcessingMenu.Add(SharpenToggle); + SharpenToggle.RegisterValueChangedCallback(evt => {DoSharpen = evt.newValue; RayMaster.LocalTTSettings.DoSharpen = DoSharpen; if(evt.newValue) PostProcessingMenu.Insert(PostProcessingMenu.IndexOf(SharpenToggle) + 1, SharpenFoldout); else PostProcessingMenu.Remove(SharpenFoldout);}); + if(DoSharpen) PostProcessingMenu.Add(SharpenFoldout); + + + + BloomToggle = new Toggle() {value = Bloom, text = "Enable Bloom"}; + VisualElement BloomBox = new VisualElement(); + Toggle ConvBloomToggle = new Toggle {value = ConvBloom, text = "Convolutional Bloom"}; + VisualElement StandardBloomBox = new VisualElement(); + StandardBloomBox.style.flexDirection = FlexDirection.Row; + Label BloomLabel = new Label("Bloom Strength"); + Slider BloomSlider = new Slider() {value = BloomStrength, highValue = 0.9999f, lowValue = 0.25f}; + BloomSlider.style.width = 100; + BloomSlider.RegisterValueChangedCallback(evt => {BloomStrength = evt.newValue; RayMaster.LocalTTSettings.BloomStrength = BloomStrength;}); + StandardBloomBox.Add(BloomLabel); + StandardBloomBox.Add(BloomSlider); + VisualElement ConvBloomBox = new VisualElement(); + Slider ConvBloomStrengthSlider = new Slider() {label = "Convolution Bloom Strength", value = ConvStrength, highValue = 10.0f, lowValue = 0.0f}; + ConvBloomStrengthSlider.style.width = 400; + ConvBloomStrengthSlider.RegisterValueChangedCallback(evt => {ConvStrength = evt.newValue; RayMaster.LocalTTSettings.ConvStrength = ConvStrength;}); + Slider ConvBloomThresholdSlider = new Slider() {label = "Convolution Bloom Threshold", value = ConvBloomThreshold, highValue = 20.0f, lowValue = 0.0f}; + ConvBloomThresholdSlider.style.width = 400; + ConvBloomThresholdSlider.RegisterValueChangedCallback(evt => {ConvBloomThreshold = evt.newValue; RayMaster.LocalTTSettings.ConvBloomThreshold = ConvBloomThreshold;}); + Vector2Field ConvBloomSizeField = new Vector2Field() {label = "Convolution Bloom Size", value = ConvBloomSize}; + ConvBloomSizeField.RegisterValueChangedCallback(evt => {ConvBloomSize = evt.newValue; RayMaster.LocalTTSettings.ConvBloomSize = ConvBloomSize;}); + VisualElement ConvDistExpBox = CreateHorizontalBox("Convolution Distance Container"); + FloatField ConvBloomDistExpField = new FloatField() {label = "Convolution Bloom Dist Exp", value = ConvBloomDistExp}; + ConvBloomDistExpField.RegisterValueChangedCallback(evt => {ConvBloomDistExp = evt.newValue; RayMaster.LocalTTSettings.ConvBloomDistExp = ConvBloomDistExp;}); + FloatField ConvBloomDistExpClampMinField = new FloatField() {label = "Convolution Bloom Dist Exp Clamp Min", value = ConvBloomDistExpClampMin}; + ConvBloomDistExpClampMinField.RegisterValueChangedCallback(evt => {ConvBloomDistExpClampMin = evt.newValue; RayMaster.LocalTTSettings.ConvBloomDistExpClampMin = ConvBloomDistExpClampMin;}); + FloatField ConvBloomDistExpScaleField = new FloatField() {label = "Convolution Bloom Dist Exp Scale", value = ConvBloomDistExpScale}; + ConvBloomDistExpScaleField.RegisterValueChangedCallback(evt => {ConvBloomDistExpScale = evt.newValue; RayMaster.LocalTTSettings.ConvBloomDistExpScale = ConvBloomDistExpScale;}); + ConvDistExpBox.Add(ConvBloomDistExpField); + ConvDistExpBox.Add(ConvBloomDistExpClampMinField); + ConvDistExpBox.Add(ConvBloomDistExpScaleField); + + + ConvBloomBox.Add(ConvBloomStrengthSlider); + ConvBloomBox.Add(ConvBloomThresholdSlider); + ConvBloomBox.Add(ConvBloomSizeField); + ConvBloomBox.Add(ConvDistExpBox); + BloomBox.Add(ConvBloomToggle); + if(ConvBloom) BloomBox.Add(ConvBloomBox); + else BloomBox.Add(StandardBloomBox); + ConvBloomToggle.RegisterValueChangedCallback(evt => {ConvBloom = evt.newValue; RayMaster.LocalTTSettings.ConvBloom = ConvBloom; if(evt.newValue) {BloomBox.Remove(StandardBloomBox); BloomBox.Insert(BloomBox.IndexOf(ConvBloomToggle) + 1, ConvBloomBox); } else {BloomBox.Remove(ConvBloomBox); BloomBox.Insert(BloomBox.IndexOf(ConvBloomToggle) + 1, StandardBloomBox); }}); + BloomToggle.RegisterValueChangedCallback(evt => {Bloom = evt.newValue; RayMaster.LocalTTSettings.PPBloom = Bloom; if(evt.newValue) PostProcessingMenu.Insert(PostProcessingMenu.IndexOf(BloomToggle) + 1, BloomBox); else PostProcessingMenu.Remove(BloomBox);}); + PostProcessingMenu.Add(BloomToggle); + if(Bloom) { + PostProcessingMenu.Add(BloomBox); + + } + + + + Label AperatureLabel = new Label("Aperature Size"); + AperatureSlider = new Slider() {value = DoFAperature, highValue = 1, lowValue = 0}; + AperatureSlider.style.width = 250; + FloatField AperatureScaleField = new FloatField() {value = DoFAperatureScale, label = "Aperature Scale"}; + AperatureScaleField.ElementAt(0).style.minWidth = 65; + AperatureScaleField.RegisterValueChangedCallback(evt => {DoFAperatureScale = evt.newValue; DoFAperatureScale = Mathf.Max(DoFAperatureScale, 0.0001f); RayMaster.LocalTTSettings.DoFAperatureScale = DoFAperatureScale; AperatureScaleField.value = DoFAperatureScale;}); + Label FocalLabel = new Label("Focal Length"); + FocalSlider = new FloatField() {value = DoFFocal}; + FocalSlider.style.width = 150; + Label AutoFocLabel = new Label("Hold Middle Mouse + Left Control in game to focus"); + // Button AutofocusButton = new Button(() => {IsFocusing = true;}) {text = "Autofocus DoF"}; + // AutofocusButton.RegisterCallback(evt => {}); + // AutofocusButton.RegisterCallback(evt => {}); + + + Box AperatureBox = new Box(); + AperatureBox.Add(AperatureLabel); + AperatureBox.Add(AperatureSlider); + AperatureBox.Add(AperatureScaleField); + AperatureBox.style.flexDirection = FlexDirection.Row; + Box FocalBox = new Box(); + FocalBox.Add(FocalLabel); + FocalBox.Add(FocalSlider); + FocalBox.Add(AutoFocLabel); + // FocalBox.Add(AutofocusButton); + FocalBox.style.flexDirection = FlexDirection.Row; + + Toggle DoFToggle = new Toggle() {value = DoF, text = "Enable DoF"}; + VisualElement DoFFoldout = new VisualElement(); + DoFFoldout.Add(AperatureBox); + DoFFoldout.Add(FocalBox); + PostProcessingMenu.Add(DoFToggle); + DoFToggle.RegisterValueChangedCallback(evt => {DoF = evt.newValue; RayMaster.LocalTTSettings.PPDoF = DoF;if(evt.newValue) PostProcessingMenu.Insert(PostProcessingMenu.IndexOf(DoFToggle) + 1, DoFFoldout); else PostProcessingMenu.Remove(DoFFoldout);}); + AperatureSlider.RegisterValueChangedCallback(evt => {DoFAperature = evt.newValue; RayMaster.LocalTTSettings.DoFAperature = DoFAperature;}); + FocalSlider.RegisterValueChangedCallback(evt => {DoFFocal = Mathf.Max(0.001f, evt.newValue); RayMaster.LocalTTSettings.DoFFocal = DoFFocal;}); + if(DoF) PostProcessingMenu.Add(DoFFoldout); + + Toggle DoExposureToggle = new Toggle() {value = DoExposure, text = "Enable Auto/Manual Exposure"}; + PostProcessingMenu.Add(DoExposureToggle); + VisualElement ExposureElement = new VisualElement(); + ExposureElement.style.flexDirection = FlexDirection.Row; + Label ExposureLabel = new Label("Exposure"); + Slider ExposureSlider = new Slider() {value = Exposure, highValue = 50.0f, lowValue = 0}; + FloatField ExposureField = new FloatField() {value = Exposure}; + Toggle ExposureAutoToggle = new Toggle() {value = ExposureAuto, text = "Auto(On)/Manual(Off)"}; + ExposureAutoToggle.RegisterValueChangedCallback(evt => {ExposureAuto = evt.newValue; RayMaster.LocalTTSettings.ExposureAuto = ExposureAuto;}); + DoExposureToggle.tooltip = "Slide to the left for Auto"; + ExposureSlider.tooltip = "Slide to the left for Auto"; + ExposureLabel.tooltip = "Slide to the left for Auto"; + ExposureSlider.style.width = 100; + ExposureElement.Add(ExposureLabel); + ExposureElement.Add(ExposureSlider); + ExposureElement.Add(ExposureField); + ExposureElement.Add(ExposureAutoToggle); + DoExposureToggle.RegisterValueChangedCallback(evt => {DoExposure = evt.newValue; RayMaster.LocalTTSettings.PPExposure = DoExposure;if(evt.newValue) PostProcessingMenu.Insert(PostProcessingMenu.IndexOf(DoExposureToggle) + 1, ExposureElement); else PostProcessingMenu.Remove(ExposureElement);}); + ExposureSlider.RegisterValueChangedCallback(evt => {Exposure = evt.newValue; ExposureField.value = Exposure; RayMaster.LocalTTSettings.Exposure = Exposure;}); + ExposureField.RegisterValueChangedCallback(evt => {Exposure = evt.newValue; ExposureSlider.value = Exposure; RayMaster.LocalTTSettings.Exposure = Exposure;}); + if(DoExposure) PostProcessingMenu.Add(ExposureElement); + + TAAToggle = new Toggle() {value = TAA, text = "Enable TAA"}; + PostProcessingMenu.Add(TAAToggle); + TAAToggle.RegisterValueChangedCallback(evt => {TAA = evt.newValue; RayMaster.LocalTTSettings.PPTAA = TAA;}); + + FXAAToggle = new Toggle() {value = FXAA, text = "Enable FXAA"}; + PostProcessingMenu.Add(FXAAToggle); + FXAAToggle.RegisterValueChangedCallback(evt => {FXAA = evt.newValue; RayMaster.LocalTTSettings.PPFXAA = FXAA;}); + + + Toggle BCSToggle = new Toggle() {value = DoBCS, text = "Enable Contrast/Saturation Adjustment"}; + VisualElement BCSContainer = new VisualElement(); + VisualElement SaturationContainer = CreateHorizontalBox(); + Label SaturationLabel = new Label("Saturation"); + Slider SaturationSlider = new Slider() {value = Saturation, highValue = 2.0f, lowValue = 0}; + FloatField SaturationField = new FloatField() {value = Saturation}; + SaturationSlider.style.width = 100; + SaturationSlider.RegisterValueChangedCallback(evt => {Saturation = evt.newValue; SaturationField.value = Saturation; RayMaster.LocalTTSettings.Saturation = Saturation;}); + SaturationField.RegisterValueChangedCallback(evt => {Saturation = evt.newValue; SaturationSlider.value = Saturation; RayMaster.LocalTTSettings.Saturation = Saturation;}); + SaturationContainer.Add(SaturationLabel); + SaturationContainer.Add(SaturationSlider); + SaturationContainer.Add(SaturationField); + + VisualElement ContrastContainer = CreateHorizontalBox(); + Label ContrastLabel = new Label("Contrast"); + Slider ContrastSlider = new Slider() {value = Contrast, highValue = 2.0f, lowValue = 0}; + FloatField ContrastField = new FloatField() {value = Contrast}; + ContrastSlider.style.width = 100; + ContrastSlider.RegisterValueChangedCallback(evt => {Contrast = evt.newValue; ContrastField.value = Contrast; RayMaster.LocalTTSettings.Contrast = Contrast;}); + ContrastField.RegisterValueChangedCallback(evt => {Contrast = evt.newValue; ContrastSlider.value = Contrast; RayMaster.LocalTTSettings.Contrast = Contrast;}); + ContrastContainer.Add(ContrastLabel); + ContrastContainer.Add(ContrastSlider); + ContrastContainer.Add(ContrastField); + BCSContainer.Add(SaturationContainer); + BCSContainer.Add(ContrastContainer); + + PostProcessingMenu.Add(BCSToggle); + if(DoBCS) PostProcessingMenu.Add(BCSContainer); + BCSToggle.RegisterValueChangedCallback(evt => {DoBCS = evt.newValue; RayMaster.LocalTTSettings.DoBCS = DoBCS; if(evt.newValue) PostProcessingMenu.Insert(PostProcessingMenu.IndexOf(BCSToggle) + 1, BCSContainer); else PostProcessingMenu.Remove(BCSContainer);}); + + + Toggle DoVignetteToggle = new Toggle() {value = DoVignette, text = "Enable Vignette"}; + PostProcessingMenu.Add(DoVignetteToggle); + VisualElement VignetteContainer = new VisualElement(); + FloatSliderPair VignetteStrengthContainer = CreatePairedFloatSlider("Vignette Strength", 0, 4, ref strengthVignette); + VignetteStrengthContainer.DynamicSlider.RegisterValueChangedCallback(evt => {strengthVignette = evt.newValue; VignetteStrengthContainer.DynamicField.value = strengthVignette; RayMaster.LocalTTSettings.strengthVignette = strengthVignette;}); + VignetteStrengthContainer.DynamicField.RegisterValueChangedCallback(evt => {strengthVignette = evt.newValue; VignetteStrengthContainer.DynamicSlider.value = strengthVignette; RayMaster.LocalTTSettings.strengthVignette = strengthVignette;}); + + FloatSliderPair innerVignetteContainer = CreatePairedFloatSlider("Vignette Inner", 0, 4, ref innerVignette); + innerVignetteContainer.DynamicSlider.RegisterValueChangedCallback(evt => {innerVignette = evt.newValue; innerVignetteContainer.DynamicField.value = innerVignette; RayMaster.LocalTTSettings.innerVignette = innerVignette;}); + innerVignetteContainer.DynamicField.RegisterValueChangedCallback(evt => {innerVignette = evt.newValue; innerVignetteContainer.DynamicSlider.value = innerVignette; RayMaster.LocalTTSettings.innerVignette = innerVignette;}); + + FloatSliderPair outerVignetteContainer = CreatePairedFloatSlider("Vignette Outer", 0, 4, ref outerVignette); + outerVignetteContainer.DynamicSlider.RegisterValueChangedCallback(evt => {outerVignette = evt.newValue; outerVignetteContainer.DynamicField.value = outerVignette; RayMaster.LocalTTSettings.outerVignette = outerVignette;}); + outerVignetteContainer.DynamicField.RegisterValueChangedCallback(evt => {outerVignette = evt.newValue; outerVignetteContainer.DynamicSlider.value = outerVignette; RayMaster.LocalTTSettings.outerVignette = outerVignette;}); + + FloatSliderPair curveVignetteContainer = CreatePairedFloatSlider("Vignette Curve", 0, 4, ref curveVignette); + curveVignetteContainer.DynamicSlider.RegisterValueChangedCallback(evt => {curveVignette = evt.newValue; curveVignetteContainer.DynamicField.value = curveVignette; RayMaster.LocalTTSettings.curveVignette = curveVignette;}); + curveVignetteContainer.DynamicField.RegisterValueChangedCallback(evt => {curveVignette = evt.newValue; curveVignetteContainer.DynamicSlider.value = curveVignette; RayMaster.LocalTTSettings.curveVignette = curveVignette;}); + + ColorField VignetteColorField = new ColorField(); + VignetteColorField.value = ColorVignette; + VignetteColorField.style.width = 150; + VignetteColorField.RegisterValueChangedCallback(evt => {ColorVignette = evt.newValue; RayMaster.LocalTTSettings.ColorVignette = new Vector3(ColorVignette.r,ColorVignette.g,ColorVignette.b);}); + + + VignetteContainer.Add(innerVignetteContainer.DynamicContainer); + VignetteContainer.Add(outerVignetteContainer.DynamicContainer); + VignetteContainer.Add(VignetteStrengthContainer.DynamicContainer); + VignetteContainer.Add(curveVignetteContainer.DynamicContainer); + VignetteContainer.Add(VignetteColorField); + + DoVignetteToggle.RegisterValueChangedCallback(evt => {DoVignette = evt.newValue; RayMaster.LocalTTSettings.DoVignette = DoVignette;if(evt.newValue) PostProcessingMenu.Insert(PostProcessingMenu.IndexOf(DoVignetteToggle) + 1, VignetteContainer); else PostProcessingMenu.Remove(VignetteContainer);}); + if(DoVignette) PostProcessingMenu.Add(VignetteContainer); + + + + Toggle DoChromaAberToggle = new Toggle() {value = DoChromaAber, text = "Enable Chomatic Aberation"}; + PostProcessingMenu.Add(DoChromaAberToggle); + VisualElement ChromaAberContainer = CreateHorizontalBox(); + Label ChromaAberLabel = new Label("Chromatic Aberation Strength"); + Slider ChromaAberSlider = new Slider() {value = ChromaDistort, highValue = 7.0f, lowValue = 0}; + FloatField ChromaAberField = new FloatField() {value = ChromaDistort}; + ChromaAberSlider.RegisterValueChangedCallback(evt => {ChromaDistort = evt.newValue; ChromaAberField.value = ChromaDistort; RayMaster.LocalTTSettings.ChromaDistort = ChromaDistort;}); + ChromaAberField.RegisterValueChangedCallback(evt => {ChromaDistort = evt.newValue; ChromaAberSlider.value = ChromaDistort; RayMaster.LocalTTSettings.ChromaDistort = ChromaDistort;}); + ChromaAberSlider.style.width = 100; + ChromaAberContainer.Add(ChromaAberLabel); + ChromaAberContainer.Add(ChromaAberSlider); + ChromaAberContainer.Add(ChromaAberField); + + DoChromaAberToggle.RegisterValueChangedCallback(evt => {DoChromaAber = evt.newValue; RayMaster.LocalTTSettings.DoChromaAber = DoChromaAber;if(evt.newValue) PostProcessingMenu.Insert(PostProcessingMenu.IndexOf(DoChromaAberToggle) + 1, ChromaAberContainer); else PostProcessingMenu.Remove(ChromaAberContainer);}); + if(DoChromaAber) PostProcessingMenu.Add(ChromaAberContainer); + + + } - private VisualElement CreateHorizontalBox(string Name) { + private VisualElement CreateHorizontalBox(string Name = "") { VisualElement HorizBox = new VisualElement(); HorizBox.style.flexDirection = FlexDirection.Row; return HorizBox; @@ -1856,40 +2197,83 @@ private VisualElement CreateHorizontalBox(string Name) { private void UndoInstances() { GameObject Obj = SelectiveField.value as GameObject; if(Obj == null) return; + if(!Obj.scene.IsValid()) { + GameObject[] InstanceQues = PrefabUtility.FindAllInstancesOfPrefab(SelectiveField.value as GameObject); + int QueCount = InstanceQues.Length; + ParentObject OrigPObj = null; + RayTracingObject OrigRObj = null; + string OrigName = ""; + if(QueCount > 0) { + InstancedObject[] TempVar = InstanceQues[0].GetComponentsInChildren(); + if(TempVar != null && TempVar.Length != 0) { + if(TempVar[0].InstanceParent != null) { + OrigPObj = TempVar[0].InstanceParent.GetComponent(); + OrigRObj = TempVar[0].InstanceParent.GetComponent(); + OrigName = TempVar[0].InstanceParent.gameObject.name; + } + } + } + for(int i = 0; i < QueCount; i++) { + InstancedObject[] TempVar = InstanceQues[i].GetComponentsInChildren(); + if(TempVar != null && TempVar.Length != 0) { + PrefabUtility.RevertPrefabInstance(InstanceQues[i], InteractionMode.AutomatedAction); + for(int i2 = 0; i2 < InstanceQues[i].transform.childCount; i2++) { + if(OrigName.Contains(InstanceQues[i].transform.GetChild(i2).gameObject.name)) { + InstanceQues[i].transform.GetChild(i2).gameObject.AddComponent(OrigRObj); + InstanceQues[i].transform.GetChild(i2).gameObject.AddComponent(); + } + } + } + } + DestroyImmediate(OrigPObj.gameObject); + } else { + var E = Obj.GetComponentsInChildren(); + foreach(var a in E) { + GameObject TempOBJ = GameObject.Instantiate(a.InstanceParent.gameObject); + TempOBJ.transform.parent = a.gameObject.transform.parent; + TempOBJ.transform.position = a.gameObject.transform.position; + TempOBJ.transform.rotation = a.gameObject.transform.rotation; + DestroyImmediate(a.gameObject); + } + ParentData SourceParent = GrabChildren2(Obj.transform); - var E = Obj.GetComponentsInChildren(); - foreach(var a in E) { - GameObject TempOBJ = GameObject.Instantiate(a.InstanceParent.gameObject); - TempOBJ.transform.parent = a.gameObject.transform.parent; - TempOBJ.transform.position = a.gameObject.transform.position; - TempOBJ.transform.rotation = a.gameObject.transform.rotation; - DestroyImmediate(a.gameObject); + SolveChildren(SourceParent); } - ParentData SourceParent = GrabChildren2(Obj.transform); + } - SolveChildren(SourceParent); + VisualElement MakeSpacer(int Height = 30) { + VisualElement TempSpace = new VisualElement(); + TempSpace.style.minHeight = 30; + TempSpace.style.maxHeight = 30; + return TempSpace; } void AddHierarchyOptionsToMenu() { SelectiveField = new ObjectField(); SelectiveField.objectType = typeof(GameObject); - SelectiveField.label = "Selective Auto Assign Scripts"; - HierarchyOptionsMenu.Add(SelectiveField); + SelectiveField.label = "Selected Object"; Button SelectiveAutoAssignButton = new Button(() => { ParentData SourceParent = GrabChildren2((SelectiveField.value as GameObject).transform); SolveChildren(SourceParent); }) {text = "Selective Auto Assign"}; Button ReplaceInstanceButton = new Button(() => UndoInstances()) {text = "Undo Selective Instances"}; - HierarchyOptionsMenu.Add(SelectiveAutoAssignButton); - HierarchyOptionsMenu.Add(ReplaceInstanceButton); ForceInstancesButton = new Button(() => {if(!Application.isPlaying) ConstructInstances(); else Debug.Log("Cant Do This In Editor");}) {text = "Force All Instances"}; - HierarchyOptionsMenu.Add(ForceInstancesButton); + Button ForceInstancesSelectiveButton = new Button(() => {if(!Application.isPlaying) {if((SelectiveField.value as GameObject).TryGetComponent(out MeshFilter TempFilter)) ConstructInstancesSelective(TempFilter.sharedMesh); else Debug.Log("Missing Valid Object With Mesh");} else Debug.Log("Cant Do This In Editor");}) {text = "Force Selected Mesh Into Instances"}; StaticButton = new Button(() => {if(!Application.isPlaying) OptimizeForStatic(); else Debug.Log("Cant Do This In Editor");}) {text = "Make All Static"}; StaticButton.style.minWidth = 105; + + HierarchyOptionsMenu.Add(SelectiveField); + HierarchyOptionsMenu.Add(ForceInstancesSelectiveButton); + HierarchyOptionsMenu.Add(ReplaceInstanceButton); + + HierarchyOptionsMenu.Add(MakeSpacer()); + + HierarchyOptionsMenu.Add(SelectiveAutoAssignButton); + HierarchyOptionsMenu.Add(ForceInstancesButton); HierarchyOptionsMenu.Add(StaticButton); } @@ -1923,27 +2307,31 @@ void EvaluateScene(Scene Current, Scene Next) { } void SaveScene(Scene Current, string ThrowawayString) { - EditorUtility.SetDirty(Assets); - Assets.ClearAll(); + if(Assets != null) { + EditorUtility.SetDirty(Assets); + Assets.ClearAll(); + } InstancedManager Instanced = GameObject.Find("InstancedStorage").GetComponent(); - EditorUtility.SetDirty(Instanced); - Instanced.ClearAll(); + if(Instanced != null) { + EditorUtility.SetDirty(Instanced); + Instanced.ClearAll(); + } Cleared = true; } - [Shortcut("TrueTrace/ScreenShot", KeyCode.None, ShortcutModifiers.Action)] - private static void TakeScreenShotHotkey() { - if(Application.isPlaying) { - TakeScreenshot(); - } - } + // [Shortcut("TrueTrace/ScreenShot", KeyCode.None, ShortcutModifiers.Action)] + // private static void TakeScreenShotHotkey() { + // if(Application.isPlaying) { + // TakeScreenshot(); + // } + // } - [Shortcut("TrueTrace/RebuildBVH", KeyCode.None, ShortcutModifiers.Action)] - private static void RebuildBVHHotkey() { - EditorUtility.SetDirty(GameObject.Find("Scene").GetComponent()); - BuildWatch.Start(); - GameObject.Find("Scene").GetComponent().EditorBuild(); - } + // [Shortcut("TrueTrace/RebuildBVH", KeyCode.None, ShortcutModifiers.Action)] + // private static void RebuildBVHHotkey() { + // EditorUtility.SetDirty(GameObject.Find("Scene").GetComponent()); + // BuildWatch.Start(); + // GameObject.Find("Scene").GetComponent().EditorBuild(); + // } public static void TakeScreenshot() { string SegmentNumber = ""; @@ -2000,7 +2388,6 @@ public void CreateGUI() { PlayerPrefs.SetString("PanoramaPath", Application.dataPath + "/ScreenShots"); } - DingNoise = Resources.Load("Utility/DING", typeof(AudioClip)) as AudioClip; OnFocus(); MainSource = new VisualElement(); MainSource.style.justifyContent = Justify.FlexStart; // Align items to the start @@ -2009,6 +2396,7 @@ public void CreateGUI() { MaterialPairingMenu = new VisualElement(); SceneSettingsMenu = new VisualElement(); HardSettingsMenu = new VisualElement(); + PostProcessingMenu = new VisualElement(); InputMaterialField = new ObjectField(); InputMaterialField.objectType = typeof(Material); InputMaterialField.label = "Drag a material with the desired shader here ->"; @@ -2016,16 +2404,35 @@ public void CreateGUI() { MaterialPairingMenu.Add(InputMaterialField); toolbar = new Toolbar(); rootVisualElement.Add(toolbar); + Button MainSourceButton = new Button(() => {rootVisualElement.Clear(); rootVisualElement.Add(toolbar); rootVisualElement.Add(MainSource); MaterialPairingMenu.Clear();}); + Button MaterialPairButton = new Button(() => {rootVisualElement.Clear(); rootVisualElement.Add(toolbar); InputMaterialField.value = null; MaterialPairingMenu.Add(InputMaterialField); rootVisualElement.Add(MaterialPairingMenu);}); + Button SceneSettingsButton = new Button(() => {rootVisualElement.Clear(); rootVisualElement.Add(toolbar); rootVisualElement.Add(SceneSettingsMenu);}); + Button HardSettingsButton = new Button(() => {rootVisualElement.Clear(); rootVisualElement.Add(toolbar); HardSettingsMenu.Clear(); AddHardSettingsToMenu(); rootVisualElement.Add(HardSettingsMenu);}); + Button HierarchyOptionsButton = new Button(() => {rootVisualElement.Clear(); rootVisualElement.Add(toolbar); rootVisualElement.Add(HierarchyOptionsMenu);}); + MainSourceButton.text = "Main Options"; + MaterialPairButton.text = "Material Pair Options"; + SceneSettingsButton.text = "Scene Settings"; + HardSettingsButton.text = "Functionality Settings"; + HierarchyOptionsButton.text = "Hierarchy Options"; if(Assets == null) { + toolbar.Add(MainSourceButton); + toolbar.Add(HardSettingsButton); RearrangeElement = new VisualElement(); Button RearrangeButton = new Button(() => {UnityEditor.PopupWindow.Show(new Rect(0,0,10,10), new PopupWarningWindow());}) {text="Arrange Hierarchy"}; RearrangeElement.Add(RearrangeButton); - rootVisualElement.Add(RearrangeElement); + MainSource.Add(RearrangeElement); + rootVisualElement.Add(MainSource); return; } else { + toolbar.Add(MainSourceButton); + toolbar.Add(MaterialPairButton); + toolbar.Add(SceneSettingsButton); + toolbar.Add(HardSettingsButton); + toolbar.Add(HierarchyOptionsButton); {rootVisualElement.Clear(); rootVisualElement.Add(toolbar); rootVisualElement.Add(MainSource); MaterialPairingMenu.Clear();} Assets.UpdateMaterialDefinition(); + #if UNITY_PIPELINE_HDRP GameObject NewObject = GameObject.Find("HDRPPASS"); @@ -2048,32 +2455,16 @@ public void CreateGUI() { } #endif } - Button MainSourceButton = new Button(() => {rootVisualElement.Clear(); rootVisualElement.Add(toolbar); rootVisualElement.Add(MainSource); MaterialPairingMenu.Clear();}); - Button MaterialPairButton = new Button(() => {rootVisualElement.Clear(); rootVisualElement.Add(toolbar); InputMaterialField.value = null; MaterialPairingMenu.Add(InputMaterialField); rootVisualElement.Add(MaterialPairingMenu);}); - Button SceneSettingsButton = new Button(() => {rootVisualElement.Clear(); rootVisualElement.Add(toolbar); rootVisualElement.Add(SceneSettingsMenu);}); - Button HardSettingsButton = new Button(() => {rootVisualElement.Clear(); rootVisualElement.Add(toolbar); HardSettingsMenu.Clear(); AddHardSettingsToMenu(); rootVisualElement.Add(HardSettingsMenu);}); - Button HierarchyOptionsButton = new Button(() => {rootVisualElement.Clear(); rootVisualElement.Add(toolbar); rootVisualElement.Add(HierarchyOptionsMenu);}); - toolbar.Add(MainSourceButton); - toolbar.Add(MaterialPairButton); - toolbar.Add(SceneSettingsButton); - toolbar.Add(HardSettingsButton); - toolbar.Add(HierarchyOptionsButton); - MainSourceButton.text = "Main Options"; - MaterialPairButton.text = "Material Pair Options"; - SceneSettingsButton.text = "Scene Settings"; - HardSettingsButton.text = "Functionality Settings"; - HierarchyOptionsButton.text = "Hierarchy Options"; if(RayMaster != null && Assets != null) { AddNormalSettings(); Assets.UseSkinning = MeshSkin; RayMaster.AtmoNumLayers = AtmoScatter; Assets.MainDesiredRes = AtlasSize; - RayMaster.LoadTT(); + if(RayMaster.LocalTTSettings == null) RayMaster.LoadTT(); LightEnergyScale = RayMaster.LocalTTSettings.LightEnergyScale; LEMEnergyScale = RayMaster.LocalTTSettings.LEMEnergyScale; RayTracingMaster.DoSaving = DoSaving; - RayTracingMaster.DoDing = DoDing; MatChangeResetsAccum = RayMaster.LocalTTSettings.MatChangeResetsAccum; UseTransmittanceInNEE = RayMaster.LocalTTSettings.UseTransmittanceInNEE; BounceCount = RayMaster.LocalTTSettings.bouncecount; @@ -2137,6 +2528,18 @@ public void CreateGUI() { ConvBloomDistExp = RayMaster.LocalTTSettings.ConvBloomDistExp; ConvBloomDistExpClampMin = RayMaster.LocalTTSettings.ConvBloomDistExpClampMin; ConvBloomDistExpScale = RayMaster.LocalTTSettings.ConvBloomDistExpScale; + DoBCS = RayMaster.LocalTTSettings.DoBCS; + Saturation = RayMaster.LocalTTSettings.Saturation; + Contrast = RayMaster.LocalTTSettings.Contrast; + DoVignette = RayMaster.LocalTTSettings.DoVignette; + innerVignette = RayMaster.LocalTTSettings.innerVignette; + outerVignette = RayMaster.LocalTTSettings.outerVignette; + strengthVignette = RayMaster.LocalTTSettings.strengthVignette; + curveVignette = RayMaster.LocalTTSettings.curveVignette; + ColorVignette = new Color(RayMaster.LocalTTSettings.ColorVignette.x,RayMaster.LocalTTSettings.ColorVignette.y,RayMaster.LocalTTSettings.ColorVignette.z,1); + FogDensity = RayMaster.LocalTTSettings.FogDensity; + FogHeight = RayMaster.LocalTTSettings.FogHeight; + DoChromaAber = RayMaster.LocalTTSettings.DoChromaAber; } // AddHardSettingsToMenu(); @@ -2304,128 +2707,14 @@ public void CreateGUI() { - BloomToggle = new Toggle() {value = Bloom, text = "Enable Bloom"}; - VisualElement BloomBox = new VisualElement(); - Toggle ConvBloomToggle = new Toggle {value = ConvBloom, text = "Convolutional Bloom"}; - VisualElement StandardBloomBox = new VisualElement(); - StandardBloomBox.style.flexDirection = FlexDirection.Row; - Label BloomLabel = new Label("Bloom Strength"); - Slider BloomSlider = new Slider() {value = BloomStrength, highValue = 0.9999f, lowValue = 0.25f}; - BloomSlider.style.width = 100; - BloomSlider.RegisterValueChangedCallback(evt => {BloomStrength = evt.newValue; RayMaster.LocalTTSettings.BloomStrength = BloomStrength;}); - StandardBloomBox.Add(BloomLabel); - StandardBloomBox.Add(BloomSlider); - VisualElement ConvBloomBox = new VisualElement(); - Slider ConvBloomStrengthSlider = new Slider() {label = "Convolution Bloom Strength", value = ConvStrength, highValue = 10.0f, lowValue = 0.0f}; - ConvBloomStrengthSlider.style.width = 400; - ConvBloomStrengthSlider.RegisterValueChangedCallback(evt => {ConvStrength = evt.newValue; RayMaster.LocalTTSettings.ConvStrength = ConvStrength;}); - Slider ConvBloomThresholdSlider = new Slider() {label = "Convolution Bloom Threshold", value = ConvBloomThreshold, highValue = 20.0f, lowValue = 0.0f}; - ConvBloomThresholdSlider.style.width = 400; - ConvBloomThresholdSlider.RegisterValueChangedCallback(evt => {ConvBloomThreshold = evt.newValue; RayMaster.LocalTTSettings.ConvBloomThreshold = ConvBloomThreshold;}); - Vector2Field ConvBloomSizeField = new Vector2Field() {label = "Convolution Bloom Size", value = ConvBloomSize}; - ConvBloomSizeField.RegisterValueChangedCallback(evt => {ConvBloomSize = evt.newValue; RayMaster.LocalTTSettings.ConvBloomSize = ConvBloomSize;}); - VisualElement ConvDistExpBox = CreateHorizontalBox("Convolution Distance Container"); - FloatField ConvBloomDistExpField = new FloatField() {label = "Convolution Bloom Dist Exp", value = ConvBloomDistExp}; - ConvBloomDistExpField.RegisterValueChangedCallback(evt => {ConvBloomDistExp = evt.newValue; RayMaster.LocalTTSettings.ConvBloomDistExp = ConvBloomDistExp;}); - FloatField ConvBloomDistExpClampMinField = new FloatField() {label = "Convolution Bloom Dist Exp Clamp Min", value = ConvBloomDistExpClampMin}; - ConvBloomDistExpClampMinField.RegisterValueChangedCallback(evt => {ConvBloomDistExpClampMin = evt.newValue; RayMaster.LocalTTSettings.ConvBloomDistExpClampMin = ConvBloomDistExpClampMin;}); - FloatField ConvBloomDistExpScaleField = new FloatField() {label = "Convolution Bloom Dist Exp Scale", value = ConvBloomDistExpScale}; - ConvBloomDistExpScaleField.RegisterValueChangedCallback(evt => {ConvBloomDistExpScale = evt.newValue; RayMaster.LocalTTSettings.ConvBloomDistExpScale = ConvBloomDistExpScale;}); - ConvDistExpBox.Add(ConvBloomDistExpField); - ConvDistExpBox.Add(ConvBloomDistExpClampMinField); - ConvDistExpBox.Add(ConvBloomDistExpScaleField); - ConvBloomBox.Add(ConvBloomStrengthSlider); - ConvBloomBox.Add(ConvBloomThresholdSlider); - ConvBloomBox.Add(ConvBloomSizeField); - ConvBloomBox.Add(ConvDistExpBox); - BloomBox.Add(ConvBloomToggle); - if(ConvBloom) BloomBox.Add(ConvBloomBox); - else BloomBox.Add(StandardBloomBox); - ConvBloomToggle.RegisterValueChangedCallback(evt => {ConvBloom = evt.newValue; RayMaster.LocalTTSettings.ConvBloom = ConvBloom; if(evt.newValue) {BloomBox.Remove(StandardBloomBox); BloomBox.Insert(BloomBox.IndexOf(ConvBloomToggle) + 1, ConvBloomBox); } else {BloomBox.Remove(ConvBloomBox); BloomBox.Insert(BloomBox.IndexOf(ConvBloomToggle) + 1, StandardBloomBox); }}); - BloomToggle.RegisterValueChangedCallback(evt => {Bloom = evt.newValue; RayMaster.LocalTTSettings.PPBloom = Bloom; if(evt.newValue) MainSource.Insert(MainSource.IndexOf(BloomToggle) + 1, BloomBox); else MainSource.Remove(BloomBox);}); - MainSource.Add(BloomToggle); - if(Bloom) { - MainSource.Add(BloomBox); - - } - - VisualElement SharpenFoldout = new VisualElement() {}; - Slider SharpnessSlider = new Slider() {label = "Sharpness: ", value = Sharpness, highValue = 1.0f, lowValue = 0.0f}; - SharpnessSlider.style.width = 200; - SharpnessSlider.RegisterValueChangedCallback(evt => {Sharpness = evt.newValue; RayMaster.LocalTTSettings.Sharpness = Sharpness;}); - SharpenFoldout.Add(SharpnessSlider); - SharpnessSlider.ElementAt(0).style.minWidth = 65; - Toggle SharpenToggle = new Toggle() {value = DoSharpen, text = "Use Sharpness Filter"}; - MainSource.Add(SharpenToggle); - SharpenToggle.RegisterValueChangedCallback(evt => {DoSharpen = evt.newValue; RayMaster.LocalTTSettings.DoSharpen = DoSharpen; if(evt.newValue) MainSource.Insert(MainSource.IndexOf(SharpenToggle) + 1, SharpenFoldout); else MainSource.Remove(SharpenFoldout);}); - if(DoSharpen) MainSource.Add(SharpenFoldout); - - - - Label AperatureLabel = new Label("Aperature Size"); - AperatureSlider = new Slider() {value = DoFAperature, highValue = 1, lowValue = 0}; - AperatureSlider.style.width = 250; - FloatField AperatureScaleField = new FloatField() {value = DoFAperatureScale, label = "Aperature Scale"}; - AperatureScaleField.ElementAt(0).style.minWidth = 65; - AperatureScaleField.RegisterValueChangedCallback(evt => {DoFAperatureScale = evt.newValue; DoFAperatureScale = Mathf.Max(DoFAperatureScale, 0.0001f); RayMaster.LocalTTSettings.DoFAperatureScale = DoFAperatureScale; AperatureScaleField.value = DoFAperatureScale;}); - Label FocalLabel = new Label("Focal Length"); - FocalSlider = new FloatField() {value = DoFFocal}; - FocalSlider.style.width = 150; - Label AutoFocLabel = new Label("Hold Middle Mouse + Left Control in game to focus"); - // Button AutofocusButton = new Button(() => {IsFocusing = true;}) {text = "Autofocus DoF"}; - // AutofocusButton.RegisterCallback(evt => {}); - // AutofocusButton.RegisterCallback(evt => {}); - - Box AperatureBox = new Box(); - AperatureBox.Add(AperatureLabel); - AperatureBox.Add(AperatureSlider); - AperatureBox.Add(AperatureScaleField); - AperatureBox.style.flexDirection = FlexDirection.Row; - Box FocalBox = new Box(); - FocalBox.Add(FocalLabel); - FocalBox.Add(FocalSlider); - FocalBox.Add(AutoFocLabel); - // FocalBox.Add(AutofocusButton); - FocalBox.style.flexDirection = FlexDirection.Row; - Toggle DoFToggle = new Toggle() {value = DoF, text = "Enable DoF"}; - VisualElement DoFFoldout = new VisualElement(); - DoFFoldout.Add(AperatureBox); - DoFFoldout.Add(FocalBox); - MainSource.Add(DoFToggle); - DoFToggle.RegisterValueChangedCallback(evt => {DoF = evt.newValue; RayMaster.LocalTTSettings.PPDoF = DoF;if(evt.newValue) MainSource.Insert(MainSource.IndexOf(DoFToggle) + 1, DoFFoldout); else MainSource.Remove(DoFFoldout);}); - AperatureSlider.RegisterValueChangedCallback(evt => {DoFAperature = evt.newValue; RayMaster.LocalTTSettings.DoFAperature = DoFAperature;}); - FocalSlider.RegisterValueChangedCallback(evt => {DoFFocal = Mathf.Max(0.001f, evt.newValue); RayMaster.LocalTTSettings.DoFFocal = DoFFocal;}); - if(DoF) MainSource.Add(DoFFoldout); - - Toggle DoExposureToggle = new Toggle() {value = DoExposure, text = "Enable Auto/Manual Exposure"}; - MainSource.Add(DoExposureToggle); - VisualElement ExposureElement = new VisualElement(); - ExposureElement.style.flexDirection = FlexDirection.Row; - Label ExposureLabel = new Label("Exposure"); - Slider ExposureSlider = new Slider() {value = Exposure, highValue = 50.0f, lowValue = 0}; - FloatField ExposureField = new FloatField() {value = Exposure}; - Toggle ExposureAutoToggle = new Toggle() {value = ExposureAuto, text = "Auto(On)/Manual(Off)"}; - ExposureAutoToggle.RegisterValueChangedCallback(evt => {ExposureAuto = evt.newValue; RayMaster.LocalTTSettings.ExposureAuto = ExposureAuto;}); - DoExposureToggle.tooltip = "Slide to the left for Auto"; - ExposureSlider.tooltip = "Slide to the left for Auto"; - ExposureLabel.tooltip = "Slide to the left for Auto"; - ExposureSlider.style.width = 100; - ExposureElement.Add(ExposureLabel); - ExposureElement.Add(ExposureSlider); - ExposureElement.Add(ExposureField); - ExposureElement.Add(ExposureAutoToggle); - DoExposureToggle.RegisterValueChangedCallback(evt => {DoExposure = evt.newValue; RayMaster.LocalTTSettings.PPExposure = DoExposure;if(evt.newValue) MainSource.Insert(MainSource.IndexOf(DoExposureToggle) + 1, ExposureElement); else MainSource.Remove(ExposureElement);}); - ExposureSlider.RegisterValueChangedCallback(evt => {Exposure = evt.newValue; ExposureField.value = Exposure; RayMaster.LocalTTSettings.Exposure = Exposure;}); - ExposureField.RegisterValueChangedCallback(evt => {Exposure = evt.newValue; ExposureSlider.value = Exposure; RayMaster.LocalTTSettings.Exposure = Exposure;}); - if(DoExposure) MainSource.Add(ExposureElement); GIToggle = new Toggle() {value = ReSTIRGI, text = "Use ReSTIR GI"}; VisualElement GIFoldout = new VisualElement() {}; @@ -2477,37 +2766,9 @@ public void CreateGUI() { MainSource.Add(GIToggle); GIToggle.RegisterValueChangedCallback(evt => {ReSTIRGI = evt.newValue; RayMaster.LocalTTSettings.UseReSTIRGI = ReSTIRGI;if(evt.newValue) MainSource.Insert(MainSource.IndexOf(GIToggle) + 1, GIFoldout); else MainSource.Remove(GIFoldout);}); if(ReSTIRGI) MainSource.Add(GIFoldout); - - - TAAToggle = new Toggle() {value = TAA, text = "Enable TAA"}; - MainSource.Add(TAAToggle); - TAAToggle.RegisterValueChangedCallback(evt => {TAA = evt.newValue; RayMaster.LocalTTSettings.PPTAA = TAA;}); - - FXAAToggle = new Toggle() {value = FXAA, text = "Enable FXAA"}; - MainSource.Add(FXAAToggle); - FXAAToggle.RegisterValueChangedCallback(evt => {FXAA = evt.newValue; RayMaster.LocalTTSettings.PPFXAA = FXAA;}); + - - List TonemapSettings = new List(); - TonemapSettings.Add("TonyMcToneFace"); - TonemapSettings.Add("ACES Filmic"); - TonemapSettings.Add("Uchimura"); - TonemapSettings.Add("Reinhard"); - TonemapSettings.Add("Uncharted 2"); - TonemapSettings.Add("AgX"); - PopupField ToneMapField = new PopupField("Tonemapper"); - ToneMapField.ElementAt(0).style.minWidth = 65; - ToneMapField.choices = TonemapSettings; - ToneMapField.index = ToneMapIndex; - ToneMapField.RegisterValueChangedCallback(evt => {ToneMapIndex = ToneMapField.index; RayMaster.LocalTTSettings.ToneMapper = ToneMapIndex;}); - - Toggle ToneMapToggle = new Toggle() {value = ToneMap, text = "Enable Tonemapping"}; - VisualElement ToneMapFoldout = new VisualElement() {}; - ToneMapFoldout.style.flexDirection = FlexDirection.Row; - ToneMapFoldout.Add(ToneMapField); - MainSource.Add(ToneMapToggle); - ToneMapToggle.RegisterValueChangedCallback(evt => {ToneMap = evt.newValue; RayMaster.LocalTTSettings.PPToneMap = ToneMap; if(evt.newValue) MainSource.Insert(MainSource.IndexOf(ToneMapToggle) + 1, ToneMapFoldout); else MainSource.Remove(ToneMapFoldout);}); - if(ToneMap) MainSource.Add(ToneMapFoldout); + @@ -2597,6 +2858,12 @@ public void CreateGUI() { SampleShowToggle.RegisterValueChangedCallback(evt => {ShowFPS = evt.newValue; if(evt.newValue) MainSource.Insert(MainSource.IndexOf(SampleShowToggle) + 1, SampleCountBox); else MainSource.Remove(SampleCountBox);}); if(ShowFPS) MainSource.Add(SampleCountBox); + + AddPostProcessingToMenu(); + Foldout PostProcessingFoldout = new Foldout() {text = "Post Processing"}; + PostProcessingFoldout.Add(PostProcessingMenu); + MainSource.Add(PostProcessingFoldout); + Rect WindowRect = MainSource.layout; Box EnclosingBox = new Box(); try { @@ -2612,7 +2879,7 @@ public void CreateGUI() { Box ReadyBox = new Box(); ReadyBox.style.height = 18; ReadyBox.style.backgroundColor = Color.green; - RemainingObjectsField.RegisterValueChangedCallback(evt => {if(evt.newValue == 0) {ReadyBox.style.backgroundColor = Color.green; if(!Cleared) PlayClip(DingNoise);} else ReadyBox.style.backgroundColor = Color.red;}); + RemainingObjectsField.RegisterValueChangedCallback(evt => {if(evt.newValue == 0) {ReadyBox.style.backgroundColor = Color.green;} else ReadyBox.style.backgroundColor = Color.red;}); Label ReadyLabel = new Label("All Objects Built"); ReadyLabel.style.color = Color.black; ReadyBox.style.alignItems = Align.Center; @@ -2628,6 +2895,7 @@ public void CreateGUI() { RayCastMaterialSelector TempTest; int AFrame = -1; int FramesSinceDOF = 0; + string PrevLocTTSettingsName = ""; void Update() { if(AFrame != -1) { RayTracingObjectEditor[] editors = (RayTracingObjectEditor[])Resources.FindObjectsOfTypeAll(typeof(RayTracingObjectEditor)); @@ -2643,6 +2911,16 @@ void Update() { } } if(RayMaster != null) { + if(Application.isPlaying && RayTracingMaster.RayMaster != null && RayTracingMaster.RayMaster.LocalTTSettings != null) { + if(!(PrevLocTTSettingsName.Equals(RayTracingMaster.RayMaster.LocalTTSettings.name))) { + rootVisualElement.Clear(); + MainSource.Clear(); + CreateGUI(); + } + PrevLocTTSettingsName = RayTracingMaster.RayMaster.LocalTTSettings.name; + } + + // Debug.Log(Input.GetAxis("Mouse ScrollWheel")); if(RayMaster.LocalTTSettings.PPDoF && ((Input.GetAxis("Mouse ScrollWheel") != 0 && Input.GetKey(KeyCode.LeftControl)))) { RayMaster.IsFocusingDelta = true; @@ -2760,7 +3038,7 @@ void Update() { } if(Assets != null && Instancer != null && RemainingObjectsField != null) RemainingObjectsField.value = Assets.RunningTasks + Instancer.RunningTasks; - if(RayMaster != null) SampleCountField.value = RayTracingMaster.SampleCount; + if(RayTracingMaster.RayMaster != null) SampleCountField.value = RayTracingMaster.SampleCount; if(Assets != null && Assets.NeedsToUpdateXML) { string materialMappingsPath = TTPathFinder.GetMaterialMappingsPath(); @@ -2773,28 +3051,8 @@ void Update() { Cleared = false; } - public static void PlayClip(AudioClip clip, int startSample = 0, bool loop = false) - { - float TimeElapsed = BuildWatch.GetSeconds(); - BuildWatch.Stop(); - if(RayTracingMaster.DoDing && TimeElapsed > 15.0f) { - Assembly unityEditorAssembly = typeof(AudioImporter).Assembly; - - System.Type audioUtilClass = unityEditorAssembly.GetType("UnityEditor.AudioUtil"); - MethodInfo method = audioUtilClass.GetMethod( - "PlayPreviewClip", - BindingFlags.Static | BindingFlags.Public, - null, - new System.Type[] { typeof(AudioClip), typeof(int), typeof(bool) }, - null - ); - method.Invoke( - null, - new object[] { clip, startSample, loop } - ); - } } - } + public class PopupWarningWindow : PopupWindowContent { diff --git a/TrueTrace/Editor/RayTracingObjectEditor.cs b/TrueTrace/Editor/RayTracingObjectEditor.cs index 9f201a6d..bbe3a651 100644 --- a/TrueTrace/Editor/RayTracingObjectEditor.cs +++ b/TrueTrace/Editor/RayTracingObjectEditor.cs @@ -777,13 +777,15 @@ public override void OnInspectorGUI() { if(GUILayout.Button("Load Material Preset")) UnityEditor.PopupWindow.Show(new Rect(0,0,100,10), new LoadPopup(this)); EditorGUILayout.EndHorizontal(); - + bool QuickPasted = false; EditorGUILayout.BeginHorizontal(); if(GUILayout.Button("Quick Copy")) CopyFunction(t, Selected); - if(GUILayout.Button("Quick Paste")) + if(GUILayout.Button("Quick Paste")) { PasteFunction(); + QuickPasted = true; + } EditorGUILayout.EndHorizontal(); @@ -998,7 +1000,7 @@ public override void OnInspectorGUI() { serializedObject.FindProperty("MainTexScaleOffset").GetArrayElementAtIndex(Selected).vector4Value = EditorGUILayout.Vector4Field("MainTex Scale/Offset: ", t.MainTexScaleOffset[Selected]); serializedObject.FindProperty("SecondaryAlbedoTexScaleOffset").GetArrayElementAtIndex(Selected).vector4Value = EditorGUILayout.Vector4Field("Secondary Albedo Scale/Offset: ", t.SecondaryAlbedoTexScaleOffset[Selected]); serializedObject.FindProperty("SecondaryTextureScale").GetArrayElementAtIndex(Selected).vector2Value = EditorGUILayout.Vector2Field("SecondaryTex Scale: ", t.SecondaryTextureScale[Selected]); - serializedObject.FindProperty("Rotation").GetArrayElementAtIndex(Selected).floatValue = EditorGUILayout.Slider("Texture Rotation: ", t.Rotation[Selected], 0, 1); + serializedObject.FindProperty("Rotation").GetArrayElementAtIndex(Selected).floatValue = EditorGUILayout.Slider("Texture Rotation: ", t.Rotation[Selected], 0, 360); serializedObject.FindProperty("AlbedoBlendFactor").GetArrayElementAtIndex(Selected).floatValue = EditorGUILayout.Slider("Albedo Blend Factor: ", t.AlbedoBlendFactor[Selected], 0, 1); serializedObject.FindProperty("SecondaryNormalTexScaleOffset").GetArrayElementAtIndex(Selected).vector4Value = EditorGUILayout.Vector4Field("Detail Normal Scale/Offset: ", t.SecondaryNormalTexScaleOffset[Selected]); serializedObject.FindProperty("SecondaryNormalTexBlend").GetArrayElementAtIndex(Selected).floatValue = EditorGUILayout.Slider("Detail Normal Blend Factor: ", t.SecondaryNormalTexBlend[Selected], 0, 1); @@ -1029,7 +1031,7 @@ public override void OnInspectorGUI() { MaterialWasChanged = true; } serializedObject.FindProperty("FollowMaterial").GetArrayElementAtIndex(Selected).boolValue = EditorGUILayout.Toggle("Link Mat To Unity Material: ", t.FollowMaterial[Selected]); - serializedObject.ApplyModifiedProperties(); + if(!QuickPasted) serializedObject.ApplyModifiedProperties(); if(MaterialWasChanged) { string Name = TheseNames[Selected]; diff --git a/TrueTrace/Models/1sponza (2)/Materials/fabric_c.mat b/TrueTrace/Models/1sponza (2)/Materials/fabric_c.mat index 96da6bc1..a9b33184 100644 --- a/TrueTrace/Models/1sponza (2)/Materials/fabric_c.mat +++ b/TrueTrace/Models/1sponza (2)/Materials/fabric_c.mat @@ -41,7 +41,7 @@ Material: m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MainTex: - m_Texture: {fileID: 2800000, guid: 485233ca597afda4fb7d18c571b6a801, type: 3} + m_Texture: {fileID: 2800000, guid: edfe82195fdbf7f4d8fa7a59282650a3, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MetallicGlossMap: diff --git a/TrueTrace/Models/1sponza (2)/Materials/fabric_f.mat b/TrueTrace/Models/1sponza (2)/Materials/fabric_f.mat index 17408961..8c336fdc 100644 --- a/TrueTrace/Models/1sponza (2)/Materials/fabric_f.mat +++ b/TrueTrace/Models/1sponza (2)/Materials/fabric_f.mat @@ -41,7 +41,7 @@ Material: m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MainTex: - m_Texture: {fileID: 2800000, guid: 2fd9297c087b1334195e475b89ed03cf, type: 3} + m_Texture: {fileID: 2800000, guid: 64ec855af9265d74fa3d391fbf0516cd, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MetallicGlossMap: diff --git a/TrueTrace/Models/1sponza (2)/Materials/fabric_g.mat b/TrueTrace/Models/1sponza (2)/Materials/fabric_g.mat index 05b4b7de..8742fdb7 100644 --- a/TrueTrace/Models/1sponza (2)/Materials/fabric_g.mat +++ b/TrueTrace/Models/1sponza (2)/Materials/fabric_g.mat @@ -41,7 +41,7 @@ Material: m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MainTex: - m_Texture: {fileID: 2800000, guid: b73406b81b6cd484181dedc3f25e648f, type: 3} + m_Texture: {fileID: 2800000, guid: 180cd58a9e745954f9f78d8b15b59cca, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MetallicGlossMap: diff --git a/TrueTrace/Models/1sponza (2)/textures/background.png.meta b/TrueTrace/Models/1sponza (2)/textures/background.png.meta index 325a1f44..d11b94eb 100644 --- a/TrueTrace/Models/1sponza (2)/textures/background.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/background.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 @@ -67,7 +67,7 @@ TextureImporter: platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 + maxTextureSize: 1024 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 2 diff --git a/TrueTrace/Models/1sponza (2)/textures/chain_texture.png.meta b/TrueTrace/Models/1sponza (2)/textures/chain_texture.png.meta index 044fa15e..9d327b3b 100644 --- a/TrueTrace/Models/1sponza (2)/textures/chain_texture.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/chain_texture.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/lion.png.meta b/TrueTrace/Models/1sponza (2)/textures/lion.png.meta index a486cf5a..f2343add 100644 --- a/TrueTrace/Models/1sponza (2)/textures/lion.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/lion.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/spnza_bricks_a_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/spnza_bricks_a_diff.png.meta index fda1b812..b9b1b406 100644 --- a/TrueTrace/Models/1sponza (2)/textures/spnza_bricks_a_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/spnza_bricks_a_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_arch_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_arch_diff.png.meta index b1ad196b..b01d5ce8 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_arch_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_arch_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_ceiling_a_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_ceiling_a_diff.png.meta index d4289fde..22747aa7 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_ceiling_a_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_ceiling_a_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_column_a_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_column_a_diff.png.meta index 8337d5fa..cee56341 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_column_a_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_column_a_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_column_b_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_column_b_diff.png.meta index a4b31dc3..a9f07fd7 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_column_b_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_column_b_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_column_c_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_column_c_diff.png.meta index 7fece194..9081994a 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_column_c_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_column_c_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_blue_diff.jpg b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_blue_diff.jpg new file mode 100644 index 00000000..9a3a7596 Binary files /dev/null and b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_blue_diff.jpg differ diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_green_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_blue_diff.jpg.meta similarity index 96% rename from TrueTrace/Models/1sponza (2)/textures/sponza_curtain_green_diff.png.meta rename to TrueTrace/Models/1sponza (2)/textures/sponza_curtain_blue_diff.jpg.meta index fd62e775..49d52fb4 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_green_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_blue_diff.jpg.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b73406b81b6cd484181dedc3f25e648f +guid: 64ec855af9265d74fa3d391fbf0516cd TextureImporter: internalIDToNameTable: [] externalObjects: {} @@ -67,10 +67,10 @@ TextureImporter: platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 + maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 - textureCompression: 2 + textureCompression: 1 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_blue_diff.png b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_blue_diff.png deleted file mode 100644 index 0bd77e01..00000000 Binary files a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_blue_diff.png and /dev/null differ diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_diff.jpg b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_diff.jpg new file mode 100644 index 00000000..2eac2905 Binary files /dev/null and b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_diff.jpg differ diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_blue_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_diff.jpg.meta similarity index 96% rename from TrueTrace/Models/1sponza (2)/textures/sponza_curtain_blue_diff.png.meta rename to TrueTrace/Models/1sponza (2)/textures/sponza_curtain_diff.jpg.meta index 839db7b5..ef436b6d 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_blue_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_diff.jpg.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2fd9297c087b1334195e475b89ed03cf +guid: edfe82195fdbf7f4d8fa7a59282650a3 TextureImporter: internalIDToNameTable: [] externalObjects: {} @@ -67,10 +67,10 @@ TextureImporter: platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 + maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 - textureCompression: 2 + textureCompression: 1 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_diff.png b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_diff.png deleted file mode 100644 index 959a210f..00000000 Binary files a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_diff.png and /dev/null differ diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_green_diff.jpg b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_green_diff.jpg new file mode 100644 index 00000000..7001987a Binary files /dev/null and b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_green_diff.jpg differ diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_green_diff.jpg.meta similarity index 96% rename from TrueTrace/Models/1sponza (2)/textures/sponza_curtain_diff.png.meta rename to TrueTrace/Models/1sponza (2)/textures/sponza_curtain_green_diff.jpg.meta index 60869dd5..f82ec6d4 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_green_diff.jpg.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 485233ca597afda4fb7d18c571b6a801 +guid: 180cd58a9e745954f9f78d8b15b59cca TextureImporter: internalIDToNameTable: [] externalObjects: {} @@ -67,10 +67,10 @@ TextureImporter: platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 + maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 - textureCompression: 2 + textureCompression: 1 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_green_diff.png b/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_green_diff.png deleted file mode 100644 index ac4371e8..00000000 Binary files a/TrueTrace/Models/1sponza (2)/textures/sponza_curtain_green_diff.png and /dev/null differ diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_details_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_details_diff.png.meta index c17b1b1c..7840dc4d 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_details_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_details_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_fabric_blue_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_fabric_blue_diff.png.meta index ca7593b1..914d62a0 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_fabric_blue_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_fabric_blue_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_fabric_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_fabric_diff.png.meta index b21ff5b3..b25e7118 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_fabric_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_fabric_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_fabric_green_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_fabric_green_diff.png.meta index 784a7dbd..a9f8a0d8 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_fabric_green_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_fabric_green_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_flagpole_diff.png b/TrueTrace/Models/1sponza (2)/textures/sponza_flagpole_diff.png index a5887833..cb122412 100644 Binary files a/TrueTrace/Models/1sponza (2)/textures/sponza_flagpole_diff.png and b/TrueTrace/Models/1sponza (2)/textures/sponza_flagpole_diff.png differ diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_flagpole_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_flagpole_diff.png.meta index b5dbb02a..4b9241fa 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_flagpole_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_flagpole_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 @@ -67,7 +67,7 @@ TextureImporter: platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 + maxTextureSize: 512 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 2 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_floor_a_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_floor_a_diff.png.meta index 45c9a622..afe991f9 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_floor_a_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_floor_a_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_roof_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_roof_diff.png.meta index 6f9ee187..5751874d 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_roof_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_roof_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 @@ -67,7 +67,7 @@ TextureImporter: platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 + maxTextureSize: 1024 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 2 diff --git a/TrueTrace/Models/1sponza (2)/textures/sponza_thorn_diff.png.meta b/TrueTrace/Models/1sponza (2)/textures/sponza_thorn_diff.png.meta index 6c0cb93c..bf2c6cc0 100644 --- a/TrueTrace/Models/1sponza (2)/textures/sponza_thorn_diff.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/sponza_thorn_diff.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/vase_dif.png.meta b/TrueTrace/Models/1sponza (2)/textures/vase_dif.png.meta index da953efc..93cf2c0f 100644 --- a/TrueTrace/Models/1sponza (2)/textures/vase_dif.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/vase_dif.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/vase_hanging.png.meta b/TrueTrace/Models/1sponza (2)/textures/vase_hanging.png.meta index 350f35a0..5df81ae5 100644 --- a/TrueTrace/Models/1sponza (2)/textures/vase_hanging.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/vase_hanging.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 @@ -67,7 +67,7 @@ TextureImporter: platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 + maxTextureSize: 1024 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 2 diff --git a/TrueTrace/Models/1sponza (2)/textures/vase_plant.png.meta b/TrueTrace/Models/1sponza (2)/textures/vase_plant.png.meta index b2d3bf12..1d74eb83 100644 --- a/TrueTrace/Models/1sponza (2)/textures/vase_plant.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/vase_plant.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Models/1sponza (2)/textures/vase_round.png.meta b/TrueTrace/Models/1sponza (2)/textures/vase_round.png.meta index 564c8bc7..b518431d 100644 --- a/TrueTrace/Models/1sponza (2)/textures/vase_round.png.meta +++ b/TrueTrace/Models/1sponza (2)/textures/vase_round.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 12 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 diff --git a/TrueTrace/Resources/AssetManager.cs b/TrueTrace/Resources/AssetManager.cs index f38301ba..700245f6 100644 --- a/TrueTrace/Resources/AssetManager.cs +++ b/TrueTrace/Resources/AssetManager.cs @@ -797,6 +797,11 @@ public void Awake() { public void Start() { Assets = this; SceneManager.sceneLoaded += OnSceneLoaded; + SceneManager.sceneUnloaded += OnSceneUnloaded; + } + + void OnSceneUnloaded(Scene scene) { + ClearAll(); } void OnSceneLoaded(Scene scene, LoadSceneMode mode) { @@ -842,6 +847,7 @@ void OnDisable() { bindlessTextures?.Dispose(); bindlessTextures = null; SceneManager.sceneLoaded -= OnSceneLoaded; + SceneManager.sceneUnloaded -= OnSceneUnloaded; } @@ -996,7 +1002,9 @@ private void UpdateRenderAndBuildQues() { QueCount = BuildQue.Count; for (int i = QueCount - 1; i >= 0; i--) {//Promotes from Build Que to Render Que if (BuildQue[i].AsyncTask.IsFaulted) {//Fuck, something fucked up +#if TTVerbose Debug.LogError(BuildQue[i].AsyncTask.Exception + ", " + BuildQue[i].Name); +#endif BuildQue[i].FailureCount++; BuildQue[i].ClearAll(); if(BuildQue[i].FailureCount > 6) { @@ -1067,7 +1075,7 @@ private void UpdateRenderAndBuildQues() { QueCount = InstanceRemoveQue.Count; for (int i = QueCount - 1; i >= 0; i--) { switch(InstanceRemoveQue[i].ExistsInQue) { - default: Debug.Log("INSTANCES BROKE!"); break; + default: Debug.LogError("Report this to the developer"); break; case 0: {InstanceRenderTransforms.RemoveAt(InstanceRenderQue.IndexOf(InstanceRemoveQue[i])); InstanceRenderQue.Remove(InstanceRemoveQue[i]);} break; case 1: InstanceBuildQue.Remove(InstanceRemoveQue[i]); break; case 3: InstanceAddQue.Remove(InstanceRemoveQue[i]); break; @@ -1250,8 +1258,10 @@ private void AccumulateData(CommandBuffer cmd) CurSGNodeOffset = 2 * (LightMeshCount); AggSGTreeNodeCount += CurSGNodeOffset; +#if TTVerbose Debug.Log("Light Tri Count: " + LightTriCount); Debug.Log("Total Tri Count: " + AggTriCount); +#endif if(LightTriCount == 0) {LightTriCount++; AggSGTreeNodeCount++;} if (AggNodeCount != 0) {//Accumulate the BVH nodes and triangles for all normal models @@ -1616,23 +1626,23 @@ unsafe public void ConstructNewTLAS() { TempConfig.mesh = mesh; TempConfig.subMeshIndex = (uint)i2; InstanceData.RenderQue[i].TryGetComponent(out MeshRenderer TempRend); - TempConfig.material = TempRend.sharedMaterials[i2]; + TempConfig.material = TempRend.sharedMaterials[Mathf.Min(i2, TempRend.sharedMaterials.Length - 1)]; TempConfig.material.enableInstancing = true; InstanceData.RenderQue[i].RTAccelHandle[i2] = AccelStruct.AddInstances(TempConfig, InstanceData.RenderQue[i].InstanceDatas, -1, 0, (uint)MeshOffset + (uint)ExistingList.Count * (uint)i2); InstanceData.RenderQue[i].RTAccelSubmeshOffsets[i2] = MeshOffset + ExistingList.Count * i2; } - for (int i2 = 0; i2 < SubMeshCount; ++i2) - {//Add together all the submeshes in the mesh to consider it as one object - SubMeshOffsets.Add(TotLength); - int IndiceLength = (int)mesh.GetIndexCount(i2) / 3; - TotLength += IndiceLength; - } - MeshOffset += ExistingList.Count * SubMeshCount; - ExteriorCount += ExistingList.Count;// * SubMeshCount; + MeshOffset += ExistingList.Count * SubMeshCount; + ExteriorCount += ExistingList.Count;// * SubMeshCount; } + for (int i2 = 0; i2 < SubMeshCount; ++i2) + {//Add together all the submeshes in the mesh to consider it as one object + SubMeshOffsets.Add(TotLength); + int IndiceLength = (int)mesh.GetIndexCount(i2) / 3; + TotLength += IndiceLength; + } } AccelStruct.Build(); @@ -2142,7 +2152,9 @@ public int UpdateTLAS(CommandBuffer cmd) CommonFunctions.CreateComputeBuffer(ref LightMeshBuffer, LightMeshes); +#if TTVerbose Debug.Log("Total Object Count: " + MeshAABBs.Length); +#endif // UnityEngine.Profiling.Profiler.BeginSample("Update Materials"); HasChangedMaterials = UpdateMaterials(); // UnityEngine.Profiling.Profiler.EndSample(); @@ -2254,7 +2266,7 @@ public int UpdateTLAS(CommandBuffer cmd) TempConfig.mesh = mesh; TempConfig.subMeshIndex = (uint)i2; ObjsToUpdate[i].TryGetComponent(out MeshRenderer TempRend); - TempConfig.material = TempRend.sharedMaterials[i2]; + TempConfig.material = TempRend.sharedMaterials[Mathf.Min(i2, TempRend.sharedMaterials.Length - 1)]; ObjsToUpdate[i].RTAccelHandle[i2] = AccelStruct.AddInstances(TempConfig, ObjsToUpdate[i].InstanceDatas, -1, 0, (uint)ObjsToUpdate[i].RTAccelSubmeshOffsets[i2]); } diff --git a/TrueTrace/Resources/Builders/BVH8Builder.cs b/TrueTrace/Resources/Builders/BVH8Builder.cs index dc0af7bd..c3d5ce71 100644 --- a/TrueTrace/Resources/Builders/BVH8Builder.cs +++ b/TrueTrace/Resources/Builders/BVH8Builder.cs @@ -419,6 +419,15 @@ float surface_area(ref AABB aabb) { public BVH8Builder() {}//null constructor + public void Dispose() { + if(decisionsArray.IsCreated) decisionsArray.Dispose(); + if(costArray.IsCreated) costArray.Dispose(); + if(BVH8NodesArray.IsCreated) BVH8NodesArray.Dispose(); + if(BVH8NodesArraySecondary.IsCreated) BVH8NodesArraySecondary.Dispose(); + CommonFunctions.DeepClean(ref cwbvh_indices); + + } + public BVH8Builder(ref BVH2Builder BVH2) {//Bottom Level CWBVH Builder int BVH2NodesCount = BVH2.BVH2NodesArray.Length; int BVH2IndicesCount = BVH2.FinalIndices.Length; diff --git a/TrueTrace/Resources/Builders/CommonVars.cs b/TrueTrace/Resources/Builders/CommonVars.cs index 75612849..65579de9 100644 --- a/TrueTrace/Resources/Builders/CommonVars.cs +++ b/TrueTrace/Resources/Builders/CommonVars.cs @@ -1006,6 +1006,11 @@ public static void ReleaseSafe(this ComputeBuffer Buff) if (Buff != null) {Buff.Release(); Buff = null;} } + public static void ReleaseSafe(this GraphicsBuffer Buff) + { + if (Buff != null) {Buff.Release(); Buff = null;} + } + static Vector2 msign(Vector2 v) { return new Vector2((v.x >= 0.0f) ? 1.0f : -1.0f, (v.y >= 0.0f) ? 1.0f : -1.0f); @@ -1206,5 +1211,34 @@ public static uint packRGBE(Color v) return result; } + #if UNITY_EDITOR + public static T GetCopyOf2(this Component comp, T other) where T : Component + { + System.Type type = comp.GetType(); + if (type != other.GetType()) return null; // type mis-match + System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Default | System.Reflection.BindingFlags.DeclaredOnly; + System.Reflection.PropertyInfo[] pinfos = type.GetProperties(flags); + foreach (var pinfo in pinfos) { + if (pinfo.CanWrite) { + try { + pinfo.SetValue(comp, pinfo.GetValue(other, null), null); + } + catch { } // In case of NotImplementedException being thrown. For some reason specifying that exception didn't seem to catch it, so I didn't catch anything specific. + } + } + System.Reflection.FieldInfo[] finfos = type.GetFields(flags); + foreach (var finfo in finfos) { + finfo.SetValue(comp, finfo.GetValue(other)); + } + return comp as T; + } + public static T AddComponent(this GameObject go, T toAdd) where T : Component + { + return go.AddComponent().GetCopyOf2(toAdd) as T; + } + + #endif + + } } diff --git a/TrueTrace/Resources/Builders/InstancedManager.cs b/TrueTrace/Resources/Builders/InstancedManager.cs index 1f06aa64..af67a18d 100644 --- a/TrueTrace/Resources/Builders/InstancedManager.cs +++ b/TrueTrace/Resources/Builders/InstancedManager.cs @@ -34,10 +34,16 @@ public struct InstanceTransformData { public void InitRelationships() { NeedsToReinit = false; - TempQue = new List(this.GetComponentsInChildren()); + TempQue = new List(this.GetComponentsInChildren(false)); InstanceIndexes = new Dictionary(); - InstancedObject[] InstanceQues = GameObject.FindObjectsOfType(); + InstancedObject[] InstanceQues = GameObject.FindObjectsOfType(false); int InstCount = InstanceQues.Length; + List TempObject2 = new List(); + for(int i = 0; i < InstCount; i++) { + if(InstanceQues[i].InstanceParent != null) TempObject2.Add(InstanceQues[i]); + } + InstanceQues = TempObject2.ToArray(); + InstCount = InstanceQues.Length; for(int i = 0; i < InstCount; i++) { if (InstanceIndexes.TryGetValue(InstanceQues[i].InstanceParent, out InstanceData ExistingList)) { ExistingList.InstanceTargets.Add(InstanceQues[i]); @@ -81,6 +87,10 @@ public void RenderInstances() { int Coun2 = ExistingList.InstanceTargets.Count; Bounds TempBounds = ExistingList.LocalMesh.bounds; Matrix4x4 TempIden; + if(ExistingList.InstTransfArray == null) { + NeedsToReinit = true; + continue; + } for(int i2 = 0; i2 < Coun2; i2++) { TempIden = Matrix4x4.identity; ExistingList.InstTransfArray[i2].prevObjectToWorld = ExistingList.InstTransfArray[i2].objectToWorld; @@ -88,7 +98,16 @@ public void RenderInstances() { else ExistingList.InstTransfArray[i2].objectToWorld = ExistingList.InstanceTargets[i2].transform.localToWorldMatrix; } - for(int i2 = 0; i2 < ExistingList.SubMeshCount; i2++) {try {Graphics.RenderMeshInstanced(ExistingList.LocalRendp, TempQue[i].RenderImposters ? Resources.GetBuiltinResource("Cube.fbx") : ExistingList.LocalMesh, i2, ExistingList.InstTransfArray);} catch(System.Exception E) {}} + for(int i2 = 0; i2 < ExistingList.SubMeshCount; i2++) {try { + int Count = ExistingList.InstTransfArray.Length; + int Offset = 0; + int Batches = Mathf.CeilToInt((float)Count / 512.0f); + for(int i3 = 0; i3 < Batches; i3++) { + Graphics.RenderMeshInstanced(ExistingList.LocalRendp, TempQue[i].RenderImposters ? Resources.GetBuiltinResource("Cube.fbx") : ExistingList.LocalMesh, i2, ExistingList.InstTransfArray, Mathf.Min(Count - Offset, 512), Offset); + Offset += 512; + } + + } catch(System.Exception E) {}} } } } diff --git a/TrueTrace/Resources/Builders/LightBVHBuilder.cs b/TrueTrace/Resources/Builders/LightBVHBuilder.cs index 051e37ac..8f81835b 100644 --- a/TrueTrace/Resources/Builders/LightBVHBuilder.cs +++ b/TrueTrace/Resources/Builders/LightBVHBuilder.cs @@ -337,6 +337,29 @@ float SGIntegral(float sharpness) return 4.0f * Mathf.PI * expm1_over_x(-2.0f * sharpness); } + // Estimation of vMF sharpness (i.e., SG sharpness) from the average of directions in R^3. + // [Banerjee et al. 2005 "Clustering on the Unit Hypersphere using von Mises-Fisher Distributions"] + float VMFAxisLengthToSharpness(float axisLength) + { + return axisLength * (3.0f - axisLength * axisLength) / (1.0f - axisLength * axisLength); + } + + // Inverse of VMFAxisLengthToSharpness. + float VMFSharpnessToAxisLength(float sharpness) + { + // Solve x^3 - sx^2 - 3x + s = 0, where s = sharpness. + // For x in [0, 1] and s in [0, infty), this equation has only a single solution. + // [Xu and Wang 2015 "Realtime Rendering Glossy to Glossy Reflections in Screen Space"] + // We solve this cubic equation in a numerically stable manner. + // [Peters, C. 2016 "How to solve a cubic equation, revisited" https://momentsingraphics.de/CubicRoots.html] + float a = sharpness / 3.0f; + float b = a * a * a; + float c = Mathf.Sqrt(1.0f + 3.0f * (a * a) * (1.0f + a * a)); + float theta = Mathf.Atan2(c, b) / 3.0f; + float d = -2.0f * Mathf.Sin(Mathf.PI / 6.0f - theta); // = sin(theta) * sqrt(3) - cos(theta). + return (sharpness > 33554432.0f) ? 1.0f : Mathf.Sqrt(1.0f + a * a) * d + a; + } + public unsafe LightBVHBuilder(List Tris, List Norms, float phi, List LuminanceWeights) {//need to make sure incomming is transformed to world space already @@ -457,7 +480,7 @@ public unsafe LightBVHBuilder(List Tris, List Norms, floa float w_left = phi_left / (phi_left + phi_right); float w_right = phi_right / (phi_left + phi_right); - V = w_left * LeftNode.axis + w_right * RightNode.axis; + V = w_left * LeftNode.axis * VMFSharpnessToAxisLength(LeftNode.sharpness) + w_right * RightNode.axis * VMFSharpnessToAxisLength(RightNode.sharpness); mean = w_left * LeftNode.S.Center + w_right * RightNode.S.Center; variance = w_left * LeftNode.variance + w_right * RightNode.variance + w_left * w_right * Vector3.Dot(LeftNode.S.Center - RightNode.S.Center, LeftNode.S.Center - RightNode.S.Center); @@ -465,7 +488,10 @@ public unsafe LightBVHBuilder(List Tris, List Norms, floa intensity = LeftNode.intensity + RightNode.intensity; radius = Mathf.Max(Distance(mean, LeftNode.S.Center) + LeftNode.S.Radius, Distance(mean, RightNode.S.Center) + RightNode.S.Radius); } - TempNode.sharpness = ((3.0f * Distance(Vector3.zero, V) - Mathf.Pow(Distance(Vector3.zero, V), 3))) / (1.0f - Mathf.Pow(Distance(Vector3.zero, V), 2)); + float AxisLength = Distance(Vector3.zero, V); + if(AxisLength == 0) V = new Vector3(0,1,0); + else V /= AxisLength; + TempNode.sharpness = Mathf.Min(VMFAxisLengthToSharpness(Mathf.Clamp(AxisLength, 0.0f, 1.0f)), 2199023255552.0f);// ((3.0f * Distance(Vector3.zero, V) - Mathf.Pow(Distance(Vector3.zero, V), 3))) / (1.0f - Mathf.Pow(Distance(Vector3.zero, V), 2)); TempNode.axis = V; TempNode.S.Center = mean; TempNode.variance = variance; @@ -591,6 +617,7 @@ public LightBVHBuilder(LightBounds[] Tris,ref GaussianTreeNode[] SGTree, LightBV Vector3 center = CommonFunctions.ToVector3(LightBVHTransforms[-(LBVHNode.left+1)].Transform * CommonFunctions.ToVector4(TempNode.S.Center, 1)); Vector3 Axis = CommonFunctions.ToVector3(LightBVHTransforms[-(LBVHNode.left+1)].Transform * CommonFunctions.ToVector4(TempNode.axis, 0)); float Scale = Distance(center, ExtendedCenter) / TempNode.S.Radius; + TempNode.sharpness = Mathf.Min(VMFAxisLengthToSharpness(Mathf.Clamp(VMFSharpnessToAxisLength(TempNode.sharpness) / Scale, 0.0f, 1.0f)), 2199023255552.0f);// ((3.0f * Distance(Vector3.zero, V) - Mathf.Pow(Distance(Vector3.zero, V), 3))) / (1.0f - Mathf.Pow(Distance(Vector3.zero, V), 2)); TempNode.axis = Axis; TempNode.S.Center = center; TempNode.variance *= Scale; @@ -605,14 +632,20 @@ public LightBVHBuilder(LightBounds[] Tris,ref GaussianTreeNode[] SGTree, LightBV float w_left = phi_left / (phi_left + phi_right); float w_right = phi_right / (phi_left + phi_right); - V = w_left * LeftNode.axis + w_right * RightNode.axis;//may be wrong, paper uses BAR_V(BAR_axis here), not just normalized V/axis + V = w_left * LeftNode.axis * VMFSharpnessToAxisLength(LeftNode.sharpness) + w_right * RightNode.axis * VMFSharpnessToAxisLength(RightNode.sharpness); + // V = w_left * LeftNode.axis + w_right * RightNode.axis;//may be wrong, paper uses BAR_V(BAR_axis here), not just normalized V/axis mean = w_left * LeftNode.S.Center + w_right * RightNode.S.Center; variance = w_left * LeftNode.variance + w_right * RightNode.variance + w_left * w_right * Vector3.Dot(LeftNode.S.Center - RightNode.S.Center, LeftNode.S.Center - RightNode.S.Center); intensity = LeftNode.intensity + RightNode.intensity; radius = Mathf.Max(Distance(mean, LeftNode.S.Center) + LeftNode.S.Radius, Distance(mean, RightNode.S.Center) + RightNode.S.Radius); - TempNode.sharpness = ((3.0f * Distance(Vector3.zero, V) - Mathf.Pow(Distance(Vector3.zero, V), 3))) / (1.0f - Mathf.Pow(Distance(Vector3.zero, V), 2)); + + float AxisLength = Distance(Vector3.zero, V); + if(AxisLength == 0) V = new Vector3(0,1,0); + else V /= AxisLength; + TempNode.sharpness = Mathf.Min(VMFAxisLengthToSharpness(Mathf.Clamp(AxisLength, 0.0f, 1.0f)), 2199023255552.0f);// ((3.0f * Distance(Vector3.zero, V) - Mathf.Pow(Distance(Vector3.zero, V), 3))) / (1.0f - Mathf.Pow(Distance(Vector3.zero, V), 2)); + TempNode.axis = V; TempNode.S.Center = mean; TempNode.variance = variance; diff --git a/TrueTrace/Resources/GlobalDefines.cginc b/TrueTrace/Resources/GlobalDefines.cginc index 54f408c6..20f88102 100644 --- a/TrueTrace/Resources/GlobalDefines.cginc +++ b/TrueTrace/Resources/GlobalDefines.cginc @@ -18,7 +18,7 @@ // #define FasterLightSampling #define AccurateEmissionTex #define TrueBlack -#define UseTextureLOD +// #define UseTextureLOD // #define vMFDiffuse #define EONDiffuse // #define AdvancedBackground @@ -26,8 +26,10 @@ #define DoubleBufferSGTree // #define Fog #define RadCache -// #define NonDirectionalRadCache #define ExpensiveReSTIR +// #define FakedAO +// #define AutoDebugReading + //END OF DEFINES @@ -47,7 +49,7 @@ #define DepthDivisor 1000.0f -#define FogScale 4.0f +#define FogScale 12.0f //Dont change the ones below diff --git a/TrueTrace/Resources/MainCompute/CommonData.cginc b/TrueTrace/Resources/MainCompute/CommonData.cginc index 51216c07..a9494443 100644 --- a/TrueTrace/Resources/MainCompute/CommonData.cginc +++ b/TrueTrace/Resources/MainCompute/CommonData.cginc @@ -182,7 +182,7 @@ inline float2 AlignUV(float2 BaseUV, float4 TexScale, int2 TexDim2, float Rotati // BaseUV =fmod(abs(BaseUV), 1.0f); if(Rotation != 0) { float sinc, cosc; - sincos(Rotation, sinc, cosc); + sincos(Rotation / 180.0f, sinc, cosc); BaseUV -= 0.5f; float2 tempuv = BaseUV; BaseUV.x = tempuv.x * cosc - tempuv.y * sinc; @@ -253,7 +253,7 @@ inline float4 SampleTexture(float2 UV, int TextureType, const MaterialData MatTe int2 TextureIndexAndChannel = -1;// = MatTex.BindlessIndex; if(MatTex.Rotation != 0) { float sinc, cosc; - sincos(MatTex.Rotation, sinc, cosc); + sincos(MatTex.Rotation / 180.0f, sinc, cosc); UV -= 0.5f; float2 tempuv = UV; UV.x = tempuv.x * cosc - tempuv.y * sinc; @@ -374,7 +374,7 @@ bool UseASVGF; bool UseReSTIRGI; float2 randomNEE(uint samdim, uint pixel_index) { - uint hash = pcg_hash((pixel_index * (uint)258 + samdim) * (MaxBounce + 1) + CurBounce); + uint hash = pcg_hash((pixel_index * (uint)526 + samdim) * (MaxBounce + 1) + CurBounce); static const float one_over_max_unsigned = asfloat(0x2f7fffff); @@ -388,7 +388,7 @@ float2 randomNEE(uint samdim, uint pixel_index) { float2 random(uint samdim, uint pixel_index) { [branch] if (UseASVGF || (UseReSTIRGI && ReSTIRGIUpdateRate != 0)) { uint2 pixid = uint2(pixel_index % screen_width, pixel_index / screen_width); - uint hash = pcg_hash(((uint)RandomNums[pixid].y * (uint)258 + samdim) * (MaxBounce + 1) + CurBounce); + uint hash = pcg_hash(((uint)RandomNums[pixid].y * (uint)526 + samdim) * (MaxBounce + 1) + CurBounce); const static float one_over_max_unsigned = asfloat(0x2f7fffff); @@ -399,7 +399,7 @@ float2 random(uint samdim, uint pixel_index) { return float2(x, y); } else { - uint hash = pcg_hash((pixel_index * (uint)258 + samdim) * (MaxBounce + 1) + CurBounce); + uint hash = pcg_hash((pixel_index * (uint)526 + samdim) * (MaxBounce + 1) + CurBounce); const static float one_over_max_unsigned = asfloat(0x2f7fffff); @@ -804,8 +804,8 @@ inline uint cwbvh_node_intersect(const SmallerRay ray, int oct_inv4, float max_d [unroll] for(int j = 0; j < 4; j++) { - tmin3 = float3(((x_min >> (j * 8)) & 0xff), ((y_min >> (j * 8)) & 0xff), ((z_min >> (j * 8)) & 0xff)); - tmax3 = float3(((x_max >> (j * 8)) & 0xff), ((y_max >> (j * 8)) & 0xff), ((z_max >> (j * 8)) & 0xff)); + tmin3 = float3(((x_min >> (j * 8)) & 0xffu), ((y_min >> (j * 8)) & 0xffu), ((z_min >> (j * 8)) & 0xffu)); + tmax3 = float3(((x_max >> (j * 8)) & 0xffu), ((y_max >> (j * 8)) & 0xffu), ((z_max >> (j * 8)) & 0xffu)); tmin3 = mad(tmin3, adjusted_ray_direction_inv, adjusted_ray_origin); tmax3 = mad(tmax3, adjusted_ray_direction_inv, adjusted_ray_origin); @@ -816,8 +816,8 @@ inline uint cwbvh_node_intersect(const SmallerRay ray, int oct_inv4, float max_d bool intersected = tmin < tmax; [branch] if (intersected) { - child_bits = (child_bits4 >> (j * 8)) & 0xff; - bit_index = (bit_index4 >> (j * 8)) & 0xff; + child_bits = (child_bits4 >> (j * 8)) & 0xffu; + bit_index = (bit_index4 >> (j * 8)) & 0xffu; hit_mask |= child_bits << bit_index; } @@ -1226,7 +1226,7 @@ inline float AreaOfTriangle(float3 pt1, float3 pt2, float3 pt3) { } static const float FLT_EPSILON = 1.192092896e-07f; - +static const float FLT_MIN = 1.175494351e-38f; inline float2 mulsign(const float2 x, const float2 y) @@ -1316,17 +1316,18 @@ struct SGLobe { float sharpness ; float logAmplitude ; }; + inline SGLobe sg_product ( float3 axis1 , float sharpness1 , float3 axis2 , float sharpness2 ) { float3 axis = axis1 * sharpness1 + axis2 * sharpness2 ; float sharpness = length ( axis ) ; - float cosine = clamp (dot( axis1 , axis2 ) , -1.0 , 1.0) ; - float sharpnessMin = min( sharpness1 , sharpness2 ) ; - float sharpnessRatio = sharpnessMin / max( sharpness1 , sharpness2 ) ; - float logAmplitude = 2.0 * sharpnessMin * ( cosine - 1.0) / (1.0 + sharpnessRatio + sqrt (2.0 * sharpnessRatio * cosine - + sharpnessRatio * sharpnessRatio + 1.0) ) ; - SGLobe result = { axis / max( sharpness , EPSILON ) , sharpness , logAmplitude }; + + float3 d = axis1 - axis2; + float len2 = dot(d, d); + float logAmplitude = -sharpness1 * sharpness2 * len2 / max(sharpness + sharpness1 + sharpness2, FLT_MIN); + SGLobe result = { axis / max( sharpness , FLT_MIN ) , sharpness , logAmplitude }; return result ; } + static const float FLT_MAX = 3.402823466e+38f; @@ -1524,7 +1525,6 @@ inline float SGImportance(const GaussianTreeNode TargetNode, const float3 viewDi to_light = normalize(to_light); const SGLobe LightLobe = sg_product((TargetNode.axis), TargetNode.sharpness, to_light, squareddist / Variance); - const float emissive = (TargetNode.intensity) / (Variance * SGIntegral(TargetNode.sharpness)); const float amplitude = exp(LightLobe.logAmplitude); @@ -1847,8 +1847,8 @@ float3 LoadSurfaceInfo(int2 id) { void Unity_Hue_Degrees_float(float3 In, float Offset, out float3 Out) { // RGB to HSV float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); - float4 P = lerp(float4(In.bg, K.wz), float4(In.gb, K.xy), step(In.b, In.g)); - float4 Q = lerp(float4(P.xyw, In.r), float4(In.r, P.yzx), step(P.x, In.r)); + float4 P = step(In.z, In.y) ? float4(In.yz, K.xy) : float4(In.zy, K.wz); + float4 Q = step(P.x, In.x) ? float4(In.x, P.yzx) : float4(P.xyw, In.x); float D = Q.x - min(Q.w, Q.y); float E = 1e-10; float V = (D == 0) ? Q.x : (Q.x + E); @@ -2338,9 +2338,7 @@ inline int SelectLight(const uint pixel_index, inout uint MeshIndex, inout float MatDat.surfaceColor *= SampleTexture(BaseUv, SampleAlbedo, MatDat); float3 TempCol = MatDat.surfaceColor; - #ifndef DX11 - Unity_Hue_Degrees_float(TempCol, MatDat.Hue * 500.0f, MatDat.surfaceColor); - #endif + Unity_Hue_Degrees_float(TempCol, MatDat.Hue * 500.0f, MatDat.surfaceColor); MatDat.surfaceColor *= MatDat.Brightness; TempCol = MatDat.surfaceColor; Unity_Saturation_float(TempCol, MatDat.Saturation, MatDat.surfaceColor); @@ -2620,3 +2618,343 @@ bool plane_distance_disocclusion_check(float3 current_pos, float3 history_pos, f +#define FLT_EPS 5.960464478e-8 + +// 'height' is the altitude. +// 'cosTheta' is the Z component of the ray direction. +// 'dist' is the distance. +// seaLvlExt = (sigma_t * b) is the sea-level (height = 0) extinction coefficient. +// n = (1 / H) is the falloff exponent, where 'H' is the scale height. +float3 OptDepthRectExpMedium(float height, float cosTheta, float dist, + float3 seaLvlExt, float n) +{ + float p = -cosTheta * n; + + // Equation 26. + float3 optDepth = seaLvlExt * dist; + + if (abs(p) > FLT_EPS) // Uniformity check + { + // Equation 34. + optDepth = seaLvlExt * rcp(p) * exp(height * n) * (exp(p * dist) - 1); + } + + return optDepth; +} + +// 'optDepth' is the value of optical depth. +// 'height' is the altitude. +// 'cosTheta' is the Z component of the ray direction. +// seaLvlExtRcp = (1 / seaLvlExt). +// n = (1 / H) is the falloff exponent, where 'H' is the scale height. +float SampleRectExpMedium(float optDepth, float height, float cosTheta, + float seaLvlExtRcp, float n) +{ + float p = -cosTheta * n; + + // Equation 27. + float dist = optDepth * seaLvlExtRcp; + + if (abs(p) > FLT_EPS) // Uniformity check + { + // Equation 35. + dist = rcp(p) * log(1 + dist * p * exp(height * n)); + } + + return dist; +} + +// Max Abs Error: 0.000000969658452. +// Max Rel Error: 0.000001091639525. +float Exp2Erfc(float x) +{ + float t, u, y; + + t = 3.9788608f * rcp(x + 3.9788608f); // Reduce the range + u = t - 0.5f; // Center around 0 + + y = -0.010297533124685f; + y = mad(y, u, 0.288184314966202f); + y = mad(y, u, 0.805188119411469f); + y = mad(y, u, 1.203098773956299f); + y = mad(y, u, 1.371236562728882f); + y = mad(y, u, 1.312000870704651f); + y = mad(y, u, 1.079175233840942f); + y = mad(y, u, 0.774399876594543f); + y = mad(y, u, 0.490166693925858f); + y = mad(y, u, 0.275374621152878f); + + return y * t; // Expand the range +} + +float ChapmanUpper(float z, float absCosTheta) +{ + float sinTheta = sqrt(saturate(1 - absCosTheta * absCosTheta)); + + float zm12 = rsqrt(z); // z^(-1/2) + float zp12 = z * zm12; // z^(+1/2) + + float tp = 1 + sinTheta; // 1 + Sin + float rstp = rsqrt(tp); // 1 / Sqrt[1 + Sin] + float rtp = rstp * rstp; // 1 / (1 + Sin) + float stm = absCosTheta * rstp; // Sqrt[1 - Sin] = Abs[Cos] / Sqrt[1 + Sin] + float arg = zp12 * stm; // Sqrt[z - z * Sin], argument of Erfc + float e2ec = Exp2Erfc(arg); // Exp[x^2] * Erfc[x] + + // Term 1 of Equation 46. + float mul1 = absCosTheta * rtp; // Sqrt[(1 - Sin) / (1 + Sin)] = Abs[Cos] / (1 + Sin) + float trm1 = mul1 * (1 - 0.5 * rtp); + + // Term 2 of Equation 46. + float mul2 = sqrt(PI) * rstp * e2ec; // Sqrt[Pi / (1 + Sin)] * Exp[x^2] * Erfc[x] + float trm2 = mul2 * (zp12 * (-1.5 + tp + rtp) + + zm12 * 0.25 * (2 * tp - 1) * rtp); + return trm1 + trm2; +} + +float ChapmanHorizontal(float z) +{ + float zm12 = rsqrt(z); // z^(-1/2) + float zm32 = zm12 * zm12 * zm12; // z^(-3/2) + + float p = -0.14687275046666018 + z * (0.4699928014933126 + z * 1.2533141373155001); + + // Equation 47. + return p * zm32; +} + +// z = (r / H), Z = (R / H). +float RescaledChapman(float z, float Z, float cosTheta) +{ + float sinTheta = sqrt(saturate(1 - cosTheta * cosTheta)); + + // Cos[Pi - theta] = -Cos[theta], + // Sin[Pi - theta] = Sin[theta], + // so we can just use Abs[Cos[theta]]. + float ch = ChapmanUpper(z, abs(cosTheta)) * exp(Z - z); // Rescaling adds 'exp' + + if (cosTheta < 0) + { + // Ch[z, theta] = 2 * Exp[z - z_0] * Ch[z_0, Pi/2] - Ch[z, Pi - theta]. + // z_0 = r_0 / H = (r / H) * Sin[theta] = z * Sin[theta]. + float z_0 = z * sinTheta; + float chP = ChapmanHorizontal(z_0) * exp(Z - z_0); // Rescaling adds 'exp' + + // Equation 48. + ch = 2 * chP - ch; + } + + return ch; +} + + + +float RadAtDist(float r, float rRcp, float cosTheta, float s) +{ + float x2 = 1 + (s * rRcp) * ((s * rRcp) + 2 * cosTheta); + + // Equation 38. + return r * sqrt(x2); +} + +float CosAtDist(float r, float rRcp, float cosTheta, float s) +{ + float x2 = 1 + (s * rRcp) * ((s * rRcp) + 2 * cosTheta); + + // Equation 39. + return ((s * rRcp) + cosTheta) * rsqrt(x2); +} + +// This variant of the function evaluates optical depth along an infinite path. +// 'r' is the radial distance from the center of the planet. +// 'cosTheta' is the value of the dot product of the ray direction and the surface normal. +// seaLvlExt = (sigma_t * b) is the sea-level (height = 0) extinction coefficient. +// 'R' is the radius of the planet. +// n = (1 / H) is the falloff exponent, where 'H' is the scale height. +float3 OptDepthSpherExpMedium(float r, float cosTheta, float R, + float3 seaLvlExt, float H, float n) +{ + float z = r * n; + float Z = R * n; + + float ch = RescaledChapman(z, Z, cosTheta); + + return ch * H * seaLvlExt; +} + +// This variant of the function evaluates optical depth along a bounded path. +// 'r' is the radial distance from the center of the planet. +// rRcp = (1 / r). +// 'cosTheta' is the value of the dot product of the ray direction and the surface normal. +// 'dist' is the distance. +// seaLvlExt = (sigma_t * b) is the sea-level (height = 0) extinction coefficient. +// 'R' is the radius of the planet. +// n = (1 / H) is the falloff exponent, where 'H' is the scale height. +float3 OptDepthSpherExpMedium(float r, float rRcp, float cosTheta, float dist, float R, + float3 seaLvlExt, float H, float n) +{ + float rX = r; + float rRcpX = rRcp; + float cosThetaX = cosTheta; + float rY = RadAtDist(rX, rRcpX, cosThetaX, dist); + float cosThetaY = CosAtDist(rX, rRcpX, cosThetaX, dist); + + // Potentially swap X and Y. + // Convention: at point Y, the ray points up. + cosThetaX = (cosThetaY >= 0) ? cosThetaX : -cosThetaX; + + float zX = rX * n; + float zY = rY * n; + float Z = R * n; + + float chX = RescaledChapman(zX, Z, cosThetaX); + float chY = ChapmanUpper(zY, abs(cosThetaY)) * exp(Z - zY); // Rescaling adds 'exp' + + // We may have swapped X and Y. + float ch = abs(chX - chY); + + return ch * H * seaLvlExt; +} + +#define EPS_ABS 0.0001 +#define EPS_REL 0.0001 +#define MAX_ITER 4 + +// 'optDepth' is the value to solve for. +// 'maxOptDepth' is the maximum value along the ray, s.t. (maxOptDepth >= optDepth). +// 'maxDist' is the maximum distance along the ray. +float SampleSpherExpMedium(float optDepth, float r, float rRcp, float cosTheta, float R, + float2 seaLvlExt, float2 H, float2 n, // Air & aerosols + float maxOptDepth, float maxDist) +{ + const float optDepthRcp = rcp(optDepth); + const float2 Z = R * n; + + // Make an initial guess (assume the medium is uniform). + float t = maxDist * (optDepth * rcp(maxOptDepth)); + + // Establish the ranges of valid distances ('tRange') and function values ('fRange'). + float tRange[2], fRange[2]; + tRange[0] = 0; /* -> */ fRange[0] = 0 - optDepth; + tRange[1] = maxDist; /* -> */ fRange[1] = maxOptDepth - optDepth; + + uint iter = 0; + float absDiff = optDepth, relDiff = 1; + + do // Perform a Newton–Raphson iteration. + { + float radAtDist = RadAtDist(r, rRcp, cosTheta, t); + float cosAtDist = CosAtDist(r, rRcp, cosTheta, t); + // Evaluate the function and its derivatives: + // f [t] = OptDepthAtDist[t] - GivenOptDepth = 0, + // f' [t] = ExtCoefAtDist[t], + // f''[t] = ExtCoefAtDist'[t] = -ExtCoefAtDist[t] * CosAtDist[t] / H. + float optDepthAtDist = 0, extAtDist = 0, extAtDistDeriv = 0; + optDepthAtDist += OptDepthSpherExpMedium(r, rRcp, cosTheta, t, R, + seaLvlExt.x, H.x, n.x); + optDepthAtDist += OptDepthSpherExpMedium(r, rRcp, cosTheta, t, R, + seaLvlExt.y, H.y, n.y); + extAtDist += seaLvlExt.x * exp(Z.x - radAtDist * n.x); + extAtDist += seaLvlExt.y * exp(Z.y - radAtDist * n.y); + extAtDistDeriv -= seaLvlExt.x * exp(Z.x - radAtDist * n.x) * n.x; + extAtDistDeriv -= seaLvlExt.y * exp(Z.y - radAtDist * n.y) * n.y; + extAtDistDeriv *= cosAtDist; + + float f = optDepthAtDist - optDepth; + float df = extAtDist; + float ddf = extAtDistDeriv; + float dg = df - 0.5 * f * (ddf * rcp(df)); + + // assert(df > 0 && dg > 0); + + #if 0 + // https://en.wikipedia.org/wiki/Newton%27s_method + float slope = rcp(df); + #else + // https://en.wikipedia.org/wiki/Halley%27s_method + float slope = rcp(dg); + #endif + + float dt = -f * slope; + + // Find the boundary value we are stepping towards: + // supremum for (f < 0) and infimum for (f > 0). + uint sgn = asuint(f) >> 31; + float tBound = tRange[sgn]; + float fBound = fRange[sgn]; + float tNewton = t + dt; + // if(iter == 0) _DebugTex[id] = df;//-tNewton;//tRange[0] < tNewton; + + bool isInRange = tRange[0] < tNewton && tNewton < tRange[1]; + if (!isInRange) + { + // Newton's algorithm has effectively run out of digits of precision. + // While it's possible to continue improving precision (to a certain degree) + // via bisection, it is costly, and the convergence rate is low. + // It's better to recall that, for short distances, optical depth is a + // linear function of distance to an excellent degree of approximation. + slope = (tBound - t) * rcp(fBound - f); + dt = -f * slope; + iter = MAX_ITER; + } + + tRange[1 - sgn] = t; // Adjust the range using the + fRange[1 - sgn] = f; // previous values of 't' and 'f' + + t = t + dt; + + absDiff = abs(optDepthAtDist - optDepth); + relDiff = abs(optDepthAtDist * optDepthRcp - 1); + + iter++; + + // Stop when the accuracy goal has been reached. + // Note that this uses the accuracy corresponding to the old value of 't'. + // The new value of 't' we just computed should result in higher accuracy. + } while ((absDiff > EPS_ABS) && (relDiff > EPS_REL) && (iter < MAX_ITER)); + + return t; +} + + +float HenyeyGreenstein(float g, float mu) { + float gg = g * g; + return (1.0 / (4.0 * PI)) * ((1.0 - gg) / pow(1.0 + gg - 2.0 * g * mu, 1.5)); +} + +float DualHenyeyGreenstein(float g, float costh) { + return lerp(HenyeyGreenstein(-g, costh), HenyeyGreenstein(g, costh), 0.7f); +} + +float PhaseFunction(float g, float costh) { + return DualHenyeyGreenstein(g, costh); +} + +float3 MultipleOctaveScattering(float density, float mu) { + float attenuation = 0.2; + float contribution = 0.2; + float phaseAttenuation = 0.5; + + float a = 1.0; + float b = 1.0; + float c = 1.0; + float g = 0.85; + const float scatteringOctaves = 4.0; + + float3 luminance = 0.0; + + for (float i = 0.0; i < scatteringOctaves; i++) { + float phaseFunction = PhaseFunction(0.3 * c, mu); + float3 beers = exp(-density * float3(0.8, 0.8, 1) * a); + + luminance += b * phaseFunction * beers; + + a *= attenuation; + b *= contribution; + c *= (1.0 - phaseAttenuation); + } + return luminance; +} + + + diff --git a/TrueTrace/Resources/MainCompute/CommonStructs.cginc b/TrueTrace/Resources/MainCompute/CommonStructs.cginc index 9baf9505..9a22935f 100644 --- a/TrueTrace/Resources/MainCompute/CommonStructs.cginc +++ b/TrueTrace/Resources/MainCompute/CommonStructs.cginc @@ -20,6 +20,11 @@ struct CudaTriangle { StructuredBuffer AggTris; +struct AABB { + float3 BBMax; + float3 BBMin; +}; + struct GaussianTreeNode { float3 position; float radius; diff --git a/TrueTrace/Resources/MainCompute/Materials.cginc b/TrueTrace/Resources/MainCompute/Materials.cginc index 0fb7aeab..1d1abd5a 100644 --- a/TrueTrace/Resources/MainCompute/Materials.cginc +++ b/TrueTrace/Resources/MainCompute/Materials.cginc @@ -1345,7 +1345,7 @@ float3 EvaluateDisney3(MaterialData hitDat, float3 V, float3 L, bool thin, CalculateAnisotropicParams(rscaled, hitDat.anisotropic, tax, tay); float3 transmission = EvaluateDisneySpecTransmission(hitDat, wo, wm, wi, tax, tay, thin); - reflectance += 1;//transmission; + reflectance += 0;//transmission; float forwardTransmissivePdfW; GgxVndfAnisotropicPdf2(wi, wm, wo, tax, tay, forwardTransmissivePdfW); @@ -1441,7 +1441,7 @@ float3 ReconstructDisney2(MaterialData hitDat, float3 wo, float3 wi, bool thin, reflectance += ReconstructDisneyClearcoat(hitDat.clearcoat, hitDat.clearcoatGloss, wo, wm, wi, forwardPdf, Success); } if(P.z > 0) { - reflectance += ((EvaluateDisneyDiffuse(hitDat, wo, wm, wi, thin, pixel_index) + EvaluateSheen(hitDat, wo, wm, wi) / PI)); + reflectance += (1.0f - P.w) * ((EvaluateDisneyDiffuse(hitDat, wo, wm, wi, thin, pixel_index) + EvaluateSheen(hitDat, wo, wm, wi) / PI)); forwardPdf += AbsCosTheta(wi); Success = forwardPdf > 0; } @@ -1450,9 +1450,9 @@ float3 ReconstructDisney2(MaterialData hitDat, float3 wo, float3 wi, bool thin, float forwardSpecPdfW; float3 SpecCol = ReconstructDisneySpecTransmission(hitDat, wo, wm, wi, forwardSpecPdfW, pixel_index); - reflectance += SpecCol; - forwardPdf += forwardSpecPdfW; if(forwardSpecPdfW > 0) { + reflectance += SpecCol * P.w; + forwardPdf += forwardSpecPdfW; Success = Success || true; } } diff --git a/TrueTrace/Resources/MainCompute/RayTracingShader.compute b/TrueTrace/Resources/MainCompute/RayTracingShader.compute index 9a6cd52b..49603f45 100644 --- a/TrueTrace/Resources/MainCompute/RayTracingShader.compute +++ b/TrueTrace/Resources/MainCompute/RayTracingShader.compute @@ -57,6 +57,7 @@ bool VisabilityCheck(SmallerRay ray, float dist) { float FogDensity; +float ScaleHeight; float3 FogColor; float3 SampleHomo(SmallerRay ray, float maxT, int pixel_index, inout float t, inout float pdf) { @@ -64,10 +65,14 @@ float3 SampleHomo(SmallerRay ray, float maxT, int pixel_index, inout float t, in float3 SigmaS = SigmaT * FogColor; float3 SigmaA = SigmaT - SigmaS; uint channel = min(floor(random(33, pixel_index).x * 3), 2); - t = -log(1 - random(33, pixel_index).y) / SigmaT[channel]; + // t = SampleRectExpMedium(exp(-(-log(1 - random(33, pixel_index).y))*SigmaT), ray.origin.y, ray.direction.y, 1.0f / SigmaT, 1.0f / H);/// SigmaT[channel]; + t = SampleRectExpMedium(-log(1 - random(33, pixel_index).y)/ SigmaT[channel], ray.origin.y, ray.direction.y, 1.0f / SigmaT, 1.0f / ScaleHeight); + // t = SampleSpherExpMedium(random(33, pixel_index).y, ray.origin.y+bottom_radius, rcp(ray.origin.y+bottom_radius), ray.direction.y, bottom_radius, float2(1,1), float2(1,ScaleHeight), 1.0f / float2(1,ScaleHeight), 1, t);/// SigmaT[channel]; + // t = -log(1 - random(33, pixel_index).y) / SigmaT[channel]; bool m_internal = t < maxT; t = min(t, maxT); - float3 Tr = exp(-t * SigmaT); + // float3 Tr = exp(-t * SigmaT); + float3 Tr = exp(-SigmaT * OptDepthSpherExpMedium(ray.origin.y+bottom_radius, rcp(ray.origin.y+bottom_radius), ray.direction.y, t, bottom_radius, SigmaT, ScaleHeight, 1.0f / ScaleHeight)); if(m_internal) { @@ -76,6 +81,8 @@ float3 SampleHomo(SmallerRay ray, float maxT, int pixel_index, inout float t, in } else { pdf = (Tr.x + Tr.y + Tr.z) / 3.0f; } + + // return exp(-t * OptDepthRectExpMedium(ray.origin.y, ray.direction.x, t, SigmaT, 1.0f / H)); return m_internal ? SigmaS * Tr / pdf : (Tr / pdf); } @@ -183,19 +190,30 @@ inline void calcFinalColor(SmallerRay ray, inout ColData Color, MaterialData hit } } + int MaterialLobe = 2; float3 bsdfmodifier = 1; + bool Refracted = false; #ifdef Fog - bool DidScatter = false; float VolumeBSDF; float newT = hit.t; - bool Refracted = false; - int MaterialLobe = 2; - throughput *= SampleHomo(ray, hit.t, pixel_index, newT, VolumeBSDF); + bool DidScatter = false; + float3 Homo = SampleHomo(ray, hit.t, pixel_index, newT, VolumeBSDF); + throughput *= Homo; if(newT == hit.t) { #endif [branch] if (hitDat.emission > 0.0f) {//if we hit a light, this ray is done #ifdef Fog - hitDat.emission *= exp(-hit.t * SigmaT); + // if(CurBounce == 0) _DebugTex[id.xy] = float4(exp(-SigmaT * -OptDepthRectExpMedium(ray.origin.y, ray.direction.y, hit.t, SigmaT, 1.0f / H)), 1); + float3 Tr = exp(-SigmaT * OptDepthSpherExpMedium(ray.origin.y+bottom_radius, rcp(ray.origin.y+bottom_radius), ray.direction.y, hit.t, bottom_radius, SigmaT, ScaleHeight, 1.0f / ScaleHeight)); + float pdf3 = (Tr.x + Tr.y + Tr.z) / 3.0f; + hitDat.emission *= Tr;// / pdf3;// / pdf; + // return exp(-t * OptDepthRectExpMedium(ray.origin.y, ray.direction.x, t, SigmaT, 1.0f / H)); + // return (Tr / pdf); + + // hitDat.emission *= exp(-hit.t * OptDepthRectExpMedium(ray.origin.y, ray.direction.y, hit.t, SigmaT, 1.0f / ScaleHeight)); + // hitDat.emission *= exp(-OptDepthRectExpMedium(ray.origin.y, ray.direction.y, hit.t, SigmaT * 0.0001f, 1.0f / ScaleHeight)); + + // hitDat.emission *= exp(-hit.t * SigmaT); #endif #ifdef WhiteLights hitDat.surfaceColor = 0.5f; @@ -227,6 +245,9 @@ inline void calcFinalColor(SmallerRay ray, inout ColData Color, MaterialData hit #else light_pdf *= rcp(_MeshData[hit.mesh_id].LightTriCount); #endif + #ifdef Fog + // light_pdf *= (1.0f - VolumeBSDF); + #endif float w = power_heuristic(max(last_pdf,0), light_pdf); if (CurBounce == 0) Color.Direct += EmissCol; #ifdef UseBRDFLights @@ -266,8 +287,6 @@ inline void calcFinalColor(SmallerRay ray, inout ColData Color, MaterialData hit hitDat.surfaceColor = ((lum * 255.0f) + (hitDat.ColorBleed *((hitDat.surfaceColor * 255.0f) - (lum * 255.0f)))) / 255.0f; } - int MaterialLobe = 2; - bool Refracted = false; [branch] if(CurBounce == 0 && UseReSTIRGI && ReSTIRGIUpdateRate != 0 && RandomNums[id].z != 0) { #ifdef HDRP float2 MotionVector = MotionVectors[int3(id,0)].xy; @@ -356,7 +375,7 @@ inline void calcFinalColor(SmallerRay ray, inout ColData Color, MaterialData hit if(CurBounce == 0) _DebugTex[id.xy] = float4(ray.origin, asfloat(octahedral_32(Geomnorm))); #endif float pdf3 = 0; - ReconstructBsdf2(hitDat, PrevDirection, ray.direction, norm, pdf3, bsdf, GetTangentSpace2(norm), pixel_index); + // ReconstructBsdf2(hitDat, PrevDirection, ray.direction, Refracted ? -norm : norm, pdf3, bsdf, GetTangentSpace2(Refracted ? -norm : norm), pixel_index); [branch]if(luminance(Color.Indirect) <= 0.01f) {// || CurBounce < 3 //This may make some situations more accurate if(GetBounceData(CachePathLength) != 0){ #ifdef NonDirectionalRadCache @@ -456,6 +475,10 @@ inline void calcFinalColor(SmallerRay ray, inout ColData Color, MaterialData hit area = PI * Light.SpotAngle.x * Light.SpotAngle.x; break; } + + + + // float newt = hit.t; // float newPDF = 1; // sampleEquiAngular(random(321, pixel_index).x, hit.t, PrevOrigin, PrevDirection, LightPosition, newt, newPDF); @@ -521,13 +544,10 @@ inline void calcFinalColor(SmallerRay ray, inout ColData Color, MaterialData hit float3 bsdf_value = 0.0f; float3 bsdf_diffuse = 0; #ifdef RadCache - float3 colcol = hitDat.surfaceColor; + float3 colcol = hitDat.surfaceColor; hitDat.surfaceColor =1 ; bool validbsdfNEE = EvaluateBsdf3(hitDat, PrevDirection, to_light, norm, bsdf_pdf, bsdf_diffuse, pixel_index); bsdf_pdf = 0; - #ifdef NonDirectionalRadCache - bsdf_diffuse = 1.0f / PI; - #endif hitDat.surfaceColor = colcol; validbsdfNEE = EvaluateBsdf(hitDat, PrevDirection, to_light, norm, bsdf_pdf, bsdf_value, pixel_index); #else @@ -535,7 +555,26 @@ inline void calcFinalColor(SmallerRay ray, inout ColData Color, MaterialData hit bool validbsdfNEE = EvaluateBsdf(hitDat, PrevDirection, to_light, norm, bsdf_pdf, bsdf_value, pixel_index); if((UseASVGF && (CurBounce == GetBounceData(Color.MetRoughIsSpec) - 2 && CurBounce > 0))) bsdf_value *= Color.Data.xyz; #endif - + #ifdef Fog + float temppdf = 1.0f / (PI * 4.0f); + Homo = exp(-SigmaT * OptDepthSpherExpMedium(PrevOrigin.y+bottom_radius, rcp(PrevOrigin.y+bottom_radius), PrevDirection.y, newT, bottom_radius, SigmaT, ScaleHeight, 1.0f / ScaleHeight)); + float3 Homo2 = exp(-SigmaT * OptDepthSpherExpMedium(pos.y+bottom_radius, rcp(pos.y+bottom_radius), to_light.y, distance_to_light, bottom_radius, SigmaT, ScaleHeight, 1.0f / ScaleHeight)); + if(DidScatter) { + SigmaT *= Homo; + float pdf3 = (SigmaT.x + SigmaT.y + SigmaT.z) / 3.0f; + Homo = SigmaS * Homo / pdf3 * (Homo2) * (temppdf); + bsdf_value = Homo; + bsdf_diffuse = Homo; + bsdf_pdf = VolumeBSDF * temppdf; + validbsdfNEE = true; + } else { + float pdf3 = (Homo.x + Homo.y + Homo.z) / 3.0f; + Homo = Homo / pdf3 * Homo2; + bsdf_pdf *= VolumeBSDF; + bsdf_value *= Homo; + bsdf_diffuse *= Homo; + } + #endif if (validbsdfNEE) { float NEE_pdf; @@ -573,27 +612,16 @@ inline void calcFinalColor(SmallerRay ray, inout ColData Color, MaterialData hit bsdf_diffuse *= saturate(saturate(dot(to_light, -LightNorm)) * MiscInfo.y + MiscInfo.z); Illum *= saturate(saturate(dot(to_light, -LightNorm)) * MiscInfo.y + MiscInfo.z); } -#ifdef Fog - Illum *= exp(-((LightFormat == DIRECTIONALLIGHT ? 1.0f : distance_to_light - 0.01f) + newT) * SigmaT); - bsdf_diffuse *= exp(-((LightFormat == DIRECTIONALLIGHT ? 1.0f : distance_to_light - 0.01f) + newT) * SigmaT); -#endif + float maxillum = max(max(Illum.x, Illum.y), Illum.z); if(DoExposure) maxillum *= Exposure[0]; if(!UseRussianRoulette || (CurBounce == 0 && (ImprovedPrimaryHit || DoPartialRendering))) maxillum = 1; Illum *= rcp(saturate(maxillum)); - #ifndef NonDirectionalRadCache - bsdf_diffuse *= rcp(saturate(maxillum)); - #endif - // // #ifdef RadCache - // // if(!UseASVGF && CurBounce > 1 && !(CurBounce != GetBounceData(CachePathLength) - 2)) { - // // Illum *= Color.Data.xyz; - // // } - // #endif + if(luminance(Illum) != 0 && maxillum > random(117, pixel_index).y) {//NEE russian roulette, massively improves performance while giivng the same result uint index3; #ifdef RadCache bool TempTemp = (CurBounce != GetBounceData(CachePathLength) - 2); - // if(!TempTemp && CurBounce != 0) Illum *= Color.Data; if(UseReSTIRGI && !TempTemp && CurBounce == 0) Illum *= (bsdf_value == 0) ? 1 : rcp(bsdf_value); #else bool TempTemp = (CurBounce != GetBounceData(Color.MetRoughIsSpec) - 2); @@ -707,6 +735,250 @@ int MaterialIndex; float TrueDeSat = DoSecondary ? SkyDesaturate : SecondarySkyDesaturate; if(CurBounce != 0 && IndirectBoost < 1) Intensity *= rcp(IndirectBoost); float3 Sun = 0; + // float weightedMeanDepth = 0; + #ifdef Fog + float rayNear; + float rayFar = 100.0f; + rayFar = raySphereFirstIntersection(ray.origin + float3(0,bottom_radius,0), ray.direction, float3(0,0, 0), bottom_radius); + if(rayFar < 0) rayFar = -raySphereFirstIntersection(ray.origin+ float3(0,bottom_radius,0), ray.direction, float3(0,0, 0), top_radius); + rayFar = min(rayFar, FarPlane); + // getRayNearFar(ray.direction, rayNear, rayFar); + // if((ray.origin + ray.direction * rayFar).y < 0) { + + + // float denom = dot(float3(0,1,0), ray.direction); + // if (abs(denom) > 0.0001f) // your favorite epsilon + // { + // float t = dot(float3(0,1,0), (float3(0,0,0) - ray.origin)) / denom; + // rayFar = min(rayFar, t); + // } + // } + // float3 skyirrad; + // float3 sunirrad;// = GetSunAndSkyIrradiance(ray.origin+float3(0,bottom_radius,0), ray.direction, SunDir, skyirrad); + // float4 rad2 = 0; + // float2 globeUv = getGlobeUv(ray.origin); + // float mipLevel = length(globeUv * localWeatherFrequency); + // mipLevel = 0;//lerp(0.0, mipLevel, min(1.0, 0.2 * ray.origin.y / maxHeight)); + + + float VolumeBSDF; + float newT = rayFar; + bool Refracted = false; + int MaterialLobe = 2; + float3 Homo = SampleHomo(ray, rayFar, pixel_index, newT, VolumeBSDF); + Intensity *= Homo; + if(newT == rayFar) Homo = 1; else { + float3 PrevOrigin = ray.origin; + float3 PrevDirection = ray.direction; + ray.origin = ray.origin + ray.direction * newT; + ray.direction = normalize(SampleDirectionSphere(random(75, pixel_index).x, random(75, pixel_index).y)); + float3 norm = ray.direction; + float3 pos = ray.origin; + if(CurBounce == 0) { + float3 LightNorm; + float3 LightPosition; + int LightFormat = TRILIGHT; + float3 Radiance; + float RunningWeight = 1; + float area = 1; + float3 MiscInfo = 0; + int AggTriIndex = 0; + int SelectedLightGroup = 0;//0 = primitive, 1 = point, spot, etc., 2 = skybox + int selectionoptions = 0; + int selections[3] = {0,0,0}; + if(LightMeshCount != 0 && LEMEnergyScale != 0) selections[selectionoptions++] = 0; + if(unitylightcount != 0) selections[selectionoptions++] = 1; + if(SecondaryBackgroundType == 1) selections[selectionoptions++] = 2; + RunningWeight = selectionoptions; + SelectedLightGroup = selections[min(floor(random(114, pixel_index).x * (float)selectionoptions), selectionoptions - 1)]; + + if (SelectedLightGroup == 1) {//we only really need to precompute this, right? maybe we can do a similar optimization as ReSTIR DI? + AggTriIndex = SelectUnityLight(pixel_index, RunningWeight, norm, pos, PrevDirection); + LightData Light = _UnityLights[AggTriIndex]; + float sinPhi, cosPhi; + LightPosition = Light.Position; + LightNorm = Light.Direction; + LightFormat = Light.Type; + Radiance = Light.Radiance / PI; + float3 RandVec = float3(random(115, pixel_index), random(116, pixel_index).x); + MiscInfo = float3(Light.Softness * 120.0f + 1, Light.SpotAngle); + if(LightFormat == AREALIGHTQUAD || LightFormat == AREALIGHTDISK) { + sincos(Light.ZAxisRotation, sinPhi, cosPhi); + } + [branch] switch (LightFormat) { + case POINTLIGHT: + LightNorm = normalize(pos - LightPosition); + LightPosition += normalize(RandVec - 0.5f) * random(116, pixel_index).y * Light.Softness * 0.1f;//Soft Shadows + break; + case DIRECTIONALLIGHT: + LightPosition = pos + LightNorm; + LightNorm = -LightNorm; + sincos(RandVec.x * 2.0f * PI, RandVec.x, RandVec.y); + RandVec.xy = mul(float2x2(cosPhi, -sinPhi, sinPhi, cosPhi), RandVec.xy) * RandVec.z * Light.Softness* 0.01f; + if(Light.Softness* 0.01f > 0.001f) { + LightPosition += ToWorld(GetTangentSpace2(LightNorm), normalize(float3(RandVec.x,0,RandVec.y))) * length(RandVec.xy); + } + if(UseTransmittanceInNEE) Radiance *= GetSkyTransmittance(pos, -LightNorm, 0, -LightNorm); + break; + case SPOTLIGHT: + Radiance *= ((1.0f - MiscInfo.z * 0.0174533) + (MiscInfo.y * 0.0174533 - MiscInfo.z * 0.0174533) / 2.0f); + LightPosition += normalize(RandVec - 0.5f) * random(116, pixel_index).y * Light.Softness * 0.1f;//Soft Shadows + break; + case AREALIGHTQUAD: + RandVec.xy = RandVec.xy * Light.SpotAngle - Light.SpotAngle / 2.0f; + RandVec.xy = mul(float2x2(cosPhi, -sinPhi, sinPhi, cosPhi), RandVec.xy); + LightPosition += ToWorld(GetTangentSpace2(LightNorm), normalize(float3(RandVec.x,0,RandVec.y))) * length(RandVec.xy); + area = (Light.SpotAngle.x * Light.SpotAngle.y); + Radiance *= PI; + break; + case AREALIGHTDISK: + sincos(RandVec.x * 2.0f * PI, RandVec.x, RandVec.y); + RandVec.xy = mul(float2x2(cosPhi, -sinPhi, sinPhi, cosPhi), RandVec.xy) * RandVec.z * Light.SpotAngle.x; + LightPosition += ToWorld(GetTangentSpace2(LightNorm), normalize(float3(RandVec.x,0,RandVec.y))) * length(RandVec.xy); + area = PI * Light.SpotAngle.x * Light.SpotAngle.x; + break; + } + } else if(SelectedLightGroup == 0) { + #ifdef LBVH + int MeshIndex; + float4x4 MeshTransformInverse; + #else + int MeshIndex = SelectLightMeshSmart(pixel_index, RunningWeight, pos); + float4x4 MeshTransformInverse = _MeshData[_LightMeshes[MeshIndex].LockedMeshIndex].W2L; + #endif + AggTriIndex = SelectLight(pixel_index, MeshIndex, RunningWeight, norm, pos, MeshTransformInverse, Radiance, LightPosition, 0, -PrevDirection, 0); + #ifdef LBVH + MeshTransformInverse = _MeshData[MeshIndex].W2L; + #endif + Radiance *= LEMEnergyScale; + TrianglePos CurTri = triangle_get_positions(AggTriIndex); + MeshTransformInverse = inverse(MeshTransformInverse); + float3 a0 = mul(MeshTransformInverse, float4(CurTri.pos0, 1)).xyz; + float3 a1 = mul(MeshTransformInverse, float4(CurTri.pos0 + CurTri.posedge1, 1)).xyz; + float3 a2 = mul(MeshTransformInverse, float4(CurTri.pos0 + CurTri.posedge2, 1)).xyz; + area = AreaOfTriangle(a0, a1, a2); + LightPosition = mul(MeshTransformInverse, float4(LightPosition,1)); + LightNorm = normalize(mul((float3x3)MeshTransformInverse, normalize(cross(CurTri.posedge1, CurTri.posedge2))).xyz); + } else { + LightFormat = DIRECTIONALLIGHT; + AggTriIndex = 0; + Radiance = SampleLI(pixel_index, RunningWeight, LightNorm) * SecondaryBackgroundIntensity; + LightPosition = pos - LightNorm; + } + + + if(AggTriIndex != -1) { + float3 to_light = LightPosition - pos; + + float distance_to_light_squared = dot(to_light, to_light); + float distance_to_light = sqrt(max(distance_to_light_squared, 0.0f)); + + to_light = to_light / distance_to_light; + if(LightFormat == SPOTLIGHT) { + float3 LocalLight = ToLocal(GetTangentSpace(LightNorm), -to_light) * 0.5f + 0.5f; + float2 AlignedUV = AlignUV(LocalLight.xz, float4(1,1,0,0), _UnityLights[AggTriIndex].IESTex); + if(AlignedUV.x != -1) Radiance *= _IESAtlas.SampleLevel(my_point_clamp_sampler, AlignedUV, 0); + } + + float SurfaceCos = dot(to_light, norm);//YES KEEP THIS, IT NOT ONLY IMPROVES PERFORMANCE BUT IT ALSO HELPS KEEPS THINGS LESS BIASED AS OTHERWISE THE NORMAL OFFSET CAN RESULT IN WRONG VISABILITY! + #ifdef IgnoreBackfacing + if(SurfaceCos > 0 && (dot(to_light, LightNorm) > 0 || LightFormat != TRILIGHT)) { + #else + if(SurfaceCos > 0) { + #endif + float3 SigmaT = FogDensity * FogScale; + float3 SigmaS = SigmaT * FogColor; + float temppdf = 1.0f / (PI * 4.0f); + Homo = exp(-SigmaT * OptDepthSpherExpMedium(PrevOrigin.y+bottom_radius, rcp(PrevOrigin.y+bottom_radius), PrevDirection.y, newT, bottom_radius, SigmaT, ScaleHeight, 1.0f / ScaleHeight)); + float3 Homo2 = exp(-SigmaT * OptDepthSpherExpMedium(pos.y+bottom_radius, rcp(pos.y+bottom_radius), to_light.y, distance_to_light, bottom_radius, SigmaT, ScaleHeight, 1.0f / ScaleHeight)); + + + // float3 Homo2 = exp(-distance_to_light * OptDepthRectExpMedium(pos.y, to_light.y, distance_to_light, SigmaT, 1.0f / ScaleHeight)); + float pdf3 = (Homo2.x + Homo2.y + Homo2.z) / 3.0f; + // Homo2 /= pdf3; + SigmaT *= Homo; + pdf3 = (SigmaT.x + SigmaT.y + SigmaT.z) / 3.0f; + Homo = SigmaS * Homo / pdf3; + + Homo = Homo * (Homo2) * (temppdf); + // m_internal ? SigmaS * Tr / pdf : (Tr / pdf); + bool validbsdfNEE = true; + + float bsdf_pdf = VolumeBSDF * temppdf; + float3 bsdf_value = Homo; + float3 bsdf_diffuse = Homo; + + if (validbsdfNEE) { + float NEE_pdf; + float3 Illum; + + + [branch]if (SelectedLightGroup == 1) { + NEE_pdf = 1.0f / (abs(dot(to_light, LightNorm)) * area / distance_to_light_squared); + Illum = (Radiance * bsdf_value) / NEE_pdf * RunningWeight; + bsdf_diffuse = (Radiance * bsdf_diffuse) / NEE_pdf * RunningWeight; + } else if(SelectedLightGroup == 0) { + NEE_pdf = (1.0f / ((abs(dot(to_light, LightNorm)) * area) / distance_to_light_squared)) / RunningWeight; + #ifndef LBVH + NEE_pdf /= LightMeshCount; + #endif + float NEEMISWeight = power_heuristic(NEE_pdf, bsdf_pdf); + Illum = (Radiance * bsdf_value) / NEE_pdf; + bsdf_diffuse = (Radiance * bsdf_diffuse) / NEE_pdf; + #ifdef UseBRDFLights + Illum *= NEEMISWeight; + bsdf_diffuse *= NEEMISWeight; + #endif + } else { + NEE_pdf = HDRIParams.x * HDRIParams.y * equirectDirectionPdf(to_light) * (luminance(Radiance) / TotSum[0]); + float NEEMISWeight = power_heuristic(NEE_pdf, bsdf_pdf); + Illum = (Radiance * bsdf_value) / NEE_pdf * RunningWeight * NEEMISWeight; + bsdf_diffuse = (Radiance * bsdf_diffuse) / NEE_pdf * RunningWeight * NEEMISWeight; + } + Illum *= Color.throughput; + + if(LightFormat == AREALIGHTQUAD || LightFormat == AREALIGHTDISK) { + Illum *= pow(saturate(dot(to_light, -LightNorm)), MiscInfo.x); + bsdf_diffuse *= pow(saturate(dot(to_light, -LightNorm)), MiscInfo.x); + } + if (LightFormat == SPOTLIGHT) { + bsdf_diffuse *= saturate(saturate(dot(to_light, -LightNorm)) * MiscInfo.y + MiscInfo.z); + Illum *= saturate(saturate(dot(to_light, -LightNorm)) * MiscInfo.y + MiscInfo.z); + } + float maxillum = max(max(Illum.x, Illum.y), Illum.z); + if(DoExposure) maxillum *= Exposure[0]; + if(!UseRussianRoulette || (CurBounce == 0 && (ImprovedPrimaryHit || DoPartialRendering))) maxillum = 1; + Illum *= rcp(saturate(maxillum)); + if(luminance(Illum) != 0 && maxillum > random(117, pixel_index).y) {//NEE russian roulette, massively improves performance while giivng the same result + uint index3; + #ifdef RadCache + bool TempTemp = (CurBounce != GetBounceData(CacheBuffer[pixel_index].pathLength) - 2); + // if(!TempTemp && CurBounce != 0) Illum *= Color.Data; + if(UseReSTIRGI && !TempTemp && CurBounce == 0) Illum *= (bsdf_value == 0) ? 1 : rcp(bsdf_value); + #else + bool TempTemp = (CurBounce != GetBounceData(Color.MetRoughIsSpec) - 2); + if(UseReSTIRGI && CurBounce == 0) Illum *= (bsdf_value == 0) ? 1 : rcp(bsdf_value); + #endif + ShadowRayData ShadRay = {pos, + packRGBE(bsdf_diffuse), + to_light, + (LightFormat == DIRECTIONALLIGHT ? 10000.0f : distance_to_light - ShadowDistanceFudgeFactor) * -1, + Illum, + pixel_index}; + if(abs(ShadRay.t) > 0.001f) { + InterlockedAdd(BufferSizes[CurBounce].shadow_rays, 1, index3); + ShadowRaysBuffer[index3] = ShadRay; + } + } + } + } + } + + } + + + } + #endif [branch]switch(DoSecondary ? BackgroundType : SecondaryBackgroundType) { case 0: Radiance = GetSkyRadiance(ray.origin, ray.direction, 0, SunDir, transmittance, debug); @@ -721,6 +993,27 @@ int MaterialIndex; Stars = pow(saturate(Stars), 2.0f); if(GetBounceData(Color.MetRoughIsSpec) <= 1) Radiance += Stars; + // if(CurBounce <= 1) { + // rad2 = + // marchToClouds( + // (ray.origin+float3(0,bottom_radius,0)), + // ray.direction, + // rayFar - rayNear, + // random(233, pixel_index).x, + // float3(random(234, pixel_index), random(235, pixel_index).x), + // pow(2.0, 0), + // SunDir, + // sunirrad, + // skyirrad, + // pixel_index, + // weightedMeanDepth + // ); + // if(weightedMeanDepth > 0) { + // Radiance *= 1.0f - (rad2.a); + // applyAerialPerspective(ray.origin, ray.origin + (weightedMeanDepth + rayNear) * ray.direction, rad2); + // } + // Radiance += pow(1.0f - exp(-rad2 / 1.0f * 10.0f), 1.0f); + // } if (all(Radiance < 10000.0f)) { Radiance = DeSat(Radiance, 1.0f - TrueDeSat); if(DoSecondary) { @@ -834,8 +1127,8 @@ int MaterialIndex; TempCol += SecondaryVal; break; case 2: - if(AlbMaskVal > 0.5f || !(TempMat.SecondaryAlbedoMask.x > 0)) - TempCol *= SecondaryVal; + SecondaryVal *= TempCol; + TempCol = lerp(TempCol, SecondaryVal, AlbMaskVal); break; } } @@ -843,9 +1136,7 @@ int MaterialIndex; TempMat.surfaceColor *= TempCol; TempCol = TempMat.surfaceColor; - #ifndef DX11 - Unity_Hue_Degrees_float(TempCol, TempMat.Hue * 500.0f, TempMat.surfaceColor); - #endif + Unity_Hue_Degrees_float(TempCol, TempMat.Hue * 500.0f, TempMat.surfaceColor); TempMat.surfaceColor *= TempMat.Brightness; TempCol = TempMat.surfaceColor; Unity_Saturation_float(TempCol, TempMat.Saturation, TempMat.surfaceColor); @@ -868,6 +1159,9 @@ int MaterialIndex; #endif #endif +#ifdef FakedAO + if(TempMat.specTrans == 0 && CurBounce != 0 && bestHit.t < 1.0f) Color.throughput *= exp(-(1.0f - bestHit.t) * 12000.0f); +#endif if (TempMat.specTrans != 1 && TempMat.MetallicTex.x > 0) TempMat.metallic = pow(SampleTexture(BaseUv, SampleMetallic, TempMat), rcp(2.2f)); if (TempMat.RoughnessTex.x > 0) { @@ -960,7 +1254,7 @@ void kernel_finalize(uint3 id : SV_DispatchThreadID) {//Moved final accumulation GBufferCol = ((DiffuseGBuffer.SampleLevel(my_linear_clamp_sampler, UV, 0).xyz + SpecularAlbedo) == 0) ? 1 : ((DiffuseGBuffer.SampleLevel(my_linear_clamp_sampler, UV, 0).xyz + SpecularAlbedo)); #endif } - float3 res = (GetBounceData(GlobalColors[final_pixel_index].MetRoughIsSpec) == 1) ? GlobalColors[final_pixel_index].Data.xyz : (((float)PartialRenderingFactor) * ((GlobalColors[final_pixel_index].Direct + GlobalColors[final_pixel_index].Indirect * (UseReSTIRGI ? 1.0f : IndirectBoost)) * GlobalColors[final_pixel_index].Data.xyz) + pow(unpackRGBE(GlobalColors[final_pixel_index].PrimaryNEERay),2.2f) / GBufferCol); + float3 res = (GetBounceData(GlobalColors[final_pixel_index].MetRoughIsSpec) == 1) ? (GlobalColors[final_pixel_index].Data.xyz + pow(unpackRGBE(GlobalColors[final_pixel_index].PrimaryNEERay),2.2f)) : (((float)PartialRenderingFactor) * ((GlobalColors[final_pixel_index].Direct + GlobalColors[final_pixel_index].Indirect * (UseReSTIRGI ? 1.0f : IndirectBoost)) * GlobalColors[final_pixel_index].Data.xyz) + pow(unpackRGBE(GlobalColors[final_pixel_index].PrimaryNEERay),2.2f) / GBufferCol); if (!all(res < 10000000)) res = 0; #if DebugView != -1 #if DebugView == DVGIView @@ -994,6 +1288,13 @@ void kernel_finalize(uint3 id : SV_DispatchThreadID) {//Moved final accumulation // #endif +#ifdef AutoDebugReading + if(_DebugTex[id.xy].w != 0) { + res = _DebugTex[id.xy]; + } + +#endif + Result[id.xy] = float4(res, 1.0f); } @@ -1048,3 +1349,5 @@ void TTtoOIDNKernelPanorama(uint3 id : SV_DispatchThreadID) { } OutputBuffer[id.x + id.y * screen_width] = Result[id.xy].xyz; } + + diff --git a/TrueTrace/Resources/MainCompute/ReSTIRGI.compute b/TrueTrace/Resources/MainCompute/ReSTIRGI.compute index 9018635b..3f8c870b 100644 --- a/TrueTrace/Resources/MainCompute/ReSTIRGI.compute +++ b/TrueTrace/Resources/MainCompute/ReSTIRGI.compute @@ -266,7 +266,7 @@ inline void RadianceDataInitialize(out RadianceData Radiance) { Radiance.Color = 0; Radiance.Wsum = 0; - Radiance.M = 1; + Radiance.M = 0; Radiance.W = 0; } @@ -314,7 +314,7 @@ int2 permutationSample(int2 samplePos, int2 jitter, uint sampleIndex) { Texture2D Gradient; RWTexture2D GradientWrite; -#define KernelSize 16 +#define KernelSize 8 int RandOffset; [numthreads(KernelSize, KernelSize, 1)] void ReSTIRGIKernel(uint3 id : SV_DispatchThreadID, uint3 id2 : SV_GroupThreadID, uint3 id3 : SV_GroupID, uint id4 : SV_GroupIndex) { @@ -512,6 +512,8 @@ void ReSTIRGIKernel(uint3 id : SV_DispatchThreadID, uint3 id2 : SV_GroupThreadID if(MergedB) WorldPos = WorldPosB[prevIndex]; bool MergedC = ReservoirMergeTemporal(prevIndex, ReservoirB[int3(prevIndex,1)].xyzw, 0, ShadowGuidanceWeight, NEEbsdf2, randomNEE(127, pixel_index).y, RunningReservoirC, MiNEE); if(MergedC) NEEPos = NEEPosB[prevIndex]; + RunningReservoirB.Radiance.M++; + RunningReservoirC.Radiance.M++; } @@ -532,6 +534,7 @@ void ReSTIRGIKernel(uint3 id : SV_DispatchThreadID, uint3 id2 : SV_GroupThreadID } MaxM /= 2; + MaxM = max(MaxM, 1); if (RunningReservoirC.Radiance.M > MaxM) { RunningReservoirC.Radiance.Wsum *= MaxM / RunningReservoirC.Radiance.M; RunningReservoirC.Radiance.M = MaxM; @@ -637,24 +640,22 @@ void ReSTIRGISpatial(uint3 id : SV_DispatchThreadID) { float Mc = 1; float McNEE = 1; float3 CenterNorm = CalcNorm(WorldPos); - int SampleCount = CurPass == 0 ? 6 : 5;//ReSTIRGISpatialCount; - float GISpatialRadius2 = CurPass == 0 ? 42 : 20;//GISpatialRadius; float3 SampleRayDir; float3 SampleNorm; float3 bsdf2; float3 NEEbsdf2; if(UseReSTIRGISpatial && Case != 3) { - for (int i = 0; i < SampleCount; i++) { + [loop]for (int i = 0; i < 6; i++) { float2 RandOffsets = randomNEE(i + 12, pixel_index); float2 RandOffsets2 = randomNEE(i + 32, pixel_index); #ifdef ExpensiveReSTIR - int2 CellOffset = vogelDiskSample(i, SampleCount, RandOffsets.y, 2.0f * PI * RandOffsets.x) * GISpatialRadius2; + int2 CellOffset = vogelDiskSample(i, 6, RandOffsets.y, 2.0f * PI * RandOffsets.x) * 42.0f; int2 CellTapCoord = id.xy + CellOffset; if(CellTapCoord.x < 0 || CellTapCoord.x >= screen_width) CellTapCoord.x = id.x - CellOffset.x; if(CellTapCoord.y < 0 || CellTapCoord.y >= screen_height) CellTapCoord.y = id.y - CellOffset.y; if(all(CellTapCoord == id.xy)) continue; #else - int2 CellTapCoord = vogelDiskSample(i, SampleCount, RandOffsets.y, 2.0f * PI * RandOffsets.x) * GISpatialRadius2; + int2 CellTapCoord = vogelDiskSample(i, 6, RandOffsets.y, 2.0f * PI * RandOffsets.x) * 42.0f; CellTapCoord += id.xy; if(all(CellTapCoord == id.xy) || any(CellTapCoord >= int2(screen_width, screen_height) || CellTapCoord < 0)) continue; #endif @@ -715,20 +716,20 @@ void ReSTIRGISpatial(uint3 id : SV_DispatchThreadID) { { static const float Beta = 3; float fx = max(RunningReservoirBCopy.Radiance.M * luminance(RunningReservoirBCopy.Radiance.Color * bsdf2),0); - float gx = max(fx + RunningReservoirBCannon.Radiance.M/((float)SampleCount) * luminance(RunningReservoirBCannon.Radiance.Color*bsdf),1e-7); + float gx = max(fx + RunningReservoirBCannon.Radiance.M/((float)6) * luminance(RunningReservoirBCannon.Radiance.Color*bsdf),1e-7); Mi = pow(min(fx / gx, gx / fx), Beta) * RayDirWeight; fx = max(RunningReservoirBCannon.Radiance.M * luminance(RunningReservoirBCannon.Radiance.Color * bsdf2),0); - gx = max(fx + RunningReservoirBCopy.Radiance.M/((float)SampleCount) * luminance(RunningReservoirBCopy.Radiance.Color*bsdf),1e-7); + gx = max(fx + RunningReservoirBCopy.Radiance.M/((float)6) * luminance(RunningReservoirBCopy.Radiance.Color*bsdf),1e-7); Mc = Mc + (1.0f - pow(min(fx / gx, gx / fx), Beta) * RayDirWeight); fx = max(RunningReservoirCCopy.Radiance.M * luminance(RunningReservoirCCopy.Radiance.Color * NEEbsdf2),0); - gx = max(fx + RunningReservoirCCannon.Radiance.M/((float)SampleCount) * luminance(RunningReservoirCCannon.Radiance.Color*NEEbsdf),1e-7); + gx = max(fx + RunningReservoirCCannon.Radiance.M/((float)6) * luminance(RunningReservoirCCannon.Radiance.Color*NEEbsdf),1e-7); MiNEE = pow(min(fx / gx, gx / fx), Beta) * RayDirWeight2; fx = max(RunningReservoirCCannon.Radiance.M * luminance(RunningReservoirCCannon.Radiance.Color * NEEbsdf2),0); - gx = max(fx + RunningReservoirCCopy.Radiance.M/((float)SampleCount) * luminance(RunningReservoirCCopy.Radiance.Color*NEEbsdf),1e-7); + gx = max(fx + RunningReservoirCCopy.Radiance.M/((float)6) * luminance(RunningReservoirCCopy.Radiance.Color*NEEbsdf),1e-7); McNEE = McNEE + (1.0f - pow(min(fx / gx, gx / fx), Beta) * RayDirWeight2); } @@ -746,7 +747,6 @@ void ReSTIRGISpatial(uint3 id : SV_DispatchThreadID) { CenterNEERayDir = SampleNEERayDir; NEEbsdf = NEEbsdf2; } - // ValidSamps++; } } @@ -757,8 +757,213 @@ void ReSTIRGISpatial(uint3 id : SV_DispatchThreadID) { if(Merged3) WorldPos = WorldPosB[id.xy]; if(Merged4) NEEPos = NEEPosB[id.xy]; + Valid2 = ReconstructBsdf2(SurfaceMat, CameraRay.direction, normalize(CalcPos(WorldPos) - PrimaryHitPosition), SurfNorm, pdf, bsdf, TangSpace, pixel_index); + Valid2 = EvaluateBsdf2(SurfaceMat, CameraRay.direction, normalize(NEEPos - PrimaryHitPosition), SurfNorm, pdf, NEEbsdf, pixel_index); + + RunningReservoirB.Radiance.W = RunningReservoirB.Radiance.Wsum / max((RunningReservoirB.Radiance.M) * luminance(RunningReservoirB.Radiance.Color * bsdf), 1e-7) ; + RunningReservoirC.Radiance.W = RunningReservoirC.Radiance.Wsum / max((RunningReservoirC.Radiance.M) * luminance(RunningReservoirC.Radiance.Color * NEEbsdf), 1e-7) ; + WorldPosA[id.xy] = WorldPos; + NEEPosA[id.xy] = NEEPos; + ReservoirA[int3(id.xy,0)] = uint4(PackRadianceData(RunningReservoirB.Radiance).xy, PackRayData(RunningReservoirB.Ray).xy); + ReservoirA[int3(id.xy,1)] = uint4(PackRadianceData(RunningReservoirC.Radiance).xy, PackRayData(RunningReservoirC.Ray).xy); +} + + + + +#pragma kernel ReSTIRGISpatial2 + +[numthreads(KernelSize, KernelSize, 1)] +void ReSTIRGISpatial2(uint3 id : SV_DispatchThreadID) { + if(id.x >= screen_width || id.y >= screen_height) return; + const int pixel_index = id.x + id.y * screen_width; + + const float4 GBuffer = ScreenSpaceInfoRead[id.xy]; + const int MatIndex = (asuint(GBuffer.w) << 4) >> 4; + const float3 GeomNorm = i_octahedral_32(asuint(GBuffer.x)); + const float3 SurfNorm = i_octahedral_32(asuint(GBuffer.y)); + float3 PrimaryHitPosition = LoadSurfaceInfo(id.xy); + SmallerRay CameraRay = CreateCameraRay(id.xy / float2(screen_width, screen_height) * 2.0f - 1.0f); + [branch]if(DoPanorama) { + float2 jitter = ((random(0, pixel_index) - 0.5)); + if(OIDNGuideWrite) jitter = 0; + float2 uv = float2((id.xy + jitter) / float2(screen_width, screen_height)); + uv.y = 1.0f - uv.y; + uv.x = (uv.x * (Segment.y - Segment.x)) + Segment.x; + uv.x = 1.0f - uv.x; + + CameraRay = CreateRay(mul(CamToWorld, float4(0.0f, 0.0f, 0.0f, 1.0f)).xyz + NearPlane * normalize(equirectUvToDirection(uv)), normalize(equirectUvToDirection(uv))); + } + const ColData CenterCol = GlobalColors[pixel_index]; + const float3 Data = CenterCol.Data; + uint MetRoughIsSpec = CenterCol.MetRoughIsSpec; + MaterialData SurfaceMat = _Materials[MatIndex]; + const uint Flag = CenterCol.Flags; + const uint Case = (asuint(GBuffer.w) << 1) >> 30; + SurfaceMat.surfaceColor = unpackRGBE(Flag); + SurfaceMat.roughness = FromColorSpecPacked(MetRoughIsSpec).y; + SurfaceMat.metallic = FromColorSpecPacked(MetRoughIsSpec).x; + float4 WorldPos = WorldPosB[id.xy]; + float4 NEEPos = NEEPosB[id.xy]; + + ReservoirStruct RunningReservoirB; + ReservoirStruct RunningReservoirBCannon; + ReservoirStruct RunningReservoirC; + ReservoirStruct RunningReservoirCCannon; + ReservoirStruct RunningReservoirCCopy; + ReservoirStruct RunningReservoirBCopy; + ReservoirInitialize(id.xy, RunningReservoirB); + ReservoirInitialize(id.xy, RunningReservoirBCannon); + ReservoirInitialize(id.xy, RunningReservoirBCopy); + ReservoirInitialize(id.xy, RunningReservoirC); + ReservoirInitialize(id.xy, RunningReservoirCCannon); + ReservoirInitialize(id.xy, RunningReservoirCCopy); + + float3 CenterRayDir = CalcPos(WorldPos) - PrimaryHitPosition; + float3 CenterNEERayDir = NEEPos - PrimaryHitPosition; + float3 bsdf; + float3 NEEbsdf; + float pdf; + const float3x3 TangSpace = GetTangentSpace(SurfNorm); + bool Valid2 = ReconstructBsdf2(SurfaceMat, CameraRay.direction, normalize(CenterRayDir), SurfNorm, pdf, bsdf, TangSpace, pixel_index); + Valid2 = EvaluateBsdf2(SurfaceMat, CameraRay.direction, normalize(CenterNEERayDir), SurfNorm, pdf, NEEbsdf, pixel_index); + + + const uint4 PackedCenterResA = ReservoirB[int3(id.xy,0)]; + const uint4 PackedCenterResB = ReservoirB[int3(id.xy,1)]; + UnpackRadianceData(PackedCenterResA.xy, bsdf, RunningReservoirBCannon.Radiance); + UnpackRadianceData(PackedCenterResB.xy, NEEbsdf, RunningReservoirCCannon.Radiance); + + + UnpackRayData(PackedCenterResA.zw, RunningReservoirBCannon.Ray); + UnpackRayData(PackedCenterResB.zw, RunningReservoirCCannon.Ray); + #ifdef ReSTIRAdvancedValidation + float centerValid = Gradient[id.xy].x; + float centerValidNEE = Gradient[id.xy].y; + #endif + + const float ReservoirCenterOcclusion = ScreenSpaceInfoRead[id.xy].z; + float Mc = 1; + float McNEE = 1; + float3 CenterNorm = CalcNorm(WorldPos); + float3 SampleRayDir; + float3 SampleNorm; + float3 bsdf2; + float3 NEEbsdf2; + if(UseReSTIRGISpatial && Case != 3) { + [loop]for (int i = 0; i < 5; i++) { + float2 RandOffsets = randomNEE(i + 32, pixel_index); + float2 RandOffsets2 = randomNEE(i + 64, pixel_index); + #ifdef ExpensiveReSTIR + int2 CellOffset = vogelDiskSample(i, 5, RandOffsets.y, 2.0f * PI * RandOffsets.x) * 20.0f; + int2 CellTapCoord = id.xy + CellOffset; + if(CellTapCoord.x < 0 || CellTapCoord.x >= screen_width) CellTapCoord.x = id.x - CellOffset.x; + if(CellTapCoord.y < 0 || CellTapCoord.y >= screen_height) CellTapCoord.y = id.y - CellOffset.y; + if(all(CellTapCoord == id.xy)) continue; + #else + int2 CellTapCoord = vogelDiskSample(i, 5, RandOffsets.y, 2.0f * PI * RandOffsets.x) * 20.0f; + CellTapCoord += id.xy; + if(all(CellTapCoord == id.xy) || any(CellTapCoord >= int2(screen_width, screen_height) || CellTapCoord < 0)) continue; + #endif + float ReservoirSampleOcclusion = ScreenSpaceInfoRead[CellTapCoord].z; + if(asuint(ScreenSpaceInfoRead[CellTapCoord].w) == 0) continue; + float3 SampleSurfNorm = i_octahedral_32(asuint(ScreenSpaceInfoRead[CellTapCoord].y)); + + #ifdef ExpensiveReSTIR + float3 SampleGeomNorm = i_octahedral_32(asuint(ScreenSpaceInfoRead[CellTapCoord].x)); + float NormDiff = max(dot(SurfNorm, SampleSurfNorm), 0); + if(dot(GeomNorm, SampleGeomNorm) < 0.9f) continue; + float ShadowGuidanceWeight = !plane_distance_disocclusion_check(PrimaryHitPosition, LoadSurfaceInfo(CellTapCoord), GeomNorm);// abs(ReservoirCenterOcclusion - ReservoirSampleOcclusion) / max(ReservoirCenterOcclusion, ReservoirSampleOcclusion) < 0.1f; + if(ShadowGuidanceWeight == 0) continue; + #else + float NormDiff = max(dot(SurfNorm, SampleSurfNorm), 0); + if(NormDiff < 0.9f) continue; + float ShadowGuidanceWeight = abs(ReservoirCenterOcclusion - ReservoirSampleOcclusion) / max(ReservoirCenterOcclusion, ReservoirSampleOcclusion) < 0.1f; + #endif + + const uint4 PackedReservoirA = ReservoirB[int3(CellTapCoord,0)]; + const uint4 PackedReservoirB = ReservoirB[int3(CellTapCoord,1)]; + uint4 SampleWorldPos = WorldPosB[CellTapCoord]; + float4 SampleNEEPos = NEEPosB[CellTapCoord]; + CalcPosNorm(SampleWorldPos, SampleRayDir, SampleNorm); + SampleRayDir -= PrimaryHitPosition; + + float3 SampleNEERayDir = SampleNEEPos - PrimaryHitPosition; + Valid2 = ReconstructBsdf2(SurfaceMat, CameraRay.direction, normalize(SampleRayDir), SurfNorm, pdf, bsdf2, TangSpace, pixel_index); + Valid2 = EvaluateBsdf2(SurfaceMat, CameraRay.direction, normalize(SampleNEERayDir), SurfNorm, pdf, NEEbsdf2, pixel_index); + UnpackRadianceData(PackedReservoirA.xy, bsdf2, RunningReservoirBCopy.Radiance); + UnpackRadianceData(PackedReservoirB.xy, NEEbsdf2, RunningReservoirCCopy.Radiance); + + float RayDirWeight = 1; + float RayDirWeight2 = 1; + + + float Dist = length(SampleRayDir - CenterRayDir); + [branch]if(Dist < 1.0f) { + RayDirWeight = lerp(1.0f - exp(-120.0f * abs(dot(SampleRayDir, CenterRayDir))), 1, SurfaceMat.roughness); + RayDirWeight *= pow(abs(dot(SampleNorm, CenterNorm)), 122.0f); + } + + Dist = length(SampleNEERayDir - CenterNEERayDir); + [branch]if(Dist < 1.0f) { + RayDirWeight2 = lerp(1.0f - exp(-120.0f * abs(dot(SampleNEERayDir, CenterNEERayDir))), 1, SurfaceMat.roughness); + // RayDirWeight *= pow(abs(dot(-normalize(SampleNEERayDir), -normalize(CenterNEERayDir))), 122.0f); + } + #ifdef ReSTIRAdvancedValidation + if(DoReSTIRGIConnectionValidation) { + float2 Grad = Gradient[CellTapCoord]; + RayDirWeight *= lerp(0.25f, 1.0f, saturate(exp2(-20.0f * abs(centerValid - Grad.x)))); + RayDirWeight2 *= lerp(0.25f, 1.0f, saturate(exp2(-20.0f * abs(centerValidNEE - Grad.y)))); + } + #endif + + float Mi = 1; + float MiNEE = 1; + { + static const float Beta = 3; + float fx = max(RunningReservoirBCopy.Radiance.M * luminance(RunningReservoirBCopy.Radiance.Color * bsdf2),0); + float gx = max(fx + RunningReservoirBCannon.Radiance.M/((float)5) * luminance(RunningReservoirBCannon.Radiance.Color*bsdf),1e-7); + Mi = pow(min(fx / gx, gx / fx), Beta) * RayDirWeight; + + fx = max(RunningReservoirBCannon.Radiance.M * luminance(RunningReservoirBCannon.Radiance.Color * bsdf2),0); + gx = max(fx + RunningReservoirBCopy.Radiance.M/((float)5) * luminance(RunningReservoirBCopy.Radiance.Color*bsdf),1e-7); + Mc = Mc + (1.0f - pow(min(fx / gx, gx / fx), Beta) * RayDirWeight); + + + fx = max(RunningReservoirCCopy.Radiance.M * luminance(RunningReservoirCCopy.Radiance.Color * NEEbsdf2),0); + gx = max(fx + RunningReservoirCCannon.Radiance.M/((float)5) * luminance(RunningReservoirCCannon.Radiance.Color*NEEbsdf),1e-7); + MiNEE = pow(min(fx / gx, gx / fx), Beta) * RayDirWeight2; + + fx = max(RunningReservoirCCannon.Radiance.M * luminance(RunningReservoirCCannon.Radiance.Color * NEEbsdf2),0); + gx = max(fx + RunningReservoirCCopy.Radiance.M/((float)5) * luminance(RunningReservoirCCopy.Radiance.Color*NEEbsdf),1e-7); + McNEE = McNEE + (1.0f - pow(min(fx / gx, gx / fx), Beta) * RayDirWeight2); + } + + + bool MergedB = ReservoirMergeSpatial(CellTapCoord, PackedReservoirA, ShadowGuidanceWeight * NormDiff, bsdf2, RunningReservoirB, RandOffsets2.x, Mi); + bool MergedC = ReservoirMergeSpatial(CellTapCoord, PackedReservoirB, ShadowGuidanceWeight * NormDiff, NEEbsdf2, RunningReservoirC, RandOffsets2.y, MiNEE); + [branch]if(MergedB) { + WorldPos = SampleWorldPos; + CenterRayDir = SampleRayDir; + bsdf = bsdf2; + CenterNorm = SampleNorm; + } + [branch]if(MergedC) { + NEEPos = SampleNEEPos; + CenterNEERayDir = SampleNEERayDir; + NEEbsdf = NEEbsdf2; + } + } + + } + Valid2 = ReconstructBsdf2(SurfaceMat, CameraRay.direction, normalize(CalcPos(WorldPosB[id.xy]) - PrimaryHitPosition), SurfNorm, pdf, bsdf, TangSpace, pixel_index); + Valid2 = EvaluateBsdf2(SurfaceMat, CameraRay.direction, normalize(NEEPosB[id.xy].xyz - PrimaryHitPosition), SurfNorm, pdf, NEEbsdf, pixel_index); + bool Merged3 = ReservoirMergeSpatial(id.xy, PackedCenterResA, 1, bsdf, RunningReservoirB, randomNEE(324, pixel_index).x, Mc); + bool Merged4 = ReservoirMergeSpatial(id.xy, PackedCenterResB, 1, NEEbsdf, RunningReservoirC, randomNEE(324, pixel_index).y, McNEE); + if(Merged3) WorldPos = WorldPosB[id.xy]; + if(Merged4) NEEPos = NEEPosB[id.xy]; + - if(CurPass == 1) { [branch]if (DoReSTIRGIConnectionValidation && Case != 3) { float2 DistDist = 1; if(SurfaceMat.diffTrans == 0) { @@ -803,17 +1008,15 @@ void ReSTIRGISpatial(uint3 id : SV_DispatchThreadID) { GradientWrite[id.xy] = DistDist; #endif } -} Valid2 = ReconstructBsdf2(SurfaceMat, CameraRay.direction, normalize(CalcPos(WorldPos) - PrimaryHitPosition), SurfNorm, pdf, bsdf, TangSpace, pixel_index); Valid2 = EvaluateBsdf2(SurfaceMat, CameraRay.direction, normalize(NEEPos - PrimaryHitPosition), SurfNorm, pdf, NEEbsdf, pixel_index); RunningReservoirB.Radiance.W = RunningReservoirB.Radiance.Wsum / max((RunningReservoirB.Radiance.M) * luminance(RunningReservoirB.Radiance.Color * bsdf), 1e-7) ; RunningReservoirC.Radiance.W = RunningReservoirC.Radiance.Wsum / max((RunningReservoirC.Radiance.M) * luminance(RunningReservoirC.Radiance.Color * NEEbsdf), 1e-7) ; - [branch]if(CurPass == 1) { Valid2 = EvaluateBsdf(SurfaceMat, CameraRay.direction, normalize(NEEPos - PrimaryHitPosition), SurfNorm, pdf, NEEbsdf, pixel_index); - // RunningReservoirB.Radiance.W *= RunningReservoirB.Radiance.W < 100.0f; - // RunningReservoirC.Radiance.W *= RunningReservoirC.Radiance.W < 100.0f; + RunningReservoirB.Radiance.W *= RunningReservoirB.Radiance.W < 100.0f; + RunningReservoirC.Radiance.W *= RunningReservoirC.Radiance.W < 100.0f; GlobalColors[pixel_index].PrimaryNEERay = packRGBE(pow(RunningReservoirC.Radiance.Color * RunningReservoirC.Radiance.W * NEEbsdf,rcp(2.2f))); @@ -826,10 +1029,4 @@ void ReSTIRGISpatial(uint3 id : SV_DispatchThreadID) { } else { GlobalColors[pixel_index].Indirect *= IndirectBoost; } - } else { - WorldPosA[id.xy] = WorldPos; - NEEPosA[id.xy] = NEEPos; - ReservoirA[int3(id.xy,0)] = uint4(PackRadianceData(RunningReservoirB.Radiance).xy, PackRayData(RunningReservoirB.Ray).xy); - ReservoirA[int3(id.xy,1)] = uint4(PackRadianceData(RunningReservoirC.Radiance).xy, PackRayData(RunningReservoirC.Ray).xy); - } } \ No newline at end of file diff --git a/TrueTrace/Resources/Objects/ParentObject.cs b/TrueTrace/Resources/Objects/ParentObject.cs index bebe4560..d10bd503 100644 --- a/TrueTrace/Resources/Objects/ParentObject.cs +++ b/TrueTrace/Resources/Objects/ParentObject.cs @@ -187,11 +187,9 @@ public void ClearAll() { if(BVH2 != null) { BVH2.Dispose(); } + BVH2 = null; if(BVH != null) { - CommonFunctions.DeepClean(ref BVH.cwbvh_indices); - if(BVH.BVH8NodesArray.IsCreated) BVH.BVH8NodesArray.Dispose(); - if(BVH.costArray.IsCreated) BVH.costArray.Dispose(); - if(BVH.decisionsArray.IsCreated) BVH.decisionsArray.Dispose(); + BVH.Dispose(); } BVH = null; CurMeshData.Clear(); @@ -235,7 +233,10 @@ public void Reset(int Que) { public void OnApplicationQuit() { if (VertexBuffers != null) { - for (int i = 0; i < Mathf.Max(SkinnedMeshes.Length, DeformableMeshes.Length); i++) { + int Leng = 0; + if(SkinnedMeshes != null) Leng = SkinnedMeshes.Length; + if(DeformableMeshes != null) Leng = Mathf.Max(Leng, DeformableMeshes.Length); + for (int i = 0; i < Leng; i++) { if(VertexBuffers != null && VertexBuffers[i] != null) VertexBuffers[i].Release(); IndexBuffers[i].Release(); NodeBuffer.Release(); @@ -451,13 +452,13 @@ public void CreateAtlas(ref int VertCount) List DoneMats = new List(); Material[] SharedMaterials;// = new Material[1]; foreach (RayTracingObject obj in ChildObjects) { - if(obj == null) Debug.Log("WTF"); + if(obj == null) Debug.LogError("Report this to the developer!"); DoneMats.Clear(); if (obj.TryGetComponent(out MeshFilter TempMesh)) mesh = TempMesh.sharedMesh; else if(obj.TryGetComponent(out SkinnedMeshRenderer TempSkin)) mesh = TempSkin.sharedMesh; else mesh = null; - if(mesh == null) Debug.Log("Missing Mesh: " + name); + if(mesh == null) Debug.LogError("Missing Mesh: " + name); obj.matfill(); VertCount += mesh.vertexCount; if(obj.TryGetComponent(out Renderer TempRend)) SharedMaterials = TempRend.sharedMaterials; @@ -477,8 +478,9 @@ public void CreateAtlas(ref int VertCount) TempObj.ObjIndex = i; int Index = AssetManager.ShaderNames.IndexOf(SharedMaterials[i].shader.name); if (Index == -1) { +#if TTVerbose Debug.Log("Adding Material To XML: " + SharedMaterials[i].shader.name); - +#endif if (SharedMaterials[i].mainTexture != null) { if (!AlbedoTexs.Contains(SharedMaterials[i].mainTexture)) { AlbedoTexs.Add(SharedMaterials[i].mainTexture); @@ -490,7 +492,7 @@ public void CreateAtlas(ref int VertCount) } MaterialShader RelevantMat = AssetManager.data.Material[Index]; if(!RelevantMat.MetallicRange.Equals("null") && JustCreated) obj.Metallic[i] = SharedMaterials[i].GetFloat(RelevantMat.MetallicRange); - if(!RelevantMat.RoughnessRange.Equals("null") && JustCreated) obj.Roughness[i] = SharedMaterials[i].GetFloat(RelevantMat.RoughnessRange); + if(!RelevantMat.RoughnessRange.Equals("null") && JustCreated) obj.Roughness[i] = (RelevantMat.UsesSmoothness ? (1.0f - SharedMaterials[i].GetFloat(RelevantMat.RoughnessRange)) : SharedMaterials[i].GetFloat(RelevantMat.RoughnessRange)); if(RelevantMat.MetallicRemapMin != null && !RelevantMat.MetallicRemapMin.Equals("null") && JustCreated) obj.MetallicRemap[i] = new Vector2(SharedMaterials[i].GetFloat(RelevantMat.MetallicRemapMin), SharedMaterials[i].GetFloat(RelevantMat.MetallicRemapMax)); else if(JustCreated) obj.MetallicRemap[i] = new Vector2(0, 1); if(RelevantMat.RoughnessRemapMin != null && !RelevantMat.RoughnessRemapMin.Equals("null") && JustCreated) obj.RoughnessRemap[i] = new Vector2(SharedMaterials[i].GetFloat(RelevantMat.RoughnessRemapMin), SharedMaterials[i].GetFloat(RelevantMat.RoughnessRemapMax)); @@ -670,8 +672,12 @@ public unsafe void LoadData() { TempObj.matfill(); if(Target.TryGetComponent(out RayTracingObject TempRayObj2)) { if(Target.TryGetComponent(out MeshRenderer TempRenderer)) { - if(TempRenderer.enabled) + if(TempRenderer.enabled){ + if(TempRenderer.rayTracingMode == UnityEngine.Experimental.Rendering.RayTracingMode.DynamicGeometry) { + IsDeformable = true; + } ChildObjectTransforms.Add(ChildTransf[i]); + } } } } @@ -683,7 +689,14 @@ public unsafe void LoadData() { if(ChildObjectTransforms[i].gameObject.TryGetComponent(out RayTracingObject Target)) if(ChildObjectTransforms[i] != this.transform) ChildObjects.Add(Target); } - if(TryGetComponent(out RayTracingObject TempObj2)) ChildObjects.Add(TempObj2); + if(TryGetComponent(out RayTracingObject TempObj2)) { + if(TryGetComponent(out MeshRenderer TempRenderer)) { + if(TempRenderer.rayTracingMode == UnityEngine.Experimental.Rendering.RayTracingMode.DynamicGeometry) { + IsDeformable = true; + } + } + ChildObjects.Add(TempObj2); + } TotalObjects = ChildObjects.Count; CachedTransforms = new StorableTransform[TotalObjects + 1]; CachedTransforms[0].WTL = transf.worldToLocalMatrix; @@ -813,7 +826,6 @@ public unsafe void LoadData() { case 4: ColOff = BufferIndexers[TempIndex][i3].y; break; } } - // Debug.Log(VertCount); for(int i3 = 0; i3 < VertCount; i3++) { int Index = i3 * TotalStride; if(VertOff != -1) CurMeshData.Verticies[CurMeshData.CurVertexOffset + i3] = (new Vector3(Data[Index + VertOff], Data[Index + VertOff + 1], Data[Index + VertOff + 2])); @@ -828,12 +840,6 @@ public unsafe void LoadData() { AsyncGPUReadback.Request(MeshBuffer, checkOutput); } } - // for(int i2 = 0; i2 < TotVertCount; i2++) { - // if(!HasAttribute[1]) CurMeshData.Tangents.Add(new Vector4(0,1,0,1)); - // if(!HasAttribute[2]) CurMeshData.Normals.Add(Vector3.one); - // if(!HasAttribute[3]) CurMeshData.UVs.Add(Vector2.one); - // } - // CurMeshData.SetColorsZero(TotVertCount); @@ -867,7 +873,7 @@ public unsafe void LoadData() { int TotalIndexLength = 0; for (int i2 = 0; i2 < submeshcount; ++i2) {//Add together all the submeshes in the mesh to consider it as one object int IndiceLength = (int)mesh.GetIndexCount(i2) / 3; - MatIndex = Mathf.Min(i2, CurrentObject.Names.Length) + RepCount; + MatIndex = Mathf.Min(i2, CurrentObject.Names.Length-1) + RepCount; TotalIndexLength += IndiceLength; var SubMesh = new int[IndiceLength]; System.Array.Fill(SubMesh, MatIndex); @@ -1278,6 +1284,10 @@ public unsafe async Task BuildTotal() { float scalex = Distance(ChildMat * new Vector3(1,0,0), new Vector3(0,0,0)); float scaley = Distance(ChildMat * new Vector3(0,1,0), new Vector3(0,0,0)); float scalez = Distance(ChildMat * new Vector3(0,0,1), new Vector3(0,0,0)); + float Leng = Distance(new Vector3(scalex, scaley, scalez), new Vector3(0,0,0)); + scalex /= Leng; + scaley /= Leng; + scalez /= Leng; Vector3 ScaleFactor = IsSingle ? new Vector3(1,1,1) : new Vector3(Mathf.Pow(1.0f / scalex, 2.0f), Mathf.Pow(1.0f / scaley, 2.0f), Mathf.Pow(1.0f / scalez, 2.0f)); int InitOff = TransformIndexes[i].IndexOffset; int IndEnd = TransformIndexes[i].IndexOffsetEnd; @@ -1427,7 +1437,9 @@ public unsafe async Task BuildTotal() { MeshCountChanged = false; HasCompleted = true; NeedsToUpdate = false; +#if TTVerbose Debug.Log(Name + " Has Completed Building with " + AggTriangles.Length + " triangles"); +#endif FailureCount = 0; } @@ -1483,15 +1495,17 @@ private void OnEnable() { } } else { - if(!AssetManager.Assets.RemoveQue.Contains(this)) { - if(QueInProgress == 2) { - AssetManager.Assets.UpdateQue.Remove(this); + if(AssetManager.Assets != null) { + if(!AssetManager.Assets.RemoveQue.Contains(this)) { + if(QueInProgress == 2) { + AssetManager.Assets.UpdateQue.Remove(this); + } + AssetManager.Assets.AddQue.Add(this); + QueInProgress = 3; + ExistsInQue = 3; } - AssetManager.Assets.AddQue.Add(this); - QueInProgress = 3; - ExistsInQue = 3; + AssetManager.Assets.ParentCountHasChanged = true; } - AssetManager.Assets.ParentCountHasChanged = true; } HasCompleted = false; } diff --git a/TrueTrace/Resources/PostProcess/Compute/CombinedPP.compute b/TrueTrace/Resources/PostProcess/Compute/CombinedPP.compute new file mode 100644 index 00000000..cb633a75 --- /dev/null +++ b/TrueTrace/Resources/PostProcess/Compute/CombinedPP.compute @@ -0,0 +1,120 @@ +//https://www.shadertoy.com/view/wsdBWM + +float DISTORTION_AMOUNT; + +Texture2D Input; +RWTexture2D Result; +SamplerState my_linear_repeat_sampler; +int screen_width; +int screen_height; + +float2 PincushionDistortion(in float2 uv, float strength) +{ + float2 st = uv - 0.5; + float uvA = atan2(st.x, st.y); + float uvD = dot(st, st); + return 0.5 + float2(sin(uvA), cos(uvA)) * sqrt(uvD) * (1.0 - strength * uvD); +} + +float3 ChromaticAbberation(float2 uv) +{ + float rChannel = Input.SampleLevel(my_linear_repeat_sampler, PincushionDistortion(uv, 0.3 * DISTORTION_AMOUNT),0).r; + float gChannel = Input.SampleLevel(my_linear_repeat_sampler, PincushionDistortion(uv, 0.15 * DISTORTION_AMOUNT),0).g; + float bChannel = Input.SampleLevel(my_linear_repeat_sampler, PincushionDistortion(uv, 0.075 * DISTORTION_AMOUNT),0).b; + float3 retColor = float3(rChannel, gChannel, bChannel); + return retColor; +} +#pragma kernel ChromaticAbberationKernel + +[numthreads(16,16,1)] +void ChromaticAbberationKernel (uint3 id : SV_DispatchThreadID) +{ + Result[id.xy] = float4(ChromaticAbberation((float2)id.xy / float2(screen_width, screen_height)), Input[id.xy].w); +} + + +//https://www.shadertoy.com/view/XdcXzn + +float contrast; +float saturation; + + + +float4x4 contrastMatrix( float contrast ) +{ + float t = ( 1.0 - contrast ) / 2.0; + + // return float4x4( contrast, 0, 0, 0, + // 0, contrast, 0, 0, + // 0, 0, contrast, 0, + // t, t, t, 1 ); + + return float4x4( contrast, 0, 0, t, + 0, contrast, 0, t, + 0, 0, contrast, t, + 0,0,0, 1 ); + +} + +float4x4 saturationMatrix( float saturation ) +{ + float3 luminance = float3( 0.3086, 0.6094, 0.0820 ); + + float oneMinusSat = 1.0 - saturation; + + float3 red = luminance.x * oneMinusSat; + red+= float3( saturation, 0, 0 ); + + float3 green = luminance.y * oneMinusSat; + green += float3( 0, saturation, 0 ); + + float3 blue = luminance.z * oneMinusSat; + blue += float3( 0, 0, saturation ); + + + + return float4x4( red.x, green.x, blue.x, 0, + red.y, green.y, blue.y, 0, + red.z, green.z, blue.z, 0, + 0,0,0,1); + + +} + + + + + + +#pragma kernel BSCKernel + +[numthreads(16,16,1)] +void BSCKernel (uint3 id : SV_DispatchThreadID) +{ + Result[id.xy] = float4((mul(mul(contrastMatrix(contrast), saturationMatrix(saturation)), float4(Input[id.xy].xyz,1))).xyz, Input[id.xy].w); +} + +//Inner radius +float inner; +float outer; +float strength; +float curvature; +float3 Color; + +#pragma kernel VignetteKernel + +[numthreads(16,16,1)] +void VignetteKernel (uint3 id : SV_DispatchThreadID) +{ + float2 uv = id.xy / float2(screen_width, screen_height); + float2 curve = pow(abs(uv*2.-1.),(1./curvature)); + float edge = pow(length(curve),curvature); + float vignette = 1.-strength*smoothstep(inner,outer,edge); + float4 InputCol = Input[id.xy]; + Result[id.xy] = float4(lerp(InputCol.xyz * Color, InputCol.xyz, vignette), InputCol.w); + + +} + + + diff --git a/TrueTrace/Resources/PostProcess/Compute/SVGF.compute.meta b/TrueTrace/Resources/PostProcess/Compute/CombinedPP.compute.meta similarity index 65% rename from TrueTrace/Resources/PostProcess/Compute/SVGF.compute.meta rename to TrueTrace/Resources/PostProcess/Compute/CombinedPP.compute.meta index e9d966ce..e78c9008 100644 --- a/TrueTrace/Resources/PostProcess/Compute/SVGF.compute.meta +++ b/TrueTrace/Resources/PostProcess/Compute/CombinedPP.compute.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: be089208a75d77d4a9d8f812dad3a36e +guid: 2c00ac773aed9b64b813571427841708 ComputeShaderImporter: externalObjects: {} - preprocessorOverride: 1 + preprocessorOverride: 0 userData: assetBundleName: assetBundleVariant: diff --git a/TrueTrace/Resources/PostProcess/Compute/SVGF.compute b/TrueTrace/Resources/PostProcess/Compute/SVGF.compute deleted file mode 100644 index 1af56529..00000000 --- a/TrueTrace/Resources/PostProcess/Compute/SVGF.compute +++ /dev/null @@ -1,602 +0,0 @@ -#include "UnityCG.cginc" -#include "../../GlobalDefines.cginc" - -int screen_width; -int screen_height; - -int AtrousIterations; - -int PartialRenderingFactor; - -struct ColData { - float3 throughput; - float3 Direct; - float3 Indirect; - uint PrimaryNEERay; - int IsSpecular; - float pad; -}; -StructuredBuffer PerPixelRadiance; - -Texture2D DirectB; -Texture2D IndirectB; -RWTexture2D DirectA; -RWTexture2D IndirectA; -RWTexture2D Result; - -Texture2D TempAlbedoTex; - - - -Texture2D ScreenSpaceInfo; -Texture2D PrevScreenSpaceInfo; - -RWTexture2D MomentA; -Texture2D MomentB; - -RWTexture2D HistoryTex; - -Texture2D WorldPosData; - -float3 unpackRGBE(uint x) -{ - int exponent = int(x >> 27) - 20; - float scale = pow(2, exponent) / 256.0; - - float3 v; - v.r = float(x & 0x1ff) * scale; - v.g = float((x >> 9) & 0x1ff) * scale; - v.b = float((x >> 18) & 0x1ff) * scale; - - return v; -} - -float3 i_octahedral_32( uint data ) { - uint2 iv = uint2( data, data>>16u ) & 65535u; - float2 v = float2(iv)/32767.5f - 1.0f; - float3 nor = float3(v, 1.0f - abs(v.x) - abs(v.y)); // Rune Stubbe's version, - float t = max(-nor.z,0.0); // much faster than original - nor.x += (nor.x>0.0)?-t:t; // implementation of this - nor.y += (nor.y>0.0)?-t:t; // technique - return normalize( nor ); -} -SamplerState my_linear_clamp_sampler; - -#define THRESHOLD_NORMAL 0.7f; -#define THRESHOLD_DEPTH 0.1f; -#pragma kernel kernel_copy - -float FarPlane; -#ifdef HDRP - Texture2DArray MotionVectors; -#else - Texture2D MotionVectors; -#endif - -[numthreads(16, 16, 1)] -void kernel_copy(int3 id : SV_DispatchThreadID) -{//Reprojects and moves the color data from the array to textures - if (id.x >= screen_width || id.y >= screen_height) return; - int pixel_index = id.y * screen_width + id.x; - - ColData Pixel = PerPixelRadiance[pixel_index]; - - float3 TexBaseColor = TempAlbedoTex[id.xy].xyz; - TexBaseColor = (TexBaseColor > 0.005f ? rcp(TexBaseColor) : 0); - // uint Input = asuint(Pixel.Metallic); - - float3 WorldAlbedo = unpackRGBE(WorldPosData[id.xy].w); - - IndirectA[id.xy] = float4(clamp(Pixel.Indirect * ((TempAlbedoTex[id.xy].xyz * ((WorldAlbedo > 0.001f) ? rcp(WorldAlbedo) : 0))),0,1200.0f),1); - DirectA[id.xy] = float4(clamp((Pixel.Direct + unpackRGBE(Pixel.PrimaryNEERay) * ((Pixel.IsSpecular != 2) ? TexBaseColor : TexBaseColor)) * TempAlbedoTex[id.xy].xyz * ((WorldAlbedo > 0.001f) ? rcp(WorldAlbedo) : 0),0,1200.0f), 0); - -} - - -inline float luminance(const float r, const float g, const float b) { - return 0.299f * r + 0.587f * g + 0.114f * b; -} - - - - -inline bool is_tap_consistent(int x, int y, const float3 normal, float depth) { - if (y < 0 || y >= screen_height || x < 0 || x >= screen_width) return false; - - float3 prev_normal = i_octahedral_32(asuint(PrevScreenSpaceInfo[int2(x, y)].x)); - float prev_depth = PrevScreenSpaceInfo[int2(x, y)].z; - - bool consistent_normal = dot(normal, prev_normal) > THRESHOLD_NORMAL; - bool consistent_depth = abs(depth - prev_depth) / abs(depth) < THRESHOLD_DEPTH; - - return consistent_normal && consistent_depth; -} - - - -#pragma kernel kernel_reproject -bool UseReSTIRGI; -[numthreads(16, 16, 1)] -void kernel_reproject(int3 id : SV_DispatchThreadID) -{ - if (id.x >= screen_width || id.y >= screen_height) return; - - - float4 direct = DirectA[id.xy]; - float4 indirect = IndirectA[id.xy]; - - float4 moment; - moment.x = luminance(direct.x, direct.y, direct.z); - moment.y = luminance(indirect.x, indirect.y, indirect.z); - moment.z = moment.x * moment.x; - moment.w = moment.y * moment.y; - - - float3 normal = i_octahedral_32(asuint(ScreenSpaceInfo[id.xy].x)); - float depth = ScreenSpaceInfo[id.xy].z; - // float depth_prev = HistoryNormalAndDepth[id.xy].w; - - #ifdef HDRP - float2 motion = -MotionVectors.SampleLevel(my_linear_clamp_sampler, int3(id.xy,0) / float3(screen_width, screen_height, 1), 0).xy; - #else - float2 motion = -MotionVectors.SampleLevel(my_linear_clamp_sampler, id.xy / float2(screen_width, screen_height), 0).xy; - #endif - - float2 screen_position_prev = ((((float2(id.xy)) * float2(rcp(screen_width), rcp(screen_height)) + motion)));// * float2(screen_width, screen_height))); - - if (depth == 0.0f) { - DirectA[id.xy] = DirectB[id.xy]; - IndirectA[id.xy] = IndirectB[id.xy]; - return; - }; - float u_prev = screen_position_prev.x; - float v_prev = screen_position_prev.y; - - float s_prev = u_prev * (float)screen_width; - float t_prev = v_prev * (float)screen_height; - - int x_prev = (int)(s_prev); - int y_prev = (int)(t_prev); - - float fractional_s = s_prev - floor(s_prev); - float fractional_t = t_prev - floor(t_prev); - - float one_minus_fractional_s = 1.0f - fractional_s; - float one_minus_fractional_t = 1.0f - fractional_t; - - float w0 = one_minus_fractional_s * one_minus_fractional_t; - float w1 = fractional_s * one_minus_fractional_t; - float w2 = one_minus_fractional_s * fractional_t; - float w3 = 1.0f - w0 - w1 - w2; - - float weights[4] = { w0, w1, w2, w3 }; - float consistent_weights_sum = 0.0f; - float depth_prev; - - for (int j = 0; j < 2; j++) { - for (int i = 0; i < 2; i++) { - int tap = i + j * 2; - - if (is_tap_consistent(x_prev + i, y_prev + j, normal, depth)) { - consistent_weights_sum += weights[tap]; - } else { - weights[tap] = 0.0f; - } - } - } - - float4 prev_direct = float4(0.0f, 0.0f, 0.0f, 0.0f); - float4 prev_indirect = float4(0.0f, 0.0f, 0.0f, 0.0f); - float4 prev_moment = float4(0.0f, 0.0f, 0.0f, 0.0f); - - // If we already found at least 1 consistent tap - if (consistent_weights_sum > 0.0f) { - // Add consistent taps using their bilinear weight - for (int j = 0; j < 2; j++) { - for (int i = 0; i < 2; i++) { - int tap = i + j * 2; - - if (weights[tap] != 0.0f) { - int tap_x = x_prev + i; - int tap_y = y_prev + j; - int2 tap_index = int2(tap_x, tap_y); - - float4 tap_direct = DirectB [tap_index]; - float4 tap_indirect = IndirectB[tap_index]; - float4 tap_moment = MomentB[tap_index]; - - prev_direct += weights[tap] * tap_direct; - prev_indirect += weights[tap] * tap_indirect; - prev_moment += weights[tap] * tap_moment; - } - } - } - } else { - // If we haven't yet found a consistent tap in a 2x2 region, try a 3x3 region - for (int j = -1; j <= 1; j++) { - for (int i = -1; i <= 1; i++) { - int tap_x = x_prev + i; - int tap_y = y_prev + j; - - if (is_tap_consistent(tap_x, tap_y, normal, depth)) { - int2 tap_index = int2(tap_x, tap_y); - - prev_direct += DirectB [tap_index]; - prev_indirect += IndirectB[tap_index]; - prev_moment += MomentB [tap_index]; - - consistent_weights_sum += 1.0f; - } - } - } - } - - - - - - - - - float History = 0; // Increase History Length by 1 step//whyh are we reading from id.xy, not prevpos? - if (consistent_weights_sum > 1e-6) { - // Normalize - prev_direct /= consistent_weights_sum; - prev_indirect /= consistent_weights_sum; - prev_moment /= consistent_weights_sum; - //consistent_weights_sum = max(consistent_weights_sum, 0.1f); - History = HistoryTex[int2(x_prev, y_prev)] + 1.0f; // Increase History Length by 1 step//whyh are we reading from id.xy, not prevpos? - - // history = min(history,10); - // HistoryTex[id.xy] = history; - - - float inv_history = rcp((float)(History)); - float alpha_colour = max(0.05f, inv_history); - float alpha_moment = max(0.2f, inv_history); - - // Integrate using exponential moving average - direct = lerp(prev_direct, direct, alpha_colour); - indirect = lerp(prev_indirect, indirect, alpha_colour); - moment = lerp(prev_moment, moment, alpha_moment); - if (History >= 4) { - History *= clamp(exp2(-abs((moment.z - moment.x * moment.x) - (prev_moment.z - prev_moment.x * prev_moment.x))),0.5f,1.0f); - float variance_direct = max(0.0f, moment.z - moment.x * moment.x); - float variance_indirect = max(0.0f, moment.w - moment.y * moment.y); - - // Store the Variance in the alpha channels - direct.w = variance_direct; - indirect.w = variance_indirect; - } - } - else { - - direct.w = 1.0f; - indirect.w = 1.0f; - } - HistoryTex[id.xy] = History; // Reset History Length - DirectA[id.xy] = direct; - IndirectA[id.xy] = indirect; - - MomentA[id.xy] = moment; - -} - - -#pragma kernel kernel_variance - - -#define epsilon 0.000000001f -static float sigma_z = 4.0f; -static float sigma_n = 128.0f; -static float sigma_l = 10.0f; -static float sigma_l_square = 100.0f; -static float luminance_denom = 0.8f; - -inline float2 edge_stopping_weights( - int delta_x, - int delta_y, - const float2 center_depth_gradient, - float center_depth, - float depth, - const float3 center_normal, - const float3 normal, - float center_luminance_direct, - float center_luminance_indirect, - float luminance_direct, - float luminance_indirect, - float luminance_denom_direct, - float luminance_denom_indirect, - int2 Offset, - float StepSize -) { - // ∇z(p)·(p−q) (Actually the negative of this but we take its absolute value) - float d = - center_depth_gradient.x * (float)delta_x + - center_depth_gradient.y * (float)delta_y; - - float ln_w_z = abs(center_depth - depth) / (sigma_z * abs(d) + epsilon); - // float ln_w_z = 0.1f / (sigma_z + epsilon); - - float w_n = pow(max(0.0f, dot(center_normal, normal)), sigma_n); - - float w_l_direct = w_n * exp2(-abs(center_luminance_direct - luminance_direct) * luminance_denom_direct - ln_w_z); - float w_l_indirect = w_n * exp2(-abs(center_luminance_indirect - luminance_indirect) * luminance_denom_indirect - ln_w_z); - - return float2(w_l_direct, w_l_indirect); -} - -[numthreads(16, 16, 1)] -void kernel_variance(int3 id : SV_DispatchThreadID) -{ - if (id.x >= screen_width || id.y >= screen_height) return; - int history = HistoryTex[id.xy].x; - - if (history >= 4) { - DirectA[id.xy] = DirectB[id.xy]; - IndirectA[id.xy] = IndirectB[id.xy]; - return; - } - - float4 center_color_direct = DirectB[id.xy]; - float4 center_color_indirect = IndirectB[id.xy]; - - float4 center_luminence_direct = luminance(center_color_direct.x, center_color_direct.y, center_color_direct.z); - float4 center_luminence_indirect = luminance(center_color_indirect.x, center_color_indirect.y, center_color_indirect.z); - - float3 CenterNormal = i_octahedral_32(asuint(ScreenSpaceInfo[id.xy].x)); - float CenterDepth = ScreenSpaceInfo[id.xy].z; - - float2 center_depth_gradient = float2( - ScreenSpaceInfo[int2(id.x + 1, id.y)].z - CenterDepth, - ScreenSpaceInfo[int2(id.x, id.y + 1)].z - CenterDepth); - - if (CenterDepth == 0.0f) { - DirectA[id.xy] = DirectB[id.xy]; - IndirectA[id.xy] = IndirectB[id.xy]; - return; - } - - - float sum_weight_direct = 1.0f; - float sum_weight_indirect = 1.0f; - - float4 sum_colour_direct = center_color_direct; - float4 sum_colour_indirect = center_color_indirect; - - float4 sum_moment = float4(0.0f, 0.0f, 0.0f, 0.0f); - - - int2 tap_index; - [unroll] for (int j = -3; j <= 3; j++) { - int tap_y = id.y + j; - - if (tap_y < 0 || tap_y >= screen_height) continue; - - [unroll] for (int i = -3; i <= 3; i++) { - int tap_x = id.x + i; - - if (tap_x < 0 || tap_x >= screen_width) continue; - - if (i == 0 && j == 0) continue; // Center pixel is treated separately - - tap_index = int2(tap_x, tap_y); - - float4 colour_direct = DirectB[tap_index]; - float4 colour_indirect = IndirectB[tap_index]; - float4 moment = MomentB[tap_index]; - - float luminance_direct = luminance(colour_direct.x, colour_direct.y, colour_direct.z); - float luminance_indirect = luminance(colour_indirect.x, colour_indirect.y, colour_indirect.z); - - float2 w = edge_stopping_weights( - i, j, - center_depth_gradient, - CenterDepth, ScreenSpaceInfo[tap_index].z, - CenterNormal, i_octahedral_32(asuint(ScreenSpaceInfo[tap_index].x)), - center_luminence_direct, center_luminence_indirect, - luminance_direct, luminance_indirect, - luminance_denom, luminance_denom, - int2(i, j), - 1 - ); - - float w_direct = w.x; - float w_indirect = w.y; - - sum_weight_direct += w_direct; - sum_weight_indirect += w_indirect; - - sum_colour_direct += w_direct * colour_direct; - sum_colour_indirect += w_indirect * colour_indirect; - - sum_moment += moment * float4(w_direct, w_indirect, w_direct, w_indirect); - } - } - - - sum_weight_direct = max(sum_weight_direct, 0.000001f); - sum_weight_indirect = max(sum_weight_indirect, 0.000001f); - - sum_colour_direct /= sum_weight_direct; - sum_colour_indirect /= sum_weight_indirect; - - sum_moment /= float4(sum_weight_direct, sum_weight_indirect, sum_weight_direct, sum_weight_indirect); - - sum_colour_direct.w = max(0.0f, sum_moment.z - sum_moment.x * sum_moment.x); - sum_colour_indirect.w = max(0.0f, sum_moment.w - sum_moment.y * sum_moment.y); - - // Store the Variance in the alpha channel - DirectA[id.xy] = clamp(sum_colour_direct,0,120.0f); - IndirectA[id.xy] = clamp(sum_colour_indirect,0,120.0f); - -} - - -#pragma kernel kernel_atrous - -const static int feedback_iteration = 1; -uniform int step_size; - -const static float kernel_gaussian[2][2] = { - { 1.0f / 1.0f, 1.0f / 2.0f }, - { 1.0f / 2.0f, 1.0f / 4.0f } -}; - -[numthreads(16, 16, 1)] -void kernel_atrous(int3 id : SV_DispatchThreadID) -{ - if (id.x >= screen_width || id.y >= screen_height) return; - - float variance_blurred_direct = 0.0f; - float variance_blurred_indirect = 0.0f; - int i, j, tap_x, tap_y; - - - for (j = -1; j <= 1; j++) { - tap_y = clamp(id.y + j, 0, screen_height - 1); - [unroll] - for (i = -1; i <= 1; i++) { - tap_x = clamp(id.x + i, 0, screen_width - 1); - // Read the Variance of Direct/Indirect Illumination - // The Variance is stored in the alpha channel (w coordinate) - float variance_direct = DirectB[int2(tap_x, tap_y)].w; - float variance_indirect = IndirectB[int2(tap_x, tap_y)].w; - - float kernel_weight = kernel_gaussian[abs(i)][abs(j)]; - - variance_blurred_direct += variance_direct * kernel_weight; - variance_blurred_indirect += variance_indirect * kernel_weight; - } - } - - // Precompute denominators that are loop invariant - const float luminance_denom_direct = rsqrt(sigma_l_square * max(0.0f, variance_blurred_direct) + epsilon); - float luminance_denom_indirect = rsqrt(sigma_l_square * max(0.0f, variance_blurred_indirect) + epsilon); - - const float4 center_colour_direct = DirectB[id.xy]; - const float4 center_colour_indirect = IndirectB[id.xy]; - - float center_luminance_direct = luminance(center_colour_direct.x, center_colour_direct.y, center_colour_direct.z); - float center_luminance_indirect = luminance(center_colour_indirect.x, center_colour_indirect.y, center_colour_indirect.z); - - - float3 center_normal = i_octahedral_32(asuint(ScreenSpaceInfo[id.xy].y)); - float center_depth = ScreenSpaceInfo[id.xy].z; - - // Check if the pixel belongs to the Skybox - if (center_depth == 0.0f) return; - - float2 center_depth_gradient = float2( - ScreenSpaceInfo[int2(id.x + 1, id.y)].z - center_depth, - ScreenSpaceInfo[int2(id.x, id.y + 1)].z - center_depth - ); - - float sum_weight_direct = 1.0f; - float sum_weight_indirect = 1.0f; - float4 sum_colour_direct = center_colour_direct; - float4 sum_colour_indirect = center_colour_indirect; - - // Use a 3x3 box filter, as recommended in the A-SVGF paper - const static int radius = 1; - float4 color_direct; - float4 color_indirect; - float4 normal_and_depth; - for (j = -radius; j <= radius; j++) { - tap_y = j * ceil(step_size * abs(1.0f - abs(center_depth_gradient.y))) + id.y;//these ceils and such could be weird - - // if (tap_y < 0 || tap_y >= screen_height) continue; - [unroll] - for (i = -radius; i <= radius; i++) { - tap_x = i * ceil(step_size * abs(1.0f - abs(center_depth_gradient.x))) + id.x; - - // if (tap_x < 0 || tap_x >= screen_width) continue; - if(i == 0 && j == 0) continue; - - color_direct = DirectB[int2(tap_x, tap_y)]; - color_indirect = IndirectB[int2(tap_x, tap_y)]; - - float luminance_direct = luminance(color_direct.x, color_direct.y, color_direct.z); - float luminance_indirect = luminance(color_indirect.x, color_indirect.y, color_indirect.z); - - - float3 normal = i_octahedral_32(asuint(ScreenSpaceInfo[int2(tap_x, tap_y)].y)); - float depth = ScreenSpaceInfo[int2(tap_x, tap_y)].z; - - float2 w = edge_stopping_weights( - i * step_size, - j * step_size, - center_depth_gradient, - center_depth, depth, - center_normal, normal, - center_luminance_direct, center_luminance_indirect, - luminance_direct, luminance_indirect, - luminance_denom_direct, luminance_denom_indirect, - int2(i, j), - step_size - ); - - float weight_direct = w.x; - float weight_indirect = w.y; - - sum_weight_direct += weight_direct; - sum_weight_indirect += weight_indirect; - - // Filter Colour using the weights, filter Variance using the square of the weights - sum_colour_direct += float4(weight_direct, weight_direct, weight_direct, weight_direct * weight_direct) * color_direct; - sum_colour_indirect += float4(weight_indirect, weight_indirect, weight_indirect, weight_indirect * weight_indirect) * color_indirect; - } - } - - float inv_sum_weight_direct = rcp(sum_weight_direct); - float inv_sum_weight_indirect = rcp(sum_weight_indirect); - - // Normalize - sum_colour_direct *= inv_sum_weight_direct; - sum_colour_indirect *= inv_sum_weight_indirect; - - // Alpha channel contains Variance, and needs to be divided by the square of the weights - sum_colour_direct.w *= inv_sum_weight_direct; - sum_colour_indirect.w *= inv_sum_weight_indirect; - - DirectA[id.xy] = sum_colour_direct; - IndirectA[id.xy] = sum_colour_indirect; -} - - - -#pragma kernel kernel_finalize - -bool DiffRes; - -inline float luminance(const float3 a) { - return dot(float3(0.299f, 0.587f, 0.114f), a); -} -#ifdef HDRP - Texture2DArray DiffuseGBuffer; - Texture2DArray SpecularGBuffer; -#else - Texture2D DiffuseGBuffer; - Texture2D SpecularGBuffer; -#endif - -[numthreads(16, 16, 1)] -void kernel_finalize(int3 id : SV_DispatchThreadID) -{ - if (id.x >= screen_width || id.y >= screen_height) return; - int pixel_index = id.y * screen_width + id.x; - float3 GBufferCol = 1; - // if(DiffRes) { - // float2 UV = id.xy / float2(screen_width, screen_height); - // #ifdef HDRP - // float3 SpecularAlbedo = 0;//Albedo2[int3(ipos,0)].xyz; - // GBufferCol = ((DiffuseGBuffer.SampleLevel(my_linear_clamp_sampler, float3(UV, 0), 0).xyz + SpecularAlbedo) == 0) ? 1 : (DiffuseGBuffer.SampleLevel(my_linear_clamp_sampler, float3(UV, 0), 0).xyz + SpecularAlbedo); - // #else - // float3 SpecularAlbedo = SpecularGBuffer.SampleLevel(my_linear_clamp_sampler, UV, 0); - // GBufferCol = ((DiffuseGBuffer.SampleLevel(my_linear_clamp_sampler, UV, 0).xyz + SpecularAlbedo) == 0) ? 1 : ((DiffuseGBuffer.SampleLevel(my_linear_clamp_sampler, UV, 0).xyz + SpecularAlbedo)); - // #endif - // } - float3 colour = TempAlbedoTex[id.xy].w <= 0 ? TempAlbedoTex[id.xy] : ((DirectB[id.xy].xyz + IndirectB[id.xy].xyz) * unpackRGBE(WorldPosData[id.xy].w)); - Result[id.xy] = float4(colour, 1); - -} \ No newline at end of file diff --git a/TrueTrace/Resources/PostProcess/Compute/TAA.compute b/TrueTrace/Resources/PostProcess/Compute/TAA.compute index 616b5be1..4a7df2f6 100644 --- a/TrueTrace/Resources/PostProcess/Compute/TAA.compute +++ b/TrueTrace/Resources/PostProcess/Compute/TAA.compute @@ -1,32 +1,19 @@ #include "../../GlobalDefines.cginc" Texture2D ColorIn; -SamplerState sampler_ColorIn; RWTexture2D ColorOut; -RWTexture2D RWScreenPosPrev; -Texture2D ScreenPosPrev; -SamplerState sampler_ScreenPosPrev; -Texture2D PosTex; int screen_width; int screen_height; -int target_width; -int target_height; - -float4x4 viewprojection; -float4x4 prevviewprojection; #ifdef HDRP Texture2DArray MotionVectors; - Texture2DArray DepthTex; #else Texture2D MotionVectors; - Texture2D DepthTex; #endif -float FarPlane; #pragma kernel kernel_taa_prepare @@ -34,33 +21,12 @@ inline float luminance(const float r, const float g, const float b) { return 0.299f * r + 0.587f * g + 0.114f * b; } -const static int2 offsets[4] = { - int2(-1, -1), - int2(1, 1), - int2(-1, 1), - int2(1, -1), -}; - -int2 get_rpx_offset(uint sample_i, uint frame_index) { - - const int2 reservoir_px_offset_base = - offsets[frame_index & 3] - + offsets[(sample_i + (frame_index ^ 1)) & 3]; - return - sample_i == 0 - ? 0 - : int2(reservoir_px_offset_base) - ; -} int Samples_Accumulated; [numthreads(16, 16, 1)] void kernel_taa_prepare(int3 id : SV_DispatchThreadID) { if (id.x >= screen_width || id.y >= screen_height) return; - //in = Result - //out = ColorDirectOut - float3 colour = ColorIn[id.xy].xyz; @@ -275,95 +241,6 @@ float4 TAAA(int2 id) { } return colour; } -#define EPS 1e-4 - -float3 rgb2ycocg(in float3 rgb) -{ - float co = rgb.r - rgb.b; - float t = rgb.b + co / 2.0; - float cg = rgb.g - t; - float y = t + cg / 2.0; - return float3(y, co, cg); -} - - -float3 ycocg2rgb(in float3 ycocg) -{ - float t = ycocg.r - ycocg.b / 2.0; - float g = ycocg.b + t; - float b = t - ycocg.g / 2.0; - float r = ycocg.g + b; - return float3(r, g, b); -} - -float3 RGBtoYCoCg(float3 c) -{ - //return rgb2ycocg(c); - return mul(float3x3(0.25, 0.5, -0.25, 0.5, 0, 0.5, 0.25, -0.5, -0.25), c); -} - -float3 YCoCgToRGB(float3 c) -{ - //return ycocg2rgb(c); - return mul(float3x3(1, 1, 1, 1, 0, -1, -1, 1, -1), c); -} - - - -float4 SampleTextureCatmullRom(Texture2D tex, float2 texSize, float2 uv) -{ - // We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding - // down the sample location to get the exact center of our "starting" texel. The starting texel will be at - // location [1, 1] in the grid, where [0, 0] is the top left corner. - float2 samplePos = uv * texSize; - float2 texPos1 = floor(samplePos - 0.5) + 0.5; - - // Compute the fractional offset from our starting texel to our original sample location, which we'll - // feed into the Catmull-Rom spline function to get our filter weights. - float2 f = samplePos - texPos1; - - // Compute the Catmull-Rom weights using the fractional offset that we calculated earlier. - // These equations are pre-expanded based on our knowledge of where the texels will be located, - // which lets us avoid having to evaluate a piece-wise function. - float2 w0 = f * ( -0.5 + f * (1.0 - 0.5*f)); - float2 w1 = 1.0 + f * f * (-2.5 + 1.5*f); - float2 w2 = f * ( 0.5 + f * (2.0 - 1.5*f) ); - float2 w3 = f * f * (-0.5 + 0.5 * f); - - // Work out weighting factors and sampling offsets that will let us use bilinear filtering to - // simultaneously evaluate the middle 2 samples from the 4x4 grid. - float2 w12 = w1 + w2; - float2 offset12 = w2 / w12; - - // Compute the final UV coordinates we'll use for sampling the texture - float2 texPos0 = texPos1 - 1.0f; - float2 texPos3 = texPos1 + 2.0f; - float2 texPos12 = texPos1 + offset12; - - texPos0 /= texSize; - texPos3 /= texSize; - texPos12 /= texSize; - - float4 result = 0; - result += tex.SampleLevel(my_linear_clamp_sampler, float2(texPos0.x, texPos0.y),0) * w0.x * w0.y; - result += tex.SampleLevel(my_linear_clamp_sampler, float2(texPos12.x, texPos0.y),0) * w12.x * w0.y; - result += tex.SampleLevel(my_linear_clamp_sampler, float2(texPos3.x, texPos0.y),0) * w3.x * w0.y; - - result += tex.SampleLevel(my_linear_clamp_sampler, float2(texPos0.x, texPos12.y),0) * w0.x * w12.y; - result += tex.SampleLevel(my_linear_clamp_sampler, float2(texPos12.x, texPos12.y),0) * w12.x * w12.y; - result += tex.SampleLevel(my_linear_clamp_sampler, float2(texPos3.x, texPos12.y),0) * w3.x * w12.y; - - result += tex.SampleLevel(my_linear_clamp_sampler, float2(texPos0.x, texPos3.y),0) * w0.x * w3.y; - result += tex.SampleLevel(my_linear_clamp_sampler, float2(texPos12.x, texPos3.y),0) * w12.x * w3.y; - result += tex.SampleLevel(my_linear_clamp_sampler, float2(texPos3.x, texPos3.y),0) * w3.x * w3.y; - - return result; -} - - - - - [numthreads(16, 16, 1)] @@ -392,7 +269,6 @@ void kernel_taa_finalize(int3 id : SV_DispatchThreadID) color = color / (1.0f - luminance(color.x, color.y, color.z)); - // id.xy += (Offsets[Samples_Accumulated % 16] - 0.5f);// / float2(screen_width, screen_height); ColorOut[id.xy] = color; } diff --git a/TrueTrace/Resources/PostProcess/TTPostProcessing.cs b/TrueTrace/Resources/PostProcess/TTPostProcessing.cs index cd8eadc8..9228ce07 100644 --- a/TrueTrace/Resources/PostProcess/TTPostProcessing.cs +++ b/TrueTrace/Resources/PostProcess/TTPostProcessing.cs @@ -17,12 +17,14 @@ public class TTPostProcessing private ComputeShader TAAU; private ComputeShader Sharpen; private ComputeShader FXAAShader; + private ComputeShader CombinedPPShader; bool BloomInitialized = false; bool TAAInitialized = false; bool UpscalerInitialized = false; bool TAAUInitialized = false; bool SharpenInitialized = false; bool FXAAInitialized = false; + bool CombinedPPInitialized = false; public RenderTexture FXAAFlopper; private int FXAAFXAAKernel; @@ -39,6 +41,9 @@ public class TTPostProcessing private RenderTexture SharpenTex; + + + private RenderTexture CombinedPPIntermediateTex; @@ -87,6 +92,9 @@ public class TTPostProcessing private int TAAUKernel; private int TAAUCopyKernel; + private int BSCKernel; + private int VignetteKernel; + private int ChromaticAbberationKernel; @@ -106,7 +114,9 @@ private void InitRenderTexture(bool Force = false) TempTexTAA.ReleaseSafe(); TempTexTAA2.ReleaseSafe(); SharpenTex.ReleaseSafe(); + CombinedPPIntermediateTex.ReleaseSafe(); FXAAFlopper.ReleaseSafe(); + CombinedPPInitialized = false; FXAAInitialized = false; BloomInitialized = false; TAAInitialized = false; @@ -127,7 +137,7 @@ public void ClearAll() { TAAA.ReleaseSafe(); TAAB.ReleaseSafe(); - + CombinedPPIntermediateTex.ReleaseSafe(); SharpenTex.ReleaseSafe(); ExposureBuffer.ReleaseSafe(); @@ -155,6 +165,7 @@ public void init(int SourceWidth, int SourceHeight) if (TAAU == null) { TAAU = Resources.Load("PostProcess/Compute/TAAU"); } if (Sharpen == null) { Sharpen = Resources.Load("PostProcess/Compute/Sharpen"); } if (FXAAShader == null) { FXAAShader = Resources.Load("PostProcess/Compute/FXAA"); } + if (CombinedPPShader == null) {CombinedPPShader = Resources.Load("PostProcess/Compute/CombinedPP"); } ConvBloom = new ConvolutionBloom(); TAAUKernel = TAAU.FindKernel("TAAU"); @@ -162,6 +173,11 @@ public void init(int SourceWidth, int SourceHeight) FXAAFXAAKernel = FXAAShader.FindKernel("FXAA"); + ChromaticAbberationKernel = CombinedPPShader.FindKernel("ChromaticAbberationKernel"); + VignetteKernel = CombinedPPShader.FindKernel("VignetteKernel"); + BSCKernel = CombinedPPShader.FindKernel("BSCKernel"); + + BloomDownsampleKernel = Bloom.FindKernel("Downsample"); BloomLowPassKernel = Bloom.FindKernel("LowPass"); @@ -179,6 +195,9 @@ public void init(int SourceWidth, int SourceHeight) TestBuffer.Add(1); ExposureBuffer?.Release(); ExposureBuffer = new ComputeBuffer(1, sizeof(float)); ExposureBuffer.SetData(TestBuffer); + CombinedPPShader.SetInt("screen_width", _camera.scaledPixelWidth); + CombinedPPShader.SetInt("screen_height", _camera.scaledPixelHeight); + Bloom.SetInt("screen_width", _camera.scaledPixelWidth); Bloom.SetInt("screen_height", _camera.scaledPixelHeight); @@ -206,6 +225,7 @@ public void init(int SourceWidth, int SourceHeight) UpscalerInitialized = false; SharpenInitialized = false; FXAAInitialized = false; + CombinedPPInitialized = false; InitRenderTexture(); Initialized = true; } @@ -240,7 +260,7 @@ public void Reinit(int SourceWidth, int SourceHeight) InitRenderTexture(true); } - public void ValidateInit(bool BloomInit, bool TAAInit, bool IsUpscaling, bool UseTAAU, bool SharpenInit, bool FXAAInit) { + public void ValidateInit(bool BloomInit, bool TAAInit, bool IsUpscaling, bool UseTAAU, bool SharpenInit, bool FXAAInit, bool CombinedPPInit) { if(!BloomInit) { if(ConvBloom.Initialized) ConvBloom.ClearAll(); if(BloomInitialized) { @@ -277,12 +297,18 @@ public void ValidateInit(bool BloomInit, bool TAAInit, bool IsUpscaling, bool Us } } } - if(!FXAAInitialized) { + if(!FXAAInit) { if(FXAAInitialized) { FXAAFlopper.ReleaseSafe(); FXAAInitialized = false; } } + if(!CombinedPPInit) { + if(CombinedPPInitialized) { + CombinedPPIntermediateTex.ReleaseSafe(); + CombinedPPInitialized = false; + } + } } @@ -564,6 +590,46 @@ public void ExecuteFXAA(ref RenderTexture Output, CommandBuffer cmd) { } + private void InitializeCombinedPP() { + CommonFunctions.CreateRenderTexture(ref CombinedPPIntermediateTex, _camera.scaledPixelWidth, _camera.scaledPixelHeight, CommonFunctions.RTFull4); + CombinedPPInitialized = true; + } + public void ExecuteCombinedPP(ref RenderTexture Output, CommandBuffer cmd, bool DoBCS, bool DoVignette, bool DoChromaAber, float Contrast, float Saturation, float ChromaDistort, float VignetteInner, float VignetteOuter, float VignetteStrength, float VignetteCurve, Vector3 VignetteColor) { + if(!CombinedPPInitialized) InitializeCombinedPP(); + if (CombinedPPShader == null) { CombinedPPShader = Resources.Load("PostProcess/Compute/CombinedPP"); } + CombinedPPShader.SetInt("screen_width", Output.width); + CombinedPPShader.SetInt("screen_height", Output.height); + if(DoBCS) { + cmd.CopyTexture(Output, 0, 0, CombinedPPIntermediateTex, 0, 0); + CombinedPPShader.SetFloat("contrast", Contrast); + CombinedPPShader.SetFloat("saturation", Saturation); + cmd.SetComputeTextureParam(CombinedPPShader, BSCKernel, "Input", CombinedPPIntermediateTex); + cmd.SetComputeTextureParam(CombinedPPShader, BSCKernel, "Result", Output); + cmd.DispatchCompute(CombinedPPShader, BSCKernel, Mathf.CeilToInt((float)Output.width / 16.0f), Mathf.CeilToInt((float)Output.height / 16.0f), 1); + + } + if(DoChromaAber) { + cmd.CopyTexture(Output, 0, 0, CombinedPPIntermediateTex, 0, 0); + CombinedPPShader.SetFloat("DISTORTION_AMOUNT", ChromaDistort); + cmd.SetComputeTextureParam(CombinedPPShader, ChromaticAbberationKernel, "Input", CombinedPPIntermediateTex); + cmd.SetComputeTextureParam(CombinedPPShader, ChromaticAbberationKernel, "Result", Output); + cmd.DispatchCompute(CombinedPPShader, ChromaticAbberationKernel, Mathf.CeilToInt((float)Output.width / 16.0f), Mathf.CeilToInt((float)Output.height / 16.0f), 1); + } + if(DoVignette) { + cmd.CopyTexture(Output, 0, 0, CombinedPPIntermediateTex, 0, 0); + CombinedPPShader.SetFloat("inner", VignetteInner); + CombinedPPShader.SetFloat("outer", VignetteOuter); + CombinedPPShader.SetFloat("strength", VignetteStrength); + CombinedPPShader.SetFloat("curvature", VignetteCurve); + CombinedPPShader.SetVector("Color", VignetteColor); + cmd.SetComputeTextureParam(CombinedPPShader, VignetteKernel, "Input", CombinedPPIntermediateTex); + cmd.SetComputeTextureParam(CombinedPPShader, VignetteKernel, "Result", Output); + cmd.DispatchCompute(CombinedPPShader, VignetteKernel, Mathf.CeilToInt((float)Output.width / 16.0f), Mathf.CeilToInt((float)Output.height / 16.0f), 1); + } + + + } + } } diff --git a/TrueTrace/Resources/RayTracingMaster.cs b/TrueTrace/Resources/RayTracingMaster.cs index 8bd53b5b..11951d84 100644 --- a/TrueTrace/Resources/RayTracingMaster.cs +++ b/TrueTrace/Resources/RayTracingMaster.cs @@ -10,8 +10,10 @@ namespace TrueTrace { public class RayTracingMaster : MonoBehaviour { + public static RayTracingMaster RayMaster; [HideInInspector] public static Camera _camera; - public static bool DoKernelProfiling = false; + public static bool DoKernelProfiling = true; + [HideInInspector] [SerializeField] public string LocalTTSettingsName = "TTGlobalSettings"; private bool OverriddenResolutionIsActive = false; public bool HDRPorURPRenderInScene = false; [HideInInspector] public AtmosphereGenerator Atmo; @@ -19,7 +21,7 @@ public class RayTracingMaster : MonoBehaviour private ReSTIRASVGF ReSTIRASVGFCode; private TTPostProcessing TTPostProc; private ASVGF ASVGFCode; - private bool Abandon = false; + public static bool ImageIsModified = false; #if UseOIDN private UnityDenoiserPlugin.DenoiserPluginWrapper OIDNDenoiser; #endif @@ -171,13 +173,15 @@ public static void WriteString(RayTracingObject OBJtoWrite, string NameIndex) { [SerializeField] [HideInInspector] public static int SampleCount; private int uFirstFrame = 1; - [HideInInspector] public static bool DoDing = true; [HideInInspector] public static bool DoCheck = false; [HideInInspector] public bool PrevReSTIRGI = false; [HideInInspector] public bool DoPanorama = false; [HideInInspector] public bool DoChainedImages = false; - [HideInInspector] [SerializeField] public TTSettings LocalTTSettings; + // #if !LoadTTSettingsFromResources + // [HideInInspector] + // #endif + [SerializeField] public TTSettings LocalTTSettings; public static bool SceneIsRunning = false; @@ -260,6 +264,7 @@ private void CheckAndHandleResolutionChange(int newWidth, int newHeight) { } unsafe public void Start2() { + RayMaster = this; CurrentHorizonalPatch = new Vector2(0,1); LoadTT(); // LoadInitialSettings();//Build only @@ -311,9 +316,12 @@ unsafe public void Start2() TTPostProc.Initialized = false; } public void Awake() { + RayMaster = this; LoadTT(); } public void Start() { + RayMaster = this; + SceneManager.sceneUnloaded += OnSceneUnloaded; DoPanorama = false; DoChainedImages = false; LoadTT(); @@ -323,8 +331,8 @@ void Reset() { LoadTT(); } public void LoadTT() { - if(TTCPUDefines.fallbackTTSettingsName.Equals("null")) { - if(LocalTTSettings == null || !LocalTTSettings.name.Equals(UnityEngine.SceneManagement.SceneManager.GetActiveScene().name)) { + #if !LoadTTSettingsFromResources + if(LocalTTSettings == null || (!LocalTTSettings.name.Equals(UnityEngine.SceneManagement.SceneManager.GetActiveScene().name) && !ImageIsModified)) { #if UNITY_EDITOR UnityEngine.SceneManagement.Scene CurrentScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); string path = CurrentScene.path.Replace(".unity", ""); @@ -346,11 +354,28 @@ public void LoadTT() { if(LocalTTSettings != null) { LoadInitialSettings(); } - } else { - LocalTTSettings = Resources.Load(TTCPUDefines.fallbackTTSettingsName); - if(LocalTTSettings == null) - LocalTTSettings = ScriptableObject.CreateInstance(); - } + #else + if(LocalTTSettings == null) { + LocalTTSettings = Resources.Load("Utility/TTSettingsStorage/" + LocalTTSettingsName); + if(LocalTTSettings == null) { + #if UNITY_EDITOR + string path = "Assets/TrueTrace-Unity-Pathtracer/TrueTrace/Resources/Utility/TTSettingsStorage/" + LocalTTSettingsName; + LocalTTSettings = ScriptableObject.CreateInstance(); + UnityEditor.AssetDatabase.CreateAsset(LocalTTSettings, path + ".asset"); + UnityEditor.AssetDatabase.SaveAssets(); + #else + LocalTTSettings = ScriptableObject.CreateInstance(); + #endif + } + } else { + if(!LocalTTSettings.name.Equals(LocalTTSettingsName)) { + LocalTTSettingsName = LocalTTSettings.name; + } + } + #if UNITY_EDITOR + UnityEditor.EditorUtility.SetDirty(LocalTTSettings); + #endif + #endif } private void OnEnable() { @@ -368,25 +393,24 @@ void OnDestroy() { } #endif } - public void OnDisable() { + + + + void OnSceneUnloaded(Scene scene) { + ClearAll(); + } + + public void ClearAll() { DoCheck = true; - _RayBuffer?.Release(); - LightingBuffer?.Release(); - _BufferSizes?.Release(); - _ShadowBuffer?.Release(); - #if UseOIDN - ColorBuffer?.Release(); - OutputBuffer?.Release(); - AlbedoBuffer?.Release(); - NormalBuffer?.Release(); - if(OIDNDenoiser != null) { - OIDNDenoiser.Dispose(); - OIDNDenoiser = null; - } - #endif + if(TTPostProc != null) TTPostProc.ClearAll(); + _RayBuffer.ReleaseSafe(); + LightingBuffer.ReleaseSafe(); + _BufferSizes.ReleaseSafe(); + _ShadowBuffer.ReleaseSafe(); if(ASVGFCode != null) ASVGFCode.ClearAll(); if(ReSTIRASVGFCode != null) ReSTIRASVGFCode.ClearAll(); - CurBounceInfoBuffer?.Release(); + CurBounceInfoBuffer.ReleaseSafe(); + Atmo.Dispose(); TTPostProc.ClearAll(); CDFX.ReleaseSafe(); CDFY.ReleaseSafe(); @@ -398,6 +422,41 @@ public void OnDisable() { HashBufferA.ReleaseSafe(); HashBufferB.ReleaseSafe(); #endif + + _RandomNums.ReleaseSafe(); + _RandomNumsB.ReleaseSafe(); + _target.ReleaseSafe(); + _converged.ReleaseSafe(); + _DebugTex.ReleaseSafe(); + _FinalTex.ReleaseSafe(); + GIReservoirA.ReleaseSafe(); + GIReservoirB.ReleaseSafe(); + GIReservoirC.ReleaseSafe(); + GINEEPosA.ReleaseSafe(); + GINEEPosB.ReleaseSafe(); + GINEEPosC.ReleaseSafe(); + GIWorldPosA.ReleaseSafe(); + GIWorldPosB.ReleaseSafe(); + GIWorldPosC.ReleaseSafe(); + _PrimaryTriangleInfo.ReleaseSafe(); + ScreenSpaceInfo.ReleaseSafe(); + ScreenSpaceInfoPrev.ReleaseSafe(); + GradientsA.ReleaseSafe(); + GradientsB.ReleaseSafe(); + #if UseOIDN + ColorBuffer.ReleaseSafe(); + OutputBuffer.ReleaseSafe(); + AlbedoBuffer.ReleaseSafe(); + NormalBuffer.ReleaseSafe(); + if(OIDNDenoiser != null) { + OIDNDenoiser.Dispose(); + OIDNDenoiser = null; + } + #endif + } + public void OnDisable() { + ClearAll(); + SceneManager.sceneUnloaded -= OnSceneUnloaded; } private void RunUpdate() { @@ -448,7 +507,7 @@ public bool RebuildMeshObjectBuffers(CommandBuffer cmd) FramesSinceStart = 0; - if(CurBounceInfoBuffer != null) CurBounceInfoBuffer.Release(); + if(CurBounceInfoBuffer != null) CurBounceInfoBuffer.ReleaseSafe(); CurBounceInfoBuffer = new ComputeBuffer(1, 12); if(_RayBuffer == null || _RayBuffer.count != SourceWidth * SourceHeight) { CommonFunctions.CreateDynamicBuffer(ref _RayBuffer, SourceWidth * SourceHeight * 2, 48); @@ -515,7 +574,7 @@ Matrix4x4 CalcProj(Camera cam) { private Vector2 HDRIParams = Vector2.zero; private void SetShaderParameters(CommandBuffer cmd) { - HasSDFHandler = (OptionalSDFHandler != null); + HasSDFHandler = (OptionalSDFHandler != null) && OptionalSDFHandler.enabled && OptionalSDFHandler.gameObject.activeInHierarchy; if(LocalTTSettings.RenderScale != 1.0f) _camera.renderingPath = RenderingPath.DeferredShading; _camera.depthTextureMode |= DepthTextureMode.Depth | DepthTextureMode.MotionVectors; if(LocalTTSettings.UseReSTIRGI && LocalTTSettings.DenoiserMethod == 1 && !ReSTIRASVGFCode.Initialized) ReSTIRASVGFCode.init(SourceWidth, SourceHeight); @@ -537,7 +596,7 @@ private void SetShaderParameters(CommandBuffer cmd) { _BufferSizes = new ComputeBuffer(LocalTTSettings.bouncecount + 1, 16); } if(_BufferSizes.count != LocalTTSettings.bouncecount + 1) { - _BufferSizes.Release(); + _BufferSizes.ReleaseSafe(); _BufferSizes = new ComputeBuffer(LocalTTSettings.bouncecount + 1, 16); } _BufferSizes.SetData(BufferSizes); @@ -600,6 +659,7 @@ private void SetShaderParameters(CommandBuffer cmd) { SetFloat("LEMEnergyScale", LocalTTSettings.LEMEnergyScale, cmd); SetFloat("OIDNBlendRatio", LocalTTSettings.OIDNBlendRatio, cmd); SetFloat("FogDensity", LocalTTSettings.FogDensity, cmd); + SetFloat("ScaleHeight", LocalTTSettings.FogHeight, cmd); SetInt("NonInstanceCount", Assets.NonInstanceCount, cmd); SetInt("AlbedoAtlasSize", Assets.AlbedoAtlasSize, cmd); @@ -681,7 +741,7 @@ private void SetShaderParameters(CommandBuffer cmd) { CDFCompute.SetBuffer(0, "CounterBuffer", CounterBuffer); CDFCompute.SetBuffer(0, "TotalBuff", CDFTotalBuffer); CDFCompute.Dispatch(0, 1, SkyboxTexture.height, 1); - CounterBuffer.Release(); + CounterBuffer.ReleaseSafe(); HDRIParams = new Vector2(SkyboxTexture.width, SkyboxTexture.height); ShadingShader.SetTexture(ShadeKernel, "CDFX", CDFX); ShadingShader.SetTexture(ShadeKernel, "CDFY", CDFY); @@ -764,6 +824,9 @@ private void SetShaderParameters(CommandBuffer cmd) { AssetManager.Assets.SetLightData(ShadingShader, ShadeKernel); AssetManager.Assets.SetMeshTraceBuffers(ShadingShader, ShadeKernel); AssetManager.Assets.SetHeightmapTraceBuffers(ShadingShader, ShadeKernel); + // ShadingShader.SetTexture(ShadeKernel, "CloudShapeTex", Atmo.CloudShapeTex); + // ShadingShader.SetTexture(ShadeKernel, "CloudShapeDetailTex", Atmo.CloudShapeDetailTex); + // ShadingShader.SetTexture(ShadeKernel, "localWeatherTexture", Atmo.WeatherTex); ShadingShader.SetTexture(ShadeKernel, "WorldPosB", !FlipFrame ? GIWorldPosB : GIWorldPosC); ShadingShader.SetTexture(ShadeKernel, "RandomNums", FlipFrame ? _RandomNums : _RandomNumsB); ShadingShader.SetTexture(ShadeKernel, "SingleComponentAtlas", Assets.SingleComponentAtlas); @@ -812,9 +875,7 @@ private void SetShaderParameters(CommandBuffer cmd) { ReSTIRGI.SetTexture(ReSTIRGIKernel, "Gradient", GradientsA); ReSTIRGI.SetTexture(ReSTIRGIKernel, "GradientWrite", GradientsB); - ReSTIRGI.SetTexture(ReSTIRGISpatialKernel, "GradientWrite", GradientsA); ReSTIRGI.SetTexture(ReSTIRGISpatialKernel, "Gradient", GradientsB); - ReSTIRGI.SetTexture(ReSTIRGISpatialKernel, "WorldPosC", GIWorldPosA); ReSTIRGI.SetTexture(ReSTIRGISpatialKernel, "WorldPosB", FlipFrame ? GIWorldPosB : GIWorldPosC); ReSTIRGI.SetTexture(ReSTIRGISpatialKernel, "NEEPosB", FlipFrame ? GINEEPosA : GINEEPosB); ReSTIRGI.SetTexture(ReSTIRGISpatialKernel, "ReservoirB", FlipFrame ? GIReservoirB : GIReservoirA); @@ -822,11 +883,23 @@ private void SetShaderParameters(CommandBuffer cmd) { ReSTIRGI.SetTexture(ReSTIRGISpatialKernel, "ScreenSpaceInfoRead", FlipFrame ? ScreenSpaceInfo : ScreenSpaceInfoPrev); ReSTIRGI.SetTexture(ReSTIRGISpatialKernel, "RandomNums", FlipFrame ? _RandomNums : _RandomNumsB); ReSTIRGI.SetTexture(ReSTIRGISpatialKernel, "PrimaryTriData", _PrimaryTriangleInfo); + ReSTIRGI.SetTexture(ReSTIRGISpatialKernel, "WorldPosA", GIWorldPosA); + ReSTIRGI.SetTexture(ReSTIRGISpatialKernel, "NEEPosA", GINEEPosC); + ReSTIRGI.SetTexture(ReSTIRGISpatialKernel, "ReservoirA", GIReservoirC); - + ReSTIRGI.SetTexture(ReSTIRGISpatialKernel+1, "GradientWrite", GradientsA); + ReSTIRGI.SetTexture(ReSTIRGISpatialKernel+1, "Gradient", GradientsB); + ReSTIRGI.SetTexture(ReSTIRGISpatialKernel+1, "WorldPosB", GIWorldPosA); + ReSTIRGI.SetTexture(ReSTIRGISpatialKernel+1, "NEEPosB", GINEEPosC); + ReSTIRGI.SetTexture(ReSTIRGISpatialKernel+1, "ReservoirB", GIReservoirC); + ReSTIRGI.SetTexture(ReSTIRGISpatialKernel+1, "ScreenSpaceInfoRead", FlipFrame ? ScreenSpaceInfo : ScreenSpaceInfoPrev); + ReSTIRGI.SetTexture(ReSTIRGISpatialKernel+1, "RandomNums", FlipFrame ? _RandomNums : _RandomNumsB); + ReSTIRGI.SetTexture(ReSTIRGISpatialKernel+1, "PrimaryTriData", _PrimaryTriangleInfo); + ReSTIRGI.SetComputeBuffer(ReSTIRGISpatialKernel+1, "GlobalColors", LightingBuffer); AssetManager.Assets.SetMeshTraceBuffers(ReSTIRGI, ReSTIRGISpatialKernel); + AssetManager.Assets.SetMeshTraceBuffers(ReSTIRGI, ReSTIRGISpatialKernel+1); Shader.SetGlobalTexture("_DebugTex", _DebugTex); } @@ -895,29 +968,29 @@ private void InitRenderTexture(bool ForceReset = false) LightingBuffer.ReleaseSafe(); _RandomNums.ReleaseSafe(); _RandomNumsB.ReleaseSafe(); - _target.Release(); - _converged.Release(); - _DebugTex.Release(); - _FinalTex.Release(); - GIReservoirA.Release(); - GIReservoirB.Release(); - GIReservoirC.Release(); - GINEEPosA.Release(); - GINEEPosB.Release(); - GINEEPosC.Release(); - GIWorldPosA.Release(); - GIWorldPosB.Release(); - GIWorldPosC.Release(); - _PrimaryTriangleInfo.Release(); - ScreenSpaceInfo.Release(); - ScreenSpaceInfoPrev.Release(); - GradientsA.Release(); - GradientsB.Release(); + _target.ReleaseSafe(); + _converged.ReleaseSafe(); + _DebugTex.ReleaseSafe(); + _FinalTex.ReleaseSafe(); + GIReservoirA.ReleaseSafe(); + GIReservoirB.ReleaseSafe(); + GIReservoirC.ReleaseSafe(); + GINEEPosA.ReleaseSafe(); + GINEEPosB.ReleaseSafe(); + GINEEPosC.ReleaseSafe(); + GIWorldPosA.ReleaseSafe(); + GIWorldPosB.ReleaseSafe(); + GIWorldPosC.ReleaseSafe(); + _PrimaryTriangleInfo.ReleaseSafe(); + ScreenSpaceInfo.ReleaseSafe(); + ScreenSpaceInfoPrev.ReleaseSafe(); + GradientsA.ReleaseSafe(); + GradientsB.ReleaseSafe(); #if UseOIDN - ColorBuffer.Release(); - OutputBuffer.Release(); - AlbedoBuffer.Release(); - NormalBuffer.Release(); + ColorBuffer.ReleaseSafe(); + OutputBuffer.ReleaseSafe(); + AlbedoBuffer.ReleaseSafe(); + NormalBuffer.ReleaseSafe(); if(OIDNDenoiser != null) { OIDNDenoiser.Dispose(); OIDNDenoiser = null; @@ -933,7 +1006,7 @@ private void InitRenderTexture(bool ForceReset = false) guideNormal = 1, temporalMode = 0, cleanAux = 1, - prefilterAux = 0 + prefilterAux = 1 }; UnityDenoiserPlugin.DenoiserType denoiserType; @@ -945,7 +1018,7 @@ private void InitRenderTexture(bool ForceReset = false) denoiserType = UnityDenoiserPlugin.DenoiserType.OptiX; break; default: - denoiserType = UnityDenoiserPlugin.DenoiserType.OptiX; + denoiserType = UnityDenoiserPlugin.DenoiserType.OIDN; break; } OIDNDenoiser = new UnityDenoiserPlugin.DenoiserPluginWrapper(denoiserType, cfg); @@ -1025,7 +1098,7 @@ private void Render(RenderTexture destination, CommandBuffer cmd) cmd.DispatchCompute(GenerateShader, CompactKernel, Mathf.CeilToInt((4.0f * 1024.0f * 1024.0f) / 256.0f), 1, 1); if(DoKernelProfiling) cmd.EndSample("RadCacheCompact"); #endif - TTPostProc.ValidateInit(LocalTTSettings.PPBloom, LocalTTSettings.PPTAA, SourceWidth != TargetWidth, LocalTTSettings.UpscalerMethod == 2, LocalTTSettings.DoSharpen, LocalTTSettings.PPFXAA); + TTPostProc.ValidateInit(LocalTTSettings.PPBloom, LocalTTSettings.PPTAA, SourceWidth != TargetWidth, LocalTTSettings.UpscalerMethod == 2, LocalTTSettings.DoSharpen, LocalTTSettings.PPFXAA, LocalTTSettings.DoChromaAber || LocalTTSettings.DoBCS || LocalTTSettings.DoVignette); float CurrentSample; GenerateRays(cmd); @@ -1105,28 +1178,20 @@ private void Render(RenderTexture destination, CommandBuffer cmd) if (LocalTTSettings.UseReSTIRGI) { SetInt("CurBounce", 0, cmd); if(DoKernelProfiling) cmd.BeginSample("ReSTIRGI Temporal Kernel"); - cmd.DispatchCompute(ReSTIRGI, ReSTIRGIKernel, Mathf.CeilToInt(SourceWidth / 16.0f), Mathf.CeilToInt(SourceHeight / 16.0f), 1); + cmd.DispatchCompute(ReSTIRGI, ReSTIRGIKernel, Mathf.CeilToInt(SourceWidth / 8.0f), Mathf.CeilToInt(SourceHeight / 8.0f), 1); if(DoKernelProfiling) cmd.EndSample("ReSTIRGI Temporal Kernel"); bool FlipFrame = (FramesSinceStart2 % 2 == 0); if(DoKernelProfiling) cmd.BeginSample("ReSTIRGI Extra Spatial Kernel"); SetInt("CurPass", 0, cmd); - cmd.SetComputeTextureParam(ReSTIRGI, ReSTIRGISpatialKernel, "WorldPosB", FlipFrame ? GIWorldPosB : GIWorldPosC); - cmd.SetComputeTextureParam(ReSTIRGI, ReSTIRGISpatialKernel, "WorldPosA", GIWorldPosA); - cmd.SetComputeTextureParam(ReSTIRGI, ReSTIRGISpatialKernel, "NEEPosB", FlipFrame ? GINEEPosA : GINEEPosB); - cmd.SetComputeTextureParam(ReSTIRGI, ReSTIRGISpatialKernel, "NEEPosA", GINEEPosC); - cmd.SetComputeTextureParam(ReSTIRGI, ReSTIRGISpatialKernel, "ReservoirB", FlipFrame ? GIReservoirB : GIReservoirA); - cmd.SetComputeTextureParam(ReSTIRGI, ReSTIRGISpatialKernel, "ReservoirA", GIReservoirC); - cmd.DispatchCompute(ReSTIRGI, ReSTIRGISpatialKernel, Mathf.CeilToInt(SourceWidth / 16.0f), Mathf.CeilToInt(SourceHeight / 16.0f), 1); + + cmd.DispatchCompute(ReSTIRGI, ReSTIRGISpatialKernel, Mathf.CeilToInt(SourceWidth / 8.0f), Mathf.CeilToInt(SourceHeight / 8.0f), 1); if(DoKernelProfiling) cmd.EndSample("ReSTIRGI Extra Spatial Kernel"); if(DoKernelProfiling) cmd.BeginSample("ReSTIRGI Extra Spatial Kernel 1"); SetInt("frames_accumulated", _currentSample * 2, cmd); SetInt("CurPass", 1, cmd); - cmd.SetComputeTextureParam(ReSTIRGI, ReSTIRGISpatialKernel, "WorldPosB", GIWorldPosA); - cmd.SetComputeTextureParam(ReSTIRGI, ReSTIRGISpatialKernel, "NEEPosB", GINEEPosC); - cmd.SetComputeTextureParam(ReSTIRGI, ReSTIRGISpatialKernel, "ReservoirB", GIReservoirC); - cmd.DispatchCompute(ReSTIRGI, ReSTIRGISpatialKernel, Mathf.CeilToInt(SourceWidth / 16.0f), Mathf.CeilToInt(SourceHeight / 16.0f), 1); + cmd.DispatchCompute(ReSTIRGI, ReSTIRGISpatialKernel+1, Mathf.CeilToInt(SourceWidth / 8.0f), Mathf.CeilToInt(SourceHeight / 8.0f), 1); if(DoKernelProfiling) cmd.EndSample("ReSTIRGI Extra Spatial Kernel 1"); cmd.Blit(GradientsA, GradientsB); @@ -1244,6 +1309,7 @@ private void Render(RenderTexture destination, CommandBuffer cmd) if(LocalTTSettings.ConvBloom) TTPostProc.ExecuteConvBloom(ref _FinalTex, LocalTTSettings.ConvStrength, LocalTTSettings.ConvBloomThreshold, LocalTTSettings.ConvBloomSize, LocalTTSettings.ConvBloomDistExp, LocalTTSettings.ConvBloomDistExpClampMin, LocalTTSettings.ConvBloomDistExpScale, cmd); else TTPostProc.ExecuteBloom(ref _FinalTex, LocalTTSettings.BloomStrength, cmd); } + if(LocalTTSettings.DoChromaAber || LocalTTSettings.DoBCS || LocalTTSettings.DoVignette) TTPostProc.ExecuteCombinedPP(ref _FinalTex, cmd, LocalTTSettings.DoBCS, LocalTTSettings.DoVignette, LocalTTSettings.DoChromaAber, LocalTTSettings.Contrast, LocalTTSettings.Saturation, LocalTTSettings.ChromaDistort, LocalTTSettings.innerVignette, LocalTTSettings.outerVignette, LocalTTSettings.strengthVignette, LocalTTSettings.curveVignette, LocalTTSettings.ColorVignette); if(LocalTTSettings.PPToneMap) TTPostProc.ExecuteToneMap(ref _FinalTex, cmd, ref ToneMapTex, ref ToneMapTex2, LocalTTSettings.ToneMapper); if (LocalTTSettings.PPTAA) TTPostProc.ExecuteTAA(ref _FinalTex, _currentSample, cmd); if (LocalTTSettings.PPFXAA) TTPostProc.ExecuteFXAA(ref _FinalTex, cmd); @@ -1261,7 +1327,6 @@ private void Render(RenderTexture destination, CommandBuffer cmd) public void RenderImage(RenderTexture destination, CommandBuffer cmd) { - Abandon = false; _camera.renderingPath = RenderingPath.DeferredShading; if (SceneIsRunning && Assets != null && Assets.RenderQue.Count > 0) { diff --git a/TrueTrace/Resources/TTCPUDefines.cs b/TrueTrace/Resources/TTCPUDefines.cs deleted file mode 100644 index 2375a5ee..00000000 --- a/TrueTrace/Resources/TTCPUDefines.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace TrueTrace { - public static class TTCPUDefines - { - public static string fallbackTTSettingsName = "null"; - } -} \ No newline at end of file diff --git a/TrueTrace/Resources/TTInterface.cs b/TrueTrace/Resources/TTInterface.cs new file mode 100644 index 00000000..baa04f7a --- /dev/null +++ b/TrueTrace/Resources/TTInterface.cs @@ -0,0 +1,22 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace TrueTrace { + public static class TTInterface + { + public static void SetTTSettings(string SettingsName) { + RayTracingMaster.RayMaster.LocalTTSettingsName = SettingsName; + RayTracingMaster.RayMaster.LoadTT(); + } + public static void SetTTSettings(TTSettings Settings) { + if(RayTracingMaster.RayMaster != null) { + RayTracingMaster.RayMaster.LocalTTSettings = Settings; + RayTracingMaster.RayMaster.LocalTTSettingsName = Settings.name; + } + } + public static void CallUpdatedTextureMappings(RayTracingObject TargetMat) { + TargetMat.CallTilingScrolled(); + } + } +} \ No newline at end of file diff --git a/TrueTrace/Resources/Utility/TurnTableScript.cs.meta b/TrueTrace/Resources/TTInterface.cs.meta similarity index 83% rename from TrueTrace/Resources/Utility/TurnTableScript.cs.meta rename to TrueTrace/Resources/TTInterface.cs.meta index 997ee280..0c3d921f 100644 --- a/TrueTrace/Resources/Utility/TurnTableScript.cs.meta +++ b/TrueTrace/Resources/TTInterface.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b512fb01ad2958748872f15e9f5cd90b +guid: f64715b52964115499328e44b319d078 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/TrueTrace/Resources/Utility/ArrayInstancer.cs b/TrueTrace/Resources/Utility/ArrayInstancer.cs index 4b7fb4c2..eaba6109 100644 --- a/TrueTrace/Resources/Utility/ArrayInstancer.cs +++ b/TrueTrace/Resources/Utility/ArrayInstancer.cs @@ -22,6 +22,7 @@ public class ArrayInstancer : MonoBehaviour public float DiskRadiusPositionRandomize = 0; public int Seed = 3223; + public bool InstanceOverSurface = false; public void CreateInstancesARRAY() { Random.InitState(Seed); @@ -32,9 +33,22 @@ public void CreateInstancesARRAY() { Vector2 UnitRandom = Random.insideUnitCircle * DiskRadiusPositionRandomize; GameObject TempOBJ = GameObject.Instantiate(TargetObject); TempOBJ.transform.parent = TargetObject.transform.parent; - TempOBJ.transform.position = BasePosition + new Vector3((float)i * Spacing.x + UnitRandom.x, 0, (float)j * Spacing.y + UnitRandom.y); - TempOBJ.transform.eulerAngles += Vector3.Scale(new Vector3(Random.value * 2.0f - 1.0f, Random.value * 2.0f - 1.0f, Random.value * 2.0f - 1.0f), RotationRandomizeUpper - RotationRandomizeLower) + RotationRandomizeLower; - TempOBJ.transform.localScale = Vector3.Scale(new Vector3(Random.value, Random.value, Random.value), ScaleRandomizeUpper - ScaleRandomizeLower) + ScaleRandomizeLower; + + Vector3 position = BasePosition + new Vector3((float)i * Spacing.x + UnitRandom.x, 0, (float)j * Spacing.y + UnitRandom.y); + if(InstanceOverSurface) { + Ray ray = new Ray(position, new Vector3(0,-1,0)); + RaycastHit hit = new RaycastHit(); + if (Physics.Raycast(ray, out hit, 1000.0f)) { + TempOBJ.transform.position = hit.point; + TempOBJ.transform.eulerAngles = Quaternion.FromToRotation(Vector3.up, hit.normal).eulerAngles; + } + } else { + TempOBJ.transform.position = position; + + } + TempOBJ.transform.eulerAngles += Vector3.Scale(new Vector3(Random.value * 2.0f - 1.0f, Random.value * 2.0f - 1.0f, Random.value * 2.0f - 1.0f), RotationRandomizeUpper - RotationRandomizeLower) + RotationRandomizeLower; + TempOBJ.transform.localScale = Vector3.Scale(new Vector3(Random.value, Random.value, Random.value), ScaleRandomizeUpper - ScaleRandomizeLower) + ScaleRandomizeLower; + } } } @@ -43,12 +57,31 @@ public void CreateInstancesARRAY() { public void OnDrawGizmos() { Random.InitState(Seed); Vector3 BasePosition = this.transform.position; + Matrix4x4 PrevMat = Gizmos.matrix; + Quaternion TempQuant = new Quaternion(); for(int i = 0; i < Resolution.x; i++) { for(int j = 0; j < Resolution.y; j++) { Vector2 UnitRandom = Random.insideUnitCircle * DiskRadiusPositionRandomize; - Gizmos.DrawCube(BasePosition + new Vector3((float)i * Spacing.x + UnitRandom.x, 0, (float)j * Spacing.y + UnitRandom.y), Vector3.Scale(new Vector3(Random.value, Random.value, Random.value), ScaleRandomizeUpper - ScaleRandomizeLower) + ScaleRandomizeLower); + Vector3 position = BasePosition + new Vector3((float)i * Spacing.x + UnitRandom.x, 0, (float)j * Spacing.y + UnitRandom.y); + if(InstanceOverSurface) { + Ray ray = new Ray(position, new Vector3(0,-1,0)); + RaycastHit hit = new RaycastHit(); + if (Physics.Raycast(ray, out hit, 1000.0f)) { + Gizmos.matrix = PrevMat; + Gizmos.DrawLine(hit.point, position); + TempQuant = Quaternion.FromToRotation(transform.up, hit.normal); + } + TempQuant.eulerAngles = TempQuant.eulerAngles + Vector3.Scale(new Vector3(Random.value * 2.0f - 1.0f, Random.value * 2.0f - 1.0f, Random.value * 2.0f - 1.0f), RotationRandomizeUpper - RotationRandomizeLower) + RotationRandomizeLower; + Gizmos.matrix = Matrix4x4.TRS(hit.point, TempQuant, Vector3.one); + Gizmos.DrawCube(Vector3.zero, Vector3.Scale(new Vector3(Random.value, Random.value, Random.value), ScaleRandomizeUpper - ScaleRandomizeLower) + ScaleRandomizeLower); + } else { + TempQuant.eulerAngles = Quaternion.identity.eulerAngles + Vector3.Scale(new Vector3(Random.value * 2.0f - 1.0f, Random.value * 2.0f - 1.0f, Random.value * 2.0f - 1.0f), RotationRandomizeUpper - RotationRandomizeLower) + RotationRandomizeLower; + Gizmos.matrix = Matrix4x4.TRS(position, TempQuant, Vector3.one); + Gizmos.DrawCube(Vector3.zero, Vector3.Scale(new Vector3(Random.value, Random.value, Random.value), ScaleRandomizeUpper - ScaleRandomizeLower) + ScaleRandomizeLower); + } } } + Gizmos.matrix = PrevMat; } } @@ -159,6 +192,14 @@ public override VisualElement CreateInspectorGUI() SeedContainer.Add(SeedLabel); SeedContainer.Add(SeedField); + VisualElement IOSContainer = CreateHorizontalBox("IOS Container"); + Label IOSLabel = new Label("Instance Over Surface: "); + IOSLabel.style.width = 200; + Toggle IOSField = new Toggle() {value = t.InstanceOverSurface}; + IOSField.RegisterValueChangedCallback(evt => {t.InstanceOverSurface = evt.newValue;}); + IOSContainer.Add(IOSLabel); + IOSContainer.Add(IOSField); + RootElement.Add(InstanceToArrayButton); RootElement.Add(ObjectContainer); @@ -198,6 +239,7 @@ public override VisualElement CreateInspectorGUI() RootElement.Add(SpacerElement); } RootElement.Add(SeedContainer); + RootElement.Add(IOSContainer); return RootElement; } } diff --git a/TrueTrace/Resources/Utility/Atmosphere/AtmosphereGenerator.cs b/TrueTrace/Resources/Utility/Atmosphere/AtmosphereGenerator.cs index a5dbc385..edf9a09d 100644 --- a/TrueTrace/Resources/Utility/Atmosphere/AtmosphereGenerator.cs +++ b/TrueTrace/Resources/Utility/Atmosphere/AtmosphereGenerator.cs @@ -22,11 +22,20 @@ public class AtmosphereGenerator private RenderTexture DeltaMultiScatterTex; + + public RenderTexture CloudShapeTex; + public RenderTexture CloudShapeDetailTex; + public RenderTexture WeatherTex; + + private ComputeShader Atmosphere; private ComputeBuffer rayleigh_densityC; private ComputeBuffer mie_densityC; private ComputeBuffer absorption_densityC; + // public Texture2D CloudSampA; + // public Texture2D CloudSampB; + private int SkyViewKernel; public struct DensityProfileLayer @@ -44,6 +53,15 @@ public void AssignTextures(ComputeShader ThisShader, int Kernel) { ThisShader.SetTexture(Kernel, "IrradianceTex", IrradianceTex); } + public void Dispose() { + if(_TransmittanceLUT != null) _TransmittanceLUT.Release(); + if(MultiScatterTex != null) MultiScatterTex.Release(); + if(IrradianceTex != null) IrradianceTex.Release(); + if(CloudShapeTex != null) CloudShapeTex.Release(); + if(CloudShapeDetailTex != null) CloudShapeDetailTex.Release(); + if(WeatherTex != null) WeatherTex.Release(); + } + public AtmosphereGenerator(float BottomRadius, float TopRadius, int MultiScatterIterations) { if (Atmosphere == null) { Atmosphere = Resources.Load("Utility/Atmosphere/AtmosphereLUTGenerator"); } @@ -117,8 +135,9 @@ public AtmosphereGenerator(float BottomRadius, float TopRadius, int MultiScatter int IndirectIrradianceKernel = Atmosphere.FindKernel("IndirectIrradiance_Kernel"); int ScatteringDensityKernel = Atmosphere.FindKernel("ScatteringDensity_kernel"); int MultipleScatteringKernel = Atmosphere.FindKernel("MultiScatter_kernel"); - int FirstCloudKernel = Atmosphere.FindKernel("FirstCloudKernel"); - int SecondCloudKernel = Atmosphere.FindKernel("SecondCloudKernel"); + int CloudShapeKernel = Atmosphere.FindKernel("CloudShapeKernel"); + int CloudShapeDetailKernel = Atmosphere.FindKernel("CloudShapeDetailKernel"); + int WeatherKernel = Atmosphere.FindKernel("WeatherKernel"); CommonFunctions.CreateComputeBuffer(ref rayleigh_densityC, rayleigh_density); CommonFunctions.CreateComputeBuffer(ref mie_densityC, mie_density); @@ -256,6 +275,43 @@ public AtmosphereGenerator(float BottomRadius, float TopRadius, int MultiScatter ScatteringTex.Release(); DeltaScatteringTex.Release(); DeltaMultiScatterTex.Release(); + + +// CloudShapeTex = new RenderTexture(128, 128, 0, +// RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.sRGB); +// CloudShapeTex.volumeDepth = 128; +// CloudShapeTex.dimension = UnityEngine.Rendering.TextureDimension.Tex3D; +// CloudShapeTex.enableRandomWrite = true; +// CloudShapeTex.Create(); + +// CloudShapeDetailTex = new RenderTexture(32, 32, 0, +// RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.sRGB); +// CloudShapeDetailTex.volumeDepth = 32; +// CloudShapeDetailTex.dimension = UnityEngine.Rendering.TextureDimension.Tex3D; +// CloudShapeDetailTex.enableRandomWrite = true; +// CloudShapeDetailTex.Create(); + +// WeatherTex = new RenderTexture(512, 512, 0, +// RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.sRGB); +// WeatherTex.useMipMap = true; +// WeatherTex.autoGenerateMips = false; +// WeatherTex.enableRandomWrite = true; +// WeatherTex.Create(); + +// Atmosphere.SetTexture(CloudShapeKernel, "CloudShapeTex", CloudShapeTex); +// Atmosphere.Dispatch(CloudShapeKernel, 128, 128, 128); + +// Atmosphere.SetTexture(CloudShapeDetailKernel, "CloudShapeDetailTex", CloudShapeDetailTex); +// Atmosphere.Dispatch(CloudShapeDetailKernel, 32, 32, 32); + +// CloudSampA = Resources.Load("Utility/Atmosphere/GgAa20KbQAABHGm"); +// CloudSampB = Resources.Load("Utility/Atmosphere/GgAa3ZuaIAAjUL8"); +// Atmosphere.SetTexture(WeatherKernel, "WeatherTex", WeatherTex); +// Atmosphere.SetTexture(WeatherKernel, "CloudSampA", CloudSampA); +// Atmosphere.SetTexture(WeatherKernel, "CloudSampB", CloudSampB); +// Atmosphere.Dispatch(WeatherKernel, Mathf.CeilToInt(512.0f / 16.0f), Mathf.CeilToInt(512.0f / 16.0f), 1); + +// WeatherTex.GenerateMips(); } diff --git a/TrueTrace/Resources/Utility/Atmosphere/AtmosphereLUTGenerator.compute b/TrueTrace/Resources/Utility/Atmosphere/AtmosphereLUTGenerator.compute index 14db2225..25ff7f02 100644 --- a/TrueTrace/Resources/Utility/Atmosphere/AtmosphereLUTGenerator.compute +++ b/TrueTrace/Resources/Utility/Atmosphere/AtmosphereLUTGenerator.compute @@ -705,14 +705,14 @@ inline float3 ComputeMultipleScattering( for (int i = 0; i <= 50; ++i) { float d_i = float(i) * dx; - // The r, mu and mu_s parameters at the current integration point (see the + // The r, mu and mu_s parameters at the current integration thispoint (see the // single scattering section for a detailed explanation). float r_i = ClampRadius(sqrt(d_i * d_i + 2.0 * r * mu * d_i + r * r)); float mu_i = ClampCosine((r * mu + d_i) / r_i); float mu_s_i = ClampCosine((r * mu_s + d_i * nu) / r_i); - // The Rayleigh and Mie multiple scattering at the current sample point. + // The Rayleigh and Mie multiple scattering at the current sample thispoint. float3 rayleigh_mie_i = GetScattering2(ScatteringDensityTexRead, r_i, mu_i, mu_s_i, nu, @@ -754,175 +754,369 @@ void MultiScatter_kernel(uint3 id : SV_DispatchThreadID) -#pragma kernel FirstCloudKernel +#pragma kernel CloudShapeKernel +float inverseLerp(const float x, const float y, const float a) { + return (a - x) / (y - x); +} -RWTexture3D CloudTex1; +float2 inverseLerp(const float2 x, const float2 y, const float2 a) { + return (a - x) / (y - x); +} -#define UI0 1597334673U -#define UI1 3812015801U -#define UI2 uint2(UI0, UI1) -#define UI3 uint3(UI0, UI1, 2798796415U) -#define UIF (1.0 / float(0xffffffffU)) +float3 inverseLerp(const float3 x, const float3 y, const float3 a) { + return (a - x) / (y - x); +} -float3 mod(float3 x, float3 y) { - return x - y * floor(x / y); +float4 inverseLerp(const float4 x, const float4 y, const float4 a) { + return (a - x) / (y - x); } -float3 hash_33(float3 p) -{ - uint3 q = uint3(int3(p)) * UI3; - q = (q.x ^ q.y ^ q.z)*UI3; - return -1. + 2. * float3(q) * UIF; +float remap(const float x, const float min1, const float max1, const float min2, const float max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); } -float remap(float x, float a, float b, float c, float d) -{ - return (((x - a) / (b - a)) * (d - c)) + c; +float2 remap(const float2 x, const float2 min1, const float2 max1, const float2 min2, const float2 max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); } -// Gradient noise by iq (modified to be tileable) -float gradient_noise(float3 x, float freq) -{ - // grid - float3 p = floor(x); - float3 w = frac(x); - - // quintic interpolant - float3 u = w * w * w * (w * (w * 6. - 15.) + 10.); - - // gradients - float3 ga = hash_33(mod(p + float3(0., 0., 0.), freq)); - float3 gb = hash_33(mod(p + float3(1., 0., 0.), freq)); - float3 gc = hash_33(mod(p + float3(0., 1., 0.), freq)); - float3 gd = hash_33(mod(p + float3(1., 1., 0.), freq)); - float3 ge = hash_33(mod(p + float3(0., 0., 1.), freq)); - float3 gf = hash_33(mod(p + float3(1., 0., 1.), freq)); - float3 gg = hash_33(mod(p + float3(0., 1., 1.), freq)); - float3 gh = hash_33(mod(p + float3(1., 1., 1.), freq)); - - // projections - float va = dot(ga, w - float3(0., 0., 0.)); - float vb = dot(gb, w - float3(1., 0., 0.)); - float vc = dot(gc, w - float3(0., 1., 0.)); - float vd = dot(gd, w - float3(1., 1., 0.)); - float ve = dot(ge, w - float3(0., 0., 1.)); - float vf = dot(gf, w - float3(1., 0., 1.)); - float vg = dot(gg, w - float3(0., 1., 1.)); - float vh = dot(gh, w - float3(1., 1., 1.)); - - // interpolation - return va + - u.x * (vb - va) + - u.y * (vc - va) + - u.z * (ve - va) + - u.x * u.y * (va - vb - vc + vd) + - u.y * u.z * (va - vc - ve + vg) + - u.z * u.x * (va - vb - ve + vf) + - u.x * u.y * u.z * (-va + vb + vc - vd + ve - vf - vg + vh); -} - -int u_size; - -// Tileable 3D worley noise -float worley_noise(float3 uv, float freq) -{ - // uv *= u_size; - float3 id = floor(uv); - float3 p = frac(uv); - - float min_dist = 10000.; - for (float x = -1.; x <= 1.; ++x) - { - for(float y = -1.; y <= 1.; ++y) - { - for(float z = -1.; z <= 1.; ++z) - { - float3 offset = float3(x, y, z); - float3 h = hash_33(mod(id + offset, freq)) * .5 + .5; - h += offset; - float3 d = p - h; - min_dist = min(min_dist, dot(d, d)); - } - } - } - - // inverted worley noise - return 1. - min_dist; +float2 remap(const float2 x, const float min1, const float max1, const float min2, const float max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); } -// Fbm for Perlin noise based on iq's blog -float perlin_fbm(float3 p, float freq, int octaves) -{ - float G = exp2(-.85); - float amp = 1.; - float noise = 0.; - for (int i = 0; i < octaves; ++i) - { - noise += amp * gradient_noise(p * freq, freq); - freq *= 2.; - amp *= G; +float3 remap(const float3 x, const float3 min1, const float3 max1, const float3 min2, const float3 max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); +} + +float3 remap(const float3 x, const float min1, const float max1, const float min2, const float max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); +} + +float4 remap(const float4 x, const float4 min1, const float4 max1, const float4 min2, const float4 max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); +} + +float4 remap(const float4 x, const float min1, const float max1, const float min2, const float max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); +} + + + +RWTexture3D CloudShapeTex; + + +float4 mod289(const float4 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +float4 permute(const float4 v) { + return mod289((v * 34.0 + 1.0) * v); +} + +float4 taylorInvSqrt(const float4 r) { + return 1.79284291400159 - 0.85373472095314 * r; +} + +float4 fade(const float4 v) { + return v * v * v * (v * (v * 6.0 - 15.0) + 10.0); +} + +// Classic Perlin noise, periodic version +float perlin(const float4 position, const float4 rep) { + float4 Pi0 = fmod(floor(position), rep); // Integer part modulo rep + float4 Pi1 = fmod(Pi0 + 1.0, rep); // Integer part + 1 fmod rep + float4 Pf0 = frac(position); // Fractional part for interpolation + float4 Pf1 = Pf0 - 1.0; // Fractional part - 1.0 + float4 ix = float4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + float4 iy = float4(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + float4 iz0 = Pi0.z; + float4 iz1 = Pi1.z; + float4 iw0 = Pi0.w; + float4 iw1 = Pi1.w; + + float4 ixy = permute(permute(ix) + iy); + float4 ixy0 = permute(ixy + iz0); + float4 ixy1 = permute(ixy + iz1); + float4 ixy00 = permute(ixy0 + iw0); + float4 ixy01 = permute(ixy0 + iw1); + float4 ixy10 = permute(ixy1 + iw0); + float4 ixy11 = permute(ixy1 + iw1); + + float4 gx00 = ixy00 / 7.0; + float4 gy00 = floor(gx00) / 7.0; + float4 gz00 = floor(gy00) / 6.0; + gx00 = frac(gx00) - 0.5; + gy00 = frac(gy00) - 0.5; + gz00 = frac(gz00) - 0.5; + float4 gw00 = 0.75 - abs(gx00) - abs(gy00) - abs(gz00); + float4 sw00 = step(gw00, 0); + gx00 -= sw00 * (step(0.0, gx00) - 0.5); + gy00 -= sw00 * (step(0.0, gy00) - 0.5); + + float4 gx01 = ixy01 / 7.0; + float4 gy01 = floor(gx01) / 7.0; + float4 gz01 = floor(gy01) / 6.0; + gx01 = frac(gx01) - 0.5; + gy01 = frac(gy01) - 0.5; + gz01 = frac(gz01) - 0.5; + float4 gw01 = 0.75 - abs(gx01) - abs(gy01) - abs(gz01); + float4 sw01 = step(gw01, 0.0); + gx01 -= sw01 * (step(0.0, gx01) - 0.5); + gy01 -= sw01 * (step(0.0, gy01) - 0.5); + + float4 gx10 = ixy10 / 7.0; + float4 gy10 = floor(gx10) / 7.0; + float4 gz10 = floor(gy10) / 6.0; + gx10 = frac(gx10) - 0.5; + gy10 = frac(gy10) - 0.5; + gz10 = frac(gz10) - 0.5; + float4 gw10 = 0.75 - abs(gx10) - abs(gy10) - abs(gz10); + float4 sw10 = step(gw10, 0.0); + gx10 -= sw10 * (step(0.0, gx10) - 0.5); + gy10 -= sw10 * (step(0.0, gy10) - 0.5); + + float4 gx11 = ixy11 / 7.0; + float4 gy11 = floor(gx11) / 7.0; + float4 gz11 = floor(gy11) / 6.0; + gx11 = frac(gx11) - 0.5; + gy11 = frac(gy11) - 0.5; + gz11 = frac(gz11) - 0.5; + float4 gw11 = 0.75 - abs(gx11) - abs(gy11) - abs(gz11); + float4 sw11 = step(gw11, 0.0); + gx11 -= sw11 * (step(0.0, gx11) - 0.5); + gy11 -= sw11 * (step(0.0, gy11) - 0.5); + + float4 g0000 = float4(gx00.x, gy00.x, gz00.x, gw00.x); + float4 g1000 = float4(gx00.y, gy00.y, gz00.y, gw00.y); + float4 g0100 = float4(gx00.z, gy00.z, gz00.z, gw00.z); + float4 g1100 = float4(gx00.w, gy00.w, gz00.w, gw00.w); + float4 g0010 = float4(gx10.x, gy10.x, gz10.x, gw10.x); + float4 g1010 = float4(gx10.y, gy10.y, gz10.y, gw10.y); + float4 g0110 = float4(gx10.z, gy10.z, gz10.z, gw10.z); + float4 g1110 = float4(gx10.w, gy10.w, gz10.w, gw10.w); + float4 g0001 = float4(gx01.x, gy01.x, gz01.x, gw01.x); + float4 g1001 = float4(gx01.y, gy01.y, gz01.y, gw01.y); + float4 g0101 = float4(gx01.z, gy01.z, gz01.z, gw01.z); + float4 g1101 = float4(gx01.w, gy01.w, gz01.w, gw01.w); + float4 g0011 = float4(gx11.x, gy11.x, gz11.x, gw11.x); + float4 g1011 = float4(gx11.y, gy11.y, gz11.y, gw11.y); + float4 g0111 = float4(gx11.z, gy11.z, gz11.z, gw11.z); + float4 g1111 = float4(gx11.w, gy11.w, gz11.w, gw11.w); + + float4 norm00 = taylorInvSqrt( + float4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)) + ); + g0000 *= norm00.x; + g0100 *= norm00.y; + g1000 *= norm00.z; + g1100 *= norm00.w; + + float4 norm01 = taylorInvSqrt( + float4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)) + ); + g0001 *= norm01.x; + g0101 *= norm01.y; + g1001 *= norm01.z; + g1101 *= norm01.w; + + float4 norm10 = taylorInvSqrt( + float4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)) + ); + g0010 *= norm10.x; + g0110 *= norm10.y; + g1010 *= norm10.z; + g1110 *= norm10.w; + + float4 norm11 = taylorInvSqrt( + float4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)) + ); + g0011 *= norm11.x; + g0111 *= norm11.y; + g1011 *= norm11.z; + g1111 *= norm11.w; + + float n0000 = dot(g0000, Pf0); + float n1000 = dot(g1000, float4(Pf1.x, Pf0.y, Pf0.z, Pf0.w)); + float n0100 = dot(g0100, float4(Pf0.x, Pf1.y, Pf0.z, Pf0.w)); + float n1100 = dot(g1100, float4(Pf1.x, Pf1.y, Pf0.z, Pf0.w)); + float n0010 = dot(g0010, float4(Pf0.x, Pf0.y, Pf1.z, Pf0.w)); + float n1010 = dot(g1010, float4(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); + float n0110 = dot(g0110, float4(Pf0.x, Pf1.y, Pf1.z, Pf0.w)); + float n1110 = dot(g1110, float4(Pf1.x, Pf1.y, Pf1.z, Pf0.w)); + float n0001 = dot(g0001, float4(Pf0.x, Pf0.y, Pf0.z, Pf1.w)); + float n1001 = dot(g1001, float4(Pf1.x, Pf0.y, Pf0.z, Pf1.w)); + float n0101 = dot(g0101, float4(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); + float n1101 = dot(g1101, float4(Pf1.x, Pf1.y, Pf0.z, Pf1.w)); + float n0011 = dot(g0011, float4(Pf0.x, Pf0.y, Pf1.z, Pf1.w)); + float n1011 = dot(g1011, float4(Pf1.x, Pf0.y, Pf1.z, Pf1.w)); + float n0111 = dot(g0111, float4(Pf0.x, Pf1.y, Pf1.z, Pf1.w)); + float n1111 = dot(g1111, Pf1); + + float4 fade_xyzw = fade(Pf0); + float4 n_0w = lerp(float4(n0000, n1000, n0100, n1100), float4(n0001, n1001, n0101, n1101), fade_xyzw.w); + float4 n_1w = lerp(float4(n0010, n1010, n0110, n1110), float4(n0011, n1011, n0111, n1111), fade_xyzw.w); + float4 n_zw = lerp(n_0w, n_1w, fade_xyzw.z); + float2 n_yzw = lerp(n_zw.xy, n_zw.zw, fade_xyzw.y); + float n_xyzw = lerp(n_yzw.x, n_yzw.y, fade_xyzw.x); + return 2.2 * n_xyzw; +} + + + +float hash(const float n) { + return frac(sin(n + 1.951) * 43758.5453); +} + +float noise(const float3 x) { + float3 p = floor(x); + float3 f = frac(x); + + f = f * f * (3.0 - 2.0 * f); + float n = p.x + p.y * 57.0 + 113.0 * p.z; + return lerp( + lerp(lerp(hash(n + 0.0), hash(n + 1.0), f.x), lerp(hash(n + 57.0), hash(n + 58.0), f.x), f.y), + lerp( + lerp(hash(n + 113.0), hash(n + 114.0), f.x), + lerp(hash(n + 170.0), hash(n + 171.0), f.x), + f.y + ), + f.z + ); +} + +float getWorleyNoise(const float3 p, const float cellCount) { + float3 cell = p * cellCount; + float d = 1.0e10; + for (int x = -1; x <= 1; ++x) { + for (int y = -1; y <= 1; ++y) { + for (int z = -1; z <= 1; ++z) { + float3 tp = floor(cell) + float3(x, y, z); + tp = cell - tp - noise(fmod(tp, cellCount / 1.0)); + d = min(d, dot(tp, tp)); + } } - - return noise; + } + return clamp(d, 0.0, 1.0); } -// Tileable Worley fbm inspired by Andrew Schneider's Real-Time Volumetric Cloudscapes -// chapter in GPU Pro 7. -float worley_fbm(float3 p, float freq) -{ - return worley_noise(p*freq, freq) * .625; + - worley_noise(p*freq*2., freq*2.) * .25 + - worley_noise(p*freq*4., freq*4.) * .125; +float getPerlinNoise(const float3 thispoint, const float frequency, const int octaveCount) { + // Noise frequency factor between octave, forced to 2. + const float octaveFrequencyFactor = 2.0; + + // Compute the sum for each octave. + float sum = 0.0; + float roughness = 0.5; + float weightSum = 0.0; + float weight = 1.0; + float nextFrequency = frequency; + for (int i = 0; i < octaveCount; ++i) { + float4 p = float4(thispoint.x, thispoint.y, thispoint.z, 0.0) * nextFrequency; + float value = perlin(p, nextFrequency); + sum += value * weight; + weightSum += weight; + weight *= roughness; + nextFrequency *= octaveFrequencyFactor; + } + + float noise = sum / weightSum; + return clamp(noise, 0.0, 1.0); } + +float getPerlinWorley(const float3 thispoint) { + int octaveCount = 3; + float frequency = 8.0; + float perlin = getPerlinNoise(thispoint, frequency, octaveCount); + + float cellCount = 4.0; + float3 noise = float3( + 1.0 - getWorleyNoise(thispoint, cellCount * 2.0), + 1.0 - getWorleyNoise(thispoint, cellCount * 8.0), + 1.0 - getWorleyNoise(thispoint, cellCount * 14.0) + ); + float fbm = dot(noise, float3(0.625, 0.25, 0.125)); + return remap(perlin, 0.0, 1.0, fbm, 1.0); +} + +float getWorleyFbm(const float3 thispoint) { + float cellCount = 4.0; + float4 noise = float4( + 1.0 - getWorleyNoise(thispoint, cellCount * 2.0), + 1.0 - getWorleyNoise(thispoint, cellCount * 4.0), + 1.0 - getWorleyNoise(thispoint, cellCount * 8.0), + 1.0 - getWorleyNoise(thispoint, cellCount * 16.0) + ); + float3 fbm = float3( + dot(noise.xyz, float3(0.625, 0.25, 0.125)), + dot(noise.yzw, float3(0.625, 0.25, 0.125)), + dot(noise.zw, float2(0.75, 0.25)) + ); + return dot(fbm, float3(0.625, 0.25, 0.125)); +} + [numthreads(1, 1, 1)] -void FirstCloudKernel(uint3 id : SV_DispatchThreadID) +void CloudShapeKernel(uint3 id : SV_DispatchThreadID) { - float3 vUvs = id.xyz / (float)u_size; + float3 thispoint = float3(id.x, id.z, id.y) / 128.0f; + float perlinWorley = getPerlinWorley(thispoint); + float worleyFbm = getWorleyFbm(thispoint); + CloudShapeTex[id.xzy] = remap(perlinWorley, worleyFbm - 1.0, 1.0, 0.0, 1.0); - float perlin = lerp(1.0f, perlin_fbm(vUvs, 4.0f, 7), 0.5f); - perlin = abs(perlin * 2. - 1.); // billowy perlin noise - float freq = 4.0f; - float worley0 = worley_fbm(vUvs, freq * 2.0f); - float worley1 = worley_fbm(vUvs, freq * 4.0f); - float worley2 = worley_fbm(vUvs, freq * 8.0f); - // perlin = worley_fbm(vUvs, freq); - perlin = remap(perlin, 0.0f, 1.0f, worley0, 1.0f); // perlin-worley - // perlin *= 0.7f; - // perlin += 0.15f; - perlin *= 0.75f; - perlin += worley0 * 0.75f * 0.75f; - perlin += worley1 * pow(0.75f, 3); - perlin += worley2 * pow(0.75f, 4); - float4 cloud = float4(perlin, perlin, perlin, 1); +} - CloudTex1[id.xyz] = cloud; +#pragma kernel CloudShapeDetailKernel + +RWTexture3D CloudShapeDetailTex; + +[numthreads(1, 1, 1)] +void CloudShapeDetailKernel(uint3 id : SV_DispatchThreadID) +{ + float3 thispoint = float3(id.x, id.z, id.y) / 32.0f; + float cellCount = 2.0; + float4 noise = float4( + 1.0 - getWorleyNoise(thispoint, cellCount * 1.0), + 1.0 - getWorleyNoise(thispoint, cellCount * 2.0), + 1.0 - getWorleyNoise(thispoint, cellCount * 4.0), + 1.0 - getWorleyNoise(thispoint, cellCount * 8.0) + ); + float3 fbm = float3( + dot(noise.xyz, float3(0.625, 0.25, 0.125)), + dot(noise.yzw, float3(0.625, 0.25, 0.125)), + dot(noise.zw, float2(0.75, 0.25)) + ); + CloudShapeDetailTex[id.xzy] = dot(fbm, float3(0.625, 0.25, 0.125)); } -#pragma kernel SecondCloudKernel -RWTexture3D CloudTex2; +#pragma kernel WeatherKernel -[numthreads(1, 1, 1)] -void SecondCloudKernel(uint3 id : SV_DispatchThreadID) +RWTexture2D WeatherTex; +Texture2D CloudSampA; +Texture2D CloudSampB; +[numthreads(16, 16, 1)] +void WeatherKernel(uint3 id : SV_DispatchThreadID) { - float3 vUvs = id.xyz / (float)u_size; - float freq = 8.0f; + float3 thispoint = float3(id.x, 1028, id.y) / 512.0f; + float cellCount = 2.0; + float4 noise = + float4( + 1.0f - getPerlinNoise(thispoint, cellCount * 1.0, 2), + 1.0f - getPerlinNoise(thispoint, cellCount * 2.0, 4), + getPerlinNoise(thispoint, cellCount * 0.5f, 8), + 1.0f - getPerlinNoise(thispoint, cellCount * 8.0, 12) + ); + float3 fbm = float3( + dot(noise.xyz, float3(0.625, 0.25, 0.125)), + dot(noise.yzw, float3(0.625, 0.25, 0.125)), + dot(noise.zw, float2(0.75, 0.25)) + ); + WeatherTex[id.xy] = float4(CloudSampA[id.xy].x, 0, CloudSampB[id.xy].x, 0);//float4(clamp((1.0f - abs(fbm)) * float3(0.3f, 1.0f, 1.0f),0,1), 1);//noise;//dot(fbm, float3(0.625, 0.25, 0.125)); - float worley0 = worley_fbm(vUvs, freq); - float worley1 = worley_fbm(vUvs, freq * 2.0f); - float worley2 = worley_fbm(vUvs, freq * 4.0f); - worley0 *= 0.5; - worley0 += worley1 * 0.25; - worley0 += worley2 * 0.13; - float4 worley = float4(worley0, worley0, worley0, 1.0f); - - CloudTex2[id] = worley; } + diff --git a/TrueTrace/Resources/Utility/Atmosphere/AtmosphereSampling.cginc b/TrueTrace/Resources/Utility/Atmosphere/AtmosphereSampling.cginc index a8dd3fd7..d3bece74 100644 --- a/TrueTrace/Resources/Utility/Atmosphere/AtmosphereSampling.cginc +++ b/TrueTrace/Resources/Utility/Atmosphere/AtmosphereSampling.cginc @@ -3,8 +3,8 @@ static uint ScatteringTexMUSize = 128; static uint ScatteringTexMUSSize = 32; static uint ScatteringTexNUSize = 8; -#define bottom_radius (6360 * 1000.0f) -#define top_radius (6420 * 1000.0f) +#define bottom_radius (636000.0f) +#define top_radius (642000.0f) static uint TransmittanceTexWidth = 256; static uint TransmittanceTexHeight = 64; @@ -345,4 +345,714 @@ float3 GetSkyTransmittance( return ray_r_mu_intersects_ground ? 0.0 : (GetTransmittanceToTopAtmosphereBoundary(r, mu)); -} \ No newline at end of file +} + + + +Texture3D CloudShapeDetailTex; +Texture3D CloudShapeTex; +Texture2D localWeatherTexture; +SamplerState my_linear_repeat_sampler; + +// Scattering parameters +#define albedo float3(0.98, 0.98, 0.98) +#define powderScale 0.8 +#define powderExponent 200 +#define scatterAnisotropy1 0.6 +#define scatterAnisotropy2 -0.3 +#define scatterAnisotropyMix 0.5 +#define skyIrradianceScale 0.1 + +// Raymarch to clouds +#define maxIterations 500 +#define initialStepSize 100 +#define maxStepSize 1000 +#define maxRayDistance 1.5e5 +#define minDensity 1e-5 +#define minTransmittance 1e-2 + +#define PI 3.14159265359 +#define PI2 6.28318530718 +#define PI_HALF 1.5707963267949 +#define RECIPROCAL_PI 0.31830988618 +#define RECIPROCAL_PI2 0.15915494 +#define LOG2 1.442695 +#define EPSILON 1e-6 + +#define maxLayerHeights float4(1200,0,8000,0) +#define minLayerHeights float4(600,0,6700,0) +#define weatherExponents float4(1,1,3,1) +#define localWeatherFrequency float2(200,150) +#define coverage 0.2 +#define coverageFilterWidths float4(0.6,0,0.5,0) +#define detailAmounts float4(1,0,0.3,0) +#define extinctionCoeffs (float4(0.3,0,0.005,0) * 1.02f) +#define shapeFrequency 0.0003 +#define MULTI_SCATTERING_OCTAVES 32 +#define ellipsoidCenter float3(0,0,0) +#define minHeight 0 +#define maxHeight 8000 +#define shapeDetailFrequency 0.007f +#define minStepSize 10 + +float inverseLerp(const float x, const float y, const float a) { + return (a - x) / (y - x); +} + +float2 inverseLerp(const float2 x, const float2 y, const float2 a) { + return (a - x) / (y - x); +} + +float3 inverseLerp(const float3 x, const float3 y, const float3 a) { + return (a - x) / (y - x); +} + +float4 inverseLerp(const float4 x, const float4 y, const float4 a) { + return (a - x) / (y - x); +} + +float remap(const float x, const float min1, const float max1, const float min2, const float max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); +} + +float2 remap(const float2 x, const float2 min1, const float2 max1, const float2 min2, const float2 max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); +} + +float2 remap(const float2 x, const float min1, const float max1, const float min2, const float max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); +} + +float3 remap(const float3 x, const float3 min1, const float3 max1, const float3 min2, const float3 max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); +} + +float3 remap(const float3 x, const float min1, const float max1, const float min2, const float max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); +} + +float4 remap(const float4 x, const float4 min1, const float4 max1, const float4 min2, const float4 max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); +} + +float4 remap(const float4 x, const float min1, const float max1, const float min2, const float max2) { + return min2 + (x - min1) / (max1 - min1) * (max2 - min2); +} + + +float raySphereFirstIntersection( + const float3 origin, + const float3 direction, + const float3 center, + const float radius +) { + float3 a = origin - center; + float b = 2.0 * dot(direction, a); + float c = dot(a, a) - radius * radius; + float discriminant = b * b - 4.0 * c; + return discriminant < 0.0 + ? -1.0 + : (-b - sqrt(discriminant)) * 0.5; +} + +void getRayNearFar( + const float3 viewPosition, + const float3 rayDirection, + out float rayNear, + out float rayFar +) { + rayNear = raySphereFirstIntersection( + viewPosition, + rayDirection, + ellipsoidCenter, + bottom_radius + maxLayerHeights.x + ); + if (rayNear < 0.0) { + return; + } + rayFar = raySphereFirstIntersection( + viewPosition, + rayDirection, + ellipsoidCenter, + bottom_radius + minLayerHeights.x + ); +} + +float2 getGlobeUv(const float3 position) { + float2 st = normalize(position.yx); + float phi = atan(st.x / st.y); + float theta = asin(normalize(position).z); + return float2(phi * RECIPROCAL_PI2 + 0.5, theta * RECIPROCAL_PI + 0.5); +} + +// float getMipLevel(const float2 uv) { +// float2 coord = uv * resolution; +// float2 ddx = dFdx(coord); +// float2 ddy = dFdy(coord); +// return max(0.0, 0.5 * log2(max(dot(ddx, ddx), dot(ddy, ddy)))); +// } + +struct WeatherSample { + float4 heightFraction; // Normalized height of each layer + float4 density; +}; + +float4 shapeAlteringFunction(const float4 heightFraction, const float bias) { + // Apply a semi-circle transform to round the clouds towards the top. + float4 biased = pow(heightFraction, bias); + float4 x = clamp(biased * 2.0 - 1.0, -1.0, 1.0); + return 1.0 - x * x; +} + +WeatherSample sampleWeather(const float2 uv, const float height, const float mipLevel) { + WeatherSample weather; + weather.heightFraction = saturate( + remap(height, minLayerHeights, maxLayerHeights, 0.0, 1.0) + ); + + float4 localWeather = pow( + localWeatherTexture.SampleLevel(my_linear_repeat_sampler, uv * localWeatherFrequency + (curframe / 120000.0f), mipLevel), + weatherExponents + ); + float4 heightScale = shapeAlteringFunction(weather.heightFraction, 0.4); + + // Modulation to control weather by coverage parameter. + // Reference: https://github.com/Prograda/Skybolt/blob/master/Assets/Core/Shaders/Clouds.h#L63 + float4 factor = 1.0 - coverage * heightScale; + weather.density = saturate( + remap( + lerp(localWeather, 1.0, coverageFilterWidths), + factor, + factor + coverageFilterWidths, + 0.0, + 1.0 + ) + ); + + return weather; +} + +float sampleDensityDetail(WeatherSample weather, const float3 position, const float mipLevel) { + float4 density = weather.density; + if (mipLevel < 2.0) { + float shape = CloudShapeTex.SampleLevel(my_linear_repeat_sampler, position * shapeFrequency, 0.0).r; + // shape = pow(shape, 6.0) * 0.4; // Modulation for whippier shape + shape = 1.0 - shape; // Or invert for fluffy shape + density = lerp(density, saturate(remap(density, shape, 1.0, 0.0, 1.0)), detailAmounts); + + // #ifdef USE_DETAIL + if (mipLevel < 1.0) { + float detail = CloudShapeDetailTex.SampleLevel(my_linear_repeat_sampler, position * shapeDetailFrequency, 0.0).r; + // Fluffy at the top and whippy at the bottom. + float4 modifier = lerp( + pow(detail, 6.0), + 1.0 - detail, + saturate(remap(weather.heightFraction, 0.2, 0.4, 0.0, 1.0)) + ); + modifier = lerp(0.0, modifier, detailAmounts); + density = saturate( + remap(density * 2.0, modifier * 0.5, 1.0, 0.0, 1.0) + ); + } + // #endif + } + // Nicely decrease density at the bottom. + return saturate(dot(density, extinctionCoeffs * weather.heightFraction)); +} + + +float2 henyeyGreenstein(const float2 g, const float cosTheta) { + float2 g2 = g * g; + const float reciprocalPi4 = 0.07957747154594767; + return reciprocalPi4 * ((1.0 - g2) / pow(1.0 + g2 - 2.0 * g * cosTheta, 1.5)); +} + +float phaseFunction(const float cosTheta, const float attenuation) { + float2 g = float2(scatterAnisotropy1, scatterAnisotropy2); + float2 weights = float2(1.0 - scatterAnisotropyMix, scatterAnisotropyMix); + return dot(henyeyGreenstein(g * attenuation, cosTheta), weights); +} + +float sampleOpticalDepth( + const float3 rayOrigin, + const float3 rayDirection, + const int iterations, + const float mipLevel +) { + float stepSize = 40.0 / float(iterations); + float opticalDepth = 0.0; + float stepScale = 1.0; + float prevStepScale = 0.0; + for (int i = 0; i < iterations; ++i) { + float3 position = rayOrigin + rayDirection * stepScale * stepSize; + float2 uv = getGlobeUv(position); + float height = length(position) - bottom_radius; + WeatherSample weather = sampleWeather(uv, height, mipLevel); + float density = sampleDensityDetail(weather, position, mipLevel); + opticalDepth += density * (stepScale - prevStepScale) * stepSize; + prevStepScale = stepScale; + stepScale *= 2.0; + } + return opticalDepth; +} + +float multipleScattering(const float opticalDepth, const float cosTheta) { + // Multiple scattering approximation + // See: https://fpsunflower.github.io/ckulla/data/oz_volumes.pdf + // Attenuation (a), contribution (b) and phase attenuation (c). + float3 abc = 1.0; + const float3 attenuation = float3(0.5, 0.5, 0.8); // Should satisfy a <= b + float scattering = 0.0; + [loop]for (int octave = 0; octave < MULTI_SCATTERING_OCTAVES; ++octave) { + float beerLambert = exp(-opticalDepth * abc.y); + // A similar approximation is described in the Frostbite's paper, where + // phase angle is attenuated. + scattering += abc.x * beerLambert * phaseFunction(cosTheta, abc.z); + abc *= attenuation; + } + return scattering; +} +float raySphereSecondIntersection( + const float3 origin, + const float3 direction, + const float3 center, + const float radius +) { + float3 a = origin - center; + float b = 2.0 * dot(direction, a); + float c = dot(a, a) - radius * radius; + float discriminant = b * b - 4.0 * c; + return discriminant < 0.0 + ? -1.0 + : (-b + sqrt(discriminant)) * 0.5; +} + + +void applyAerialPerspective(const float3 camera, const float3 thispoint, inout float4 color) { + float3 transmittance; + float3 inscatter = GetSkyRadianceToPoint( + CamPos+float3(0,bottom_radius,0), + thispoint+float3(0,bottom_radius,0), + SunDir, + transmittance + ); + color.rgb = lerp(color.rgb, inscatter, color.a); +} + +void swapIfBigger(inout float4 a, inout float4 b) { + if (a.w > b.w) { + float4 t = a; + a = b; + b = t; + } +} + + +float3 getPentagonalWeights(const float3 direction, const float3 v1, const float3 v2, const float3 v3) { + float d1 = dot(v1, direction); + float d2 = dot(v2, direction); + float d3 = dot(v3, direction); + float3 w = exp(float3(d1, d2, d3) * 40.0); + return w / (w.x + w.y + w.z); +} + + +void sortVertices(inout float3 a, inout float3 b, inout float3 c) { + const float3 base = float3(0.5, 0.5, 1.0); + float4 aw = float4(a, dot(a, base)); + float4 bw = float4(b, dot(b, base)); + float4 cw = float4(c, dot(c, base)); + swapIfBigger(aw, bw); + swapIfBigger(bw, cw); + swapIfBigger(aw, bw); + a = aw.xyz; + b = bw.xyz; + c = cw.xyz; +} + +void intersectStructuredPlanes( + const float3 normal, + const float3 rayOrigin, + const float3 rayDirection, + const float samplePeriod, + out float stepOffset, + out float stepSize +) { + float NoD = dot(rayDirection, normal); + stepSize = samplePeriod / abs(NoD); + + // Skips leftover bit to get from rayOrigin to first strata plane. + stepOffset = -fmod(dot(rayOrigin, normal), samplePeriod) / NoD; + + // fmod() gives different results depending on if the arg is negative or + // positive. This line makes it consistent, and ensures the first sample is in + // front of the viewer. + if (stepOffset < 0.0) { + stepOffset += stepSize; + } +} + +void getIcosahedralVertices(const float3 direction, out float3 v1, out float3 v2, out float3 v3) { + // Normalization scalers to fit dodecahedron to unit sphere. + const float a = 0.85065080835204; // phi / sqrt(2 + phi) + const float b = 0.5257311121191336; // 1 / sqrt(2 + phi) + + // Derive the vertices of icosahedron where triangle intersects the direction. + // See: https://www.ppsloan.org/publications/AmbientDice.pdf + const float kT = 0.6180339887498948; // 1 / phi + const float kT2 = 0.38196601125010515; // 1 / phi^2 + float3 absD = abs(direction); + float selector1 = dot(absD, float3(1.0, kT2, -kT)); + float selector2 = dot(absD, float3(-kT, 1.0, kT2)); + float selector3 = dot(absD, float3(kT2, -kT, 1.0)); + v1 = selector1 > 0.0 ? float3(a, b, 0.0) : float3(-b, 0.0, a); + v2 = selector2 > 0.0 ? float3(0.0, a, b) : float3(a, -b, 0.0); + v3 = selector3 > 0.0 ? float3(b, 0.0, a) : float3(0.0, a, -b); + float3 octantSign = sign(direction); + v1 *= octantSign; + v2 *= octantSign; + v3 *= octantSign; +} + + +float3 getStructureNormal( + const float3 direction, + const float jitter, + out float3 a, + out float3 b, + out float3 c, + out float3 weights +) { + getIcosahedralVertices(direction, a, b, c); + sortVertices(a, b, c); + weights = getPentagonalWeights(direction, a, b, c); + return jitter < weights.x + ? a + : jitter < weights.x + weights.y + ? b + : c; +} + +float3 getStructureNormal(const float3 direction, const float jitter) { + float3 a, b, c, weights; + return getStructureNormal(direction, jitter, a, b, c, weights); +} + + +float4 marchToCloudsShadow( + float3 rayOrigin, // Relative to the ellipsoid center + float3 rayDirection, + float frustumRadius, + float maxRayDistance2, + float jitter2 + ) { + // Setup structured volume sampling. + float3 normal = getStructureNormal(rayDirection, jitter2); + float rayDistance; + float stepSize; + intersectStructuredPlanes( + normal, + rayOrigin, + rayDirection, + clamp(maxRayDistance2 / float(maxIterations) * (frustumRadius * 1e-4), minStepSize, maxStepSize), + rayDistance, + stepSize + ); + + float extinctionSum = 0.0; + float maxOpticalDepth = 0.0; + float transmittanceIntegral = 1.0; + float weightedDistanceSum = 0.0; + float transmittanceSum = 0.0; + + int sampleCount = 0; + for (int i = 0; i < maxIterations; ++i) { + if (rayDistance > maxRayDistance2) { + break; // Termination + } + float3 position = rayOrigin + rayDirection * rayDistance; + + // Terminate the ray at the scene objects. + // if (intersectsSceneObjects(position)) { + // break; + // } + + // Sample a rough density. + float mipLevel = 0.0; // TODO + float height = length(position) - bottom_radius; + float2 uv = getGlobeUv(position); + WeatherSample weather = sampleWeather(uv, height, mipLevel); + + if (any(weather.density > minDensity)) { + // Sample a detailed density. + float density = sampleDensityDetail(weather, position, mipLevel); + if (density > minDensity) { + extinctionSum += density; + maxOpticalDepth += density * stepSize; + ++sampleCount; + + float transmittance = exp(-density * stepSize); + transmittanceIntegral *= transmittance; + + // Use the method of the Frostbite's 5.9.1 to obtain smooth front depth. + weightedDistanceSum += rayDistance * transmittanceIntegral; + transmittanceSum += transmittanceIntegral; + } + + // Take a shorter step because we've already hit the clouds. + // stepSize *= 1.005f; + if(height > 5000) stepSize = 1000.0f; + rayDistance += stepSize; + } else { + // Otherwise step longer in empty space. + // TODO + // stepSize *= 1.005f; + if(height > 5000) stepSize = 1000.0f; + rayDistance += stepSize; + } + + if (transmittanceIntegral <= minTransmittance) { + break; // Early termination + } + } + + float frontDepth = maxRayDistance2; + float distanceToEllipsoid = 0.0; + if (transmittanceSum > 0.0) { + frontDepth = weightedDistanceSum / transmittanceSum; + distanceToEllipsoid = raySphereFirstIntersection( + rayOrigin + rayDirection * frontDepth, + rayDirection, + 0.0, + bottom_radius + ); + } + float meanExtinction = sampleCount > 0 ? extinctionSum / float(sampleCount) : 0.0; + return float4(frontDepth, meanExtinction, maxOpticalDepth, distanceToEllipsoid); +} + + +float4 marchToClouds(const float3 rayOrigin, const float3 rayDirection, const float maxRayDistance2, + const float jitter, + const float3 jitterVector, + const float rayStartTexelsPerPixel, + const float3 sunDirection, + float3 sunIrradiance, + float3 skyIrradiance, + int pixel_index, + out float weightedMeanDepth +) { + float3 radianceIntegral = 0.0; + float transmittanceIntegral = 1.0; + float weightedDistanceSum = 0.0; + float transmittanceSum = 0.0; + + float stepSize = initialStepSize; + float rayDistance = stepSize * jitter; + float cosTheta = dot(sunDirection, rayDirection); + + for (int i = 0; i < maxIterations; ++i) { + if (rayDistance > maxRayDistance2) { + break; // Termination + } + float3 position = rayOrigin + rayDirection * rayDistance; + + // Sample a rough density. + float mipLevel = log2(max(1.0, rayStartTexelsPerPixel + rayDistance * 1e-5)); + float height = length(position) - bottom_radius; + float2 uv = getGlobeUv(position); + WeatherSample weather = sampleWeather(uv, height, mipLevel); + if(height > 5000) stepSize = 1000.0f; + + if (any(weather.density > minDensity)) { + // Sample a detailed density. + float density = sampleDensityDetail(weather, position, mipLevel); + if (density > minDensity) { + // #ifdef ACCURATE_ATMOSPHERIC_IRRADIANCE + sunIrradiance = GetSunAndSkyIrradiance( + position, + float3(0,1,0), + sunDirection, + skyIrradiance + ); + // #endif // ACCURATE_ATMOSPHERIC_IRRADIANCE + + // Distance to the top of the bottom layer along the sun direction. + // This matches the ray origin of BSM. + float distanceToTop = raySphereSecondIntersection( + position + ellipsoidCenter, + sunDirection, + ellipsoidCenter, + bottom_radius + maxLayerHeights.x + ); + + float rayNear; + float rayFar; + getRayNearFar(position, -SunDir, rayNear, rayFar); + // if (rayNear < 0.0) { + // discard; + // } + + // Obtain the optical depth at the position from BSM. + float3 shadow = marchToCloudsShadow(position, SunDir, 1222, rayFar - rayNear, random(377 + i, pixel_index).x); + float frontDepth = shadow.x; + float meanExtinction = shadow.y; + float maxOpticalDepth = shadow.z; + float shadowOpticalDepth = min( + maxOpticalDepth, + meanExtinction * max(0.0, distanceToTop - frontDepth) + ); + + float sunOpticalDepth = 0.0; + if (mipLevel < 0.5) { + sunOpticalDepth = sampleOpticalDepth(position, sunDirection, 2, mipLevel); + } else { + sunOpticalDepth = sampleOpticalDepth(position, sunDirection, 1, mipLevel); + } + float opticalDepth = sunOpticalDepth + shadowOpticalDepth; + float scattering = multipleScattering(opticalDepth, cosTheta); + float3 radiance = (6.0f * sunIrradiance * scattering + skyIrradiance * skyIrradianceScale) * density; + + // Fudge factor for the irradiance from ground. + if (mipLevel < 0.5) { + float groundOpticalDepth = sampleOpticalDepth( + position, + -normalize(position), + 2, + mipLevel + ); + radiance += radiance * exp(-groundOpticalDepth - (height - minHeight) * 0.01); + } + + // #ifdef USE_POWDER + radiance *= 1.0 - powderScale * exp(-density * powderExponent); + // #endif // USE_POWDER + + // Energy-conserving analytical integration of scattered light + // See 5.6.3 in https://media.contentapi.ea.com/content/dam/eacom/frostbite/files/s2016-pbs-frostbite-sky-clouds-new.pdf + float transmittance = exp(-density * stepSize); + float clampedDensity = max(density, 1e-7); + float3 scatteringIntegral = (radiance - radiance * transmittance) / clampedDensity; + radianceIntegral += transmittanceIntegral * scatteringIntegral; + transmittanceIntegral *= transmittance; + + // Aerial perspective affecting clouds + // See 5.9.1 in https://media.contentapi.ea.com/content/dam/eacom/frostbite/files/s2016-pbs-frostbite-sky-clouds-new.pdf + weightedDistanceSum += rayDistance * transmittanceIntegral; + transmittanceSum += transmittanceIntegral; + } + + // Take a shorter step because we've already hit the clouds. + stepSize *= 1.005; + rayDistance += min(stepSize, maxStepSize); + } else { + // Otherwise step longer in empty space. + // TODO: This produces some banding artifacts. + stepSize *= 1.005; + rayDistance += min(stepSize, maxStepSize);//, maxStepSize, min(1.0, mipLevel)); + } + + if (transmittanceIntegral <= minTransmittance) { + break; // Early termination + } + } + + // The final product of 5.9.1 and we'll evaluate this in aerial perspective. + weightedMeanDepth = transmittanceSum > 0.0 ? weightedDistanceSum / transmittanceSum : 0.0; + + return float4( + radianceIntegral, + saturate(remap(transmittanceIntegral, minTransmittance, 1.0, 1.0, 0.0)) + ); +} + + + + +void raySphereIntersections( + const float3 origin, + const float3 direction, + const float3 center, + const float radius, + out float intersection1, + out float intersection2 +) { + float3 a = origin - center; + float b = 2.0 * dot(direction, a); + float c = dot(a, a) - radius * radius; + float discriminant = b * b - 4.0 * c; + if (discriminant < 0.0) { + intersection1 = -1.0; + intersection2 = -1.0; + return; + } else { + float Q = sqrt(discriminant); + intersection1 = (-b - Q) * 0.5; + intersection2 = (-b + Q) * 0.5; + } +} + +void getRayNearFar(const float3 rayDirection, out float rayNear, out float rayFar) { + bool intersectsGround = + raySphereFirstIntersection(CamPos, rayDirection, ellipsoidCenter, bottom_radius) >= 0.0; + + if (CamPos.y < minHeight) { + if (intersectsGround) { + rayNear = -1.0; + return; + } + rayNear = raySphereSecondIntersection( + CamPos, + rayDirection, + ellipsoidCenter, + bottom_radius + minHeight + ); + rayFar = raySphereSecondIntersection( + CamPos, + rayDirection, + ellipsoidCenter, + bottom_radius + maxHeight + ); + rayFar = min(rayFar, maxRayDistance); + } else if (CamPos.y < maxHeight) { + rayNear = 0.0; + if (intersectsGround) { + rayFar = raySphereFirstIntersection( + CamPos, + rayDirection, + ellipsoidCenter, + bottom_radius + minHeight + ); + } else { + rayFar = raySphereSecondIntersection( + CamPos, + rayDirection, + ellipsoidCenter, + bottom_radius + maxHeight + ); + } + } else { + float intersection1; + float intersection2; + raySphereIntersections( + CamPos, + rayDirection, + ellipsoidCenter, + bottom_radius + maxHeight, + intersection1, + intersection2 + ); + rayNear = intersection1; + if (intersectsGround) { + rayFar = raySphereFirstIntersection( + CamPos, + rayDirection, + ellipsoidCenter, + bottom_radius + minHeight + ); + } else { + rayFar = intersection2; + } + } +} + diff --git a/TrueTrace/Resources/Utility/BVHRefitter.compute b/TrueTrace/Resources/Utility/BVHRefitter.compute index ac13ec4d..770b7372 100644 --- a/TrueTrace/Resources/Utility/BVHRefitter.compute +++ b/TrueTrace/Resources/Utility/BVHRefitter.compute @@ -466,14 +466,38 @@ inline float SGIntegral(const float sharpness) } +float VMFAxisLengthToSharpness(float axisLength) +{ + return axisLength * (3.0f - axisLength * axisLength) / (1.0f - axisLength * axisLength); +} + +// Inverse of VMFAxisLengthToSharpness. +float VMFSharpnessToAxisLength(float sharpness) +{ + // Solve x^3 - sx^2 - 3x + s = 0, where s = sharpness. + // For x in [0, 1] and s in [0, infty), this equation has only a single solution. + // [Xu and Wang 2015 "Realtime Rendering Glossy to Glossy Reflections in Screen Space"] + // We solve this cubic equation in a numerically stable manner. + // [Peters, C. 2016 "How to solve a cubic equation, revisited" https://momentsingraphics.de/CubicRoots.html] + float a = sharpness / 3.0f; + float b = a * a * a; + float c = sqrt(1.0f + 3.0f * (a * a) * (1.0f + a * a)); + float theta = atan2(c, b) / 3.0f; + float d = -2.0f * sin(3.14159f / 6.0f - theta); // = sin(theta) * sqrt(3) - cos(theta). + return (sharpness > 33554432.0f) ? 1.0f : sqrt(1.0f + a * a) * d + a; +} + + + inline GaussianTreeNode UnionSG(const GaussianTreeNode LeftNode, const GaussianTreeNode RightNode, int Left) { - + if(LeftNode.intensity == 0) return RightNode; + if(RightNode.intensity == 0) return LeftNode; float phi_left = LeftNode.intensity; float phi_right = RightNode.intensity; float w_left = phi_left / (phi_left + phi_right); float w_right = phi_right / (phi_left + phi_right); - float3 V = w_left * LeftNode.axis + w_right * RightNode.axis;//may be wrong, paper uses BAR_V(BAR_axis here), not just normalized V/axis + float3 V = w_left * LeftNode.axis * VMFSharpnessToAxisLength(LeftNode.sharpness) + w_right * RightNode.axis * VMFSharpnessToAxisLength(RightNode.sharpness);//may be wrong, paper uses BAR_V(BAR_axis here), not just normalized V/axis float3 mean = w_left * LeftNode.position + w_right * RightNode.position; float variance = w_left * LeftNode.variance + w_right * RightNode.variance + w_left * w_right * dot(LeftNode.position - RightNode.position, LeftNode.position - RightNode.position); @@ -482,8 +506,11 @@ inline GaussianTreeNode UnionSG(const GaussianTreeNode LeftNode, const GaussianT float radius = max(distance(mean, LeftNode.position) + LeftNode.radius, distance(mean, RightNode.position) + RightNode.radius); - float VLength = length(V); - float sharpness = ((3.0f * VLength - VLength * VLength * VLength)) / (1.0f - VLength * VLength); + + float AxisLength = length(V); + if(AxisLength == 0) V = float3(0,1,0); + else V /= AxisLength; + float sharpness = min(VMFAxisLengthToSharpness(saturate(AxisLength)), 2199023255552.0f);// ((3.0f * Distance(Vector3.zero, V) - Mathf.Pow(Distance(Vector3.zero, V), 3))) / (1.0f - Mathf.Pow(Distance(Vector3.zero, V), 2)); GaussianTreeNode Dat = {mean, radius, V, variance, sharpness, intensity, Left}; @@ -527,10 +554,9 @@ void TLASSGTreeRefitKernel (uint3 id : SV_DispatchThreadID) float Scale = length(center - ExtendedCenter) / SGTreeWrite[Transf.SolidOffset].radius; SGTreeWrite[Index].position = center; + SGTreeWrite[Index].sharpness = min(VMFAxisLengthToSharpness(saturate(VMFSharpnessToAxisLength(SGTreeWrite[Transf.SolidOffset].sharpness) / Scale)), 2199023255552.0f);// ((3.0f * Distance(Vector3.zero, V) - Mathf.Pow(Distance(Vector3.zero, V), 3))) / (1.0f - Mathf.Pow(Distance(Vector3.zero, V), 2)); SGTreeWrite[Index].axis = axis; - SGTreeWrite[Index].variance = SGTreeWrite[Transf.SolidOffset].variance * Scale; - SGTreeWrite[Index].sharpness = SGTreeWrite[Transf.SolidOffset].sharpness; - + SGTreeWrite[Index].variance = SGTreeWrite[Transf.SolidOffset].variance * Scale; SGTreeWrite[Index].radius = SGTreeWrite[Transf.SolidOffset].radius * Scale; SGTreeWrite[Index].intensity = SGTreeWrite[Transf.SolidOffset].intensity * Scale * Scale; @@ -615,12 +641,16 @@ void BLASSGTreeRefitKernel (uint3 id : SV_DispatchThreadID) float area = AreaOfTriangle(LightTri.pos0, LightTri.pos0 + LightTri.posedge1, LightTri.pos0 + LightTri.posedge2); - if(area == 0) area = 0.000000001f; + // if(area == 0) area = 0.000000001f; float intensity = LightTri.SourceEnergy * area; float3 V = 0.5f * normalize(cross(normalize(LightTri.posedge1), normalize(LightTri.posedge2))); float variance = (dot(LightTri.posedge1, LightTri.posedge1) + dot(LightTri.posedge2, LightTri.posedge2) - dot(LightTri.posedge1, LightTri.posedge2)) / 18.0f; - SGTreeWrite[Index].sharpness = ((3.0f * length(V) - pow(length(V), 3))) / (1.0f - pow(length(V), 2)); + float AxisLength = length(V); + if(AxisLength == 0) V = float3(0,1,0); + else V /= AxisLength; + SGTreeWrite[Index].sharpness = min(VMFAxisLengthToSharpness(saturate(AxisLength)), 2199023255552.0f);// ((3.0f * Distance(Vector3.zero, V) - Mathf.Pow(Distance(Vector3.zero, V), 3))) / (1.0f - Mathf.Pow(Distance(Vector3.zero, V), 2)); + SGTreeWrite[Index].position = mean; SGTreeWrite[Index].radius = radius; SGTreeWrite[Index].intensity = intensity; diff --git a/TrueTrace/Resources/Utility/DING.mp3 b/TrueTrace/Resources/Utility/DING.mp3 deleted file mode 100644 index f2843b06..00000000 Binary files a/TrueTrace/Resources/Utility/DING.mp3 and /dev/null differ diff --git a/TrueTrace/Resources/Utility/DING.mp3.meta b/TrueTrace/Resources/Utility/DING.mp3.meta deleted file mode 100644 index 110d7030..00000000 --- a/TrueTrace/Resources/Utility/DING.mp3.meta +++ /dev/null @@ -1,22 +0,0 @@ -fileFormatVersion: 2 -guid: 2299c7cc904f5bd4fba933950ebf087b -AudioImporter: - externalObjects: {} - serializedVersion: 6 - defaultSettings: - loadType: 0 - sampleRateSetting: 0 - sampleRateOverride: 44100 - compressionFormat: 1 - quality: 1 - conversionMode: 0 - platformSettingOverrides: {} - forceToMono: 0 - normalize: 1 - preloadAudioData: 1 - loadInBackground: 0 - ambisonic: 0 - 3D: 1 - userData: - assetBundleName: - assetBundleVariant: diff --git a/TrueTrace/Resources/Utility/MaterialMappings.xml b/TrueTrace/Resources/Utility/MaterialMappings.xml index 928314bc..851fbcd7 100644 --- a/TrueTrace/Resources/Utility/MaterialMappings.xml +++ b/TrueTrace/Resources/Utility/MaterialMappings.xml @@ -88,13 +88,18 @@ 3 _MetallicGlossMap + + 1 + 3 + _MainTex + _Metallic - _GlossMapScale + _Glossiness false false - false - null + true + _Color null null null @@ -503,6 +508,11 @@ -4 _MainTex + + 1 + 3 + _MainTex + null null @@ -8024,4 +8034,219 @@ null null + + Bakery/Standard Noise + + + 0 + -4 + _MainTex + + + 2 + -3 + _BumpMap + + + 4 + 0 + _MetallicGlossMap + + + 5 + 1 + _MetallicGlossMap + + + 1 + 3 + _MainTex + + + _Metallic + _Glossiness + false + false + true + _Color + null + null + null + null + + + Custom/waterBlocker + + + 0 + -4 + _MainTex + + + 1 + 3 + _MainTex + + + null + null + false + false + false + null + null + null + null + null + + + Bakery/Standard Dissolve + + + 0 + -4 + _MainTex + + + 2 + -3 + _BumpMap + + + 3 + -4 + _EmissionMap + + + 4 + 0 + _MetallicGlossMap + + + 5 + 1 + _MetallicGlossMap + + + 1 + 3 + _MainTex + + + _Metallic + _Glossiness + false + false + true + _Color + null + null + null + null + + + Hidden/Locked/.poiyomi/Poiyomi 7.3/• Poiyomi Toon •/39a6a26bfb4ee614f838615f87916b0b + + + 0 + -4 + _MainTex + + + 1 + 3 + _MainTex + + + null + null + false + false + false + null + null + null + null + null + + + Real Ivy/Flat leaves + + + 0 + -4 + _AlbedoTexture + + + 2 + -3 + _NormalTexture + + + 1 + 3 + _AlbedoTexture + + + null + null + false + true + false + _Color + null + null + null + null + + + Mobile/Particles/Alpha Blended + + + 0 + -4 + _MainTex + + + 1 + 3 + _MainTex + + + null + null + false + true + false + null + null + null + null + null + + + Legacy Shaders/Particles/Additive + + + 0 + -4 + _MainTex + + + 1 + 3 + _MainTex + + + null + null + false + true + false + null + null + null + null + null + \ No newline at end of file diff --git a/TrueTrace/Resources/Utility/MaterialPresets.xml b/TrueTrace/Resources/Utility/MaterialPresets.xml index cc6e79dc..2e3a8b4a 100644 --- a/TrueTrace/Resources/Utility/MaterialPresets.xml +++ b/TrueTrace/Resources/Utility/MaterialPresets.xml @@ -404,7 +404,7 @@ 0 COPYPASTEBUFFER - 0 + 2 1 1 @@ -429,21 +429,21 @@ 1 1 - 0.66 - 1.19 + 0 + 1 0 0 - 7.1 - 0.176 - 0.311 - 1 + 0 + 0 + 0 + 0 0 0 - 0 + 0.644 0 false 0.1 - 0.143 + 0 0.1 1 0 @@ -486,17 +486,17 @@ 0 1 - 041ccda934077fb4eb81e3b6e1d79e32 + fa7f0741e64958441a9929db34f801be null null null - null + fa7f0741e64958441a9929db34f801be null null null null null - .poiyomi/Poiyomi 8.0/Poiyomi Pro + Mobile/Particles/Alpha Blended @@ -1102,4 +1102,203 @@ + + Transparents + + + 0 + Leaf + 1 + + 1 + 1 + 1 + + + 1 + 1 + 1 + + + 0 + 1 + + + 0 + 1 + + 0 + + 1 + 1 + 1 + + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0.302 + 0 + false + 1.37 + 0 + 0.1 + 1 + 0 + 1 + 1 + 1 + + 1 + 1 + 1 + + 0 + + 1 + 1 + 0 + 0 + + + 1 + 1 + 0 + 0 + + + 1 + 1 + + 0 + 512 + false + 0 + 1 + 0 + + 1 + 1 + 0 + 0 + + 0 + 1 + b329662f3af831a419fb0ca394253b3e + null + null + null + b329662f3af831a419fb0ca394253b3e + null + null + null + null + null + Standard + + + 0 + LeafA + 1 + + 1 + 1 + 1 + + + 1 + 1 + 1 + + + 0 + 1 + + + 0 + 1 + + 0 + + 1 + 1 + 1 + + 0.18 + 1.51 + 0 + 0 + 2.7 + 0 + 0 + 0 + 0 + 1 + 0.622 + 0 + false + 0.58 + 0.235 + 0.1 + 1 + 0 + 1 + 1 + 1 + + 1 + 1 + 1 + + 0 + + 1 + 1 + 0 + 0 + + + 1 + 1 + 0 + 0 + + + 1 + 1 + + 0 + 512 + false + 0 + 1 + 0 + + 1 + 1 + 0 + 0 + + 0 + 1 + a13d0741ba1b57640b1b4b035043021f + null + null + null + a13d0741ba1b57640b1b4b035043021f + null + null + null + null + 67631cd853304ee45bfa2775f9c9fc9c + Real Ivy/Flat leaves + + + \ No newline at end of file diff --git a/TrueTrace/Resources/Utility/PanoramaDoer.cs b/TrueTrace/Resources/Utility/PanoramaDoer.cs deleted file mode 100644 index d165c75e..00000000 --- a/TrueTrace/Resources/Utility/PanoramaDoer.cs +++ /dev/null @@ -1,258 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using System.IO; -using System; - using UnityEngine.Profiling; -using System.Reflection; - -namespace TrueTrace { - public class PanoramaDoer : MonoBehaviour - { - public int Padding = 32; - float PaddingHalfValue = 0; - public bool DoPanorama = true; - RayTracingMaster RayMaster; - public Camera[] Cameras; - public float TimeBetweenSegments = 10f; - public int MaxSamples = 10000; - private int CurrentCamera = 0; - public Vector2Int FinalAtlasSize = new Vector2Int(10000, 5000); - private bool PrevPanorama = false; - private float waitedTime = 0; - public int HorizontalSegments = 10; - private int CurrentSegment = 0; - private Texture2D[] TexArray; - - Matrix4x4 CalcProj(Camera cam) { - float Aspect = FinalAtlasSize.x / (float)FinalAtlasSize.y; - float YFOV = 1.0f / Mathf.Tan(cam.fieldOfView / (2.0f * (360.0f / (2.0f * 3.14159f)))); - float XFOV = YFOV / Aspect; - Matrix4x4 TempProj = cam.projectionMatrix; - TempProj[0,0] = XFOV; - TempProj[1,1] = YFOV; - return TempProj; - } - int CurrentResIndex = 0; -void AddResolution(int width, int height, string label) - { - Type gameViewSize = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSize"); - Type gameViewSizes = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes"); - Type gameViewSizeType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType"); - Type generic = typeof(ScriptableSingleton<>).MakeGenericType(gameViewSizes); - MethodInfo getGroup = gameViewSizes.GetMethod("GetGroup"); - object instance = generic.GetProperty("instance").GetValue(null, null); - object group = getGroup.Invoke(instance, new object[] { (int)GameViewSizeGroupType.Standalone }); - Type[] types = new Type[] { gameViewSizeType, typeof(int), typeof(int), typeof(string)}; - ConstructorInfo constructorInfo = gameViewSize.GetConstructor(types); - object entry = constructorInfo.Invoke(new object[] { 1, width, height, label }); - MethodInfo addCustomSize = getGroup.ReturnType.GetMethod("AddCustomSize"); - addCustomSize.Invoke(group, new object[] { entry }); - } - - - void SetResolution(int index) - { - Type gameView = typeof(Editor).Assembly.GetType("UnityEditor.GameView"); - PropertyInfo selectedSizeIndex = gameView.GetProperty("selectedSizeIndex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - EditorWindow window = EditorWindow.GetWindow(gameView); - selectedSizeIndex.SetValue(window, index, null); - } - - int GetResolution() - { - Type gameView = typeof(Editor).Assembly.GetType("UnityEditor.GameView"); - PropertyInfo selectedSizeIndex = gameView.GetProperty("selectedSizeIndex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - EditorWindow window = EditorWindow.GetWindow(gameView); - return (int)selectedSizeIndex.GetValue(window); - } - - - void RemoveResolution(int index) - { - Type gameViewSizes = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes"); - Type generic = typeof(ScriptableSingleton<>).MakeGenericType(gameViewSizes); - MethodInfo getGroup = gameViewSizes.GetMethod("GetGroup"); - object instance = generic.GetProperty("instance").GetValue(null, null); - object group = getGroup.Invoke(instance, new object[] { (int)GameViewSizeGroupType.Standalone }); - MethodInfo removeCustomSize = getGroup.ReturnType.GetMethod("RemoveCustomSize"); - removeCustomSize.Invoke(group, new object[] { index }); - } - - int GetCount() - { - Type gameViewSizes = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes"); - Type generic = typeof(ScriptableSingleton<>).MakeGenericType(gameViewSizes); - MethodInfo getGroup = gameViewSizes.GetMethod("GetGroup"); - object instance = generic.GetProperty("instance").GetValue(null, null); - PropertyInfo currentGroupType = instance.GetType().GetProperty("currentGroupType"); - GameViewSizeGroupType groupType = (GameViewSizeGroupType)(int)currentGroupType.GetValue(instance, null); - object group = getGroup.Invoke(instance, new object[] { (int)groupType }); - MethodInfo getBuiltinCount = group.GetType().GetMethod("GetBuiltinCount"); - MethodInfo getCustomCount = group.GetType().GetMethod("GetCustomCount"); - return (int)getBuiltinCount.Invoke(group, null) + (int)getCustomCount.Invoke(group, null); - } - - public void Start() { - RayMaster = GameObject.Find("Scene").GetComponent(); - // HorizontalSegments = Mathf.CeilToInt(FinalAtlasSize.x / (float)Screen.width); - Application.runInBackground = true; - RayMaster.DoPanorama = false; - RayMaster.DoChainedImages = false; - CurrentResIndex = GetResolution(); - if(DoPanorama) { - AddResolution(Mathf.CeilToInt((float)FinalAtlasSize.x / (float)HorizontalSegments) + Padding, FinalAtlasSize.y, "TempPanoramaSize"); - SetResolution(GetCount() - 1); - } else { - AddResolution(Mathf.CeilToInt((float)FinalAtlasSize.x / (float)HorizontalSegments) + Padding, FinalAtlasSize.y, "TempPanoramaSize"); - SetResolution(GetCount() - 1); - } - Init(); - RayMaster.DoPanorama = DoPanorama; - RayMaster.DoChainedImages = true; - } - public void OnDisable() { - if(RayMaster.DoChainedImages) { - SetResolution(CurrentResIndex); - RemoveResolution(GetCount() - 1); - } - } - private void FinalizePanorama(Camera cam) { - Color[] FinalAtlasData = new Color[FinalAtlasSize.x * FinalAtlasSize.y]; - - for(int iter = 0; iter < HorizontalSegments; iter++) { - int width = TexArray[iter].width - Padding; - int height = TexArray[iter].height; - Color[] CurrentData = TexArray[iter].GetPixels(0); - int XOffset = iter * Mathf.CeilToInt((float)FinalAtlasSize.x / (float)HorizontalSegments); - // int YOffset = iter * Mathf.CeilToInt(5000.0f / 5000.0f); - for(int i = 0; i < width + Padding; i++) { - for(int j = 0; j < height; j++) { - int IndexChild = i + j * (width + Padding); - int IndexFinal = (i + XOffset - (Padding / 2)) + (j) * FinalAtlasSize.x; - if(i >= Padding / 2 && iter != HorizontalSegments - 1) FinalAtlasData[IndexFinal] = new Color(CurrentData[IndexChild].r, CurrentData[IndexChild].g, CurrentData[IndexChild].b, 1); - else if(iter != 0 && iter != HorizontalSegments - 1) { - float Ratio = 1; - if(i < Padding / 2) { - Ratio = 1.0f - ((float)i / (float)(Padding / 2)); - } - FinalAtlasData[IndexFinal] = new Color((FinalAtlasData[IndexFinal].r * Ratio + CurrentData[IndexChild].r * (1.0f - Ratio)), (FinalAtlasData[IndexFinal].g * Ratio + CurrentData[IndexChild].g * (1.0f - Ratio)), (FinalAtlasData[IndexFinal].b * (Ratio) + CurrentData[IndexChild].b * (1.0f - Ratio)), 1); - } else if(iter == HorizontalSegments - 1 && i < width + (Padding / 2)) { - FinalAtlasData[IndexFinal] = new Color(CurrentData[IndexChild].r, CurrentData[IndexChild].g, CurrentData[IndexChild].b, 1); - } - } - } - DestroyImmediate(TexArray[iter]); - } - Texture2D FinalAtlas = new Texture2D(FinalAtlasSize.x, FinalAtlasSize.y); - FinalAtlas.SetPixels(FinalAtlasData, 0); - FinalAtlas.Apply(); - - string SegmentNumber = ""; - string FilePath = ""; - int TempSeg = 1; - do { - SegmentNumber = ""; - FilePath = ""; - int TempTempSeg = TempSeg; - int[] NumSegments = new int[3]; - for(int i = 0; i < 3; i++) { - NumSegments[i] = ((TempTempSeg) % 10); - TempTempSeg /= 10; - } - for(int i = 0; i < 3; i++) { - SegmentNumber += NumSegments[2 - i]; - } - TempSeg++; - - FilePath = PlayerPrefs.GetString("ScreenShotPath") + "/" + UnityEngine.SceneManagement.SceneManager.GetActiveScene().name.Replace(" ", "") + "_" + RayTracingMaster._camera.name + "_" + SegmentNumber + ".png"; - } while(System.IO.File.Exists(FilePath)); - - - System.IO.File.WriteAllBytes(FilePath, FinalAtlas.EncodeToPNG()); - - // System.IO.File.WriteAllBytes(PlayerPrefs.GetString("PanoramaPath") + "/" + cam.gameObject.name + ".png", FinalAtlas.EncodeToPNG()); - } - public void Init() { - RayTracingMaster.SampleCount = 0; - RayMaster.FramesSinceStart = 0; - RayMaster._currentSample = 0; - TexArray = new Texture2D[HorizontalSegments]; - PrevPanorama = true; - CurrentCamera = 0; - if(Cameras == null || Cameras.Length == 0) { - Cameras = new Camera[1]; - if(RayTracingMaster._camera != null) - Cameras[0] = RayTracingMaster._camera; - } - if(!(Cameras == null || Cameras.Length == 0)) { - Cameras[0].gameObject.SetActive(true); - for(int i = 1; i < Cameras.Length; i++) Cameras[i].gameObject.SetActive(false); - Camera[] AllCameras = GameObject.FindObjectsOfType(); - for(int i = 0; i < AllCameras.Length; i++) { - if(!DoPanorama) { - Cameras[i].projectionMatrix = CalcProj(Cameras[i]); - } - if(!Cameras[0].Equals(AllCameras[i])) AllCameras[i].gameObject.SetActive(false); - - } - } - - } - - IEnumerator RecordFrame() - { - yield return new WaitForEndOfFrame(); - if(RayMaster.DoChainedImages && TexArray != null) { - if(PrevPanorama) { - PrevPanorama = false; - RayTracingMaster.SampleCount = 0; - RayMaster.FramesSinceStart = 0; - } - PaddingHalfValue = (Padding / 2.0f) / (float)FinalAtlasSize.x; - RayMaster.CurrentHorizonalPatch = new Vector2((float)CurrentSegment / (float)HorizontalSegments - PaddingHalfValue, (float)(CurrentSegment + 1) / (float)HorizontalSegments + PaddingHalfValue); - waitedTime += Time.deltaTime; - if (RayMaster.FramesSinceStart >= MaxSamples || waitedTime >= TimeBetweenSegments) { - waitedTime = 0; - if(!System.IO.Directory.Exists(Application.dataPath.Replace("/Assets", "") + "/TempPanoramas")) { - System.IO.Directory.CreateDirectory(Application.dataPath.Replace("/Assets", "") + "/TempPanoramas"); - } - ScreenCapture.CaptureScreenshot(Application.dataPath.Replace("/Assets", "") + "/TempPanoramas/" + CurrentSegment + ".png"); - TexArray[CurrentSegment] = ScreenCapture.CaptureScreenshotAsTexture(); - CurrentSegment++; - RayTracingMaster.SampleCount = 0; - RayMaster.FramesSinceStart = 0; - RayMaster._currentSample = 0; - PrevPanorama = true; - if(CurrentSegment == HorizontalSegments) { - CurrentSegment = 0; - waitedTime = 0; - FinalizePanorama(Cameras[CurrentCamera]); - CurrentCamera++; - if(CurrentCamera < Cameras.Length) { - Cameras[CurrentCamera - 1].gameObject.SetActive(false); - Cameras[CurrentCamera].gameObject.SetActive(true); - RayMaster.TossCamera(Cameras[CurrentCamera]); - } else { - RemoveResolution(GetCount() - 1); - RayMaster.DoPanorama = false; - RayMaster.DoChainedImages = false; - Application.runInBackground = false; - EditorApplication.isPlaying = false; - } - - } - } - } - } - public void LateUpdate() - { - RayMaster.DoPanorama = DoPanorama; - RayMaster.DoChainedImages = true; - StartCoroutine(RecordFrame()); - } - } -} -#endif \ No newline at end of file diff --git a/TrueTrace/Resources/Utility/PanoramaDoer.cs.meta b/TrueTrace/Resources/Utility/PanoramaDoer.cs.meta deleted file mode 100644 index 57c3c089..00000000 --- a/TrueTrace/Resources/Utility/PanoramaDoer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0c0a645c565400043a70a5ac2a4de0c1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/TrueTrace/Resources/Utility/RayCastMaterialSelector/RayCastKernels.compute b/TrueTrace/Resources/Utility/RayCastMaterialSelector/RayCastKernels.compute index 2886a01f..6d14081f 100644 --- a/TrueTrace/Resources/Utility/RayCastMaterialSelector/RayCastKernels.compute +++ b/TrueTrace/Resources/Utility/RayCastMaterialSelector/RayCastKernels.compute @@ -29,7 +29,7 @@ void FinalizeKernel (uint3 id : SV_DispatchThreadID) RayHit bestHit = get2(GlobalRays[0].hits); #ifdef HardwareRT if(bestHit.mesh_id != 9999999) { - int2 Indexes = int2(bestHit.mesh_id & 0x0000FFFF, bestHit.mesh_id >> 16); + int2 Indexes = int2(bestHit.mesh_id & 0x7FFFFFF, bestHit.mesh_id >> 27); int triangleOffset = SubMeshOffsets[MeshOffsets[Indexes.x].x + Indexes.y]; bestHit.triangle_id += triangleOffset; bestHit.mesh_id = MeshOffsets[Indexes.x].y; diff --git a/TrueTrace/Resources/Utility/TTAdvancedImageGen.cs b/TrueTrace/Resources/Utility/TTAdvancedImageGen.cs new file mode 100644 index 00000000..f6aa3e5a --- /dev/null +++ b/TrueTrace/Resources/Utility/TTAdvancedImageGen.cs @@ -0,0 +1,712 @@ +#if UNITY_EDITOR +using System.Collections; +using System.Collections.Generic; +using System; +using UnityEngine; +using UnityEditor; +using System.Reflection; + +namespace TrueTrace { + [System.Serializable] + public class TTAdvancedImageGen : MonoBehaviour + { + public enum ImageGenType {NULL, Panorama, LargeScreenShot, TurnTable, TimedScreenShot}; + [SerializeField] public ImageGenType SelectedFunctionality = ImageGenType.NULL; + private int CurrentResIndex; + private TTSettings InitialSettings; + [SerializeField] public int SamplesBetweenShots = 1000; + [SerializeField] public bool ResetSampCountAfterShot = false; + [Serializable] + public class CameraListData { + public Camera TargCam; + public TTSettings CamSettings; + } + [SerializeField] public List CameraList; + + [Serializable] + public class TurnTableData { + private int CurrentSegment = 0; + private int CurrentCamera = 0; + private float waitedTime = 0; + private bool PrevImage = false; + public bool Running = false; + public List CameraList; + [System.Serializable] + public struct CamData { + public float TimeBetweenSegments; + public int MaxSamples; + public int HorizontalResolution; + public Vector3 Center; + public float Distance; + [Range(-89.9f, 89.9f)]public float Pitch; + } + public List CamSettings; + public TurnTableData(ref List CamList) { + CamSettings = new List(); + CameraList = CamList; + } + public void SetInitialSettings(List CamList) { + CameraList = CamList; + TTInterface.SetTTSettings(CameraList[0].CamSettings); + } + public IEnumerator RecordFrame() + { + yield return new WaitForEndOfFrame(); + if(PrevImage) { + PrevImage = false; + RayTracingMaster.SampleCount = 0; + RayTracingMaster.RayMaster.FramesSinceStart = 0; + } + waitedTime += Time.deltaTime; + if(!Running) { + Running = true; + } + if (RayTracingMaster.RayMaster.FramesSinceStart >= CamSettings[CurrentCamera].MaxSamples || waitedTime >= CamSettings[CurrentCamera].TimeBetweenSegments) { + waitedTime = 0; + string SegmentNumber = ""; + int TempSeg = CurrentSegment; + int[] NumSegments = new int[3]; + for(int i = 0; i < 3; i++) { + NumSegments[i] = ((TempSeg) % 10); + TempSeg /= 10; + } + for(int i = 0; i < 3; i++) { + SegmentNumber += NumSegments[2 - i]; + if(i < 2) { + SegmentNumber += "_"; + } + } + if(!System.IO.Directory.Exists(PlayerPrefs.GetString("TurnTablePath") + "/" + CameraList[CurrentCamera].TargCam.gameObject.name.Replace(" ", ""))) { + System.IO.Directory.CreateDirectory(PlayerPrefs.GetString("TurnTablePath") + "/" + CameraList[CurrentCamera].TargCam.gameObject.name.Replace(" ", "")); + } + ScreenCapture.CaptureScreenshot(PlayerPrefs.GetString("TurnTablePath") + "/" + CameraList[CurrentCamera].TargCam.gameObject.name.Replace(" ", "") + "/" + CameraList[CurrentCamera].TargCam.gameObject.name + "." + SegmentNumber + ".png"); + CurrentSegment++; + CameraList[CurrentCamera].TargCam.gameObject.transform.RotateAround(CamSettings[CurrentCamera].Center, Vector3.up, (360.0f / (float)CamSettings[CurrentCamera].HorizontalResolution)); + RayTracingMaster.SampleCount = 0; + RayTracingMaster.RayMaster.FramesSinceStart = 0; + RayTracingMaster.RayMaster._currentSample = 0; + PrevImage = true; + if(CurrentSegment == CamSettings[CurrentCamera].HorizontalResolution) { + CurrentSegment = 0; + waitedTime = 0; + CurrentCamera++; + if(CurrentCamera < CamSettings.Count) { + CameraList[CurrentCamera - 1].TargCam.gameObject.SetActive(false); + CameraList[CurrentCamera].TargCam.gameObject.SetActive(true); + RayTracingMaster.RayMaster.TossCamera(CameraList[CurrentCamera].TargCam); + TTInterface.SetTTSettings(CameraList[CurrentCamera].CamSettings); + } else { + Application.runInBackground = false; + EditorApplication.isPlaying = false; + } + + } + + } + } + + } + + [SerializeField] public TurnTableData TurnTableSettings; + + + [Serializable] + public class SlicedImageData { + public Vector2Int FinalAtlasSize; + public int Padding; + public float TimeBetweenSegments; + public int MaxSamples; + public int HorizontalSegments; + public Texture2D[] TexArray; + public bool PrevPanorama = false; + private float waitedTime = 0; + private int CurrentCamera = 0; + private int CurrentSegment = 0; + public List CameraList; + public SlicedImageData(ref List CamList) { + CameraList = CamList; + FinalAtlasSize = new Vector2Int(10000, 5000); + Padding = 32; + TimeBetweenSegments = 10f; + MaxSamples = 10000; + HorizontalSegments = 10; + } + + public IEnumerator RecordFrame() + { + yield return new WaitForEndOfFrame(); + if(TexArray != null) { + if(PrevPanorama) { + PrevPanorama = false; + RayTracingMaster.SampleCount = 0; + RayTracingMaster.RayMaster.FramesSinceStart = 0; + } + float PaddingHalfValue = (Padding / 2.0f) / (float)FinalAtlasSize.x; + RayTracingMaster.RayMaster.CurrentHorizonalPatch = new Vector2((float)CurrentSegment / (float)HorizontalSegments - PaddingHalfValue, (float)(CurrentSegment + 1) / (float)HorizontalSegments + PaddingHalfValue); + waitedTime += Time.deltaTime; + if (RayTracingMaster.RayMaster.FramesSinceStart >= MaxSamples || waitedTime >= TimeBetweenSegments) { + waitedTime = 0; + if(!System.IO.Directory.Exists(Application.dataPath.Replace("/Assets", "") + "/TempPanoramas")) { + System.IO.Directory.CreateDirectory(Application.dataPath.Replace("/Assets", "") + "/TempPanoramas"); + } + ScreenCapture.CaptureScreenshot(Application.dataPath.Replace("/Assets", "") + "/TempPanoramas/" + CurrentSegment + ".png"); + TexArray[CurrentSegment] = ScreenCapture.CaptureScreenshotAsTexture(); + CurrentSegment++; + RayTracingMaster.SampleCount = 0; + RayTracingMaster.RayMaster.FramesSinceStart = 0; + RayTracingMaster.RayMaster._currentSample = 0; + PrevPanorama = true; + if(CurrentSegment == HorizontalSegments) { + CurrentSegment = 0; + waitedTime = 0; + StitchSlices(CameraList[CurrentCamera].TargCam); + CurrentCamera++; + if(CurrentCamera < CameraList.Count) { + CameraList[CurrentCamera - 1].TargCam.gameObject.SetActive(false); + CameraList[CurrentCamera].TargCam.gameObject.SetActive(true); + RayTracingMaster.RayMaster.TossCamera(CameraList[CurrentCamera].TargCam); + TTInterface.SetTTSettings(CameraList[CurrentCamera].CamSettings); + } else { + // RemoveResolution(GetCount() - 1); + RayTracingMaster.RayMaster.DoPanorama = false; + RayTracingMaster.RayMaster.DoChainedImages = false; + Application.runInBackground = false; + EditorApplication.isPlaying = false; + } + + } + } + } + } + public void SetInitialSettings(List CamList) { + CameraList = CamList; + TTInterface.SetTTSettings(CameraList[0].CamSettings); + } + public void StitchSlices(Camera cam) { + Color[] FinalAtlasData = new Color[FinalAtlasSize.x * FinalAtlasSize.y]; + + for(int iter = 0; iter < HorizontalSegments; iter++) { + int width = TexArray[iter].width - Padding; + int height = TexArray[iter].height; + Color[] CurrentData = TexArray[iter].GetPixels(0); + int XOffset = iter * Mathf.CeilToInt((float)FinalAtlasSize.x / (float)HorizontalSegments); + // int YOffset = iter * Mathf.CeilToInt(5000.0f / 5000.0f); + for(int i = 0; i < width + Padding; i++) { + for(int j = 0; j < height; j++) { + int IndexChild = i + j * (width + Padding); + int IndexFinal = (i + XOffset - (Padding / 2)) + (j) * FinalAtlasSize.x; + if(i >= Padding / 2 && iter != HorizontalSegments - 1) FinalAtlasData[IndexFinal] = new Color(CurrentData[IndexChild].r, CurrentData[IndexChild].g, CurrentData[IndexChild].b, 1); + else if(iter != 0 && iter != HorizontalSegments - 1) { + float Ratio = 1; + if(i < Padding / 2) { + Ratio = 1.0f - ((float)i / (float)(Padding / 2)); + } + FinalAtlasData[IndexFinal] = new Color((FinalAtlasData[IndexFinal].r * Ratio + CurrentData[IndexChild].r * (1.0f - Ratio)), (FinalAtlasData[IndexFinal].g * Ratio + CurrentData[IndexChild].g * (1.0f - Ratio)), (FinalAtlasData[IndexFinal].b * (Ratio) + CurrentData[IndexChild].b * (1.0f - Ratio)), 1); + } else if(iter == HorizontalSegments - 1 && i < width + (Padding / 2)) { + FinalAtlasData[IndexFinal] = new Color(CurrentData[IndexChild].r, CurrentData[IndexChild].g, CurrentData[IndexChild].b, 1); + } + } + } + DestroyImmediate(TexArray[iter]); + } + Texture2D FinalAtlas = new Texture2D(FinalAtlasSize.x, FinalAtlasSize.y); + FinalAtlas.SetPixels(FinalAtlasData, 0); + FinalAtlas.Apply(); + + string SegmentNumber = ""; + string FilePath = ""; + int TempSeg = 1; + do { + SegmentNumber = ""; + FilePath = ""; + int TempTempSeg = TempSeg; + int[] NumSegments = new int[3]; + for(int i = 0; i < 3; i++) { + NumSegments[i] = ((TempTempSeg) % 10); + TempTempSeg /= 10; + } + for(int i = 0; i < 3; i++) { + SegmentNumber += NumSegments[2 - i]; + } + TempSeg++; + + FilePath = PlayerPrefs.GetString("ScreenShotPath") + "/" + UnityEngine.SceneManagement.SceneManager.GetActiveScene().name.Replace(" ", "") + "_" + RayTracingMaster._camera.name + "_" + SegmentNumber + ".png"; + } while(System.IO.File.Exists(FilePath)); + + + System.IO.File.WriteAllBytes(FilePath, FinalAtlas.EncodeToPNG()); + + // System.IO.File.WriteAllBytes(PlayerPrefs.GetString("PanoramaPath") + "/" + cam.gameObject.name + ".png", FinalAtlas.EncodeToPNG()); + } + + } + [SerializeField] public SlicedImageData SlicedImageSettings; + + + Matrix4x4 CalcProj(Camera cam) { + float Aspect = SlicedImageSettings.FinalAtlasSize.x / (float)SlicedImageSettings.FinalAtlasSize.y; + float YFOV = 1.0f / Mathf.Tan(cam.fieldOfView / (2.0f * (360.0f / (2.0f * 3.14159f)))); + float XFOV = YFOV / Aspect; + Matrix4x4 TempProj = cam.projectionMatrix; + TempProj[0,0] = XFOV; + TempProj[1,1] = YFOV; + return TempProj; + } + + void AddResolution(int width, int height, string label) + { + Type gameViewSize = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSize"); + Type gameViewSizes = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes"); + Type gameViewSizeType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType"); + Type generic = typeof(ScriptableSingleton<>).MakeGenericType(gameViewSizes); + MethodInfo getGroup = gameViewSizes.GetMethod("GetGroup"); + object instance = generic.GetProperty("instance").GetValue(null, null); + object group = getGroup.Invoke(instance, new object[] { (int)GameViewSizeGroupType.Standalone }); + Type[] types = new Type[] { gameViewSizeType, typeof(int), typeof(int), typeof(string)}; + ConstructorInfo constructorInfo = gameViewSize.GetConstructor(types); + object entry = constructorInfo.Invoke(new object[] { 1, width, height, label }); + MethodInfo addCustomSize = getGroup.ReturnType.GetMethod("AddCustomSize"); + addCustomSize.Invoke(group, new object[] { entry }); + } + + + void SetResolution(int index) + { + Type gameView = typeof(Editor).Assembly.GetType("UnityEditor.GameView"); + PropertyInfo selectedSizeIndex = gameView.GetProperty("selectedSizeIndex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + EditorWindow window = EditorWindow.GetWindow(gameView); + selectedSizeIndex.SetValue(window, index, null); + } + + int GetResolution() + { + Type gameView = typeof(Editor).Assembly.GetType("UnityEditor.GameView"); + PropertyInfo selectedSizeIndex = gameView.GetProperty("selectedSizeIndex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + EditorWindow window = EditorWindow.GetWindow(gameView); + return (int)selectedSizeIndex.GetValue(window); + } + + + void RemoveResolution(int index) + { + Type gameViewSizes = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes"); + Type generic = typeof(ScriptableSingleton<>).MakeGenericType(gameViewSizes); + MethodInfo getGroup = gameViewSizes.GetMethod("GetGroup"); + object instance = generic.GetProperty("instance").GetValue(null, null); + object group = getGroup.Invoke(instance, new object[] { (int)GameViewSizeGroupType.Standalone }); + MethodInfo removeCustomSize = getGroup.ReturnType.GetMethod("RemoveCustomSize"); + removeCustomSize.Invoke(group, new object[] { index }); + } + + int GetCount() + { + Type gameViewSizes = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes"); + Type generic = typeof(ScriptableSingleton<>).MakeGenericType(gameViewSizes); + MethodInfo getGroup = gameViewSizes.GetMethod("GetGroup"); + object instance = generic.GetProperty("instance").GetValue(null, null); + PropertyInfo currentGroupType = instance.GetType().GetProperty("currentGroupType"); + GameViewSizeGroupType groupType = (GameViewSizeGroupType)(int)currentGroupType.GetValue(instance, null); + object group = getGroup.Invoke(instance, new object[] { (int)groupType }); + MethodInfo getBuiltinCount = group.GetType().GetMethod("GetBuiltinCount"); + MethodInfo getCustomCount = group.GetType().GetMethod("GetCustomCount"); + return (int)getBuiltinCount.Invoke(group, null) + (int)getCustomCount.Invoke(group, null); + } + + private void InitCameras() { + RayTracingMaster.SampleCount = 0; + RayTracingMaster.RayMaster.FramesSinceStart = 0; + RayTracingMaster.RayMaster._currentSample = 0; + // if(Cameras == null || Cameras.Length == 0) { + // Cameras = new Camera[1]; + // if(RayTracingMaster._camera != null) + // Cameras[0] = RayTracingMaster._camera; + // } + // if(/!(Cameras == null || Cameras.Length == 0)) { + Camera[] AllCameras = GameObject.FindObjectsOfType(); + for(int i = 0; i < AllCameras.Length; i++) { + if(SelectedFunctionality == ImageGenType.LargeScreenShot) { + AllCameras[i].projectionMatrix = CalcProj(AllCameras[i]); + } + AllCameras[i].gameObject.SetActive(false); + + } + CameraList[0].TargCam.gameObject.SetActive(true); + // } + } + + public void OnDisable() { + switch(SelectedFunctionality) { + default: + break; + case(ImageGenType.LargeScreenShot): + case(ImageGenType.Panorama): + SetResolution(CurrentResIndex); + RemoveResolution(GetCount() - 1); + break; + } + TTInterface.SetTTSettings(InitialSettings); + RayTracingMaster.ImageIsModified = false; + } + + public void Init() { + switch(SelectedFunctionality) { + default: + break; + case(ImageGenType.LargeScreenShot): + case(ImageGenType.Panorama): + SlicedImageSettings = new SlicedImageData(ref CameraList); + break; + case(ImageGenType.TurnTable): + TurnTableSettings = new TurnTableData(ref CameraList); + break; + } + } + bool HasStarted = false; + public void Start() { + InitialSettings = RayTracingMaster.RayMaster.LocalTTSettings; + InitCameras(); + switch(SelectedFunctionality) { + default: + break; + case(ImageGenType.Panorama): + Application.runInBackground = true; + RayTracingMaster.RayMaster.DoPanorama = true; + RayTracingMaster.RayMaster.DoChainedImages = true; + CurrentResIndex = GetResolution(); + AddResolution(Mathf.CeilToInt((float)SlicedImageSettings.FinalAtlasSize.x / (float)SlicedImageSettings.HorizontalSegments) + SlicedImageSettings.Padding, SlicedImageSettings.FinalAtlasSize.y, "TempPanoramaSize"); + SetResolution(GetCount() - 1); + SlicedImageSettings.TexArray = new Texture2D[SlicedImageSettings.HorizontalSegments]; + SlicedImageSettings.PrevPanorama = true; + SlicedImageSettings.CameraList = CameraList; + RayTracingMaster.ImageIsModified = true; + break; + case(ImageGenType.LargeScreenShot): + Application.runInBackground = true; + RayTracingMaster.RayMaster.DoPanorama = false; + RayTracingMaster.RayMaster.DoChainedImages = true; + CurrentResIndex = GetResolution(); + AddResolution(Mathf.CeilToInt((float)SlicedImageSettings.FinalAtlasSize.x / (float)SlicedImageSettings.HorizontalSegments) + SlicedImageSettings.Padding, SlicedImageSettings.FinalAtlasSize.y, "TempPanoramaSize"); + SetResolution(GetCount() - 1); + SlicedImageSettings.TexArray = new Texture2D[SlicedImageSettings.HorizontalSegments]; + SlicedImageSettings.PrevPanorama = true; + SlicedImageSettings.CameraList = CameraList; + RayTracingMaster.ImageIsModified = true; + break; + case(ImageGenType.TurnTable): + TurnTableSettings.CameraList = CameraList; + RayTracingMaster.ImageIsModified = true; + break; + } + } + + public void LateUpdate() { + switch(SelectedFunctionality) { + default: + break; + case(ImageGenType.LargeScreenShot): + case(ImageGenType.Panorama): + RayTracingMaster.RayMaster.DoPanorama = SelectedFunctionality == ImageGenType.Panorama; + RayTracingMaster.RayMaster.DoChainedImages = true; + if(!HasStarted) SlicedImageSettings.SetInitialSettings(CameraList); + StartCoroutine(SlicedImageSettings.RecordFrame()); + break; + case(ImageGenType.TurnTable): + if(!HasStarted) TurnTableSettings.SetInitialSettings(CameraList); + StartCoroutine(TurnTableSettings.RecordFrame()); + break; + case(ImageGenType.TimedScreenShot): + if(((RayTracingMaster.SampleCount % SamplesBetweenShots) == SamplesBetweenShots - 1 && !ResetSampCountAfterShot) || (RayTracingMaster.SampleCount >= SamplesBetweenShots && ResetSampCountAfterShot)) { + ScreenCapture.CaptureScreenshot(PlayerPrefs.GetString("ScreenShotPath") + "/" + System.DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ", " + RayTracingMaster.SampleCount + " Samples.png"); + UnityEditor.AssetDatabase.Refresh(); + if(ResetSampCountAfterShot) { + RayTracingMaster.SampleCount = 0; + RayTracingMaster.RayMaster.FramesSinceStart = 0; + } + } + break; + + } + HasStarted = true; + } + + + } + + + [CustomEditor(typeof(TTAdvancedImageGen))] + public class TTAdvancedImageGenEditor : Editor + { + // Custom in-scene UI for when ExampleScript + // component is selected. + float ttt = 0; + TTAdvancedImageGen t; + int SelectedCam = -1; + bool TurnTableShowAll = false; + + private void ConstructCameraList() { + if(t.CameraList == null) t.CameraList = new List(); + } + Vector2 scrollPosition; + private void DisplayCameraList() { + GUIStyle TempStyle = new GUIStyle(); + TempStyle.fixedWidth = 120; + scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(450), GUILayout.Height(100)); + for(int i = 0; i < t.CameraList.Count; i++) { + var A = i; + GUILayout.BeginHorizontal(); + if(t.SelectedFunctionality == TTAdvancedImageGen.ImageGenType.TurnTable) if(GUILayout.Button("Select", GUILayout.Width(50))) {SelectedCam = A;} + TTAdvancedImageGen.CameraListData TempDat = t.CameraList[i]; + TempDat.TargCam = EditorGUILayout.ObjectField(TempDat.TargCam, typeof(Camera), true, GUILayout.Width(150)) as Camera; + TempDat.CamSettings = EditorGUILayout.ObjectField(TempDat.CamSettings, typeof(TTSettings), true, GUILayout.Width(150)) as TTSettings; + t.CameraList[i] = TempDat; + if(GUILayout.Button("Delete", GUILayout.Width(50))) { + if(t.SelectedFunctionality == TTAdvancedImageGen.ImageGenType.TurnTable) { + t.TurnTableSettings.CamSettings.RemoveAt(A); + } + t.CameraList.RemoveAt(A); + i--; + } + GUILayout.EndHorizontal(); + } + GUILayout.EndScrollView(); + } + private void AddNewCam() { + Camera TempCam = null; + TTSettings TempSet = null; + if(t.CameraList.Count != 0) { + if(t.CameraList[t.CameraList.Count - 1].TargCam != null) TempCam = t.CameraList[t.CameraList.Count - 1].TargCam; + if(t.CameraList[t.CameraList.Count - 1].CamSettings != null) TempSet = t.CameraList[t.CameraList.Count - 1].CamSettings; + } + t.CameraList.Add(new TTAdvancedImageGen.CameraListData() { + TargCam = TempCam, + CamSettings = TempSet//RayTracingMaster.RayMaster.LocalTTSettings + }); + if(t.SelectedFunctionality == TTAdvancedImageGen.ImageGenType.TurnTable) { + t.TurnTableSettings.CamSettings.Add(new TTAdvancedImageGen.TurnTableData.CamData() { + HorizontalResolution = 10, + Center = Vector3.one, + Distance = 1.0f, + Pitch = 0.0f, + MaxSamples = 64, + TimeBetweenSegments = 10.0f + }); + } + } + private void DisplaySlicedSettings() { + GUILayout.BeginVertical(GUILayout.Width(345)); + GUILayout.BeginHorizontal(); + GUILayout.Label("Final Atlas Size: ", GUILayout.Width(145)); + GUILayout.Label("W:", GUILayout.Width(25)); + if(t.SelectedFunctionality == TTAdvancedImageGen.ImageGenType.Panorama) { + EditorGUI.BeginChangeCheck(); + t.SlicedImageSettings.FinalAtlasSize.x = EditorGUILayout.IntField(t.SlicedImageSettings.FinalAtlasSize.x, GUILayout.Width(100)); + if(EditorGUI.EndChangeCheck()) { + t.SlicedImageSettings.FinalAtlasSize.y = t.SlicedImageSettings.FinalAtlasSize.x / 2; + } + GUILayout.Label("H:", GUILayout.Width(20)); + EditorGUILayout.LabelField((t.SlicedImageSettings.FinalAtlasSize.x / 2).ToString(), GUILayout.Width(100)); + } else { + t.SlicedImageSettings.FinalAtlasSize.x = EditorGUILayout.IntField(t.SlicedImageSettings.FinalAtlasSize.x, GUILayout.Width(100)); + GUILayout.Label("H:", GUILayout.Width(20)); + t.SlicedImageSettings.FinalAtlasSize.y = EditorGUILayout.IntField(t.SlicedImageSettings.FinalAtlasSize.y, GUILayout.Width(100)); + } + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + GUILayout.Label("Maximum Time Per Slice: ", GUILayout.Width(175)); + t.SlicedImageSettings.TimeBetweenSegments = EditorGUILayout.FloatField(t.SlicedImageSettings.TimeBetweenSegments, GUILayout.Width(100)); + GUILayout.Label("s", GUILayout.Width(20)); + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + GUILayout.Label("Maximum Samples Per Slice: ", GUILayout.Width(175)); + t.SlicedImageSettings.MaxSamples = EditorGUILayout.IntField(t.SlicedImageSettings.MaxSamples, GUILayout.Width(100)); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + GUILayout.Label("Slice Padding: ", GUILayout.Width(175)); + t.SlicedImageSettings.Padding = EditorGUILayout.IntField(t.SlicedImageSettings.Padding, GUILayout.Width(100)); + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + GUILayout.Label("Slice Segments: ", GUILayout.Width(175)); + t.SlicedImageSettings.HorizontalSegments = EditorGUILayout.IntField(t.SlicedImageSettings.HorizontalSegments, GUILayout.Width(100)); + GUILayout.EndHorizontal(); + + EditorGUILayout.Space(); + GUILayout.BeginHorizontal(); + GUILayout.Label("Final Slice Size: ", GUILayout.Width(145)); + GUILayout.Label("W:", GUILayout.Width(25)); + EditorGUILayout.LabelField((Mathf.CeilToInt((float)t.SlicedImageSettings.FinalAtlasSize.x / (float)t.SlicedImageSettings.HorizontalSegments) + t.SlicedImageSettings.Padding).ToString(), GUILayout.Width(100)); + GUILayout.Label("H:", GUILayout.Width(20)); + EditorGUILayout.LabelField((t.SlicedImageSettings.FinalAtlasSize.y).ToString(), GUILayout.Width(100)); + GUILayout.EndHorizontal(); + + + GUILayout.EndVertical(); + } + + private void DisplayTurnTableSettings() { + GUILayout.BeginVertical(GUILayout.Width(345)); + if(SelectedCam != -1 && SelectedCam < t.TurnTableSettings.CamSettings.Count) { + TTAdvancedImageGen.TurnTableData.CamData TempDat = t.TurnTableSettings.CamSettings[SelectedCam]; + GUILayout.BeginHorizontal(); + GUILayout.Label("Camera " + SelectedCam, GUILayout.Width(175)); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + GUILayout.Label("Horizontal Resolution: ", GUILayout.Width(175)); + TempDat.HorizontalResolution = EditorGUILayout.IntField(TempDat.HorizontalResolution, GUILayout.Width(100)); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + GUILayout.Label("Center: ", GUILayout.Width(175)); + TempDat.Center = EditorGUILayout.Vector3Field("",TempDat.Center, GUILayout.Width(100)); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + GUILayout.Label("Distance: ", GUILayout.Width(175)); + TempDat.Distance = EditorGUILayout.FloatField(TempDat.Distance, GUILayout.Width(100)); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + GUILayout.Label("Pitch: ", GUILayout.Width(175)); + TempDat.Pitch = EditorGUILayout.FloatField(TempDat.Pitch, GUILayout.Width(100)); + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + GUILayout.Label("Maximum Time Per Turn: ", GUILayout.Width(175)); + TempDat.TimeBetweenSegments = EditorGUILayout.FloatField(TempDat.TimeBetweenSegments, GUILayout.Width(100)); + GUILayout.Label("s", GUILayout.Width(20)); + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + GUILayout.Label("Maximum Samples Per Turn: ", GUILayout.Width(175)); + TempDat.MaxSamples = EditorGUILayout.IntField(TempDat.MaxSamples, GUILayout.Width(100)); + GUILayout.EndHorizontal(); + t.TurnTableSettings.CamSettings[SelectedCam] = TempDat; + } else { + EditorGUILayout.Space(); + } + GUILayout.EndVertical(); + } + + public override void OnInspectorGUI() { + var t1 = (targets); + t = t1[0] as TTAdvancedImageGen; + if(t.SelectedFunctionality == TTAdvancedImageGen.ImageGenType.NULL) { + EditorGUI.BeginChangeCheck(); + t.SelectedFunctionality = (TTAdvancedImageGen.ImageGenType)EditorGUILayout.EnumPopup("Functionality: ", t.SelectedFunctionality); + if(EditorGUI.EndChangeCheck()) { + switch(t.SelectedFunctionality) { + default: + break; + case(TTAdvancedImageGen.ImageGenType.Panorama): + case(TTAdvancedImageGen.ImageGenType.LargeScreenShot): + case(TTAdvancedImageGen.ImageGenType.TurnTable): + ConstructCameraList(); + break; + case(TTAdvancedImageGen.ImageGenType.TimedScreenShot): + ConstructCameraList(); + AddNewCam(); + break; + } + t.Init(); + } + + } else { + GUILayout.Label("Selected Function: " + t.SelectedFunctionality.ToString()); + switch(t.SelectedFunctionality) { + default: + break; + case(TTAdvancedImageGen.ImageGenType.Panorama): + case(TTAdvancedImageGen.ImageGenType.LargeScreenShot): + if(GUILayout.Button("Add Camera")) AddNewCam(); + GUILayout.BeginHorizontal(); + DisplaySlicedSettings(); + DisplayCameraList(); + GUILayout.EndHorizontal(); + break; + case(TTAdvancedImageGen.ImageGenType.TurnTable): + if(GUILayout.Button("Add Camera")) AddNewCam(); + TurnTableShowAll = EditorGUILayout.ToggleLeft("Show All Sets", TurnTableShowAll, GUILayout.MaxWidth(135)); + t.TurnTableSettings.Running = EditorGUILayout.ToggleLeft("Running", t.TurnTableSettings.Running, GUILayout.MaxWidth(135)); + GUILayout.BeginHorizontal(); + DisplayTurnTableSettings(); + DisplayCameraList(); + GUILayout.EndHorizontal(); + break; + case(TTAdvancedImageGen.ImageGenType.TimedScreenShot): + GUILayout.BeginHorizontal(); + GUILayout.BeginVertical(GUILayout.Width(345)); + GUILayout.BeginHorizontal(); + GUILayout.Label("Samples Between Shots: ", GUILayout.Width(175)); + t.SamplesBetweenShots = EditorGUILayout.IntField(t.SamplesBetweenShots, GUILayout.Width(100)); + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + t.ResetSampCountAfterShot = EditorGUILayout.ToggleLeft("Reset Accumulation After Shot", t.ResetSampCountAfterShot, GUILayout.MaxWidth(135)); + GUILayout.EndHorizontal(); + GUILayout.EndVertical(); + DisplayCameraList(); + GUILayout.EndHorizontal(); + break; + } + } + } + + Vector3 GetTangent(float RadsAlong) { + return (new Vector3(Mathf.Sin(Mathf.Deg2Rad * RadsAlong), 0, Mathf.Cos(Mathf.Deg2Rad * RadsAlong))).normalized; + } + + Vector3 GetToVector(float Yaw, float Pitch) { + return new Vector3(Mathf.Cos(Mathf.Deg2Rad * Yaw) * Mathf.Cos(Mathf.Deg2Rad * Pitch), Mathf.Sin(Mathf.Deg2Rad * Pitch), Mathf.Sin(Mathf.Deg2Rad * Yaw) * Mathf.Cos(Mathf.Deg2Rad * Pitch)); + } + public void OnSceneGUI() + { + var t = target as TTAdvancedImageGen; + if(t.SelectedFunctionality == TTAdvancedImageGen.ImageGenType.TurnTable) { + var tr = t.transform; + var pos = tr.position; + float ArcLength = 5.0f; + if(!t.TurnTableSettings.Running) { + ttt += Time.deltaTime; + EditorGUI.BeginChangeCheck(); + if(t.TurnTableSettings.CamSettings != null) { + int StartIndex = 0; + int EndIndex = t.TurnTableSettings.CamSettings.Count; + if(!TurnTableShowAll) { + if(SelectedCam != -1 && SelectedCam < t.TurnTableSettings.CamSettings.Count) { + StartIndex = SelectedCam; + EndIndex = SelectedCam + 1; + } + } + for(int i = StartIndex; i < EndIndex; i++) { + if(t.CameraList[i].TargCam != null) { + TTAdvancedImageGen.TurnTableData.CamData TempVar = t.TurnTableSettings.CamSettings[i]; + TempVar.Center = Handles.PositionHandle(TempVar.Center, Quaternion.identity); + float yaw = 0; + + Vector3 Pos2 = TempVar.Center + GetToVector(yaw, TempVar.Pitch) * TempVar.Distance; + t.CameraList[i].TargCam.transform.position = Pos2; + + + int HorizSegments = TempVar.HorizontalResolution; + Vector3 Pos3 = new Vector3(TempVar.Center.x, Pos2.y, TempVar.Center.z); + // Handles.DrawLine(Pos2, Pos2 + GetTangent(yaw), 0.01f); + for(int i2 = 0; i2 < HorizSegments; i2++) { + Handles.DrawWireArc(Pos3, Vector3.up, GetTangent(90 + 360.0f / (float)HorizSegments * (float)i2 - (ArcLength / 2.0f)), ArcLength, Vector3.Distance(Pos3, Pos2)); + Vector3 ToVector = GetToVector(90 + 360.0f / (float)HorizSegments * (float)i2, TempVar.Pitch); + t.CameraList[i].TargCam.transform.forward = ToVector; + Vector3 Pos4 = TempVar.Center + ToVector * TempVar.Distance; + Handles.ConeHandleCap(0, Pos4 - ToVector * 0.15f, t.CameraList[i].TargCam.transform.rotation, 0.2f, EventType.Repaint); + Handles.DrawDottedLine(TempVar.Center, Pos4, 0.01f); + // Handles.ConeHandleCap(0, TempVar.Center - t.CameraList[i].TargCam.transform.forward * 0.1f, t.CameraList[i].TargCam.transform.rotation, 0.2f, EventType.Repaint); + } + + t.CameraList[i].TargCam.transform.forward = (TempVar.Center - Pos2).normalized; + t.TurnTableSettings.CamSettings[i] = TempVar; + } + } + } + if (EditorGUI.EndChangeCheck()) {} + } + } + } + } +} +#endif \ No newline at end of file diff --git a/TrueTrace/Resources/TTCPUDefines.cs.meta b/TrueTrace/Resources/Utility/TTAdvancedImageGen.cs.meta similarity index 83% rename from TrueTrace/Resources/TTCPUDefines.cs.meta rename to TrueTrace/Resources/Utility/TTAdvancedImageGen.cs.meta index 5f6c4223..363fccf9 100644 --- a/TrueTrace/Resources/TTCPUDefines.cs.meta +++ b/TrueTrace/Resources/Utility/TTAdvancedImageGen.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7d24d8f0ff33a324cb01d99ae1bc9ebf +guid: 899a59e3be883b644a1ef3cbdabe9acb MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/TrueTrace/Resources/Utility/TTSettings.cs b/TrueTrace/Resources/Utility/TTSettings.cs index 106102a9..90efe4f3 100644 --- a/TrueTrace/Resources/Utility/TTSettings.cs +++ b/TrueTrace/Resources/Utility/TTSettings.cs @@ -1,6 +1,9 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif namespace TrueTrace { @@ -79,8 +82,49 @@ namespace TrueTrace { [SerializeField] public float PrimaryBackgroundTint = 0; [SerializeField] public float PrimaryBackgroundContrast = 1; [SerializeField] public float FogDensity = 0.0002f; + [SerializeField] public float FogHeight = 80.0f; [SerializeField] public Vector3 FogColor = new Vector3(0.6f, 0.6f, 0.6f); [SerializeField] public int MaxSampCount = 99999999; + [SerializeField] public bool DoChromaAber = false; + [SerializeField] public float ChromaDistort = 0.3f; + [SerializeField] public bool DoBCS = false; + [SerializeField] public float Saturation = 1.0f; + [SerializeField] public float Contrast = 1.0f; + [SerializeField] public bool DoVignette = false; + [SerializeField] public float innerVignette = 0.5f; + [SerializeField] public float outerVignette = 1.2f; + [SerializeField] public float strengthVignette = 0.8f; + [SerializeField] public float curveVignette = 0.5f; + [SerializeField] public Vector3 ColorVignette = Vector3.zero; } + +#if UNITY_EDITOR + [CustomEditor(typeof(TTSettings))] + public class TTSettingsEditor : Editor + { + // SerializedProperty lookAtPoint; + + void OnEnable() + { + // lookAtPoint = serializedObject.FindProperty("lookAtPoint"); + } + + public override void OnInspectorGUI() + { + + base.OnInspectorGUI(); + var script = (TTSettings)target; + + if(GUILayout.Button("Set For Modification", GUILayout.Height(40))) { + TTInterface.SetTTSettings(script); + } + // serializedObject.Update(); + // EditorGUILayout.PropertyField(lookAtPoint); + // serializedObject.ApplyModifiedProperties(); + } + } + + +#endif } \ No newline at end of file diff --git a/TrueTrace/Resources/Utility/TTSettingsStorage.meta b/TrueTrace/Resources/Utility/TTSettingsStorage.meta new file mode 100644 index 00000000..6542afae --- /dev/null +++ b/TrueTrace/Resources/Utility/TTSettingsStorage.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4f268cfcbd6107845aefa296a2f2d272 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TrueTrace/Resources/Utility/TTSettingsStorage/TTGlobalSettings 1.asset b/TrueTrace/Resources/Utility/TTSettingsStorage/TTGlobalSettings 1.asset new file mode 100644 index 00000000..3f1e3328 --- /dev/null +++ b/TrueTrace/Resources/Utility/TTSettingsStorage/TTGlobalSettings 1.asset @@ -0,0 +1,89 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + 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: 11500000, guid: 2ce9a6213bc68c0458b33690315e1b16, type: 3} + m_Name: TTGlobalSettings 1 + m_EditorClassIdentifier: + SceneName: TestA + IndirectBoost: 1 + bouncecount: 12 + ClayMode: 0 + UseRussianRoulette: 1 + UseNEE: 1 + DoTLASUpdates: 1 + Accumulate: 1 + PPBloom: 0 + BloomStrength: 0.5 + PPDoF: 1 + DoFAperature: 0.2 + DoFAperatureScale: 1 + DoFFocal: 5.22169 + PPExposure: 0 + ExposureAuto: 0 + PPToneMap: 1 + PPTAA: 0 + RenderScale: 1 + DenoiserMethod: 0 + UpscalerMethod: 0 + UseReSTIRGITemporal: 1 + UseReSTIRGISpatial: 1 + UseReSTIRGI: 0 + ReSTIRGISpatialCount: 24 + ReSTIRGISpatialRadius: 50 + ReSTIRGITemporalMCap: 20 + ReSTIRGIUpdateRate: 7 + DoReSTIRGIConnectionValidation: 1 + Exposure: 1 + DoPartialRendering: 0 + PartialRenderingFactor: 1 + DoFirefly: 0 + ImprovedPrimaryHit: 0 + RISCount: 12 + ToneMapper: 0 + SkyDesaturate: 0 + ClayColor: {x: 0.5, y: 0.5, z: 0.5} + GroundColor: {x: 0.1, y: 0.1, z: 0.1} + FireflyFrameCount: 0 + FireflyFrameInterval: 1 + FireflyStrength: 1 + FireflyOffset: 0 + OIDNFrameCount: 0 + DoSharpen: 0 + Sharpness: 1 + MainDesiredRes: 16384 + UseSkinning: 1 + LightEnergyScale: 1 + BackgroundType: 0 + BackgroundIntensity: {x: 1, y: 1} + SceneBackgroundColor: {x: 1, y: 1, z: 1} + SecondaryBackgroundType: 0 + SecondarySceneBackgroundColor: {x: 1, y: 1, z: 1} + HDRILongLat: {x: 0, y: 0} + HDRIScale: {x: 1, y: 1} + LEMEnergyScale: 1 + UseTransmittanceInNEE: 1 + SecondarySkyDesaturate: 0 + MatChangeResetsAccum: 0 + PPFXAA: 0 + OIDNBlendRatio: 1 + ConvBloom: 0 + ConvStrength: 1.37 + ConvBloomThreshold: 13.23 + ConvBloomSize: {x: 1, y: 1} + ConvBloomDistExp: 0 + ConvBloomDistExpClampMin: 1 + ConvBloomDistExpScale: 1 + PrimaryBackgroundTintColor: {x: 1, y: 1, z: 1} + PrimaryBackgroundTint: 0 + PrimaryBackgroundContrast: 1 + FogDensity: 0.0002 + FogColor: {x: 0.6, y: 0.6, z: 0.6} + MaxSampCount: 99999999 diff --git a/TrueTrace/Resources/Utility/TTSettingsStorage/TTGlobalSettings 1.asset.meta b/TrueTrace/Resources/Utility/TTSettingsStorage/TTGlobalSettings 1.asset.meta new file mode 100644 index 00000000..63a95c44 --- /dev/null +++ b/TrueTrace/Resources/Utility/TTSettingsStorage/TTGlobalSettings 1.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ebc162160e6bab04491289b6e7676db3 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/TrueTrace/Resources/Utility/TTSettingsStorage/TTGlobalSettings.asset b/TrueTrace/Resources/Utility/TTSettingsStorage/TTGlobalSettings.asset new file mode 100644 index 00000000..222b4eaa --- /dev/null +++ b/TrueTrace/Resources/Utility/TTSettingsStorage/TTGlobalSettings.asset @@ -0,0 +1,89 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + 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: 11500000, guid: 2ce9a6213bc68c0458b33690315e1b16, type: 3} + m_Name: TTGlobalSettings + m_EditorClassIdentifier: + SceneName: TestA + IndirectBoost: 1 + bouncecount: 12 + ClayMode: 0 + UseRussianRoulette: 1 + UseNEE: 1 + DoTLASUpdates: 1 + Accumulate: 1 + PPBloom: 0 + BloomStrength: 0.5 + PPDoF: 1 + DoFAperature: 0.2 + DoFAperatureScale: 1 + DoFFocal: 0.9822057 + PPExposure: 0 + ExposureAuto: 0 + PPToneMap: 1 + PPTAA: 0 + RenderScale: 1 + DenoiserMethod: 0 + UpscalerMethod: 0 + UseReSTIRGITemporal: 1 + UseReSTIRGISpatial: 1 + UseReSTIRGI: 0 + ReSTIRGISpatialCount: 24 + ReSTIRGISpatialRadius: 50 + ReSTIRGITemporalMCap: 20 + ReSTIRGIUpdateRate: 7 + DoReSTIRGIConnectionValidation: 1 + Exposure: 1 + DoPartialRendering: 0 + PartialRenderingFactor: 1 + DoFirefly: 0 + ImprovedPrimaryHit: 0 + RISCount: 12 + ToneMapper: 0 + SkyDesaturate: 0 + ClayColor: {x: 0.5, y: 0.5, z: 0.5} + GroundColor: {x: 0.1, y: 0.1, z: 0.1} + FireflyFrameCount: 0 + FireflyFrameInterval: 1 + FireflyStrength: 1 + FireflyOffset: 0 + OIDNFrameCount: 0 + DoSharpen: 0 + Sharpness: 1 + MainDesiredRes: 16384 + UseSkinning: 1 + LightEnergyScale: 1 + BackgroundType: 0 + BackgroundIntensity: {x: 1, y: 1} + SceneBackgroundColor: {x: 1, y: 1, z: 1} + SecondaryBackgroundType: 0 + SecondarySceneBackgroundColor: {x: 1, y: 1, z: 1} + HDRILongLat: {x: 0, y: 0} + HDRIScale: {x: 1, y: 1} + LEMEnergyScale: 1 + UseTransmittanceInNEE: 1 + SecondarySkyDesaturate: 0 + MatChangeResetsAccum: 0 + PPFXAA: 0 + OIDNBlendRatio: 1 + ConvBloom: 0 + ConvStrength: 1.37 + ConvBloomThreshold: 13.23 + ConvBloomSize: {x: 1, y: 1} + ConvBloomDistExp: 0 + ConvBloomDistExpClampMin: 1 + ConvBloomDistExpScale: 1 + PrimaryBackgroundTintColor: {x: 1, y: 1, z: 1} + PrimaryBackgroundTint: 0 + PrimaryBackgroundContrast: 1 + FogDensity: 0.0002 + FogColor: {x: 0.6, y: 0.6, z: 0.6} + MaxSampCount: 99999999 diff --git a/TrueTrace/Resources/Utility/TTSettingsStorage/TTGlobalSettings.asset.meta b/TrueTrace/Resources/Utility/TTSettingsStorage/TTGlobalSettings.asset.meta new file mode 100644 index 00000000..5d8e78f9 --- /dev/null +++ b/TrueTrace/Resources/Utility/TTSettingsStorage/TTGlobalSettings.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 575d73661f77c60478eccf5fd260bbcb +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/TrueTrace/Resources/Utility/TTTimedScreenShotter.cs b/TrueTrace/Resources/Utility/TTTimedScreenShotter.cs deleted file mode 100644 index c329f576..00000000 --- a/TrueTrace/Resources/Utility/TTTimedScreenShotter.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -#if UNITY_EDITOR -namespace TrueTrace { - public class TTTimedScreenShotter : MonoBehaviour - { - public int SamplesBetweenShots = 1000; - public bool ResetSampCountAfterShot = false; - - void Update() { - if(((RayTracingMaster.SampleCount % SamplesBetweenShots) == SamplesBetweenShots - 1 && !ResetSampCountAfterShot) || (RayTracingMaster.SampleCount >= SamplesBetweenShots && ResetSampCountAfterShot)) { - ScreenCapture.CaptureScreenshot(PlayerPrefs.GetString("ScreenShotPath") + "/" + System.DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ", " + RayTracingMaster.SampleCount + " Samples.png"); - UnityEditor.AssetDatabase.Refresh(); - if(ResetSampCountAfterShot) { - RayTracingMaster.SampleCount = 0; - GameObject.Find("Scene").GetComponent().FramesSinceStart = 0; - } - } - } - } -} -#endif \ No newline at end of file diff --git a/TrueTrace/Resources/Utility/TTTimedScreenShotter.cs.meta b/TrueTrace/Resources/Utility/TTTimedScreenShotter.cs.meta deleted file mode 100644 index ef516d0d..00000000 --- a/TrueTrace/Resources/Utility/TTTimedScreenShotter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 24041bcbbf2821d4cb6995df4bbc7f6e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/TrueTrace/Resources/Utility/TurnTableScript.cs b/TrueTrace/Resources/Utility/TurnTableScript.cs deleted file mode 100644 index b0010d4f..00000000 --- a/TrueTrace/Resources/Utility/TurnTableScript.cs +++ /dev/null @@ -1,174 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using System.IO; -using System; - using UnityEngine.Profiling; -using System.Reflection; - -namespace TrueTrace { - public class TurnTableScript : MonoBehaviour - { - RayTracingMaster RayMaster; - private int CurrentSegment = 0; - private int CurrentCamera = 0; - private float waitedTime = 0; - private bool PrevImage = false; - public bool Running = false; - public float TimeBetweenSegments = 10.0f; - public int MaxSamples = 64; - [System.Serializable] - public struct CamData { - public Camera Cam; - public int HorizontalResolution; - public int VerticalResolution; - public Vector3 Center; - public float Distance; - [Range(-89.9f, 89.9f)]public float Pitch; - } - public CamData[] CamSettings; - - void Start() { - RayMaster = GameObject.Find("Scene").GetComponent(); - Application.runInBackground = true; - Running = false; - Init(); - } - - public void Init() { - RayTracingMaster.SampleCount = 0; - RayMaster.FramesSinceStart = 0; - RayMaster._currentSample = 0; - PrevImage = true; - CurrentCamera = 0; - if(!(CamSettings == null || CamSettings.Length == 0)) { - if(CamSettings[0].Cam != null) CamSettings[0].Cam.gameObject.SetActive(true); - for(int i = 1; i < CamSettings.Length; i++) if(CamSettings[i].Cam != null) CamSettings[i].Cam.gameObject.SetActive(false); - Camera[] AllCameras = GameObject.FindObjectsOfType(); - for(int i = 0; i < AllCameras.Length; i++) { - if(!CamSettings[0].Cam.Equals(AllCameras[i])) AllCameras[i].gameObject.SetActive(false); - // if(!AllCameras[i].gameObject.TryGetComponent(out RenderHandle ExistingHandle)) AllCameras[i].gameObject.AddComponent(); - } - } - - } - - IEnumerator RecordFrame() - { - yield return new WaitForEndOfFrame(); - if(PrevImage) { - PrevImage = false; - RayTracingMaster.SampleCount = 0; - RayMaster.FramesSinceStart = 0; - } - waitedTime += Time.deltaTime; - if(!Running) { - Running = true; - } - if (RayMaster.FramesSinceStart >= MaxSamples || waitedTime >= TimeBetweenSegments) { - waitedTime = 0; - string SegmentNumber = ""; - int TempSeg = CurrentSegment; - int[] NumSegments = new int[3]; - for(int i = 0; i < 3; i++) { - NumSegments[i] = ((TempSeg) % 10); - TempSeg /= 10; - } - for(int i = 0; i < 3; i++) { - SegmentNumber += NumSegments[2 - i]; - if(i < 2) { - SegmentNumber += "_"; - } - } - if(!System.IO.Directory.Exists(PlayerPrefs.GetString("TurnTablePath") + "/" + CamSettings[CurrentCamera].Cam.gameObject.name.Replace(" ", ""))) { - System.IO.Directory.CreateDirectory(PlayerPrefs.GetString("TurnTablePath") + "/" + CamSettings[CurrentCamera].Cam.gameObject.name.Replace(" ", "")); - } - ScreenCapture.CaptureScreenshot(PlayerPrefs.GetString("TurnTablePath") + "/" + CamSettings[CurrentCamera].Cam.gameObject.name.Replace(" ", "") + "/" + CamSettings[CurrentCamera].Cam.gameObject.name + "." + SegmentNumber + ".png"); - CurrentSegment++; - CamSettings[CurrentCamera].Cam.gameObject.transform.RotateAround(CamSettings[CurrentCamera].Center, Vector3.up, (360.0f / (float)CamSettings[CurrentCamera].HorizontalResolution)); - RayTracingMaster.SampleCount = 0; - RayMaster.FramesSinceStart = 0; - RayMaster._currentSample = 0; - PrevImage = true; - if(CurrentSegment == CamSettings[CurrentCamera].HorizontalResolution) { - CurrentSegment = 0; - waitedTime = 0; - CurrentCamera++; - if(CurrentCamera < CamSettings.Length) { - CamSettings[CurrentCamera - 1].Cam.gameObject.SetActive(false); - CamSettings[CurrentCamera].Cam.gameObject.SetActive(true); - RayMaster.TossCamera(CamSettings[CurrentCamera].Cam); - } else { - Application.runInBackground = false; - EditorApplication.isPlaying = false; - } - - } - - } - } - public void LateUpdate() - { - StartCoroutine(RecordFrame()); - } - - } - - [CustomEditor(typeof(TurnTableScript))] - public class TurnTableScriptEditor : Editor - { - // Custom in-scene UI for when ExampleScript - // component is selected. - float ttt = 0; - - Vector3 GetTangent(float RadsAlong) { - return (new Vector3(Mathf.Sin(Mathf.Deg2Rad * RadsAlong), 0, Mathf.Cos(Mathf.Deg2Rad * RadsAlong))).normalized; - } - - Vector3 GetToVector(float Yaw, float Pitch) { - return new Vector3(Mathf.Cos(Mathf.Deg2Rad * Yaw) * Mathf.Cos(Mathf.Deg2Rad * Pitch), Mathf.Sin(Mathf.Deg2Rad * Pitch), Mathf.Sin(Mathf.Deg2Rad * Yaw) * Mathf.Cos(Mathf.Deg2Rad * Pitch)); - } - public void OnSceneGUI() - { - var t = target as TurnTableScript; - var tr = t.transform; - var pos = tr.position; - float ArcLength = 5.0f; - if(!t.Running) { - ttt += Time.deltaTime; - EditorGUI.BeginChangeCheck(); - if(t.CamSettings != null) { - for(int i = 0; i < t.CamSettings.Length; i++) { - if(t.CamSettings[i].Cam != null) { - t.CamSettings[i].Center = Handles.PositionHandle(t.CamSettings[i].Center, Quaternion.identity); - float yaw = 0; - - Vector3 Pos2 = t.CamSettings[i].Center + GetToVector(yaw, t.CamSettings[i].Pitch) * t.CamSettings[i].Distance; - t.CamSettings[i].Cam.transform.position = Pos2; - - - int HorizSegments = t.CamSettings[i].HorizontalResolution; - Vector3 Pos3 = new Vector3(t.CamSettings[i].Center.x, Pos2.y, t.CamSettings[i].Center.z); - // Handles.DrawLine(Pos2, Pos2 + GetTangent(yaw), 0.01f); - for(int i2 = 0; i2 < HorizSegments; i2++) { - Handles.DrawWireArc(Pos3, Vector3.up, GetTangent(90 + 360.0f / (float)HorizSegments * (float)i2 - (ArcLength / 2.0f)), ArcLength, Vector3.Distance(Pos3, Pos2)); - Vector3 ToVector = GetToVector(90 + 360.0f / (float)HorizSegments * (float)i2, t.CamSettings[i].Pitch); - t.CamSettings[i].Cam.transform.forward = ToVector; - Vector3 Pos4 = t.CamSettings[i].Center + ToVector * t.CamSettings[i].Distance; - Handles.ConeHandleCap(0, Pos4 - ToVector * 0.15f, t.CamSettings[i].Cam.transform.rotation, 0.2f, EventType.Repaint); - Handles.DrawDottedLine(t.CamSettings[i].Center, Pos4, 0.01f); - // Handles.ConeHandleCap(0, t.CamSettings[i].Center - t.CamSettings[i].Cam.transform.forward * 0.1f, t.CamSettings[i].Cam.transform.rotation, 0.2f, EventType.Repaint); - } - - t.CamSettings[i].Cam.transform.forward = (t.CamSettings[i].Center - Pos2).normalized; - } - } - } - if (EditorGUI.EndChangeCheck()) {} - } - } - } -} -#endif \ No newline at end of file diff --git a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2.dll b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2.dll index b328e2f4..8bb5b38a 100644 Binary files a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2.dll and b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2.dll differ diff --git a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2_core.dll b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2_core.dll new file mode 100644 index 00000000..5c031c7c Binary files /dev/null and b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2_core.dll differ diff --git a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise_core.dll.meta b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2_core.dll.meta similarity index 92% rename from TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise_core.dll.meta rename to TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2_core.dll.meta index feb57b82..f6226288 100644 --- a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise_core.dll.meta +++ b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2_core.dll.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a6e9a05b5a6a81847b446d33807f198e +guid: a4502d0805ec9b445b6fb65408012590 PluginImporter: externalObjects: {} serializedVersion: 2 diff --git a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise_device_cuda.dll b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2_device_cuda.dll similarity index 81% rename from TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise_device_cuda.dll rename to TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2_device_cuda.dll index 81b2be0e..1a0a9ea5 100644 Binary files a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise_device_cuda.dll and b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2_device_cuda.dll differ diff --git a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise_device_cuda.dll.meta b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2_device_cuda.dll.meta similarity index 92% rename from TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise_device_cuda.dll.meta rename to TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2_device_cuda.dll.meta index ed89dc43..c4178d38 100644 --- a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise_device_cuda.dll.meta +++ b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise2_device_cuda.dll.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1d160bb05d2a7994a93adfa279c25a76 +guid: 807ac32ec42e2714099236cbd6fe8b3a PluginImporter: externalObjects: {} serializedVersion: 2 diff --git a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise_core.dll b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise_core.dll deleted file mode 100644 index e133310c..00000000 Binary files a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/OpenImageDenoise_core.dll and /dev/null differ diff --git a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/UnityDenoiserPlugin.dll b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/UnityDenoiserPlugin.dll index 147cb51c..3555adb4 100644 Binary files a/TrueTrace/Resources/Utility/UnityDenoiserPlugin/UnityDenoiserPlugin.dll and b/TrueTrace/Resources/Utility/UnityDenoiserPlugin/UnityDenoiserPlugin.dll differ