Jump to content
  • Advertisement
KKTHXBYE

OpenGL ES Line drawing in fragment shader

Recommended Posts

I have a fullscreen sized quad, now i draw it on screen then in fragment shader i choose whenever linenis visible or not and draw it on screen (2d grid rendering)

However when i zoom out lines dissapear not to mention i cant achieve one thickeness regardless of the zoom

Left zoomed in right and below zoomed out

1FGrueO.png

 

And heres the shader

precision highp float;

uniform vec3 translation;
uniform float grid_size;
uniform vec3 bg_color;
uniform vec3 grid_color;
uniform float lthick;
uniform float sw;
uniform float sh;
uniform float scale;
	
varying vec3 vc;

int modulo(float x, float y)
{
	return int (x - y * float ( int (x/y)));
}

float modulof(float x, float y)
{
	return x - y * float ( int (x/y) );
}

void main()
{
	bool found = false;
	vec2 fragcoord = vc.xy * 0.5 + 0.5;

  	//find how much units do we have in worldspace for a halfspace
	vec2 sc = ( vec2(sw, sh) / 2.0 ) / scale;
	sc = sc * vc.xy + translation.xy; //world position

	int px = modulo(float (sc.x), grid_size);
	int py = modulo(float (sc.y), grid_size);
	if ( (px == 0) || (py == 0) )
  		found = true;

	if (found)
		gl_FragColor = vec4(grid_color, 1.0);
	else
		gl_FragColor = vec4(bg_color, 1.0);
}

I know that when zooming out, a fragment can not represent actual grid line.

Share this post


Link to post
Share on other sites
Advertisement

This is an aliasing problem. The issue is that the sampling is skipping the coordinate you are testing for. You'll also discover that when zooming in closer than 1:1, you'll have thicker grid lines than intended.

Instead of testing for == 0, calculate the world-position stride from one screen pixel to the next, use floating-point modulo instead (the function that trims off the integer part and leaves the fractional part intact), and choose grid colour if the current world-space position is >= 0 and < that stride (instead of < 1, which you are effectively doing here). Remember to respect the device pixel aspect ratio as well, so that this will still work on devices with non-square pixels.

Share this post


Link to post
Share on other sites

I use this shader for debug visualization. It draws black line on values of 0,1,2.. cyan line on values of 0.5, 1.5, 2.5 etc, but it's antialiased.

(i use inColor.xy to define the grid values and z for grayscale lighting - you want to change that too probably.)

#version 400

layout (location = 0) in vec4 inColor;
layout (location = 0) out vec4 uFragColor;

void main() 
{
	vec4 color = clamp (inColor, 0, 1);


	float scale = 1.0f;//64.0f;
	float gridX = clamp ((abs ((fract(inColor.x * scale) - 0.5) * 2.0)-0.9), 0, 1);
	float gridY = clamp ((abs ((fract(inColor.y * scale) - 0.5) * 2.0)-0.9), 0, 1);
	float grid = gridX + gridY;// max(gridX,gridY);
	grid *= grid;
	grid *= 32.0f;

	scale *= 2.0f;
	gridX = clamp ((abs ((fract(inColor.x * scale) - 0.5) * 2.0)-0.9), 0, 1);
	gridY = clamp ((abs ((fract(inColor.y * scale) - 0.5) * 2.0)-0.9), 0, 1);
	float grid2 = gridX + gridY;// max(gridX,gridY);

	scale *= 2.0f;
	gridX = clamp ((abs ((fract(inColor.x * scale) - 0.5) * 2.0)-0.9), 0, 1);
	gridY = clamp ((abs ((fract(inColor.y * scale) - 0.5) * 2.0)-0.9), 0, 1);
	float grid3 = gridX + gridY;// max(gridX,gridY);

	scale *= 2.0f;
	gridX = clamp ((abs ((fract(inColor.x * scale) - 0.5) * 2.0)-0.9), 0, 1);
	gridY = clamp ((abs ((fract(inColor.y * scale) - 0.5) * 2.0)-0.9), 0, 1);
	float grid4 = (gridX + gridY) * 0.6f;// max(gridX,gridY);

	grid = 1-grid + 0.1f;
	vec4 gC = vec4(grid,grid,grid, 1);
	gC -= vec4(grid2,grid3,grid4,0);
		

	float light = 0.2f + abs(inColor.z) * 0.7f;
	vec4 lC = vec4(light,light,light, 1);

	uFragColor = gC * lC;


}

 

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!