void ResetCloud() { CoreUtils.Destroy(m_CloudLayer); m_CloudLayer = null; m_CloudLayerFromProfile = null; m_LastComputedCloudHash = 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); }
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(); } }
void GetCloudFromVolume(VolumeProfile profile, out CloudLayer cloudLayer) { if (profile != null) { profile.TryGet(out cloudLayer); if (cloudLayer != null && !cloudLayer.active) { cloudLayer = null; } } else { cloudLayer = null; } }
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); }
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); } }
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"); } }
/// <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); }
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(); }