   float NdotH = clamp( dot( normal, H ), 0.0, 1.0 );
 #endif // USE_PHYSICAL_MAPPING || r_specularMapping
 
+  // clamp( NdotL, 0.0, 1.0 ) is done below
+  // if no r_halfLambertLighting and no r_wrapAroundLighting.
+  float NdotL = dot( normal, lightDir );
+
+#if defined(r_halfLambertLighting)
+  // http://developer.valvesoftware.com/wiki/Half_Lambert
+  NdotL = NdotL * 0.5 + 0.5;
+  NdotL *= NdotL;
+#elif defined(r_wrapAroundLighting)
+  NdotL = clamp( NdotL + r_wrapAroundLighting, 0.0, 1.0) / clamp(1.0 + r_wrapAroundLighting, 0.0, 1.0);
+#else
+  NdotL = clamp( NdotL, 0.0, 1.0 );
+#endif
+
 #if defined(USE_PHYSICAL_MAPPING)
   // Daemon PBR packing defaults to ORM like glTF 2.0 defines
   // https://www.khronos.org/blog/art-pipeline-for-gltf

  color.rgb += lightColor.rgb * vec3((D * F * G) / (4.0 * NdotV));
  color.a = mix(diffuseColor.a, 1.0, FexpNV);
#else // !USE_PHYSICAL_MAPPING
  float NdotL = dot( normal, lightDir );
#if defined(r_halfLambertLighting)
  // http://developer.valvesoftware.com/wiki/Half_Lambert
  NdotL = NdotL * 0.5 + 0.5;
  NdotL *= NdotL;
#elif defined(r_wrapAroundLighting)
  NdotL = clamp( NdotL + r_wrapAroundLighting, 0.0, 1.0) / clamp(1.0 + r_wrapAroundLighting, 0.0, 1.0);
#else
  NdotL = clamp( NdotL, 0.0, 1.0 );
#endif

#if defined(USE_REFLECTIVE_SPECULAR)
	// not implemented for PBR yet


  float NdotV = clamp( dot( normal, viewDir ), 0.0, 1.0);
  float VdotH = clamp( dot( viewDir, H ), 0.0, 1.0);

  float alpha = roughness * roughness;
  float k = 0.125 * (roughness + 1.0) * (roughness + 1.0);
