简单的问题,我只是让我的第一个镜面着色器工作,并查看数学,我不能帮助认为每个边缘之间的角度应该导致“镜面反射”尖峰/变成锯齿状。但它完全是流体/球形。
这个想法是计算偏离顶点法线的角度,但是只有这么多,并且“镜面阴影”仍然完美无缺。
我无法看到gpu如何仅根据顶点法线知道片段的角度。
编辑: 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);
}
和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;
}
//修改
我找到了这个btw(一年后)的答案:Vertice法线(vn)是连接到它的每个面/三角形的组合值。也就是说,连接到多个面的1个顶点在标准化时将具有组合的面法线。该值vn被计算为相邻面法线的平均值。当计算该值以指示亮度时,GPU将提供“阴影”,这是每个附近边的标准化交叉积。
我在重新计算项目的面部法线时想到了这一点:
重新计算顶点法线的伪代码:
for (for each face/triangle, find face-normal and add to adjacent vn's)
vec3 face_normal=cross(face[1]-face[0],face[2]-face[0]);
vn[0]+=face_normal; //notice +=
vn[1]+=face_normal;
vn[2]+=face_normal;
//then just normalize them to get the weighted average
for(auto&x:vn)x=normalize(x);
对于渲染器,这将等同于平均曲线,而不是锯齿状边缘(平面阴影)
答案 0 :(得分:2)
没有代码.etc。很难准确回答你的问题,但假设一个简单的矢量着色器 - &gt;片段着色器管道。将为每个顶点运行矢量着色器。它将设置通常设置的标记为“变化”的参数。 (例如纹理坐标)。
每3个顶点将被分组以形成多边形,并且片段着色器运行以确定多边形内每个点的颜色。 &#39;变化&#39;由顶点着色器设置的参数将根据片段与多边形的3个边缘的距离进行插值(参见:重心插值)。
因此例如:
gl_FragColor = texture2D(myUniformSampler, vec2(myTextureCoord.s,myTextureCoord.t));
将为每个像素正确采样纹理。假设您正在使用每片段光照,则可能会根据您在顶点着色器中设置的值为每个片段着色器插值。如果为每条边设置相同的法线,则会产生不同的效果。
编辑(根据您添加的代码):
out vec2 UV;
out vec3 normal;
out vec3 color;
在顶点着色器中为每个顶点设置。每三个顶点定义一个多边形。然后对多边形内的每个点(例如像素)运行片段着色器以确定颜色.etc。每一点。
这些参数的值:
in vec3 color; /// <<-- You don't seem to be actually using this
in vec2 UV;
in vec3 normal;
片段着色器中的是根据被绘制的多边形上的点的距离进行插值的。来自每个顶点(参见:重心插值)。因此,法线在顶点着色器定义的顶点之间变化。
如果对于由三个顶点定义的给定多边形,您将法线设置为朝向相同方向,则会产生不同的效果。