Multisampling in gles canvas shader

This commit is contained in:
martinfouilleul 2023-02-02 13:34:06 +01:00
parent f73241e4a6
commit 28e2a3648e
4 changed files with 137 additions and 79 deletions

View File

@ -71,19 +71,19 @@ int main()
{ {
if(event.key.code == MP_KEY_LEFT) if(event.key.code == MP_KEY_LEFT)
{ {
dx-=1.1; dx-=5.1;
} }
else if(event.key.code == MP_KEY_RIGHT) else if(event.key.code == MP_KEY_RIGHT)
{ {
dx+=1.1; dx+=5.1;
} }
else if(event.key.code == MP_KEY_UP) else if(event.key.code == MP_KEY_UP)
{ {
dy+=1.1; dy+=5.1;
} }
else if(event.key.code == MP_KEY_DOWN) else if(event.key.code == MP_KEY_DOWN)
{ {
dy-=1.1; dy-=5.1;
} }
} }
} break; } break;

View File

@ -51,22 +51,37 @@ const char* gles_canvas_fragment =
"\n" "\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" float subPixelFactor = 16.;\n" " const float subPixelFactor = 16.;\n"
" const int sampleCount = 8;\n"
"\n" "\n"
" vec4 pixelColor = clearColor;\n" " ivec2 centerPoint = ivec2(round(gl_FragCoord.xy * subPixelFactor));\n"
" vec4 currentColor = clearColor;\n" " ivec2 samplePoints[sampleCount] = ivec2[sampleCount](centerPoint + ivec2(1, 3),\n"
" centerPoint + ivec2(-1, -3),\n"
" centerPoint + ivec2(5, -1),\n"
" centerPoint + ivec2(-3, 5),\n"
" centerPoint + ivec2(-5, -5),\n"
" centerPoint + ivec2(-7, 1),\n"
" centerPoint + ivec2(3, -7),\n"
" centerPoint + ivec2(7, 7));\n"
"\n" "\n"
" ivec2 samplePoint = ivec2(gl_FragCoord.xy * subPixelFactor + vec2(0.5, 0.5));\n" " vec4 sampleColor[sampleCount];\n"
" vec4 currentColor[sampleCount];\n"
" int currentZIndex[sampleCount];\n"
" int flipCount[sampleCount];\n"
"\n" "\n"
" int currentZIndex = -1;\n" " for(int i=0; i<sampleCount; i++)\n"
" int flipCount = 0;\n"
"\n"
"\n"
" for(int i=0; i<indexCount; i+=3)\n"
" {\n" " {\n"
" uint i0 = indexBuffer.elements[i];\n" " currentZIndex[i] = -1;\n"
" uint i1 = indexBuffer.elements[i+1];\n" " flipCount[i] = 0;\n"
" uint i2 = indexBuffer.elements[i+2];\n" " sampleColor[i] = clearColor;\n"
" currentColor[i] = clearColor;\n"
" }\n"
"\n"
" for(int triangleIndex=0; triangleIndex<indexCount; triangleIndex+=3)\n"
" {\n"
" uint i0 = indexBuffer.elements[triangleIndex];\n"
" uint i1 = indexBuffer.elements[triangleIndex+1];\n"
" uint i2 = indexBuffer.elements[triangleIndex+2];\n"
"\n" "\n"
" ivec2 p0 = ivec2(vertexBuffer.elements[i0].pos * subPixelFactor + vec2(0.5, 0.5));\n" " ivec2 p0 = ivec2(vertexBuffer.elements[i0].pos * subPixelFactor + vec2(0.5, 0.5));\n"
" ivec2 p1 = ivec2(vertexBuffer.elements[i1].pos * subPixelFactor + vec2(0.5, 0.5));\n" " ivec2 p1 = ivec2(vertexBuffer.elements[i1].pos * subPixelFactor + vec2(0.5, 0.5));\n"
@ -96,6 +111,10 @@ const char* gles_canvas_fragment =
" int bias1 = is_top_left(p2, p0) ? 0 : -1;\n" " int bias1 = is_top_left(p2, p0) ? 0 : -1;\n"
" int bias2 = is_top_left(p0, p1) ? 0 : -1;\n" " int bias2 = is_top_left(p0, p1) ? 0 : -1;\n"
"\n" "\n"
" for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)\n"
" {\n"
" ivec2 samplePoint = samplePoints[sampleIndex];\n"
"\n"
" int w0 = orient2d(p1, p2, samplePoint);\n" " int w0 = orient2d(p1, p2, samplePoint);\n"
" int w1 = orient2d(p2, p0, samplePoint);\n" " int w1 = orient2d(p2, p0, samplePoint);\n"
" int w2 = orient2d(p0, p1, samplePoint);\n" " int w2 = orient2d(p0, p1, samplePoint);\n"
@ -107,29 +126,34 @@ const char* gles_canvas_fragment =
" float eps = 0.0001;\n" " float eps = 0.0001;\n"
" if(cubic.w*(cubic.x*cubic.x*cubic.x - cubic.y*cubic.z) <= eps)\n" " if(cubic.w*(cubic.x*cubic.x*cubic.x - cubic.y*cubic.z) <= eps)\n"
" {\n" " {\n"
" if(zIndex == currentZIndex)\n" " if(zIndex == currentZIndex[sampleIndex])\n"
" {\n" " {\n"
" flipCount++;\n" " flipCount[sampleIndex]++;\n"
" }\n" " }\n"
" else\n" " else\n"
" {\n" " {\n"
" if((flipCount & 0x01) != 0)\n" " if((flipCount[sampleIndex] & 0x01) != 0)\n"
" {\n" " {\n"
" pixelColor = currentColor;\n" " sampleColor[sampleIndex] = currentColor[sampleIndex];\n"
" }\n" " }\n"
" currentColor = pixelColor*(1.-color.a) + color.a*color;\n" " currentColor[sampleIndex] = sampleColor[sampleIndex]*(1.-color.a) + color.a*color;\n"
" currentZIndex = zIndex;\n" " currentZIndex[sampleIndex] = zIndex;\n"
" flipCount = 1;\n" " flipCount[sampleIndex] = 1;\n"
" }\n" " }\n"
" }\n" " }\n"
" }\n" " }\n"
" }\n" " }\n"
" if((flipCount & 0x01) != 0)\n" " }\n"
" vec4 pixelColor = vec4(0);\n"
" for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)\n"
" {\n" " {\n"
" pixelColor = currentColor;\n" " if((flipCount[sampleIndex] & 0x01) != 0)\n"
" {\n"
" sampleColor[sampleIndex] = currentColor[sampleIndex];\n"
" }\n" " }\n"
"\n" " pixelColor += sampleColor[sampleIndex];\n"
" fragColor = pixelColor;\n" " }\n"
" fragColor = pixelColor/float(sampleCount);\n"
"}\n"; "}\n";
//NOTE: string imported from src\gles_canvas_shaders\gles_canvas_vertex.glsl //NOTE: string imported from src\gles_canvas_shaders\gles_canvas_vertex.glsl

View File

@ -38,22 +38,37 @@ int orient2d(ivec2 a, ivec2 b, ivec2 p)
void main() void main()
{ {
float subPixelFactor = 16.; const float subPixelFactor = 16.;
const int sampleCount = 8;
vec4 pixelColor = clearColor; ivec2 centerPoint = ivec2(round(gl_FragCoord.xy * subPixelFactor));
vec4 currentColor = clearColor; ivec2 samplePoints[sampleCount] = ivec2[sampleCount](centerPoint + ivec2(1, 3),
centerPoint + ivec2(-1, -3),
centerPoint + ivec2(5, -1),
centerPoint + ivec2(-3, 5),
centerPoint + ivec2(-5, -5),
centerPoint + ivec2(-7, 1),
centerPoint + ivec2(3, -7),
centerPoint + ivec2(7, 7));
ivec2 samplePoint = ivec2(gl_FragCoord.xy * subPixelFactor + vec2(0.5, 0.5)); vec4 sampleColor[sampleCount];
vec4 currentColor[sampleCount];
int currentZIndex[sampleCount];
int flipCount[sampleCount];
int currentZIndex = -1; for(int i=0; i<sampleCount; i++)
int flipCount = 0;
for(int i=0; i<indexCount; i+=3)
{ {
uint i0 = indexBuffer.elements[i]; currentZIndex[i] = -1;
uint i1 = indexBuffer.elements[i+1]; flipCount[i] = 0;
uint i2 = indexBuffer.elements[i+2]; sampleColor[i] = clearColor;
currentColor[i] = clearColor;
}
for(int triangleIndex=0; triangleIndex<indexCount; triangleIndex+=3)
{
uint i0 = indexBuffer.elements[triangleIndex];
uint i1 = indexBuffer.elements[triangleIndex+1];
uint i2 = indexBuffer.elements[triangleIndex+2];
ivec2 p0 = ivec2(vertexBuffer.elements[i0].pos * subPixelFactor + vec2(0.5, 0.5)); ivec2 p0 = ivec2(vertexBuffer.elements[i0].pos * subPixelFactor + vec2(0.5, 0.5));
ivec2 p1 = ivec2(vertexBuffer.elements[i1].pos * subPixelFactor + vec2(0.5, 0.5)); ivec2 p1 = ivec2(vertexBuffer.elements[i1].pos * subPixelFactor + vec2(0.5, 0.5));
@ -83,6 +98,10 @@ void main()
int bias1 = is_top_left(p2, p0) ? 0 : -1; int bias1 = is_top_left(p2, p0) ? 0 : -1;
int bias2 = is_top_left(p0, p1) ? 0 : -1; int bias2 = is_top_left(p0, p1) ? 0 : -1;
for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
{
ivec2 samplePoint = samplePoints[sampleIndex];
int w0 = orient2d(p1, p2, samplePoint); int w0 = orient2d(p1, p2, samplePoint);
int w1 = orient2d(p2, p0, samplePoint); int w1 = orient2d(p2, p0, samplePoint);
int w2 = orient2d(p0, p1, samplePoint); int w2 = orient2d(p0, p1, samplePoint);
@ -94,27 +113,32 @@ void main()
float eps = 0.0001; float eps = 0.0001;
if(cubic.w*(cubic.x*cubic.x*cubic.x - cubic.y*cubic.z) <= eps) if(cubic.w*(cubic.x*cubic.x*cubic.x - cubic.y*cubic.z) <= eps)
{ {
if(zIndex == currentZIndex) if(zIndex == currentZIndex[sampleIndex])
{ {
flipCount++; flipCount[sampleIndex]++;
} }
else else
{ {
if((flipCount & 0x01) != 0) if((flipCount[sampleIndex] & 0x01) != 0)
{ {
pixelColor = currentColor; sampleColor[sampleIndex] = currentColor[sampleIndex];
} }
currentColor = pixelColor*(1.-color.a) + color.a*color; currentColor[sampleIndex] = sampleColor[sampleIndex]*(1.-color.a) + color.a*color;
currentZIndex = zIndex; currentZIndex[sampleIndex] = zIndex;
flipCount = 1; flipCount[sampleIndex] = 1;
} }
} }
} }
} }
if((flipCount & 0x01) != 0) }
vec4 pixelColor = vec4(0);
for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
{ {
pixelColor = currentColor; if((flipCount[sampleIndex] & 0x01) != 0)
{
sampleColor[sampleIndex] = currentColor[sampleIndex];
} }
pixelColor += sampleColor[sampleIndex];
fragColor = pixelColor; }
fragColor = pixelColor/float(sampleCount);
} }

View File

@ -22,17 +22,27 @@
-> convert verts pos to fixed point -> convert verts pos to fixed point
-> do orient2d in fixed point -> do orient2d in fixed point
[!] Check precision/possible overflow when using barycentric coords [!] Check precision/possible overflow when using barycentric coords
[!] Avoid first useless (degenerate) triangle on every path
[x] Set backround clear color [x] Set backround clear color
[ ] Multi-sampling [x] Multi-sampling
[ ] Assess perf [!] Avoid first useless (degenerate) triangle on every path
[ ] image rendering
[ ] Re-think image API first??
[ ] gles image atlas logic
[ ] textured rendering in shader
[ ] Image rendering test app
[ ] Text rendering test app
[?] Little test drawing app?
[>] Assess perf
[ ] Tiling [ ] Tiling
[ ] Precomputing triangle edges/biases? [ ] Precomputing triangle edges/biases?
[ ] Little test drawing app
[ ] Implement surfaces with child windows on win32 [ ] Implement surfaces with child windows on win32
[/] Maybe implement compositing directly in d3d and opengl compat extension... [/] Maybe implement compositing directly in d3d and opengl compat extension...
[ ] Cleanup routines
Windows port Windows port
------------ ------------