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(); }
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(); }