4085

Precision loss with mod in GLSL

Question:

I'm repeating a texture in the vertex shader (for storage, not for repeating at the spot). Is this the right way? I seem to lose precision somehwere.

varying vec2 texcoordC; texcoordC = gl_MultiTexCoord0.xy; texcoordC *= 10.0; texcoordC.x = mod(texcoordC.x, 1.0); texcoordC.y = mod(texcoordC.y, 1.0);

ADDED: I then save (storage) the texcoord in the color, print it to the texture and later use that texture again. When I retrieve the color from the texture, I find the texcoords and use them to apply a texture in postprocess. There's a reason I want it this way, that I won't go into. I get it that the texcoords will be limited by the color's precision, that is alright as my texture is 256 in width and height.

I know normally I would set the texcoords with glTexcoord2f to higher than 1.0 to repeat (and using GL_REPEAT), but I am using a modelloader which I am to lazy to edit, as I think it is not necessary/not the easiest way.

Answer1:

There are (at least) two ways in which this could go wrong:

Firstly yes, you will lose precision. You are essentially taking the fractional part of a floating point number, after scaling it up. This essentially throws some of the number away.

Secondly, this probably won't work anyway, not for most typical uses. You are trying to tile a texture per-vertex, but the texture is interpolated across a polygon. So this technique could tile the texture differently on different vertices of the same polygon, resulting in a bit of a mess.

i.e.

If vertex1 has a U of 1.5 (after scaling), and vertex2 has a U of 2.2, then you expect the interpolation to give increasing values between those points, with the half-way point having a U of 1.85.

If you take the modulo at each vertex, you will have a U of 0.5, and a U of 0.2 respectively, resulting in a <em>decreasing</em> U, and a half-way point with a U of 0.35...

Textures can be tiled just be enabling tiling on the texture/sampler, and using coordinates outside the range 0->1. If you really want to increase sampling accuracy and have a large amount of tiling, you need to wrap the UV coordinates uniformly across whole polygons, rather than per-vertex. i.e. do it in your data, not in the vertex shader.

For your case, where you're trying to output the UV coordinates into a buffer for some later purpose, you could clamp/wrap the UVs in the <em>pixel</em> shader. So multiply up the UV in the vertex shader, interpolate it across the polygon correctly, and then apply the modulo only when writing to the buffer.

However I still think you'll have precision issues as you're losing all the sub-pixel information. Whether or not that's a problem for the technique you're using, I don't know.

Recommend

  • opengl multiple textures [closed]
  • JOGL mipmaps and texture shimmering
  • Simple way to display the borders of a CGRect?
  • How to run instrumentation tests for an android library in android studio?
  • How can we handle large matrices in matlab(larger than 10000x10000)
  • String says its not null but then later throw NullPointerException
  • Delphi: how to compose an email in Outlook without using MAPI?
  • Connection String in a WIX Custom Action Parameter
  • How to cache images only in disk using Kingfisher?
  • Accessing Redshift from Lambda - Avoiding the 0.0.0.0/0 Security Group
  • Vertical alignment of float:left div's
  • Breaking down CRUD In Use Case Modeling
  • AWS S3 implementation for serving private files
  • UIimage to char* conversion
  • Singleton Alternative - is it equivalent?
  • Polymer build not to create bundled and unbundled folder
  • Easiest way to covert part of a byte array to uint16
  • Change zIndex in HighChart
  • MySql - get days remaining
  • segue from landscape only to portrait only
  • How to set current CultureUI via XAML binding
  • Floated image with variable width and heading with background image
  • Low TTL with Leveled Compaction, should I reduce gc_grace_seconds to improve read performance withou
  • Tamper-proof configuration files in .NET?
  • Change multiple background-images with jQuery
  • How to delay loading a property with linq to sql external mapping?
  • What is Eclipse's Declaration View used for?
  • Fetching methods from BroadcastReceiver to update UI
  • Align navbar back button on right side
  • Sending data from AppleScript to FileMaker records
  • Javascript + PHP Encryption with pidCrypt
  • Symfony2: How to get request parameter
  • How to show dropdown in excel using jrxml (jasper api)?
  • WOWZA + RTMP + HTML5 Playback?
  • GridView Sorting works once only
  • WPF Applying a trigger on binding failure
  • NSLayoutConstraint that would pin a view to the bottom edge of a superview
  • How get height of the a view with gone visibility and height defined as wrap_content in xml?
  • How does Linux kernel interrupt the application?
  • python draw pie shapes with colour filled