private void CalculateMatrices( HDCamera targetCamera, ViewportSettings viewportSettings, out Matrix4x4 proj, out Matrix4x4 invProj, out Matrix4x4 invView, out Matrix4x4 invViewProj, out Matrix4x4 solidRenderMvp) { ((HDRenderPipeline)RenderPipelineManager.currentPipeline).GetGlobalShaderMatrices(out var cameraView, out proj); if (SolidFovReprojection) { var mul = 1 / GetFovReprojectionMultiplier(viewportSettings); proj[0, 0] *= mul; proj[1, 1] *= mul; } invProj = proj.inverse; invView = cameraView.inverse; invViewProj = (proj * cameraView).inverse; var m = transform.localToWorldMatrix; var v = targetCamera.camera.worldToCameraMatrix; solidRenderMvp = proj * v * m; }
private float GetFovReprojectionMultiplier(ViewportSettings viewportSettings) { if (!SolidFovReprojection) { return(1f); } var originalFov = viewportSettings.fieldOfView; var extendedFov = originalFov * ReprojectionRatio; return(Mathf.Tan(0.5f * extendedFov * Mathf.Deg2Rad) / Mathf.Tan(0.5f * originalFov * Mathf.Deg2Rad)); }
private Vector4 GetInverseUvFovReprojectionVector(ViewportSettings viewportSettings) { if (!SolidFovReprojection) { return(new Vector4(1f, 0f, 0f, 0f)); } var vec = GetFovReprojectionVector(viewportSettings); var width = viewportSettings.width; var height = viewportSettings.height; return(new Vector4(1.0f / vec.x, -vec.y / vec.x / width, -vec.z / vec.x / height)); }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { var vi = new ViewInfo(doc.Views.ActiveView.ActiveViewport); var vpi = vi.Viewport; var vud = vpi.UserData.Find(typeof(ViewportSettings)) as ViewportSettings; if (vud == null) { var nvud = new ViewportSettings(); vpi.UserData.Add(nvud); } return(Result.Success); }
private Vector4 GetFovReprojectionVector(ViewportSettings viewportSettings) { if (!SolidFovReprojection) { return(new Vector4(1f, 0f, 0f, 0f)); } var mult = GetFovReprojectionMultiplier(viewportSettings); var width = viewportSettings.width; var height = viewportSettings.height; var revMult = 1f / mult; var border = 0.5f * (1 - revMult); return(new Vector4(revMult, width * border, height * border, 0f)); }
private void RenderAsSolid(CommandBuffer cmd, HDCamera targetCamera, RenderTargetIdentifier[] rtIds, RTHandle depthBuffer, RTHandle cameraColorBuffer) { // More than 1 RT currently means that render is targeting GBuffer var targetGBuffer = rtIds.Length > 1; var calculateNormals = CalculateNormals; var smoothNormals = SmoothNormals && calculateNormals; var unlitShadows = CalculateNormals && Lighting == LightingMode.ShadowReceiver; var viewportSettings = new ViewportSettings(targetCamera.actualWidth, targetCamera.actualHeight, targetCamera.camera.fieldOfView); CoreUtils.SetKeyword(cmd, PointCloudShaderIDs.SolidCompose.TargetGBufferKeyword, targetGBuffer); CoreUtils.SetKeyword(cmd, PointCloudShaderIDs.SolidCompose.UnlitShadowsKeyword, unlitShadows); RenderSolidCore(cmd, targetCamera, cameraColorBuffer, calculateNormals, smoothNormals, viewportSettings); // One texture can't be set as target and read from at the same time - copy needed depth data var depthCopy = Resources.GetRTHandle(RTUsage.DepthCopy); cmd.CopyTexture(depthBuffer, depthCopy); cmd.SetGlobalTexture(PointCloudShaderIDs.SolidCompose.ColorTexture, Resources.GetRTHandle(RTUsage.ColorBuffer)); cmd.SetGlobalTexture(PointCloudShaderIDs.SolidCompose.NormalTexture, Resources.GetRTHandle(RTUsage.Generic0)); cmd.SetGlobalTexture(PointCloudShaderIDs.SolidCompose.OriginalDepth, depthCopy); cmd.SetGlobalVector(PointCloudShaderIDs.SolidCompose.ReprojectionVector, GetFovReprojectionVector(viewportSettings)); var composePass = Resources.Passes.solidCompose; CoreUtils.SetRenderTarget(cmd, rtIds, depthBuffer); CoreUtils.DrawFullScreen(cmd, Resources.SolidComposeMaterial, shaderPassId: composePass); // cmd.CopyTexture(depthBuffer, rtDepthCopy); // SolidBlitMaterial.SetTexture(PointCloudShaderIDs.SolidCompose.OriginalDepth, rtDepthCopy); // SolidBlitMaterial.SetTexture(PointCloudShaderIDs.SolidCompose.ColorTexture, rtColor); // SolidBlitMaterial.SetVector(PointCloudShaderIDs.SolidCompose.ReprojectionVector, GetFovReprojectionVector(targetCamera.camera)); // var composePass = SolidBlitMaterial.FindPass("Point Cloud Debug Compose"); // // CoreUtils.SetRenderTarget(cmd, rtIds, depthBuffer); // CoreUtils.DrawFullScreen(cmd, SolidBlitMaterial, shaderPassId: composePass); }
private void RenderSolidCore( CommandBuffer cmd, HDCamera targetCamera, RTHandle cameraColorBuffer, bool calculateNormals, bool smoothNormals, ViewportSettings viewportSettings) { var rt = Resources.GetRTHandle(RTUsage.PointRender); var rt1 = Resources.GetRTHandle(RTUsage.Generic0); var rt2 = Resources.GetRTHandle(RTUsage.Generic1); var rtColor = Resources.GetRTHandle(RTUsage.ColorBuffer); var rtDepth = Resources.GetRTHandle(RTUsage.DepthBuffer); var rtDepth2 = Resources.GetRTHandle(RTUsage.DepthBuffer2); // TODO: handle resolutions above reference size // Custom cubemap target can have resolution higher than RT reference size, in which case it will be cut var width = viewportSettings.width; var height = viewportSettings.height; var refSize = rt.referenceSize; var msaaSamples = ((HDRenderPipeline)RenderPipelineManager.currentPipeline).MSAASamples; // TODO: verify if this is still needed after updating HDRP above 10.3.2 // In previous versions (7.3) viewport size was updated automatically - now it has to be manually managed // This can have critical performance impact if new MSAA samples settings don't not match current settings RTHandles.SetReferenceSize(width, height, msaaSamples); var resolution = new Vector2Int(width, height); var rtHandleRefSize = new Vector2Int(RTHandles.maxWidth, RTHandles.maxHeight); var refToCurrent = new Vector2((float)rtHandleRefSize.x / width, (float)rtHandleRefSize.y / height); var fov = viewportSettings.fieldOfView; if (SolidFovReprojection) { fov *= ReprojectionRatio; } var size = Math.Max(width, height); var maxLevel = 0; while (size >> maxLevel >= 16) { maxLevel++; } CalculateMatrices(targetCamera, viewportSettings, out var projMatrix, out var invProjMatrix, out var invViewMatrix, out var invViewProjMatrix, out var solidRenderMvp); var cs = Resources.SolidComputeShader; cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.TextureSize, new Vector4(width, height, 1f / width, 1f / height)); cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.RefSizeMult, new Vector4(refToCurrent.x, refToCurrent.y, 1 / refToCurrent.x, 1 / refToCurrent.y)); cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.FullRTSize, new Vector4(refSize.x - 1, refSize.y - 1, 1f / refSize.x, 1f / refSize.y)); cmd.SetComputeFloatParam(cs, PointCloudShaderIDs.SolidCompute.FarPlane, targetCamera.camera.farClipPlane); cmd.SetComputeMatrixParam(cs, PointCloudShaderIDs.SolidCompute.ProjectionMatrix, projMatrix); cmd.SetComputeMatrixParam(cs, PointCloudShaderIDs.SolidCompute.InverseProjectionMatrix, invProjMatrix); cmd.SetComputeMatrixParam(cs, PointCloudShaderIDs.SolidCompute.InverseViewMatrix, invViewMatrix); cmd.SetComputeMatrixParam(cs, PointCloudShaderIDs.SolidCompute.InverseVPMatrix, invViewProjMatrix); cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.InverseReprojectionVector, GetInverseUvFovReprojectionVector(viewportSettings)); cmd.SetGlobalBuffer(PointCloudShaderIDs.Shared.Buffer, GetBufferForCamera(targetCamera)); cmd.SetGlobalInt(PointCloudShaderIDs.Shared.Colorize, (int)Colorize); cmd.SetGlobalFloat(PointCloudShaderIDs.Shared.MinHeight, Bounds.min.y); cmd.SetGlobalFloat(PointCloudShaderIDs.Shared.MaxHeight, Bounds.max.y); cmd.SetGlobalMatrix(PointCloudShaderIDs.SolidRender.MVPMatrix, solidRenderMvp); if (ForcedFill == ForcedFillMode.HorizonAndDepth || SolidRemoveHidden && HiddenPointRemoval == HprMode.DepthPrepass) { SetCirclesMaterialProperties(cmd, targetCamera); CoreUtils.SetRenderTarget(cmd, rt2, rtDepth2); CoreUtils.ClearRenderTarget(cmd, ClearFlag.All, Color.clear); var pass = Resources.Passes.circlesDepthPrepass; cmd.DrawProcedural(Matrix4x4.identity, Resources.CirclesMaterial, pass, MeshTopology.Points, GetPointCountForCamera(targetCamera)); } if (ForcedFill == ForcedFillMode.HorizonAndDepth) { var setupCopyFill = Resources.Kernels.Setup; cmd.SetComputeTextureParam(cs, setupCopyFill, PointCloudShaderIDs.SolidCompute.SetupCopy.InputPosition, rtDepth2, 0); cmd.SetComputeTextureParam(cs, setupCopyFill, PointCloudShaderIDs.SolidCompute.SetupCopy.OutputPosition, rt1, 0); cmd.DispatchCompute(cs, setupCopyFill, GetGroupSize(width, 8), GetGroupSize(height, 8), 1); // Prepare rough depth with hole fixing var downsample = Resources.Kernels.Downsample; for (var i = 1; i <= maxLevel + 3; i++) { GetMipData(resolution, i - 1, out var mipRes, out var mipVec); cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.MipTextureSize, mipVec); cmd.SetComputeTextureParam(cs, downsample, PointCloudShaderIDs.SolidCompute.Downsample.InputPosition, rt1, i - 1); cmd.SetComputeTextureParam(cs, downsample, PointCloudShaderIDs.SolidCompute.Downsample.OutputPosition, rt1, i); cmd.DispatchCompute(cs, downsample, GetGroupSize(mipRes.x, 16), GetGroupSize(mipRes.y, 16), 1); } var fillHolesKernel = Resources.Kernels.FillRoughDepth; GetMipData(resolution, 4, out var gmipRes, out var higherMipVec); GetMipData(resolution, 4 - 1, out _, out var gmipVec); cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.MipTextureSize, gmipVec); cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.HigherMipTextureSize, higherMipVec); cmd.SetComputeTextureParam(cs, fillHolesKernel, PointCloudShaderIDs.SolidCompute.FillRoughHoles.TexIn, rt1); cmd.SetComputeTextureParam(cs, fillHolesKernel, PointCloudShaderIDs.SolidCompute.FillRoughHoles.TexOut, rt2, 4); cmd.DispatchCompute(cs, fillHolesKernel, GetGroupSize(gmipRes.x, 8), GetGroupSize(gmipRes.y, 8), 1); } CoreUtils.SetRenderTarget(cmd, rt, rtDepth); CoreUtils.ClearRenderTarget(cmd, ClearFlag.All, Color.clear); cmd.DrawProcedural(Matrix4x4.identity, Resources.SolidRenderMaterial, 0, MeshTopology.Points, GetPointCountForCamera(targetCamera)); var setupCopy = Resources.Kernels.Setup; cmd.SetComputeTextureParam(cs, setupCopy, PointCloudShaderIDs.SolidCompute.SetupCopy.InputPosition, rtDepth, 0); cmd.SetComputeTextureParam(cs, setupCopy, PointCloudShaderIDs.SolidCompute.SetupCopy.OutputPosition, rt1, 0); cmd.DispatchCompute(cs, setupCopy, GetGroupSize(width, 8), GetGroupSize(height, 8), 1); var blendSky = DebugBlendSky && cameraColorBuffer != null; var skyBlend = Resources.Kernels.GetSkyBlendKernel(ForcedFill, blendSky); cmd.SetComputeTextureParam(cs, skyBlend, PointCloudShaderIDs.SolidCompute.SkyBlend.ViewPos, rt1, 0); cmd.SetComputeTextureParam(cs, skyBlend, PointCloudShaderIDs.SolidCompute.SkyBlend.ColorIn, rt, 0); cmd.SetComputeTextureParam(cs, skyBlend, PointCloudShaderIDs.SolidCompute.SkyBlend.ColorOut, rtColor, 0); if (blendSky) { cmd.SetComputeTextureParam(cs, skyBlend, PointCloudShaderIDs.SolidCompute.SkyBlend.PostSkyPreRenderTexture, cameraColorBuffer, 0); } if (ForcedFill == ForcedFillMode.HorizonAndDepth) { cmd.SetComputeTextureParam(cs, skyBlend, PointCloudShaderIDs.SolidCompute.SkyBlend.RoughDepth, rt2, 0); } cmd.SetComputeFloatParam(cs, PointCloudShaderIDs.SolidCompute.SkyBlend.HorizonThreshold, DebugFillThreshold); cmd.DispatchCompute(cs, skyBlend, GetGroupSize(width, 8), GetGroupSize(height, 8), 1); if (SolidRemoveHidden) { switch (HiddenPointRemoval) { case HprMode.ScreenSpace: { var downsample = Resources.Kernels.Downsample; for (var i = 1; i <= maxLevel + 3; i++) { GetMipData(resolution, i - 1, out var mipRes, out var mipVec); cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.MipTextureSize, mipVec); cmd.SetComputeTextureParam(cs, downsample, PointCloudShaderIDs.SolidCompute.Downsample.InputPosition, rt1, i - 1); cmd.SetComputeTextureParam(cs, downsample, PointCloudShaderIDs.SolidCompute.Downsample.OutputPosition, rt1, i); cmd.DispatchCompute(cs, downsample, GetGroupSize(mipRes.x, 16), GetGroupSize(mipRes.y, 16), 1); } DebugSolidFixedLevel = Math.Min(Math.Max(DebugSolidFixedLevel, 0), maxLevel); var removeHidden = Resources.Kernels.GetRemoveHiddenKernel(DebugShowRemoveHiddenCascades); var removeHiddenMagic = RemoveHiddenCascadeOffset * height * 0.5f / Mathf.Tan(0.5f * fov * Mathf.Deg2Rad); cmd.SetComputeIntParam(cs, PointCloudShaderIDs.SolidCompute.RemoveHidden.LevelCount, maxLevel); cmd.SetComputeTextureParam(cs, removeHidden, PointCloudShaderIDs.SolidCompute.RemoveHidden.Position, rt1); cmd.SetComputeTextureParam(cs, removeHidden, PointCloudShaderIDs.SolidCompute.RemoveHidden.PositionRough, rt1); cmd.SetComputeTextureParam(cs, removeHidden, PointCloudShaderIDs.SolidCompute.RemoveHidden.Color, rtColor, 0); cmd.SetComputeFloatParam(cs, PointCloudShaderIDs.SolidCompute.RemoveHidden.CascadesOffset, removeHiddenMagic); cmd.SetComputeFloatParam(cs, PointCloudShaderIDs.SolidCompute.RemoveHidden.CascadesSize, RemoveHiddenCascadeSize); cmd.SetComputeIntParam(cs, PointCloudShaderIDs.SolidCompute.RemoveHidden.FixedLevel, DebugSolidFixedLevel); cmd.DispatchCompute(cs, removeHidden, GetGroupSize(width, 8), GetGroupSize(height, 8), 1); } break; case HprMode.DepthPrepass: { var removeHidden = Resources.Kernels.RemoveHiddenDepthPrepass; cmd.SetComputeTextureParam(cs, removeHidden, PointCloudShaderIDs.SolidCompute.RemoveHidden.Position, rt1); cmd.SetComputeTextureParam(cs, removeHidden, PointCloudShaderIDs.SolidCompute.RemoveHidden.EarlyDepth, rtDepth2, 0); cmd.SetComputeTextureParam(cs, removeHidden, PointCloudShaderIDs.SolidCompute.RemoveHidden.Color, rtColor, 0); cmd.SetComputeFloatParam(cs, PointCloudShaderIDs.SolidCompute.RemoveHidden.PointScale, AbsoluteSize); cmd.DispatchCompute(cs, removeHidden, GetGroupSize(width, 8), GetGroupSize(height, 8), 1); } break; default: throw new ArgumentOutOfRangeException(); } } if (DebugSolidPullPush) { var pullKernel = Resources.Kernels.Pull; cmd.SetComputeFloatParam(cs, PointCloudShaderIDs.SolidCompute.PullKernel.FilterExponent, DebugSolidPullParam); for (var i = 1; i <= maxLevel; i++) { GetMipData(resolution, i, out var mipRes, out var higherMipVec); GetMipData(resolution, i - 1, out _, out var mipVec); cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.MipTextureSize, mipVec); cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.HigherMipTextureSize, higherMipVec); cmd.SetComputeIntParam(cs, PointCloudShaderIDs.SolidCompute.PullKernel.SkipWeightMul, i == maxLevel ? 1 : 0); cmd.SetComputeTextureParam(cs, pullKernel, PointCloudShaderIDs.SolidCompute.PullKernel.InputColor, rtColor, i - 1); cmd.SetComputeTextureParam(cs, pullKernel, PointCloudShaderIDs.SolidCompute.PullKernel.OutputColor, rtColor, i); cmd.DispatchCompute(cs, pullKernel, GetGroupSize(mipRes.x, 8), GetGroupSize(mipRes.y, 8), 1); } var pushKernel = Resources.Kernels.Push; for (var i = maxLevel; i > 0; i--) { GetMipData(resolution, i - 1, out var mipRes, out var mipVec); GetMipData(resolution, i, out _, out var lowerMipVec); cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.MipTextureSize, mipVec); cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.HigherMipTextureSize, lowerMipVec); cmd.SetComputeIntParam(cs, PointCloudShaderIDs.SolidCompute.PushKernel.InputLevel, i); cmd.SetComputeTextureParam(cs, pushKernel, PointCloudShaderIDs.SolidCompute.PushKernel.InputColor, rtColor, i); cmd.SetComputeTextureParam(cs, pushKernel, PointCloudShaderIDs.SolidCompute.PushKernel.OutputColor, rtColor, i - 1); cmd.DispatchCompute(cs, pushKernel, GetGroupSize(mipRes.x, 8), GetGroupSize(mipRes.y, 8), 1); } if (calculateNormals) { var calculateNormalsKernel = Resources.Kernels.CalculateNormals; var normalsTarget = smoothNormals ? rt2 : rt1; for (var i = 0; i < maxLevel; ++i) { GetMipData(resolution, i, out var mipRes, out var mipVec); cmd.SetComputeVectorParam(cs, PointCloudShaderIDs.SolidCompute.MipTextureSize, mipVec); cmd.SetComputeIntParam(cs, PointCloudShaderIDs.SolidCompute.CalculateNormals.InputLevel, i); cmd.SetComputeTextureParam(cs, calculateNormalsKernel, PointCloudShaderIDs.SolidCompute.CalculateNormals.Input, rtColor); cmd.SetComputeTextureParam(cs, calculateNormalsKernel, PointCloudShaderIDs.SolidCompute.CalculateNormals.Output, normalsTarget, i); cmd.DispatchCompute(cs, calculateNormalsKernel, GetGroupSize(mipRes.x, 8), GetGroupSize(mipRes.x, 8), 1); } if (smoothNormals) { var smoothNormalsKernel = Resources.Kernels.GetSmoothNormalsKernel(DebugShowSmoothNormalsCascades); var smoothNormalsMagic = SmoothNormalsCascadeOffset * height * 0.5f / Mathf.Tan(0.5f * fov * Mathf.Deg2Rad); cmd.SetComputeTextureParam(cs, smoothNormalsKernel, PointCloudShaderIDs.SolidCompute.SmoothNormals.Input, rt2); cmd.SetComputeTextureParam(cs, smoothNormalsKernel, PointCloudShaderIDs.SolidCompute.SmoothNormals.Output, rt1, 0); cmd.SetComputeFloatParam(cs, PointCloudShaderIDs.SolidCompute.SmoothNormals.CascadesOffset, smoothNormalsMagic); cmd.SetComputeFloatParam(cs, PointCloudShaderIDs.SolidCompute.SmoothNormals.CascadesSize, SmoothNormalsCascadeSize); if (DebugShowSmoothNormalsCascades) { cmd.SetComputeTextureParam(cs, smoothNormalsKernel, PointCloudShaderIDs.SolidCompute.SmoothNormals.ColorDebug, rtColor, 0); } cmd.DispatchCompute(cs, smoothNormalsKernel, GetGroupSize(width, 8), GetGroupSize(height, 8), 1); } } } }