运行时,程序会在PGraphics对象'g'中显示在P3D环境中渲染的3D球体,通过获取渲染的PGraphics对象并通过主图形上下文中的image()方法显示它。碰巧是P2D。
该程序的目的是显示窗口大小与渲染大小的关系并不总是如此。如果您全屏播放旧的Widows98游戏,游戏最有可能以480p呈现,无论如何,所以将其全屏显示只会降低每英寸的像素,并使图像看起来模糊。这很好,因为480p的全屏优先于窗口模式(特别是如果你使用的是4K X_X)
鼠标在窗口中的y位置会更改3d摄像机的视野,x位置会更改用于显示球体的P3D上下文的渲染分辨率。此外,P3D上下文通过image()方法在主(P2D)上下文中绘制,并且是“强制”的。以窗口大小显示。因此,如果P3D渲染分辨率小于窗口,则它将开始看起来模糊且更像素化,并且如果渲染分辨率更大,则会产生奇怪的锐化效果。
现在,我的程序工作正常,但是。该程序的另一个目的是被这个问题所掩盖,这就是随着渲染分辨率的降低,球体的“清晰度”逐渐消失。你可能会说它清楚地显示出来了,但我正在寻找的是一个没有“消除别名”效果的图像。我希望图像在分辨率变小时保留像素,因此您可以看到球体的实际形状,例如50 x 50像素。
noSmooth()方法似乎不起作用,在你告诉我做
之前g.loadPixels();
然后执行双循环以将原始像素绘制到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);
}
答案 0 :(得分:2)
将g.noSmooth()
替换为((PGraphicsOpenGL)g).textureSampling(2);
积分转到Vallentin因为奇怪的是我对P3D渲染器有同样的问题
答案 1 :(得分:1)
(编辑:此解决方案修复了默认渲染器中的问题,但OP正在使用P2D渲染器。解决方案应该类似,所以如果有人知道如何更改图像插值模式opengl,这就是答案。)
这实际上并不是由抗锯齿引起的。它是由image scaling引起的。
此外,如果您提供MCVE,则可以更轻松地提供帮助,如下所示:
PGraphics buffer;
void setup() {
size(1000, 1000);
buffer = createGraphics(100, 100);
buffer.noSmooth();
buffer.beginDraw();
buffer.background(255);
buffer.line(0, 0, width, height);
buffer.endDraw();
}
void draw() {
background(0);
image(buffer, 0, 0, mouseX, mouseY);
}
此代码表现出同样的问题,但理解和使用起来要容易得多。
无论如何,通过Processing's code进行追踪,我们可以看到image()
函数最终调用imageImpl()
类here中的PGraphics
函数。
然后,此函数使用以下代码绘制图像:
beginShape(QUADS);
texture(img);
vertex(x1, y1, u1, v1);
vertex(x1, y2, u1, v2);
vertex(x2, y2, u2, v2);
vertex(x2, y1, u2, v1);
endShape();
然后在渲染器中实现endShape()
函数,特别是PGraphicsJava2D
类,它调用drawShape()
函数here:
protected void drawShape(Shape s) {
if (fillGradient) {
g2.setPaint(fillGradientObject);
g2.fill(s);
} else if (fill) {
g2.setColor(fillColorObject);
g2.fill(s);
}
if (strokeGradient) {
g2.setPaint(strokeGradientObject);
g2.draw(s);
} else if (stroke) {
g2.setColor(strokeColorObject);
g2.draw(s);
}
}
最后,这告诉我们正在调用Graphics2D.fill()
函数,这实际上是在绘制函数。
“问题”是Graphics2D.fill()
正在使用导致某些模糊的算法缩放图像。我们可以咨询the Java API和Google以了解如何解决这个问题。
具体来说,this tutorial向您展示了如何设置各种渲染提示以更改缩放算法。我们可以在Processing中使用它:
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import processing.awt.PGraphicsJava2D;
PGraphics buffer;
void setup() {
size(1000, 1000);
buffer = createGraphics(100, 100);
buffer.noSmooth();
buffer.beginDraw();
buffer.background(255);
buffer.line(0, 0, width, height);
buffer.endDraw();
}
void draw() {
if (mousePressed) {
Graphics2D g2d = ((PGraphicsJava2D)g).g2;
g2d.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
}
background(0);
image(buffer, 0, 0, mouseX, mouseY);
}
首先,我们导入我们需要的类。然后我们到达渲染器中的Graphics2D
实例,最后调用它的setRenderingHint()
函数。我把它包裹在if(mousePressed)
中,这样你就可以很容易地看到差异。单击鼠标时,插值设置为最近邻居,您不再看到模糊。
另请注意,我的代码使用的是继承自g
超类的PApplet
变量,因此您必须更改g
变量,以便它不再隐藏它。