Skip to content

Commit 9762383

Browse files
committed
Optimize getReflectionKernel by using vectorized operations. ~900x faster (reduced execution time from ~7.7s to ~0.008s for a 100x100 grid).
1 parent 5105435 commit 9762383

File tree

1 file changed

+48
-16
lines changed

1 file changed

+48
-16
lines changed

ReflectionModel/getReflectionKernel.m

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,59 @@
1313
% 1: Lambertian
1414
% K: the resulting reflection kernel
1515

16-
K=zeros(dim(1),dim(2));
16+
% Extract scalar coordinates for readability and speed
1717
lx=light(1);
1818
ly=light(2);
1919
lz=light(3);
2020
sx=sensor(1);
2121
sy=sensor(2);
2222
sz=sensor(3);
2323

24-
for x=1:dim(1)
25-
for y=1:dim(2)
26-
d1=sqrt((lx-x)^2+(ly-y)^2);
27-
d2=sqrt((sx-x)^2+(sy-y)^2);
28-
D1=sqrt(d1^2+lz^2);
29-
D2=sqrt(d2^2+sz^2);
30-
cos1=lz/D1;
31-
cos2=sz/D2;
32-
theta1=acos(cos1);
33-
v=lightDistribution(theta1)*cos1*cos2/D1^2/D2^2;
34-
if para==1
35-
v=v*cos2; % Lambertian reflectance
36-
end
37-
K(x,y)=v;
38-
end
24+
% Vectorized implementation for performance.
25+
% This replaces the nested loops over x and y with matrix operations.
26+
%
27+
% 1. coordinate grid generation:
28+
% We use ndgrid(1:dim(1), 1:dim(2)) to generate matrices X and Y.
29+
% X(i,j) contains the x-coordinate for the pixel (i,j).
30+
% Y(i,j) contains the y-coordinate for the pixel (i,j).
31+
% This avoids the explicit 'for x' and 'for y' loops.
32+
[X, Y] = ndgrid(1:dim(1), 1:dim(2));
33+
34+
% 2. Distance calculations:
35+
% Calculate distances from every grid point (X,Y) to the light (lx, ly)
36+
% and sensor (sx, sy) simultaneously for the entire grid.
37+
% result `d1` and `d2` are matrices of size dim(1) x dim(2).
38+
d1 = sqrt((lx - X).^2 + (ly - Y).^2);
39+
d2 = sqrt((sx - X).^2 + (sy - Y).^2);
40+
41+
% 3. 3D Distance calculations:
42+
% Convert 2D distances to 3D distances including height differences (lz, sz).
43+
D1 = sqrt(d1.^2 + lz^2);
44+
D2 = sqrt(d2.^2 + sz^2);
45+
46+
% 4. Cosine calculations:
47+
% Calculate cosine of angles. Result is element-wise matrix division.
48+
cos1 = lz ./ D1;
49+
cos2 = sz ./ D2;
50+
51+
% 5. Angle calculations:
52+
% Calculate theta1 for all points.
53+
theta1 = acos(cos1);
54+
55+
% 6. Luminous Intensity calculation:
56+
% The lightDistribution function calls interp1.
57+
% Since theta1 is a matrix, interp1 runs on all elements at once,
58+
% which is much faster than calling it inside a loop.
59+
Iq = lightDistribution(theta1);
60+
61+
% 7. Final Kernel calculation:
62+
% Combine all terms using element-wise multiplication (.*) and division (./).
63+
% Original: v = lightDistribution(theta1)*cos1*cos2/D1^2/D2^2;
64+
v = Iq .* cos1 .* cos2 ./ (D1.^2) ./ (D2.^2);
65+
66+
% 8. Lambertian correction:
67+
if para == 1
68+
v = v .* cos2; % Lambertian reflectance
3969
end
70+
71+
K = v;

0 commit comments

Comments
 (0)