7 views (last 30 days)

Show older comments

According to the math of alpha compositing and color blending (also on Wikipedia), no matter the transparency (alpha), a sufficiently large number of overlapping dots of a color should look the same as an opaque dot of the same color. Yet, while attempting to visualize the density of point clouds using point transparency, I found that the color never saturated, no matter how dense the point cloud. Instead, the "final" color reached depended on the alpha of the dots, which it should not. By "final", I mean the color for which adding more dots doesn't change the color. To demonstrate this, in the following example, in each pass through the for loop, I'm plotting a very large number, 100,000, of coincident points of the same color and transparency; each pass is for a different alpha (transparency). The number of coincident points plotted is large enough that the apparent color is constant, i.e. plotting more coincident points doesn't change the apparent color.

alphas=[0.001,0.002,0.01,0.1,1]; %transparencies to use, 1=opaque

figure

for cnt1=1:numel(alphas)

%plot 1e5 coincident dots at x=cnt1, y=0, and of transparency alphas(cnt1)

scatter(zeros(1e5,1)+cnt1,zeros(1e5,1),100,'k','markerfacecolor',[0,0.7,0.7],'markeredgecolor',[0,0,0],'markerfacealpha',alphas(cnt1))

hold on

xticklabels{cnt1}=num2str(alphas(cnt1));

end

axis([1,numel(alphas),-1,1])

set(gca,'xtick',1:numel(alphas),'xticklabel',xticklabels,'ytick',[])

xlabel('alpha')

Per the first sentence of this post, all the dots in the figure this makes should appear, as an integer RGP triplet, as [0,179,179], but due to the issue, only the opaque dot achieves this color. The apparent colors are, from left to right:

[255,255,255], [128,255,255], [41,221,221], [4,4,183], [0,179,179]

Note the left-most dot is transparent; the transparencies also vary in an incorrect fashion. Via some research and testing, I've found that the exact problem appears to be due to roundoff error in the calculation of color with transparency. Specifically, working with integer colors from 0 to 255, when the change in apparent color due to adding one more dot is smaller than 0.5, adding another dot doesn't change the apparent color. This is a function of the level of transparency used: the higher the transparency, the larger the error in "final" color. It is also affected by the background color. The higher the transparency, the more severe the problem, as the example figure shows.

I'm using the default hardware OpenGL renderer. If I switch to opengl software, the problem worsens. If I switch to painters, it changes marginally. Behavior is consistent across multiple Windows-based machines.

Is this a fundamental limitation of 2D rendering in OpenGL, an issue with Matlab's implementation, or is there some way around it?

Per the discussion in the comments with J. Alex Lee, we can see that in 3D, this does not happen.

alphas=0.1; %transparency

intervalRepeat=1; %step size for repeats

nRepeat=30; %maximum number of repeats (overlapping dots) to plot

% alphas=0.01; %transparency

% intervalRepeat=10; %step size for repeats

% nRepeat=300; %maximum number of repeats (overlapping dots) to plot

%2d plot

figure

% dockit

for cnt1=1:intervalRepeat:nRepeat

%plot cnt1 coincident dots in 2D at x=cnt1, y=0 and of transparency alphas

scatter(cnt1+zeros(cnt1,1),zeros(cnt1,1),100,'k',...

'markeredgecolor','none','markerfacecolor',[0,0.7,0.7],'markerfacealpha',alphas)

hold on

end

%plot a final opaque dot on the right-hand side

scatter3(cnt1+intervalRepeat,0,1,100,'k',...

'markeredgecolor','none','markerfacecolor',[0,0.7,0.7],'markerfacealpha',1)

grid on

% title('2D')

%3d plot

% figure

% % dockit

for cnt1=1:intervalRepeat:nRepeat

%plot cnt1 coincident dots in 3D at x=cnt1, y=1, z=1:cnt1 and of transparency alphas

scatter3(cnt1+zeros(cnt1,1),zeros(cnt1,1)+1,1:cnt1+zeros(cnt1,1),100,'k',...

'markeredgecolor','none','markerfacecolor',[0,0.7,0.7],'markerfacealpha',alphas)

hold on

end

%plot a final opaque dot on the right-hand side

scatter3(cnt1+intervalRepeat,0+1,1,100,'k',...

'markeredgecolor','none','markerfacecolor',[0,0.7,0.7],'markerfacealpha',1)

xlabel('number of overlapping points')

ylim([-1,2])

set(gca,'ytick',[0,1],'yticklabel',{'2D','3D'})

% grid off

% title('3D')

view(2) %make view angle be the same as that of a 2D plot

Although this plots the same thing in 2D and 3D, only the 3D leads to the correct alpha compositing and color blending. If you run the code, you can rotate the view to see the 3D dots.

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!