I am doing a bit of work on some of our HLSL shaders, trying to get them to work in SM2.0. I've nearly succeeded but one of our shaders accepts a parameter:
float alignment : VFACE
My understanding from MSDN is this is an automatic var calculated in case I need it, but it's not supported under SM2.0... so, how might I reproduce this? I'm not a shader programmer so any (pseudo) code would be really helpful. I understand what VFACE does, but not how I might calculate it myself in a pixel shader, or in a VS and pass it into the PS. Calculating it per-pixel sounds expensive so maybe someone can show a skeleton to calculate it in a VS and use it in a PS?
You can't. Because VFACE means orientation of the triangle (back or front) and the VS or PS stages have not access to the whole primitive (like in SM4/5 GS stage).
The only way is to render your geometry in two passes (one with back face culling, the other with front face culling) and pass a constant value to the shader matching VFACE meaning.
Related
Using webgl I need to perform 3 passes to render my scene. Each pass runs the same geometry and shaders but has differing values for some uniforms and textures.
I seem to have two choices. Have a single "program" and set all of the uniforms and textures for each pass. Or have 3 "programs" each containing the same shaders, and set all the necessary uniforms/shaders once per program, and then just switch programs for each pass. This means that I will do one useProgram call per pass instead of man setUniform calls for each pass.
Is this second technique likely to be faster as it will avoid very many setuniform calls, or is changing the program very expensive? I've done some trials but with the very simple geometry I have at the moment I don't see any difference in performance because setup costs overwhelm any differences.
Is there any reason to prefer one technique over the other?
Just send different values via glUniform if the shader programs are the same.
Switching between programs is generally slower than change value of uniform.
Anyway Uber Shader Program (with list of uniforms like useLighting, useAlphaMap) in most cases aren't good.
#gman
We are talking about WebGL (GLES 2.0) where we don't have UBO. (uniform buffer object)
#top
Summing try to avoid rebinding shader programs (but it's not end of the world) and don't create one uber shader!
When you have large amouts of textures to rebind, texture atlasing should be the fastest solution, so you don't need to rebind textures, don't need to rebind programs. Textures can be switched by modifying uniforms representing texCoord offsets.
Modifying such uniforms can be optimized even further:
You should consider moving frequently modified uniforms to attributes. Usualy their data source are provided using attribPointers but you can also use constant values when they are disabled. Instead of unformXXX() use attribXXX() functions to specify their constant values.
I think best example is light position. Normaly you'd have to specify uniform values for it every time light position changes to ALL programs that make use of it. In contrast, when using 'attributed' uniforms you can specify attribute value once globaly when your light moves.
-pros:
This method is best suited when you have many programs which would like to share uniforms, as we know we can't use uniform buffers in WebGL, it seams to be the only reasonable solution.
-cons:
Of course available size of such 'attributed' uniforms will be much smaller than using regular uniforms, but it still can speed things up a lot if you do it to some part of your uniforms.
I've been researching this problem I have and I can't seem to understand it well enough to solve it so I thought I might as well throw it out there and the intelligent bunch might have some ideas. :P
Basically I have been working on a iPhone project for a while where I have the luxury to use all the newest frameworks and target 5.1. So I've been using GLKit and the GLKBaseEffect which have been working just fine for me. The reason I started out with GLKBaseEffect rather then writing my own shaders is that I don't know glsl well. However the requirements have become more precise and the base effect just doesn't seem to cut it any longer.
Since I am already doing all my transforms using the base effect I would prefer if I could keep my base effect intact but add glsl-type shaders on top if that makes any sense.
My old approach look something like this (this is in a loop rendering all objects, where an object contain such things as transforms, a mesh and some other less important things for this problem, such as textures, materials and so on)
ObjectBase *obj = [ResourceManager.shared getObjectNamed:name inScene:sceneName];
GLKMatrix4 modelview = effect.transform.modelviewMatrix;
effect.transform.modelviewMatrix = GLKMatrix4Multiply(effect.transform.modelviewMatrix, obj.transform);
[effect prepareToDraw];
[obj render];
effect.transform.modelviewMatrix = modelView;
Here we fetch an object to render and transform (i.e. translate, rotate and scale) the object then we render it, where the rendering itself fetches the mesh for the object, bind the buffers and render it.
So far so good.
What I would like to do however is that during the [obj render]; call I would like the object to also do something like glUseProgram(someProgram); adding more specialized shader code.
I guess one could argue that I am trying to use the base effect for my vertex shaders and want to use "normal" shaders for my fragment shaders. At least that's what I think I want to do.
I have been trying some things.
I tried to create just the fragment shaders and glUseProgramon it, however it said that I need one vertex and one fragment shader when setting up and compiling it. I've also tried to create an empty vertex shader, which didn't turn out very well, I don't know what happens with that, but I am guessing that it overrule the base effect.
I am leaning toward, in the end, accept that it's probably best to throw out the base effects and just write my own shaders all the way. I just feel like it's a lot of work out the window, so I wanted to see how much of it I can save.
I do understand that my understanding of shaders are the part that gives me the most problems, so please be patient with that fact.
I just wanted to give my conclusions for anyone interested in them.
What I've done is actually thrown out the GLBaseEffect all together and implemented my own shader code.
My biggest problem were that I didn't really understand that it's all or nothing so to speak.
Please I might be wrong, so any corrections to where I am wrong will be greatly appreciated, I really don't want to fool anyone reading this.
What I found out during my endeavors is a couple of key-points:
GLKBaseEffect, is meant to mimic the fixed-function pipeline as seen in earlier versions of OpenGLES. Hence it is wrapping the common shader code so you don't really have to care to much about it. You will have basic functionality but it's not really very extendible.
You can still use the neat features of GLKit such as texture loader, the math library and so on if you write your own shader-code. So if you want something more complicated or customizable (bump mapping, toon shading and so on) it is totally worth rewriting the boiler-plate code needed to render properly. What I did at first was that I used the GLKBaseEffect to orient in the scene since it's quite comfortable and easy to use. However when I wanted to do more (tangent-space normal mapping) I kind of got stuck since I couldn't add to the shader program handled by the GLKBaseEffect.
Shaders are really not as scary as I always thought! I just had no idea what it really meant, and I'm surprised that I've read so much about them and still hadn't understood that basically shaders are programs REPLACING the fixed functionality pipeline. Simple as that.
That's enough rant I guess, just wanted to follow up and add what bits and pieces I've collected this far.
Just as you discovered, you can't just use a fragment shader and leave behind the vertex shader. This is because both have different tasks. Vertex shaders deal with the per-vertex aspects: calculating the vertex data, texture (uv's) etc and finally drawing the faces (triangles). Fragment shaders deal with what exactly will be drawn at each pixel on the screen (or in the viewport). When you provide only a fragment shader, you are not telling what your vertex data is, rather you are only telling OpenGL to do something on the pixels. And these pixels hold nothing/gibberish (I am not sure which) since your vertex shader did not do anything.
When using GLKEffect, a call to the [yourEffect prepareToDraw] method takes care of the shaders etc.
If you just wish to use a stock shader pair, why not use the one provided in the XCode OpenGL game template? When you run it, it has two cubes, one rendered using GLKit, and other the normal way. Though I think it will not be enough for most effects. In case you wish to know more about shaders, you can have a look at the NeHe GLSL introduction article. It is about GLSL and how you can write and use shaders in your code. You might want to have a look at Diney Bomfim's All About Shaders articles and this page.
Using GLKit is nice in most cases, since it saves you from writing lots of useless, repetitive code. For example, you do not have to go through so many image formats with different color codings and bits per pixel (per format) and all when you can just use GLKTextureLoader.
I am new to directx, but have been surprised that most examples I have seen the world matrix and view matrix are multiplied as part of the vertex shader, rather than being multiplied by the CPU and the result being passed to the shader.
For rigid objects this means you multiply the same two matrices once for every single vertex of the object. I know that the GPU can do this in parallel over a number of vertices (don't really have an idea how many), but isn't this really inefficient, or am I just missing something? I am still new and clueless.
In general, you want to do it on the CPU. However, DirectX 9 has the concept of "preshaders", which means that this multiplication will be done on the CPU up-front. This has been removed for newer APIs, but it might be very well relevant for the examples you're looking at.
Moreover, modern GPUs are extremely fast when it comes to ALU operations compared to memory access. Having a modestly complex vertex shader (with a texture fetch maybe) means that the math required to do the matrix multiplication comes for free, so the authors might have not even bothered.
Anyway, the best practice is to pre-multiply everything constant on the CPU. Same applies for moving work from the pixel shaders into the vertex shaders (if something is constant across a triangle, don't compute it per-pixel.)
Well, that doesn't sound clueless to me at all, you are absolutely right!
I don't know exactly what examples you have been looking at, but in general you'd pass precalculated matrices as much as possible, that is what semantics like WORLDVIEW (and even more appropriate for simple shaders, WORLDVIEWPROJECTION) are for.
Exceptions could be cases where the shader code needs access to the separate matrices as well (but even then I'd usually pass the combined matrices as well)... or perhaps those examples where all about illustrating matrix multiplication. :-)
I've got a question regarding ComputeShader compared to PixelShader.
I want to do some processing on a buffer, and this is possible both with a pixel shader and a compute shader, and now I wonder if there is any advantage in either over the other one, specifically when it comes to speed. I've had issues with either getting to use just 8 bit values, but I should be able to work-around that.
Every data point in the output will be calculated from using in total 8 data points surrounding it (MxN matrix), so I'd think this would be perfect for a pixel shader, since the different outputs don't influence each other at all.
But I was unable to find any benchmarkings to compare the shaders, and now I wonder which one I should aim for. Only target is the speed.
From what i understand, shaders are shaders in the sense that they are just programs run by alot of threads on data. Therefore, in general there should not be any diffrence in terms of computing power/speed doing calculations in the pixel shader as opposed to the compute shader. However..
To do calculations on the pixelshader you have to massage your data so that it looks like image data, this means you have to draw a quad first of all, but also that your output must have the 'shape' of a pixel (float4 basically). This data must then be interpreted by you app into something useful
if you're using the computeshader you can completly control the number of threads to use where as for pixel shaders they have to be valid resolutions. Also you can input and output data in any format you like and take advantage of accelerated conversion using UAVs (i think)
i'd recommend using computeshaders since they are ment for doing general purpose computation and are alot easier to work with. Your over all application will probably be faster too, even if the actual shader computation time is about the same, just because you can avoid some of the hoops you have to jump through just through to get pixel shaders to do what you want.
As a learning experience, I'm writing an Immediate mode managed DirectX 9 application.
I'm manually calculating Vertex normals across all triangles in a scene to allow smooth Gouraud shading.
This works as expected, but I'm guessing this is not the most efficient approach. Is it possible to get the GPU to do this for me?
You could in theory generate the vertex normals inside the vertex shader. That involves computation every single time you render a mesh using that shader though, so why not generate them in advance.
If you mean you want to generate them in advance of rendering, but use the GPU instead of the CPU, I would say that it's not worth the bother of speeding up something you are only going to do once. Besides, I'm not sure if DX9 has a way to get computed vertex information back from a shader (DX10 does).
All in all, the best thing to do in most cases is the traditional: compute vertex normals in the program that saves the data files that contain the meshes - do it as a pre-computation step. Usually you have them if the mesh came from a 3d package like Max or Maya, because there is artistic information in the normals, unless you know the whole mesh is supposed to be perfectly smooth (or faceted), it's not computable in the general case.