AcademySoftwareFoundation / OpenColorIO

A color management framework for visual effects and animation.
https://opencolorio.org
BSD 3-Clause "New" or "Revised" License
1.76k stars 438 forks source link

greaterThan() error with GPU_LANGUAGE_CG #1701

Open fannychaleon-fn opened 1 year ago

fannychaleon-fn commented 1 year ago

When using the new ACES 1.3 ocio config, I'm getting the following error:

(283) : error C1101: ambiguous overloaded function reference "greaterThan(half4, half4)"
    (0) : bool4 greaterThan(unsigned long4, unsigned long4)
    (0) : bool4 greaterThan(long4, long4)
    (0) : bool4 greaterThan(double4, double4)
    (0) : bool4 greaterThan(unsigned int4, unsigned int4)
    (0) : bool4 greaterThan(int4, int4)
    (0) : bool4 greaterThan(float4, float4)

I'm using GPU_LANGUAGE_CG and the OpenColorIO generated shader uses half vectors as per the getVecKeyword() method in GpuShaderUtils.cpp. The GLSL method greaterThan() (which does component-wise greater-than comparison of two vectors) doesn't support half4 so I'm proposing the change below:

diff --git a/src/OpenColorIO/GpuShaderUtils.cpp b/src/OpenColorIO/GpuShaderUtils.cpp
index 711bde89..418f27df 100644
--- a/src/OpenColorIO/GpuShaderUtils.cpp
+++ b/src/OpenColorIO/GpuShaderUtils.cpp
@@ -985,11 +985,11 @@ std::string GpuShaderText::float3GreaterThan(const std::string & a,
         case GPU_LANGUAGE_GLSL_4_0:
         case GPU_LANGUAGE_GLSL_ES_1_0:
         case GPU_LANGUAGE_GLSL_ES_3_0:
-        case GPU_LANGUAGE_CG:
         {
             kw << float3Keyword() << "(greaterThan( " << a << ", " << b << "))";
             break;
         }
+        case GPU_LANGUAGE_CG:
         case LANGUAGE_OSL_1:
         case GPU_LANGUAGE_MSL_2_0:
         case GPU_LANGUAGE_HLSL_DX11:
@@ -1020,13 +1020,13 @@ std::string GpuShaderText::float4GreaterThan(const std::string & a,
         case GPU_LANGUAGE_GLSL_4_0:
         case GPU_LANGUAGE_GLSL_ES_1_0:
         case GPU_LANGUAGE_GLSL_ES_3_0:
-        case GPU_LANGUAGE_CG:
         {
             kw << float4Keyword() << "(greaterThan( " << a << ", " << b << "))";
             break;
         }
         case GPU_LANGUAGE_MSL_2_0:
         case GPU_LANGUAGE_HLSL_DX11:
+        case GPU_LANGUAGE_CG:
         {
             kw << float4Keyword() << "("
                << "(" << a << "[0] > " << b << "[0]) ? 1.0 : 0.0, "
doug-walker commented 1 year ago

@fannychaleon-fn , could you provide more details about which software you are using and what computer OS?

fannychaleon-fn commented 1 year ago

I'm using OCIO to generate a shader than I use in my application. Building on Windows 10 with MSVC 14.29. Here is a snippet of what I use to generate the OCIO shader:

OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
OCIO::LegacyViewingPipelineRcPtr vp = OCIO::LegacyViewingPipeline::Create();
OCIO::ConstProcessorRcPtr processor = vp->getProcessor(config, config->getCurrentContext());

OCIO::GpuShaderDescRcPtr shaderDesc = OCIO::GpuShaderDesc::CreateShaderDesc();
shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_CG);
shaderDesc->setFunctionName("applyFilmlook");

OCIO::ConstGPUProcessorRcPtr gpuProcessor = processor->getOptimizedGPUProcessor(OCIO::OPTIMIZATION_DEFAULT);
gpuProcessor->extractGpuShaderInfo(shaderDesc);
const std::string ocioShaderText = shaderDesc->getShaderText();

When the ocio config is set to ACES 1.3 cg-config-v0.2.0_aces-v1.3_ocio-v2.1.2.ocio I'm getting the following shader function:

half4 applyFilmlook(half4 inPixel)
{
  half4 outColor = inPixel;

  // Add Matrix processing

  {
    half4 res = half4(outColor.rgb.r, outColor.rgb.g, outColor.rgb.b, outColor.a);
    half4 tmp = res;
    res = mul(half4x4(0.69545224135745187, 0.14067869647029416, 0.16386906217225405, 0., 0.044794563372037716, 0.85967111845642163, 0.0955343181715404, 0., -0.0055258825581135443, 0.0040252103059786595, 1.0015006722521349, 0., 0., 0., 0., 1.), tmp);
    outColor.rgb = half3(res.x, res.y, res.z);
    outColor.a = res.w;
  }

  // Add FixedFunction 'ACES_Glow10 (Forward)' processing

  {
    half chroma = sqrt( outColor.rgb.b * (outColor.rgb.b - outColor.rgb.g) + outColor.rgb.g * (outColor.rgb.g - outColor.rgb.r) + outColor.rgb.r * (outColor.rgb.r - outColor.rgb.b) );
    half YC = (outColor.rgb.b + outColor.rgb.g + outColor.rgb.r + 1.75 * chroma) / 3.;
    half maxval = max( outColor.rgb.r, max( outColor.rgb.g, outColor.rgb.b));
    half minval = min( outColor.rgb.r, min( outColor.rgb.g, outColor.rgb.b));
    half sat = ( max(1e-10, maxval) - max(1e-10, minval) ) / max(1e-2, maxval);
    half x = (sat - 0.4) * 5.;
    half t = max( 0., 1. - 0.5 * abs(x));
    half s = 0.5 * (1. + sign(x) * (1. - t * t));
    half GlowGain = 0.0500000007 * s;
    half GlowMid = 0.0799999982;
    half glowGainOut = lerp(GlowGain, GlowGain * (GlowMid / YC - 0.5), float( YC > GlowMid * 2. / 3. ));
    glowGainOut = lerp(glowGainOut, 0., float( YC > GlowMid * 2. ));
    outColor.rgb = outColor.rgb * glowGainOut + outColor.rgb;
  }

  // Add FixedFunction 'ACES_RedMod10 (Forward)' processing

  {
    half a = 2.0 * outColor.rgb.r - (outColor.rgb.g + outColor.rgb.b);
    half b = 1.7320508075688772 * (outColor.rgb.g - outColor.rgb.b);
    half hue = atan(b, a);
    half knot_coord = clamp(2. + hue * float(1.6976527), 0., 4.);
    int j = int(min(knot_coord, 3.));
    half t = knot_coord - float(j);
    half4 monomials = half4(t*t*t, t*t, t, 1.);
    half4 m0 = half4(0.25, 0., 0., 0.);
    half4 m1 = half4(-0.75, 0.75, 0.75, 0.25);
    half4 m2 = half4(0.75, -1.5, 0., 1.);
    half4 m3 = half4(-0.25, 0.75, -0.75, 0.25);
    half4 coefs = lerp(m0, m1, float(j == 1));
    coefs = lerp(coefs, m2, float(j == 2));
    coefs = lerp(coefs, m3, float(j == 3));
    half f_H = dot(coefs, monomials);
    half maxval = max( outColor.rgb.r, max( outColor.rgb.g, outColor.rgb.b));
    half minval = min( outColor.rgb.r, min( outColor.rgb.g, outColor.rgb.b));
    half f_S = ( max(1e-10, maxval) - max(1e-10, minval) ) / max(1e-2, maxval);
    outColor.rgb.r = outColor.rgb.r + f_H * f_S * (0.0299999993 - outColor.rgb.r) * 0.180000007;
  }

  // Add Range processing

  {
    outColor.rgb = max(half3(0., 0., 0.), outColor.rgb);
  }

  // Add Matrix processing

  {
    half4 res = half4(outColor.rgb.r, outColor.rgb.g, outColor.rgb.b, outColor.a);
    half4 tmp = res;
    res = mul(half4x4(1.4514393161456653, -0.23651074689374019, -0.21492856925192524, 0., -0.07655377339602043, 1.1762296998335731, -0.099675926437552201, 0., 0.008316148425697719, -0.0060324497910210278, 0.9977163013653233, 0., 0., 0., 0., 1.), tmp);
    outColor.rgb = half3(res.x, res.y, res.z);
    outColor.a = res.w;
  }

  // Add Range processing

  {
    outColor.rgb = max(half3(0., 0., 0.), outColor.rgb);
  }

  // Add Matrix processing

  {
    half4 res = half4(outColor.rgb.r, outColor.rgb.g, outColor.rgb.b, outColor.a);
    half4 tmp = res;
    res = mul(half4x4(0.97088914867099996, 0.026963270631999998, 0.0021475806959999999, 0., 0.010889148671, 0.98696327063199996, 0.0021475806959999999, 0., 0.010889148671, 0.026963270631999998, 0.96214758069600004, 0., 0., 0., 0., 1.), tmp);
    outColor.rgb = half3(res.x, res.y, res.z);
    outColor.a = res.w;
  }

  // Add Log processing

  {
    outColor.rgb = max( half3(0., 0., 0.), outColor.rgb);
    outColor.rgb = log(outColor.rgb) * half3(0.434294462, 0.434294462, 0.434294462);
  }

  // Add GradingRGBCurve 'log' forward processing

  {
    outColor.rgb.r = ocio_grading_rgbcurve_evalBSplineCurve_0(0, outColor.rgb.r);
    outColor.rgb.g = ocio_grading_rgbcurve_evalBSplineCurve_0(1, outColor.rgb.g);
    outColor.rgb.b = ocio_grading_rgbcurve_evalBSplineCurve_0(2, outColor.rgb.b);
    outColor.rgb.r = ocio_grading_rgbcurve_evalBSplineCurve_0(3, outColor.rgb.r);
    outColor.rgb.g = ocio_grading_rgbcurve_evalBSplineCurve_0(3, outColor.rgb.g);
    outColor.rgb.b = ocio_grading_rgbcurve_evalBSplineCurve_0(3, outColor.rgb.b);
  }

  // Add GradingRGBCurve 'log' forward processing

  {
    outColor.rgb.r = ocio_grading_rgbcurve_evalBSplineCurve_1(0, outColor.rgb.r);
    outColor.rgb.g = ocio_grading_rgbcurve_evalBSplineCurve_1(1, outColor.rgb.g);
    outColor.rgb.b = ocio_grading_rgbcurve_evalBSplineCurve_1(2, outColor.rgb.b);
    outColor.rgb.r = ocio_grading_rgbcurve_evalBSplineCurve_1(3, outColor.rgb.r);
    outColor.rgb.g = ocio_grading_rgbcurve_evalBSplineCurve_1(3, outColor.rgb.g);
    outColor.rgb.b = ocio_grading_rgbcurve_evalBSplineCurve_1(3, outColor.rgb.b);
  }

  // Add Log 'Anti-Log' processing

  {
    outColor.rgb = pow( half3(10., 10., 10.), outColor.rgb);
  }

  // Add Matrix processing

  {
    half4 res = half4(outColor.rgb.r, outColor.rgb.g, outColor.rgb.b, outColor.a);
    res = half4(0.0208420176, 0.0208420176, 0.0208420176, 1.) * res;
    res = half4(-0.000416840339, -0.000416840339, -0.000416840339, 0.) + res;
    outColor.rgb = half3(res.x, res.y, res.z);
    outColor.a = res.w;
  }

  // Add FixedFunction 'ACES_DarkToDim10 (Forward)' processing

  {
    half Y = max( 1e-10, 0.27222871678091454 * outColor.rgb.r + 0.67408176581114831 * outColor.rgb.g + 0.053689517407937051 * outColor.rgb.b );
    half Ypow_over_Y = pow( Y, -0.0188999772);
    outColor.rgb = outColor.rgb * Ypow_over_Y;
  }

  // Add Matrix processing

  {
    half4 res = half4(outColor.rgb.r, outColor.rgb.g, outColor.rgb.b, outColor.a);
    half4 tmp = res;
    res = mul(half4x4(1.604753433346922, -0.531080948604018, -0.073672484741910349, 0., -0.10208245810655031, 1.1081341286221253, -0.0060516705145729488, 0., -0.0032671116532946819, -0.072755424133422703, 1.0760225357877193, 0., 0., 0., 0., 1.), tmp);
    outColor.rgb = half3(res.x, res.y, res.z);
    outColor.a = res.w;
  }

  // Add Gamma 'monCurveRev' processing

  {
    half4 breakPnt = half4(0.00303993467, 0.00303993467, 0.00303993467, 1.);
    half4 slope = half4(12.9232101, 12.9232101, 12.9232101, 1.);
    half4 scale = half4(1.05499995, 1.05499995, 1.05499995, 1.00000095);
    half4 offset = half4(0.0549999997, 0.0549999997, 0.0549999997, 0.);
    half4 gamma = half4(0.416666657, 0.416666657, 0.416666657, 0.999998987);
    half4 isAboveBreak = half4(greaterThan( outColor, breakPnt));
    half4 linSeg = outColor * slope;
    half4 powSeg = pow( max( half4(0., 0., 0., 0.), outColor ), gamma ) * scale - offset;
    half4 res = isAboveBreak * powSeg + ( half4(1., 1., 1., 1.) - isAboveBreak ) * linSeg;
    outColor.rgb = half3(res.x, res.y, res.z);
    outColor.a = res.w;
  }

  return outColor;
}

When feeding that shader to my application I'm getting an error for line half4 isAboveBreak = half4(greaterThan( outColor, breakPnt));. Let me know if that's enough info to help you reproduce the error.