Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-82654

Dynamic looping based on light count uniforms in custom materials is not portable

XMLWordPrintable

    • Icon: Task Task
    • Resolution: Done
    • Icon: P2: Important P2: Important
    • None
    • None
    • Qt RHI, Quick: 3D
    • None

      HLSL compilation dies with "HLSL shader compilation failed: E:\qtquick3d_515\examples\quick3d\lights\Shader@0x0000015B634A1FE8(844,5-45): error X3511: forced to unroll loop, but unrolling failed."

      when encountering code like

          for (int i = 0; i < _301_lightCount; i++)
          {
              param.position = _2304_lights[i].position;
              param.direction = _2304_lights[i].direction;
              param.up = _2304_lights[i].up;
              param.right = _2304_lights[i].right;
              param.diffuse = _2304_lights[i].diffuse;
              param.ambient = _2304_lights[i].ambient;
              param.specular = _2304_lights[i].specular;
              param.coneAngle = _2304_lights[i].coneAngle;
              param.innerConeAngle = _2304_lights[i].innerConeAngle;
              param.constantAttenuation = _2304_lights[i].constantAttenuation;
              param.linearAttenuation = _2304_lights[i].linearAttenuation;
              param.quadraticAttenuation = _2304_lights[i].quadraticAttenuation;
              param.range = _2304_lights[i].range;
              param.width = _2304_lights[i].width;
              param.height = _2304_lights[i].height;
              param.shadowControls = _2304_lights[i].shadowControls;
              param.shadowView = _2304_lights[i].shadowView;
              param.shadowIdx = _2304_lights[i].shadowIdx;
              float3 param_1 = varWorldPos;
              sampleLight(param, param_1, param_2, param_3, param_4, param_5);
              float3 L = param_2;
              float3 lightAmbient = param_3;
              float3 lightDiffuse = param_4;
              float3 lightSpecular = param_5;
              lightAmbient *= aoFactor;
              lightDiffuse *= aoFactor;
              if (gl_FrontFacing)
              {
                  float3 param_6 = normal;
                  float3 param_7 = L;
                  float3 param_8 = viewDir;
                  float3 param_9 = lightDiffuse;
                  float3 param_10 = lightSpecular;
                  float param_11 = materialIOR;
                  float param_12 = aoFactor;
                  computeFrontLayerColor(param_6, param_7, param_8, param_9, param_10, param_11, param_12);
              }
              else
              {
                  float3 param_13 = normal;
                  float3 param_14 = L;
                  float3 param_15 = viewDir;
                  float3 param_16 = lightDiffuse;
                  float3 param_17 = lightSpecular;
                  float param_18 = materialIOR;
                  float param_19 = aoFactor;
                  computeBackLayerColor(param_13, param_14, param_15, param_16, param_17, param_18, param_19);
              }
          }
      

      This is because operations like the following in the sampleLight() function:

      att *= sampleCubemap( shadowCubes[light.shadowIdx], light.shadowControls, light.shadowView, light.position.xyz, pos, vec2(1.0, light.shadowControls.z) );
      

      Note the indexing with light.shadowIdx. This causes unrolling to fail.

      This can be worked around by the following pattern. (have some doubts about the shader code quality we end up with after all these unrolling and conditions and whatnot, but let's hope we can live with this for now)

      -    if ( light.shadowIdx >= 0 )
      -      att *= sampleOrthographic( shadowMaps[light.shadowIdx], light.shadowControls, light.shadowView, pos, vec2(1.0, light.shadowControls.z) );
      +    if (light.shadowIdx == 0)
      +        att *= sampleOrthographic( shadowMaps[0], light.shadowControls, light.shadowView, pos, vec2(1.0, light.shadowControls.z) );
      +    else if (light.shadowIdx == 1)
      +        att *= sampleOrthographic( shadowMaps[1], light.shadowControls, light.shadowView, pos, vec2(1.0, light.shadowControls.z) );
      +    else if (light.shadowIdx == 2)
      +        att *= sampleOrthographic( shadowMaps[2], light.shadowControls, light.shadowView, pos, vec2(1.0, light.shadowControls.z) );
      +    else if (light.shadowIdx == 3)
      +        att *= sampleOrthographic( shadowMaps[3], light.shadowControls, light.shadowView, pos, vec2(1.0, light.shadowControls.z) );
      

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            lagocs Laszlo Agocs
            lagocs Laszlo Agocs
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes