285 if (_shader && _vertexBuffer && _vertexFormat && _blendState &&
286 _depthState && _depthStencilState) {
292 definition.
name =
"ComposePass";
293 definition.
vshader =
"composeVertex";
294 definition.
fshader =
"composeFragment";
295 _shader =
createShader(_device, definition, COMPOSE_SOURCE);
298 if (!_vertexFormat) {
299 _vertexFormat = std::make_shared<VertexFormat>(
static_cast<int>(14 *
sizeof(
float)),
true,
false);
302 if (!_vertexBuffer && _vertexFormat) {
307 constexpr float vertexData[3 * 14] = {
309 -1.0f, -1.0f, 0.0f, 0, 0, 1, 0.0f, 1.0f, 1, 0, 0, 1, 0.0f, 1.0f,
310 3.0f, -1.0f, 0.0f, 0, 0, 1, 2.0f, 1.0f, 1, 0, 0, 1, 0.0f, 1.0f,
311 -1.0f, 3.0f, 0.0f, 0, 0, 1, 0.0f,-1.0f, 1, 0, 0, 1, 0.0f,-1.0f
315 options.
data.resize(
sizeof(vertexData));
316 std::memcpy(options.
data.data(), vertexData,
sizeof(vertexData));
317 _vertexBuffer = _device->createVertexBuffer(_vertexFormat, 3, options);
321 _blendState = std::make_shared<BlendState>();
324 _depthState = std::make_shared<DepthState>();
326 if (!_depthStencilState && _device->raw()) {
327 auto* depthDesc = MTL::DepthStencilDescriptor::alloc()->init();
328 depthDesc->setDepthCompareFunction(MTL::CompareFunctionAlways);
329 depthDesc->setDepthWriteEnabled(
false);
330 _depthStencilState = _device->raw()->newDepthStencilState(depthDesc);
331 depthDesc->release();
337 const std::vector<std::shared_ptr<MetalBindGroupFormat>>& bindGroupFormats,
338 MTL::SamplerState* defaultSampler)
344 if (!_shader || !_vertexBuffer || !_vertexFormat || !_blendState || !_depthState) {
354 auto pipelineState = pipeline->
get(primitive, _vertexFormat,
nullptr, -1, _shader, renderTarget,
356 if (!pipelineState) {
361 if (!vb || !vb->raw()) {
365 encoder->setRenderPipelineState(pipelineState);
366 encoder->setCullMode(MTL::CullModeNone);
367 encoder->setDepthStencilState(_depthStencilState);
368 encoder->setVertexBuffer(vb->raw(), 0, 0);
378 encoder->setFragmentTexture(sceneHw ? sceneHw->raw() :
nullptr, 0);
379 encoder->setFragmentTexture(bloomHw ? bloomHw->raw() :
nullptr, 1);
380 encoder->setFragmentTexture(cocHw ? cocHw->raw() :
nullptr, 2);
381 encoder->setFragmentTexture(blurHw ? blurHw->raw() :
nullptr, 3);
382 encoder->setFragmentTexture(ssaoHw ? ssaoHw->raw() :
nullptr, 4);
383 encoder->setFragmentTexture(depthHw ? depthHw->raw() :
nullptr, 5);
384 if (defaultSampler) {
385 encoder->setFragmentSamplerState(defaultSampler, 0);
388 struct alignas(16) ComposeUniforms
390 uint32_t dofEnabled = 0u;
391 uint32_t taaEnabled = 0u;
392 uint32_t ssaoEnabled = 0u;
393 uint32_t bloomEnabled = 0u;
394 uint32_t blurTextureUpscale = 0u;
395 float bloomIntensity = 0.01f;
396 float dofIntensity = 1.0f;
397 float sharpness = 0.0f;
398 uint32_t tonemapMode = 0u;
399 float exposure = 1.0f;
400 float sceneTextureInvRes[2] = {0.0f, 0.0f};
402 float dofFocusDistance = 1.0f;
403 float dofFocusRange = 0.5f;
404 float dofBlurRadius = 3.0f;
405 float dofCameraNear = 0.01f;
406 float dofCameraFar = 100.0f;
409 uint32_t vignetteEnabled = 0u;
410 float vignetteInner = 0.5f;
411 float vignetteOuter = 1.0f;
412 float vignetteCurvature = 0.5f;
413 float vignetteIntensity = 0.3f;
414 float vignetteColorR = 0.0f;
415 float vignetteColorG = 0.0f;
416 float vignetteColorB = 0.0f;
418 uniforms.dofEnabled = params.
dofEnabled ? 1u : 0u;
419 uniforms.taaEnabled = params.
taaEnabled ? 1u : 0u;
420 uniforms.ssaoEnabled = params.
ssaoTexture ? 1u : 0u;
426 uniforms.tonemapMode =
static_cast<uint32_t
>(params.
toneMapping);
427 uniforms.exposure = params.
exposure;
429 uniforms.sceneTextureInvRes[0] = 1.0f /
static_cast<float>(params.
sceneTexture->
width());
430 uniforms.sceneTextureInvRes[1] = 1.0f /
static_cast<float>(params.
sceneTexture->
height());
449 encoder->setFragmentBytes(&uniforms,
sizeof(ComposeUniforms), 5);
450 encoder->drawPrimitives(MTL::PrimitiveTypeTriangle,
static_cast<NS::UInteger
>(0),
static_cast<NS::UInteger
>(3));
451 _device->recordDrawCall();
gpu::HardwareTexture * impl() const