Example #1
0
 void ResetCloud()
 {
     CoreUtils.Destroy(m_CloudLayer);
     m_CloudLayer            = null;
     m_CloudLayerFromProfile = null;
     m_LastComputedCloudHash = 0;
 }
Example #2
0
        bool UpdateCache(CloudLayer cloudLayer, Light sunLight)
        {
            int currPrecomputationParamHash = cloudLayer.GetBakingHashCode(sunLight);

            if (currPrecomputationParamHash != m_LastPrecomputationParamHash)
            {
                s_PrecomputationCache.Release(m_LastPrecomputationParamHash);
                m_PrecomputedData             = s_PrecomputationCache.Get(cloudLayer, currPrecomputationParamHash);
                m_LastPrecomputationParamHash = currPrecomputationParamHash;
                return(true);
            }
            return(false);
        }
Example #3
0
        void UpdateCurrentStaticLightingCloud()
        {
            // First, grab the cloud layer of the right type in the profile.
            CoreUtils.Destroy(m_CloudLayer);
            m_CloudLayer            = null;
            m_LastComputedCloudHash = 0;
            GetCloudFromVolume(m_Profile, out m_CloudLayerFromProfile);

            if (m_CloudLayerFromProfile != null)
            {
                // The static lighting sky is a Volume Component that lives outside of the volume system (we just grab a component from a profile)
                // As such, it may contain values that are not actually overridden
                // For example, user overrides a value, change it, and disable overrides. In this case the volume still contains the old overridden value
                // In this case, we want to use values only if they are still overridden, so we create a volume component with default values and then copy the overridden values from the profile.
                // Also, a default profile might be set in the HDRP project settings, this volume is applied by default to all the scene so it should also be taken into account here.

                // Create an instance with default values
                m_CloudLayer = ScriptableObject.CreateInstance <CloudLayer>();
                var newCloudParameters     = m_CloudLayer.parameters;
                var profileCloudParameters = m_CloudLayerFromProfile.parameters;

                var defaultVolume = HDRenderPipeline.GetOrCreateDefaultVolume();
                defaultVolume.sharedProfile.TryGet(out CloudLayer defaultCloud);
                var defaultCloudParameters = defaultCloud != null ? defaultCloud.parameters : null; // Can be null if the profile does not contain the component.

                // Seems to inexplicably happen sometimes on domain reload.
                if (profileCloudParameters == null)
                {
                    return;
                }

                int parameterCount = m_CloudLayer.parameters.Count;
                // Copy overridden parameters.
                for (int i = 0; i < parameterCount; ++i)
                {
                    if (profileCloudParameters[i].overrideState == true)
                    {
                        newCloudParameters[i].SetValue(profileCloudParameters[i]);
                    }
                    // Fallback to the default profile if values are overridden in there.
                    else if (defaultCloudParameters != null && defaultCloudParameters[i].overrideState == true)
                    {
                        newCloudParameters[i].SetValue(defaultCloudParameters[i]);
                    }
                }

                m_LastComputedCloudHash = m_CloudLayerFromProfile.GetHashCode();
            }
        }
Example #4
0
 void GetCloudFromVolume(VolumeProfile profile, out CloudLayer cloudLayer)
 {
     if (profile != null)
     {
         profile.TryGet(out cloudLayer);
         if (cloudLayer != null && !cloudLayer.active)
         {
             cloudLayer = null;
         }
     }
     else
     {
         cloudLayer = null;
     }
 }
Example #5
0
            public bool InitIfNeeded(CloudLayer cloudLayer, Light sunLight, CommandBuffer cmd)
            {
                if (initialized)
                {
                    return(false);
                }

                Vector4 params1 = sunLight == null ? Vector3.zero : sunLight.transform.forward;

                params1.w = (cloudLayer.upperHemisphereOnly.value ? 1.0f : 0.0f);

                cmd.SetComputeVectorParam(s_BakeCloudTextureCS, HDShaderIDs._Params, params1);
                cmd.SetComputeTextureParam(s_BakeCloudTextureCS, s_BakeCloudTextureKernel, _CloudTexture, cloudTextureRT);

                cmd.SetComputeTextureParam(s_BakeCloudTextureCS, s_BakeCloudTextureKernel, _CloudMapA, cloudLayer.layerA.cloudMap.value);
                var paramsA = cloudLayer.layerA.GetBakingParameters();

                paramsA.Item2.w = 1.0f / cloudTextureWidth;

                if (cloudLayer.NumLayers == 1)
                {
                    s_BakeCloudTextureCS.DisableKeyword("USE_SECOND_CLOUD_LAYER");
                    cmd.SetComputeVectorParam(s_BakeCloudTextureCS, HDShaderIDs._Params1, paramsA.Item1);
                    cmd.SetComputeVectorParam(s_BakeCloudTextureCS, HDShaderIDs._Params2, paramsA.Item2);
                }
                else
                {
                    cmd.SetComputeTextureParam(s_BakeCloudTextureCS, s_BakeCloudTextureKernel, _CloudMapB, cloudLayer.layerB.cloudMap.value);
                    var paramsB = cloudLayer.layerB.GetBakingParameters();

                    s_BakeCloudTextureCS.EnableKeyword("USE_SECOND_CLOUD_LAYER");
                    s_VectorArray[0] = paramsA.Item1; s_VectorArray[1] = paramsB.Item1;
                    cmd.SetComputeVectorArrayParam(s_BakeCloudTextureCS, HDShaderIDs._Params1, s_VectorArray);
                    s_VectorArray[0] = paramsA.Item2; s_VectorArray[1] = paramsB.Item2;
                    cmd.SetComputeVectorArrayParam(s_BakeCloudTextureCS, HDShaderIDs._Params2, s_VectorArray);
                }

                const int groupSizeX   = 8;
                const int groupSizeY   = 8;
                int       threadGroupX = (cloudTextureWidth + (groupSizeX - 1)) / groupSizeX;
                int       threadGroupY = (cloudTextureHeight + (groupSizeY - 1)) / groupSizeY;

                cmd.DispatchCompute(s_BakeCloudTextureCS, s_BakeCloudTextureKernel, threadGroupX, threadGroupY, 1);

                initialized = true;
                return(true);
            }
Example #6
0
            public PrecomputationData Get(CloudLayer cloudLayer, int currentHash)
            {
                RefCountedData result;

                if (m_CachedData.TryGetValue(currentHash, out result))
                {
                    result.refCount++;
                    return(result.data);
                }
                else
                {
                    result          = m_DataPool.Get();
                    result.refCount = 1;
                    result.data.Allocate(cloudLayer);
                    m_CachedData.Add(currentHash, result);
                    return(result.data);
                }
            }
Example #7
0
            public void Allocate(CloudLayer cloudLayer)
            {
                initialized        = false;
                cloudTextureWidth  = (int)cloudLayer.resolution.value;
                cloudTextureHeight = cloudLayer.upperHemisphereOnly.value ? cloudTextureWidth / 2 : cloudTextureWidth;
                if (!cloudTextureCache.TryGet(cloudTextureWidth, cloudTextureHeight, ref cloudTextureRT))
                {
                    cloudTextureRT = RTHandles.Alloc(cloudTextureWidth, cloudTextureHeight,
                                                     cloudLayer.NumLayers, colorFormat: GraphicsFormat.R16G16_SFloat, dimension: TextureDimension.Tex2DArray,
                                                     enableRandomWrite: true, useMipMap: false, filterMode: FilterMode.Bilinear, name: "Cloud Texture");
                }

                cloudShadowsRT         = null;
                cloudShadowsResolution = (int)cloudLayer.shadowResolution.value;
                if (cloudLayer.CastShadows && !cloudShadowsCache.TryGet(cloudShadowsResolution, cloudShadowsResolution, ref cloudShadowsRT))
                {
                    cloudShadowsRT = RTHandles.Alloc(cloudShadowsResolution, cloudShadowsResolution,
                                                     colorFormat: GraphicsFormat.B10G11R11_UFloatPack32, dimension: TextureDimension.Tex2D,
                                                     enableRandomWrite: true, useMipMap: false, filterMode: FilterMode.Bilinear, name: "Cloud Shadows");
                }
            }
Example #8
0
        /// <summary>Sets keywords and parameters on a sky material to render the cloud layer.</summary>
        /// <param name="layer">The cloud layer to apply.</param>
        /// <param name="skyMaterial">The sky material to change.</param>
        public static void Apply(CloudLayer layer, Material skyMaterial)
        {
            if (layer != null && layer.enabled.value == true)
            {
                layer.scrollFactor += layer.scrollSpeed.value * (Time.time - layer.lastTime) * 0.01f;
                layer.lastTime      = Time.time;

                Vector4 cloudParam  = layer.GetParameters();
                Vector4 cloudParam2 = layer.tint.value;
                cloudParam2.w = layer.intensityMultiplier.value;

                skyMaterial.EnableKeyword("USE_CLOUD_MAP");
                skyMaterial.SetTexture(HDShaderIDs._CloudMap, layer.cloudMap.value);
                skyMaterial.SetVector(HDShaderIDs._CloudParam, cloudParam);
                skyMaterial.SetVector(HDShaderIDs._CloudParam2, cloudParam2);

                if (layer.enableDistortion.value == true)
                {
                    skyMaterial.EnableKeyword("USE_CLOUD_MOTION");
                    if (layer.procedural.value == true)
                    {
                        skyMaterial.DisableKeyword("USE_CLOUD_MAP");
                    }
                    else
                    {
                        skyMaterial.SetTexture(HDShaderIDs._CloudFlowmap, layer.flowmap.value);
                    }
                }
                else
                {
                    skyMaterial.DisableKeyword("USE_CLOUD_MOTION");
                }
            }
            else
            {
                skyMaterial.DisableKeyword("USE_CLOUD_MAP");
                skyMaterial.DisableKeyword("USE_CLOUD_MOTION");
            }
        }
        // 'renderSunDisk' parameter is not supported.
        // Users should instead create an emissive (or lit) mesh for every relevant light source
        // (to support multiple stars in space, moons with moon phases, etc).
        public override void RenderSky(BuiltinSkyParameters builtinParams, bool renderForCubemap, bool renderSunDisk)
        {
            var pbrSky = builtinParams.skySettings as PhysicallyBasedSky;

            // TODO: the following expression is somewhat inefficient, but good enough for now.
            Vector3 cameraPos    = builtinParams.worldSpaceCameraPos;
            Vector3 planetCenter = pbrSky.GetPlanetCenterPosition(cameraPos);
            float   R            = pbrSky.GetPlanetaryRadius();

            Vector3 cameraToPlanetCenter = planetCenter - cameraPos;
            float   r = cameraToPlanetCenter.magnitude;

            cameraPos = planetCenter - Mathf.Max(R, r) * cameraToPlanetCenter.normalized;

            CommandBuffer cmd = builtinParams.commandBuffer;

            // Precomputation is done, shading is next.
            Quaternion planetRotation = Quaternion.Euler(pbrSky.planetRotation.value.x,
                                                         pbrSky.planetRotation.value.y,
                                                         pbrSky.planetRotation.value.z);

            Quaternion spaceRotation = Quaternion.Euler(pbrSky.spaceRotation.value.x,
                                                        pbrSky.spaceRotation.value.y,
                                                        pbrSky.spaceRotation.value.z);

            s_PbrSkyMaterialProperties.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, builtinParams.pixelCoordToViewDirMatrix);
            s_PbrSkyMaterialProperties.SetVector(HDShaderIDs._WorldSpaceCameraPos1, cameraPos);
            s_PbrSkyMaterialProperties.SetMatrix(HDShaderIDs._ViewMatrix1, builtinParams.viewMatrix);
            s_PbrSkyMaterialProperties.SetMatrix(HDShaderIDs._PlanetRotation, Matrix4x4.Rotate(planetRotation));
            s_PbrSkyMaterialProperties.SetMatrix(HDShaderIDs._SpaceRotation, Matrix4x4.Rotate(spaceRotation));

            m_PrecomputedData.BindBuffers(cmd, s_PbrSkyMaterialProperties);

            int hasGroundAlbedoTexture = 0;

            if (pbrSky.groundColorTexture.value != null)
            {
                hasGroundAlbedoTexture = 1;
                s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._GroundAlbedoTexture, pbrSky.groundColorTexture.value);
            }
            s_PbrSkyMaterialProperties.SetInt(HDShaderIDs._HasGroundAlbedoTexture, hasGroundAlbedoTexture);

            int hasGroundEmissionTexture = 0;

            if (pbrSky.groundEmissionTexture.value != null)
            {
                hasGroundEmissionTexture = 1;
                s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._GroundEmissionTexture, pbrSky.groundEmissionTexture.value);
                s_PbrSkyMaterialProperties.SetFloat(HDShaderIDs._GroundEmissionMultiplier, pbrSky.groundEmissionMultiplier.value);
            }
            s_PbrSkyMaterialProperties.SetInt(HDShaderIDs._HasGroundEmissionTexture, hasGroundEmissionTexture);

            int hasSpaceEmissionTexture = 0;

            if (pbrSky.spaceEmissionTexture.value != null)
            {
                hasSpaceEmissionTexture = 1;
                s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._SpaceEmissionTexture, pbrSky.spaceEmissionTexture.value);
                s_PbrSkyMaterialProperties.SetFloat(HDShaderIDs._SpaceEmissionMultiplier, pbrSky.spaceEmissionMultiplier.value);
            }
            s_PbrSkyMaterialProperties.SetInt(HDShaderIDs._HasSpaceEmissionTexture, hasSpaceEmissionTexture);

            s_PbrSkyMaterialProperties.SetInt(HDShaderIDs._RenderSunDisk, renderSunDisk ? 1 : 0);

            int pass = (renderForCubemap ? 0 : 2);

            CloudLayer.Apply(builtinParams.cloudLayer, m_PbrSkyMaterial);

            CoreUtils.DrawFullScreen(builtinParams.commandBuffer, m_PbrSkyMaterial, s_PbrSkyMaterialProperties, pass);
        }
Example #10
0
            public void BakeCloudShadows(CloudLayer cloudLayer, Light sunLight, HDCamera camera, CommandBuffer cmd)
            {
                InitIfNeeded(cloudLayer, sunLight, cmd);
                Vector4 _Params  = sunLight.transform.forward;
                Vector4 _Params1 = sunLight.transform.right;
                Vector4 _Params2 = sunLight.transform.up;
                Vector4 _Params3 = cloudLayer.shadowTint.value;

                _Params.w  = 1.0f / cloudShadowsResolution;
                _Params3.w = cloudLayer.shadowMultiplier.value * 8.0f;

                cmd.SetComputeVectorParam(s_BakeCloudShadowsCS, HDShaderIDs._Params, _Params);
                cmd.SetComputeVectorParam(s_BakeCloudShadowsCS, HDShaderIDs._Params1, _Params1);
                cmd.SetComputeVectorParam(s_BakeCloudShadowsCS, HDShaderIDs._Params2, _Params2);
                cmd.SetComputeVectorParam(s_BakeCloudShadowsCS, HDShaderIDs._Params3, _Params3);

                cmd.SetComputeTextureParam(s_BakeCloudShadowsCS, s_BakeCloudShadowsKernel, _CloudTexture, cloudTextureRT);
                cmd.SetComputeTextureParam(s_BakeCloudShadowsCS, s_BakeCloudShadowsKernel, _CloudShadows, cloudShadowsRT);

                var paramsA = cloudLayer.layerA.GetRenderingParameters(camera, 0);
                var paramsB = cloudLayer.layerB.GetRenderingParameters(camera, 0);

                paramsA.Item1.z = paramsA.Item1.z * 0.2f;
                paramsB.Item1.z = paramsB.Item1.z * 0.2f;
                paramsA.Item1.w = cloudLayer.upperHemisphereOnly.value ? 1 : 0;
                paramsB.Item1.w = cloudLayer.opacity.value;

                s_VectorArray[0] = paramsA.Item1; s_VectorArray[1] = paramsB.Item1;
                cmd.SetComputeVectorArrayParam(s_BakeCloudShadowsCS, HDShaderIDs._FlowmapParam, s_VectorArray);

                bool useSecond = (cloudLayer.layers.value == CloudMapMode.Double) && cloudLayer.layerB.castShadows.value;

                CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "DISABLE_MAIN_LAYER", !cloudLayer.layerA.castShadows.value);
                CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "USE_SECOND_CLOUD_LAYER", useSecond);

                if (cloudLayer.layerA.castShadows.value)
                {
                    CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "USE_CLOUD_MOTION", cloudLayer.layerA.distortionMode.value != CloudDistortionMode.None);
                    CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "USE_FLOWMAP", cloudLayer.layerA.distortionMode.value == CloudDistortionMode.Flowmap);
                    if (cloudLayer.layerA.distortionMode.value == CloudDistortionMode.Flowmap)
                    {
                        cmd.SetComputeTextureParam(s_BakeCloudShadowsCS, s_BakeCloudShadowsKernel, _FlowmapA, cloudLayer.layerA.flowmap.value);
                    }
                }

                if (useSecond)
                {
                    CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "USE_SECOND_CLOUD_MOTION", cloudLayer.layerB.distortionMode.value != CloudDistortionMode.None);
                    CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "USE_SECOND_FLOWMAP", cloudLayer.layerB.distortionMode.value == CloudDistortionMode.Flowmap);
                    if (cloudLayer.layerB.distortionMode.value == CloudDistortionMode.Flowmap)
                    {
                        cmd.SetComputeTextureParam(s_BakeCloudShadowsCS, s_BakeCloudShadowsKernel, _FlowmapB, cloudLayer.layerB.flowmap.value);
                    }
                }

                const int groupSizeX   = 8;
                const int groupSizeY   = 8;
                int       threadGroupX = (cloudShadowsResolution + (groupSizeX - 1)) / groupSizeX;
                int       threadGroupY = (cloudShadowsResolution + (groupSizeY - 1)) / groupSizeY;

                cmd.DispatchCompute(s_BakeCloudShadowsCS, s_BakeCloudShadowsKernel, threadGroupX, threadGroupY, 1);
                cloudShadowsRT.rt.IncrementUpdateCount();
            }