void CommandBuffer_FillApplyDeferred(CommandBuffer cb, TargetDesc target, bool logTarget) { cb.SetGlobalTexture("_AO_OcclusionTexture", m_occlusionRT); m_applyDeferredTargets[0] = BuiltinRenderTextureType.GBuffer0; m_applyDeferredTargets[1] = logTarget ? BuiltinRenderTextureType.GBuffer3 : BuiltinRenderTextureType.CameraTarget; if (!logTarget) { SetBlitTarget(cb, m_applyDeferredTargets, target.fullWidth, target.fullHeight); PerformBlit(cb, m_occlusionMat, ShaderPass.ApplyDeferred); } else { int gbufferAlbedoRT = SafeAllocateTemporaryRT(cb, "_AO_GBufferAlbedo", target.fullWidth, target.fullHeight, RenderTextureFormat.ARGB32); int gbufferEmissionRT = SafeAllocateTemporaryRT(cb, "_AO_GBufferEmission", target.fullWidth, target.fullHeight, RenderTextureFormat.ARGB32); cb.Blit(m_applyDeferredTargets[0], gbufferAlbedoRT); cb.Blit(m_applyDeferredTargets[1], gbufferEmissionRT); cb.SetGlobalTexture("_AO_GBufferAlbedo", gbufferAlbedoRT); cb.SetGlobalTexture("_AO_GBufferEmission", gbufferEmissionRT); SetBlitTarget(cb, m_applyDeferredTargets, target.fullWidth, target.fullHeight); PerformBlit(cb, m_occlusionMat, ShaderPass.ApplyDeferredLog); SafeReleaseTemporaryRT(cb, gbufferAlbedoRT); SafeReleaseTemporaryRT(cb, gbufferEmissionRT); } cb.SetRenderTarget(default(RenderTexture)); }
void CommandBuffer_Rebuild(TargetDesc target) { bool gbufferSource = (PerPixelNormals == PerPixelNormalSource.GBuffer || PerPixelNormals == PerPixelNormalSource.GBufferOctaEncoded); CommandBuffer cb = null; CameraEvent stage = gbufferSource ? CameraEvent.AfterLighting : CameraEvent.BeforeImageEffectsOpaque; if (ApplyMethod == ApplicationMethod.Debug) { cb = CommandBuffer_AllocateRegister(stage); CommandBuffer_FillComputeOcclusion(cb, target); CommandBuffer_FillApplyDebug(cb, target); } else { bool logTarget = (!m_camera.hdr && gbufferSource); stage = (ApplyMethod == ApplicationMethod.Deferred) ? CameraEvent.BeforeReflections : stage; cb = CommandBuffer_AllocateRegister(stage); CommandBuffer_FillComputeOcclusion(cb, target); if (ApplyMethod == ApplicationMethod.PostEffect) { CommandBuffer_FillApplyPostEffect(cb, target, logTarget); } else if (ApplyMethod == ApplicationMethod.Deferred) { CommandBuffer_FillApplyDeferred(cb, target, logTarget); } } }
void CommandBuffer_FillApplyPostEffect(CommandBuffer cb, TargetDesc target, bool logTarget) { cb.SetGlobalTexture("_AO_OcclusionTexture", m_occlusionRT); if (!logTarget) { SetBlitTarget(cb, BuiltinRenderTextureType.CameraTarget, target.fullWidth, target.fullHeight); PerformBlit(cb, m_occlusionMat, ShaderPass.ApplyPostEffect); } else { int gbufferEmissionRT = SafeAllocateTemporaryRT(cb, "_AO_GBufferEmission", target.fullWidth, target.fullHeight, RenderTextureFormat.ARGB32); cb.Blit(BuiltinRenderTextureType.GBuffer3, gbufferEmissionRT); cb.SetGlobalTexture("_AO_GBufferEmission", gbufferEmissionRT); SetBlitTarget(cb, BuiltinRenderTextureType.GBuffer3, target.fullWidth, target.fullHeight); PerformBlit(cb, m_occlusionMat, ShaderPass.ApplyPostEffectLog); SafeReleaseTemporaryRT(cb, gbufferEmissionRT); } cb.SetRenderTarget(default(RenderTexture)); }
void UpdateGlobalShaderConstants(TargetDesc target) { float fovRad = m_camera.fieldOfView * Mathf.Deg2Rad; Vector2 focalLen = new Vector2(1.0f / Mathf.Tan(fovRad * 0.5f) * (target.height / ( float )target.width), 1.0f / Mathf.Tan(fovRad * 0.5f)); Vector2 invFocalLen = new Vector2(1.0f / focalLen.x, 1.0f / focalLen.y); float projScale; if (m_camera.orthographic) { projScale = (( float )target.height) / m_camera.orthographicSize; } else { projScale = (( float )target.height) / (Mathf.Tan(fovRad * 0.5f) * 2.0f); } float bias = Mathf.Clamp(Bias, 0.0f, 1.0f); Shader.SetGlobalMatrix("_AO_CameraProj", GL.GetGPUProjectionMatrix(Matrix4x4.Ortho(0, 1, 0, 1, -1, 100), false)); Shader.SetGlobalMatrix("_AO_CameraView", m_camera.worldToCameraMatrix); Shader.SetGlobalVector("_AO_UVToView", new Vector4(2.0f * invFocalLen.x, -2.0f * invFocalLen.y, -1.0f * invFocalLen.x, 1.0f * invFocalLen.y)); Shader.SetGlobalFloat("_AO_NegRcpR2", -1.0f / (Radius * Radius)); Shader.SetGlobalFloat("_AO_RadiusToScreen", Radius * 0.5f * projScale); Shader.SetGlobalFloat("_AO_PowExponent", PowerExponent); Shader.SetGlobalFloat("_AO_Bias", bias); Shader.SetGlobalFloat("_AO_Multiplier", 1.0f / (1.0f - bias)); Shader.SetGlobalFloat("_AO_BlurSharpness", BlurSharpness); Shader.SetGlobalColor("_AO_Levels", new Color(Tint.r, Tint.g, Tint.b, Intensity)); }
void CommandBuffer_FillApplyDebug(CommandBuffer cb, TargetDesc target) { cb.SetGlobalTexture("_AO_OcclusionTexture", m_occlusionRT); SetBlitTarget(cb, BuiltinRenderTextureType.CameraTarget, target.fullWidth, target.fullHeight); PerformBlit(cb, m_occlusionMat, ShaderPass.ApplyDebug); cb.SetRenderTarget(default(RenderTexture)); }
void UpdateGlobalShaderConstants(TargetDesc target) { float fovRad = m_camera.fieldOfView * Mathf.Deg2Rad; Vector2 focalLen = new Vector2(1.0f / Mathf.Tan(fovRad * 0.5f) * (target.height / ( float )target.width), 1.0f / Mathf.Tan(fovRad * 0.5f)); Vector2 invFocalLen = new Vector2(1.0f / focalLen.x, 1.0f / focalLen.y); float projScale; if (m_camera.orthographic) { projScale = (( float )target.height) / m_camera.orthographicSize; } else { projScale = (( float )target.height) / (Mathf.Tan(fovRad * 0.5f) * 2.0f); } float bias = Mathf.Clamp(Bias, 0.0f, 1.0f); FadeStart = Mathf.Max(0.0f, FadeStart); FadeLength = Mathf.Max(0.01f, FadeLength); float rcpFadeLength = FadeEnabled ? 1.0f / FadeLength : 0.0f; Shader.SetGlobalMatrix("_AO_CameraProj", GL.GetGPUProjectionMatrix(Matrix4x4.Ortho(0, 1, 0, 1, -1, 100), false)); Shader.SetGlobalMatrix("_AO_CameraView", m_camera.worldToCameraMatrix); Shader.SetGlobalVector("_AO_UVToView", new Vector4(2.0f * invFocalLen.x, -2.0f * invFocalLen.y, -1.0f * invFocalLen.x, 1.0f * invFocalLen.y)); Shader.SetGlobalFloat("_AO_HalfProjScale", 0.5f * projScale); Shader.SetGlobalFloat("_AO_Radius", Radius); Shader.SetGlobalFloat("_AO_PowExponent", PowerExponent); Shader.SetGlobalFloat("_AO_Bias", bias); Shader.SetGlobalFloat("_AO_Multiplier", 1.0f / (1.0f - bias)); Shader.SetGlobalFloat("_AO_BlurSharpness", BlurSharpness); Shader.SetGlobalColor("_AO_Levels", new Color(Tint.r, Tint.g, Tint.b, Intensity)); Shader.SetGlobalVector("_AO_FadeParams", new Vector2(FadeStart, rcpFadeLength)); Shader.SetGlobalVector("_AO_FadeValues", new Vector3(FadeToIntensity, FadeToRadius, FadeToPowerExponent)); }
void CommandBuffer_Rebuild(TargetDesc target) { bool gbufferSource = (PerPixelNormals == PerPixelNormalSource.GBuffer || PerPixelNormals == PerPixelNormalSource.GBufferOctaEncoded); CommandBuffer cb = null; // NOTE: applying occlusion after lighting when using gbuffer normals avoids seethrough on forward materials in deferred mode CameraEvent stage = gbufferSource ? CameraEvent.AfterLighting : CameraEvent.BeforeImageEffectsOpaque; if (ApplyMethod == ApplicationMethod.Debug) { cb = CommandBuffer_AllocateRegister(stage); CommandBuffer_FillComputeOcclusion(cb, target); CommandBuffer_FillApplyDebug(cb, target); } else { #if UNITY_5_6_OR_NEWER bool hdr = m_camera.allowHDR; #else bool hdr = m_camera.hdr; #endif bool logTarget = (!hdr && gbufferSource); stage = (ApplyMethod == ApplicationMethod.Deferred) ? CameraEvent.BeforeReflections : stage; cb = CommandBuffer_AllocateRegister(stage); CommandBuffer_FillComputeOcclusion(cb, target); if (ApplyMethod == ApplicationMethod.PostEffect) { CommandBuffer_FillApplyPostEffect(cb, target, logTarget); } else if (ApplyMethod == ApplicationMethod.Deferred) { CommandBuffer_FillApplyDeferred(cb, target, logTarget); } } }
void CommandBuffer_FillComputeOcclusion(CommandBuffer cb, TargetDesc target) { CheckMaterial(); CheckRandomData(); cb.SetGlobalVector("_AO_Buffer_PadScale", new Vector4(target.padRatioWidth, target.padRatioHeight, 1.0f / target.padRatioWidth, 1.0f / target.padRatioHeight)); cb.SetGlobalVector("_AO_Buffer_TexelSize", new Vector4(1.0f / target.width, 1.0f / target.height, target.width, target.height)); cb.SetGlobalVector("_AO_QuarterBuffer_TexelSize", new Vector4(1.0f / target.quarterWidth, 1.0f / target.quarterHeight, target.quarterWidth, target.quarterHeight)); cb.SetGlobalFloat("_AO_MaxRadiusPixels", Mathf.Min(target.width, target.height)); if (m_occlusionRT == null || m_occlusionRT.width != target.width || m_occlusionRT.height != target.height || !m_occlusionRT.IsCreated()) { SafeReleaseRT(ref m_occlusionRT); m_occlusionRT = SafeAllocateRT("_AO_OcclusionTexture", target.width, target.height, RenderTextureFormat.RGHalf, RenderTextureReadWrite.Linear); } int smallOcclusionRT = -1; if (Downsample) { smallOcclusionRT = SafeAllocateTemporaryRT(cb, "_AO_SmallOcclusionTexture", target.width / 2, target.height / 2, RenderTextureFormat.RGHalf, RenderTextureReadWrite.Linear, FilterMode.Bilinear); } // Ambient Occlusion if (CacheAware && !Downsample) { int occlusionAtlasRT = SafeAllocateTemporaryRT(cb, "_AO_OcclusionAtlas", target.width, target.height, RenderTextureFormat.RGHalf, RenderTextureReadWrite.Linear); for (int i = 0; i < 16; i++) { m_depthLayerRT[i] = SafeAllocateTemporaryRT(cb, m_layerDepthNames[i], target.quarterWidth, target.quarterHeight, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear); m_normalLayerRT[i] = SafeAllocateTemporaryRT(cb, m_layerNormalNames[i], target.quarterWidth, target.quarterHeight, RenderTextureFormat.ARGB2101010, RenderTextureReadWrite.Linear); m_occlusionLayerRT[i] = SafeAllocateTemporaryRT(cb, m_layerOcclusionNames[i], target.quarterWidth, target.quarterHeight, RenderTextureFormat.RGHalf, RenderTextureReadWrite.Linear); } // Deinterleaved Normal + Depth for (int scan = 0; scan < 16; scan += m_mrtCount) { for (int i = 0; i < m_mrtCount; i++) { int layer = i + scan; int x = layer & 3; int y = layer >> 2; cb.SetGlobalVector(m_layerOffsetNames[i], new Vector2(x + 0.5f, y + 0.5f)); m_depthTargets[i] = m_depthLayerRT[layer]; m_normalTargets[i] = m_normalLayerRT[layer]; } SetBlitTarget(cb, m_depthTargets, target.quarterWidth, target.quarterHeight); PerformBlit(cb, m_occlusionMat, m_deinterleaveDepthPass); SetBlitTarget(cb, m_normalTargets, target.quarterWidth, target.quarterHeight); PerformBlit(cb, m_occlusionMat, m_deinterleaveNormalPass + ( int )PerPixelNormals); } // Deinterleaved Occlusion for (int i = 0; i < 16; i++) { cb.SetGlobalVector("_AO_LayerOffset", new Vector2((i & 3) + 0.5f, (i >> 2) + 0.5f)); cb.SetGlobalVector("_AO_LayerRandom", m_randomData[i]); cb.SetGlobalTexture("_AO_NormalTexture", m_normalLayerRT[i]); cb.SetGlobalTexture("_AO_DepthTexture", m_depthLayerRT[i]); SetBlitTarget(cb, m_occlusionLayerRT[i], target.quarterWidth, target.quarterHeight); PerformBlit(cb, m_occlusionMat, ShaderPass.OcclusionCache_Low + ( int )SampleCount); } // Reinterleave SetBlitTarget(cb, occlusionAtlasRT, target.width, target.height); for (int i = 0; i < 16; i++) { int dst_x = (i & 3) * target.quarterWidth; int dst_y = (i >> 2) * target.quarterHeight; PerformBlit(cb, m_occlusionLayerRT[i], target.quarterWidth, target.quarterHeight, m_copyMat, ShaderPass.Copy, dst_x, dst_y); } cb.SetGlobalTexture("_AO_OcclusionAtlas", occlusionAtlasRT); SetBlitTarget(cb, m_occlusionRT, target.width, target.height); PerformBlit(cb, m_occlusionMat, ShaderPass.Reinterleave); for (int i = 0; i < 16; i++) { SafeReleaseTemporaryRT(cb, m_occlusionLayerRT[i]); SafeReleaseTemporaryRT(cb, m_normalLayerRT[i]); SafeReleaseTemporaryRT(cb, m_depthLayerRT[i]); } SafeReleaseTemporaryRT(cb, occlusionAtlasRT); } else { m_occlusionMat.SetTexture("_AO_RandomTexture", m_randomTex); int occlusionPass = (ShaderPass.OcclusionLow_None + (( int )SampleCount) * PerPixelNormalSourceCount + (( int )PerPixelNormals)); if (Downsample) { cb.Blit((Texture)null, new RenderTargetIdentifier(smallOcclusionRT), m_occlusionMat, occlusionPass); SetBlitTarget(cb, m_occlusionRT, target.width, target.height); PerformBlit(cb, smallOcclusionRT, target.width / 2, target.height / 2, m_occlusionMat, ShaderPass.CombineDownsampledOcclusionDepth); } else { cb.Blit((Texture)null, m_occlusionRT, m_occlusionMat, occlusionPass); } } if (BlurEnabled) { int tempRT = SafeAllocateTemporaryRT(cb, "_AO_TEMP", target.width, target.height, RenderTextureFormat.RGHalf, RenderTextureReadWrite.Linear); // Apply Cross Bilateral Blur for (int i = 0; i < BlurPasses; i++) { SetBlitTarget(cb, tempRT, target.width, target.height); PerformBlit(cb, m_occlusionRT, target.width, target.height, m_blurMat, ShaderPass.BlurHorizontal1 + (BlurRadius - 1) * 2); SetBlitTarget(cb, m_occlusionRT, target.width, target.height); PerformBlit(cb, tempRT, target.width, target.height, m_blurMat, ShaderPass.BlurVertical1 + (BlurRadius - 1) * 2); } SafeReleaseTemporaryRT(cb, tempRT); } if (Downsample && smallOcclusionRT >= 0) { SafeReleaseTemporaryRT(cb, smallOcclusionRT); } cb.SetRenderTarget(default(RenderTexture)); }
public static extern void Compile([In] ref SourceDesc source, [In] ref TargetDesc target, out ResultDesc result);