# Texture sampling NEAREST in P2D render

**URL:** <https://discourse.processing.org/t/texture-sampling-nearest-in-p2d-render/48399>\
**Category:** Coding Questions\
**Created:** [April 4, 2026, 1:03pm UTC](https://discourse.processing.org/t/texture-sampling-nearest-in-p2d-render/48399 "2026-04-04T13:03:47Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![AniManOtaku](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/animanotaku/32/18733_2.png) [@AniManOtaku](https://discourse.processing.org/u/AniManOtaku)\
**Post date:** [April 4, 2026, 1:03pm UTC](https://discourse.processing.org/t/texture-sampling-nearest-in-p2d-render/48399/1 "2026-04-04T13:03:47Z")

</div>

Hi i work with PShader and i really want to get not smoothed pixels from texture2D. How do i set texture sampling NEAREST in PGraphics in P2D render?

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [April 4, 2026, 6:33pm UTC](https://discourse.processing.org/t/texture-sampling-nearest-in-p2d-render/48399/2 "2026-04-04T18:33:07Z")

</div>

Within glsl, you can use `texelFetch()` to read non-filtered data from a single pixel. Does that match what you are trying to do?

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [April 4, 2026, 6:49pm UTC](https://discourse.processing.org/t/texture-sampling-nearest-in-p2d-render/48399/3 "2026-04-04T18:49:53Z")

</div>

Or you can ignore the sampling and just always read from exactly the center of the pixels:

```auto
PGraphics thing;
PShader shdr;

void setup() {
  size( 800, 800, P2D );
  shdr = new PShader( this, vertSrc, fragSrc );
  thing = createGraphics( 16, 16, P2D );
  thing.noSmooth();

  thing.beginDraw(); // begin/draw pair needed to
  thing.endDraw(); // "init" PGraphics using P2D

  thing.beginDraw();
  thing.background(0);
  thing.loadPixels();
  for( int i=0; i<thing.height; i++ )
    thing.pixels[i + i*thing.height] = 0xffffffff;
  thing.updatePixels();
  thing.stroke( 200, 255, 200 );
  thing.line( 0, 5, thing.width, thing.height );
  thing.stroke( 255, 200, 100 );
  thing.noFill();
  thing.circle( 8, 6, 7 );
  thing.stroke( 200, 255, 100 );
  thing.strokeCap( PROJECT ); // needed to make point() visible
  thing.point( 8, 6 );
  thing.endDraw();
}

void draw() {
  if( frameCount % 60 == 0 ) {
    thing.beginDraw();
    thing.stroke( random(100,255), random(100,255), random(100,255) );
    thing.point( random( thing.width ), random( thing.height ) );
    thing.endDraw();
  }

  background( 100 );
  shdr.set( "texture", thing );
  shader(shdr);
  noStroke();
  rect( 60, 80, 16, 16 );
  rect( 60, 180, 64, 64 );
  float s = 384+128*sin(frameCount/30.0);
  rect( 200, 80, s, s );
  resetShader();
}

String[] vertSrc = { """#version 130
uniform mat4 transformMatrix;
uniform mat4 texMatrix;
in vec4 position;
in vec2 texCoord;
varying vec4 vertTexCoord;

void main() {
  gl_Position = transformMatrix * position;
  vertTexCoord = texMatrix * vec4( texCoord, 1.0, 1.0 );
  vertTexCoord.y = 1.0 - vertTexCoord.y;
}
""" };

String[] fragSrc = { """#version 130
uniform sampler2D texture;
in vec4 vertTexCoord;

void main() {
  vec2 texSize = textureSize( texture, 0 );
  vec2 uv = (floor(vertTexCoord.st*texSize) + 0.5) / texSize;
  gl_FragColor = texture2D( texture, clamp(uv, 0., 1.) );
}
""" };

```

---

<div class="post-metadata">

**Author:** ![AniManOtaku](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/animanotaku/32/18733_2.png) [@AniManOtaku](https://discourse.processing.org/u/AniManOtaku)\
**Post date:** [April 5, 2026, 12:17am UTC](https://discourse.processing.org/t/texture-sampling-nearest-in-p2d-render/48399/4 "2026-04-05T00:17:12Z")

</div>

Thanks for your reply! When I try to use textlFetch, I get lots of errors.

```auto
#ifdef GL_ES
precision highp float;
#endif

uniform sampler2D texture;

void main() {
  gl_FragColor = texelFetch(texture, ivec2(gl_FragCoord.xy), 0);
}

```

To be honest, I’m not sure exactly what I’m doing wrong. I’d be very grateful if you could show me the simplest example of how to use it correctly.

Oh, and if this matter, I use APDE not processing for desktop.

---

<div class="post-metadata">

**Author:** ![AniManOtaku](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/animanotaku/32/18733_2.png) [@AniManOtaku](https://discourse.processing.org/u/AniManOtaku)\
**Post date:** [April 5, 2026, 12:29am UTC](https://discourse.processing.org/t/texture-sampling-nearest-in-p2d-render/48399/5 "2026-04-05T00:29:03Z")

</div>

Yes, that’s exactly what I tried to do first. But I noticed that the colour of the pixels at the colour boundaries still becomes slightly blurred. For example, it used to be (255,255,255,255) and became (254,254,254,254). After a series of tests, I concluded that this was specifically due to bilinear smooth. Perhaps the float type introduces a small margin of error, and something similar happens when retrieving a pixel from the texture. Yes, I also tried using high-precision floats, but that didn’t solve the problem.

I realise the error is very small, but for my project it’s a problem.

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [April 5, 2026, 12:55am UTC](https://discourse.processing.org/t/texture-sampling-nearest-in-p2d-render/48399/6 "2026-04-05T00:55:48Z")

</div>

Add

`#version 130 core`

as the first line of your shader.

```auto
PGraphics thing;
PShader shdr;

void setup() {
  size( 800, 800, P2D );
  shdr = new PShader( this, vertSrc, fragSrc );
  thing = createGraphics( 16, 16, P2D );
  thing.noSmooth();

  thing.beginDraw(); // begin/draw pair needed to
  thing.endDraw(); // "init" PGraphics using P2D

  thing.beginDraw();
  thing.background(0);
  thing.loadPixels();
  for( int i=0; i<thing.height; i++ )
    thing.pixels[i + i*thing.height] = 0xffffffff;
  thing.updatePixels();
  thing.stroke( 200, 255, 200 );
  thing.line( 0, 5, thing.width, thing.height );
  thing.stroke( 255, 200, 100 );
  thing.noFill();
  thing.circle( 8, 6, 7 );
  thing.stroke( 200, 255, 100 );
  thing.strokeCap( PROJECT ); // needed to make point() visible
  thing.point( 8, 6 );
  thing.endDraw();
}

void draw() {
  if( frameCount % 60 == 0 ) {
    thing.beginDraw();
    thing.stroke( random(100,255), random(100,255), random(100,255) );
    thing.point( random( thing.width ), random( thing.height ) );
    thing.endDraw();
  }

  background( 100 );
  shdr.set( "texture", thing );
  shader(shdr);
  noStroke();
  rect( 60, 80, 16, 16 );
  rect( 60, 180, 64, 64 );
  float s = 384+128*sin(frameCount/30.0);
  rect( 200, 80, s, s );
  resetShader();
}

String[] vertSrc = { """#version 130
uniform mat4 transformMatrix;
uniform mat4 texMatrix;
in vec4 position;
in vec2 texCoord;
out vec4 vertTexCoord;

void main() {
  gl_Position = transformMatrix * position;
  vertTexCoord = texMatrix * vec4( texCoord, 1.0, 1.0 );
  vertTexCoord.y = 1.0 - vertTexCoord.y;
}
""" };

String[] fragSrc = { """#version 130
uniform sampler2D texture;
in vec4 vertTexCoord;
out vec4 fragColor;

void main() {
  vec2 texSize = textureSize( texture, 0 );
// vec2 uv = (floor(vertTexCoord.st*texSize) + 0.5) / texSize;
// gl_FragColor = texture2D( texture, clamp(uv, 0., 1.) );
  fragColor = texelFetch( texture, ivec2( vertTexCoord.st * texSize ), 0 );
}
""" };

```

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [April 5, 2026, 1:21am UTC](https://discourse.processing.org/t/texture-sampling-nearest-in-p2d-render/48399/7 "2026-04-05T01:21:51Z")

</div>

Ah, sorry, I just saw the APDE part. That means you’re using OpenGL ES. Put

```auto
#version 300 es

```

at the start of your shaders.

You might like to read through [https://registry.khronos.org/OpenGL/specs/es/3.0/GLSL\_ES\_Specification\_3.00.pdf](https://registry.khronos.org/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf) to learn the particulars.

In later versions of glsl, they replaced `gl_FragColor` with an output `vec4` of your own creation, so that’s why my code has my own `out vec4 fragColor;` line.

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [April 5, 2026, 1:29am UTC](https://discourse.processing.org/t/texture-sampling-nearest-in-p2d-render/48399/8 "2026-04-05T01:29:12Z")

</div>

Here’s the same code I’ve been posting, but changed to version 300 es:

```auto
PGraphics thing;
PShader shdr;

void setup() {
  size( 800, 800, P2D );
  shdr = new PShader( this, vertSrc, fragSrc );
  thing = createGraphics( 16, 16, P2D );
  thing.noSmooth();

  thing.beginDraw(); // begin/draw pair needed to
  thing.endDraw(); // "init" PGraphics using P2D

  thing.beginDraw();
  thing.background(0);
  thing.loadPixels();
  for( int i=0; i<thing.height; i++ )
    thing.pixels[i + i*thing.height] = 0xffffffff;
  thing.updatePixels();
  thing.stroke( 200, 255, 200 );
  thing.line( 0, 5, thing.width, thing.height );
  thing.stroke( 255, 200, 100 );
  thing.noFill();
  thing.circle( 8, 6, 7 );
  thing.stroke( 200, 255, 100 );
  thing.strokeCap( PROJECT ); // needed to make point() visible
  thing.point( 8, 6 );
  thing.endDraw();
}

void draw() {
  if( frameCount % 60 == 0 ) {
    thing.beginDraw();
    thing.stroke( random(100,255), random(100,255), random(100,255) );
    thing.point( random( thing.width ), random( thing.height ) );
    thing.endDraw();
  }

  background( 100 );
  shdr.set( "texture", thing );
  shader(shdr);
  noStroke();
  rect( 60, 80, 16, 16 );
  rect( 60, 180, 64, 64 );
  float s = 384+128*sin(frameCount/30.0);
  rect( 200, 80, s, s );
  resetShader();
}

String[] vertSrc = { """#version 300 es
precision highp float;
uniform mat4 transformMatrix;
uniform mat4 texMatrix;
in vec4 position;
in vec2 texCoord;
out vec4 vertTexCoord;

void main() {
  gl_Position = transformMatrix * position;
  vertTexCoord = texMatrix * vec4( texCoord, 1.0, 1.0 );
  vertTexCoord.y = 1.0 - vertTexCoord.y;
}
""" };

String[] fragSrc = { """#version 300 es
precision highp float;
uniform sampler2D texture;
in vec4 vertTexCoord;
out vec4 fragColor;

void main() {
  vec2 texSize = vec2( textureSize( texture, 0 ) );
  fragColor = texelFetch( texture, ivec2( vertTexCoord.st * texSize ), 0 );
}
""" };

```

---

<div class="post-metadata">

**Author:** ![AniManOtaku](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/animanotaku/32/18733_2.png) [@AniManOtaku](https://discourse.processing.org/u/AniManOtaku)\
**Post date:** [April 5, 2026, 9:19am UTC](https://discourse.processing.org/t/texture-sampling-nearest-in-p2d-render/48399/9 "2026-04-05T09:19:27Z")

</div>

Errors:

> java.lang.RuntimeException: Cannot compile fragment shader:  
> 0:3: S0022: Symbol ‘texture’ redeclared  
> 0:8: L0001: Symbol ‘texture’ can’t be referenced as a variable  
> 0:9: L0001: Symbol ‘texture’ can’t be referenced as a variable  
> at processing.core.PGraphics.showException(PGraphics.java:5701)  
> at processing.opengl.PShader.compileFragmentShader

It seems that Processing creates its own `texture` variable, so that needs to be removed. As for the other error, I’m not sure what to do about it.

---

<div class="post-metadata">

**Author:** ![AniManOtaku](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/animanotaku/32/18733_2.png) [@AniManOtaku](https://discourse.processing.org/u/AniManOtaku)\
**Post date:** [April 5, 2026, 9:39am UTC](https://discourse.processing.org/t/texture-sampling-nearest-in-p2d-render/48399/10 "2026-04-05T09:39:15Z")

</div>

The solution is very simple – we just need to rename the variable, for example to `mytexture`.

And it seems to work perfectly. The image doesn’t become blurry when zoomed in. Anyway, thanks for your help! I’m really grateful to you!!! @scudly
