----------------------------------------------2024.12.30----------------------------------------------

因为还是有很多人私信询问我关于此方面的问题,所以我重新标注了:

1. 需要OpenGL或者Direct3D从底层进行刷新。只有这样才能保证完全稳定不掉帧。

2. Unity/UE都只能做无训练的SSVEP,有训练也需要重新编写Shader或者是Render否则掉帧. PsychoPy如果掉帧在程序里把优先级调出来……任意封装了OpenGL接口调用的软件编写软件的第一件事是提高程序优先级

3. WebGL,OpenGL ES, OpenGL都能达到在网页上,安卓上,PC端上的稳定刷新,±2ms内。

4. 不过以我做OpenGL的情况来看,如果负载太重(比如电脑内存少显卡烂还想刷新3D,底层也会刷新不过来导致掉帧,这是必然的,不过SSVEP的2D刷新负载很少了,基本上都能维持十分稳定的刷新。)

5. 虽然已经离开了脑机接口行业,但是由于种种原因没办法提供更完善的代码,请诸位见谅,不过比我以前一个一个试过去最起码可以明白只能做OpenGL或者是Direct3D了,可以找点图形学的书来看。

还有我是女生,私信的评论的不要叫我老哥了,谢谢!

----------------------------------------------2024.8.14------------------------------------------

用OpenGL可以在大部分软件上得到稳定性。

如果实在是搞不定优先尝试animation。尚有一线生机……        

-----------------------------------------------2022.3.14------------------------------------------------

因为工作涉及到了这一个问题,在这一年里也做了很多的尝试,所以在此分享一下经验,以免后来人没有资料再过多的浪费时间。

        1.刺激刷新稳定性需要使用OpenGL或者Direct3D显卡角度进行编写操作,所有定时器、线程等相关的代码,都无法满足稳定性为±2ms的刺激刷新操作(极低的频率刷新也许可以,但是时间上的稳定性再后来我就再也没有验证过。

        2.低于15Hz的刺激可以通过简单调用封装后的OpenGL的API进行操作。

        以下附Java以及C++的代码,均实现了15Hz以下的稳定性,但是再往上想要更高的稳定性时均失败。

Java(该方法是做一个活动时和游戏公司出来的大佬那边偶然讨论到的):

/* autogenerated by Processing revision 1281 on 2022-03-01 */
import processing.core.*;
import processing.data.*;
import processing.event.*;
import processing.opengl.*;

import java.util.HashMap;
import java.util.ArrayList;
import java.io.File;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

public class sketch_220301a extends PApplet {

 public void setup()
{

  frameRate(30);
  /* size commented out by preprocessor */;
}
int i=0;
 public void draw() {
  background(162);
    noStroke();

  textSize(30);
  text("frameRate:"+ frameRate,20,40);
 
  rectMode(CENTER);
  rect(width/2, 100, 200, 200);
  rect(100, height/2, 200, 200);
  rect(width-100, height/2, 200, 200);
  rect(width/2, height-100, 200, 200);
  if (i!=0)
  {
    fill(255, 255, 255);
    i=0;
  } else
  {
    fill(0, 0, 0);
    i=1;
  }

}

 public void keyPressed()
{
switch(key) {
  case '+':
   frameRate(frameRate++);
    break;
      case '-':
   frameRate(frameRate--);
    break;
  default:
    break;
  }

}


  public void settings() { fullScreen(); }

  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "sketch_220301a" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}

其稳定性测试相关情况,在15Hz下是可以接受的,15Hz以上则掉帧严重:

        C++代码(此代码是从github上downLoad后经过了一些修改,因此我直接放上了该github地址):

        C++版本的刺激实现

        3.完成30Hz的刺激,目前除了Matlab之外我成功了两种工具,一种是Python的PsychoPy,另一种是Unity3D.这两款是我已知的可以完成30Hz稳定性测试的项目,并且已经完全实现。

        (等我有时间了一定把代码放上来,现在还要提炼打包就比较麻烦)。

        关于30Hz的稳定性实现并且拓展性强还是要用C++调用OpenGL的显卡语言进行操作。关于这方面我一直没时间研究(本来的方向也并非计算机图形学)。

        欢迎一些同样有这问题,或者已经解决了这问题的工程师和我踊跃探讨这方面的实现方法。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐