Rumah > Artikel > hujung hadapan web > Bagaimanakah saya boleh memberikan suasana di sekeliling planet dalam Three.js?
Saya cuba bawa Three.js bertekstur kepada kehidupan. Isu yang saya hadapi ialah penyemak imbas saya menghalang tekstur daripada dimuatkan, yang telah dibetulkan dengan mengikut arahan di sini.
Selain itu, saya sedang membina permainan navigator angkasa untuk salah satu kelas saya yang termasuk kapal angkasa navigasi. Akibatnya, saya memaparkan sekumpulan planet, dengan Bumi menjadi salah satu daripadanya. Saya telah memasukkan imej pemaparan Bumi saya di bawah. Nampaknya ia berada dalam keadaan baik, tetapi saya cuba memperbaik realismenya dengan menambahkan 'suasana' di sekelilingnya.
Saya telah melihat sekeliling dan menemui beberapa ciptaan yang kelihatan sangat cantik yang menggunakan cahaya, tetapi Saya tidak percaya ia terpakai pada situasi saya.
Dan inilah kod yang meletakkan bumi dalam tempat kejadian saya (ia adalah versi kod diubah suai yang saya dapat daripada Three.js tutorial):
function addEarth(x,y){ var sphereMaterial = new THREE.MeshLambertMaterial({ //color: 0x0000ff, map: earthTexture }); // set up the sphere vars var radius = 75; segments = 16; rings = 16; // create a new mesh with // sphere geometry - we will cover // the sphereMaterial next! earth = new THREE.Mesh( new THREE.SphereGeometry( radius, segments, rings), sphereMaterial); earth.position.x = x; earth.position.y = y; // add the sphere to the scene scene.add(earth); }
[Edit 3]
Berikut ialah contoh kod sisi CPU padat yang saya gunakan dalam enjin saya untuk menjadikan suasana menggunakan shader yang disediakan di atas:
if (sys->_enable_bodya) // has planet atmosphere? if (view_depth>=0.0) { glColor4f(1.0,1.0,1.0,1.0); double a,b,p[3],d[3]; sys->shd_engine.unbind(); sys->shd_scatter.bind(); // this is the atmospheric shader if (1) //*** GLSL_uniform_supported (leftover from old GL engine version) { int j; double *w; AnsiString s; a=re; b=rp; a=divide(1.0,a*a); b=divide(1.0,b*b); // radius of planet re equatoral and rp polar and ha is atmosphere thickness sys->shd_scatter.set3f("planet_r",a,a,b); a=re+ha; b=rp+ha; a=divide(1.0,a*a); b=divide(1.0,b*b); sys->shd_scatter.set3f("planet_R" ,a,a,b); sys->shd_scatter.set1f("planet_h" ,ha); sys->shd_scatter.set1f("view_depth",view_depth); // visibility distance sys->shd_scatter.set4f("B0",B0[0],B0[1],B0[2],B0[3]); // saturated atmosphere color and overglow sys->shd_scatter.set1i("lights",sys->local_star.num); // local stars for (j=0;jlocal_star.num;j++) { a=sys->local_star[j].r; w=sys->local_star[j].p; s=AnsiString().sprintf("light_posr[%i]",j); sys->shd_scatter.set4f(s,w[0],w[1],w[2],divide(1.0,a*a)); w=sys->local_star[j].d; s=AnsiString().sprintf("light_dir[%i]",j); sys->shd_scatter.set3f(s,w[0],w[1],w[2]); vector_mul(p,sys->local_star[j].col,10.0); s=AnsiString().sprintf("light_col[%i]",j); sys->shd_scatter.set3f(s,p[0],p[1],p[2]); } } glEnable(GL_BLEND); glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); a=1.0; b=-2.0*view.scr->views[view.scr->view].znear; // color = pixel pos in screen space <-1,+1> ... no Projection/ModelView is used :) // vertex = pixel pos in elypsoid space // normal = eye-pixel direction in elypsoid space zsort.rep0.g2l_dir(d,zsort.obj_pos0); glDepthMask(0); glBegin(GL_QUADS); a=divide(1.0,view.zoom); glColor4d(-1.0,-1.0,0.0,1.0); vector_ld(p,-a,-a,b); view.scr->fromscr(p,p); view.eye0.l2g(q,p); zsort.rep0.g2l_dir(q,q); vector_sub(p,q,d); vector_one(q,q); glNormal3dv(q); glVertex3dv(p); glColor4d(+1.0,-1.0,0.0,1.0); vector_ld(p,+a,-a,b); view.scr->fromscr(p,p); view.eye0.l2g(q,p); zsort.rep0.g2l_dir(q,q); vector_sub(p,q,d); vector_one(q,q); glNormal3dv(q); glVertex3dv(p); glColor4d(+1.0,+1.0,0.0,1.0); vector_ld(p,+a,+a,b); view.scr->fromscr(p,p); view.eye0.l2g(q,p); zsort.rep0.g2l_dir(q,q); vector_sub(p,q,d); vector_one(q,q); glNormal3dv(q); glVertex3dv(p); glColor4d(-1.0,+1.0,0.0,1.0); vector_ld(p,-a,+a,b); view.scr->fromscr(p,p); view.eye0.l2g(q,p); zsort.rep0.g2l_dir(q,q); vector_sub(p,q,d); vector_one(q,q); glNormal3dv(q); glVertex3dv(p); glEnd(); glDepthMask(1); glDisable(GL_BLEND); sys->shd_scatter.unbind(); sys->shd_engine.bind(); } Ia diambil dari enjin saya, jadi ia menggunakan pelbagai perkara yang anda tidak miliki, tetapi ia sepatutnya memberi anda gambaran tentang cara sesuatu digunakan. g2l_dir, sebagai contoh, menterjemahkan vektor daripada kedudukan, dan l2g menterjemahkan kedudukan dan bukannya vektor. fromscr menukar koordinat skrin kepada koordinat 3D (tempatan kepada kamera), dan vector_one menormalkan vektor kepada vektor unit. Saya harap saya tidak lupa untuk menerangkan apa-apa.
Maklumat Tambahan
- [Adakah mungkin untuk membuat simulasi sistem suria n-jasad yang realistik dari segi saiz dan jisim? ](https://forum.threejs.org/viewtopic.php?t=14122)
Contoh Rendering Atmosfera
Berikut ialah beberapa contoh penyerakan atmosfera dan GLSL yang mengagumkan:
- [Demystifying Atmospheric Scattering for Real-Time 3D Grafik](https://marcinignac.com/2014/04/03/demystifying-atmospheric-scattering/)
- [Penyebaran Cahaya Atmosfera (Bahagian 1)](https://www.clicktorelease.com/blog/atmospheric-light-scattering-part-1)
- [Javidx9/raymarching_
Atas ialah kandungan terperinci Bagaimanakah saya boleh memberikan suasana di sekeliling planet dalam Three.js?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!