Fragment shader是每个像素调用一次,对吧. 那里面的变量varying vec2 v_texCoord是每次都不一样的. 所有教程都说这个量是由vertex shader传递过来的. 那我就不明白了,vertex shader只被调用三次(对应三个顶点),而Fragment shader是调用N次的(N个像素), v_texCoord的值还每次不一样. 这对应不上啊.
请问我哪里理解错了
vertex shader为啥只被调用三次 ?没有这种说法哈 兄弟
顶点着色器:用来处理顶点数据
片段着色器:用来处理每个像素的颜色简单点理解
几何着色器:是上面两个中间的一个流程,用来把上个阶段组装好的图形或者叫图元做处理然后再把这个图形流出到下一个管线,一般用不到
放个图上来更好的说明吧
举个列子:虽然你只定义了三个顶点,但是经过了图元装配阶段已经变成了一个图形,你可以想象下,在一块白纸上点了三个点,然后连起来成了一个三角形,下一个阶段如果你不写几何着色器,那么默认的就是这个三角形继续流入下个管线,重点来了,兄弟,你困惑的三个点以及N个像素的可能是这里,光栅化会把你这个三角形划分为一个一个的像素块,你可以继续把刚才说的纸上的三角形用线切割,这样子之后的产品会流入片段着色器,也就是你说的处理N个像素的地方。然后你举例子的v_texCoord应该就是纹理坐标
就像这个图一样,0-1的范围内一张图你可以想象这张图每个像素都有坐标值。
定义顶点的时候其实就把纹理数据啊 顶点的位置啊 颜色 可能还有法向量等等 都定义好了,所以这样的顶点数据可以解释了吧。
其实就是强调一下,虽然三个点数据但是经过光栅后变成了N个像素块
我也好久没看了。。不知道是不是误人子弟了。。
谢谢兄弟,让您敲这么多字,真是太感谢了.
虽然还是很多困惑.我尽力去理解. 你的图让我更清楚了整个流程的细节.
可能是在计算机上编程太久,让我的思维有点局限了.
在看了你的回答之后,我又找了一下,有一篇文章是这样回答的:
从 vertex shader 传递到 fragment shader 的信息则通过 varying 属性指定的变量,varying 属性的变量
在一对 vertex shader 和 fragment shader 之间的定义必须匹配(注:即在 vertex shader 里
定义了一个,则在 fragment shader 里也必须有一个)。处在 vertex shader 和 fragment shader
之间的固定功能管道将对 varying 变量进行插值。当一个 fragment shader 读取一个 varying
变量的时候,它得到的值是已经插值过的。
感觉这个解释比较完美.不知您的看法如何. 现在我的理解就是: 对于每个三角形, 首先调用三次vertex shade,得到三个v_texCoord,将之存入缓冲,再经过您上述图中的一系列流程,来到 fragment shader阶段.在此由前面的三个v_texCoord插值得到每个像素的v_texCoord,分别传给每次(像素)的 fragment shader
-----------------------------------分隔线-------------------------------------------------------------
https://zilongshanren.com/blog/2014-06-07-write-your-own-shader.html 这是 “子龙山人” 转的文章,里面明确提到
" vertex shader是作用于每一个顶点的,我们本例中有三个点,所以这个vertex shader会被执行三次。 "
当然,我查了好几篇文章,都不约而同地有类似提法.
关于varying vec2 v_texCoord的例子, 下面是cocos2d-x V3.16自带的文件 ccShader_PositionTextureColor_noMVP.vert :
const char* ccPositionTextureColor_noMVP_vert = R"(
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
)";
是的,感觉你现在的理解没啥毛病 赞
但是还是没有回答 顶点着色器到底执行几次。我看别人文档都有几个顶点执行几次顶点着色器,但是没有办法解释每个片段着色器收到参数都是不一样的这个问题。
几个顶点,顶点着色器就执行几次,其他的坐标是插值出来的
顶点向片段参数传递的细节:
在顶点着色器中,输出的参数会被存储在一个称为参数缓存的内存区域中,这些参数在光栅化过程中会被插值,以便在片段着色器中使用 。这意味着,片段着色器接收到的每个像素的属性值都是基于其对应的顶点数据经过插值计算得出的结果。