in与out在着色器中的作用

in和out是GLSL语言中的关键字,它们用来控制顶点着色器和片段着色器之间的数据传递。

in变量是从CPU端传递给顶点着色器的数据,它只能在顶点着色器中使用,是只读的。
out变量是从顶点着色器传递给片段着色器的数据,它只能在顶点着色器中定义,在片段着色器中使用,是可读可写的。
没有out的变量则会直接输出。
因此,通常需要在顶点着色器中定义in变量来接收顶点数据,在顶点着色器中定义out变量来传递数据给片段着色器进行处理,最后片段着色器中对颜色进行处理,得到最终的渲染效果。
来看一个顶点着色器的例子:

#version 330 core

layout(location = 0) in vec3 position; //坐标
layout(location = 1) in vec4 incolor; //颜色
layout(location = 2) in vec3 innormal; //法向量
layout(location = 3) in vec3 position_offset; //偏移值
layout(location = 4) in float radius_offset; //半径

uniform mat4 ProjectionMatrix; //投影矩阵
uniform mat4 ViewMatrix; //视角矩阵
uniform mat4 ModelMatrix; //模型矩阵

out vec4 outcolor;
out vec3 outnormal;


void main(){
	// 顶点坐标变换
	vec3 new_position = position * radius_offset;
	gl_Position = ProjectionMatrix * ViewMatrix  * ModelMatrix * vec4(new_position+position_offset, 1.0);
	// 传递颜色和法向量
	outcolor = incolor;
	// 法向量旋转
	outnormal = mat3(ViewMatrix) * innormal;
}

这段顶点着色器代码的功能:

首先,它定义了五个顶点属性输入,分别是顶点坐标、顶点颜色、顶点法向量、坐标偏移值和半径偏移值。

然后定义了三个矩阵uniform变量,分别是投影矩阵、视角矩阵和模型矩阵。

在main函数中,首先对顶点坐标进行变换,通过改变坐标和半径来得到新的坐标new_position。然后将变换后的坐标new_position通过投影矩阵、视角矩阵和模型矩阵相乘,得到最终的顶点坐标gl_Position,此坐标会传递给片段着色器进行渲染。

然后使用out变量将顶点颜色和法向量传递给片段着色器,片段着色器可以根据顶点颜色和法向量来进行其他渲染效果的处理。最后顶点坐标矩阵变换,顶点法向量矩阵变换,使其能够被正确的渲染。

为什么片段着色器不能直接获得顶点的颜色和法向量?

顶点着色器是用来计算屏幕上每个顶点的位置的,片段着色器是用来计算每个像素的颜色的。
片段着色器只能访问到在屏幕上已经计算好了位置的顶点,而顶点颜色和法向量信息并没有被计算进顶点位置中,因此片段着色器无法直接获得顶点的颜色和法向量。需要在顶点着色器中对顶点颜色和法向量进行处理,并使用out变量将顶点颜色和法向量传递给片段着色器。
因此,我们通过out变量将顶点着色器中处理过的颜色和法向量传递给片段着色器,在片段着色器中再进行相应的处理。

为什么in只能在顶点着色器中用?(说的不完全对)

in 变量只能在顶点着色器中使用,是因为它表示顶点属性,它们是由应用程序传递到顶点着色器中的。在顶点着色器中,in变量可以获取到顶点坐标,颜色,纹理坐标等。这些顶点属性是由应用程序设置的。 与之相对应,片段着色器中使用in变量并没有什么意义,因为顶点属性在顶点着色器中已经被处理过了,而片段着色器中可以使用in变量来接收顶点着色器中的输出。

你可能感兴趣的:(OpenGL,着色器,算法,矩阵)