Ejemplo n.º 1
0
        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++;
        }