Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 02 Oct 2013
Offline Last Active Feb 05 2016 02:05 PM

#5136181 Help with lighting options

Posted by TheComet on 03 March 2014 - 03:14 PM

Okay, upon closer inspection, I understand why the tangent transformation matrix is being used in the pixel shader. It's because there really isn't any other way to do it.


If you did the transformation in the vertex shader, you'd be limited to the number of texcoord channels, but by moving it to the pixel shader, you can go way over the 8-light-limit. You're just trading that off for speed, because for every single pixel on the screen you're doing light_count+1 number of transforms into tangent space.


My educated guess is that the slowdown has something to do with that transformation matrix.


The way I see it, you have two options:

  1. You could consider multipass lighting. Basically, the pixel shader is called once for every light in your scene, and you blend them all together. It's very speedy because no state changes are involved.
  2. You could optimise the crap out of the current shader, and cross your fingers in the hopes of it being a little bit faster.

If you choose number 1), I need to know something: Is it possible to use for-loops inside a technique?

#5136038 Help with lighting options

Posted by TheComet on 03 March 2014 - 03:25 AM

I see a few problems with this shader.


  • The TBN matrix is calculated and used in the pixel shader?! That makes zero sense, and is a slowdown in performance. You should never be doing transformations in pixel shaders. It's enough to do the necessary transformations in the vertex shader and pass what's really required to the pixel shader, since the rasteriser does the necessary interpolations. So: Don't pass the binormal, normal, and tangent to the pixel shader. Instead, construct your TBN matrix in the vertex shader and transform the necessary vectors required for lighting in the vertex shader, and then only output what the pixel shader needs.
  • You are unnecessarily sampling twice from the normal map. Sampling textures is an expensive operation.
  • The input datatype for your pixel shader is VS_OUTPUT. This means the rasteriser is forced to unnecessarily interpolate registers it doesn't really need (POSITION for instance).
  • On some cards, using integers for for-loops is a huge slowdown. I've observed this before on my laptop when writing a fractal shader. The solution was to use floats (you might want to consider using float16 to save space and computational power).
  • You're always allocating space for 16 lights, even though you might only be using 1. This seems inefficient to me.

You might also want to consider using a lower shader model as well. None of the commands in your shader require shader model 3.0.

#5135415 How can i convert texture formats?

Posted by TheComet on 28 February 2014 - 11:32 AM

I'm in no way a whizz in Java, but maybe this will help you:


#5135108 does a dll much differ to a lib?

Posted by TheComet on 27 February 2014 - 11:53 AM

Read this



#5134981 C++ Constructors vs. Init() Functions

Posted by TheComet on 27 February 2014 - 03:36 AM

For large/complex professional game engines, this commonly includes:

don't use the standard new/delete/malloc/free (use some engine-specific replacement / wrapper),
don't use std containers (as they will call new, and custom allocator mechanisms are broken),
don't use exceptions (as writing to satisfy the "strict exception safety" guarantee is hard in C++, there's a performance impact, and some gaming platforms may not even support them),
don't use RTTI or dynamic_cast,

and sometimes includes (these used to be common 10 years ago, but not so much today).

don't use anything in std,
don't use templates.

But that's just C without the ++, what's the point of having all of these fancy features if you can't use them? I'd also think that writing your own containers is more error prone. Then again, I was never affiliated with the gaming industry, I'm sure these decisions are for the best.

#5134728 name mangling..

Posted by TheComet on 26 February 2014 - 06:08 AM

I'm desperately trying to understand what you're trying to ask... Could you repeat that?


Are you asking why they didn't just use the function signature instead of a mangled name?

#5134409 Is there a way to make text progressively appear as typed out on screen?

Posted by TheComet on 25 February 2014 - 07:37 AM

The answer heavily depends on what your programming language is (Java I presume), and what graphics library you're using, but it basically comes down to this: Make a class to encapsulate the "target" string and all of the logic required to "type" out the string. I'd probably have a variable that counts upwards whenever some update() method is called, and use that to progressively append the next character to an output string.


This gives you a basis to also add fancy particle effects or whatever you plan on doing in the future.

#5134391 disasembly of some function

Posted by TheComet on 25 February 2014 - 05:35 AM

The @16? This is a byproduct of C++ called name mangling. In C++ you can have several functions with the same name, which only differ in the number of parameters (or in the case of methods in the classes they belong to). In order to distinguish those, the compiler adds some magic numbers and characters to the function names, usually based on

the number and type of parameters. The specifics however are different for each compiler.

This is incorrect, see my post above.

#5134388 disasembly of some function

Posted by TheComet on 25 February 2014 - 05:14 AM

I'll try and answer what I know.


i do not understand this 0040218B values (what it really stands for? some previous examples seem to suggest that it is real process memory adress where this code will be laying in 9after loading to ram) but i am not sure

On Windows, the address 0x00401000 is a pretty standard address for the main entry point of your program (if no executable packing or other obfuscation has been done). It is however not global to the system, it is relative to the starting point of your program space allocated by the underlying OS, and unsurprisingly starts at 0x00000000.


also what means @16 at the and of _MessageBoxA@16

It is a calling convention of Window's STDCALL. The function being called is always name decorated with a leading underscore, followed by an @, and then the number (in bytes) of arguments passed on the stack. This number will always be a multiple of 4 on a 32-bit aligned machine.


In your example, @16 means that 4 arguments are passed to _MessageBox on the stack. If you were to disassemble the function _MessageBox, you will find the return statement:

ret 16

which will pop the 4 arguments off the stack again before returning.


As to the other questions, I can only make educated guesses.

#5134234 C++ IDEs for Linux

Posted by TheComet on 24 February 2014 - 04:42 PM

I like Visual Studio on Windows, but I actually prefer not using an IDE on Linux.


I like VIM + CMAKE + make at console in a Linux environment, but admittedly using VIM is somewhat self-justifying as an exercise for me to learn VIM, which itself is a useful skill (its nice to know one good non-wysiwyg text editor because you're basically guaranteed to have access to it on any system you can imagine, even minimalist linux systems and often even embedded systems like routers, and/or when you SSH into a remote system). Once you configure CMAKE and generate a make file for your system, building from the shell is as simple as 'make build'. I like VIM as my non-wysiwyg editor, but some people like Emacs, its one of the great nerd holy wars.


If I wanted to be a bit easier on myself, I'd probably substitute SlickEdit in for VIM. It's got powerful shortcuts like VIM/Emacs, and is Linux/Mac/Windows cross-platform, but also offers a better wysiwyg/GUI experience than gVIM.

I've always wondered, how do you effectively debug a program on the command line? Do you really use GDB on the command line? I can't imagine doing that without an IDE to show me variable watches, stack, memory dump, and disassembly.

#5134087 C++ IDEs for Linux

Posted by TheComet on 24 February 2014 - 06:21 AM

KDevelop looks beautiful! This is the first time I've heard of it. Tell me, is it as "bloated" as Eclipse?

#5134025 C++ IDEs for Linux

Posted by TheComet on 24 February 2014 - 01:24 AM

I use Code::Blocks. The IDE on its own is already pretty nice, and the community has produced some awesome third-party plugins.

#5133855 data compression

Posted by TheComet on 23 February 2014 - 08:23 AM


I don't think that's a good word, it should be "replace"

replaced by a repetition

If that was in response to what I said, then no. JPEG compression does destroy data, because it makes approximations in such a way that it is impossible to fully reconstruct the original data.


My take on what OP is trying to say is that it takes time to decompress data, but in return you can reduce the amount of data.

#5133819 data compression

Posted by TheComet on 23 February 2014 - 05:17 AM

JPEG compression destroys data because it is a lossy compression algorithm

#5133289 Multi-material texture?

Posted by TheComet on 21 February 2014 - 10:33 AM

Something like this will do it:

// Pixel Shaders.

float4 PS_AllLighting(VS_OUTPUT IN) : COLOR

float3 t = normalize(IN.tangent);
float3 b = normalize(IN.bitangent);
float3 n = normalize(IN.normal);

float3x3 tbnMatrix = float3x3(t.x, b.x, n.x,
     t.y, b.y, n.y,
     t.z, b.z, n.z);
float3 v = normalize(mul(cameraPos - IN.worldPos, tbnMatrix));
float3 l = float3(0.0f, 0.0f, 0.0f);
float3 h = float3(0.0f, 0.0f, 0.0f);

float atten = 0.0f;
float nDotL = 0.0f;
float nDotH = 0.0f;
float power = 0.0f;

float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f);

n = normalize(tex2D(normalMap, IN.texCoord).rgb * 2.0f - 1.0f);

    // sample color map
   float4 colorMap = tex2D(colorMap, IN.texCoord);  // TC Edit

    for (int i = 0; i < numLights; ++i)
        float len=length(lights[i].pos - IN.worldPos);
        if (len<lights[i].radius*1.25f){
            if (lights[i].type==0){
                atten = 1.0f;
                l = mul((lights[i].pos - IN.worldPos) / lights[i].radius, tbnMatrix);
             atten = saturate(1.0f - dot(l, l));
            l = normalize(l);
            if (lights[i].type==2) {
                float2 cosAngles = cos(float2(lights[i].spotOuterCone, lights[i].spotInnerCone) * 0.5f);
                float3 dl=mul(lights[i].dir,tbnMatrix);
                float spotDot = dot(-l, normalize(dl));
                float spotEffect = smoothstep(cosAngles[0], cosAngles[1], spotDot);

                atten *= spotEffect;
            h = normalize(l + v);

            nDotL = saturate(dot(n, l));
            nDotH = saturate(dot(n, h));
            power = (nDotL == 0.0f) ? 0.0f : pow(nDotH, material.shininess * colorMap.w);  // TC Edit

            color += ((material.diffuse * lights[i].diffuse )+
                (lights[i].specular * power ))* atten;

color += material.ambient * globalAmbient +material.emissive;

     return color * colorMap;  // TC Edit

An alpha value of 0.0 means no specular lighting, an alpha value of 1.0 means full specular lighting.


You *might* have to change this:

return color * colorMap;

To the following,

return color * float4(colorMap.xyz, 1.0f);

if the render target makes use of the alpha channel.