How can i make gradient sphere on glsl?

流过昼夜 提交于 2019-11-29 16:52:23
Spektre

Well without depth the shaders are simple enough:

// Vertex
varying vec2 pos;       // fragment position in world space
void main()
    {
    pos=gl_Vertex.xy;
    gl_Position=ftransform();
    }

// Fragment
varying vec2 pos;
uniform vec4 sphere;    // sphere center and radius (x,y,z,r)
void main()
    {
    float r,z;
    r=length(pos-sphere.xy);    // radius = 2D distance to center (ignoring z)
    if (r>sphere.a) discard;    // throw away fragments outside sphere
    r=0.2*(1.0-(r/sphere[3]));  // color gradient from 2D radius ...
    gl_FragColor=vec4(r,r,r,1.0);
    }

Yes you can also use gl_ModelViewProjectionMatrix * gl_Vertex; instead of the ftransform(). As you can see I used world coordinates so I do not need to play with radius scaling... If you want also the gl_FragDepth to make this 3D then you have to work in screen space which is much more complicated and I am too lazy to try it. Anyway change the gradient color to whatever you like.

The rendering in C++ is done like this:

void gl_draw()
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    GLint id;

    float aspect=float(xs)/float(ys);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0/aspect,aspect,0.1,100.0);
    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef(15.0,0.0,1.0,0.0);
    glTranslatef(1.0,1.0,-10.0);

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_TEXTURE_2D);

    float xyzr[4]={ 0.7,0.3,-5.0,1.5 };

    // GL 1.0 circle for debug
    int e; float a,x,y,z;
    glBegin(GL_LINE_STRIP);
    for (a=0.0,e=1;e;a+=0.01*M_PI)
        {
        if (a>=2.0*M_PI) { e=0; a=2.0*M_PI; }
        x=xyzr[0]+(xyzr[3]*cos(a));
        y=xyzr[1]+(xyzr[3]*sin(a));
        z=xyzr[2];
        glVertex3f(x,y,z);
        }
    glEnd();

    // GLSL sphere
    glUseProgram(prog_id);
    id=glGetUniformLocation(prog_id,"sphere"); glUniform4fv(id,1,xyzr);
    glBegin(GL_QUADS);
    glColor3f(1,1,1);
    glVertex3f(xyzr[0]-xyzr[3],xyzr[1]-xyzr[3],xyzr[2]);
    glVertex3f(xyzr[0]+xyzr[3],xyzr[1]-xyzr[3],xyzr[2]);
    glVertex3f(xyzr[0]+xyzr[3],xyzr[1]+xyzr[3],xyzr[2]);
    glVertex3f(xyzr[0]-xyzr[3],xyzr[1]+xyzr[3],xyzr[2]);
    glEnd();
    glUseProgram(0);

    glFlush();
    SwapBuffers(hdc);
    }

And result:

In white is the debug GL 1.0 circle to see if the two are placed in the same place. Change the gradient to match your needs. I did not use transparency so if you need it change the alpha component and enable/set BLENDing.

The xs,ys is resolution of my GL window. and xyzr is your sphere { x,y,z,r } definition. Hope I did not forget to copy something. This code and answer take advantage of (so look there for more info in case I miss something):

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!