如何在glsl上制作渐变球? [英] How can i make gradient sphere on glsl?

查看:137
本文介绍了如何在glsl上制作渐变球?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是GLSL的菜鸟,不知道如何在GLSL中做到这一点.
我想做的是在球心上将alpha值设为1,然后在球体外逐渐减小.

I'm just a noob to GLSL and don't know how to do this in GLSL.
What I trying to do is making alpha value to 1 on center of sphere and drop gradually on outer.

因此,我使用Blender节点编辑器制作了一个原型,这就是我所做的.

So I made a prototype using Blender node editor and that's how I did.

现在我正尝试在glsl中执行此操作.
也许我可以使用gl_Normal替换Blender上的几何上的法线".
(尽管在版本140之后将其删除,但我的最终目标只是制作"它,所以请忽略它.)
并且在glsl上也有点函数来计算向量数学上的点积".

Now I am trying to do this in glsl.
Maybe i can use gl_Normal to replace "normal on Geometry" on Blender.
(Though it's removed after version 140, my final goal is just "make" it, so ignore that.)
And there are also dot function to calculate "dot product on vector math" on glsl.

现在我需要的是查看摄像机数据的向量"和"ColorRamp".
我认为可以使用混合和sin函数来完成"ColorRamp",
但不知道如何获取摄像机数据的查看矢量".
我已经阅读了,并且了解了它的含义,但不知道如何获得.

Now i need is "View vector of camera data" and "ColorRamp".
I think "ColorRamp" can be done with mix and sin functions,
but have no idea how to get "View vector of camera data".
I already read this, and understand what it is, but don't know how to get.

那么我如何获得查看摄像机数据矢量"?

So How can I get "View vector of camera data"?

推荐答案

着色器很浅就很简单:

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

是的,您也可以使用gl_ModelViewProjectionMatrix * gl_Vertex;代替ftransform().如您所见,我使用了世界坐标,因此我不需要使用半径缩放...如果您还想使用gl_FragDepth进行此3D绘制,则必须在屏幕空间中工作,这要复杂得多,我也是懒尝试.无论如何,将渐变颜色更改为您喜欢的任何颜色.

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.

在C ++中的渲染是这样完成的:

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

结果:

白色的是调试 GL 1.0 圆圈,以查看两者是否放置在同一位置.更改渐变以符合您的需求.我没有使用透明度,因此,如果需要,可以更改Alpha组件并启用/设置 BLEND ing.

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.

xs,ys是我的GL窗口的分辨率. xyzr是您的球体{ x,y,z,r }定义.希望我没有忘记复制一些东西.这段代码和答案可以利用(因此,请在此处查找更多信息,以防万一我错过了什么):

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):

  • GLSL render Disc pattern
  • complete GL+GLSL+VAO/VBO C++ example

这篇关于如何在glsl上制作渐变球?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆