0

简单的问题,我刚刚让我的第一个镜面着色器工作,并查看数学,我不禁认为每个边缘之间的角度应该导致“镜面反射”尖峰/变成锯齿状。但它完全是流体/球形的。

这个想法是计算顶点法线的角度,但只有这么多,“镜面阴影”仍然完美均匀。

我看不出 gpu 如何仅根据顶点法线知道片段的角度。

在此处输入图像描述

编辑:垂直着色器

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

和碎片

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

答案:插值

对于渲染器,这将等同于平均曲线,而不是锯齿状边缘(平坦阴影)

4

1 回答 1

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.

如果对于由三个顶点定义的给定多边形,您将法线设置为全部面向同一方向,您将获得不同的效果。

于 2016-02-23T09:47:39.427 回答