2016-12-31 4 views
0

Я просто noob для GLSL и не знаю, как это сделать в GLSL.
То, что я пытаюсь сделать, это сделать значение альфа-значения равным 1 по центру сферы и постепенно опускаться на внешний.Как я могу сделать сферу градиента на glsl?

Итак, я создал прототип с использованием редактора узлов Blender, и так я и сделал. Sphere gradient

Теперь я пытаюсь сделать это в glsl.
Возможно, я могу использовать gl_Normal для замены «normal on Geometry» на Blender.
(Несмотря на то, что он удаляется после версии 140, моя конечная цель - просто «сделать» его, поэтому не обращайте внимания.)
И есть также функция точек для вычисления «точечного произведения на векторной математике» на glsl.

Теперь мне нужно «Посмотреть вектор данных камеры» и «ColorRamp».
Я думаю, что «ColorRamp» можно сделать с функциями смешивания и греха,
, но понятия не имею, как получить «Просмотр вектора данных камеры».
Я уже читал this и понимаю, что это такое, но не знаю, как это сделать.

Так как я могу получить «Просмотр вектора данных камеры»?

+0

перепечатывать это на http://blender.stackexchange.com/ –

+0

@AndyRay Я хочу сделать это в ** GLSL **, чтобы использовать другой проект (не на Blender), и только что сделал прототип с помощью Blender, поэтому я думаю, что SO - это подходящее место для постановки вопроса: -P –

+0

вы можете слегка moddify это: [GLSL render Disc pattern] (http: // stackoverflow.com/a/35940219/2521214) просто вычислите цвет как функцию средней точки расстояния. Вы знаете 'Z = z0 (+/-) sqrt (R^2 - (x-x0)^2 - (y-y0)^2) '... – Spektre

ответ

1

Ну без глубины шейдеры достаточно просты:

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

И результат:

overview

в белом отладки GL 1.0 круг, чтобы увидеть, если два расположены в такое же место. Измените градиент, чтобы он соответствовал вашим потребностям. Я не использовал прозрачность, поэтому, если вам это нужно, измените альфа-компонент и включите/установите BLEND ing.

xs,ys - это разрешение моего окна GL. и xyzr ваша сфера { x,y,z,r } определение. Надеюсь, я не забыл что-то скопировать. Этот код и ответ воспользоваться (так что смотрите здесь для получения дополнительной информации в случае, если я что-то пропустил):

+0

Спасибо! Решена путем изменения моей программы, следуя инструкциям. :-) И извините за поздний комментарий ... Я был в больнице из-за какой-то аварии ;-( –