// // // // // // // // // // // // // // // // // // // // // ! ! ! // // IF THE PAGE IS STUCK AT THIS STAGE AND THE TEXT DOES NOT DISAPPEAR // TRY TO UPDATE YOUR BROWSER // // RUNS BEST ON CHROME // // // // // // // // // // // // // // // // // let φ = measure => {} let videoPlayerTime = {value:0} let videoPlayerRate = 0 window.videoPlayer_play = () => {videoPlayerRate=1} window.videoPlayer_play_faster = () => {videoPlayerRate+=3} window.videoPlayer_pause = () => {videoPlayerRate=0} window.videoPlayer_rewind = () => {videoPlayerRate=-1} window.videoPlayer_rewind_faster = () => {videoPlayerRate-=3} window.videoPlayer_stop = () => {videoPlayerRate=0;videoPlayerTime.value=0} let videoPlayerGlobalTime = new Date(); let videoPlayerUpdate = () => { let now = new Date(); let dt = (now - videoPlayerGlobalTime)/1000; videoPlayerGlobalTime = now; if(keyboardState['k']=='k') { window.videoPlayer_pause(); } else if(keyboardState['l']=='l') { if(keyboardState['Shift']=='Shift') window.videoPlayer_play_faster() else window.videoPlayer_play() } else if(keyboardState['j']=='j') { if(keyboardState['Shift']=='Shift') window.videoPlayer_rewind_faster() else window.videoPlayer_rewind() } else if(keyboardState['h']=='h') { if(keyboardState['Shift']=='Shift') {videoPlayerRate=0;videoPlayerTime.value=60} else window.videoPlayer_stop() } videoPlayerTime.value += dt*videoPlayerRate if(videoPlayerTime.value < 0) { videoPlayerTime.value=0 videoPlayerRate=0 } // document.getElementById('thank-you').style.color='rgba(255,255,255,'+0.5+')' if(videoPlayerRate!=0) renderplease() window.requestAnimationFrame(videoPlayerUpdate) } videoPlayerUpdate() window.renderAnimation = renderName => { let firstFrame = 21710 let frameRate = 24*16 // [s⁻¹] let filmDuration = 72 // [s] let lastFrame = frameRate*filmDuration for(let frame=firstFrame; frame < lastFrame ;frame++) { videoPlayerTime.value = frame/frameRate let frameIndex = "0000000000" + frame frameIndex = frameIndex.substr(frameIndex.length-5) render2file( renderName + "-" + frameIndex + ".png") } // videoPlayerTime.value = 8 // render2file( "presentation-test.png") } // renderAnimation("presentation") let splot { let uniforms = { videoPlayerTime: videoPlayerTime, } let positions = [] let velocities = [] let angles = [] let angleVelocities = [] let angleGalactic = [] let angleGalacticVelocities = [] data.map( (measure,index) => { let phot_g = measure[index_phot_g_mean_mag] let phot_bp = measure[index_phot_bp_mean_mag] let phot_rp = measure[index_phot_rp_mean_mag] //////////////////////////////////////////////////////////////////////////// // ρφθ position let α = measure[index_ra] /180*π // + Math.random()*0.1 let δ = measure[index_dec] /180*π // + Math.random()*0.1 let [l,b] = CooConversion.J20002Galactic([α*180/π,δ*180/π]) b*=π/180 l*=-π/180 let M = 0.6 // rough estimation let ρ = Math.pow(10,(phot_g - M + 5)/5)/30000 // [pc] let k = 4.74 // VT [km s-1] = 4.74 1000 mu [ pc mas yr⁻¹] let μαstar = measure[index_pmra] // [mas.yr⁻¹] let μα = μαstar/cos(δ) let μδ = measure[index_pmdec] // let μρ = measure[index_radial_velocity]/k||0 // [ pc mas yr⁻¹] default amplitude to 0 if absent from DB let μρ = 0 // [ pc mas yr⁻¹] default amplitude to 0 if absent from DB // ! TODO : this transform is not the right one (it's unused here but should be fixed) : let [μl,μb] = CooConversion.J20002Galactic([μα*180/π,μδ*180/π]) // let [μφ,μb] = CooConversion.J20002Galactic([μαstar*180/π,μδ*180/π]) μb*=π/180 μl*=π/180 //////////////////////////////////////////////////////////////////////////// // xyz position let x = ρ*cos(b)*cos(l) let y = ρ*cos(b)*sin(l) let z = ρ*sin(b) let vx = μρ*cos(b)*cos(l) - ρ*μb*sin(b)*cos(l) - ρ*μl*cos(b)*sin(l) let vy = μρ*cos(b)*cos(l) - ρ*μb*sin(b)*sin(l) + ρ*μl*cos(b)*cos(l) let vz = μρ*sin(b) + ρ*μb*cos(b) //////////////////////////////////////////////////////////////////////////// positions.push( y,z,x ) velocities.push( vy, vz, vx ) angleGalactic.push( b,l+π,ρ ) angleGalacticVelocities.push( μb,μl,μρ) angles.push( δ,α,ρ ) angleVelocities.push( μδ,μα,μρ) // sizes.push( obs.size ) }) let positionsBuffer = new THREE.Float32BufferAttribute( positions, 3 ) let anglesBuffer = new THREE.Float32BufferAttribute( angles, 3 ) let velocitiesBuffer = new THREE.Float32BufferAttribute( velocities, 3 ) let angleVelocitiesBuffer = new THREE.Float32BufferAttribute( angleVelocities, 3 ) let angleGalacticBuffer = new THREE.Float32BufferAttribute( angleGalactic, 3 ) let angleGalacticVelocitiesBuffer = new THREE.Float32BufferAttribute( angleGalacticVelocities, 3 ) // let indexBuffer = new THREE.Float32BufferAttribute( indexInArray, 4 ) // let sizesBuffer = new THREE.Float32BufferAttribute( sizes, 1 ) let geometry = new THREE.BufferGeometry() geometry.addAttribute( 'position', positionsBuffer ) geometry.addAttribute( 'velocity' , velocitiesBuffer ) geometry.addAttribute( 'angle', anglesBuffer ) geometry.addAttribute( 'angleVelocity', angleVelocitiesBuffer ) geometry.addAttribute( 'angleGalactic', angleGalacticBuffer ) geometry.addAttribute( 'angleGalacticVelocities', angleGalacticVelocitiesBuffer ) // geometry.addAttribute( 'size' , sizesBuffer ) let vertexShader = CGPUglsl + ` uniform float videoPlayerTime; uniform mat4 slider_a_rot; uniform vec2 slider_s_log; uniform vec2 slider_b; uniform vec2 slider_e; uniform vec2 slider_i; uniform vec2 slider_u_log; uniform vec2 slider_w; uniform vec2 slider_w_log; uniform vec2 slider_q; uniform vec2 slider_q_log; // uniform bool key_k; // uniform vec2 slider_c; // uniform vec2 slider_v_log; // uniform mat4 slider_l_rot; // uniform vec2 slider_o; // uniform vec2 slider_p; attribute vec3 velocity; attribute vec3 angle; attribute vec3 angleVelocity; attribute vec3 angleGalactic; attribute vec3 angleGalacticVelocity; varying vec4 vColor; const mat4 j2k2gal = mat4( -0.0548755604024359, -0.873437090247923, -0.4838350155267381, 0. , 0.4941094279435681, -0.4448296299195045, 0.7469822444763707, 0. , -0.8676661489811610, -0.1980763734646737, 0.4559837762325372, 0. , 0., 0., 0., 1. ); float sigmoid(float x, float k) { return 1./(1.+exp( -(x - k*k)/k )); } float sigmoid_lin(float x, float k) { return x/(1.+exp( -(x - k*k)/k )); } void main2() { vec4 mvPosition =modelViewMatrix*vec4(position*5.,1.); gl_Position = projectionMatrix * mvPosition; gl_PointSize = 1. * slider_s_log.y; vColor = vec4(1,1,1,1); } void main() { float t_keyframe1 = 2.; float t_keyframe2 = 15.; float t_keyframe3 = 20.; float t_keyframe4 = 26.; float t_keyframe5 = 28.; float t_keyframe6 = 40.; float t_keyframe7 = 55.; float zoom = 1./(0.1+2.*sigmoid(videoPlayerTime-t_keyframe1,1.) + 10.*( sigmoid(videoPlayerTime-t_keyframe3,0.5) -sigmoid(videoPlayerTime-t_keyframe6,0.5) +sigmoid(videoPlayerTime-t_keyframe7,0.5) )); float hammer3dCtrl = 1. - clamp(slider_q.y,0.,1.) -(1. -sigmoid(videoPlayerTime-t_keyframe2,0.3) +sigmoid(videoPlayerTime-t_keyframe6,0.3) -sigmoid(videoPlayerTime-t_keyframe7,0.3) ); float highlightCtrl = clamp(slider_w_log.y * (1.+5.*( sigmoid(videoPlayerTime-t_keyframe4,0.5) -sigmoid(videoPlayerTime-t_keyframe7,0.5) )) ,1.,3.); float highlightInvCtrl = 1./clamp(slider_w.y/2.+1.,1.,1.6); float velocityMapCtrl = clamp(slider_e.x,0.,1.); float rotationSpeed = 0.2;// 0.2; float rotationSpeed2 = 0.2;// 0.2; float lambda2_t = pi + rotationSpeed* sigmoid_lin(videoPlayerTime,1.5); float ct = cos( lambda2_t ); float st = sin( lambda2_t ); mat4 rotationAnim = mat4( ct,0,-st,0, 0,1,0,0, st,0,ct,0, 0,0,0,1 ); // float ending_fun_angle = pi/8.*sin(sigmoid_lin(videoPlayerTime-t_keyframe7,1.5)*0.2); float ending_fun_angle = (pi/8.) * sigmoid(videoPlayerTime-t_keyframe7,1.5); ct = cos(ending_fun_angle); st = sin(ending_fun_angle); mat4 solidRot = mat4(1); solidRot = mat4( 1,0,0,0, 0,ct,-st,0, 0,st,ct,0, 0,0,0,1 ); // solidRot = mat4( // ct,0,-st,0, // 0,1,0,0, // st,0,ct,0, // 0,0,0,1 // )* solidRot; // vec3 ending_fun_translate = vec3(.8,-.8,0.) * sigmoid(videoPlayerTime-t_keyframe7,1.); vec3 ending_fun_translate = vec3(0,0,0); mat4 solidTrans = mat4(1); solidTrans = mat4( 1,0,0,0, 0,1,0,0, 0,0,1,0, ending_fun_translate,1 ); mat4 zoomMat = mat4(zoom,0,0,0, 0,zoom,0,0, 0,0,zoom,0, 0,0,0,1); vec4 pos = solidRot*vec4(position*5.,1.); vec4 vel = vec4(velocity*5.,1.); vec4 mvPosition = solidTrans*modelViewMatrix*zoomMat*rotationAnim * pos; vec2 hammer = spheric2hammer(spheric_rotation(angleGalactic.yx + vec2(lambda2_t,0.), slider_a_rot)); vec4 mvHammerPosition = modelViewMatrix*zoomMat * vec4( hammer,angleGalactic.z,1.); gl_Position = projectionMatrix * ( hammer3dCtrl*(mvPosition) + (1.-hammer3dCtrl)*(mvHammerPosition) ); vec2 velocityMap2d = vec2(atan(angleVelocity.y*cos(angle.x),angleVelocity.x),angle.z); vec4 velocityMap = projectionMatrix*modelViewMatrix*rotationAnim*vec4(velocityMap2d,0.,1.); gl_Position = (1. - velocityMapCtrl)*gl_Position + velocityMapCtrl * velocityMap; // float cluster = clamp( slider_u_log.y*abs(velocityMap2d.x + 2.05 )*abs(velocityMap2d.y -1. ) -.1,0.,1.); float cluster = 1.-clamp( length(velocityMap2d - vec2(-2.05,1.))*5.,0.,1.); // float cluster = 1.; float size = 1.; // size = 0.001*resolution.x; // size = length(angleVelocity.xy); // size = max(1. , size ); gl_PointSize = size * slider_s_log.y * highlightInvCtrl; // orth scale // gl_PointSize = gl_PointSize*pow(1.0 - gl_Position.z/gl_Position.w ,20000.); gl_PointSize = gl_PointSize*(2. - 1000000.*gl_Position.z/gl_Position.w); gl_PointSize = gl_PointSize*(.4+zoom); float alpha = 1.; float colorshift = 0.; if ( // angleGalacticVelocity.y > slider_b.x && // (5.31 < angleGalacticVelocity.y && angleGalacticVelocity.y < 6.08) ( (position.y > 0.3) && (position.y < 2.5) && (position.x > -0.0) && (position.x < 0.5) && (position.z > -1.0)&& (position.z < 2.0) ) ) { // float y2 = clamp(10.*abs(position.y-2.0),0.,10.); float y1 = sin( clamp(abs(position.y-0.3)*2. ,0.,pi/2.)); float y2 = sin( clamp(abs(position.y-2.5)*1. ,0.,pi/2.)); float highlight = 1. + max(highlightCtrl-1.,0.)*clamp(y1*y2,0.,1.); gl_PointSize = highlight * gl_PointSize; colorshift = -.1*highlight*( sigmoid(videoPlayerTime-t_keyframe4,0.5) -sigmoid(videoPlayerTime-t_keyframe7,0.5) ); // gl_PointSize = highlightCtrl*gl_PointSize; // alpha=0.; } if ( (cluster !=0.) && (position.x < 0.0) && (position.x > -0.4) ) { float highlight = 1. + max(highlightCtrl-1.,0.)*cluster; gl_PointSize = highlight * gl_PointSize; colorshift -= .1*highlight*( sigmoid(videoPlayerTime-t_keyframe5,0.5) -sigmoid(videoPlayerTime-t_keyframe7,0.5) ); } // vec3 s = vec3(.5+length(velocity)/100. + colorshift, 1. ,.8+clamp(-gl_Position.z*1000000.,0.,1.)); vec3 s = vec3(.5+clamp(length(velocity),0.,20.)/100. + colorshift, 1. ,1.); // vec3 s = vec3(.5+length(angleGalacticVelocity.y)/2.,1.,1.0); // vec3 s = vec3(length(angleGalacticVelocity.y)/10.,1.,1.0); // vec3 s = vec3(atan(angleGalacticVelocity.x,angleGalacticVelocity.y/cos(angleGalactic.x)),1.,1.0); vColor = vec4( hsv2rgb(s) ,alpha); // gl_PointSize = max(5.,gl_PointSize); // gl_PointSize = max(1.,gl_PointSize); gl_PointSize = max(2.,gl_PointSize); }` let fragmentShader = CGPUglsl + ` varying vec4 vColor; float sigmoid (float x, float k) {return 1./(1.+exp( -(x - k*k)/k ));} float sigmoid_lin(float x, float k) {return x /(1.+exp( -(x - k*k)/k ));} float rand(vec2 co){ return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); } uniform vec2 slider_p; float sampleAt(vec2 seed) { float dx = .5;//slider_p.x; float dy = .5;//slider_p.x; vec2 d = vec2(dx*rand(seed),dy*rand(seed.yx)) - vec2(dx*.5,dy*.5); vec2 p = gl_PointCoord + d - vec2(.5,.5); float radius = sigmoid( - length(p)*2. + 0.5 , .1 ); return radius; } void main() { float radius = 0.; float count = 0.; radius += sampleAt(vec2( 0., 0.)); count+=1.; radius += sampleAt(vec2(+1., 0.)); count+=1.; radius += sampleAt(vec2(-1., 0.)); count+=1.; radius += sampleAt(vec2( 0.,+1.)); count+=1.; radius += sampleAt(vec2( 0.,-1.)); count+=1.; radius += sampleAt(vec2(+1.,+1.)); count+=1.; radius += sampleAt(vec2(-1.,+1.)); count+=1.; radius += sampleAt(vec2(+1.,-1.)); count+=1.; radius += sampleAt(vec2(-1.,-1.)); count+=1.; radius += sampleAt(vec2( 0., 0.) + vec2(5.,5.)); count+=1.; radius += sampleAt(vec2(+1., 0.) + vec2(5.,5.)); count+=1.; radius += sampleAt(vec2(-1., 0.) + vec2(5.,5.)); count+=1.; radius += sampleAt(vec2( 0.,+1.) + vec2(5.,5.)); count+=1.; radius += sampleAt(vec2( 0.,-1.) + vec2(5.,5.)); count+=1.; radius += sampleAt(vec2(+1.,+1.) + vec2(5.,5.)); count+=1.; radius += sampleAt(vec2(-1.,+1.) + vec2(5.,5.)); count+=1.; radius += sampleAt(vec2(+1.,-1.) + vec2(5.,5.)); count+=1.; radius += sampleAt(vec2(-1.,-1.) + vec2(5.,5.)); count+=1.; radius = radius/count; // average gl_FragColor = vec4(vColor.xyz,radius); }` let pointProgram = new THREE.ShaderMaterial( { uniforms: uniforms, vertexShader: vertexShader, fragmentShader: fragmentShader, // blending: THREE.NoBlending, blending: THREE.AdditiveBlending, depthTest: false // transparent: true }) console.log(THREE) let points = new THREE.Points( geometry, pointProgram ) splot = new StellarPlot(data, undefined, φ, points) } output(splot)