diff --git a/Sim/Computation/RoughMultiLayerContribution.cpp b/Sim/Computation/RoughMultiLayerContribution.cpp
index 6df88f3e2a04bb1fe202061d9e692aab5dafb613..0e27ce59d4f132da7fd7746245f4b3e74eb42922 100644
--- a/Sim/Computation/RoughMultiLayerContribution.cpp
+++ b/Sim/Computation/RoughMultiLayerContribution.cpp
@@ -100,34 +100,28 @@ complex_t get_sum8terms(const ReSample& re_sample, size_t i_layer, const Diffuse
     return term1 + term2 + term3 + term4 + term5 + term6 + term7 + term8;
 }
 
-// Fourier transform of the correlation function of roughnesses between the interfaces
-double crossCorrSpectralFun(const R3& qvec, const SliceStack& stack, size_t j, size_t k)
+double underlyingInterfaceReplication(const R3& qvec, const SliceStack& stack, size_t j)
 {
-    ASSERT(j < k);
-
-    const double distance = std::abs(stack[j].hig() - stack[k].hig());
-    const AutocorrelationModel* rough_j = stack[j].topRoughness()->autocorrelationModel();
-    const AutocorrelationModel* rough_k = stack[k].topRoughness()->autocorrelationModel();
-    const double sigma_j = rough_j->sigma();
-    const double sigma_k = rough_k->sigma();
+    const CrosscorrelationModel* crosscorr_j = stack[j].topRoughness()->crosscorrelationModel();
 
-    if (sigma_j <= 0 || sigma_k <= 0)
+    if (!crosscorr_j)
         return 0.0;
 
-    const CrosscorrelationModel* crosscorr_j = stack[j].topRoughness()->crosscorrelationModel();
+    const double distance = std::abs(stack[j].hig() - stack[j + 1].hig());
+    return crosscorr_j->replicationFactor(qvec, distance);
+}
 
-    if (!crosscorr_j)
+double crossInterfaceSpectralFun(double spectrum_j, double spectrum_k, double sigma_j,
+                                 double sigma_k)
+{
+    if (sigma_j <= 0 || sigma_k <= 0)
         return 0.0;
 
-    return 0.5
-           * ((sigma_k / sigma_j) * rough_j->spectralFunction(qvec)
-              + (sigma_j / sigma_k) * rough_k->spectralFunction(qvec))
-           * crosscorr_j->replicationFactor(qvec, distance);
+    return 0.5 * ((sigma_k / sigma_j) * spectrum_j + (sigma_j / sigma_k) * spectrum_k);
 }
 
 } // namespace
 
-
 double Compute::roughMultiLayerContribution(const ReSample& re_sample, const DiffuseElement& ele)
 {
     if (ele.alphaMean() < 0.0)
@@ -155,19 +149,35 @@ double Compute::roughMultiLayerContribution(const ReSample& re_sample, const Dif
         }
 
     const size_t n_interfaces = roughStack.size();
+    std::vector<double> spectrum(n_interfaces, 0);
 
     // auto correlation in each layer (first term in final expression in Eq (3) of Schlomka et al)
-    for (size_t i = 0; i < n_interfaces; i++)
-        autocorr += std::norm(rterm[i] * sterm[i])
-                    * roughStack[i].topRoughness()->autocorrelationModel()->spectralFunction(q);
+    for (size_t i = 0; i < n_interfaces; i++) {
+        spectrum[i] = roughStack[i].topRoughness()->autocorrelationModel()->spectralFunction(q);
+        autocorr += std::norm(rterm[i] * sterm[i]) * spectrum[i];
+    }
 
     // cross correlation between layers (second term in loc. cit.)
-    for (size_t j = 0; j < n_interfaces; j++) {
-        if (!roughStack[j].topRoughness()->crosscorrelationModel())
+    std::vector<double> underlying_interface_replication(n_interfaces, 0); // the last is unused
+    std::vector<double> sigma(n_interfaces);
+
+    for (size_t j = 0; j < n_interfaces - 1; j++) {
+        sigma[j] = roughStack[j].topRoughness()->sigma();
+        underlying_interface_replication[j] = underlyingInterfaceReplication(q, roughStack, j);
+    }
+
+    for (size_t j = 0; j < n_interfaces - 1; j++) {
+        if (underlying_interface_replication[j] == 0)
             continue;
-        for (size_t k = j + 1; k < n_interfaces; k++)
+        double accumulated_replication = underlying_interface_replication[j];
+        for (size_t k = j + 1; k < n_interfaces; k++) {
             crosscorr += (rterm[j] * sterm[j] * std::conj(rterm[k] * sterm[k])).real()
-                         * ::crossCorrSpectralFun(q, roughStack, j, k);
+                         * crossInterfaceSpectralFun(spectrum[j], spectrum[k], sigma[j], sigma[k])
+                         * accumulated_replication;
+            if (underlying_interface_replication[k] == 0)
+                break;
+            accumulated_replication *= underlying_interface_replication[k];
+        }
     }
 
     const double k0 = (2 * pi) / wavelength;