- /
-
Spheres in spheres
on 4 Nov 2024
- 52
- 451
- 0
- 1
- 1975
Cite your audio source here (if applicable): Daisukey Amaya (Pixel) / Cave Story / Moonsong
drawframe(1);
Write your drawframe function below
% In the tradition of slap-dash last minute submissions, this one
% has a function that creates a camera-sphere: it takes pictures from 6
% directions and seemlessly maps the results to a sphere. The patch objects
% for the originally rendered scene are deleted and replaced with the
% cam-sphere map. Two cam-spheres are made at two locations, then expanded
% versions of both are made; a logarithmic sphere spirals out of the
% inner scene to the identical outer scene.
function drawframe(f)
l=@linspace;
% No persistent variables, we are just going to change camera position
% after the first iteration
if f==1
% Make our scene:
rng(2,'v4');
N=600;
q=l(-1,1,N);
[q1,q2]=meshgrid(q);
k=exp(6i*randn(N))./(q.^2+q'.^2+2e-5); % Complex spatial noise
k1=abs(ifft2(k))*.3;
k2=circshift(abs(ifft2(k.*(hann(N)*hann(N)').^300))*3+1+randn(N)/200, [0,-30])/20; % Sand
sf=(q1.^2+q2.^2)/10;
E='EdgeC';
O='none';
D='DiffuseS';
L='SpecularS';
A='AmbientS';
F='FaceC';
p={E,O,D,1,L,0}; % Got this shortener from Matteo's awesome sub. thanks(!)
SA=surf(q1+(k1-.1),q2,k1-sf/3,F,[.3,.3,.3],p{:});
hold;
SB=surf(q1+(k2-.1),q2,k2-sf/3,F,[.8,.9,1],A,.5,p{:});
[x,y,z]=sphere(N-1);
cp=rescale(max(k1-l(0,1,N)'.^4+.6,.8*(erf(2*l(1.3,-1,N)'+.4)/2+.5)));
c2=(cool+1)/2;
c2(:,3)=l(1,.2,256)'.^.6;
c2=c2.*[.6,.7,1];
SC=surf(x*5,y*5,z*5,cp,E,O,A,1);
colormap(c2);
axis equal off;
light('position',[-.5,0,1],'color',[.8,.9,1]);
% Alright, we have our scene. Now, camera location for the first
% photo-sphere:
P=[0,0,.5];
[a,b,c,I]=H(P); % Photo sphere function; includes output points and image.
% Could use warp for a lighter-weight mapping but...
% slapdash
% Create sphere
d=.55;
S=surf(d*a+P(1),d*b+P(2),d*c+P(3),I/220,E,O,A,1,D,1);
% Define location for next sphere, centered around current camera position
d2=1.9*1.5;
P2=[.8,.8,.5];
[a2,b2,c2,I2]=H(P2); % Create camera sphere
% Plot sphere
S2=surf(d2*a2+P2(1),d2*b2+P2(2),d2*c2+P2(3),I2/255,E,O,A,1,D,0,L,0);
d2=d2*1.005;
% Make outer spheres for loop
S3=surf(d2*a2+P2(1),d2*b2+P2(2),d2*c2+P2(3),I/220,E,O,A,1);
d2=d2*4;
P2=[5,5,.5];
S4=surf(d2*a2+P2(1),d2*b2+P2(2),d2*c2+P2(3),I2/255,E,O,A,1,D,0,L,0);
A=gca;
cla(A.Children(1:end-3));
camva(60);
camtarget([0,0,.5]);
end
% Logarithmic spiral for camera position
ag=l(0,2*pi,97)+pi/4;
xx=[.905*exp(.291*ag).*sin(ag)];
yy=[.905*exp(.291*ag).*cos(ag)];
campos([xx(f),yy(f),.5]);
end
% Photo-sphere function; user enters camera position. Assumes there is no
% black in the scene beside the patch faces used for occlusion.
function [a,b,c,I]=H(P)
[a,b,c]=sphere(499);
l=@(x)linspace(-1,1,x)/.99;
V=.1*[1,1,1;-1,1,1;-1,-1,1;1,-1,1;1,1,-1;-1,1,-1;-1,-1,-1;1,-1,-1]+P;
F=[1,2,3,4;1,2,6,5;1,4,8,5;5,6,7,8;3,4,8,7;2,3,7,6];
o=[0,0,1;0,1,0;1,0,0;0,0,-1;0,-1,0;-1,0,0];
A=gca;
for n=1:6
p=patch(Faces=F(setdiff(1:6,n),:),Vertices=V);
camproj p
campos(P);
camtarget(P+o(n,:));
camva(90);
M{n}=getframe(gcf);
cla(A.Children(2:end));
end
m=max(M{1}.cdata,[],3)>0;
s=size(M{1}.cdata(:,:,1));
[w,o]=ind2sub(s,min(find(m>0)));
[W,O]=ind2sub(s,max(find(m>0)));
[X,Y]=meshgrid(l(O-o+1),l(W-w+1));
for m=1:3
G=@(x,n)double(x.cdata(w:W,o:O,n));
q=@(C,a,b,n,x,y,z,I)nanmax(C,interp2(a,b,G(M{n},m),x./z,y./z));
C=q(0,X,Y,1,a,b,c.*(c>0));
C=q(C,X,Y,1,a,b,c.*(c>0));
C=q(C,X,-Y,2,a,c,b.*(b>0));
C=q(C,-X,-Y,3,b,c,a.*(a>0));
C=q(C,-X,-Y,4,a,-b,c.*(c<0));
C=q(C,X,Y,5,a,c,b.*(b<0));
I(:,:,m)=q(C,-X,Y,6,b,c,a.*(a<0));
end
end