Example #1
0
    internal void InjectObject(Matrix4x4 viewProj, int kernel, VaporObject obj)
    {
        if (kernel == -1)
        {
            return;
        }

        m_worldBounds.Clear();
        obj.GetBounds(transform, m_worldBounds);
        Bounds uvBounds = new Bounds(GetUvFromWorld(obj.transform.position, viewProj), Vector3.one * 0.05f);

        for (int i = 0; i < m_worldBounds.Count; i++)
        {
            Vector3 uv = GetUvFromWorld(m_worldBounds[i], viewProj);
            uvBounds.Encapsulate(uv);
        }

        Vector3 min = uvBounds.min;
        Vector3 max = uvBounds.max;

        m_offset[0] = Mathf.FloorToInt(min.x * m_densityTex.width);
        m_offset[1] = Mathf.FloorToInt(min.y * m_densityTex.height);
        m_offset[2] = Mathf.FloorToInt(min.z * m_densityTex.volumeDepth);

        m_vaporCompute.SetInts("_LightWriteLower", m_offset);

        int maxX = Mathf.CeilToInt(max.x * m_densityTex.width);
        int maxY = Mathf.CeilToInt(max.y * m_densityTex.height);
        int maxZ = Mathf.CeilToInt(max.z * m_densityTex.volumeDepth);

        Profiler.BeginSample("Object pass");
        m_vaporCompute.DispatchScaled(kernel, maxX - m_offset[0], maxY - m_offset[1], maxZ - m_offset[2]);
        Profiler.EndSample();
    }
Example #2
0
    void DoComputeSteps()
    {
        //TODO: Could switch between eyes? Would slightly blur the fog -> Probably nice
        if (Camera.current.stereoEnabled && Camera.current.stereoActiveEye == Camera.MonoOrStereoscopicEye.Right)
        {
            m_setting = Setting;             //Do update default setting if it's null
            return;
        }

        Graphics.ClearRandomWriteTargets();

        if (m_instant)
        {
            m_vaporCompute.SetFloat("_ExponentialWeight", 1.0f);
            m_instant = false;
        }
        else
        {
            m_vaporCompute.SetFloat("_ExponentialWeight", AveragingSpeed);
        }

        m_vaporCompute.SetFloat("_TemporalStrength", TemporalStrength);
        m_vaporCompute.SetInt("_Frame", Random.Range(0, m_blueNoiseTex.width * m_blueNoiseTex.height));
        m_vaporCompute.SetVector("_CameraPos", Camera.current.transform.position);

        if (QualitySettings.shadowCascades == 2)
        {
            m_vaporCompute.SetVector("_ShadowRange", new Vector4(0.0f, 0.5f, 0.0f, 1.0f));
        }
        else
        {
            m_vaporCompute.SetVector("_ShadowRange", new Vector4(0.5f, 0.5f));
        }


        Matrix4x4 v;

        if (Camera.current.stereoEnabled)
        {
            v = m_camera.GetStereoViewMatrix(Camera.StereoscopicEye.Left);
        }
        else
        {
            v = m_camera.worldToCameraMatrix;
        }


        Vector2 jitter = GenerateRandomOffset();

        jitter *= (TemporalStrength * 10);

        Matrix4x4 p  = GetJitteredMatrix(m_camera, jitter);
        Matrix4x4 vp = p * v;

        //Set VP from old frame for reprojection
        Matrix4x4 vpi = vp.inverse;

        m_vaporCompute.SetMatrix("_VAPOR_REPROJECT", m_vpMatrixOld * vpi);
        m_vaporCompute.SetMatrix("_VAPOR_I_VP", vpi);
        m_vaporCompute.SetMatrix("_VAPOR_VP", vp);
        m_vpMatrixOld = vp;

        //Bind system settings
        {
            m_res[0] = m_densityTex.width;
            m_res[1] = m_densityTex.height;
            m_res[2] = m_densityTex.volumeDepth;

            m_vaporCompute.SetInts("_VaporResolution", m_res);

            m_vaporCompute.SetFloat("_VaporDepthPow", DepthCurvePower);
            Shader.SetGlobalFloat("_VaporDepthPow", DepthCurvePower);

            float   near          = m_camera.nearClipPlane;
            float   far           = m_camera.farClipPlane;
            Vector4 planeSettings = GetPlaneSettings(near, far);

            m_vaporCompute.SetVector("_VaporPlaneSettings", planeSettings);
            Shader.SetGlobalVector("_VaporPlaneSettings", planeSettings);
            Shader.SetGlobalTexture("_VaporFogTexture", m_integratedTexture);
            Shader.SetGlobalMatrix("_VAPOR_I_VP", vpi);
            Shader.SetGlobalMatrix("_VAPOR_VP", vp);


            float zc0 = 1.0f - far / near;
            float zc1 = far / near;
            m_vaporCompute.SetVector("_ZBufferParams", new Vector4(zc0, zc1, zc0 / far, zc1 / far));

            for (int i = 0; i < 11; ++i)
            {
                m_vaporCompute.SetTexture(i, "_BlueNoise", m_blueNoiseTex);
            }
        }

        //Bind noise settings
        {
            Vector4 scale = new Vector4(2.5f, 1.0f, 2.5f);
            m_vaporCompute.SetVector("_NoiseWeights", NoiseWeights / (NoiseWeights.x + NoiseWeights.y + NoiseWeights.z));
            float colMin     = 1.0f - NoiseColorStrength;
            float extinctMin = 1.0f - NoiseExtinctionStrength;

            m_vaporCompute.SetVector("_NoiseMin", new Vector4(colMin, colMin, colMin, extinctMin));

            m_vaporCompute.SetVector("_NoiseFrequency", Vector4.Scale(NoiseFrequency, scale));
            m_vaporCompute.SetVector("_NoiseSpeed", Vector4.Scale(Vector4.Scale(NoiseSpeed, scale), NoiseFrequency) * 0.01f);
            m_vaporCompute.SetFloat("_NoisePower", NoisePower);
        }

        //Bind scattering settings
        {
            //refractive index of nitrogen
            const double indexSqr = 1.0002772 * 1.0002772;
            const double r        = (indexSqr - 1) * (indexSqr - 1) / ((indexSqr + 2) * (indexSqr + 2));

            double size = Mathf.Pow(ScatteringIntensity * 1e3f, 1.0f / 6.0f);

            float rsize = (float)(r * Math.Pow(size * ScatteringColor.r / 200.0f, 4.0f) * size * size * (1e-18 * 2.5e25));
            float gsize = (float)(r * Math.Pow(size * ScatteringColor.g / 200.0f, 4.0f) * size * size * (1e-18 * 2.5e25));
            float bsize = (float)(r * Math.Pow(size * ScatteringColor.b / 200.0f, 4.0f) * size * size * (1e-18 * 2.5e25));

            Vector3 rayleighBase   = new Vector3(rsize, gsize, bsize);
            Vector3 rayleighWeight = rayleighBase * Mathf.Pow(2.0f * Mathf.PI, 4.0f) / (Mathf.Pow(2.0f, 6.0f));

            Vector3 rayleighCross = rayleighBase * 24 * Mathf.Pow(Mathf.PI, 3.0f);

            rayleighCross.x = (float)(Math.Pow(1.0 - rayleighCross.x, 1000));
            rayleighCross.y = (float)(Math.Pow(1.0 - rayleighCross.y, 1000));
            rayleighCross.z = (float)(Math.Pow(1.0 - rayleighCross.z, 1000));

            m_vaporCompute.SetVector("_Rayleigh", rayleighWeight * 1e5f);
            m_vaporCompute.SetVector("_RayleighCross", rayleighCross);
            m_vaporCompute.SetVector("_MieScatter",
                                     new Vector4(DirectionalScatteringColor.r, DirectionalScatteringColor.g, DirectionalScatteringColor.b,
                                                 DirectionalScattering * 0.999f));

            m_vaporCompute.SetFloat("_LambertBeerDensity", Setting.Extinction * 0.1f);

            float planetSize = 8000;
            float atmoRadius = planetSize + AtmosphereThickness;
            m_vaporCompute.SetVector("_Atmosphere",
                                     new Vector4(AtmosphereRingPower, AtmosphereRingSize, atmoRadius * atmoRadius, planetSize));
        }

        Profiler.BeginSample("Write global density");
        Setting.Bind(m_vaporCompute, m_densityKernel, BlendToSetting, m_blendTime);
        m_vaporCompute.SetTexture(m_densityKernel, "_DensityTextureWrite", m_densityTex);
        m_vaporCompute.SetTexture(m_densityKernel, "_NoiseTex", NoiseTexture);
        m_vaporCompute.DispatchScaled(m_densityKernel, m_densityTex.width, m_densityTex.height, m_densityTex.volumeDepth);
        Profiler.EndSample();

        Profiler.BeginSample("Vapor Object Passes");
        //If there's no directional -> manual clear light buffer
        if (VaporObject.All.Count == 0 || (VaporObject.All[0] as VaporLight) == null ||
            (VaporObject.All[0] as VaporLight).LightType != LightType.Directional)
        {
            SetLightAccum(m_lightClearKernel, false);
            m_vaporCompute.DispatchScaled(m_lightClearKernel, m_scatterTex.width, m_scatterTex.height, m_scatterTex.volumeDepth);
        }
        //Inject vapor objects
        for (int index = 0; index < VaporObject.All.Count; index++)
        {
            VaporObject vap = VaporObject.All[index];
            vap.Inject(this, m_vaporCompute, vp);
        }
        Profiler.EndSample();

        Setting.Bind(m_vaporCompute, m_densityKernel, BlendToSetting, m_blendTime);

        Profiler.BeginSample("Scattering");
        SetLightAccum(m_scatterKernel, true);
        m_vaporCompute.SetTexture(m_scatterKernel, "_DensityTexture", m_densityTex);
        m_vaporCompute.SetTexture(m_scatterKernel, "_ScatterTextureOld", m_scatterTexOld);
        m_vaporCompute.SetTexture(m_scatterKernel, "_ScatterTexture", m_scatterTex);
        m_vaporCompute.DispatchScaled(m_scatterKernel, m_scatterTex.width, m_scatterTex.height, m_scatterTex.volumeDepth);
        Profiler.EndSample();

        Profiler.BeginSample("Integration");
        m_vaporCompute.SetTexture(m_integrateKernel, "_IntegratedTexture", m_integratedTexture);
        m_vaporCompute.SetTexture(m_integrateKernel, "_ScatterTextureOld", m_scatterTex);
        m_vaporCompute.DispatchScaled(m_integrateKernel, m_scatterTex.width, m_scatterTex.height, 1);
        Profiler.EndSample();

        Profiler.BeginSample("Blit properties");
        var temp = m_scatterTex;

        m_scatterTex    = m_scatterTexOld;
        m_scatterTexOld = temp;
        Profiler.EndSample();
    }