How can I prevent Scatter3 and plot3 points from occasionally getting rendered in front of a surface plot despite being physically behind it?

3 views (last 30 days)
I'm trying to make an animation of the publicly available cataloged objects in Earth orbit, but occasionally, and seemingly randomly, they are not rendered properly. Here are two cropped screenshots from the simulation that show what I mean:
And the very next frame:
In the second image, ALL points (plotted with plot3() in this instance) are rendered in front of the spherical surface plot representing the Earth, even though half of them are behind it. Maybe it's more clear to see a short sample of the actual animation: https://gfycat.com/tinygreenbeauceron The effect occurs halfway through, as the camera movement changes. However, I don't think the issue is exclusively due to the camera movement - the rendering issue is actually much worse if I use scatter3() instead of plot3(), and occurs in most of the frames of the animation. I would prefer to use scatter3() as it allows me to change the alpha values, whereas plot3() does not.
I'm not sure if I can paste code here to reproduce a "minimum working example" because I can't figure out the pattern that causes this to happen and I'm not sure how to reproduce the effect with a simpler setup. I did try, but was unable to observe the same effect. The code that does the actual plotting is pasted below, but of course it can't be run without the data from the rest of the simulation, which is too large to provide:
f1 = figure(1);
set(f1,'units','normalized','outerposition',[0 0 1 1]);
if ~strcmp(vfname,'null')
v1 = VideoWriter('2019-06-14_catalog_animation','MPEG-4');
v1.Quality = 100;
v1.FrameRate = 60;
open(v1);
nframes = numel(CamVA);
else
tvec_days = tvec_days(1);
nframes = 1;
end
for ii=1:nframes
% All objects:
pl(1) = plot3(r_all(1,:,ii),r_all(2,:,ii),r_all(3,:,ii),'w.','Markersize',0.1);
hold on
plot_Earth_km(eq_pts);
hold off
campos(rCam(:,ii))
camtarget([0;0;0])
camva(CamVA(ii))
camproj('perspective')
grid off
set(gca,'xtick',[])
set(gca,'xticklabel',[])
set(gca,'ytick',[])
set(gca,'yticklabel',[])
set(gca,'ztick',[])
set(gca,'zticklabel',[])
set(gca,'XColor','k','YColor','k','ZColor','k')
set(gca,'Color','k')
% Set the axis limits to ensure the camera is inside the axes:
xLimits = max(abs([get(gca,'XLim'),rCam(1,ii)+R_E]));
yLimits = max(abs([get(gca,'YLim'),rCam(2,ii)+R_E]));
zLimits = max(abs([get(gca,'ZLim'),rCam(3,ii)+R_E]));
axis([-xLimits,xLimits,-yLimits,yLimits,-zLimits,zLimits])
set(gcf,'renderer','openGL')
drawnow
if ~strcmp(vfname,'null')
frame = getframe(gca);
writeVideo(v1,frame);
end
end
if ~strcmp(vfname,'null')
close(v1);
end
The plot_Earth_km() function generates the surface plot of the Earth, after computing the correct lighting and generating a texturemap to apply to the surface plot. It's a very large function but the part that does the actual plotting is nothing special:
function [ax,Gh] = plot_Earth_km(varargin)
% Plots the Earth with a textured map to scale in kilometers.
% Parse inputs - only 'eq_pts' (number of equatorial points) is required
[...]
% Define the surface of the sphere
RE_eq = 6378.137; %[km] Earth equatorial radius (WGS 84)
RE_pol = 6356.752314245; %[km] Earth polar radius (WGS 84)
[Earthx,Earthy,Earthz] = ellipsoid(0,0,0,RE_eq,RE_eq,RE_pol,eq_pts);
% Generate the texturemap 'cdata' with accurate lighting
[...]
Gh = surf(ax, Earthx,Earthy,-Earthz, 'FaceColor','texturemap',...
'CData',cdata, 'EdgeColor','none');
If I stop the process on one of the frames where the issue arises, and manually change the camera settings by using the rotate3d tool or zoom tool, the points get correctly plotted behind the Earth (but for some reason the camera zooms WAY out and I have to zoom back in). I have been trying to programmatically do the same thing before capturing the frame, using zoom() and rotate3d() to change the view and then change it back, but no automated actions seem to "refresh" the render the same way that using the buttons in the toolbar of the plot3 GUI does. Manually using the "pan" tool does not refresh the render.
Thanks very much for any suggestions or help!
  9 Comments
Nathan
Nathan on 2 Aug 2019
Edited: Nathan on 2 Aug 2019
The limited file sizes on attachments makes it difficult to give you exactly what I have but I did my best to simplify everything while keeping it "effectively" identical. You'll have to propagate the objects from their initial positions on the first run through the script, but if you save them to the workspace it should skip it on subsequent runs. Here is a video of the resulting animation using exactly the code attached to this comment: https://gfycat.com/chubbygorgeousaustralianfurseal
No flashing triangles this time (I have no idea how to replicate that again - it doesn't even do it with my "non-simplified" code anymore, but I'm not sure what I changed). The magenta dot and objects in Low Earth Orbit are still visible when they shouldn't be, but it appears that objects in the geostationary ring are correctly hidden at the beginning. What's more, I discovered that increasing the markersize of the magenta dot from 10 to 15 will cause it to be hidden.
Thank you for offering to look into this, I really appreciate your help.

Sign in to comment.

Answers (0)

Products


Release

R2015b

Community Treasure Hunt

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

Start Hunting!