为什么基本的镜面遮光液,而不是锯齿状?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么基本的镜面遮光液,而不是锯齿状?相关的知识,希望对你有一定的参考价值。
简单的问题,我只是让我的第一个镜面着色器工作,并查看数学,我不能帮助认为每个边缘之间的角度应该导致“镜面反射”尖峰/变成锯齿状。但它完全是流体/球形。
我们的想法是计算顶点法线的角度,但是只有这么多,并且“镜面阴影”仍然完美无缺。
我无法看到gpu如何根据顶点法线单独知道片段的角度。
编辑:vert着色器
#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;
}
//编辑
我找到了这个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);
对于渲染器,这将等同于平均曲线,而不是锯齿状边缘(平面阴影)
没有代码.etc。很难准确回答你的问题,但假设一个简单的矢量着色器 - >片段着色器管道。将为每个顶点运行矢量着色器。它将典型地设置标记为“变化”的参数(例如纹理坐标)。
每3个顶点将被分组以形成多边形,并且片段着色器运行以确定多边形内每个点的颜色。由顶点着色器设置的“变化”参数将基于片段距多边形的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;
在片段着色器中,基于从每个顶点“绘制”的多边形上的点的距离进行插值(参见:重心插值)。因此,法线在顶点着色器定义的顶点之间变化。
如果对于由三个顶点定义的给定多边形,您将法线设置为朝向相同方向,则会得到不同的效果。
以上是关于为什么基本的镜面遮光液,而不是锯齿状?的主要内容,如果未能解决你的问题,请参考以下文章
BottomNavigation popBackStack() 导航到 startDestination 而不是上一个片段