[Patch] Textures

Technical discussion for those interested in Supermodel development and Model 3 reverse engineering. Prospective contributors welcome.
Forum rules
Keep it classy!

  • No ROM requests or links.
  • Do not ask to be a play tester.
  • Do not ask about release dates.
  • No drama!

Re: [Patch] Textures

Postby Ian » Mon Jan 15, 2018 6:34 am

Well, 256 could be a valid scaling factor, but so high no one bothered to use it. It's impossible to say unless it's actually used anywhere.
Ian
 
Posts: 1535
Joined: Tue Feb 23, 2016 9:23 am

Re: [Patch] Textures

Postby HarryTuttle » Mon Jan 15, 2018 6:56 am

Ian wrote:Well, 256 could be a valid scaling factor

Yeah, I forgot you store the values as floats. Since I operate on int in shader I had to resort to clamping to avoid div by 0...
User avatar
HarryTuttle
 
Posts: 646
Joined: Thu Mar 09, 2017 8:57 am

Re: [Patch] Textures

Postby Ian » Fri Oct 05, 2018 6:07 am

Code: Select all
float LinearTexLocations(int wrapMode, float size, float u, out float u0, out float u1)
{
   float texelSize      = 1.0 / size;
   float halfTexelSize   = 0.5 / size;

   if(wrapMode==0) {                     // repeat
      u   = (u * size) - 0.5;
      u0   = (floor(u) + 0.5) / size;         // + 0.5 offset added to push us into the centre of a pixel, without we'll get rounding errors
      u0   = fract(u0);
      u1   = u0 + texelSize;
      u1   = fract(u1);

      return fract(u);                  // return weight
   }
   else if(wrapMode==1) {                  // repeat + clamp
      u   = fract(u);                     // must force into 0-1 to start
      u   = (u * size) - 0.5;
      u0   = (floor(u) + 0.5) / size;         // + 0.5 offset added to push us into the centre of a pixel, without we'll get rounding errors
      u1   = u0 + texelSize;

      if(u0 < 0.0)   u0 = 0.0;
      if(u1 > 1.0)   u1 = 1.0 - halfTexelSize;
      
      return fract(u);                  // return weight
   }
   else {                              // mirror + mirror clamp - both are the same since the edge pixels are repeated anyway

      float odd = floor(mod(u, 2.0));         // odd values are mirrored

      if(odd > 0.0) {
         u = 1.0 - fract(u);
      }
      else {
         u = fract(u);
      }

      u   = (u * size) - 0.5;
      u0   = (floor(u) + 0.5) / size;         // + 0.5 offset added to push us into the centre of a pixel, without we'll get rounding errors
      u1   = u0 + texelSize;

      if(u0 < 0.0)   u0 = 0.0;
      if(u1 > 1.0)   u1 = 1.0 - halfTexelSize;
      
      return fract(u);                  // return weight
   }
}

vec4 texBiLinear(sampler2D texSampler, int wrapMode, vec2 texCoord)
{
   float tx[2], ty[2];
   float a = LinearTexLocations(wrapMode,fWidth, texCoord.x,tx[0],tx[1]);
   float b = LinearTexLocations(wrapMode,fHeight,texCoord.y,ty[0],ty[1]);
   
   vec4 p0q0 = texture2D(texSampler, vec2(tx[0],ty[0]));
    vec4 p1q0 = texture2D(texSampler, vec2(tx[1],ty[0]));
    vec4 p0q1 = texture2D(texSampler, vec2(tx[0],ty[1]));
    vec4 p1q1 = texture2D(texSampler, vec2(tx[1],ty[1]));

   // Interpolation in X direction.
    vec4 pInterp_q0 = mix( p0q0, p1q0, a ); // Interpolates top row in X direction.
    vec4 pInterp_q1 = mix( p0q1, p1q1, a ); // Interpolates bottom row in X direction.

    return mix( pInterp_q0, pInterp_q1, b ); // Interpolate in Y direction.
}


One for Harry :) This emulates bilinear filtering in the shader .. also correctly handles the weird non smooth texture repeat, which is actually a combination in opengl of something like .. GL_CLAMP_TO_EDGE and GL_REPEAT. No equivalent function exists in opengl. Currently I fudged a solution by stretching the texture coordinates inside the polys to not sample the edge pixels, but this has its draw backs (ie doesn't work with mipmapping). This should improve the situation.

If we can add your code for pixel dilate for contour or alpha textures, and add in mipmapping, we'll have a very accurate emulation of what the model3 is doing.
Ian
 
Posts: 1535
Joined: Tue Feb 23, 2016 9:23 am

Re: [Patch] Textures

Postby Ian » Mon Oct 08, 2018 11:37 am

Harry posted this some time ago ..

Image

With this description

Regarding my last post, pixel "dilate": I'm using my version of bilinear filtering resulting from 9 texel fetches appropriately blended

What is happening here, instead, is that the edge texels "bleed" toward the "outer", transparent, texture area copying their RGB values there, while leaving the alpha channel intact. Infact the texture edge is cut in respect of the original alpha value, while its color is replicated from the "inner" texels.

This fixes, with the appropriate contour threshold, all the ugly white/black borders (but even some colored ones) in contour textures.


I think he was 100% correct in what was happening. But a bilinear filter is just 4 texture samples. Seems unlikely they would have used 9 texture samples to achieve this ..

Anyway I tried modifying regular bilinear filtering to achieve this (ie with 4 samples ..) and this is the result

Image

I just fetch the 4 texture samples. Then for each one check the 2 adjacent pixels and if necessary copy their colour, leaving the alpha untouched.

Code: Select all
   vec4 p0q0 = texture2DLod(texSampler, vec2(tx[0],ty[0]), 0.0);
    vec4 p1q0 = texture2DLod(texSampler, vec2(tx[1],ty[0]), 0.0);
    vec4 p0q1 = texture2DLod(texSampler, vec2(tx[0],ty[1]), 0.0);
    vec4 p1q1 = texture2DLod(texSampler, vec2(tx[1],ty[1]), 0.0);

   if(alphaTest) {
      if(p0q0.a > p1q0.a)      { p1q0.rgb = p0q0.rgb; }
      if(p0q0.a > p0q1.a)      { p0q1.rgb = p0q0.rgb; }

      if(p1q0.a > p0q0.a)      { p0q0.rgb = p1q0.rgb; }
      if(p1q0.a > p1q1.a)      { p1q1.rgb = p1q0.rgb; }

      if(p0q1.a > p0q0.a)      { p0q0.rgb = p0q1.rgb; }
      if(p0q1.a > p1q1.a)      { p1q1.rgb = p0q1.rgb; }

      if(p1q1.a > p0q1.a)      { p0q1.rgb = p1q1.rgb; }
      if(p1q1.a > p1q0.a)      { p1q0.rgb = p1q1.rgb; }
   }


Probably a more efficient way of doing that? but it works anyway. That level of branching would kill gpus from yesteryear lol
Ian
 
Posts: 1535
Joined: Tue Feb 23, 2016 9:23 am

Previous

Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 5 guests