calculating the valid range of exponent for a spotlight

i have played around with the spotlights a lot and if i’m not mistaken the valid range of inputs for the exponent changes depending on the fov of the light’s lens. it also crashes in some cases where the input for the exponent is outside this range.
is there a way to calculate this range? or is there a formulae used that i could convert to get me this valid range?
thanks

i’ve looked into the shader generator (i’m using the autoshader function), where i’ve found this code-part:

    for (int i=0; i<(int)_slights.size(); i++) {
      text << "\t // Spot Light " << i << "\n";
      text << "\t lcolor = slight_slight" << i << "_rel_view[0];\n";
      text << "\t lspec  = slight_slight" << i << "_rel_view[1];\n";
      text << "\t lpoint = slight_slight" << i << "_rel_view[2];\n";
      text << "\t ldir   = slight_slight" << i << "_rel_view[3];\n";
      text << "\t latten = satten_slight" << i << ";\n";
      text << "\t lvec   = lpoint - l_eye_position;\n";
      text << "\t ldist  = length(float3(lvec));\n";
      text << "\t lvec /= ldist;\n";
      text << "\t langle = saturate(dot(ldir.xyz, lvec.xyz));\n";
      text << "\t lattenv = 1/(latten.x + latten.y*ldist + latten.z*ldist*ldist);\n";
      text << "\t lattenv *= pow(langle, latten.w);\n";
      text << "\t if (langle < ldir.w) lattenv = 0;\n";
      text << "\t lcolor *= lattenv * saturate(dot(l_eye_normal.xyz, lvec.xyz));\n";
      if (_shadows && _slights[i]->_shadow_caster) {
        if (_use_shadow_filter) {
          text << "\t lshad = shadow2DProj(k_slighttex" << i << ", l_slightcoord" << i << ").r;\n";
        } else {
          text << "\t lshad = tex2Dproj(k_slighttex" << i << ", l_slightcoord" << i << ").r > l_slightcoord" << i << ".z / l_slightcoord" << i << ".w;\n";
        }
        text << "\t lcolor *= lshad;\n";
        text << "\t lspec *= lshad;\n";
      }

      if (_have_diffuse) {
        text << "\t tot_diffuse += lcolor;\n";
      }
      if (_have_specular) {
        if (_material->get_local()) {
          text << "\t lhalf  = normalize(lvec - normalize(l_eye_position));\n";
        } else {
          text << "\t lhalf = normalize(lvec - float4(0,1,0,0));\n";
        }
        text << "\t lspec *= lattenv;\n";
        text << "\t lspec *= pow(saturate(dot(l_eye_normal.xyz, lhalf.xyz)), shininess);\n";
        text << "\t tot_specular += lspec;\n";
      }
    }

i assume the exponent is stored in the latten.w variable. however with the default inputs for the exponent (0…sometimes very large values) i assume it must be converted (multiplied/divided) before the shader generator takes action. but i cant find the place where this could happen.

I don’t think the values are converted. This is the code (in graphicsStateGuardian.cxx) that passes the input to the shader:

  case Shader::SMO_satten_x: {
    const NodePath &np = _target_shader->get_shader_input_nodepath(name);
    nassertr(!np.is_empty(), &LMatrix4f::ones_mat());
    Spotlight *lt;
    DCAST_INTO_R(lt, np.node(), &LMatrix4f::ones_mat());
    LVecBase3f const &a = lt->get_attenuation();
    float x = lt->get_exponent();
    t = LMatrix4f(0,0,0,0,0,0,0,0,0,0,0,0,a[0],a[1],a[2],x);
    return &t;
  }

thanks, i think with this hint i should be able to figure out something.