/// <summary> /// Computes the world position of the corners of the frustum /// </summary> /// <param name="camera">The camera</param> /// <param name="nearClipPlaneDistance">The near plane</param> /// <param name="farClipPlaneDistance">The far plane</param> /// <returns>An array containing the world position of the corners of the frustum</returns> public static Vector3[] GetFrustumCornersWorldPosition(Camera camera, float nearClipPlaneDistance, float farClipPlaneDistance) { Vector3[] frustumWorldPos = new Vector3[8]; float nearY = FrustumCorners.GetCameraSizeAtDistance(camera.fieldOfView, nearClipPlaneDistance); float nearX = nearY * camera.aspect; float farY = FrustumCorners.GetCameraSizeAtDistance(camera.fieldOfView, farClipPlaneDistance); float farX = farY * camera.aspect; Matrix4x4 matrix = Matrix4x4.TRS(camera.transform.position, camera.transform.rotation, Vector3.one); for (int i = 0; i < 8; ++i) { Vector3 pos = FrustumCorners._frustumClipPos[i]; if (pos.z < 0) { pos.x *= nearX; pos.y *= nearY; pos.z = nearClipPlaneDistance; } else { pos.x *= farX; pos.y *= farY; pos.z = farClipPlaneDistance; } frustumWorldPos[i] = matrix.MultiplyPoint3x4(pos); } return(frustumWorldPos); }
/// <summary> /// Computes the volumetric data /// </summary> public void ComputeData() { if (!_hasInitializedBuffers) { CreateBuffers(settings.resolution); } settings.ComputeFlags(); #region Variables _farClip = Mathf.Min(Aura.CameraComponent.farClipPlane, Mathf.Max(Aura.CameraComponent.nearClipPlane, settings.farClipPlaneDistance)); _cameraRanges = new Vector4(Aura.CameraComponent.nearClipPlane, _farClip); Shader.SetGlobalVector("Aura_FrustumRange", _cameraRanges); _zParameters = new Vector4(-1.0f + Aura.CameraComponent.farClipPlane / Aura.CameraComponent.nearClipPlane, 1.0f); _zParameters.z = _zParameters.x / Aura.CameraComponent.farClipPlane; _zParameters.w = _zParameters.y / Aura.CameraComponent.farClipPlane; _volumeDepth = _farClip - Aura.CameraComponent.nearClipPlane; _layerDepth = _volumeDepth / _resolutionVector.z; _inverseLayerDepth = 1.0f / _layerDepth; #endregion #region Occlusion culling if (settings.HasFlags(FrustumParametersEnum.EnableOcclusionCulling)) { Profiler.BeginSample("Aura : Compute occlusion culling data"); _computeMaximumDepthComputeShader.SetTextureFromGlobal((int)settings.occlusionCullingAccuracy, "depthTexture", "_CameraDepthTexture"); // TODO : USE EVENT TO SET TEXTURES _computeMaximumDepthComputeShader.SetVector("cameraRanges", _cameraRanges); _computeMaximumDepthComputeShader.SetVector("zParameters", _zParameters); _computeMaximumDepthComputeShader.SetTexture((int)settings.occlusionCullingAccuracy, "occlusionTexture", _buffers.OcclusionTexture.WriteBuffer); _computeMaximumDepthComputeShader.Dispatch((int)settings.occlusionCullingAccuracy, settings.resolution.x, settings.resolution.y, 1); //Par blocks puis repasser en resolution _buffers.OcclusionTexture.Swap(); if (_processOcclusionMapMaterial == null) { _processOcclusionMapMaterial = new Material(_processOcclusionMapShader); } _processOcclusionMapMaterial.SetVector("bufferResolution", _resolutionVector); Graphics.Blit(_buffers.OcclusionTexture.ReadBuffer, _buffers.OcclusionTexture.WriteBuffer, _processOcclusionMapMaterial); _buffers.OcclusionTexture.Swap(); _computeDataComputeShader.SetTexture(settings.GetId(), "occlusionTexture", _buffers.OcclusionTexture.ReadBuffer); // TODO : USE EVENT TO SET TEXTURES _computeAccumulationComputeShader.SetTexture(1, "occlusionTexture", _buffers.OcclusionTexture.ReadBuffer); // TODO : USE EVENT TO SET TEXTURES _buffers.FogVolumeTexture.Clear(Color.black); Profiler.EndSample(); } #endregion #region Compute contributions Profiler.BeginSample("Aura : Compute volumetric lighting and density"); _buffers.LightingVolumeTextures.Swap(); Shader.SetGlobalTexture("Aura_VolumetricDataTexture", _buffers.LightingVolumeTextures.WriteBuffer); // TODO : USE EVENT TO SET TEXTURES _buffers.LightingVolumeTextures.WriteBuffer.Clear(new Color(0, 0, 0, -10)); _computeDataComputeShader.SetTexture(settings.GetId(), "textureBuffer", _buffers.LightingVolumeTextures.WriteBuffer); // TODO : USE EVENT TO SET TEXTURES _computeDataComputeShader.SetTexture(settings.GetId(), "previousFrameLightingVolumeTexture", _buffers.LightingVolumeTextures.ReadBuffer); // TODO : USE EVENT TO SET TEXTURES _computeDataComputeShader.SetFloat("time", Aura.Time); _computeDataComputeShader.SetVector("cameraPosition", Aura.CameraComponent.transform.position); _computeDataComputeShader.SetVector("cameraRanges", _cameraRanges); _computeDataComputeShader.SetFloat("layerDepth", _layerDepth); _computeDataComputeShader.SetFloat("invLayerDepth", _inverseLayerDepth); _computeDataComputeShader.SetFloats("frustumCornersWorldPositionArray", Aura.CameraComponent.GetFrustumCornersWorldPosition(Aura.CameraComponent.nearClipPlane, _farClip).AsFloatArray()); _computeDataComputeShader.SetFloat("baseDensity", settings.density); _computeDataComputeShader.SetFloat("baseAnisotropy", settings.anisotropy); _computeDataComputeShader.SetVector("baseColor", settings.color * settings.colorStrength); #region Temporal Reprojection if (settings.HasFlags(FrustumParametersEnum.EnableTemporalReprojection)) { _computeDataComputeShader.SetFloat("temporalReprojectionFactor", settings.temporalReprojectionFactor); _computeDataComputeShader.SetVector("cameraRanges", _cameraRanges); _computeDataComputeShader.SetInt("_frameID", Aura.FrameId); } #endregion #region Volumes Injection if (settings.HasFlags(FrustumParametersEnum.EnableVolumes)) { _computeDataComputeShader.SetInt("volumeCount", Aura.VolumesManager.Buffer.count); _computeDataComputeShader.SetBuffer(settings.GetId(), "volumeDataBuffer", Aura.VolumesManager.Buffer); if (settings.HasFlags(FrustumParametersEnum.EnableVolumesTextureMask)) { _computeDataComputeShader.SetTexture(settings.GetId(), "volumeMaskTexture", Aura.VolumesManager.VolumeTexture); // TODO : USE EVENT TO SET TEXTURES } } #endregion #region Directional lights if (settings.HasFlags(FrustumParametersEnum.EnableDirectionalLights)) { _computeDataComputeShader.SetInt("directionalLightCount", Aura.LightsManager.DirectionalLightsManager.DataBuffer.count); _computeDataComputeShader.SetBuffer(settings.GetId(), "directionalLightDataBuffer", Aura.LightsManager.DirectionalLightsManager.DataBuffer); if (settings.HasFlags(FrustumParametersEnum.EnableDirectionalLightsShadows)) { _computeDataComputeShader.SetTexture(settings.GetId(), "directionalShadowMapsArray", Aura.LightsManager.DirectionalLightsManager.ShadowMapsArray); // TODO : USE EVENT TO SET TEXTURES _computeDataComputeShader.SetTexture(settings.GetId(), "directionalShadowDataArray", Aura.LightsManager.DirectionalLightsManager.ShadowDataArray); // TODO : USE EVENT TO SET TEXTURES } if (settings.HasFlags(FrustumParametersEnum.EnableLightsCookies) && Aura.LightsManager.DirectionalLightsManager.HasCookieCasters) { _computeDataComputeShader.SetTexture(settings.GetId(), "directionalCookieMapsArray", Aura.LightsManager.DirectionalLightsManager.CookieMapsArray); // TODO : USE EVENT TO SET TEXTURES } } #endregion #region Spot lights if (settings.HasFlags(FrustumParametersEnum.EnableSpotLights)) { _computeDataComputeShader.SetInt("spotLightCount", Aura.LightsManager.SpotLightsManager.DataBuffer.count); _computeDataComputeShader.SetBuffer(settings.GetId(), "spotLightDataBuffer", Aura.LightsManager.SpotLightsManager.DataBuffer); if (settings.HasFlags(FrustumParametersEnum.EnableSpotLightsShadows)) { _computeDataComputeShader.SetTexture(settings.GetId(), "spotShadowMapsArray", Aura.LightsManager.SpotLightsManager.ShadowMapsArray); // TODO : USE EVENT TO SET TEXTURES } if (settings.HasFlags(FrustumParametersEnum.EnableLightsCookies) && Aura.LightsManager.SpotLightsManager.HasCookieCasters) { _computeDataComputeShader.SetTexture(settings.GetId(), "spotCookieMapsArray", Aura.LightsManager.SpotLightsManager.CookieMapsArray); // TODO : USE EVENT TO SET TEXTURES } } #endregion #region Point lights if (settings.HasFlags(FrustumParametersEnum.EnablePointLights)) { _computeDataComputeShader.SetInt("pointLightCount", Aura.LightsManager.PointLightsManager.DataBuffer.count); _computeDataComputeShader.SetBuffer(settings.GetId(), "pointLightDataBuffer", Aura.LightsManager.PointLightsManager.DataBuffer); if (settings.HasFlags(FrustumParametersEnum.EnablePointLightsShadows)) { _computeDataComputeShader.SetTexture(settings.GetId(), "pointShadowMapsArray", Aura.LightsManager.PointLightsManager.ShadowMapsArray); // TODO : USE EVENT TO SET TEXTURES } if (settings.HasFlags(FrustumParametersEnum.EnableLightsCookies) && Aura.LightsManager.PointLightsManager.HasCookieCasters) { _computeDataComputeShader.SetTexture(settings.GetId(), "pointCookieMapsArray", Aura.LightsManager.PointLightsManager.CookieMapsArray); // TODO : USE EVENT TO SET TEXTURES } } #endregion #region Compute _computeDataComputeShader.Dispatch(settings.GetId(), _computeDataComputeShaderDispatchSizeX, _computeDataComputeShaderDispatchSizeY, _computeDataComputeShaderDispatchSizeZ); Profiler.EndSample(); #endregion #endregion #region Accumulate fog texture Profiler.BeginSample("Aura : Compute accumulated contributions"); _computeAccumulationComputeShader.SetFloat("layerDepth", _layerDepth); _computeAccumulationComputeShader.SetFloat("invLayerDepth", _inverseLayerDepth); _computeAccumulationComputeShader.SetTexture(0, "textureBuffer", _buffers.LightingVolumeTextures.WriteBuffer); // TODO : USE EVENT TO SET TEXTURES _computeAccumulationComputeShader.SetTexture(1, "textureBuffer", _buffers.LightingVolumeTextures.WriteBuffer); // TODO : USE EVENT TO SET TEXTURES _computeAccumulationComputeShader.SetFloat("normalizationCoefficient", -(_farClip - Aura.CameraComponent.nearClipPlane) / 256.0f); // simplified from : (farClip - Aura.cameraComponent.nearClipPlane) / resolution.z) [->layerDepth] * (bufferResolution.z / 256.0f) [->buffer resolution normalization (256.0f is an abritrary scale factor)] * -1 [->needed for exponential function] _computeAccumulationComputeShader.Dispatch(settings.HasFlags(FrustumParametersEnum.EnableOcclusionCulling) ? 1 : 0, _computeAccumulationComputeShaderDispatchSizeX, _computeAccumulationComputeShaderDispatchSizeY, _computeAccumulationComputeShaderDispatchSizeZ); Profiler.EndSample(); #endregion _computeDataComputeShader.SetFloats("previousFrameWorldToClipMatrix", FrustumCorners.GetWorldToClipMatrix(Aura.CameraComponent, _farClip).ToFloatArray()); }