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的東西,它從幾何着色器的每個頂點存儲特定值到片段着色器? –