public override void Render(PostProcessRenderContext context) { PropertySheet sheet = context.propertySheets.Get(shader); CommandBuffer cmd = context.command; Camera cam = context.camera; #region Skybox sampling //Add the skybox rendering component to any camera rendering Fog if (settings.colorSource.value == Fog.FogColorSource.SkyboxColor) { //Ignore hidden camera's, except scene-view cam if (cam.hideFlags != HideFlags.None && cam.name != "SceneCamera") { return; } if (!skyboxCams.ContainsKey(cam)) { skyboxCams[cam] = cam.gameObject.GetComponent <RenderScreenSpaceSkybox>(); if (!skyboxCams[cam]) { skyboxCams[cam] = cam.gameObject.AddComponent <RenderScreenSpaceSkybox>(); } skyboxCams[cam].manuallyAdded = false; //Don't show warning on component } } #endregion //OpenVR.System.GetProjectionMatrix(vrEye, mainCamera.nearClipPlane, mainCamera.farClipPlane, EGraphicsAPIConvention.API_DirectX) //Clip-space to world-space camera matrix conversion #region Property value composition var p = GL.GetGPUProjectionMatrix(cam.projectionMatrix, false); p[2, 3] = p[3, 2] = 0.0f; p[3, 3] = 1.0f; var clipToWorld = Matrix4x4.Inverse(p * cam.worldToCameraMatrix) * Matrix4x4.TRS(new Vector3(0, 0, -p[2, 2]), Quaternion.identity, Vector3.one); sheet.properties.SetMatrix("clipToWorld", clipToWorld); float FdotC = cam.transform.position.y - settings.height; float paramK = (FdotC <= 0.0f ? 1.0f : 0.0f); //Always exclude skybox for skybox color mode //Always include when using light scattering to avoid depth discontinuity float skyboxInfluence = (settings.lightScattering) ? 1.0f : settings.skyboxInfluence; float distanceFog = (settings.distanceFog) ? 1.0f : 0.0f; float heightFog = (settings.heightFog) ? 1.0f : 0.0f; int colorSource = (settings.useSceneSettings) ? 0 : (int)settings.colorSource.value; var sceneMode = (settings.useSceneSettings) ? RenderSettings.fogMode : settings.fogMode; var sceneDensity = (settings.useSceneSettings) ? RenderSettings.fogDensity : settings.globalDensity / 100; var sceneStart = (settings.useSceneSettings) ? RenderSettings.fogStartDistance : settings.fogStartDistance; var sceneEnd = (settings.useSceneSettings) ? RenderSettings.fogEndDistance : settings.fogEndDistance; bool linear = (sceneMode == FogMode.Linear); float diff = linear ? sceneEnd - sceneStart : 0.0f; float invDiff = Mathf.Abs(diff) > 0.0001f ? 1.0f / diff : 0.0f; Vector4 sceneParams; sceneParams.x = sceneDensity * 1.2011224087f; // density / sqrt(ln(2)), used by Exp2 fog mode sceneParams.y = sceneDensity * 1.4426950408f; // density / ln(2), used by Exp fog mode sceneParams.z = linear ? -invDiff : 0.0f; sceneParams.w = linear ? sceneEnd * invDiff : 0.0f; float gradientDistance = (settings.gradientUseFarClipPlane.value) ? settings.gradientDistance : context.camera.farClipPlane; #endregion #region Property assignment if (settings.heightNoiseTex.value) { sheet.properties.SetTexture("_NoiseTex", settings.heightNoiseTex); } if (settings.fogColorGradient.value) { sheet.properties.SetTexture("_ColorGradient", settings.fogColorGradient); } sheet.properties.SetFloat("_FarClippingPlane", gradientDistance); sheet.properties.SetVector("_SceneFogParams", sceneParams); sheet.properties.SetVector("_SceneFogMode", new Vector4((int)sceneMode, settings.useRadialDistance ? 1 : 0, colorSource, settings.heightFogNoise ? 1 : 0)); sheet.properties.SetVector("_NoiseParams", new Vector4(settings.heightNoiseSize * 0.01f, settings.heightNoiseSpeed * 0.01f, settings.heightNoiseStrength, 0)); sheet.properties.SetVector("_DensityParams", new Vector4(settings.distanceDensity, settings.heightNoiseStrength, settings.skyboxMipLevel, 0)); sheet.properties.SetVector("_HeightParams", new Vector4(settings.height, FdotC, paramK, settings.heightDensity * 0.5f)); sheet.properties.SetVector("_DistanceParams", new Vector4(-sceneStart, 0f, distanceFog, heightFog)); sheet.properties.SetColor("_FogColor", (settings.useSceneSettings) ? RenderSettings.fogColor : settings.fogColor); sheet.properties.SetVector("_SkyboxParams", new Vector4(skyboxInfluence, settings.skyboxMipLevel, 0, 0)); Vector3 sunDir = (settings.useLightDirection) ? Fog.LightDirection : settings.lightDirection.value.normalized; float sunIntensity = (settings.useLightIntensity) ? FogLightSource.intensity : settings.lightIntensity.value; sunIntensity = (settings.enableDirectionalLight) ? sunIntensity : 0f; sheet.properties.SetVector("_DirLightParams", new Vector4(sunDir.x, sunDir.y, sunDir.z, sunIntensity)); Color sunColor = (settings.useLightColor) ? FogLightSource.color : settings.lightColor.value; sheet.properties.SetVector("_DirLightColor", new Vector4(sunColor.r, sunColor.g, sunColor.b, 0)); #endregion #region Light scattering //Repurpose parts of the bloom effect bool enableScattering = (settings.lightScattering) ? true : false; if (enableScattering) { int tw = Mathf.FloorToInt(context.screenWidth / (2f)); int th = Mathf.FloorToInt(context.screenHeight / (2f)); bool singlePassDoubleWide = (context.stereoActive && (context.stereoRenderingMode == PostProcessRenderContext.StereoRenderingMode.SinglePass) && (context.camera.stereoTargetEye == StereoTargetEyeMask.Both)); int tw_stereo = singlePassDoubleWide ? tw * 2 : tw; // Determine the iteration count int s = Mathf.Max(tw, th); float logs = Mathf.Log(s, 2f) + Mathf.Min(settings.scatterDiffusion.value, 10f) - 10f; int logs_i = Mathf.FloorToInt(logs); int iterations = Mathf.Clamp(logs_i, 1, k_MaxPyramidSize); float sampleScale = 0.5f + logs - logs_i; sheet.properties.SetFloat("_SampleScale", sampleScale); // Prefiltering parameters float lthresh = Mathf.GammaToLinearSpace(settings.scatterThreshold.value); float knee = lthresh * settings.scatterSoftKnee.value + 1e-5f; var threshold = new Vector4(lthresh, lthresh - knee, knee * 2f, 0.25f / knee); sheet.properties.SetVector("_Threshold", threshold); // Downsample var lastDown = context.source; for (int i = 0; i < iterations; i++) { int mipDown = m_Pyramid[i].down; int mipUp = m_Pyramid[i].up; int pass = i == 0 ? (int)Pass.Prefilter : (int)Pass.Downsample; context.GetScreenSpaceTemporaryRT(cmd, mipDown, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw_stereo, th); context.GetScreenSpaceTemporaryRT(cmd, mipUp, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw_stereo, th); cmd.BlitFullscreenTriangle(lastDown, mipDown, sheet, pass); lastDown = mipDown; tw_stereo = (singlePassDoubleWide && ((tw_stereo / 2) % 2 > 0)) ? 1 + tw_stereo / 2 : tw_stereo / 2; tw_stereo = Mathf.Max(tw_stereo, 1); th = Mathf.Max(th / 2, 1); } // Upsample int lastUp = m_Pyramid[iterations - 1].down; for (int i = iterations - 2; i >= 0; i--) { int mipDown = m_Pyramid[i].down; int mipUp = m_Pyramid[i].up; cmd.SetGlobalTexture("_BloomTex", mipDown); cmd.BlitFullscreenTriangle(lastUp, mipUp, sheet, (int)Pass.Upsample); lastUp = mipUp; } float intensity = RuntimeUtilities.Exp2(settings.scatterIntensity.value / 10f) - 1f; var shaderSettings = new Vector4(sampleScale, intensity, 0, iterations); sheet.properties.SetVector("_ScatteringParams", shaderSettings); cmd.SetGlobalTexture("_BloomTex", lastUp); // Cleanup for (int i = 0; i < iterations; i++) { if (m_Pyramid[i].down != lastUp) { cmd.ReleaseTemporaryRT(m_Pyramid[i].down); } if (m_Pyramid[i].up != lastUp) { cmd.ReleaseTemporaryRT(m_Pyramid[i].up); } } } #endregion #region shader passes context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, enableScattering ? (int)Pass.BlendScattering : (int)Pass.Blend); #endregion }
public override void Render(PostProcessRenderContext context) { CommandBuffer cmd = context.command; PropertySheet sheet = context.propertySheets.Get(shader); cmd.BeginSample(PROFILER_TAG); int tw = (int)(context.screenWidth / settings.RTDownScaling); int th = (int)(context.screenHeight / settings.RTDownScaling); Vector4 BlurOffset = new Vector4(settings.BlurRadius / (float)context.screenWidth, settings.BlurRadius / (float)context.screenHeight, 0, 0); sheet.properties.SetVector(ShaderIDs.BlurOffset, BlurOffset); // Downsample RenderTargetIdentifier lastDown = context.source; for (int i = 0; i < settings.Iteration; i++) { int mipDownV = m_Pyramid[i].down_vertical; int mipDowH = m_Pyramid[i].down_horizontal; int mipUpV = m_Pyramid[i].up_vertical; int mipUpH = m_Pyramid[i].up_horizontal; context.GetScreenSpaceTemporaryRT(cmd, mipDownV, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw, th); context.GetScreenSpaceTemporaryRT(cmd, mipDowH, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw, th); context.GetScreenSpaceTemporaryRT(cmd, mipUpV, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw, th); context.GetScreenSpaceTemporaryRT(cmd, mipUpH, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw, th); // horizontal blur sheet.properties.SetVector(ShaderIDs.BlurOffset, new Vector4(settings.BlurRadius / context.screenWidth, 0, 0, 0)); context.command.BlitFullscreenTriangle(lastDown, mipDowH, sheet, 0); // vertical blur sheet.properties.SetVector(ShaderIDs.BlurOffset, new Vector4(0, settings.BlurRadius / context.screenHeight, 0, 0)); context.command.BlitFullscreenTriangle(mipDowH, mipDownV, sheet, 0); lastDown = mipDownV; tw = Mathf.Max(tw / 2, 1); th = Mathf.Max(th / 2, 1); } // Upsample int lastUp = m_Pyramid[settings.Iteration - 1].down_vertical; for (int i = settings.Iteration - 2; i >= 0; i--) { int mipUpV = m_Pyramid[i].up_vertical; int mipUpH = m_Pyramid[i].up_horizontal; // horizontal blur sheet.properties.SetVector(ShaderIDs.BlurOffset, new Vector4(settings.BlurRadius / context.screenWidth, 0, 0, 0)); context.command.BlitFullscreenTriangle(lastUp, mipUpH, sheet, 0); // vertical blur sheet.properties.SetVector(ShaderIDs.BlurOffset, new Vector4(0, settings.BlurRadius / context.screenHeight, 0, 0)); context.command.BlitFullscreenTriangle(mipUpH, mipUpV, sheet, 0); lastUp = mipUpV; } // Render blurred texture in blend pass cmd.BlitFullscreenTriangle(lastUp, context.destination, sheet, 1); // Cleanup for (int i = 0; i < settings.Iteration; i++) { if (m_Pyramid[i].down_vertical != lastUp) { cmd.ReleaseTemporaryRT(m_Pyramid[i].down_vertical); } if (m_Pyramid[i].down_horizontal != lastUp) { cmd.ReleaseTemporaryRT(m_Pyramid[i].down_horizontal); } if (m_Pyramid[i].up_horizontal != lastUp) { cmd.ReleaseTemporaryRT(m_Pyramid[i].up_horizontal); } if (m_Pyramid[i].up_vertical != lastUp) { cmd.ReleaseTemporaryRT(m_Pyramid[i].up_vertical); } } cmd.EndSample(PROFILER_TAG); }
public override void Render(PostProcessRenderContext context) { var sheet = context.propertySheets.Get(Shader.Find("Hidden/Custom/RayMarchingCloud")); //sheet.properties.SetColor(Shader.PropertyToID("_color"), settings.color); Matrix4x4 projectionMatrix = GL.GetGPUProjectionMatrix(context.camera.projectionMatrix, false); sheet.properties.SetMatrix(Shader.PropertyToID("_InverseProjectionMatrix"), projectionMatrix.inverse); sheet.properties.SetMatrix(Shader.PropertyToID("_InverseViewMatrix"), context.camera.cameraToWorldMatrix); sheet.properties.SetVector(Shader.PropertyToID("_CameraDir"), context.camera.transform.forward); //sheet.properties.SetVector(Shader.PropertyToID("_WorldSpaceLightPos0"), LightDir.transform.forward); if (cloudTransform != null) { boundsMin = cloudTransform.position - cloudTransform.localScale / 2; boundsMax = cloudTransform.position + cloudTransform.localScale / 2; sheet.properties.SetVector(Shader.PropertyToID("_boundsMin"), boundsMin); sheet.properties.SetVector(Shader.PropertyToID("_boundsMax"), boundsMax); } if (settings.noise3D.value != null) { sheet.properties.SetTexture(Shader.PropertyToID("_noiseTex"), settings.noise3D.value); } if (settings.noiseDetail3D.value != null) { sheet.properties.SetTexture(Shader.PropertyToID("_noiseDetail3D"), settings.noiseDetail3D.value); } if (settings.weatherMap.value != null) { sheet.properties.SetTexture(Shader.PropertyToID("_weatherMap"), settings.weatherMap.value); } if (settings.maskNoise.value != null) { sheet.properties.SetTexture(Shader.PropertyToID("_maskNoise"), settings.maskNoise.value); } if (settings.blueNoise.value != null) { Vector4 screenUv = new Vector4( (float)context.screenWidth / (float)settings.blueNoise.value.width, (float)context.screenHeight / (float)settings.blueNoise.value.height, 0, 0); sheet.properties.SetVector(Shader.PropertyToID("_BlueNoiseCoords"), screenUv); sheet.properties.SetTexture(Shader.PropertyToID("_BlueNoise"), settings.blueNoise.value); } sheet.properties.SetFloat(Shader.PropertyToID("_shapeTiling"), settings.shapeTiling.value); sheet.properties.SetFloat(Shader.PropertyToID("_detailTiling"), settings.detailTiling.value); sheet.properties.SetFloat(Shader.PropertyToID("_step"), settings.step.value); sheet.properties.SetFloat(Shader.PropertyToID("_rayStep"), settings.rayStep.value); //sheet.properties.SetFloat(Shader.PropertyToID("_dstTravelled"),settings.dstTravelled.value); sheet.properties.SetFloat(Shader.PropertyToID("_densityOffset"), settings.densityOffset.value); sheet.properties.SetFloat(Shader.PropertyToID("_densityMultiplier"), settings.densityMultiplier.value); //sheet.properties.SetInt(Shader.PropertyToID("_numStepsLight"), (int)settings.numStepsLight.value); sheet.properties.SetColor(Shader.PropertyToID("_colA"), settings.colA.value); sheet.properties.SetColor(Shader.PropertyToID("_colB"), settings.colB.value); sheet.properties.SetFloat(Shader.PropertyToID("_colorOffset1"), settings.colorOffset1.value); sheet.properties.SetFloat(Shader.PropertyToID("_colorOffset2"), settings.colorOffset2.value); sheet.properties.SetFloat(Shader.PropertyToID("_lightAbsorptionTowardSun"), settings.lightAbsorptionTowardSun.value); sheet.properties.SetFloat(Shader.PropertyToID("_lightAbsorptionThroughCloud"), settings.lightAbsorptionThroughCloud.value); sheet.properties.SetFloat(Shader.PropertyToID("_rayOffsetStrength"), settings.rayOffsetStrength.value); sheet.properties.SetVector(Shader.PropertyToID("_phaseParams"), settings.phaseParams.value); sheet.properties.SetVector(Shader.PropertyToID("_xy_Speed_zw_Warp"), settings.xy_Speed_zw_Warp.value); sheet.properties.SetVector(Shader.PropertyToID("_shapeNoiseWeights"), settings.shapeNoiseWeights.value); sheet.properties.SetFloat(Shader.PropertyToID("_heightWeights"), settings.heightWeights.value); sheet.properties.SetFloat(Shader.PropertyToID("_detailWeights"), settings.detailWeights.value); sheet.properties.SetFloat(Shader.PropertyToID("_detailNoiseWeight"), settings.detailNoiseWeight.value); Quaternion rotation = Quaternion.Euler(cloudTransform.eulerAngles); Vector3 scaleMatrix = cloudTransform.localScale * 0.1f; scaleMatrix = new Vector3(1 / scaleMatrix.x, 1 / scaleMatrix.y, 1 / scaleMatrix.z); Matrix4x4 TRSMatrix = Matrix4x4.TRS(cloudTransform.position, rotation, scaleMatrix); sheet.properties.SetMatrix(Shader.PropertyToID("_TRSMatrix"), TRSMatrix); var cmd = context.command; //降深度采样 var DownsampleDepthID = Shader.PropertyToID("_DownsampleTemp"); context.GetScreenSpaceTemporaryRT(cmd, DownsampleDepthID, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Point, context.screenWidth / settings.Downsample.value, context.screenHeight / settings.Downsample.value); cmd.BlitFullscreenTriangle(context.source, DownsampleDepthID, sheet, 1); cmd.SetGlobalTexture(Shader.PropertyToID("_LowDepthTexture"), DownsampleDepthID); //降cloud分辨率 并使用第1个pass 渲染云 var DownsampleColorID = Shader.PropertyToID("_DownsampleColor"); context.GetScreenSpaceTemporaryRT(cmd, DownsampleColorID, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Trilinear, context.screenWidth / settings.Downsample.value, context.screenHeight / settings.Downsample.value); cmd.BlitFullscreenTriangle(context.source, DownsampleColorID, sheet, 0); //降分辨率后的云设置回_DownsampleColor cmd.SetGlobalTexture(Shader.PropertyToID("_DownsampleColor"), DownsampleColorID); //使用第0个Pass 合成 context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, 2); cmd.ReleaseTemporaryRT(DownsampleColorID); cmd.ReleaseTemporaryRT(DownsampleDepthID); }