Maths Surface Code Error

Hello.

The code below is supposed to create a surface looking something like this from a plane grid:

Unfortunately, what I get is just a big disk. Can anyone see any obvious errors in my code?


/////////////////////
////  CONSTANTS  ////
/////////////////////

#define TWOPI 6.28318531
#define PI    3.14159265

////////////////////
////  CONTROLS  ////
////////////////////

// Pre-transform matrix
// Since QC won't display mat4 variables as inputs, I'm using 4 separate
// vec4s (one for each column of the transformation matrix).
uniform vec4 TT_0;
uniform vec4 TT_1;
uniform vec4 TT_2;
uniform vec4 TT_3;

// Select algorithm
uniform int Select;

// Tweakables not always active (depends on algorithm)
uniform float A;
uniform float B;
uniform float C;
uniform float D;

// Light position
uniform vec3 LightPosition;

// Final scale adjust
uniform float ScaleAdj;

// Passes shading to Fragment Shader
varying float colpos;

/////////////////////////
////    FUNCTIONS    ////  
/////////////////////////

//// COSH Function (Hyperbolic Cosine)  
float cosh(float val)  
{  
    float tmp = exp(val);  
    float cosH = (tmp + 1.0 / tmp) / 2.0;  
    return cosH;  
}  
  
// TANH Function (Hyperbolic Tangent)  
float tanh(float val)  
{  
    float tmp = exp(val);  
    float tanH = (tmp - 1.0 / tmp) / (tmp + 1.0 / tmp);  
    return tanH;  
}  
  
// SINH Function (Hyperbolic Sine)  
float sinh(float val)  
{  
    float tmp = exp(val);  
    float sinH = (tmp - 1.0 / tmp) / 2.0;  
    return sinH;  
} 

/////////////////////////
////    MAIN LOOP    ////  
/////////////////////////

void main()
{
	// Assemble pre-transform matrix
	mat4 TT = mat4(TT_0,TT_1,TT_2,TT_3);
	
	// Placeholder variables
	float a = A;
	float b = B;
	float c = C;
	float d = D;
	
	// XYZ vertex coordinates (multiplied by pre-transform matrix)
	vec3 vertex = (gl_Vertex * TT).xyz;

	////////////////////////////////////	
	////////	  43 Henneburg     ////////
	////////////////////////////////////
	
	float u = vertex.x * 2.0;
	float v = vertex.y * 2.0;
	
	vertex.x = 2.0 * sinh(u) * cos(v) - 2.0 * sinh(3.0*u) * cos(3.0*v)/3.0;
	vertex.y = 2.0 * sinh(u) * sin(v) + 2.0 * sinh(3.0*u) * sin(3.0*v)/3.0;
	vertex.z = 2.0 * cosh(2.0*u) * cos(2.0*v);
		
	// Final scale adjustment
	mat4 finalScale =  mat4(ScaleAdj,0.0,0.0,0.0,
						0.0,ScaleAdj,0.0,0.0,
						0.0,0.0,ScaleAdj,0.0,
						0.0,0.0,0.0,1.0);
	vertex = vec3(vec4(vertex,1.0) * finalScale);
		
	// Shading calculations
	colpos = length(vertex.xyz + LightPosition);
	
	// Outputs	
	gl_Position = gl_ModelViewProjectionMatrix * vec4(vertex,1.0);
	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}

alx
http://machinesdontcare.wordpress.com

  • Are you sure your TT matrix needs to be right-multipled to vertex? In OpenGL matrices are normally left-multiplied:
    vec3 vertex = (TT * gl_Vertex).xyz; // ???

  • The whole final scale matrix is pure waste of time. Just scale the vertex.xyz with ScaleAdj directly.

  • Not sure about the hyperbolic functions, but never write “/ 2.0”, use “* 0.5” instead for performance.

  • u and v are in radians?

Hi Relic, thanks for getting back to me.

  • The TT matrix seems to work OK as it is. I’ll bear that in mind for the future though.

  • I’ve replaces the second matrix transform as you suggest. Thanks for pointing that out.

  • I’ll bear this on mind, also.

  • U and V aren’t in Radians, they’re the initial X-Y values of a plane mesh.

Thanks for all the tips- sooo much to learn…

alx

The 4 vertices of your matrix are probably stored in column-major order of the matrix. I assume that’s why you’re performing a post-multiplication, right?

To get the same result as the image you posted, you should make sure that your u-v-values are in the range [-pi,pi].

Hi -NiCo-

the initial TT matrix is constructed from 4x vec4s, one for each column. This is simply because the program I’m embedding the shader in doesn’t allow mat4s to be passed directly into the shader.

re the U-V values; maybe this is the problem. I will revisit the code.

Cheers,

alx

That’s exactly what I was referring to by column-major order. You could just as easily have passed the separate rows in a vector and used TTgl_Vertex instead of passing the separate columns and using gl_VertexTT :wink:

I just tested the range using octave

octave:1> u = -pi:0.1:pi;
octave:2> v = -pi:0.1:pi;
octave:3> [U,V] = meshgrid(u,v);
octave:4> X = 2.*sinh(U).*cos(V) - 2.sinh(3U).cos(3V)./3;
octave:5> Y = 2.*sinh(U).*sin(V) + 2.sinh(3U).sin(3V)./3;
octave:6> Z = 2.cos(2U).cos(2V);
octave:7> mesh(X,Y,Z)

Here’s the output:

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.