tl; dr: 在片段着色器中访问各个顶点数据的最佳方法是什么?glsl片段着色器如何从每个顶点获取非插值数据
例如 在该片段的三角形顶点从V0,V1和V2由与我想给每个顶点,我可以使用选择一个纹理的特定整数,然后在片段着色器3之间褪色;我不希望这些id被内插,重要的是我可以访问每个顶点的id。
当前情况: 我目前正在编写渲染地形的着色器;我在我的片段着色器中有一个函数,它将从uvs返回给定ID的合适纹理颜色(通过纹理图集)。然后我可以在3个纹理之间褪色给予给顺利纹理地形
目前代码
顶点着色器:
#version 330 core
layout(location = 0) in vec3 in_position;
layout(location = 1) in vec2 in_uv_coords;
layout(location = 2) in vec3 in_normal;
layout(location = 3) in float in_texture_id;
uniform mat4 view_matrix;
uniform mat4 projection_matrix;
out vec2 pass_uv_coords;
out vec3 pass_normal;
out vec3 texture_ratio;
out float pass_fake_brightness;
out float pass_id0;
out float pass_id1;
out float pass_id2;
void CalculateFakeLighting()
{
const vec3 light_direction = normalize(vec3(1,-1,1));
vec3 unit_normal = normalize(in_normal);
float normal_dot_light = dot(unit_normal, -light_direction);
pass_fake_brightness = max(0.2, normal_dot_light);
}
void main()
{
pass_uv_coords = in_uv_coords;
pass_normal = in_normal;
gl_Position = projection_matrix * view_matrix * vec4(in_position, 1.0);
int tile_track = int(mod(gl_VertexID, 3));
switch(tile_track)
{
case 0:
texture_ratio = vec3(1,0,0);
pass_id0 = in_texture_id;
break;
case 1:
texture_ratio = vec3(0,1,0);
pass_id1 = in_texture_id;
break;
case 2:
texture_ratio = vec3(0,0,1);
pass_id0 = in_texture_id;
break;
};
CalculateFakeLighting();
}
片段着色器:
#version 330 core
in vec2 pass_uv_coords;
in vec3 pass_normal;
in vec3 texture_ratio;
in float pass_fake_brightness;
in float pass_id0;
in float pass_id1;
in float pass_id2;
const int HORIZONTAL_IDS = 8;
const int VERTICAL_IDS = 8;
uniform sampler2D texture0_sampler;
out vec4 colour;
void UseFakeLighting()
{
colour *= pass_fake_brightness;
}
vec2 CorrectUVs(vec2 uvs)
{
vec2 corrected_uvs = uvs;
const float cushion = 0.001;
//Correct UV scale
while(corrected_uvs.x >= 1)
corrected_uvs.x--;
while(corrected_uvs.y >= 1)
corrected_uvs.y--;
if(corrected_uvs.x < cushion)
corrected_uvs.x = cushion;
if(corrected_uvs.x > 1 - cushion)
corrected_uvs.x = 1 - cushion;
if(corrected_uvs.y < cushion)
corrected_uvs.y = cushion;
if(corrected_uvs.y > 1 - cushion)
corrected_uvs.y = 1 - cushion;
return corrected_uvs;
}
vec4 GetTexture(float id, vec2 uv_coords)
{
vec2 step = vec2(
1.0/HORIZONTAL_IDS,
1.0/VERTICAL_IDS
);
uv_coords.x/=HORIZONTAL_IDS;
uv_coords.y/=VERTICAL_IDS;
uv_coords.x += step.x * mod(id, HORIZONTAL_IDS);
uv_coords.y += step.y * floor(id/VERTICAL_IDS);
//Texture is upsidedown
uv_coords.y = 1.0 - uv_coords.y;
return texture(texture0_sampler, uv_coords);
}
void main()
{
vec2 corrected_uvs = CorrectUVs(pass_uv_coords);
vec3 correct_ratio = normalize(texture_ratio);
colour = GetTexture(pass_id0, corrected_uvs) * correct_ratio.x +
GetTexture(pass_id1, corrected_uvs) * correct_ratio.y +
GetTexture(pass_id2, corrected_uvs) * correct_ratio.z;
if(colour.a == 0)
discard;
UseFakeLighting();
}
我知道,但它只会通过值pass_id0为三角形的最后一个顶点,我需要从所有顶点 –
的价值,你在哪里看的?挑动顶点完全由用户定义。你是正确的,激发顶点默认是最后一个,但描述你所做的是正确的方式是指“激发顶点”;)然而,如果你正在做一些需要来自多个顶点的值,它确实听起来像像你想在早期阶段(几何着色器,也许?)做这个计算 –
@ AndonM.Coleman我还没有触及几何着色器,所以我会读它。我可以输出类似于vec3的东西,它从几何着色器的每个顶点存储特定值到片段着色器? –