Shifting an objects position in shaders

Started by lawless_c, August 22, 2014, 01:08:14 PM

Previous topic - Next topic

lawless_c

Is it possible to shift the position of pixels being drawn in JPCT? im trying to render something and im using IRenderHooks repeatRendering method with an overlay and i want to shift it to the right on each rendering.

I've tried changing the overlay position itself in the repeatRendering method , that doesn't work however because of the way rendering all those objects remain in the same place.

The only way i can think is perhaps with pixel shaders, which i dont believe JPCT supports.


edit:  I may be misunderstanding how the shaders work but so far attempts to sue gl_position to shift the position of where i want a pixel to appear have failed.

EgonOlsen

You can't shift pixels (or fragments...) that way, because a fragment shader works on exactly one pixel at a fixed position and it can't break out.
But you can change vertex coordinates in the vertex shader. Try to add a uniform that takes your offset value as a float and add it to position.x (and/or y...depending on your needs) on each render before doing any other operation to position.

lawless_c

I'll give that a shot, would gl_FragCoord work too? maybe if i altered that instead of naively thinking i could alter gl_position.

EgonOlsen

No, that won't work. You can't reassign the values in gl_FragCoord...well, i think you actually can but it will have no effect.

lawless_c

Actually is it possible to update gl_position in repeatRendering()for a renderhook?? or even an Overlays coordinates? I cant seem to change these past when they are first set.

EgonOlsen

You should be able to update uniforms in the shader which in term can update gl_position. You can't update the overlay's coordinates outside of the shader in this stage. Can you post the code of your shader and your render hook?

lawless_c

I'm taking in the offsets and advance floats that are usually numbers like 48.0 , 52.1 etc
I think i may need to modify to work with "clip space" which seems to be -1.0 to 1.0 (not sure how though)

If you're wondering what it's for im attempting to implement signed distance field fonts. I actually managed to get it working with multiple overlays, one per each character but im trying to do it with a single one now. The repeat rendering sort of works in that it will draw each character in a string, however they all end up in single spot.

The uniforms bottomleftx and bottomlefty are finding where in the texture a character is before it's rendered(this works) though some characters end up being skewed
as the overlay dimensions don't match the character.


   @Override
   public boolean repeatRendering() {
      renderingIndex++;
     
      if(renderingIndex < charactersList.length && renderingIndex > 0)
      {
         
      advances = advances + charactersList[renderingIndex].advanceX;
   
     
      Overlayshader_.setUniform("a_colour",new SimpleVector(1,(renderingIndex*0.1f),0));
      Overlayshader_.setUniform("bottomLeftx",charactersList[renderingIndex].bottomLeftx);
      Overlayshader_.setUniform("bottomLefty", charactersList[renderingIndex].bottomLefty);   
      Overlayshader_.setUniform("width",charactersList[renderingIndex].width);
      Overlayshader_.setUniform("height",charactersList[renderingIndex].height);
     
      Overlayshader_.setUniform("offestx",renderingIndex);
      Overlayshader_.setUniform("offesty",0);
     
     
      return true;
      }
     
     
     
      setUpOverlayStart();
      renderingIndex=0;
      advances=0;
      return false;
   }



This is an example show three different strings i've added, the bottom one demonstrates a single character string a skewed zero.





And my vertex shader code




precision highp float;
// VERTEX SHADER


uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;

uniform float bottomLeftx;
uniform float bottomLefty;

uniform float width;
uniform float height;
uniform vec3 a_colour;

uniform float offsetx;
uniform float offsety;

attribute vec2 texture0;
attribute vec4 position;



varying vec4 v_color;
varying vec2 v_texCoord;

void main()
{
v_color = vec4(a_colour.x,a_colour.y,a_colour.z,1.0);

v_texCoord.x = bottomLeftx + (texture0.x/width);
v_texCoord.y = bottomLefty + (texture0.y/height);


vec4 newpos = vec4(offsetx,offsety,0,0);

gl_Position = projectionMatrix*((modelViewMatrix  * position) +newpos);

}

EgonOlsen

Try to set the offset-uniforms as real floats. The way you are doing it now, you are actually setting ints but the uniforms in the shader a floats. That might not work. Try to cast them to floats in the setters.

EgonOlsen

BTW: Why don't you simply blit the characters?

lawless_c

 :) Thanks, i'll try casting them when i get the chance.




I wanted to because i figured if i get this right https://www.youtube.com/watch?v=CGZRHJvJYIg  it will give me much more control. I would only have to use one texture containing the characters, I would be able to use this at various sizes.and things like borders and glow effect on text could be done in the shaders too.

I've already created a factory too that parses the data and creates the strings, my intention was to make it as it's own package and leave on it github for people here to use, improve , fork etc.