Ну без глубины шейдеры достаточно просты:
// 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, вам придется работать в пространстве экрана, что намного сложнее, и мне слишком лениво попробуй. В любом случае измените цвет градиента на все, что вам нравится.
Рендеринг в C++ это делается так:
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 круг, чтобы увидеть, если два расположены в такое же место. Измените градиент, чтобы он соответствовал вашим потребностям. Я не использовал прозрачность, поэтому, если вам это нужно, измените альфа-компонент и включите/установите BLEND ing.
xs,ys
- это разрешение моего окна GL. и xyzr
ваша сфера { x,y,z,r }
определение. Надеюсь, я не забыл что-то скопировать. Этот код и ответ воспользоваться (так что смотрите здесь для получения дополнительной информации в случае, если я что-то пропустил):
перепечатывать это на http://blender.stackexchange.com/ –
@AndyRay Я хочу сделать это в ** GLSL **, чтобы использовать другой проект (не на Blender), и только что сделал прототип с помощью Blender, поэтому я думаю, что SO - это подходящее место для постановки вопроса: -P –
вы можете слегка moddify это: [GLSL render Disc pattern] (http: // stackoverflow.com/a/35940219/2521214) просто вычислите цвет как функцию средней точки расстояния. Вы знаете 'Z = z0 (+/-) sqrt (R^2 - (x-x0)^2 - (y-y0)^2) '... – Spektre