glslmultiTOP - Vertex shader texture sampling

Hi!

I’m trying sample a texture in the vertex shader and send the result to the pixel shader, but the values don’t match the input. Any ideas why?

The reason I want to do this is that in my project the texture is coordinates and I want to manipulate those coordinates in the vertex shader before rendering it to the screen.

glslmultiTOP-vertex-shader.toe (4.2 KB)

You are likely better off just manipulating them in the pixel shader before you do any samples. The usage cases for a custom vertex shader in the GLSL TOP is pretty low these days

Thanks for your fast reply!

The reason I thought of using the vertex shader was to transform (translate, rotation and scale) the values that the texture represents. I have a GLSL MAT in which I successfully created functions to do those transformations (using matrices), but I did not succeed in making them work in the pixel shader.

Basically, a color represent a 3D coordinate and I want to be able to transform that coordinate giving me the “color” of the transformed coordinate.

Maybe you can enlighten me on how you would approach this?

Thanks for you time!

You’d have to post an example of what you are trying to do. You can transform something in the pixel shader just as easily as you can in the vertex shader. The only difference is that you are doing it per pixel instead of per vertex, but if you are doing the same operation you’ll get similar results, and likely even better results if it’s done at the pixel shader stage.

Of course, here’s a basic example of what I’m trying to do.

I have a position stored in a texture.
glsl-position-tex

and I want to translate these positions using another texture.
glsl-trans-tex

What I did in my vertex shader was creating translation matrix using values from the translation texture and multiplied the position of the vertex with that matrix.

uniform sampler2D sPtPosition;
uniform sampler2D sPtTranslation;

mat4 translation_matrix(vec3 t){
	mat4 translation_matrix = mat4( 1.0, 0.0, 0.0, t.x,
									0.0, 1.0, 0.0, t.y,
									0.0, 0.0, 1.0, t.z,
									0.0, 0.0, 0.0, 1.0);

	return translation_matrix;
}


void main() 
{	
	vec2 uvCoord 			= uv[1].rg;
	vec4 ptTranslation 		= texture(sPtTranslation,uvCoord);
	mat4 translationMatrix 	= translation_matrix(ptTranslation.rgb);

	vec4 worldSpacePos = TDDeform(P);
	worldSpacePos *= translationMatrix;

	gl_Position = TDWorldToProj(worldSpacePos);
}

What I don’t understand is why this transformation works with a vertex position but won’t work with the value of a pixel. Here’s my pixel shader.

mat4 translation_matrix(vec3 t){
	mat4 translation_matrix = mat4( 1.0, 0.0, 0.0, t.x,
									0.0, 1.0, 0.0, t.y,
									0.0, 0.0, 1.0, t.z,
									0.0, 0.0, 0.0, 1.0);

	return translation_matrix;
}


out vec4 fragColor;
void main()
{
	vec4 ptPosition 	= texture(sTD2DInputs[0], vUV.st);
	vec4 ptTranslation 	= texture(sTD2DInputs[1], vUV.st);
	mat4 translationMatrix = translation_matrix(ptTranslation.rgb);

	vec4 newPosition = ptPosition * translationMatrix;
	
	fragColor = TDOutputSwizzle(newPosition);
}

Again, thanks for you time!

glsl-translate3.tox (3.7 KB)

GLSL uses vector on the right convention for matrix multiplication (column vectors), so you need to be doing translationMaitrx * ptPosition. What you are doing is multiplying by the matrices transpose (which is a GLSL specific behavior, as it would usually be an error in most math workflows).

Wow…thank you pointing that out. I see now that it is written in even the most basic tutorials. I’ll leave that here for future reference :

I’ve inverted the two but now, strangely, the alpha channels receives the transformation when, from my limited understanding, the red channel should be the one affected by my transformation. I’ll keep on studying this.

I understand that we are getting far from a TD specific topic, so thanks again for your help!

Hey @malcolm, following your last reply, I went back in my code to fix any [vertex * matrix] making sure that it was now [matrix * vertex], but I get unexpected results.

In a very simple vertex shader, if I follow the rule [matrix * vertex].

mat4 translation_matrix(vec3 t){
	mat4 translation = mat4(1.0, 0.0, 0.0, t.x,
							0.0, 1.0, 0.0, t.y,
							0.0, 0.0, 1.0, t.z,
							0.0, 0.0, 0.0, 1.0);
	return translation;
}

void main() 
{
	vec4 worldSpacePos = TDDeform(P);
	mat4 translate = translation_matrix(vec3(10.0, 0.0, 0.0));
	worldSpacePos = translate * worldSpacePos;
	gl_Position = TDWorldToProj(worldSpacePos);
}

this gives me this result :
glsl-trans-mv

but if I try [vertex*matrix]

worldSpacePos = worldSpacePos * translate;

I get the expected result
glsl-trans-vm

I will admit that I am bit confused by these results.

Matrices in GLSL are column-major. That means the first 4 values in your mat4 constructor at the first column, followed by the next 4. The translate should be in the last column of a transform matrix, so you want your tx ty tz to be the last values. The way you are declaring it right now you have it transposed, which is why doing a transpose multiply ends up working out.

Oh wow… thank you for that @malcolm!

mat4 translation_matrix(vec3 t){
	mat4 translation = mat4(1.0, 0.0, 0.0, 0.0,
							0.0, 1.0, 0.0, 0.0,
							0.0, 0.0, 1.0, 0.0,
							t.x, t.y, t.z, 1.0);
	return translation;
}