opengl - How can I render an infinite 2D grid in GLSL? -
ideally, i'd draw single quad , have glsl handle creation of actual gridlines.
in attempt far vertex shader:
#version 400 layout (location = 0) in vec4 in_position; layout (location = 2) in vec3 in_uv; uniform mat4 model; uniform mat4 view; uniform mat4 projection; smooth out vec3 ex_uv; smooth out vec3 ex_originalposition; void main() { gl_position = projection * view * model * in_position; ex_uv = in_uv; ex_originalposition = vec3(in_position.xyz); }
the model matrix scales quad large number, 10,000.
#version 400 layout (location = 0) out vec4 color; smooth in vec3 ex_uv; smooth in vec3 ex_originalposition; uniform vec4 linecolor; void main(void) { if(fract(ex_uv.x / 0.001f) < 0.01f || fract(ex_uv.y / 0.001f) < 0.01f) color = linecolor; else color = vec4(0); }
i've tried using both texture coords , world space positions this. both result in same affect looks fine @ angles, @ others starts looking horrid.
i thought maybe scale alpha depending on distance, grid fades away nothing, problem can see in second image, center of screen, can see lines being rendered gaps through them (the point of grid give visual frame of reference around origin).
is there simpler way this?
edit
screenshots requested:
vbo lines x8 multisampled framebuffer
vbo lines x8 multisampled framebuffer , glenable(gl_line_smooth)
i settled on
i settled on either of above (doesn't matter which) , lowered alpha function of distance origin. serves purpose though isn't question asked.
a simple case of aliasing. polygon rendering, fragment shader run once per pixel. colour computed single central coordinate , not representative of true colour.
- you create multisample fbo , enable super-sampling. that's expensive.
- you mathematically compute how line area , empty grid area under each pixel, colour them accordingly in fragment shader. given it's uniform grid might in realm of possible, maths might still pretty complicated.
mipmapping textures. create grid texture few lines , map repeats large quad (make sure set
gl_repeat
). set correct mipmap filtering parameters texture , callglgeneratemipmap
. when calltexture2d()
/texture()
in fragment shader opengl automatically calculates level of mipmap use based off texture coordinate delta between adjacent pixels. finally, set anisotropic filtering more amazing looking grid.
if want grid "infinite", i've seen ocean renderers connect edges of grid horizon vertical geometry. if have enough grid before them, possibly away setting them 1 flat colour - colour @ top level of mipmap.
examples (relating comments):
1024x2 gl_lines drawn vbo
45fps (drawn 100 times benchmark @ hd res)
see comments regarding multisampling address gl_lines aliasing.
a 32^2 texture mapped quad mipmapping
954fps (drawn 100 times benchmark @ hd res)
image img; int w = 128; int h = 128; img.resize(w, h, 1); (int j = 0; j < h; ++j) (int = 0; < w; ++i) img.data[j*w + i] = (i < w / 16 || j < h / 16 ? 255 : 0); tex = img.upload(); glbindtexture(gl_texture_2d, tex); gltexparameteri(gl_texture_2d, gl_texture_wrap_s, gl_repeat); gltexparameteri(gl_texture_2d, gl_texture_wrap_t, gl_repeat); gltexparameteri(gl_texture_2d, gl_texture_min_filter, gl_linear_mipmap_linear); gltexparameteri(gl_texture_2d, gl_texture_mag_filter, gl_linear); gltexparameterf(gl_texture_2d, gl_texture_max_anisotropy_ext, 16); glgeneratemipmap(gl_texture_2d); glbindtexture(gl_texture_2d, 0); ... //for quick , dirty, immediate mode glenable(gl_texture_2d); glbindtexture(gl_texture_2d, tex); glbegin(gl_quads); gltexcoord2f(0, 0); glvertex3f(0, 0, 0); gltexcoord2f(1024, 0); glvertex3f(1, 0, 0); gltexcoord2f(1024, 1024); glvertex3f(1, 0, 1); gltexcoord2f(0, 1024); glvertex3f(0, 0, 1); glend(); glbindtexture(gl_texture_2d, 0); gldisable(gl_texture_2d);
Comments
Post a Comment