java如何在创建小于窗口的PGraphics对象时避免“抗锯齿效应”,然后将其放大到窗口大小?
运行时,程序将在PGraphics对象“g”中显示在P3D环境中渲染的3D球体,该球体通过获取渲染的PGraphics对象并通过主图形上下文(恰好是P2D)中的image()方法显示
该程序的目的是显示窗口大小如何不总是与渲染大小相关。如果你全屏玩Widows98旧游戏,游戏很可能会以480p的速度呈现,因此全屏只会降低每英寸的像素数,并使图像看起来模糊。这很好,因为480p的全屏模式比窗口模式更受欢迎(尤其是在4K X_X上)
鼠标在窗口中的y位置会更改三维摄影机的视野,x位置会更改用于显示球体的P3D上下文的渲染分辨率。此外,P3D上下文通过image()方法在主(P2D)上下文中绘制,并且是“强制”的。以窗口大小显示。因此,如果P3D渲染分辨率小于窗口,则它将开始看起来模糊且更像素化,如果渲染分辨率更大,则会获得奇怪的锐化效果
现在,我的程序运行正常,但是。该程序的另一个目的被这个问题掩盖了,它是如何随着渲染分辨率的降低而减弱球体的“清晰度”。你可能会说它显示得很清楚,但我要找的是一个没有“反别名”效果的图像。我希望图像在分辨率变小时保留像素,这样你就可以看到球体的实际形状,比如说,50 x 50像素
noSmooth()方法似乎不起作用,在你告诉我怎么做之前
g.loadPixels();
然后执行双for循环,将原始像素绘制到2d上下文中。不,它很邋遢。我知道这种模糊现象一定是有原因的。我希望这是image()方法,我应该使用另一种方法,或者在它之前添加另一种方法来消除图像模糊
PGraphics g;
void setup(){
size(1000,1000,P2D);
frameRate(1000);
noSmooth();
}
void draw(){
background(200);
float res = map(mouseX,0,width,0.75,128);
if (res==0) {
res=1;
}
g = createGraphics((int)(width/res),(int)(height/res),P3D);
g.noSmooth(); // is this thing working?????
float cameraZ = ((height/2.0) / tan(PI*60.0/360.0));
g.beginDraw();
g.perspective(radians(map(mouseY,0,height,0.1,160)), width/height, cameraZ/10.0, cameraZ*10.0);
g.camera(g.width/2.0, g.height/2.0, (height/2.0) / tan(PI*30.0 / 180.0), g.width/2.0, g.height/2.0, 0, 0, 1, 0);
g.background(200);
g.translate(g.width/2 ,g.height/2);
g.sphere(100);
g.endDraw();
image(g, 0, 0, width, height); // this is where it all comes together
text("rendering resolution: "+g.width+" x "+g.height,0,14);
text("fps: "+frameRate,0,14*2);
}
# 1 楼答案
(编辑:此解决方案修复了默认渲染器中的问题,但OP使用的是P2D渲染器。解决方案应该类似,因此如果有人知道如何在opengl中更改图像插值模式,这就是答案。)
这实际上不是由抗锯齿引起的。这是由image scaling引起的
此外,如果提供MCVE,帮助也会容易得多,如下所示:
这段代码也有同样的问题,但更容易理解和使用
无论如何,通过Processing's code跟踪,我们可以看到
image()
函数最终调用了PGraphics
类here中的imageImpl()
函数然后,此函数使用以下代码绘制图像:
然后在呈现器中实现
endShape()
函数,特别是PGraphicsJava2D
类,它调用drawShape()
函数here:最后,这向我们展示了正在调用
Graphics2D.fill()
函数,这就是实际绘制函数的地方“问题”是
Graphics2D.fill()
正在使用一种会导致模糊的算法缩放图像。不过,我们可以咨询the Java API和谷歌,找出如何解决这个问题具体来说,this tutorial向您展示了如何设置各种渲染提示以更改缩放算法。我们可以在这样的处理中使用:
首先,我们导入我们需要的类。然后我们进入渲染器中的
Graphics2D
实例,最后调用它的setRenderingHint()
函数。我用一个if(mousePressed)
包装了它,这样你就可以很容易地看到区别了。单击鼠标时,“插值”设置为“最近邻”,您将不再看到模糊还要注意,我的代码使用了从
PApplet
超类继承的g
变量,因此您必须更改g
变量,使其不再隐藏# 2 楼答案
将
g.noSmooth()
替换为((PGraphicsOpenGL)g).textureSampling(2);
积分归Vallentin因为我奇怪地对P3D渲染器有同样的问题