private void Start()
        {
            if (computeShader == null)
            {
                throw new System.InvalidOperationException("Compute shader not set!");
            }
            if (_instance != null)
            {
                throw new System.InvalidOperationException("AtmosphereScatteringLutManager already exists!");
            }
            _instance = this;
            AtmLutHelper.Init(computeShader);
            for (int i = 0; i < pingPongUpdaters.Length; i++)
            {
                pingPongUpdaters[i]      = new ProgressiveLutUpdater(null, lutConfig, this);
                pingPongUpdaters[i].name = "Updater " + i;
            }

            //Quickly complete two set luts.
            for (int i = 1; i <= 2; i++)
            {
                pingPongUpdaters[i].atmConfigToUse = atmosphereConfig;
                var t = pingPongUpdaters[i].UpdateCoroutine();
                while (t.MoveNext())
                {
                    ;
                }
            }
            UpdateSkyboxMaterial(pingPongUpdaters[1], pingPongUpdaters[2]);

            KickOffUpdater(pingPongUpdaters[0]);
        }
 public static void CreateCameraAlignedVolumeTexture(
     ref RenderTexture transmittance,
     ref RenderTexture scattering,
     Vector3Int volumeTexSize
     )
 {
     AtmLutHelper.CreateLUT(ref transmittance,
                            "CameraVolumeTransmittance",
                            volumeTexSize.x,
                            volumeTexSize.y,
                            volumeTexSize.z,
                            RenderTextureFormat.ARGBFloat,
                            false);
     AtmLutHelper.CreateLUT(ref scattering,
                            "CameraVolumeScattering",
                            volumeTexSize.x,
                            volumeTexSize.y,
                            volumeTexSize.z,
                            RenderTextureFormat.ARGBFloat,
                            false);
 }
        public static void CreateShadowTexture(
            ref RenderTexture shadow,
            ref RenderTexture shadowAccumulate,
            Vector3Int volumeTexSize
            )
        {
            AtmLutHelper.CreateLUT(ref shadow,
                                   "CameraVolumeShadow",
                                   volumeTexSize.x,
                                   volumeTexSize.y,
                                   volumeTexSize.z,
                                   RenderTextureFormat.R8,
                                   false);

            AtmLutHelper.CreateLUT(ref shadow,
                                   "CameraVolumeShadowAccumulate",
                                   volumeTexSize.x,
                                   volumeTexSize.y,
                                   volumeTexSize.z,
                                   RenderTextureFormat.RFloat,
                                   false);
        }
        //Generate camera volume texture.
        private void OnPreRender()
        {
            if (RenderSettings.sun == null)
            {
                return;
            }
            // get four corners of camera frustom in world space
            // bottom left
            _FrustumCorners[0] = camera.ViewportToWorldPoint(new Vector3(0, 0, camera.farClipPlane));
            // bottom right
            _FrustumCorners[1] = camera.ViewportToWorldPoint(new Vector3(1, 0, camera.farClipPlane));
            // top left
            _FrustumCorners[2] = camera.ViewportToWorldPoint(new Vector3(0, 1, camera.farClipPlane));
            // top right
            _FrustumCorners[3] = camera.ViewportToWorldPoint(new Vector3(1, 1, camera.farClipPlane));

            //Render camera volume texture.
            var projection_matrix = GL.GetGPUProjectionMatrix(camera.projectionMatrix, false);

            AtmLutHelper.CreateCameraAlignedVolumeTexture(ref transmittanceVolume, ref scatteringVolume, volumeTexSize);
            AtmLutHelper.UpdateCameraVolume(
                transmittanceVolume,
                scatteringVolume,
                volumeTexSize,
                transform.position,
                -RenderSettings.sun.transform.forward,
                _FrustumCorners,
                new Vector2(camera.nearClipPlane, camera.farClipPlane)
                );

            //Set it.
            Shader.SetGlobalTexture("_CameraVolumeTransmittance", transmittanceVolume);
            Shader.SetGlobalTexture("_CameraVolumeScattering", scatteringVolume);
            var vp_matrix = projection_matrix * camera.worldToCameraMatrix;

            Shader.SetGlobalMatrix("_Camera_VP", vp_matrix);
        }
示例#5
0
        public IEnumerator UpdateCoroutine()
        {
            working = true;
            atmConfigUsedToUpdate.CopyDataFrom(atmConfigToUse);
            AtmLutHelper.CreateTransmittanceTexture(ref transmittance, lutConfig);
            using (new ConvenientStopwatch("Complete Lut update timecost", Log)) {
                //Update transmittance.
                AtmLutHelper.ApplyComputeShaderParams(lutConfig, atmConfigUsedToUpdate);
                using (new ConvenientStopwatch("Transmittance ", Log)) {
                    AtmLutHelper.UpdateTransmittance(
                        transmittance,
                        lutConfig,
                        0.0f,
                        1.0f
                        );
                    yield return(null);
                }

                //Update GroundDirect
                using (new ConvenientStopwatch("GroundDirect", Log)) {
                    AtmLutHelper.ApplyComputeShaderParams(lutConfig, atmConfigUsedToUpdate);
                    AtmLutHelper.CreateGroundIrradianceTexture(ref groundIrradianceTemp[0], 0, lutConfig);
                    AtmLutHelper.UpdateGroundDirectIrradiance(groundIrradianceTemp[0], transmittance, lutConfig, 0.0f, 1.0f);
                    yield return(null);
                }

                //Update SingleRayleigh/Mie
                using (new ConvenientStopwatch("Single Rayleigh/Mie", Log)) {
                    AtmLutHelper.ApplyComputeShaderParams(lutConfig, atmConfigUsedToUpdate);
                    AtmLutHelper.CreateSingleRayleighMieTexture(ref singleRayleigh, ref singleMie, lutConfig);
                    AtmLutHelper.UpdateSingleRayleighMie(singleRayleigh, singleMie, transmittance, lutConfig);
                    yield return(null);
                }

                AtmLutHelper.CreateMultiScatteringTexture(ref multiScatteringTemp[1], 1, lutConfig);    //This texture is not "Meaningful"(Since the 1-st order should be SingleRayleigh and SingleMie, and this tex won't be used in actual computation either), but we need to make an empty one to avoid shader error.

                using (new ConvenientStopwatch("GroundIrradiance 1", Log)) {
                    //Ground irradiance of 1-st order scattering.
                    AtmLutHelper.ApplyComputeShaderParams(lutConfig, atmConfigUsedToUpdate);
                    AtmLutHelper.CreateGroundIrradianceTexture(ref groundIrradianceTemp[1], 1, lutConfig);
                    AtmLutHelper.UpdateGroundIrradiance(groundIrradianceTemp[1], singleRayleigh, singleMie, multiScatteringTemp[1], 1, lutConfig, 0.0f, 1.0f);
                    yield return(null);
                }

                //Real game start.
                AtmLutHelper.CreateMultiScatteringDensityTexture(ref multiScatteringDensity, lutConfig);

                for (int i = 2; i <= k_MultiScatteringOrderDepth; i++)
                {
                    using (new ConvenientStopwatch("Multi Scattering Density" + i, Log)) {
                        AtmLutHelper.ApplyComputeShaderParams(lutConfig, atmConfigUsedToUpdate);
                        AtmLutHelper.UpdateMultiScatteringDensity(multiScatteringDensity, transmittance, singleRayleigh, singleMie, multiScatteringTemp[i - 1], groundIrradianceTemp[i - 2], i, lutConfig);
                        yield return(null);
                    }

                    AtmLutHelper.CreateGroundIrradianceTexture(ref groundIrradianceTemp[i], i, lutConfig);
                    using (new ConvenientStopwatch("Ground Irradiance" + i, Log)) {
                        AtmLutHelper.ApplyComputeShaderParams(lutConfig, atmConfigUsedToUpdate);
                        AtmLutHelper.UpdateGroundIrradiance(groundIrradianceTemp[i], singleRayleigh, singleMie, multiScatteringTemp[i - 1], i - 1, lutConfig);
                        yield return(null);
                    }

                    AtmLutHelper.CreateMultiScatteringTexture(ref multiScatteringTemp[i], i, lutConfig);
                    using (new ConvenientStopwatch("Multi Scattering " + i, Log)) {
                        AtmLutHelper.ApplyComputeShaderParams(lutConfig, atmConfigUsedToUpdate);
                        AtmLutHelper.UpdateMultiScatteringCombineDensity(multiScatteringTemp[i], transmittance, multiScatteringDensity, lutConfig);
                        yield return(null);
                    }
                }

                //Combine our multiscattering texture.
                AtmLutHelper.CreateFinalCombinedTexture(ref multiScatteringCombine, ref groundIrradianceCombine, lutConfig);
                AtmLutHelper.ClearFinalCombinedMultiScatter(multiScatteringCombine, lutConfig);
                AtmLutHelper.ClearFinalCombinedIrradiance(groundIrradianceCombine, lutConfig);

                AtmLutHelper.ApplyComputeShaderParams(lutConfig, atmConfigUsedToUpdate);
                for (int i = 2; i <= k_MultiScatteringOrderDepth; i++)
                {
                    AtmLutHelper.UpdateFinalCombinedMultiScatter(multiScatteringCombine, multiScatteringTemp[i], lutConfig);
                }

                for (int i = 1; i <= k_MultiScatteringOrderDepth; i++)
                {
                    AtmLutHelper.UpdateFinalCombinedIrradiance(groundIrradianceCombine, groundIrradianceTemp[i], lutConfig);
                }
            }
            //All calculations are done.

            /*  DON"T RELEASE TEMP TEXTURES HERE, IT WILL CAUSE GRAPHICS GLITCH(FLASHING) WHEN RENDERING SKYBOX. I DON'T KNOW WHY.(2017.4.11f1)    */
            /*  AND THAT GLITCH COST ME 4 HOURS TO FIND OUT, THANK YOU UNITY */
            /*  I guess that after combine dispatch call, the process isn't finished immediately, if we release the textures right now, it will blow up. */
            /*  but I tried to wait for a few frame(yield return null), still doesn't work. */
            ////Release all temp textures. They won't be used in the future.
            //for (int i = 0; i < groundIrradianceTemp.Length; i++) {
            //    if (groundIrradianceTemp[i] != null) {
            //        groundIrradianceTemp[i].Release();
            //        groundIrradianceTemp[i] = null;
            //    }
            //}
            //for (int i = 0; i < multiScatteringTemp.Length; i++) {
            //    if (multiScatteringTemp[i] != null) {
            //        multiScatteringTemp[i].Release();
            //        multiScatteringTemp[i] = null;
            //    }
            //}

            //Done!
            working = false;
            yield break;
        }