HLSL to GLSL (bit off-topic, I'm afraid)

Hiya,

I wonder if any of you HLSL gurus could give me some pointers on converting some of the vvvv HLSL user shaders to GLSL?

I’ve managed to convert a pixel-shader based effect (Ernst Hot’s Gradients shader), but I’m drawing a blank with any of the vertex-based shaders.

I think part of the problem is to do with the matrices
float4x4 tW: WORLD;
float4x4 tV: VIEW;
float4x4 tP: PROJECTION;
float4x4 tVP: VIEWPROJECTION;
float4x4 tWVP: WORLDVIEWPROJECTION;
float4x4 tWV: WORLDVIEW;

I don’t think there are any direct GLSL equivalents to most of these, and I’m not sure how to this.

Anyone out there have any experience of working with both HLSL and GLSL?

Cheers guys,

alx
video effects blog http://machinesdontcare.wordpress.com

hello, theses are the transform matrices of the geometry. basically you only need the world, view and the projection matrix. the others are just multiplications of them.
the world matrix transforms the geometry from the object space to the world space. the view matrix then transforms the geometry into the camera space and the projection matrix into the screen space.
there are surely equivalents in GLSL, as it is a common concept for 3d graphics rendering.

not into GLSL but the big lettered words in our effects are called semantics in the directx effects-framework-world.

i think such semantics don’t exist in glsl, but googling suggests that glsl has built-in uniforms like:
gl_ModelViewMatrix
gl_ModelViewProjectionMatrix

that would correspond…

so maybe something like
float4x4 tWVP = ModelViewProjectionMatrix;
would do?!

Hi tonfilm, joreg,

thanks for getting back to me!
I think I have to do a lot more reading!

tonfilm, I posted a similar query on the the OpenGL GLSL messageboard a while back. and got this response:

“OpenGL has no concept of a “view” matrix. The local-to-world and world-to-view transforms are always considered one matrix: the GL_MODELVIEW matrix.
As such, there is no equivalent to WORLD or VIEW. Or VIEWPROJECTION. Only WORLDVIEW and WORLDVIEWPROJECTION (and PROJECTION) have OpenGL equivalents.”

Do you think this means it is possible to obtain all the necessary information from GLSL’s builtin matrices?

I’ll keep reading the OpenGL Red Book, and see if things become a little clearer, on the GLSL side, anyway.

joreg, you’re right: GLSL has builtin uniforms, but you’re also able to pass arbitrary values between Vertex and Fragment (Pixel) shaders, so the vs2ps structure and the necessity to use fixed names to pass values between the two isn’t there. I’ve come across the ModelViewProjectionMatrix before, I’m just not sure how this relates to HLSL.

Sorry for wandering even further off-topic, but I wonder if I could pick both your brains on another issue?

I’ve been messing around with an edited version of a GLSL shader that uses noise to shift the vertices of a sphere. I was hoping to be able to make areas of the texture transparent, to create the effects of separate bands.
Here’s an example.

The problem is, I get all sorts of z-fighting issues with the transparent areas. I was just wondering if you had experienced similar issues with your shaders, and if so, have come up with any workarounds.
I’m assuming that many of the shaders that appear to produce many separate bands actually use transparent areas in the texture to simulate this effect as I do in mine, but I might be completely wrong there.

Thanks again guys!

alx

Hi,
About your 'transparent areas", I would say its quite simple in vvvv and hlsl without a texture (because of z-sorting issues as you said) but with a second transformation happening before the functions…This allows to deform and spread the original and undistorted objet as you want…Have a look at the suparformulas or surfaces shader for an example…but i don’t really know how this should work in glsl…

Hi Desaxismundi,

thanks for getting back to me. I’ve been admiring your work on Flickr…
:)

I’ve actually been looking at the Superformula shaders, with a view to seeing if I could get them to work in GLSL. I managed to convert all the functions apart from the main Vertex shader loop, which I can’t get to work because of the whole transform matrices issue that started this thread. I’ve been ‘working blind’ however, in the sense that I know a little about the GLSL and HLSL languages, in terms of syntax, but the mathematics is a bit ‘over my head’, sadly.

I must admit, I’m a little confused about how you ‘deform and spread’ the geometry. Do you mean you are able to take a Sphere mesh (for example), and remove parts of the geometry, turning the single object into a number of separate band-like meshes? Sorry for my ignorance, but being able to visualise in my head what’s going on conceptually will help me work out what’s going on mathematically.

Cheers,

alx

Well, first thank you. To achieve something like seen on your web page, let say we are using a grid (as mesh input) spreaded ten times with Y scale set to a low value…so we are working with multiple objects…this is just an example…vvvv allows to work with spreads which means applying some transforms on multiple objects at the sames time…don’t know how Quartz is working for such things…I’m not so clear so i did a little patch to explain myself…but sounds that you’re under macOS, so i hope u’ll see it someday :)

2Transforms.zip (3.2 kB)

Hi again Desaxismundi,

thanks very much for getting back to me again.

I’m not familiar with the idea of spreads, and there’s no direct equivalent in Quartz Composer, I don’t think. It is possible to create iterative loops, however, and it may also be possible to embed a GLSL patch inside an Iterator, to create the initial geometry. It’s something I’ve been meaning to try, actually, so now might be the time!

I’m able to boot into Windows, as I have an Intel-based Mac. I need to finish installing XP and VVVV though, as I had to do a system-reinstall recently. I’ll get it all setup, and look at your FX in vvvv. Sorry, I’m a complete beginner when it comes to HLSL and VVVV- is there anything I need to patch up to the FX in VVVV in order to get it to work?

Thanks again!

alx

Hi again Desaxismundi,

I’ve got vvvv up-and-running under XP on my MacBook Pro now, and I managed to open your example file. Sorry for my misunderstanding above- I thought the files you attached were just the shaders, and didn’t notice one of them was a vvvv project file.

Ah… OK. So you’re not actually slicing a sphere into strips, you’re actually creating rings from a flat grid, then copying them, then the sphere function bends them around into rings. Or am I wrong?

I must admit to still being a little confused though, as to the actual mechanism by with the spreads work. For example, I see a 4x4 matrix variable named TT, which is fed from one of the spreads. I don’t see any reference to TT anywhere else in the shader code, though. Hmm… still a bit confused here, sadly.

If I could use GLSL patches inside an Iterator onject, I might be able to do something similar in Quartz Composer. Alternatively, it might be posiible to use a single shader, and simply discard some of the vertices, leaving gaps in the mesh. I know it’s possible to discard vertices using GLSL. Don’t know if this actually leaves a hole in the resulting mesh though.

The whole spreads thing looks really powerful. I’m definitely intrigued, though I don’t really understand how it works yet.

Thanks a lot for taking the time to explain things for me, and for making the example setup for me. I will study it further and see what I can learn. I seem to remember seeing a tutorial on spreads on this site somewhere, so I’ll have a look at that too. I may well be that there’s no way to emulate this in Quartz Composer, but I’d love to know one way or the other!

Thanks again,

alx

PS
there are some new screenshots on my blog. I’ve managed to partially get around the z-fighting issue by changing the blend mode of the mesh to Additive. Doesn’t solve the problem, really, but gives a nice ‘glowy’ look to the whole thing which is quite nice in its way. Wish I could get rid of the jaggies around the edge of each mesh though…

Update!

Good news and bad:
It doesn’t look like it’s possible to nest one GLSL patch inside another, so I can’t see a way to use one GLSL patch to generate the geometry for another shader to distort. Hovever, I have managed to create a stripey sphere by using the discard keyword to ‘throw away’ pixels pixels in the texture. discarded pixels, unlike merely transparent ones, don’t seem to cause z-fighting issues. The downside is, I’ve lost any antialiasing, since they’re either there, or not there (and nothing inbetween).

There are probably ways around this, however. Maybe fading the edges to transparency just before the cutoff where pixels are discarded would help a little, or maybe it needs some kind of smoothing post-processing…

Hmm… possibilities…

Thanks again. Off to bed now,

alx

Ok, good to know…about the TT transform pin…if you look closer, it appears briefly at the begining of the vertex shader part : mul(PosO, TT); (as simple as that)
so, before any transformations inside the vertex progam, deformed vertices are applied through the TT pin via spreads…

regards****

Ah… now I understand…

The spread passes an array to the shader. Each item in the array is a float4x4 list representing the corners of each mesh copy. The list is iterated through, creating and positioning a copy of the mesh for each iteration. It all makes sense now.

Thanks so much for explaining this to me- I’d never have guessed what was going on otherwise.

I think an Iterator can be used in Quartz Composer to do a similar kind of thing. I’ve used Iterators quite a lot, actually, to duplicate and position objects in space.

This is an example, and also this video clip (Flash format).

Thanks once again for all your help and advice.
Keep up the great work!!

alx

Hiya,

I wonder if any of you HLSL gurus could give me some pointers on converting some of the vvvv HLSL user shaders to GLSL?

I’ve managed to convert a pixel-shader based effect (Ernst Hot’s Gradients shader), but I’m drawing a blank with any of the vertex-based shaders.

I think part of the problem is to do with the matrices
float4x4 tW: WORLD;
float4x4 tV: VIEW;
float4x4 tP: PROJECTION;
float4x4 tVP: VIEWPROJECTION;
float4x4 tWVP: WORLDVIEWPROJECTION;
float4x4 tWV: WORLDVIEW;

I don’t think there are any direct GLSL equivalents to most of these, and I’m not sure how to this.

Anyone out there have any experience of working with both HLSL and GLSL?

Cheers guys,

alx
video effects blog http://machinesdontcare.wordpress.com

hello! i tried to translate some of the surface shaders into glsl as well. i failed especially with the superformula, because the shader code exceeded the max lines of my gfx card. hlsl is more or less cg so you can import it for example to openGL based jitter from cycling74. please see the attached code for a spherical harmonic. the formula is actually in the vertex shader, the pixelshader is the modification of some kind of lattice shader. instead of the semantics of hlsl i used with the help of a specialist the semantics of glsl. of course you need to bind your parameters to your particular shader. glsl knows a lot of built in variables as stated in the appendix of the orange book.

spreading works. in fact it is done outside the shader. its the multiplication of the grid, which is fed into the shader. you can deform these grids as well.

the whole thing is grim. better to start with vertex shaders and use passthrough.glsl shaders als pixelshaders first.

best thing is to use vvvv!

allthebest,

dd

vd.math2.jxs (3.8 kB)

Hi Sinus,

thanks for getting back to me. I’m glad I’m not the only person struggling with HLSL to GLSL conversion.

Is that file you sent a Max/Jitter file, by any chance? Unfortunately, I don’t have Jitter, so I can’t try it myself. I’d be really interested to see the shader code though. Could you possibly post the vertex and pixel shader code as text here (or send me a private message if you prefer). I actually use a Mac-only application called Quartz Composer, which is a modular video effects programming environment, a little like VVVV. It’s generally not as flexible as VVVV, but it can use GLSL shaders.

As for spreading; I can use looping in QC to create and position a number of meshes in 3D space, but the problem I’m having is that the shader seems to use local (model?) vertex coordinates for all the meshes, so the same transformations are applied to all the meshes, rather than the vertices’ positions in World space being used. The problem is, I don’t know what mechanism Quartz Composer uses to position the grids in 3D space, so I don’t know if what I want to do is possible. The VVVV file Desaxismundi very kindly put together for me used several separate meshes, which are transformed into a single 3D form. When I try to run the same code in QC and GLSL, I just get a number of separate individual forms. Annoying…

I’ve been reading the OpenGL Red Book, and while I’m learning a little, I haven’t been able to answer my question yet…

Anyway, cheers again for getting back to me,

Regards,

alx

hi toneburst! this is a jitter shader file. it´s just the code. you can open it with any text editor browser etc.
in fact you can download all the glsl shaders from jitter/cycling74 from their site. max/msp/jitter demo expires after 4 weeks, but you can still use the shader files!
good luck! varying vec4 gl_MultiCoordare calling!

dd

Hi again sinus,

doh! I should have tried opening it in a text-editor!
I will give it a go right now!

Thanks again,

alx

Hi again sinus,

I’ve managed to get a single instance of your Spherical Harmonics shader working in Quartz Composer, but couldn’t get any equivalent of the spreading to work. It’s quite frustrating, actually. I can apply the same transform to several different meshes inside the shader, but I just get exactly the same transformation being applied to all the meshes. The effect is the same as if I’d rendered one mesh to an image, and simply copied it, offset it and overlaid it on top of the original- not what I’m after at all!

I think the issue here is that vvvv is able to run the same shader iteratively and composite the resulting geometry together in 3D space (which is my current understanding of what the spreading function does).

Quartz Composer on the other hand, is not able to do this. My problem was my assumption that a spreaded shader in vvvv only runs once per frame, and is fed a number of separate meshes by the spread function, which it processes all in the same pass. In fact, the shader is run once for each mesh, and each mesh is translated to a different position according to the spread values, before it’s vertices are moved around.

Or… am I completely wrong?

alx

that is correct.

Thanks for that tonfilm.

Good to know I’m finally beginning to understand what’s going on (though depressing to know I can’t emulate it with the tools at my disposal).

Incidentally, I’m a big fan of your work in vvvv tonfilm- very impressive stuff!

Cheers,

alx

Hi again sinus.

I’ve just been experimenting with converting some of desaxismundi’s maths surfaces to GLSL, with some success (finally). I’m using the latest shader set he posted, the maths surfaces without normal calculation. Thought I’d start with something relatively simple (though the maths is still way beyond my puny Earthling mind).

I’ve managed to implement the pre-transform matrix (though poor variable support in Quartz Composer forces me to use 4x vec4s instead of one mat4 for the pre-transform input). I’ve so far converted all except one of the formulae in the Surfaces_02.fx shader. This is the vertex shader code, in case you’re interested:

{CODE(ln=>1)}/////////////////////
//// 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;

// Passes shading to Fragment Shader
varying float colpos;

////////////////////////////
//// VERTEX FUNCTIONS ////
////////////////////////////

vec3 SteinbachScrew(vec3 vertex)
{
// Tweakable parameter a

float u = vertex.x  * 8.0;
float v = vertex.y  * 12.5;

vertex.x = a * (u) * cos(v);
vertex.y = a * (u) * sin(v);
vertex.z = a * (v) * cos(u);

return vertex;

}

vec3 Sine(vec3 vertex)
{
// Tweakable parameter a

float u = vertex.x  * TWOPI;
float v =  vertex.y  * TWOPI;

vertex.x = a * sin(u);
vertex.y = a * sin(v);
vertex.z = a * sin(u+v);

return vertex;

}

vec3 Eight(vec3 vertex)
{
float u = vertex.x * 2.0TWOPI;
float v = vertex.y * 2.0
PI/2.0;

vertex.x = cos(u) * sin(2.0*v);
vertex.y = sin(u) * sin(2.0*v);
vertex.z = sin(v);

return vertex;

}

vec3 Corkscrew(vec3 vertex)
{
// Tweakable parameters a, b

float u = vertex.x  * TWOPI;
float v = vertex.y  * 2.0*TWOPI;
	
vertex.x = a * cos(u) * cos(v);
vertex.y = a * sin(u) * cos(v);
vertex.z = a * sin(v) + b * u;

return vertex;

}

vec3 Roman2Boy(vec3 vertex)
{
// Tweakable parameter a

float u = vertex.x  * PI;
float v = vertex.y  * PI;

vertex.x = (pow(2.0,0.5) * cos(2.0*u) * pow(cos(v),2.0) + cos(u) * sin(2.0*v)) / (2.0 - a*pow(2.0,0.5) * sin(3.0*u) * sin(2.0*v));
vertex.y = (pow(2.0,0.5) * sin(2.0*u) * pow(cos(v),2.0) + sin(u) * sin(2.0*v)) / (2.0 - a*pow(2.0,0.5) * sin(3.0*u) * sin(2.0*v));
vertex.z = (3.0*pow(cos(v),2.0)) / (2.0 - a*pow(2.0,0.5) * sin(3.0*u) * sin(2.0*v));

return vertex;

}

vec3 TwistedPipe(vec3 vertex)
{
float u = vertex.x * TWOPI;
float v = vertex.y * TWOPI;

vertex.x = cos(v) * (2.0 + cos(u)) / sqrt(1.0 + pow(sin(v),2.0));
vertex.y = sin(v + TWOPI/3.0) * (2.0 + cos(u + TWOPI/3.0)) / sqrt(1.0 + pow(sin(v),2.0));
vertex.z = sin(v - TWOPI/3.0) * (2.0 + cos(u - TWOPI/3.0)) / sqrt(1.0 + pow(sin(v),2.0));

return vertex;

}

vec3 BohemianDome(vec3 vertex)
{
// Tweakable parameters a, b and c

float u = vertex.x  * TWOPI;
float v = vertex.y  * TWOPI;

vertex.x = a * cos(u);
vertex.y = a * sin(u) + b * cos(v);
vertex.z = c * sin(v);

return vertex;

}

/* NEEDS GLSL tanh (hyperbolic tangent) /cosh (hyperbolic cosine) code
vec3 Folium(vec3 vertex)
{
float u = vertex.x * TWOPI;
float v = vertex.y * TWOPI;

vertex.x = cos(u) * (2.0 * v/ PI - tanh(v));
vertex.y = cos(u + TWOPI / 3.0) / cosh(v);
vertex.z = cos(u - TWOPI / 3.0) / cosh(v);

return vertex;

}*/

vec3 AstroidalEllipsoid(vec3 vertex)
{
float u = vertex.x * PI;
float v = vertex.y * TWOPI;

vertex.x = pow(cos(u)*cos(v),3.0);
vertex.y = pow(sin(u)*cos(v),3.0);
vertex.z = pow(sin(v),3.0);

return vertex;

}

vec3 TriaxialHexatorus(vec3 vertex)
{
float u = vertex.x * 2.0PI;
float v = vertex.y * 2.0
TWOPI;

vertex.x = sin(u) / (sqrt(2.0) + cos(v));
vertex.y = sin(u + TWOPI/3.0) / (sqrt(2.0) + cos(v + TWOPI/3.0));
vertex.z = cos(u - TWOPI/3.0) / (sqrt(2.0) + cos(v - TWOPI/3.0));

return vertex;

}

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

void main()
{
// Assemble pre-transform matrix
mat4 TT = mat4(TT_0,TT_1,TT_2,TT_3);

// XYZ vertex coordinates (multiplied by pre-transform matrix)
vec3 vertex = (gl_Vertex * TT).xyz;

// Select algorithm
if(Select == 0)
	vertex = SteinbachScrew(vertex);
if(Select == 1)
	vertex = Sine(vertex);
if(Select == 2)
	vertex = Eight(vertex);
if(Select == 3)
	vertex = Corkscrew(vertex);
if(Select == 4)
	vertex = Roman2Boy(vertex);
if(Select == 5)
	vertex = TwistedPipe(vertex);
if(Select == 6)
	vertex = BohemianDome(vertex);
if(Select == 7)
	vertex = AstroidalEllipsoid(vertex);
if(Select == 8)
	vertex = TriaxialHexatorus(vertex);

// Shading calculations
colpos = length(vertex.xyz + LightPosition);

// Outputs	
gl_Position = gl_ModelViewProjectionMatrix * vec4(vertex,1.0);
gl_TexCoord[0](0) = gl_TextureMatrix[0](0) * gl_MultiTexCoord0;

}^

You can see I’ve commented-out the Folium code, as there’s no direct GLSL equivalent to HLSL tanh and cosh functions. I’m sure they’re relatively easy to emulate anyway, but it wasn’t really necessary to have all the code working for the purposes of this experiment.

I’m really going to have to get my head around the way transformation matrices work, as this is definitely the key to getting interesting results from these shaders!

Incidentally, I’ve also been getting some nice results from a 2D version of the Superformula I’ve been tinkering with

No idea if my method is the ‘correct’ to go about implementing this kind of algorithm, but the result looks nice, anyway…

alx