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

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

    XMLWordPrintable

Details

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

    Description

      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) );
      

      Attachments

        Issue Links

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

          Activity

            People

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

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes