使用uniform sampler2d[]时出现无法解释的行为

5
对不起,这需要一点解释。我会尽可能简单地解释。
我想要做的是:可视化高度场。一个高度场可以有多个“补丁”。补丁是一个更改高度场的较小纹理。
我正在使用OpenGL 4.0,主要是细分着色器。然而,对于这个问题来说,这应该是无关紧要的。
已经工作的部分是:我已经完成了高度场(不包括补丁)的可视化。与问题相关的有趣部分是细分评估着色器和片段着色器。
细分评估着色器从高度场采样器中获取每个顶点的高度。
layout(quads, fractional_odd_spacing, ccw) in;

out float onEdge;
out float teDistanceToMinHeight;
out vec4 tcPosition;

void main()
{
    // bilinear interpolate: position
    vec4 pos_a    = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);
    vec4 pos_b    = mix(gl_in[3].gl_Position, gl_in[2].gl_Position, gl_TessCoord.x);
    vec4 position = mix(pos_a, pos_b, gl_TessCoord.y);

    // bilinear interpolate: hf texture coordinate
    vec2 tex_a    = mix(gl_in[0].gl_TexCoord[HFTexCoordID].xy, gl_in[1].gl_TexCoord[HFTexCoordID].xy, gl_TessCoord.x);
    vec2 tex_b    = mix(gl_in[3].gl_TexCoord[HFTexCoordID].xy, gl_in[2].gl_TexCoord[HFTexCoordID].xy, gl_TessCoord.x);
    vec2 hfTexCoord = mix(tex_a, tex_b, gl_TessCoord.y);

    float height = getHeightFieldHeight(hfTexCoord);
    position.y = height;
    //position.y = getHeightFieldHeightMin();

    gl_Position = gl_ModelViewProjectionMatrix * position;
    tcPosition = gl_Position;
    gl_TexCoord[HFTexCoordID].xy = hfTexCoord;

    // a vertex is on the edge of a patch if one of the tess coords is 0
    onEdge = float((gl_TessCoord.x == 0 || gl_TessCoord.y == 0));
    teDistanceToMinHeight = height - getHeightFieldHeightMin();
}

片元着色器使用该片元所属顶点的相对高度来访问一维高度调色板纹理。请暂时忽略高度梯度。它被用于计算法向量。这部分完全正常。

in float onEdge;
in float teDistanceToMinHeight;
in vec4 tcPosition;

out vec4 FragColor;

vec3
getHeightMapGradient(in vec2      ts_position,
                     in vec2      texel_offset)
{
    vec3 x = vec3(2.0 * texel_offset.x, 0.0, getHeightFieldHeight(ts_position + vec2(texel_offset.x, 0.0))
                                           - getHeightFieldHeight(ts_position - vec2(texel_offset.x, 0.0)));


    vec3 y = vec3(0.0, 2.0 * texel_offset.y, getHeightFieldHeight(ts_position + vec2(0.0, texel_offset.y))
                                           - getHeightFieldHeight(ts_position - vec2(0.0, texel_offset.y)));
    return cross(x, y);
}

void main()
{
    if(teDistanceToMinHeight < 0.00001){
        // filter points near the zero position
        discard;
    }

    // attributes
    vec2 hfTexCoords = gl_TexCoord[HFTexCoordID].xy;
    //float hfPaletteTexCoord = getHeightFieldHeight(hfTexCoords) / HeightFieldHeight;
    float hfPaletteTexCoord = (texture(HeightField, hfTexCoords).r -HeightFieldLowering);


    vec2 heightMapSize      = vec2(textureSize(HeightField, 0).xy);
    vec2 heightMapTexelSize = vec2(1.0) / vec2(heightMapSize);


    // some standard colors
    vec4 white = vec4(1);
    vec4 yellow = vec4(1,1,0,1);
    vec4 blue = vec4(0,0,1,1);

    // get the color
    FragColor = texture(HeightFieldPalette, hfPaletteTexCoord ); // use height field  palette as color

    if(onEdge > 0.9 && ShowOriginalGrid == 1 ){
        FragColor = mix(FragColor, yellow, 0.5);
    }

    // shading
    vec3 n = normalize(getHeightMapGradient(hfTexCoords, heightMapTexelSize).xzy);
    vec3 l = vec3(1,1,0);
    vec3 v = normalize(CameraPosition - tcPosition.xyz);
    vec3 h = normalize(l + v);

    float df= dot(n, l);

    FragColor = (FragColor * (df * 0.5 + 0.5)) // diffuse
                + vec4(1) * pow(max(0.0, dot(n,h)), 60.0) // specular
                + 0.1; // ambient


}

每个着色器之前都包含以下代码。它主要包含所有的uniform和helper函数。
#version 400 compatibility

// defines
#define HFTexCoordID 0

// environment
uniform ivec2 ScreenSize = ivec2(800,600);
uniform vec3 CameraPosition = vec3(0);

// tesselation
uniform float MaxEdgeLength = 4;

// height field
uniform float   HeightFieldHeight = 1;
uniform float   HeightFieldLowering = 0.2;

uniform sampler2D   HeightField;
uniform sampler1D   HeightFieldPalette;

// density map
uniform sampler2D   DensityMap;

// patches
uniform sampler2D[20]   Patches;
uniform int             PatchesCount = 0;
uniform ivec2[20]       PatchesPositions;
uniform float[20]       PatchesHeights;
uniform ivec2[20]       PatchesSizes;

// show options
uniform int ShowOriginalGrid = 0;


// functions
ivec2 getHFPosition(vec2 hfTexCoords){
    return ivec2(textureSize(HeightField, 0).xy * hfTexCoords);
}

ivec2 getPatchSize(in int patchIndex){
    return PatchesSizes[patchIndex];
    //return textureSize(Patches[patchIndex], 0).xy;
}

vec2 toPatchCoords(in int patchIndex, in vec2 hfTexCoords){
    ivec2 hfPosition = getHFPosition(hfTexCoords);
    ivec2 patchStart = PatchesPositions[patchIndex];
    ivec2 patchPos = hfPosition - patchStart;
    //return textureSize(Patches[1], 0).xy;

    return  vec2(patchPos / getPatchSize(patchIndex));
}

float getPatchHeight(in int patchIndex, in vec2 hfTexCoords){
    vec2 patchCoords = toPatchCoords(patchIndex, hfTexCoords);
    // seams like the combination of the for loop with this 
    // texture access results in undefined behavior.
    float relHeight = (texture(Patches[patchIndex], patchCoords).r -0.5);
    return relHeight * PatchesHeights[patchIndex] * HeightFieldHeight;
}

float getPatchedHeight(in vec2 texCoords){
    float patchesHeight = 0;
    // working
    //patchesHeight += getPatchHeight(0, texCoords);
    //patchesHeight += getPatchHeight(1, texCoords);
    //patchesHeight += getPatchHeight(2, texCoords);

    // only works for i < 5 .
    for(int i = 0; i < 6 && i < PatchesCount-1; i++){
        patchesHeight += getPatchHeight(i, texCoords);
    }

    return patchesHeight;
}

float getHeightFieldHeight(in vec2 textureCoordinates){
    float height = (texture(HeightField, textureCoordinates).r -HeightFieldLowering) * HeightFieldHeight;

    height += getPatchedHeight(textureCoordinates);

    return height;
}

float getHeightFieldHeightMin(){
    return (-0.2 * HeightFieldHeight);
}

float getDensity(in vec2 coords){
    return texture(DensityMap, coords).r;
}

问题
上述所描述和粘贴的着色器都可以正常工作,只要我不访问Patches统一变量。

uniform sampler2D[20]   Patches;

sampler2D[]的想法是创建一个类似数组的结构,而该数组中的每个纹理可能具有不同的大小。我知道在这种情况下,每个构造使用20个纹理单元。这是一种很好的限制。

当我访问Patches uniform时,片段着色器只输出黑色像素。我知道镶嵌评估着色器是正确的,因为我可以看到高度场中的山丘,但它们并不是其中的一部分。

对于这个问题,我非常感谢任何建议。

我知道我可以使用sampler2DArray,但是每个元素(纹理)必须具有相同的大小。但是我需要修补程序的大小是灵活的。将修补程序剪切为固定大小的纹理,然后在着色器中将它们拼接在一起,可能是一种替代方法,但我不想实现这种组织开销,除非我真的必须这样做。

Infolog

Visualization Lib

rary v2011.5.1142 [f32]
Jun  9 2011 - 11:36:25 - GCC compiler [RELEASE] [x32]

 --- Environment ---
VL_LOGFILE_PATH <not present>
VL_DATA_PATH <not present>
VL_VERBOSITY_LEVEL = NORMAL
VL_CHECK_GL_STATES = YES

 --- Global Settings --- 
Log file  = log.txt
Data path = ../data
Verbosity level = NORMAL
Check OpenGL States = YES

 --- GLEW ---
GLEW version: 1.5.7

 --- OpenGL Info ---
OpenGL version: 4.1.0 NVIDIA 260.19.21
OpenGL vendor: NVIDIA Corporation
OpenGL renderer: Quadro 6000/PCI/SSE2
OpenGL profile: Compatible
GLSL version: 4.10 NVIDIA via Cg compiler
Max texture size: 16384
Texture coords: 8
Texture conventional units: 4
Texture image units: 32
Anisotropic texture filter: YES, 16X
S3 Texture Compression: YES
Vertex Buffer Object: YES
Pixel Buffer Object: YES
Framebuffer Object: YES
Max vertex attributes: 16
Max varying floats: 60
Max fragment uniform components: 2048
Max vertex uniform components: 4096
Max elements vertices: 1048576
Max elements indices: 1048576

 --- OpenGL Extensions --- 
GL_ARB_blend_func_extended              GL_ARB_color_buffer_float
GL_ARB_compatibility                    GL_ARB_copy_buffer
GL_ARB_depth_buffer_float               GL_ARB_depth_clamp
GL_ARB_depth_texture                    GL_ARB_draw_buffers
GL_ARB_draw_buffers_blend               GL_ARB_draw_indirect
GL_ARB_draw_elements_base_vertex        GL_ARB_draw_instanced
GL_ARB_ES2_compatibility                GL_ARB_explicit_attrib_location
GL_ARB_fragment_coord_conventions       GL_ARB_fragment_program
GL_ARB_fragment_program_shadow          GL_ARB_fragment_shader
GL_ARB_framebuffer_object               GL_ARB_framebuffer_sRGB
GL_ARB_geometry_shader4                 GL_ARB_get_program_binary
GL_ARB_gpu_shader5                      GL_ARB_gpu_shader_fp64
GL_ARB_half_float_pixel                 GL_ARB_half_float_vertex
GL_ARB_imaging                          GL_ARB_instanced_arrays
GL_ARB_map_buffer_range                 GL_ARB_multisample
GL_ARB_multitexture                     GL_ARB_occlusion_query
GL_ARB_occlusion_query2                 GL_ARB_pixel_buffer_object
GL_ARB_point_parameters                 GL_ARB_point_sprite
GL_ARB_provoking_vertex                 GL_ARB_robustness
GL_ARB_sample_shading                   GL_ARB_sampler_objects
GL_ARB_seamless_cube_map                GL_ARB_separate_shader_objects
GL_ARB_shader_bit_encoding              GL_ARB_shader_objects
GL_ARB_shader_precision                 GL_ARB_shader_subroutine
GL_ARB_shading_language_100             GL_ARB_shadow
GL_ARB_sync                             GL_ARB_tessellation_shader
GL_ARB_texture_border_clamp             GL_ARB_texture_buffer_object
GL_ARB_texture_buffer_object_rgb32      GL_ARB_texture_compression
GL_ARB_texture_compression_bptc         GL_ARB_texture_compression_rgtc
GL_ARB_texture_cube_map                 GL_ARB_texture_cube_map_array
GL_ARB_texture_env_add                  GL_ARB_texture_env_combine
GL_ARB_texture_env_crossbar             GL_ARB_texture_env_dot3
GL_ARB_texture_float                    GL_ARB_texture_gather
GL_ARB_texture_mirrored_repeat          GL_ARB_texture_multisample
GL_ARB_texture_non_power_of_two         GL_ARB_texture_query_lod
GL_ARB_texture_rectangle                GL_ARB_texture_rg
GL_ARB_texture_rgb10_a2ui               GL_ARB_texture_swizzle
GL_ARB_timer_query                      GL_ARB_transform_feedback2
GL_ARB_transform_feedback3              GL_ARB_transpose_matrix
GL_ARB_uniform_buffer_object            GL_ARB_vertex_array_bgra
GL_ARB_vertex_array_object              GL_ARB_vertex_attrib_64bit
GL_ARB_vertex_buffer_object             GL_ARB_vertex_program
GL_ARB_vertex_shader                    GL_ARB_vertex_type_2_10_10_10_rev
GL_ARB_viewport_array                   GL_ARB_window_pos
GL_ATI_draw_buffers                     GL_ATI_texture_float
GL_ATI_texture_mirror_once              GL_S3_s3tc
GL_EXT_texture_env_add                  GL_EXT_abgr
GL_EXT_bgra                             GL_EXT_bindable_uniform
GL_EXT_blend_color                      GL_EXT_blend_equation_separate
GL_EXT_blend_func_separate              GL_EXT_blend_minmax
GL_EXT_blend_subtract                   GL_EXT_compiled_vertex_array
GL_EXT_Cg_shader                        GL_EXT_depth_bounds_test
GL_EXT_direct_state_access              GL_EXT_draw_buffers2
GL_EXT_draw_instanced                   GL_EXT_draw_range_elements
GL_EXT_fog_coord                        GL_EXT_framebuffer_blit
GL_EXT_framebuffer_multisample          GL_EXTX_framebuffer_mixed_formats
GL_EXT_framebuffer_object               GL_EXT_framebuffer_sRGB
GL_EXT_geometry_shader4                 GL_EXT_gpu_program_parameters
GL_EXT_gpu_shader4                      GL_EXT_multi_draw_arrays
GL_EXT_packed_depth_stencil             GL_EXT_packed_float
GL_EXT_packed_pixels                    GL_EXT_pixel_buffer_object
GL_EXT_point_parameters                 GL_EXT_provoking_vertex
GL_EXT_rescale_normal                   GL_EXT_secondary_color
GL_EXT_separate_shader_objects          GL_EXT_separate_specular_color
GL_EXT_shader_image_load_store          GL_EXT_shadow_funcs
GL_EXT_stencil_two_side                 GL_EXT_stencil_wrap
GL_EXT_texture3D                        GL_EXT_texture_array
GL_EXT_texture_buffer_object            GL_EXT_texture_compression_latc
GL_EXT_texture_compression_rgtc         GL_EXT_texture_compression_s3tc
GL_EXT_texture_cube_map                 GL_EXT_texture_edge_clamp
GL_EXT_texture_env_combine              GL_EXT_texture_env_dot3
GL_EXT_texture_filter_anisotropic       GL_EXT_texture_integer
GL_EXT_texture_lod                      GL_EXT_texture_lod_bias
GL_EXT_texture_mirror_clamp             GL_EXT_texture_object
GL_EXT_texture_shared_exponent          GL_EXT_texture_sRGB
GL_EXT_texture_swizzle                  GL_EXT_timer_query
GL_EXT_transform_feedback2              GL_EXT_vertex_array
GL_EXT_vertex_array_bgra                GL_EXT_vertex_attrib_64bit
GL_IBM_rasterpos_clip                   GL_IBM_texture_mirrored_repeat
GL_KTX_buffer_region                    GL_NV_blend_square
GL_NV_conditional_render                GL_NV_copy_depth_to_color
GL_NV_copy_image                        GL_NV_depth_buffer_float
GL_NV_depth_clamp                       GL_NV_explicit_multisample
GL_NV_fence                             GL_NV_float_buffer
GL_NV_fog_distance                      GL_NV_fragment_program
GL_NV_fragment_program_option           GL_NV_fragment_program2
GL_NV_framebuffer_multisample_coverage  GL_NV_geometry_shader4
GL_NV_gpu_program4                      GL_NV_gpu_program4_1
GL_NV_gpu_program5                      GL_NV_gpu_program_fp64
GL_NV_gpu_shader5                       GL_NV_half_float
GL_NV_light_max_exponent                GL_NV_multisample_coverage
GL_NV_multisample_filter_hint           GL_NV_occlusion_query
GL_NV_packed_depth_stencil              GL_NV_parameter_buffer_object
GL_NV_parameter_buffer_object2          GL_NV_pixel_data_range
GL_NV_point_sprite                      GL_NV_primitive_restart
GL_NV_register_combiners                GL_NV_register_combiners2
GL_NV_shader_buffer_load                GL_NV_texgen_reflection
GL_NV_texture_barrier                   GL_NV_texture_compression_vtc
GL_NV_texture_env_combine4              GL_NV_texture_expand_normal
GL_NV_texture_multisample               GL_NV_texture_rectangle
GL_NV_texture_shader                    GL_NV_texture_shader2
GL_NV_texture_shader3                   GL_NV_transform_feedback
GL_NV_transform_feedback2               GL_NV_vdpau_interop
GL_NV_vertex_array_range                GL_NV_vertex_array_range2
GL_NV_vertex_attrib_integer_64bit       GL_NV_vertex_buffer_unified_memory
GL_NV_vertex_program                    GL_NV_vertex_program1_1
GL_NV_vertex_program2                   GL_NV_vertex_program2_option
GL_NV_vertex_program3                   GL_NV_video_capture
GL_NVX_conditional_render               GL_NVX_gpu_memory_info
GL_SGIS_generate_mipmap                 GL_SGIS_texture_lod
GL_SGIX_depth_texture                   GL_SGIX_shadow
GL_SUN_slice_accum

 --- GLEW ---
GLEW version: 1.5.7

 --- OpenGL Info ---
OpenGL version: 4.1.0 NVIDIA 260.19.21
OpenGL vendor: NVIDIA Corporation
OpenGL renderer: Quadro 6000/PCI/SSE2
OpenGL profile: Compatible
GLSL version: 4.10 NVIDIA via Cg compiler
Max texture size: 16384
Texture coords: 8
Texture conventional units: 4
Texture image units: 32
Anisotropic texture filter: YES, 16X
S3 Texture Compression: YES
Vertex Buffer Object: YES
Pixel Buffer Object: YES
Framebuffer Object: YES
Max vertex attributes: 16
Max varying floats: 60
Max fragment uniform components: 2048
Max vertex uniform components: 4096
Max elements vertices: 1048576
Max elements indices: 1048576

 --- OpenGL Extensions --- 
GL_ARB_blend_func_extended              GL_ARB_color_buffer_float
GL_ARB_compatibility                    GL_ARB_copy_buffer
GL_ARB_depth_buffer_float               GL_ARB_depth_clamp
GL_ARB_depth_texture                    GL_ARB_draw_buffers
GL_ARB_draw_buffers_blend               GL_ARB_draw_indirect
GL_ARB_draw_elements_base_vertex        GL_ARB_draw_instanced
GL_ARB_ES2_compatibility                GL_ARB_explicit_attrib_location
GL_ARB_fragment_coord_conventions       GL_ARB_fragment_program
GL_ARB_fragment_program_shadow          GL_ARB_fragment_shader
GL_ARB_framebuffer_object               GL_ARB_framebuffer_sRGB
GL_ARB_geometry_shader4                 GL_ARB_get_program_binary
GL_ARB_gpu_shader5                      GL_ARB_gpu_shader_fp64
GL_ARB_half_float_pixel                 GL_ARB_half_float_vertex
GL_ARB_imaging                          GL_ARB_instanced_arrays
GL_ARB_map_buffer_range                 GL_ARB_multisample
GL_ARB_multitexture                     GL_ARB_occlusion_query
GL_ARB_occlusion_query2                 GL_ARB_pixel_buffer_object
GL_ARB_point_parameters                 GL_ARB_point_sprite
GL_ARB_provoking_vertex                 GL_ARB_robustness
GL_ARB_sample_shading                   GL_ARB_sampler_objects
GL_ARB_seamless_cube_map                GL_ARB_separate_shader_objects
GL_ARB_shader_bit_encoding              GL_ARB_shader_objects
GL_ARB_shader_precision                 GL_ARB_shader_subroutine
GL_ARB_shading_language_100             GL_ARB_shadow
GL_ARB_sync                             GL_ARB_tessellation_shader
GL_ARB_texture_border_clamp             GL_ARB_texture_buffer_object
GL_ARB_texture_buffer_object_rgb32      GL_ARB_texture_compression
GL_ARB_texture_compression_bptc         GL_ARB_texture_compression_rgtc
GL_ARB_texture_cube_map                 GL_ARB_texture_cube_map_array
GL_ARB_texture_env_add                  GL_ARB_texture_env_combine
GL_ARB_texture_env_crossbar             GL_ARB_texture_env_dot3
GL_ARB_texture_float                    GL_ARB_texture_gather
GL_ARB_texture_mirrored_repeat          GL_ARB_texture_multisample
GL_ARB_texture_non_power_of_two         GL_ARB_texture_query_lod
GL_ARB_texture_rectangle                GL_ARB_texture_rg
GL_ARB_texture_rgb10_a2ui               GL_ARB_texture_swizzle
GL_ARB_timer_query                      GL_ARB_transform_feedback2
GL_ARB_transform_feedback3              GL_ARB_transpose_matrix
GL_ARB_uniform_buffer_object            GL_ARB_vertex_array_bgra
GL_ARB_vertex_array_object              GL_ARB_vertex_attrib_64bit
GL_ARB_vertex_buffer_object             GL_ARB_vertex_program
GL_ARB_vertex_shader                    GL_ARB_vertex_type_2_10_10_10_rev
GL_ARB_viewport_array                   GL_ARB_window_pos
GL_ATI_draw_buffers                     GL_ATI_texture_float
GL_ATI_texture_mirror_once              GL_S3_s3tc
GL_EXT_texture_env_add                  GL_EXT_abgr
GL_EXT_bgra                             GL_EXT_bindable_uniform
GL_EXT_blend_color                      GL_EXT_blend_equation_separate
GL_EXT_blend_func_separate              GL_EXT_blend_minmax
GL_EXT_blend_subtract                   GL_EXT_compiled_vertex_array
GL_EXT_Cg_shader                        GL_EXT_depth_bounds_test
GL_EXT_direct_state_access              GL_EXT_draw_buffers2
GL_EXT_draw_instanced                   GL_EXT_draw_range_elements
GL_EXT_fog_coord                        GL_EXT_framebuffer_blit
GL_EXT_framebuffer_multisample          GL_EXTX_framebuffer_mixed_formats
GL_EXT_framebuffer_object               GL_EXT_framebuffer_sRGB
GL_EXT_geometry_shader4                 GL_EXT_gpu_program_parameters
GL_EXT_gpu_shader4                      GL_EXT_multi_draw_arrays
GL_EXT_packed_depth_stencil             GL_EXT_packed_float
GL_EXT_packed_pixels                    GL_EXT_pixel_buffer_object
GL_EXT_point_parameters                 GL_EXT_provoking_vertex
GL_EXT_rescale_normal                   GL_EXT_secondary_color
GL_EXT_separate_shader_objects          GL_EXT_separate_specular_color
GL_EXT_shader_image_load_store          GL_EXT_shadow_funcs
GL_EXT_stencil_two_side                 GL_EXT_stencil_wrap
GL_EXT_texture3D                        GL_EXT_texture_array
GL_EXT_texture_buffer_object            GL_EXT_texture_compression_latc
GL_EXT_texture_compression_rgtc         GL_EXT_texture_compression_s3tc
GL_EXT_texture_cube_map                 GL_EXT_texture_edge_clamp
GL_EXT_texture_env_combine              GL_EXT_texture_env_dot3
GL_EXT_texture_filter_anisotropic       GL_EXT_texture_integer
GL_EXT_texture_lod                      GL_EXT_texture_lod_bias
GL_EXT_texture_mirror_clamp             GL_EXT_texture_object
GL_EXT_texture_shared_exponent          GL_EXT_texture_sRGB
GL_EXT_texture_swizzle                  GL_EXT_timer_query
GL_EXT_transform_feedback2              GL_EXT_vertex_array
GL_EXT_vertex_array_bgra                GL_EXT_vertex_attrib_64bit
GL_IBM_rasterpos_clip                   GL_IBM_texture_mirrored_repeat
GL_KTX_buffer_region                    GL_NV_blend_square
GL_NV_conditional_render                GL_NV_copy_depth_to_color
GL_NV_copy_image                        GL_NV_depth_buffer_float
GL_NV_depth_clamp                       GL_NV_explicit_multisample
GL_NV_fence                             GL_NV_float_buffer
GL_NV_fog_distance                      GL_NV_fragment_program
GL_NV_fragment_program_option           GL_NV_fragment_program2
GL_NV_framebuffer_multisample_coverage  GL_NV_geometry_shader4
GL_NV_gpu_program4                      GL_NV_gpu_program4_1
GL_NV_gpu_program5                      GL_NV_gpu_program_fp64
GL_NV_gpu_shader5                       GL_NV_half_float
GL_NV_light_max_exponent                GL_NV_multisample_coverage
GL_NV_multisample_filter_hint           GL_NV_occlusion_query
GL_NV_packed_depth_stencil              GL_NV_parameter_buffer_object
GL_NV_parameter_buffer_object2          GL_NV_pixel_data_range
GL_NV_point_sprite                      GL_NV_primitive_restart
GL_NV_register_combiners                GL_NV_register_combiners2
GL_NV_shader_buffer_load                GL_NV_texgen_reflection
GL_NV_texture_barrier                   GL_NV_texture_compression_vtc
GL_NV_texture_env_combine4              GL_NV_texture_expand_normal
GL_NV_texture_multisample               GL_NV_texture_rectangle
GL_NV_texture_shader                    GL_NV_texture_shader2
GL_NV_texture_shader3                   GL_NV_transform_feedback
GL_NV_transform_feedback2               GL_NV_vdpau_interop
GL_NV_vertex_array_range                GL_NV_vertex_array_range2
GL_NV_vertex_attrib_integer_64bit       GL_NV_vertex_buffer_unified_memory
GL_NV_vertex_program                    GL_NV_vertex_program1_1
GL_NV_vertex_program2                   GL_NV_vertex_program2_option
GL_NV_vertex_program3                   GL_NV_video_capture
GL_NVX_conditional_render               GL_NVX_gpu_memory_info
GL_SGIS_generate_mipmap                 GL_SGIS_texture_lod
GL_SGIX_depth_texture                   GL_SGIX_shadow
GL_SUN_slice_accum

PatchesContainer::PatchesContainer: working dir: ./data/patches/pick_height_testing_png/
PatchesContainer::loadPatchesFromWorkingDir ignoring file = data/patches/pick_height_testing_png/.svn
Patch::initialize(): name   = data/patches/pick_height_testing_png/patch01-position=20x20-maxHeight=1.0.png
width  = 50
height = 50
depth  = 0
format = IF_LUMINANCE
type   = IT_UNSIGNED_BYTE
pitch  = 50
bytealign = 1
Patch::initialize(): name   = data/patches/pick_height_testing_png/patch02-position=20x2-maxHeight=1.5.png
width  = 20
height = 20
depth  = 0
format = IF_LUMINANCE
type   = IT_UNSIGNED_BYTE
pitch  = 20
bytealign = 1
Found matching densitymap ./data/density_maps/pick_height_testing_png.png
loading height field image
name   = ./data/horizons/pick_height_testing.png
width  = 200
height = 200
depth  = 0
format = IF_LUMINANCE
type   = IT_UNSIGNED_BYTE
pitch  = 200
bytealign = 1
name   = ./data/textures/tesselation_palette_blue_red.png
width  = 300
height = 0
depth  = 0
format = IF_RGB
type   = IT_UNSIGNED_BYTE
pitch  = 900
bytealign = 1
GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS: 32

你是否遇到了任何着色器编译错误?或者着色器仍然可以成功编译和链接?在 infolog 中有任何消息吗? - Dr. Snoopy
着色器编译和链接都很好。 infolog 中没有任何消息。 - Velrok
1个回答

6

嗯,我看到了一个问题:

uniform sampler2D[20] Patches;

我猜测你的OpenGL 4.0级别的硬件无法在单个着色器阶段中使用超过16个纹理。如果想要验证这一点,请检查 GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS; 我敢打赌它是16。

此外,访问采样器数组的规则非常严格(我打赌你正在违反它们)。在GLSL 4.00中,采样器数组的索引必须是以下两者之一:

1:编译时常量表达式

2:解析为uniform值的表达式。不是关键字中的uniform,而是基于编译时常量或uniform值的表达式。 它们不能基于从纹理、着色器阶段输入或任何其他地方检索的值。

这是合法的:

for(int i = 0; i < someUniform; i++)
{
    texture(Patches[i], texCoord);
}

这是不合法的:

texture(Patches[positionOfSomeVertex * uniformScaleFactor], texCoord);

人们使用数组纹理而不是采样器数组是有原因的。
附注:可能引用GLSL版本4.10规范中的一句话会有所帮助:
“如果所有评估它的片段得到相同的结果值,则片段着色器表达式是动态均匀的。涉及循环时,这指的是在同一循环迭代中表达式的值。当涉及函数时,这指的是来自相同调用点的调用。”
“基于它们处理的每个实例数据,其他着色器阶段也类似地定义了这一点。”
“请注意,常量表达式是显然动态均匀的。因此,基于这些的典型循环计数器也是动态均匀的。”
你的表达式涉及一个基于非动态均匀性的条件分支。因此,使用的索引不是动态均匀的。
“动态均匀”基本思想是:在给定相同的uniform值的情况下,我应该能够将任何东西作为着色器阶段输入传递,并从数组访问相同的纹理。你的代码不能保证这一点。

感谢您的回答和解释。我尝试了您关于纹理单元限制的建议。对于我的硬件,它是32(我们这里有一些不错的最新设备)GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS: 32PatchesCount是一个统一变量。所以在这里应该使用 for(int i = 0; i < someUniform; i++)。当我违反规则时,难道我不应该得到某种错误吗?我记得因为我从Patches[99]开始,所以我得到了一个not enought texture units错误。使用gDEbugger不起作用。gDEbugger不支持我正在使用的新OpenGL 4.0功能。 - Velrok
@Velrok:是的,您正在循环遍历补丁数量,但您并没有从所有补丁中访问纹理数据。您只有在特定条件下才能访问纹理数据。而这个条件是不统一的;它基于输入值(位置)。顺便说一句,您的示例完美地解释了为什么OpenGL无法给出错误;它对于编译器来说太复杂了,以至于无法检测到这种情况。因此,GLSL规范指出行为是“未定义的”。这通常意味着“不是您想要的”。 - Nicol Bolas
如果我理解正确,uniform 意味着所有的代码路径评估都可以在编译时完成。显然,包括 pervertex 属性的 if 语句只能在运行时评估,导致未知的行为。为了解决这个问题,我删除了 if 语句。所以现在我正在访问所有的补丁。每个补丁纹理都设置为 wrap s,t 到边框,即设置为灰色。因此,访问补丁外部的纹理将导致一个 0.5 的值,这是可以接受的。然而,我仍然有同样的问题(所有片段都是黑色的)。我是否缺少一个 noneuniform 操作?我更新了全局源。 - Velrok
我花了更多时间寻找确切的位置,并尝试使其更加“统一友好”。结果发现for循环和对补丁子集(由于循环限制而导致)的访问会导致未定义的行为。目前它适用于i < 5,但我认为这是随机的。然而,5将限制我正在实现的撤消功能,这太少了。我将使用sampler2DArray实现。感谢所有的帮助。 - Velrok
我的天啊,在互联网上找到这些信息真是太难了。更加令人烦恼的是,sampler2dArray不是OpenGL ES 2.0的一部分,这意味着当图集纹理出现不同问题时需要进行更多的绘制调用。 - Felix K.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接