0

Simple question, I just got my first specular shader working, and looking over the math, I cant help to think that the angle between each edge should cause the "specularity" to spike/become jagged. But its entirely fluid/spherical.

The idea is to calculate the angle off the vertice-normal, but there are only so many of these, and still the "specular shade" turns out perfectly even.

I cant see how the gpu knows the angle of the fragment based off of the vertice normal alone.

enter image description here

edit: vert shader

#version 400 core

layout ( location = 0 ) in vec3 vertex_position;
layout ( location = 2 ) in vec2 tex_cord;
layout ( location = 3 ) in vec3 vertex_normal;

uniform mat4 transform; //identity matrix
uniform mat3 lmodelmat; //inverse rotation

out vec2 UV;
out vec3 normal;

void main()
{
  UV=tex_cord;
  normal=normalize(vertex_normal*lmodelmat);  //normalize to keep brightness

  gl_Position=transform*vec4(vertex_position,1.0);
}

and frag

#version 400 core

in vec2 UV;
in vec3 normal;

uniform sampler2D mysampler;
uniform vec3 lightpos; //lights direction

out vec4 frag_colour;

in vec3 vert2cam; //specular test

void main()
{
  //skip invis frags
  vec4 alphatest=texture(mysampler,UV);
  if(alphatest.a<0.00001)discard; 

  //diffuse'ing fragment
  float diffuse=max(0.1,dot(normal,lightpos));

  //specular'izing fragment
  vec3 lpnorm=normalize(lightpos);  //vector from fragment to light
  vec3 reflection=normalize(reflect(-lpnorm,normal)); //reflection vector
  float specularity=max(0,dot(lpnorm,reflection));
  specularity=pow(specularity,50);

  frag_colour=alphatest*diffuse+specularity;
}

Answer: Interpolation

This will, for the renderer, equate as an averaged curve, and not a jagged edge (flat shading)

Charlie
  • 585
  • 9
  • 17
  • Are you using Gouraud or Phong shading? – Luka Jacobowitz Feb 23 '16 at 09:30
  • 2
    I would guess some sort of interpolation happens. But without any code, it hard to tell what's going on. – Anders Schou Feb 23 '16 at 09:35
  • you would call this phong shading? its basically the cosA between the reflection of light and vertice normal added to the color. I just cant see how glsl reads it as an even curve, when im inputting just a few values – Charlie Feb 23 '16 at 09:36
  • so whats causes the gpu to create interpolated values? like is it part of the fragmentation sequence of the pipeline? Ill edit with my "barebone" glsl code – Charlie Feb 23 '16 at 09:38
  • You did not state how a point on the face that is not a vertex gets it's color. Is the color interpolated? Or is the normal interpolated and then evaluated? – Aziuth Feb 23 '16 at 09:47
  • It gets its color from the texture sampler? the vertice normal is input via uniform as defined by maya and the obj format/standard. derp, some of the code went missing, and yeah, after adding that, the attribute color isnt used atm, it gets color from texture and tex coords – Charlie Feb 23 '16 at 09:59
  • Your fragment shader inputs are using smooth interpolation by default. Check this out: https://www.khronos.org/opengl/wiki/Type_Qualifier_(GLSL)#Interpolation_qualifiers – vesan Mar 14 '17 at 04:10
  • The value is calculated by using vertex normals, not face normals. Thats the explanation – Charlie Mar 14 '17 at 04:24

1 Answers1

2

Without code .etc. it is hard to precisely answer your question but assuming a simple vector shader -> fragment shader pipeline. The vector shader will be run for each vertex. It will set typically set parameters marked 'varying' (e.g. texture coordinates).

Every 3 vertices will be grouped to form a polygon and the fragment shader run to determine the color of each point within the polygon. The 'varying' parameters set by the vertex shader will be interpolated based on the distance of the fragment from the 3 edges of the polygon (See: Barycentric interpolation).

Hence for example:

gl_FragColor = texture2D(myUniformSampler, vec2(myTextureCoord.s,myTextureCoord.t));

Will sample the texture correctly for each pixel. Assuming you're using per-fragment lighting, the values are probably being interpolated for each fragment shader from the values you set in your vertex shader. If you set the same normal for each edge you'll get a different effect.

Edit (Based on the code you added):

out vec2 UV;
out vec3 normal;
out vec3 color;

Are set per vertex in your vertex shader. Every three vertices defines a polygon. The fragment shader is then run for each point (e.g. pixel) within the polygon to determine the color .etc. of each point.

The values of these parameters:

in vec3 color; /// <<-- You don't seem to be actually using this
in vec2 UV;
in vec3 normal;

in the fragment shader are interpolated based on the distance of the point on the polygon being 'drawn' from each vertex (See: Barycentric interpolation). Hence the normal varies between the vertices defined by your vertex shader.

If for a given polygon defined by three vertices you set the normals to all be facing in the same direction, you will get a different effect.

Jarra McIntyre
  • 1,265
  • 8
  • 13
  • I think this is the correct answer to my question. The fragmentation stage of the pipeline creates several values, that somehow inherit values from the nearby vertex? Sort of like smoothing of the colors? – Charlie Feb 23 '16 at 10:20
  • Presumably you set a normal for each vertex in the vertex shader to pass to the fragment shader. These are interpolated between to form the input values for each run of the fragment shader (the fragment shader is run many times for each polygon formed by the vertex shader to determine the color of each point (e.g. pixel)). – Jarra McIntyre Feb 23 '16 at 10:29
  • but how does the gpu know which value is which? for all it cares, im just putting random vec3s onto the stack. values that are even modified, perhaps it reads the command as a lit circle? and draws it like that, and not jagged along the edges? maybe its a redundant question – Charlie Feb 23 '16 at 10:34
  • I think Barycentric interpolation is the right think to talk about here. It seems the fragment shader does some interpolation on its own, and uses those values to fill in the color. I guess hence the word fragment? Ill chalk it up as answered, thanks =) – Charlie Feb 23 '16 at 11:18