zoukankan      html  css  js  c++  java
  • 17070302(UE4的Tonemapper)

    【目标】

    UE4的Tonemapper

    【思路】

    1 UE3中关键字

    • USE_TONEMAPPERTYPE
    • ShadersUberPostProcessBlendPixelShader.usf
    • TonemapAndGammaCorrect



    2 UE3的算法

     

    half3 TonemapAndGammaCorrect(half3 LinearColor)
    {
    half A = (half)ImageAdjustments2.x;
    half B = (half)ImageAdjustments2.y;

    half3 GammaColor;

    #if USE_TONEMAPPERTYPE == 0
    // no tonemapper
    {
    GammaColor = pow(LinearColor, 1.0f / 2.2f);
    }
    #elif USE_TONEMAPPERTYPE == 1
    // filmic approximation (s-curve, contrast enhances, small toe, changes saturation and hue)
    // simple but effective tonemapper
    // outputs in 0..1 range (saturate())
    // clamps negative colors to 0 (abs())
    {
    GammaColor = LinearColor / abs(LinearColor + A) * B;
    }

    #elif USE_TONEMAPPERTYPE == 2
    // neutral soft white clamp (experimental, not optimized yet)
    // outputs in 0..1 range (saturate())
    // clamps negataive colors to 0 (abs())
    {
    // ToeFactor 0 = non means linear .. 1 = full (filmic look)
    half ToeFactor = (half)ImageAdjustments3.x;
    half LinearSteepness = (half)ImageAdjustments2.w;
    // value below we have linear adjustments to the sigmoid curve that we don't to above the value
    half FunctionSplitPos = ImageAdjustments2.z;

    half3 GammaColorOldTonemapperTonemapperStartingFromLinear = LinearColor / abs(LinearColor + A) * B;

    // efficient 3 component implementation of: LinearColor >= FunctionSplitPos
    half3 SplitMask = saturate((LinearColor - FunctionSplitPos) * 10000.0f);

    const half3 GammaColorNotTonemapped = pow(LinearColor * LinearSteepness, 1.0f / 2.2f);

    half3 FlatGammaColor = lerp(GammaColorNotTonemapped, GammaColorOldTonemapperTonemapperStartingFromLinear, SplitMask);

    GammaColor = lerp(FlatGammaColor, GammaColorOldTonemapperTonemapperStartingFromLinear, ToeFactor);
    }
    #endif

    // in all cases it's good to clamp into the 0..1 range (e.g for LUT color grading)
    GammaColor = saturate(GammaColor);

    return GammaColor;
    }


    变量定义

    // xy=Grain Offset to have animated noise, z=unused, w=ImageGrainScale
    // Note: ImageAdjustments1.xy is a random float2 in the range 0..1
    float4 ImageAdjustments1;
    // TonemapperFunction(x) = x / (x + A) * B
    // x=A, y=B, z=split pos, w=LinearSteepness
    float4 ImageAdjustments2;
    // x=tonemapper toe factor (0=linear..1=full toe)
    float4 ImageAdjustments3;




    3 UE4相关

    ACES Gets in the Games

    Bookmark and Share

    Mon, 04/10/2017 - 12:01 -- Sarah Priestnall

    A royalty-free image from Epic Games' Unreal Engine.The Motion Picture Academy’s Academy Color Encoding System is now widely used across the movie industry but perhaps surprisingly, it’s also gaining traction in the gaming world. To learn more, Digital Cinema Report recently spoke with Brian Karis at Cary, North Carolina-based Epic Games. The company is known for its industry-leading Unreal Engine, a ground breaking game engine that can be used by other game developers who do not want to develop their own engine.

    Digital Cinema Report: Tell us what your role at Epic Games is?

    Brian Karis: I'm a senior graphics programmer on the rendering team here at Epic. I work on many different aspects of the renderer.

    DCR: What made you decide to incorporate ACES?

    Brian KarisBK: A couple of years ago I tackled changing our tone mapper from a proprietary ad hoc curve with some artist parameters to a new curve that better simulated film response and could be configured to fit a number of different film responses. During that effort I learned a ton about color science and physical film. I also came upon ACES and decided it should be the foundation for our color handling. Right now, we do all rendering in Rec. 709 space but do the grading in ACEScg and then use an Output Transform. I ended up creating a parametric curve that combines the Reference Rendering Transform (RRT) and Output Device Transform (ODT) for 100 nit monitors that allows the artist to get different film stock looks than the ACES standard look but our defaults match ACES. So currently the default tone mapper and color grading in Unreal Engine 4 (UE4) is ACES.

    DCR: What advantages do you see in using ACES within a gaming engine?

    BK: What advantages there are is a large question but I'll touch on a few things. In my opinion the biggest impact is from doing tone mapping in ACEScg space. Regardless of the curve, that alone makes colors look so much better and more realistic. The specific curve of ACES matches film characteristics but honestly it is just a choice of look amongst many options. Having the RRT and ODT separated is a really good idea and one I wish I had embraced earlier. If I had, I could have had my parametric curve work for HDR displays as well. That now needs a bit of a rethink. Matching a standard that we can load up in Nuke or other packages has proven useful so far and I expect will be ever more useful in the future as UE4 becomes more used by film and VFX companies.

    For HDR displays we use the ACES ODTs and disable those controls. I'd like to make that work in the future. We are also interested in adding support for rendering in ACEScg space. I recently engaged with the larger ACES community in helping write a retrospective and suggestions for improvements for future versions.


    4 youtube介绍

    https://www.youtube.com/watch?v=A-wectYNfRQ

    Filmic Tonemapper | Feature Highlight | Unreal Engine

     

     
     
     

     
     


    5 UE4 Shader流向

    TonemapCommon.usf FilmSlope ->FLUTBlenderPS.FilmSlope 


    FilmToneMap函数

    /*
    ============================================
    // Uncharted settings
    Slope = 0.63;
    Toe = 0.55;
    Shoulder = 0.47;
    BlackClip= 0;
    WhiteClip = 0.01;

    // HP settings
    Slope = 0.65;
    Toe = 0.63;
    Shoulder = 0.45;
    BlackClip = 0;
    WhiteClip = 0;

    // Legacy settings
    Slope = 0.98;
    Toe = 0.3;
    Shoulder = 0.22;
    BlackClip = 0;
    WhiteClip = 0.025;

    // ACES settings
    Slope = 0.88;
    Toe = 0.55;
    Shoulder = 0.26;
    BlackClip = 0;
    WhiteClip = 0.04;
    ===========================================
    */

    float FilmSlope;
    float FilmToe;
    float FilmShoulder;
    float FilmBlackClip;
    float FilmWhiteClip;

    half3 FilmToneMap( half3 LinearColor ) 
    {
    const float3x3 sRGB_2_AP0 = mul( XYZ_2_AP0_MAT, mul( D65_2_D60_CAT, sRGB_2_XYZ_MAT ) );
    const float3x3 sRGB_2_AP1 = mul( XYZ_2_AP1_MAT, mul( D65_2_D60_CAT, sRGB_2_XYZ_MAT ) );
    const float3x3 AP1_2_sRGB = mul( XYZ_2_sRGB_MAT, mul( D60_2_D65_CAT, AP1_2_XYZ_MAT ) );
    #if !ES2_PROFILE //disabling this part for mobile, Adreno devices can't handle it (UE-40689)
    float3 ACESColor = mul( sRGB_2_AP0, float3(LinearColor) );

    // --- Red modifier --- //
    const float RRT_RED_SCALE = 0.82;
    const float RRT_RED_PIVOT = 0.03;
    const float RRT_RED_HUE = 0;
    const float RRT_RED_WIDTH = 135;

    float saturation = rgb_2_saturation( ACESColor );
    float hue = rgb_2_hue( ACESColor );
    float centeredHue = center_hue( hue, RRT_RED_HUE );
    float hueWeight = Square( smoothstep( 0, 1, 1 - abs( 2 * centeredHue / RRT_RED_WIDTH ) ) );
    ACESColor.r += hueWeight * saturation * (RRT_RED_PIVOT - ACESColor.r) * (1. - RRT_RED_SCALE);

    // Use ACEScg primaries as working space
    float3 WorkingColor = mul( AP0_2_AP1_MAT, ACESColor );
    #else
    // Use ACEScg primaries as working space
    float3 WorkingColor = mul( sRGB_2_AP1, float3(LinearColor) );
    #endif

    WorkingColor = max( 0, WorkingColor );

    // Pre desaturate
    WorkingColor = lerp( dot( WorkingColor, AP1_RGB2Y ), WorkingColor, 0.96 );
    const half ToeScale = 1 + FilmBlackClip - FilmToe;
    const half ShoulderScale = 1 + FilmWhiteClip - FilmShoulder;
    const float InMatch = 0.18;
    const float OutMatch = 0.18;

    float ToeMatch;
    if( FilmToe > 0.8 )
    {
    // 0.18 will be on straight segment
    ToeMatch = ( 1 - FilmToe  - OutMatch ) / FilmSlope + log10( InMatch );
    }
    else
    {
    // 0.18 will be on toe segment

    // Solve for ToeMatch such that input of InMatch gives output of OutMatch.
    const float bt = ( OutMatch + FilmBlackClip ) / ToeScale - 1;
    ToeMatch = log10( InMatch ) - 0.5 * log( (1+bt)/(1-bt) ) * (ToeScale / FilmSlope);
    }

    float StraightMatch = ( 1 - FilmToe ) / FilmSlope - ToeMatch;
    float ShoulderMatch = FilmShoulder / FilmSlope - StraightMatch;
    half3 LogColor = log10( WorkingColor );
    half3 StraightColor = FilmSlope * ( LogColor + StraightMatch );
    half3 ToeColor = (    -FilmBlackClip ) + (2 *      ToeScale) / ( 1 + exp( (-2 * FilmSlope /      ToeScale) * ( LogColor -      ToeMatch ) ) );
    half3 ShoulderColor = ( 1 + FilmWhiteClip ) - (2 * ShoulderScale) / ( 1 + exp( ( 2 * FilmSlope / ShoulderScale) * ( LogColor - ShoulderMatch ) ) );

    ToeColor = LogColor <      ToeMatch ?      ToeColor : StraightColor;
    ShoulderColor = LogColor > ShoulderMatch ? ShoulderColor : StraightColor;

    half3 t = saturate( ( LogColor - ToeMatch ) / ( ShoulderMatch - ToeMatch ) );
    t = ShoulderMatch < ToeMatch ? 1 - t : t;
    t = (3-2*t)*t*t;
    half3 ToneColor = lerp( ToeColor, ShoulderColor, t );

    // Post desaturate
    ToneColor = lerp( dot( float3(ToneColor), AP1_RGB2Y ), ToneColor, 0.93 );

    // Returning positive AP1 values
    return max( 0, ToneColor );

    //ToneColor = mul( AP1_2_sRGB, ToneColor );

    //return saturate( ToneColor );
    //return max( 0, ToneColor );
    }


    6  UnrealEngine4EngineShadersACES.usf 定义一些要用到的常量

    https://github.com/ampas/aces-dev/tree/v1.0


    UnrealEngine4EngineShadersPostProcessTonemap.usf

    UnrealEngine4EngineShadersTonemapCommon.usf

    7 计算流程

    • PostProcessCombineLUTs.usf MainPS



    https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/

     





    【步骤】

    1 修改 EngineShadersUberPostProcessBlendPixelShader.usf


    elif USE_TONEMAPPERTYPE == 3
    {
    //float a = 2.51f;
        //float b = 0.03f;
        //float c = 2.43f;
        //float d = 0.59f;
        //float e = 0.14f;
        //return saturate((x*(a*x+b))/(x*(c*x+d)+e));
        GammaColor = saturate((LinearColor*(2.51f*LinearColor+0.03f))/(LinearColor*(2.43f*LinearColor+0.59f)+0.14f));
    }



    2 修改DevelopmentSrcEngineClassesUberPostProcessEffect.uc 添加类型

    /** Allows to specify the tone mapper function which maps HDR colors into the LDR color range. */
    var(Tonemapper) enum ETonemapperType
    {
        Tonemapper_Off<DisplayName=Off>, 
        Tonemapper_ACES<DisplayName=ACES>, 
        Tonemapper_Customizable<DisplayName=Customizable>, 
        Tonemapper_Filmic<DisplayName=Filmic>, 
    } TonemapperType;


    3 FUberPostProcessSceneProxy.Render 

    #define VARIATION1(A)        VARIATION2(A,0)            VARIATION2(A,1)            VARIATION2(A,2)            VARIATION2(A,3)



    4 UberPostProcessEffect.cpp 

    #define VARIATION1(A)        VARIATION2(A,0)            VARIATION2(A,1)            VARIATION2(A,2)        VARIATION2(A,3)


    运行 ACES效果


    对比film效果
     
    没有试过UE4的效果


    5 UE4算法

     
    6 拷贝ACES.usf
    EngineShadersUberPostProcessBlendPixelShader.usf
    #include "ACES.usf"
    ...


    EngineShadersUberPostProcessBlendPixelShader.usf

    /*
    ============================================
    // Uncharted settings
    Slope = 0.63;
    Toe = 0.55;
    Shoulder = 0.47;
    BlackClip= 0;
    WhiteClip = 0.01;

    // HP settings
    Slope = 0.65;
    Toe = 0.63;
    Shoulder = 0.45;
    BlackClip = 0;
    WhiteClip = 0;

    // Legacy settings
    Slope = 0.98;
    Toe = 0.3;
    Shoulder = 0.22;
    BlackClip = 0;
    WhiteClip = 0.025;

    // ACES settings
    Slope = 0.88;
    Toe = 0.55;
    Shoulder = 0.26;
    BlackClip = 0;
    WhiteClip = 0.04;
    ===========================================
    */

    const static float FilmSlope = 0.88;
    const static float FilmToe = 0.55;
    const static float FilmShoulder = 0.26;
    const static float FilmBlackClip = 0;
    const static float FilmWhiteClip = 0.04;

    half3 FilmToneMap( half3 LinearColor ) 
    {
    const float3x3 sRGB_2_AP0 = mul( XYZ_2_AP0_MAT, mul( D65_2_D60_CAT, sRGB_2_XYZ_MAT ) );
    const float3x3 sRGB_2_AP1 = mul( XYZ_2_AP1_MAT, mul( D65_2_D60_CAT, sRGB_2_XYZ_MAT ) );
    const float3x3 AP1_2_sRGB = mul( XYZ_2_sRGB_MAT, mul( D60_2_D65_CAT, AP1_2_XYZ_MAT ) );
    float3 ACESColor = mul( sRGB_2_AP0, float3(LinearColor) );

    // --- Red modifier --- //
    const float RRT_RED_SCALE = 0.82;
    const float RRT_RED_PIVOT = 0.03;
    const float RRT_RED_HUE = 0;
    const float RRT_RED_WIDTH = 135;

    float saturation = rgb_2_saturation( ACESColor );
    float hue = rgb_2_hue( ACESColor );
    float centeredHue = center_hue( hue, RRT_RED_HUE );
    float hueWeight = Square( smoothstep( 0, 1, 1 - abs( 2 * centeredHue / RRT_RED_WIDTH ) ) );
    ACESColor.r += hueWeight * saturation * (RRT_RED_PIVOT - ACESColor.r) * (1. - RRT_RED_SCALE);

    // Use ACEScg primaries as working space
    float3 WorkingColor = mul( AP0_2_AP1_MAT, ACESColor );


    WorkingColor = max( 0, WorkingColor );

    // Pre desaturate
    WorkingColor = lerp( dot( WorkingColor, AP1_RGB2Y ), WorkingColor, 0.96 );
    const half ToeScale = 1 + FilmBlackClip - FilmToe;
    const half ShoulderScale = 1 + FilmWhiteClip - FilmShoulder;
    const float InMatch = 0.18;
    const float OutMatch = 0.18;

    float ToeMatch;
    if( FilmToe > 0.8 )
    {
    // 0.18 will be on straight segment
    ToeMatch = ( 1 - FilmToe  - OutMatch ) / FilmSlope + log10( InMatch );
    }
    else
    {
    // 0.18 will be on toe segment

    // Solve for ToeMatch such that input of InMatch gives output of OutMatch.
    const float bt = ( OutMatch + FilmBlackClip ) / ToeScale - 1;
    ToeMatch = log10( InMatch ) - 0.5 * log( (1+bt)/(1-bt) ) * (ToeScale / FilmSlope);
    }

    float StraightMatch = ( 1 - FilmToe ) / FilmSlope - ToeMatch;
    float ShoulderMatch = FilmShoulder / FilmSlope - StraightMatch;
    half3 LogColor = log10( WorkingColor );
    half3 StraightColor = FilmSlope * ( LogColor + StraightMatch );
    half3 ToeColor = (    -FilmBlackClip ) + (2 *      ToeScale) / ( 1 + exp( (-2 * FilmSlope /      ToeScale) * ( LogColor -      ToeMatch ) ) );
    half3 ShoulderColor = ( 1 + FilmWhiteClip ) - (2 * ShoulderScale) / ( 1 + exp( ( 2 * FilmSlope / ShoulderScale) * ( LogColor - ShoulderMatch ) ) );

    ToeColor = LogColor <      ToeMatch ?      ToeColor : StraightColor;
    ShoulderColor = LogColor > ShoulderMatch ? ShoulderColor : StraightColor;

    half3 t = saturate( ( LogColor - ToeMatch ) / ( ShoulderMatch - ToeMatch ) );
    t = ShoulderMatch < ToeMatch ? 1 - t : t;
    t = (3-2*t)*t*t;
    half3 ToneColor = lerp( ToeColor, ShoulderColor, t );

    // Post desaturate
    ToneColor = lerp( dot( float3(ToneColor), AP1_RGB2Y ), ToneColor, 0.93 );

    // Returning positive AP1 values
    return max( 0, ToneColor );

    //ToneColor = mul( AP1_2_sRGB, ToneColor );

    //return saturate( ToneColor );
    //return max( 0, ToneColor );
    }
    ...
    GammaColor = FilmToneMap(LinearColor);




    【运行】

     
    7 几个配置都加进去
    #elif USE_TONEMAPPERTYPE == 3
    {
    // Simple ACES
    //float a = 2.51f;
        //float b = 0.03f;
        //float c = 2.43f;
        //float d = 0.59f;
        //float e = 0.14f;
        //return saturate((x*(a*x+b))/(x*(c*x+d)+e));
        GammaColor = saturate(( LinearColor * (2.51f * LinearColor + 0.03f )) / ( LinearColor * ( 2.43f * LinearColor + 0.59f ) + 0.14f ));  
    }
    #elif USE_TONEMAPPERTYPE == 4
    {
    // Uncharted settings
      FilmSlope = 0.63;
    FilmToe = 0.55;
    FilmShoulder = 0.47;
    FilmBlackClip= 0;
    FilmWhiteClip = 0.01;

    GammaColor = FilmToneMap(LinearColor);
    }
    #elif USE_TONEMAPPERTYPE == 5
    {
    // HP settings
    FilmSlope = 0.65;
    FilmToe = 0.63;
    FilmShoulder = 0.45;
    FilmBlackClip = 0;
    FilmWhiteClip = 0;

    GammaColor = FilmToneMap(LinearColor);
    }
    #elif USE_TONEMAPPERTYPE == 6
    {
    // Legacy settings
    FilmSlope = 0.98;
    FilmToe = 0.3;
    FilmShoulder = 0.22;
    FilmBlackClip = 0;
    FilmWhiteClip = 0.025;

    GammaColor = FilmToneMap(LinearColor);
    }
    #elif USE_TONEMAPPERTYPE == 7
    {
    // ACES settings
    FilmSlope = 0.88;
    FilmToe = 0.55;
    FilmShoulder = 0.26;
    FilmBlackClip = 0;
    FilmWhiteClip = 0.04;
    FilmGammaColor = FilmToneMap(LinearColor);
    }
    #endif



     

    FUberPostProcessSceneProxy.Render 

    #define VARIATION1(A)        VARIATION2(A,0)            VARIATION2(A,1)            VARIATION2(A,2)    VARIATION2(A,3) VARIATION2(A,4) VARIATION2(A,5) VARIATION2(A,6) VARIATION2(A,7)



    UberPostProcessEffect.cpp 

    #define VARIATION1(A)        VARIATION2(A,0)            VARIATION2(A,1)            VARIATION2(A,2)        VARIATION2(A,3) VARIATION2(A,4) VARIATION2(A,5) VARIATION2(A,6) VARIATION2(A,7)


    语法报错嵌套太深 感觉超过48层就报错了


    只能采用传另外一个参数

    ImageAdjustments3只用的第一个Float


    9 FUberPostProcessSceneProxy 中添加属性

        UINT TonemapperACESType;


    FUberPostProcessSceneProxy.FUberPostProcessSceneProxy 

        FUberPostProcessSceneProxy(const UUberPostProcessEffect* InEffect,const FPostProcessSettings* WorldSettings, UINT InColorGradingCVar, 
            UINT InTonemapperType,UINT InTonemapperACESType, UBOOL bInMotionBlur, UBOOL bInImageGrain,const FCameraInfo& CI)
            :    FDOFAndBloomPostProcessSceneProxy(InEffect, WorldSettings,CI)
            ,    MotionBlurSoftEdgeKernelSize(InEffect->MotionBlurSoftEdgeKernelSize)
            ,    TonemapperToeFactor(InEffect->TonemapperToeFactor)
            ,    TonemapperRange(InEffect->TonemapperRange)
            ,    ColorGradingCVar(InColorGradingCVar)
            ,    TonemapperType(InTonemapperType)
            ,    TonemapperACESType(InTonemapperACESType)



    10 ue3DevelopmentSrcEngineClassesUberPostProcessEffect.uc

    var(Tonemapper) enum EACESType
    {
        ACES_One<DisplayName=ACES>, 
        ACES_Simple<DisplayName=Simple>, 
        ACES_Uncharted<DisplayName=Uncharted>, 
        ACES_HP<DisplayName=HP>, 
        ACES_Legacy<DisplayName=Legacy>, 
    } ACESType;


    11 UUberPostProcessEffect.CreateSceneProxy

        return new FUberPostProcessSceneProxy(this, WorldSettings, GColorGrading, LocalTonemapperType,ACESType, bLocalMotionBlur, bEnableImageGrain,CI);


    12 Shader赋值FUberPostProcessSceneProxy.RenderVariationFullRes.{.SetPixelShaderValue 

                SetPixelShaderValue(
                    BlendPixelShader->GetPixelShader(), 
                    BlendPixelShader->ImageAdjustments3Parameter,
                    FVector4(Clamp(TonemapperToeFactor, 0.0f, 1.0f), TonemapperACESType, 0, 0));


    13 EngineShadersUberPostProcessBlendPixelShader.usf

    #elif USE_TONEMAPPERTYPE == 3
    {

    if (ACESType == 1)
    {
    // Simple ACES
    //float a = 2.51f;
        //float b = 0.03f;
        //float c = 2.43f;
        //float d = 0.59f;
        //float e = 0.14f;
        //return saturate((x*(a*x+b))/(x*(c*x+d)+e));
        GammaColor = saturate(( LinearColor * (2.51f * LinearColor + 0.03f )) / ( LinearColor * ( 2.43f * LinearColor + 0.59f ) + 0.14f ));  
        }
        else
        {
        if (ACESType == 0)
        {
        // ACES settings
    FilmSlope = 0.88;
    FilmToe = 0.55;
    FilmShoulder = 0.26;
    FilmBlackClip = 0;
    FilmWhiteClip = 0.04;
      }
      else if (ACESType == 2)
      {
      // Uncharted settings
    FilmSlope = 0.63;
    FilmToe = 0.55;
    FilmShoulder = 0.47;
    FilmBlackClip= 0;
    FilmWhiteClip = 0.01;
      }
      else if (ACESType == 3)
      {
    // HP settings
    FilmSlope = 0.65;
    FilmToe = 0.63;
    FilmShoulder = 0.45;
    FilmBlackClip = 0;
    FilmWhiteClip = 0;
      }
      else if (ACESType == 4)
      {
      // Legacy settings
    FilmSlope = 0.98;
    FilmToe = 0.3;
    FilmShoulder = 0.22;
    FilmBlackClip = 0;
    FilmWhiteClip = 0.025;
      }
      
      GammaColor = FilmToneMap(LinearColor);
        }
    }
    #endif



    14 添加指令

    UUberPostProcessEffect.CreateSceneProxy.

            CVar = GConsoleManager->FindConsoleVariable(TEXT("ACESType")); 
            Value = CVar->GetInt();
            if (Value >= ACES_One && Value < ACES_MAX)
            {
                LocalACESType = Value;
            }


    CreateConsoleVariables 

        GConsoleManager->RegisterConsoleVariable(TEXT("ACESType"),
            -1,
            TEXT("Allows to override which ACESType function (during the post processing stage to transform HDR to LDR colors) is used: ")
            TEXT("-1: use what is specified elsewhere (default) ")
            TEXT(" 0: ACES settings  ")
            TEXT(" 1: Simple ACES  ")
            TEXT(" 2: Uncharted settings ")
            TEXT(" 3: HP settings"),
            TEXT(" 4: Legacy settings"),
            ECVF_Cheat);


    指令

    TonemapperType 3
    ACESType 0-4


    " 0: ACES settings"

    " 1: Simple ACES"

    " 2: Uncharted settings"

    " 3: HP settings"

    " 4: Legacy settings"



    15 



    16






  • 相关阅读:
    .NET异常处理最佳实践
    Resharper4.5破解程序下载
    Firefox报“使用了无效的安全证书”错误的解决方法
    jQuery培训PPT
    Windows常用命令集即开始→运行→输入的命令集锦
    “NHibernate.Cfg.Environment的类型初始值设定项引发异常”的解决方法
    浅析SQL having子句、如何使用having子句及where子句与having子句的区别
    浅析SQL中 in 与 exists 用法的区别及其各自执行流程、not in/not exists区别、sql优化应该如何选择in还是exists
    浅析SQL优化查询性能的最佳实践
    SQL中的cast和convert的用法和区别以及时间转换
  • 原文地址:https://www.cnblogs.com/username/p/8879963.html
Copyright © 2011-2022 走看看