Unity 6.3
0 онлайн 54 гостей 3 в системе
Вход

Устранение неисправностей с сценариями отображения с выходом HDR в URP

Выход с высоким динамическим диапазоном (HDR) изменяет входные данные для вашего скриптируемого прохода рендеринга, когда он применяет отображение тонов и преобразование цветового пространства. Эти изменения могут привести к тому, что ваш скриптируемый проход рендеринга даст неправильные результаты. Это означает, что при использовании HDR Output и скриптируемого прохода рендеринга, который происходит в точке впрыска AfterRenderingPostProcessing или после нее, вам необходимо учитывать изменения, которые производит HDR Output. Это также относится к случаям, когда вы хотите добавить накладки во время или после пост-обработки, например, UI или выход из других камер, потому что вам нужно работать с цветовой гаммой, полученной из HDR Output. Чтобы скриптируемый проход рендеринга работал с изменениями, которые производит HDR Output, вы должны вручную выполнить отображение тонов и преобразовать цветовое пространство в скрипте.

Однако, если вы добавите свой скриптируемый проход рендеринга в точке введения BeforeRenderingPostProcessing или до нее, вам не нужно вносить никаких изменений для совместимости с HDR Output. Это потому, что Unity выполняет ваш скриптируемый проход рендеринга до того, как он рендерингирует HDR Output.

Примечание: Вы можете избежать этой проблемы, если используете стек камер для рендеринга вывода камеры до того, как Unity выполнит отображение тонов. Unity затем применяет обработку вывода HDR к последней камере в стеке. Чтобы узнать, как настроить стек камер, см. Наложение камер.

Отображение тонов и преобразование цветового пространства в сценарии

Для того, чтобы скриптируемый проход рендеринга работал с изменениями, которые HDR Output делает в цветовом пространстве и динамическом диапазоне, используйте функцию SetupHDROutput для применения отображения тонов и преобразования цветового пространства к материалу, измененному скриптируемым проходом рендеринга:

  1. Откройте скрипт C#, который содержит Scriptable Render Pass, который вы хотите использовать с HDR Output.

  2. Добавить метод с именем SetupHDROutput к классу прохода рендеринга.

    Следующий скрипт дает пример того, как использовать функцию SetupHDROutput:

    class CustomFullScreenRenderPass : ScriptableRenderPass
    {
        // Leave your existing Render Pass code here
    
        static void SetupHDROutput(ref CameraData cameraData, Material material)
        {
            // This is where most HDR related code is added
        }
    }
    
  3. Добавьте инструкцию if, чтобы проверить, активен ли HDR Output и включена ли на камере пост-обработка. Если ни одно из условий не выполнено, отключите ключевые слова шейдера HDR Output, чтобы уменьшить использование ресурсов.

    static void SetupHDROutput(ref CameraData cameraData, Material material)
    {
        // If post processing is enabled, color grading has already applied tone mapping
        // As a result the input here will be in the display colorspace (Rec2020, P3, etc) and in nits
        if (cameraData.isHDROutputActive && cameraData.postProcessEnabled)
        {
    
        }
        else
        {
            // If HDR output is disabled, disable HDR output-related keywords
            // If post processing is disabled, the final pass will do the color conversion so there is
            // no need to account for HDR Output
            material.DisableKeyword(HDROutputUtils.ShaderKeywords.HDR_INPUT);
        }
    }
    
  4. Создайте переменные для получения и хранения информации о яркости с дисплея, как показано ниже.

    if (cameraData.isHDROutputActive && cameraData.postProcessEnabled)
    {
        // Get luminance information from the display, these define the dynamic range of the display.
        float minNits = cameraData.hdrDisplayInformation.minToneMapLuminance;
        float maxNits = cameraData.hdrDisplayInformation.maxToneMapLuminance;
        float paperWhite = cameraData.hdrDisplayInformation.paperWhiteNits;
    }
    else
    {
        // If HDR output is disabled, disable HDR output-related keywords
        // If post processing is disabled, the final pass will do the color conversion so there is
        // no need to account for HDR Output
        material.DisableKeyword(HDROutputUtils.ShaderKeywords.HDR_INPUT);
    }
    
  5. Получить компонент тонового отображения из Volume Manager.

    if (cameraData.isHDROutputActive && cameraData.postProcessEnabled)
    {
        var tonemapping = VolumeManager.instance.stack.GetComponent<Tonemapping>();
    
        // Get luminance information from the display, these define the dynamic range of the display.
        float minNits = cameraData.hdrDisplayInformation.minToneMapLuminance;
        float maxNits = cameraData.hdrDisplayInformation.maxToneMapLuminance;
        float paperWhite = cameraData.hdrDisplayInformation.paperWhiteNits;
    }
    
  6. Добавить еще if оператор, чтобы проверить наличие компонента тонального отображения. Если такой компонент найден, он может переопределить данные о яркости, полученные от дисплея.

    if (cameraData.isHDROutputActive && cameraData.postProcessEnabled)
    {
        var tonemapping = VolumeManager.instance.stack.GetComponent<Tonemapping>();
    
        // Get luminance information from the display, these define the dynamic range of the display.
        float minNits = cameraData.hdrDisplayInformation.minToneMapLuminance;
        float maxNits = cameraData.hdrDisplayInformation.maxToneMapLuminance;
        float paperWhite = cameraData.hdrDisplayInformation.paperWhiteNits;
    
        if (tonemapping != null)
        {
            // Tone mapping post process can override the luminance retrieved from the display
            if (!tonemapping.detectPaperWhite.value)
            {
                paperWhite = tonemapping.paperWhite.value;
            }
            if (!tonemapping.detectBrightnessLimits.value)
            {
                minNits = tonemapping.minNits.value;
                maxNits = tonemapping.maxNits.value;
            }
        }
    }
    
  7. Настройка свойств яркости материала с помощью данных яркости с дисплея и отображения тонов.

    if (cameraData.isHDROutputActive && cameraData.postProcessEnabled)
    {
        var tonemapping = VolumeManager.instance.stack.GetComponent<Tonemapping>();
    
        // Get luminance information from the display, these define the dynamic range of the display.
        float minNits = cameraData.hdrDisplayInformation.minToneMapLuminance;
        float maxNits = cameraData.hdrDisplayInformation.maxToneMapLuminance;
        float paperWhite = cameraData.hdrDisplayInformation.paperWhiteNits;
    
        if (tonemapping != null)
        {
            // Tone mapping post process can override the luminance retrieved from the display
            if (!tonemapping.detectPaperWhite.value)
            {
                paperWhite = tonemapping.paperWhite.value;
            }
            if (!tonemapping.detectBrightnessLimits.value)
            {
                minNits = tonemapping.minNits.value;
                maxNits = tonemapping.maxNits.value;
            }
        }
    
        // Pass luminance data to the material, use these to interpret the range of values the
        // input will be in.
        material.SetFloat("_MinNits", minNits);
        material.SetFloat("_MaxNits", maxNits);
        material.SetFloat("_PaperWhite", paperWhite);
    }
    
  8. Получить цветовую гамму текущего цветового пространства и передать ее в материал.

    // Pass luminance data to the material, use these to interpret the range of values the
    // input will be in.
    material.SetFloat("_MinNits", minNits);
    material.SetFloat("_MaxNits", maxNits);
    material.SetFloat("_PaperWhite", paperWhite);
    
    // Pass the color gamut data to the material (colorspace and transfer function).
    HDROutputUtils.GetColorSpaceForGamut(cameraData.hdrDisplayColorGamut, out int colorspaceValue);
    material.SetInteger("_HDRColorspace", colorspaceValue);
    
  9. Включите ключевые слова HDR Output shader.

    // Pass the color gamut data to the material (colorspace and transfer function).
    HDROutputUtils.GetColorSpaceForGamut(cameraData.hdrDisplayColorGamut, out int colorspaceValue);
    material.SetInteger("_HDRColorspace", colorspaceValue);
    
    // Enable HDR shader keywords
    material.EnableKeyword(HDROutputUtils.ShaderKeywords.HDR_INPUT);
    
  10. Вызывайте метод SetupHDROutput в вашей функции Execute(), чтобы убедиться, что Выход HDR учитывается всякий раз, когда используется этот Scriptable Render Pass.

Полный пример скрипта

Ниже приведен полный код из примера:

class CustomFullScreenRenderPass : ScriptableRenderPass
{
    // Leave your existing Render Pass code here

    static void SetupHDROutput(ref CameraData cameraData, Material material)
    {
        // If post processing is enabled, color grading has already applied tone mapping
        // As a result the input here will be in the display colorspace (Rec2020, P3, etc) and in nits
        if (cameraData.isHDROutputActive && cameraData.postProcessEnabled)
        {
            var tonemapping = VolumeManager.instance.stack.GetComponent<Tonemapping>();

            // Get luminance information from the display, these define the dynamic range of the display.
            float minNits = cameraData.hdrDisplayInformation.minToneMapLuminance;
            float maxNits = cameraData.hdrDisplayInformation.maxToneMapLuminance;
            float paperWhite = cameraData.hdrDisplayInformation.paperWhiteNits;

            if (tonemapping != null)
            {
                // Tone mapping post process can override the luminance retrieved from the display
                if (!tonemapping.detectPaperWhite.value)
                {
                    paperWhite = tonemapping.paperWhite.value;
                }
                if (!tonemapping.detectBrightnessLimits.value)
                {
                    minNits = tonemapping.minNits.value;
                    maxNits = tonemapping.maxNits.value;
                }
            }

            // Pass luminance data to the material, use these to interpret the range of values the
            // input will be in.
            material.SetFloat("_MinNits", minNits);
            material.SetFloat("_MaxNits", maxNits);
            material.SetFloat("_PaperWhite", paperWhite);

            // Pass the color gamut data to the material (colorspace and transfer function).
            HDROutputUtils.GetColorSpaceForGamut(cameraData.hdrDisplayColorGamut, out int colorspaceValue);
            material.SetInteger("_HDRColorspace", colorspaceValue);

            // Enable HDR shader keywords
            material.EnableKeyword(HDROutputUtils.ShaderKeywords.HDR_INPUT);
        }
        else
        {
            // If HDR output is disabled, disable HDR output-related keywords
            // If post processing is disabled, the final pass will do the color conversion so there is
            // no need to account for HDR Output
            material.DisableKeyword(HDROutputUtils.ShaderKeywords.HDR_INPUT);
        }
    }
}