From 28e2a3648e49ee402d92131dcfc6d2344acb7411 Mon Sep 17 00:00:00 2001 From: martinfouilleul Date: Thu, 2 Feb 2023 13:34:06 +0100 Subject: [PATCH] Multisampling in gles canvas shader --- examples/win_canvas/main.c | 8 +- src/gles_canvas_shaders.h | 94 ++++++++++++------- .../gles_canvas_fragment.glsl | 94 ++++++++++++------- todo.txt | 20 +++- 4 files changed, 137 insertions(+), 79 deletions(-) diff --git a/examples/win_canvas/main.c b/examples/win_canvas/main.c index 82b8e97..2b86158 100644 --- a/examples/win_canvas/main.c +++ b/examples/win_canvas/main.c @@ -71,19 +71,19 @@ int main() { if(event.key.code == MP_KEY_LEFT) { - dx-=1.1; + dx-=5.1; } else if(event.key.code == MP_KEY_RIGHT) { - dx+=1.1; + dx+=5.1; } else if(event.key.code == MP_KEY_UP) { - dy+=1.1; + dy+=5.1; } else if(event.key.code == MP_KEY_DOWN) { - dy-=1.1; + dy-=5.1; } } } break; diff --git a/src/gles_canvas_shaders.h b/src/gles_canvas_shaders.h index 50a15e0..24d86fc 100644 --- a/src/gles_canvas_shaders.h +++ b/src/gles_canvas_shaders.h @@ -51,22 +51,37 @@ const char* gles_canvas_fragment = "\n" "void main()\n" "{\n" -" float subPixelFactor = 16.;\n" +" const float subPixelFactor = 16.;\n" +" const int sampleCount = 8;\n" "\n" -" vec4 pixelColor = clearColor;\n" -" vec4 currentColor = clearColor;\n" +" ivec2 centerPoint = ivec2(round(gl_FragCoord.xy * subPixelFactor));\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" -" 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" -" int currentZIndex = -1;\n" -" int flipCount = 0;\n" -"\n" -"\n" -" for(int i=0; i= 0 && (w1+bias1) >= 0 && (w2+bias2) >= 0)\n" +" for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)\n" " {\n" -" vec4 cubic = (cubic0*float(w0) + cubic1*float(w1) + cubic2*float(w2))/(float(w0)+float(w1)+float(w2));\n" +" ivec2 samplePoint = samplePoints[sampleIndex];\n" "\n" -" float eps = 0.0001;\n" -" if(cubic.w*(cubic.x*cubic.x*cubic.x - cubic.y*cubic.z) <= eps)\n" +" int w0 = orient2d(p1, p2, samplePoint);\n" +" int w1 = orient2d(p2, p0, samplePoint);\n" +" int w2 = orient2d(p0, p1, samplePoint);\n" +"\n" +" if((w0+bias0) >= 0 && (w1+bias1) >= 0 && (w2+bias2) >= 0)\n" " {\n" -" if(zIndex == currentZIndex)\n" +" vec4 cubic = (cubic0*float(w0) + cubic1*float(w1) + cubic2*float(w2))/(float(w0)+float(w1)+float(w2));\n" +"\n" +" float eps = 0.0001;\n" +" if(cubic.w*(cubic.x*cubic.x*cubic.x - cubic.y*cubic.z) <= eps)\n" " {\n" -" flipCount++;\n" -" }\n" -" else\n" -" {\n" -" if((flipCount & 0x01) != 0)\n" +" if(zIndex == currentZIndex[sampleIndex])\n" " {\n" -" pixelColor = currentColor;\n" +" flipCount[sampleIndex]++;\n" +" }\n" +" else\n" +" {\n" +" if((flipCount[sampleIndex] & 0x01) != 0)\n" +" {\n" +" sampleColor[sampleIndex] = currentColor[sampleIndex];\n" +" }\n" +" currentColor[sampleIndex] = sampleColor[sampleIndex]*(1.-color.a) + color.a*color;\n" +" currentZIndex[sampleIndex] = zIndex;\n" +" flipCount[sampleIndex] = 1;\n" " }\n" -" currentColor = pixelColor*(1.-color.a) + color.a*color;\n" -" currentZIndex = zIndex;\n" -" flipCount = 1;\n" " }\n" " }\n" " }\n" " }\n" -" if((flipCount & 0x01) != 0)\n" +" vec4 pixelColor = vec4(0);\n" +" for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)\n" " {\n" -" pixelColor = currentColor;\n" -" }\n" -"\n" -" fragColor = pixelColor;\n" +" if((flipCount[sampleIndex] & 0x01) != 0)\n" +" {\n" +" sampleColor[sampleIndex] = currentColor[sampleIndex];\n" +" }\n" +" pixelColor += sampleColor[sampleIndex];\n" +" }\n" +" fragColor = pixelColor/float(sampleCount);\n" "}\n"; //NOTE: string imported from src\gles_canvas_shaders\gles_canvas_vertex.glsl diff --git a/src/gles_canvas_shaders/gles_canvas_fragment.glsl b/src/gles_canvas_shaders/gles_canvas_fragment.glsl index b22db05..166b29a 100644 --- a/src/gles_canvas_shaders/gles_canvas_fragment.glsl +++ b/src/gles_canvas_shaders/gles_canvas_fragment.glsl @@ -38,22 +38,37 @@ int orient2d(ivec2 a, ivec2 b, ivec2 p) void main() { - float subPixelFactor = 16.; + const float subPixelFactor = 16.; + const int sampleCount = 8; - vec4 pixelColor = clearColor; - vec4 currentColor = clearColor; + ivec2 centerPoint = ivec2(round(gl_FragCoord.xy * subPixelFactor)); + 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; - int flipCount = 0; - - - for(int i=0; i= 0 && (w1+bias1) >= 0 && (w2+bias2) >= 0) + for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) { - vec4 cubic = (cubic0*float(w0) + cubic1*float(w1) + cubic2*float(w2))/(float(w0)+float(w1)+float(w2)); + ivec2 samplePoint = samplePoints[sampleIndex]; - float eps = 0.0001; - if(cubic.w*(cubic.x*cubic.x*cubic.x - cubic.y*cubic.z) <= eps) + int w0 = orient2d(p1, p2, samplePoint); + int w1 = orient2d(p2, p0, samplePoint); + int w2 = orient2d(p0, p1, samplePoint); + + if((w0+bias0) >= 0 && (w1+bias1) >= 0 && (w2+bias2) >= 0) { - if(zIndex == currentZIndex) + vec4 cubic = (cubic0*float(w0) + cubic1*float(w1) + cubic2*float(w2))/(float(w0)+float(w1)+float(w2)); + + float eps = 0.0001; + if(cubic.w*(cubic.x*cubic.x*cubic.x - cubic.y*cubic.z) <= eps) { - flipCount++; - } - else - { - if((flipCount & 0x01) != 0) + if(zIndex == currentZIndex[sampleIndex]) { - pixelColor = currentColor; + flipCount[sampleIndex]++; + } + else + { + if((flipCount[sampleIndex] & 0x01) != 0) + { + sampleColor[sampleIndex] = currentColor[sampleIndex]; + } + currentColor[sampleIndex] = sampleColor[sampleIndex]*(1.-color.a) + color.a*color; + currentZIndex[sampleIndex] = zIndex; + flipCount[sampleIndex] = 1; } - currentColor = pixelColor*(1.-color.a) + color.a*color; - currentZIndex = zIndex; - flipCount = 1; } } } } - if((flipCount & 0x01) != 0) + vec4 pixelColor = vec4(0); + for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) { - pixelColor = currentColor; - } - - fragColor = pixelColor; + if((flipCount[sampleIndex] & 0x01) != 0) + { + sampleColor[sampleIndex] = currentColor[sampleIndex]; + } + pixelColor += sampleColor[sampleIndex]; + } + fragColor = pixelColor/float(sampleCount); } diff --git a/todo.txt b/todo.txt index 55b9d34..5006478 100644 --- a/todo.txt +++ b/todo.txt @@ -22,17 +22,27 @@ -> convert verts pos to fixed point -> do orient2d in fixed point [!] Check precision/possible overflow when using barycentric coords - [!] Avoid first useless (degenerate) triangle on every path + [x] Set backround clear color - [ ] Multi-sampling - [ ] Assess perf + [x] Multi-sampling + [!] 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 [ ] Precomputing triangle edges/biases? - [ ] Little test drawing app - [ ] Implement surfaces with child windows on win32 [/] Maybe implement compositing directly in d3d and opengl compat extension... +[ ] Cleanup routines Windows port ------------