Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 28 Feb 2011
Online Last Active Today, 02:50 AM

#5162218 Why does this matrix multiplication order matter?

Posted by Bacterius on 22 June 2014 - 07:48 PM

You mean if I concatenate the projection, view, and model matrix on the CPU side once before sending it to the shader?


It shouldn't make a difference (in terms of outcome) though it would probably be faster since you'd only be doing one matrix multiplication per shader invocation instead of three. But it might work around the bug.




All my other (4 or so) shaders are working with the first method without the bug while the other 3 must be written without brackets as said.


Are they written exactly the same? How are the matrix variables (projection, model, etc..) defined?


I've noted strange bugs in GLSL compilers before (including ambiguous and sometimes plain contradictory behaviour between two or more compilers) but, well, matrix multiplication is supposed to be associative. So either there's something in how the matrices are defined that is wrong but used to work by accident before, or (more likely) it's a compiler bug...


yes, first formula is more effective since you transform vector 3 times by a matrix, while second formula performs 2 matrix multiplications and than transforms a vector. I stress again that second formula performs reverse order of transformations, and it results in the same thing since matricies are (diagnosticly) transposed.


Matrix multiplication is associative. For any three matrices A, B, C, of any dimension (where multiplication is defined), A * (B * C) = (A * B) * C. There should be no difference in the result. The order of transformations is the same, this is not about commutativity.

#5162073 Best way to remove a substring from a C string?

Posted by Bacterius on 22 June 2014 - 06:33 AM


Also if you implement it manually make sure you validate your bounds, that is:

if ((b < a) || (b > strlen(str))))    /* abort! */
Otherwise you're just setting yourself up for scribbling all over your stack or heap.
Shouldn't the sanity checks be like:
len = strlen(str);
if ( (!len) || (b <= a) || (a >= len) ) {... abort}
if (b > len) b = len;



Depends how you want to use your function. I personally prefer to not allow nonsensical input at all, thus if b is beyond the string, I would reject it. If you prefer to clamp it to the string's length instead like some string functions do, that's fine too, as long as you document that behaviour. If you don't want to allow a == b, that's fine as well. And of course you should reject null char* pointers, forgot that one (though it is obvious). Notice that !((b < a) || (b > len)) implies len > 0 (or a = b = 0) since a and b are unsigned.

#5162058 Best way to remove a substring from a C string?

Posted by Bacterius on 22 June 2014 - 05:43 AM

Also if you implement it manually make sure you validate your bounds, that is:

if ((b < a) || (b > strlen(str))))
    /* abort! */

Otherwise you're just setting yourself up for scribbling all over your stack or heap.

#5162038 Why do we need to iterate data structures as they are already in RAM

Posted by Bacterius on 22 June 2014 - 04:31 AM


Iteration means repeating something, usually refers to executing the body of a loop repeatedly (because it is a loop). It doesn't mean executing an algorithm. And a map data structure doesn't need to be implemented as a tree.

A loop is an algorithm too. Not very complex but it describes how something has to be done.


I dont said that the map is implemented in a tree. But even the traversal of a tree is done in steps that are done the same way in each step, so it is an iteration anyways you use a loop inside or recursive call to the traversal function.

Maps maybe implemented as hashtables. But even there you only get a good guess where to start the search, that afterwards is iterated through a collection of data to find the right one.



But it is not true. There are data structures which can perform constant time random access, notably arrays as mentioned earlier in the thread. To look up an element in the array from its position (index), you take the base address of the array, add to it the index of the element to be accessed multiplied by the element size in bytes, and that gives you the address of the element you are looking for, which you can then read. Directly. If you want to argue that this process consists of multiple steps and is implemented in assembly as a sequence of a handful of instructions and is thus a form of "iteration", you are free to do so, and you will have successfully redefined iteration to something different than what it means to every other programmer on the planet, and nobody will understand you.

#5162030 Why do we need to iterate data structures as they are already in RAM

Posted by Bacterius on 22 June 2014 - 03:53 AM


RAM has nothing to do with iteration, or vice-versa.

Iteration is simply one of the many algorithms which may or may not be required for a specific task in a program. For your tree-item example, the program would most likely use a map, which is a data structure optimised for quick searches: each tree item gets a unique identifier, and that identifier can be directly translated to the item's memory address, without any iteration involved.

Even a map iterates through a tree. As I said before. Iteration is done somewhere but mostly hidden behind some function or encapsulated in a class/template or however you name it.


For my understanding iteration is the step by step walkthrough an organizational unit, map list queue whatever.



Iteration means repeating something, usually refers to executing the body of a loop repeatedly (because it is a loop). It doesn't mean executing an algorithm. And a map data structure doesn't need to be implemented as a tree.

#5162012 Why do we need to iterate data structures as they are already in RAM

Posted by Bacterius on 22 June 2014 - 12:49 AM

It depends on the data structure... for an array you can work out the memory address the data is located at by simple arithmetic and then look it that up in the array which does not require iteration, but if you have a simple linked list then you do have to search for the data you need because you can't just instantly "jump" anywhere in the linked list, you have to walk the list (through the "next" pointers, i.e. from node to node).


The property you are looking for is called "random access" and not all data structures offer it.

#5161698 lazy shading

Posted by Bacterius on 20 June 2014 - 06:37 AM

Shading is done after clipping. There is literally no point in shading pixels [that the player is supposed to see] which will not be drawn on screen, so they aren't. This is done automatically by the GPU hardware. It should not be too hard to modify your rasterizer to take this into account when shading, I think, it's a fairly basic (and natural) optimization.

#5161623 float or double depth buffer?

Posted by Bacterius on 19 June 2014 - 09:12 PM

I'm getting similar results to everyone else, 13ms to 45ms and averaging 25ms roughly (2nd generation i5 at 3.7GHz), single-threaded at 550x400 resolution (the default). Lots of artifacts at close range. It's pretty slow in fullscreen mode, which is to be expected for a software renderer, however I am seeing a lot of screen tearing - are you displaying each rendered scanline on the fly? Perhaps double-buffering could help with that, and might also simplify your pipeline.

#5161395 How to install latest SharpDX from GitRepository.

Posted by Bacterius on 18 June 2014 - 07:33 PM

I did build it successfully from source. So just copying the bin folder is enough then. I wasn't sure because I've read that nuget is being used and I thought that maybe nuget was going to become the only way to install it properly. But if i can just copy the bin folder, than that's ok.



Nuget is just a tool integrated into the IDE that lets you manage dependencies easier (automatically downloads assemblies and adds them to your references so you don't have to set it up yourself). You don't have to use it, for most libraries (SharpDX included) all you need is to add the managed DLL(s) to your project references and you're good to go.

#5160474 Getting Plane Vertices

Posted by Bacterius on 14 June 2014 - 05:17 AM

A plane is by definition infinitely large, so it has no "vertices". I guess you could analytically project the plane to clip space, and then draw the resulting vertices without any transformation matrix (since they are already transformed) but that's probably not the best way to solve whatever your problem is. So, how large do you need the quad to be?

#5160386 Bell's theorem: simulating spooky action at distance of Quantum Mechanics

Posted by Bacterius on 13 June 2014 - 05:48 PM


Is it apparent the OP here has absolutely no idea of quantum mechanics what-so-ever. I'm very much unsurprised that people on physics forums ignored your arguments Humbleteleskop!


One one hand you have spoky magic of QM for which there is no explanation or understanding, and on the other you have clasical mechanics which you can simulate and see with your own eyes it's all simply a matter of how the odds go, naturally. Believe what you will.



You do know that a lot of our modern technology depends on quantum mechanics in one way or the other, right? Nanotechnology such as modern processors could not work without an understanding of quantum tunnelling, so the computer you are typing this post on is a (successful) product of the (successful) research that's gone into quantum mechanics. Precise timekeeping depends on quantum mechanics and the theory of relativity. Some medical scan technologies rely on an understanding of quantum mechanics to give accurate results, for instance. You and I live in a quantum-mechanical world - literally.


So allow me to flip your argument around: quantum mechanics has been very successful in predicting small-scale phenomena and giving scientists an understanding of how particles behave at this scale. It allowed teams of engineers to build devices which could not have even been conceived a few decades earlier. Every time I look at a computer or pull out my phone or use a GPS, that's a very real and tangible outcome of quantum mechanics. Seems to work fine, wouldn't you agree? Now what does your "experiment" tell us, that scientists were in fact completely wrong, and that the whole theory can be disproved by a layman experiment and is therefore bogus? (and as I understand it Bell's theorem is kind of the heart of quantum mechanics - if it is shown to be incorrect, the entire theory falls apart).


On one hand we have your "theory", which just claims all our modern technology works on fairy dust with no explanation or understanding behind them, and also offers no alternative whatsoever, on the other hand we have quantum mechanics, developed over decades of work by many of the brightest scientists of all time, and incredibly sophisticated technology that exists and works today, in the real world. What do you honestly expect people to think? If you truly had something worth considering you would be discussing it with actual scientists and presenting conferences about your ideas, not making crackpot threads on a game development website. Please. You're not the first crank on the internet and you won't be the last, and the reason nobody listens to you is not because of a planetwide conspiracy to "cover up the truth", it's just because you are making no sense and you don't even realize it. Now, you are free to keep rambling on - it's your life to waste - but perhaps this forum is not the best place to do so, as Bell's theorem (or crackpot theories thereof) has, as far as I know, absolutely nothing to do with game programming, or even programming in general.

#5160038 Help with the math on this?

Posted by Bacterius on 12 June 2014 - 07:19 AM

I agree with Diego that it's.. kind of a stretch to call this linear interpolation. It's just a simple complement, and just happens to be a special case of linear interpolation with a = 1, b = 0 (and probably a special case of plenty of other transforms). But anyway it's good to have a reference to it since most likely MARS_999 will need it soon wink.png

#5159956 Bell's theorem: simulating spooky action at distance of Quantum Mechanics

Posted by Bacterius on 12 June 2014 - 12:45 AM

You're obviously misinterpreting Bell's theorem, because it's obvious you can write a program that approximates any probability distribution (and I don't know anything about quantum mechanics, but even that is clear to me). You do sound like a crank, though, especially reading through that physicsforums thread, so I'll pass.

#5159681 What happens if I don't deallocate dynamic memory on application exit?

Posted by Bacterius on 11 June 2014 - 12:51 AM

Yes, any sane operating system will free up all the memory your process is currently using (as well as things like sockets, file handles, and so on, in general) upon shutdown anyway. There are many opinions on whether it makes sense to clean up on shutdown under that assumption, a few thoughts are below:


- if you ever want to take your program and refactor it into an independent module or library which may not live in its own process, then you will be glad you wrote some cleanup code, because this time the OS won't be there to do it for you (probably the most important reason)


- on the other hand, if you have very complex datastructures with lots of independent blocks of allocated memory floating around, it may take a while for your program to get around to deallocating them all the usual way (think of those games that take 10-15 seconds to close), whereas the OS itself just sees a big block of virtual memory and can just deallocate it all in one shot, this is mitigated by proper memory allocation practices, i.e. using the right allocator and not allocating memory like a chain smoker goes through cigarettes, but may nevertheless be a concern


- and as bioglaze said above, if your memory contains sensitive information, you would do well to get rid of that yourself rather than relying on the OS to do it (any modern OS will always wipe the contents of a newly allocated memory page per-process, so that a process doesn't see what an old process previously wrote somewhere in memory, but that might not happen for a while)


Also, if your destructor has observable side effects, then not calling delete may result in undefined behaviour (I'm not comfortable enough with C++ to tell whether it is for sure, maybe someone else can answer that, but you should probably check).

#5159427 cosine term in rendering equation

Posted by Bacterius on 09 June 2014 - 11:08 PM

Samith, in the ideal mirror case, I am certain that you had the right idea when you said it should be a delta function. That is the only way that your BRDF will integrate to 1. I suppose in code, this can only be approximated by having your BRDF equal 1/ΔΩ where ΔΩ is whatever step size you're using in your integration.


Yep, the BRDF is a delta function (in two dimensions), usually though in code it is handled specially, i.e. the (unique) reflected ray is calculated analytically rather than integrating the BRDF (sampling techniques tend to break down when confronted with a delta distribution) or, alternatively, define "ideal mirror" == "extremely shiny surface" so that it's not quite a delta function but is close enough, without requiring special handling. Depends on your needs. But yeah you don't sample a BRDF at uniform intervals in general, it's too expensive.


As for the cosine term confusion, remember that the BRDF essentially says "hey, such and such amount of energy is falling on my differential surface from direction L, how much of that is reflected into direction V?" and so (thinking of it as a function) converts irradiance from L to radiance into V. Now you're not given the irradiance from L, you're only given radiance from L. But you know the angle L makes with the surface normal (theta) and irradiance is equal to radiance multiplied by the cosine of the angle (e.g. grazing angle = zero irradiance, no matter how much energy is being beamed parallel to the surface, and normal incidence = maximum irradiance). That's what the cosine term in the rendering equation is doing! The Li * cos(theta) term is actually your irradiance from L, you multiply this by the BRDF to obtain radiance into V, and integrating this over the unit sphere or hemisphere gives you the total radiance into V taking into account every light source or reflector in the world. By reciprocity you can also do it backwards, etc...


So you only need a single cosine term, because that's how the BRDF is defined, now since the BRDF converts irradiance into radiance it probably has to take into account dot(N, V), and many do in some way, e.g. Cook-Torrance, by dividing by dot(N, V) since radiance is defined as watts/square meter/steradian, so the smaller the solid angle into which the light is emitted (the smaller dot(N, V)) the larger the radiance becomes (the energy is "concentrated" into a small solid angle). But the ideal diffuser doesn't have to, because that's what an ideal diffuser is: it reflects with constant radiance, so its BRDF should be constant... for radiance to be constant. The viewer's position is irrelevant.


When the light finally hits the sensor, you don't want to use irradiance as a final "pixel color" or anything, because, of course, irradiance is the amount of energy falling onto a differential cell of the sensor, and this amount of energy is proportional to the incident angle of the light falling onto that cell. So you actually want to use radiance, and so there is no need to consider the angle made by the light with the surface normal of the sensor or screen or whatever. Yeah, it's quite confusing with all the different terms and units being thrown around (sometimes in conflicting ways by different people) and there are various interpretations that are equally valid but seem quite different, but I think it makes sense.