Line drawing in fragment shader

Started by
2 comments, last by JoeJ 5 years, 10 months ago

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.

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.

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

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;


}

 

 

 

This topic is closed to new replies.

Advertisement