PDA

View Full Version : Vertex Shader/Texture Lookup: Order of Operations



Rennie Johnson
11-11-2011, 07:04 PM
Pursuant to my previous post, I now have a working Vertex Shader that replaces the functionality of glTranslate(), glScale() and glRotate().

I need to offset the R,G,B, and A color records of a source texture in order to better align the color channels. The offset values may exceed the OpenGL limitation available in textureOffset(). The only way I know to do this is with Texture Coordinate X/Y offsets. And I need to do it with offset numbers that are based on the actual pixel coordinates (not normalized 0-1 values) because the offset calculations are made by the host CPU and are based on the actual textue pixel resolution.

It is critical that the color record offsets be applied before the image is scaled by the Vertex Shader Modelview/Projection Transformations. As the texture Lookup Function occurs in the Fragment Shader, I'm concerned that the values of gl_TexCoord[0], gl_TexCoord[1], etc. will be calculated after the Modelview/Projection Matrix is applied. This will cause the registration of the original source texture color channels to be ruined.

Let me also note that the textues are separate one-channel discreet textures. They look like this is in the fragment shader:

texImageScan.r = texture2D(ScanSamplerRed, vec2(gl_TexCoord[0].st)).r;
texImageScan.g = texture2D(ScanSamplerGreen, vec2(gl_TexCoord[1].st)).r
texImageScan.b = texture2D(ScanSamplerBlue, vec2(gl_TexCoord[2].st)).r
texImageScan.a = texture2D(ScanSamplerIR, vec2(gl_TexCoord[3].st)).r;

My questions are:

1) Will the generated texture coordinates in the code below be applied before the geometry transformations?
2) How can I apply the color channel Texture Offsets By actual pixel values without risk of sub-pixel interpolation?

Here is my temporary code. Please note that I have not made the input values uniform variables yet, as I am just
testing the shader.


void main(void)
{
//These Are The X-Y Translation Offsets For Each Texture Color Record
//That Will Be Applied To TexCoord[0-3] In Fragment Shader
//They must be applied Before The ModelProjectionView Transformations Below
//so that color channels will register correctly before scaling corrupts the original
//source texture coordinate system.

vec2 offsetRed;
vec2 offsetGreen;
vec2 offsetBlue;
vec2 offsetAlpha;

//Initialize Texture Channel Offsets To 0
offsetRed.x = 0.0;
offsetRed.y = 0.0;
offsetGreen.x = 0.0;
offsetGreen.y = 0.0;
offsetBlue.x = 0.0;
offsetBlue.y = 0.00;
offsetAlpha.x = 0.0;
offsetAlpha.y = 0.0;

//Assign Individual Texture Coordinates For Each Color Record

gl_TexCoord[0].st = gl_MultiTexCoord0.st + offsetRed;
gl_TexCoord[1].st = gl_MultiTexCoord0.st + offsetGreen;
gl_TexCoord[2].st = gl_MultiTexCoord0.st + offsetBlue;
gl_TexCoord[3].st = gl_MultiTexCoord0.st + offsetAlpha;

//These variables replace the use of glTranslate(), glScale() and glRotate()
float offsetX = 0.0;
float offsetY = 0.0;
float xScale = 1.0;
float yScale = 1.0;
float rotation = 0.0;

//Convert Rotation From Degrees To Radians
float rotationRadians = rotation * -0.0174532925;

//Assign Offset Values To vec4 Variable
vec4 offset;
offset.x = offsetX;
offset.y = offsetY;
offset.z = 0.0;
offset.w = 0.0;

//Assign Scale Values To vec4 Variable
vec4 scale;
scale.x = xScale;
scale.y = yScale;
scale.z = 1.0;
scale.w = 1.0;

//Calculate Rotation Matrix
mat3 rotationMatrix = mat3( vec3( cos(rotationRadians), sin(rotationRadians), 0.0),

vec3(-sin(rotationRadians), cos(rotationRadians), 0.0), vec3( 0.0, 0.0, 1.0) );

//****APPLY MODELVIEW/PROJECTION MATRIX TRANSFORMATION*********************************
//****MUST HAPPEN AFTER gl_TexCoord[x] Texture Lookup Is Applied In Fragment Shader*****
//Standard Identity Matrix
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

//Apply Offset Transformation
gl_Position += offset;

//Apply Scale Transformation
gl_Position *= scale;

//Apply Rotation Transformation
gl_Position.xyz *= rotationMatrix;
}