问题
Im trying to achieve antialiasing using accumulation buffer, but i don't fully understand what i'm doing wrong. The only effects im getting is drop down in fps, which i know is to be expected in this method.
The jitter table is a table filled with floats to make antialiasing look smoother.
I think it's probably because setting MartixMode doesnt change UniformMatrix method i later use in drawing objects.
Here's my OnRenderFrame method:
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
GL.Viewport(0, 0, Width, Height);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Enable(EnableCap.DepthTest);
GL.Clear(ClearBufferMask.AccumBufferBit);
shaders[activeShader].EnableVertexAttribArrays();
int jitter;
int numJitters = 4;
double j0, j1;
GL.Disable(EnableCap.Multisample);
for (jitter = 0; jitter < numJitters; jitter++)
{
float dx, dy;
int[] viewport = new int[4];
GL.GetInteger(GetPName.Viewport,viewport);
float windowWidth = viewport[2];
float windowHeight = viewport[3];
float frustumWidth = (float)(right - left);
float frustumHeight = (float)(top - bottom);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
dx = (float) jitterTable[jitter, 0] * frustumWidth / windowWidth;
dy = (float) jitterTable[jitter, 1] * frustumHeight / windowHeight;
GL.Frustum(left + dx, right + dx, bottom + dy, top + dy, near, far);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
int indiceat = 0;
foreach (Volume v in objects)
{
GL.UniformMatrix4(shaders[activeShader].GetUniform("modelview"), false, ref v.ModelViewProjectionMatrix);
GL.DrawElements(BeginMode.Triangles, v.IndiceCount, DrawElementsType.UnsignedInt, indiceat * sizeof(uint));
indiceat += v.IndiceCount;
}
GL.Accum(AccumOp.Accum, 1.0f / numJitters);
}
GL.Accum(AccumOp.Return, 1.0f);
shaders[activeShader].DisableVertexAttribArrays();
GL.Flush();
SwapBuffers();
}
Also i know there are better ways to achieve antialiasing, but my task is to do it this way.
UPDATE
After some search i found a way to to use accumulation buffer with shaders. Now the part of my method where i draw looks like this: for (jitter = 0; jitter < numJitters; jitter++) {
int indiceat = 0;
foreach (Volume v in objects)
{
Matrix4 aamat = Matrix4.Identity;
Vector3 vector3 = new Vector3((float)(jitter % 4) / (4 * Width), (float)(jitter / 4) / (4 * Height), 0.0f);
Matrix4.CreateTranslation(ref vector3, out aamat);
Matrix4 mvp = v.ModelViewProjectionMatrix * aamat;
GL.UniformMatrix4(shaders[activeShader].GetUniform("modelview"), false, ref mvp);
GL.DrawElements(BeginMode.Triangles, v.IndiceCount, DrawElementsType.UnsignedInt, indiceat * sizeof(uint));
indiceat += v.IndiceCount;
}
GL.Accum(AccumOp.Accum, 1.0f / (float) numJitters);
}
GL.Accum(AccumOp.Return, 1.0f);
As you can see on screenshot it smoothes out a part of cow object,but not all of it (numJitters was set to 64 for this screenshot):
For comparison here is the same object, but with multisampling enabled:
Any idea why it smoothed out just a part of the object ?
来源:https://stackoverflow.com/questions/59363130/opentk-how-to-achive-antialiasing-using-accumulation-buffer