Reflection energy

61 views
Skip to first unread message

zhang haohui

unread,
Apr 15, 2025, 12:07:47 AMApr 15
to mcx-users
Hello, Prof. Fang,

I am computing the average specular reflectance of a Lambertian source. When light propagates from to , I obtain the correct result, which matches the theoretical value: 0.0768 of the energy is reflected specularly. However, when light propagates from to , I expect a value of 0.5290, but I still get 0.0768. Could there be an issue with how I’m handling specular reflection? Thank you!  

Best wishes
Haohui

prop = [0,0,1,1;mua,mus,0,1.4];  % All unit is 1/mm
% Bulid the shape
Vfinal = ones(400,400,151);
Vfinal(:,:,1) = 0;

%% prepare cfg for MCX simulation
clear cfg
cfg.nphoton=1e8;
cfg.outputtype='energy';
cfg.seed = 77542;

% tissue labels:0-ambient air,1-tissue
cfg.vol=Vfinal;
cfg.prop = prop;

% light source

cfg.srcpos=[199.5,199.5,0.8];
cfg.srcdir=[0,1,1];
cfg.issrcfrom0=1;

% time windows
cfg.tstart=0;
cfg.tend=1e-8;
cfg.tstep=1e-9;

% other simulation parameters
cfg.isnormalized = 0;
cfg.isspecular=1;
cfg.isreflect=1;
cfg.autopilot=1;
cfg.gpuid=1;
cfg.issaveref=1; % save diffuse reflectance
cfg.unitinmm = 0.2;


tic
%% run MCX simulation
flux=mcxlab(cfg);
toc

%% post-simulation data processing and visualization
% convert time-resolved fluence to CW fluence
CWfluence=sum(flux.data,4);
cwdref=sum(flux.dref,4);     % diffuse reflectance
cwdref=cwdref(:,:,1);


Qianqian Fang

unread,
Apr 16, 2025, 12:31:18 PMApr 16
to mcx-...@googlegroups.com, zhang haohui

hi Haohui,

your code does not run.

can you clarify what you are trying to compute?

if your goal is to get specular reflection, you should not use flux.dref,  which is diffuse reflectance - which is different from specular reflection.

Qianqian

--
You received this message because you are subscribed to the Google Groups "mcx-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mcx-users+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/mcx-users/1fa8d080-bea2-441d-90d2-f28dce2ce5cdn%40googlegroups.com.

zhang haohui

unread,
Apr 16, 2025, 2:25:30 PMApr 16
to mcx-users
Hello, Prof. Fang,

Sorry for the inconvenience.

In the code below, I obtain a final value of 0.0768 in the last row, which represents the percentage of light that is specularly reflected on the surface. This matches the theoretical result for a Lambertian source using the Fresnel equation.

However, when I modify the prop parameter to:

prop = [0,0,1,1.4;mua,mus,0,1]; % All unit is 1/mm

I expect the final result to be 0.5290, which corresponds to the theoretical specular reflectance. Despite this change, the result remains 0.0768.

Could you please advise if I am missing something in the setup or if there's another parameter I should adjust?

Thank you for your help.



mua = 0.5;
mus = 0;
prop = [0,0,1,1;mua,mus,0,1.4]; % All unit is 1/mm
% Bulid the shape
Vfinal = ones(400,400,151);
Vfinal(:,:,1) = 0;
%% prepare cfg for MCX simulation
clear cfg
cfg.nphoton=1e8;
cfg.outputtype='energy';
cfg.seed = 77542;
% tissue labels:0-ambient air,1-tissue
cfg.vol=Vfinal;
cfg.prop = prop;
% light source
cfg.srctype = 'disk';
cfg.srcpos=[199.5,199.5,0.8];
cfg.srcparam1=[0.5,0,0];
cfg.srcdir=[0,0,1,-inf];
cfg.issrcfrom0=1;
% time windows
cfg.tstart=0;
cfg.tend=1e-8;
cfg.tstep=1e-9;
% other simulation parameters
cfg.isnormalized = 0;
cfg.isspecular=1;
cfg.isreflect=1;
cfg.autopilot=1;
cfg.gpuid=1;
cfg.issaveref=1; % save diffuse reflectance
cfg.unitinmm = 0.2;
tic
%% run MCX simulation
flux=mcxlab(cfg);
toc
%% post-simulation data processing and visualization
% convert time-resolved fluence to CW fluence
CWfluence=sum(flux.data,4);
1-sum(CWfluence,"all")/1e8

Qianqian Fang

unread,
Apr 16, 2025, 7:43:32 PMApr 16
to mcx-...@googlegroups.com, zhang haohui

hi Haohui,

if your goal is to validate the Fresnel's law at the tissue surface, try the below code instead

you don't need a large domain and large number of photos to verify this - my cfg.vol below contains 3 layers, layer 1 is label 0 (background), used to store reflectance; layer 2 is material 1, layer 3 is material 2.

I use cfg.bc='aaaaaa' to disable reflection from all bounding box surfaces, but allows mcx to reflect for mismatches within the medium.

to be safe, I also set the mua of material 2 to a large number (1e6/mm), so that even there are reflection, it won't contribute much for the accumulation inside layer 1 - however, this is unnecessary if cfg.bc is used.


you can verify using the trajectory plot I used at the bottom of my script - with a screen capture shown on the right panel of the attached figure.


if you comment out the cfg.bc line, you can see multiple reflections.

I verified both directions for an incident angle of pi/4, it matches the Fresnel's equation.


air_to_tissue=1;
if(air_to_tissue)
    prop = [0,0,1,1;0,0,1,1;1e6,0,1,1.4];  % All unit is 1/mm
else
    prop = [0,0,1,1.4;0,0,1,1.4;1e6,0,1,1];  % All unit is 1/mm
end
% Bulid the shape
Vfinal = zeros(10,10,3);
Vfinal(:,:,2) = 1;
Vfinal(:,:,3) = 2;


%% prepare cfg for MCX simulation
clear cfg

cfg.nphoton=1e6;
cfg.outputtype='energy';


% tissue labels:0-ambient air,1-tissue
cfg.vol=Vfinal;
cfg.prop = prop;
% light source

cfg.srctype = 'pencil';
cfg.srcpos=[4.9,4.9,1];
theta=pi/4;
cfg.srcdir=[0,sin(theta),cos(theta)];
cfg.issrcfrom0=1;
% time windows
cfg.tend=1e-8;
cfg.tstep=cfg.tend;
cfg.bc='aaaaaa';
% other simulation parameters
cfg.isspecular=0;


cfg.issaveref=1; % save diffuse reflectance
cfg.unitinmm = 0.2;

tic
%% run MCX simulation

[flux, detp, vol, seeds, traj]=mcxlab(cfg);


toc
%% post-simulation data processing and visualization
% convert time-resolved fluence to CW fluence

disp(struct('reflection', sum(flux.dref(:,:,1), 'all')))

mcxplotphotons(traj);


Qianqian

air_to_tissue.png

zhang haohui

unread,
Apr 16, 2025, 9:13:37 PMApr 16
to mcx-users
Hello, Prof. Fang,

Thanks for your results. I tried it and it looks great!

On  the other hand, My question is related the energy of reflection and refraction. In my example, a Lambertian source emits light from a medium with refractive index n = 1 to n = 1.4, and approximately 7% of the light is reflected, which aligns with expectations. However, when I reverse the direction—having light transmit from n = 1.4 to n = 1—the reflectance remains at 7%, which does not seem correct (should be 53% theoretically). Could you help clarify this discrepancy?  

Best wishes
Haohui

Qianqian Fang

unread,
Apr 16, 2025, 10:09:31 PMApr 16
to mcx-...@googlegroups.com, zhang haohui

did you try adapting from my code instead?

I changed cfg.srctype to 'disk', and cfg.srcdir to [0,sin(theta),cos(theta), -inf] to use a Lambertian source, I see my code returned different reflection energy when air_to_tissue is set to 1 and to 0.

zhang haohui

unread,
Apr 18, 2025, 5:21:29 PMApr 18
to mcx-users
Hello, Prof. Fang,

Thank you for the explanation — I now understand your method. You consider reflection at the interface between media 1 and 2, whereas my approach involves reflection between the environment and medium 1 (i.e., media 0 and 1).

Your method definitely yields the correct result. I will adopt your method.

Best wishes

Haohui


Reply all
Reply to author
Forward
0 new messages