| 124 | } |
| 125 | |
| 126 | GPUTexture* ScreenSpaceReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* reflectionsRT, GPUTextureView* lightBuffer) |
| 127 | { |
| 128 | // Skip pass if resources aren't ready |
| 129 | if (checkIfSkipPass()) |
| 130 | return nullptr; |
| 131 | const RenderView& view = renderContext.View; |
| 132 | RenderBuffers* buffers = renderContext.Buffers; |
| 133 | |
| 134 | // TODO: add support for SSR in ortho projection |
| 135 | if (view.IsOrthographicProjection()) |
| 136 | return nullptr; |
| 137 | |
| 138 | PROFILE_GPU_CPU("Screen Space Reflections"); |
| 139 | |
| 140 | // Cache data |
| 141 | auto device = GPUDevice::Instance; |
| 142 | auto context = device->GetMainContext(); |
| 143 | const auto shader = _shader->GetShader(); |
| 144 | auto cb = shader->GetCB(0); |
| 145 | auto& settings = renderContext.List->Settings.ScreenSpaceReflections; |
| 146 | const bool useTemporal = settings.TemporalEffect && !renderContext.Task->IsCameraCut && renderContext.List->Setup.UseMotionVectors; |
| 147 | |
| 148 | // Prepare resolutions for passes |
| 149 | const int32 width = buffers->GetWidth(); |
| 150 | const int32 height = buffers->GetHeight(); |
| 151 | if (width < 4 || height < 4) |
| 152 | return nullptr; |
| 153 | const int32 traceWidth = RenderTools::GetResolution(width, settings.RayTracePassResolution); |
| 154 | const int32 traceHeight = RenderTools::GetResolution(height, settings.RayTracePassResolution); |
| 155 | const int32 resolveWidth = RenderTools::GetResolution(width, settings.ResolvePassResolution); |
| 156 | const int32 resolveHeight = RenderTools::GetResolution(height, settings.ResolvePassResolution); |
| 157 | const int32 colorBufferWidth = RenderTools::GetResolution(width, ResolutionMode::Half); |
| 158 | const int32 colorBufferHeight = RenderTools::GetResolution(height, ResolutionMode::Half); |
| 159 | const auto colorBufferMips = MipLevelsCount(colorBufferWidth, colorBufferHeight); |
| 160 | |
| 161 | // Prepare buffers |
| 162 | GPUTexture* colorBuffer0, *colorBuffer1; |
| 163 | if (settings.UseColorBufferMips) |
| 164 | { |
| 165 | auto tempDesc = GPUTextureDescription::New2D(colorBufferWidth, colorBufferHeight, 0, PixelFormat::R11G11B10_Float, GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget | GPUTextureFlags::PerMipViews); |
| 166 | colorBuffer0 = RenderTargetPool::Get(tempDesc); |
| 167 | RENDER_TARGET_POOL_SET_NAME(colorBuffer0, "SSR.ColorBuffer0"); |
| 168 | // TODO: maybe allocate colorBuffer1 smaller because mip0 is not used (the same as PostProcessingPass for Bloom), keep in sync to use the same buffer in frame |
| 169 | colorBuffer1 = RenderTargetPool::Get(tempDesc); |
| 170 | RENDER_TARGET_POOL_SET_NAME(colorBuffer1, "SSR.ColorBuffer1"); |
| 171 | } |
| 172 | else |
| 173 | { |
| 174 | // Single mip |
| 175 | auto tempDesc = GPUTextureDescription::New2D(colorBufferWidth, colorBufferHeight, 1, PixelFormat::R11G11B10_Float); |
| 176 | colorBuffer0 = RenderTargetPool::Get(tempDesc); |
| 177 | colorBuffer1 = nullptr; |
| 178 | } |
| 179 | GPUTexture* traceBuffer, *resolveBuffer; |
| 180 | { |
| 181 | auto tempDesc = GPUTextureDescription::New2D(traceWidth, traceHeight, PixelFormat::R16G16B16A16_Float); |
| 182 | traceBuffer = RenderTargetPool::Get(tempDesc); |
| 183 | RENDER_TARGET_POOL_SET_NAME(traceBuffer, "SSR.TraceBuffer"); |
nothing calls this directly
no test coverage detected