Rumah  >  Artikel  >  hujung hadapan web  >  Bagaimanakah saya boleh memberikan suasana di sekeliling planet dalam Three.js?

Bagaimanakah saya boleh memberikan suasana di sekeliling planet dalam Three.js?

DDD
DDDasal
2024-11-12 07:30:02142semak imbas

How can I render an atmosphere around a planet in Three.js?

Bagaimanakah saya boleh memaparkan 'atmosfera' berbanding paparan Bumi dalam Three.js?

Masalah

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);
    }

masukkan penerangan imej di sini

Penyelesaian

[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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn