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)
{
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;

View File

@ -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<indexCount; i+=3)\n"
" for(int i=0; i<sampleCount; i++)\n"
" {\n"
" uint i0 = indexBuffer.elements[i];\n"
" uint i1 = indexBuffer.elements[i+1];\n"
" uint i2 = indexBuffer.elements[i+2];\n"
" currentZIndex[i] = -1;\n"
" flipCount[i] = 0;\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"
" 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"
@ -96,40 +111,49 @@ const char* gles_canvas_fragment =
" int bias1 = is_top_left(p2, p0) ? 0 : -1;\n"
" int bias2 = is_top_left(p0, p1) ? 0 : -1;\n"
"\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"
" 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

View File

@ -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<indexCount; i+=3)
for(int i=0; i<sampleCount; i++)
{
uint i0 = indexBuffer.elements[i];
uint i1 = indexBuffer.elements[i+1];
uint i2 = indexBuffer.elements[i+2];
currentZIndex[i] = -1;
flipCount[i] = 0;
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 p1 = ivec2(vertexBuffer.elements[i1].pos * subPixelFactor + vec2(0.5, 0.5));
@ -83,38 +98,47 @@ void main()
int bias1 = is_top_left(p2, p0) ? 0 : -1;
int bias2 = is_top_left(p0, p1) ? 0 : -1;
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)
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);
}

View File

@ -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
------------