0
\$\begingroup\$

Character model standing on a grey grid-patterned floor

I got this photo from mixamo.com — I want to draw grid lines similar to this on my floor.

I'm sure this is easy by using textures, but I'm trying to avoid using textures as much as possible. Is there a way to implement these floor patterns in OpenGL 3.3?

\$\endgroup\$
2
\$\begingroup\$

One way to do a square pattern in glsl is with mod:

vec2 uv = coord;
float size = 1.0/8.0;   // size of the tile
float edge = size/32.0; // size of the edge
uv = (mod(uv, size) - mod(uv - edge, size) - edge) * 1.0/size;
color = vec4(0.9 - length(uv) * 0.5);
// 0.9 controls the brighness of the face of the tile
// 0.5 controls the darkness of the edge

See it at shadertoy.

Remember that mod gives us the reminder. Thus, it will go from 0.0 to whatever divisor we used. By offsetting the input by the width of the edge we get a value that is 0.0 on the tile, flat color, and has value on the edge. We scale the value so it goes to white. We need to pass it negative, so the face is white, not black, and the edge is black, not white... however, 1.0 - uv does not gives us white. That is why I added the extra term - edge (This probably can be cleaned a little more). After that, we can tweak 1.0 to 0.9 to make the face gray, and we have some control over the color of the edged by adding a factor.

\$\endgroup\$
0
\$\begingroup\$

It's pretty easy if you use shaders. You need to have the uv coordinates for the plane. Scale them up and mod them to have multiple, smaller tiles:

uv = mod(uv * tileCount, vec2(1));

You'll also need to define how large of a percentage the edges should take up from the tile. I'm going to reference it as paddingWidth. 0 is no padding, 0.5 is 50% padding. Now you can use step to get a value, that tells you whether the current pixel is inside the padding or not for each axis. It's going to be 0 if it is and 1 if it isn't:

float mixValueX = step(paddingWidth, uv.x);
float mixValueY = step(paddingWidth, uv.y);

Since you don't need to have one for each axis (the horizontal and vertical paddings are the same color), you can just take the minimum of these (since if either of them are 0, it's inside the padding):

float mixValue = min(mixValueX, mixValueY);

Now you can use mix to output a color:

vec4 color = mix(paddingColor, tileColor, mixValue);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.