Reputation: 4506
I'm working on a blocky voxel game. I implemented smooth shading from the 0fps article, and it worked great.
Today I decided I wanted to make it less-smooth by pixelizing it. Each of the vertices that make up the triangle strip (the quad) have a vec4 shadows
. And I just bilinearly interpolate between those 4 shadow points using the UV coordinates that would otherwise be for a texture..
float pixelize(float x) { return floor(x*BLOCK_DIMENSION) / BLOCK_DIMENSION; }
float linear(float u, float a, float b) { return a + u*(b - a); }
float bilinear()
{
float v0 = linear(pixelize(texUV.x), shadows.x, shadows.y);
float v1 = linear(pixelize(texUV.x), shadows.z, shadows.w);
return linear(pixelize(texUV.y), v0, v1);
}
But no matter how much I try to fudge it (adding 0.125f or 0.5f or whatever), I can't get it perfect. The pixelization is shifted by 1 (notice there's 4 shades on the left side, and 3 shades on the right side); the shading isn't symmetric.
Is it possible to fix this?
Upvotes: 2
Views: 200
Reputation: 72489
You need to add 0.5
to the result of floor
, like so:
float pixelize(float x) { return (floor(x*BLOCK_DIMENSION) + 0.5) / BLOCK_DIMENSION; }
I bet you tried to add it somewhere else, which is not the same.
The motivation for this can be understood using the following diagram:
The sampling of the second row is asymmetrical within the interval because floor
shifts everything down. Adding 0.5
restores that symmetry.
Upvotes: 4