public void CreateTextures(AtmosphereParameters AP) { transmittanceT = RTExtensions.CreateRTexture(new Vector2(AtmosphereConstants.TRANSMITTANCE_W, AtmosphereConstants.TRANSMITTANCE_H), 0, Format); irradianceT_Read = RTExtensions.CreateRTexture(new Vector2(AtmosphereConstants.SKY_W, AtmosphereConstants.SKY_H), 0, Format); irradianceT_Write = RTExtensions.CreateRTexture(new Vector2(AtmosphereConstants.SKY_W, AtmosphereConstants.SKY_H), 0, Format); inscatterT_Read = RTExtensions.CreateRTexture(new Vector2(AtmosphereConstants.RES_MU_S * AtmosphereConstants.RES_NU, AtmosphereConstants.RES_MU), 0, Format, FilterMode.Bilinear, WrapMode, AtmosphereConstants.RES_R); inscatterT_Write = RTExtensions.CreateRTexture(new Vector2(AtmosphereConstants.RES_MU_S * AtmosphereConstants.RES_NU, AtmosphereConstants.RES_MU), 0, Format, FilterMode.Bilinear, WrapMode, AtmosphereConstants.RES_R); deltaET = RTExtensions.CreateRTexture(new Vector2(AtmosphereConstants.SKY_W, AtmosphereConstants.SKY_H), 0, Format); deltaSRT = RTExtensions.CreateRTexture(new Vector2(AtmosphereConstants.RES_MU_S * AtmosphereConstants.RES_NU, AtmosphereConstants.RES_MU), 0, Format, FilterMode.Bilinear, WrapMode, AtmosphereConstants.RES_R); deltaSMT = RTExtensions.CreateRTexture(new Vector2(AtmosphereConstants.RES_MU_S * AtmosphereConstants.RES_NU, AtmosphereConstants.RES_MU), 0, Format, FilterMode.Bilinear, WrapMode, AtmosphereConstants.RES_R); deltaJT = RTExtensions.CreateRTexture(new Vector2(AtmosphereConstants.RES_MU_S * AtmosphereConstants.RES_NU, AtmosphereConstants.RES_MU), 0, Format, FilterMode.Bilinear, WrapMode, AtmosphereConstants.RES_R); }
private void DoWork(AtmosphereParameters AP) { finished = false; step = 0; order = 2; Prepeare(AP); while (!finished) { Calculate(AP); } if (ClearAfterBake) { CollectGarbage(false, true); } }
private IEnumerator DoWorkCoroutine(AtmosphereParameters AP) { finished = false; step = 0; order = 2; Prepeare(AP); while (!finished) { Calculate(AP); for (byte i = 0; i < 8; i++) { yield return(Yielders.EndOfFrame); } } if (ClearAfterBake) { CollectGarbage(false, true); } }
private void DoWork(AtmosphereParameters AP, Action callback) { finished = false; step = 0; order = 2; Prepare(AP); while (!finished) { Calculate(AP); } if (ClearAfterBake) { CollectGarbage(false, true); } if (callback != null) { callback(); } }
protected override void UI(int id) { GUILayoutExtensions.VerticalBoxed("Controls: ", GUISkin, () => { GUILayoutExtensions.VerticalBoxed("", GUISkin, () => { DrawApplyButton(() => { if (Body != null && Atmosphere != null) { Atmosphere.Bake(); } }); }); }); GUILayoutExtensions.SpacingSeparator(); ScrollPosition = GUILayout.BeginScrollView(ScrollPosition, false, true); if (Body != null && Helper.Enabled(Body)) { if (Atmosphere != null && Helper.Enabled(Body.Atmosphere) && Body.AtmosphereEnabled) { GUILayoutExtensions.VerticalBoxed("Realtime parameters: ", GUISkin, () => { GUILayoutExtensions.VerticalBoxed("", GUISkin, () => { GUILayoutExtensions.VerticalBoxed("Preset: ", GUISkin, () => { Atmosphere.AtmosphereBase = (AtmosphereBase)GUILayout.SelectionGrid((int)Atmosphere.AtmosphereBase, Enum.GetNames(typeof(AtmosphereBase)), 2); }); GUILayoutExtensions.SpacingSeparator(); GUILayoutExtensions.VerticalBoxed("Artifact fixers: ", GUISkin, () => { GUILayoutExtensions.SliderWithField("Radius Hold (Terrain Radius)", 0.0f, 2048.0f, ref Atmosphere.RadiusHold, "0.00", 75); GUILayoutExtensions.SliderWithField("Aerial Radius (Perspective Offset)", 0.0f, 4096.0f, ref Atmosphere.AerialPerspectiveOffset, "0.00", 75); GUILayoutExtensions.SliderWithFieldAndControls("Horizon Fix Eps", 0.0f, 1.0f, ref Atmosphere.HorizonFixEps, "0.00000", 75, 0.00025f); GUILayoutExtensions.SliderWithFieldAndControls("Mie Fade Fix", 0.0f, 1.0f, ref Atmosphere.MieFadeFix, "0.0000", 75, 0.0025f); }); GUILayoutExtensions.SpacingSeparator(); GUILayoutExtensions.SliderWithField("Density: ", 0.0f, 1.0f, ref Atmosphere.Density); GUILayoutExtensions.SliderWithField("Scale", 0.01f, 16.0f, ref Atmosphere.Scale, "0.000"); GUILayoutExtensions.SliderWithField("Height: ", 0.0f, Body.Size, ref Atmosphere.Height); GUILayoutExtensions.SliderWithField("Extinction Ground Fade", 0.000025f, 0.1f, ref Atmosphere.ExtinctionGroundFade, "0.000000"); GUILayoutExtensions.SliderWithField("HDR Exposure", 0.0f, 1.0f, ref Atmosphere.HDRExposure, "0.00"); }); }); GUILayoutExtensions.SpacingSeparator(); if (Atmosphere.AtmosphereBase == AtmosphereBase.Custom) { GUILayoutExtensions.VerticalBoxed("Bake parameters: ", GUISkin, () => { GUILayoutExtensions.VerticalBoxed("Copy from preset: ", GUISkin, () => { AtmosphereBase = (AtmosphereBase)GUILayout.SelectionGrid((int)AtmosphereBase, Enum.GetNames(typeof(AtmosphereBase)), 2); }); GUILayoutExtensions.SpacingSeparator(); var parameters = PresetChanged ? AtmosphereParameters.Get(AtmosphereBase) : new AtmosphereParameters(AtmosphereParameters); var mieG = parameters.MIE_G; var hr = parameters.HR; var hm = parameters.HM; var agr = parameters.AVERAGE_GROUND_REFLECTANCE; var betaR = parameters.BETA_R; var betaM = parameters.BETA_MSca; var betaE = parameters.BETA_MEx; var rg = parameters.Rg; var rt = parameters.Rt; var rl = parameters.Rl; PresetChanged = false; GUILayoutExtensions.SliderWithField("Mie G: ", 0.0f, 1.0f, ref mieG, "0.0000", textFieldWidth: 100); GUILayoutExtensions.SliderWithFieldAndControls("Air density (HR At half-height in KM): ", 0.0f, 256.0f, ref hr, "0.00", textFieldWidth: 100, controlStep: 1.0f); GUILayoutExtensions.SliderWithFieldAndControls("Particle density (HM At half-height in KM): ", 0.0f, 256.0f, ref hm, "0.00", textFieldWidth: 100, controlStep: 1.0f); GUILayoutExtensions.SliderWithField("Average Ground Reflectance: ", 0.0f, 1.0f, ref agr, "0.0000", textFieldWidth: 100); GUILayoutExtensions.SliderWithField("Rg (Planet Radius in KM): ", 0.0f, 63600.0f, ref rg, "0.00000", textFieldWidth: 100); GUILayoutExtensions.SliderWithField("Rt (Atmosphere Top Radius in KM): ", rg, 63600.0f, ref rt, "0.00000", textFieldWidth: 100); GUILayoutExtensions.SliderWithField("Rl (Planet Bottom Radius in KM): ", rt, 63600.0f, ref rl, "0.00000", textFieldWidth: 100); GUILayoutExtensions.DrawVectorWithSlidersAndFields(ref betaR, 0.0f, 1.0f, GUISkin, "Beta R (Rayliegh Scattering)", "0.0000", textFieldWidth: 100); GUILayoutExtensions.DrawVectorWithSlidersAndFields(ref betaM, 0.0f, 1.0f, GUISkin, "Beta M (Mie Scattering)", "0.0000", textFieldWidth: 100); GUILayoutExtensions.DrawVectorWithSlidersAndFields(ref betaE, 0.0f, 1.0f, GUISkin, "Beta E (Extinction Scattering)", "0.0000", textFieldWidth: 100); parameters = new AtmosphereParameters(mieG, hr, hm, agr, betaR, betaM, betaE, rg, rt, rl, rg, rt, rl, SCALE: 1.0f); AtmosphereParameters = new AtmosphereParameters(parameters); Atmosphere.PushPreset(parameters); }); } else { GUILayoutExtensions.DrawBadHolder("Atmosphere Bake parameters: ", "Use 'Custom' preset please...", GUISkin); } } else { GUILayoutExtensions.DrawBadHolder("Atmosphere parameters: ", "No Atmosphere!?", GUISkin); } } else { GUILayoutExtensions.DrawBadHolder("Atmosphere parameters: ", "No Body!?", GUISkin); } GUILayout.EndScrollView(); }
public void Calculate(AtmosphereParameters AP) { if (step == 0) { // computes transmittance texture T (line 1 in algorithm 4.1) Transmittance.SetTexture(0, "transmittanceWrite", transmittanceT); Transmittance.Dispatch(0, AtmosphereConstants.TRANSMITTANCE_W / NUM_THREADS, AtmosphereConstants.TRANSMITTANCE_H / NUM_THREADS, 1); } else if (step == 1) { // computes irradiance texture deltaE (line 2 in algorithm 4.1) Irradiance1.SetTexture(0, "transmittanceRead", transmittanceT); Irradiance1.SetTexture(0, "deltaEWrite", deltaET); Irradiance1.Dispatch(0, AtmosphereConstants.SKY_W / NUM_THREADS, AtmosphereConstants.SKY_H / NUM_THREADS, 1); } else if (step == 2) { // computes single scattering texture deltaS (line 3 in algorithm 4.1) // Rayleigh and Mie separated in deltaSR + deltaSM Inscatter1.SetTexture(0, "transmittanceRead", transmittanceT); Inscatter1.SetTexture(0, "deltaSRWrite", deltaSRT); Inscatter1.SetTexture(0, "deltaSMWrite", deltaSMT); //The inscatter calc's can be quite demanding for some cards so process //the calc's in layers instead of the whole 3D data set. for (int i = 0; i < AtmosphereConstants.RES_R; i++) { Inscatter1.SetInt("layer", i); Inscatter1.Dispatch(0, (AtmosphereConstants.RES_MU_S * AtmosphereConstants.RES_NU) / NUM_THREADS, AtmosphereConstants.RES_MU / NUM_THREADS, 1); } } else if (step == 3) { // copies deltaE into irradiance texture E (line 4 in algorithm 4.1) CopyIrradiance.SetFloat("k", 0.0f); CopyIrradiance.SetTexture(0, "deltaERead", deltaET); CopyIrradiance.SetTexture(0, "irradianceRead", irradianceT_Read); CopyIrradiance.SetTexture(0, "irradianceWrite", irradianceT_Write); CopyIrradiance.Dispatch(0, AtmosphereConstants.SKY_W / NUM_THREADS, AtmosphereConstants.SKY_H / NUM_THREADS, 1); //Swap irradianceT_Read - irradianceT_Write RTUtility.Swap(ref irradianceT_Read, ref irradianceT_Write); } else if (step == 4) { // copies deltaS into inscatter texture S (line 5 in algorithm 4.1) CopyInscatter1.SetTexture(0, "deltaSRRead", deltaSRT); CopyInscatter1.SetTexture(0, "deltaSMRead", deltaSMT); CopyInscatter1.SetTexture(0, "inscatterWrite", inscatterT_Write); //The inscatter calc's can be quite demanding for some cards so process //the calc's in layers instead of the whole 3D data set. for (int i = 0; i < AtmosphereConstants.RES_R; i++) { CopyInscatter1.SetInt("layer", i); CopyInscatter1.Dispatch(0, (AtmosphereConstants.RES_MU_S * AtmosphereConstants.RES_NU) / NUM_THREADS, AtmosphereConstants.RES_MU / NUM_THREADS, 1); } //Swap inscatterT_Write - inscatterT_Read RTUtility.Swap(ref inscatterT_Read, ref inscatterT_Write); //!!! } else if (step == 5) { //Here Nvidia GTX 430 or lower driver will crash. //If only ray1 or mie1 calculated - slow, but all is alright. //But if both - driver crash. //INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 8 - limit for GTX 430. // computes deltaJ (line 7 in algorithm 4.1) InscatterS.SetInt("first", (order == 2) ? 1 : 0); InscatterS.SetTexture(0, "transmittanceRead", transmittanceT); InscatterS.SetTexture(0, "deltaERead", deltaET); InscatterS.SetTexture(0, "deltaSRRead", deltaSRT); InscatterS.SetTexture(0, "deltaSMRead", deltaSMT); InscatterS.SetTexture(0, "deltaJWrite", deltaJT); //The inscatter calc's can be quite demanding for some cards so process //the calc's in layers instead of the whole 3D data set. for (int i = 0; i < AtmosphereConstants.RES_R; i++) { InscatterS.SetInt("layer", i); InscatterS.Dispatch(0, (AtmosphereConstants.RES_MU_S * AtmosphereConstants.RES_NU) / NUM_THREADS, AtmosphereConstants.RES_MU / NUM_THREADS, 1); } } else if (step == 6) { // computes deltaE (line 8 in algorithm 4.1) IrradianceN.SetInt("first", (order == 2) ? 1 : 0); IrradianceN.SetTexture(0, "deltaSRRead", deltaSRT); IrradianceN.SetTexture(0, "deltaSMRead", deltaSMT); IrradianceN.SetTexture(0, "deltaEWrite", deltaET); IrradianceN.Dispatch(0, AtmosphereConstants.SKY_W / NUM_THREADS, AtmosphereConstants.SKY_H / NUM_THREADS, 1); } else if (step == 7) { // computes deltaS (line 9 in algorithm 4.1) InscatterN.SetTexture(0, "transmittanceRead", transmittanceT); InscatterN.SetTexture(0, "deltaJRead", deltaJT); InscatterN.SetTexture(0, "deltaSRWrite", deltaSRT); //The inscatter calc's can be quite demanding for some cards so process //the calc's in layers instead of the whole 3D data set. for (int i = 0; i < AtmosphereConstants.RES_R; i++) { InscatterN.SetInt("layer", i); InscatterN.Dispatch(0, (AtmosphereConstants.RES_MU_S * AtmosphereConstants.RES_NU) / NUM_THREADS, AtmosphereConstants.RES_MU / NUM_THREADS, 1); } } else if (step == 8) { // adds deltaE into irradiance texture E (line 10 in algorithm 4.1) CopyIrradiance.SetFloat("k", 1.0f); CopyIrradiance.SetTexture(0, "deltaERead", deltaET); CopyIrradiance.SetTexture(0, "irradianceRead", irradianceT_Read); CopyIrradiance.SetTexture(0, "irradianceWrite", irradianceT_Write); CopyIrradiance.Dispatch(0, AtmosphereConstants.SKY_W / NUM_THREADS, AtmosphereConstants.SKY_H / NUM_THREADS, 1); //Swap irradianceT_Read - irradianceT_Write RTUtility.Swap(ref irradianceT_Read, ref irradianceT_Write); } else if (step == 9) { // adds deltaS into inscatter texture S (line 11 in algorithm 4.1) CopyInscatterN.SetTexture(0, "deltaSRead", deltaSRT); CopyInscatterN.SetTexture(0, "inscatterRead", inscatterT_Read); CopyInscatterN.SetTexture(0, "inscatterWrite", inscatterT_Write); //The inscatter calc's can be quite demanding for some cards so process //the calc's in layers instead of the whole 3D data set. for (int i = 0; i < AtmosphereConstants.RES_R; i++) { CopyInscatterN.SetInt("layer", i); CopyInscatterN.Dispatch(0, (AtmosphereConstants.RES_MU_S * AtmosphereConstants.RES_NU) / NUM_THREADS, AtmosphereConstants.RES_MU / NUM_THREADS, 1); } //Swap inscatterT_Read - inscatterT_Write RTUtility.Swap(ref inscatterT_Read, ref inscatterT_Write); if (order < 4) { step = 4; order += 1; } } else if (step == 10) { if (BakeMode == AtmosphereBakeMode.TO_HDD || BakeMode == AtmosphereBakeMode.TO_HDD_DEBUG) { var readDataShader = GodManager.Instance.ReadData; RTUtility.SaveAsRaw(AtmosphereConstants.TRANSMITTANCE_W * AtmosphereConstants.TRANSMITTANCE_H, CBUtility.Channels.RGB, "/transmittance", DestinationFolder, transmittanceT, readDataShader); RTUtility.SaveAsRaw(AtmosphereConstants.SKY_W * AtmosphereConstants.SKY_H, CBUtility.Channels.RGB, "/irradiance", DestinationFolder, irradianceT_Read, readDataShader); RTUtility.SaveAsRaw((AtmosphereConstants.RES_MU_S * AtmosphereConstants.RES_NU) * AtmosphereConstants.RES_MU * AtmosphereConstants.RES_R, CBUtility.Channels.RGB, "/inscatter", DestinationFolder, inscatterT_Read, readDataShader); if (BakeMode == AtmosphereBakeMode.TO_HDD_DEBUG) { RTUtility.SaveAs8bit(AtmosphereConstants.TRANSMITTANCE_W, AtmosphereConstants.TRANSMITTANCE_H, CBUtility.Channels.RGBA, "/transmittance_debug", DestinationFolder, transmittanceT, readDataShader); RTUtility.SaveAs8bit(AtmosphereConstants.SKY_W, AtmosphereConstants.SKY_H, CBUtility.Channels.RGBA, "/irradiance_debug", DestinationFolder, irradianceT_Read, readDataShader, 10.0f); RTUtility.SaveAs8bit(AtmosphereConstants.RES_MU_S * AtmosphereConstants.RES_NU, AtmosphereConstants.RES_MU * AtmosphereConstants.RES_R, CBUtility.Channels.RGBA, "/inscater_debug", DestinationFolder, inscatterT_Read, readDataShader); } } } else if (step == 11) { finished = true; } step++; }
public AtmospherePass(RenderPassEvent renderPassEvent, Material atmosphereMaterial, int atmosphereShaderPassIndex, AtmosphereParameters atmosphereParameters, string tag) { this.renderPassEvent = renderPassEvent; this.atmosphereMaterial = atmosphereMaterial; this.atmosphereShaderPassIndex = atmosphereShaderPassIndex; this.atmosphereParameters = atmosphereParameters; profilerTag = tag; temporaryColorTexture.Init("_TemporaryColorTexture"); }