User talk:Hvengel

From FlightGear wiki
Jump to navigation Jump to search

Spinner animation

Hi. I've duplicated the spinner for each of the stages of the propeller animation (blades, blurred blades, disk ), as each of these spins at a different rate. It's the cheapest way to solve the issue, and it avoids having extra bits of code laying around (I generally avoid having nasal involved if there's a viable solution without it). Some will argue it's a quick job in 5 lines of nasal, well 5 lines of nasal add up, and can become quite the issue as the extra-500 bears witness (it is unflyable here and elsewhere due to the low fps, as everything is waiting on the nasal scripts).

I4dnf (talk) 09:09, 11 July 2014 (UTC)

Like you I avoid Nasal if there is an XML way to handle things. With a JSBSim FDM you can do a lot of things in XML that require Nasal in a YASim aircraft and, at least for a JSBSim FDM, you should almost never need Nasal for animations unless they are VERY complex or are not FDM specific (IE. intended for use in any aircraft regardless of FDM). The K-14A gun sight reticle animations are an example of something complex enough to be beyond doing it with XML only but it is also intended to be FDM independent as well so using JSBSim to drive the animations was not an option.

Also in JSBSim you can setup XML functions specifically to drive animations. For example, I do this to throttle the gun animations as frame rates fall below certain thresholds. But I don't use any JSBSim stuff for the prop animation. When you use XML you are relegating things to either the FDM or to FG itself which will generally be more efficient and "safer" than rolling your own Nasal and much of this will actually happen in C++ space. Also if you do this using FDM XML you take this out of the main loop which is generally a good thing.

Yesterday evening I pulled the prop disk and a second copy of the spinner into a separate model and did some cleanup on the models (the blades and the disk were not running true so I fixed that issue). Looks OK.

Right now I only have two stages to the prop animation and I am trying (unsuccessfully) to use a transparency animation on the blades to simulate the blurred blades phase. In fact I have been unable to get the transparency animation working in a number of contexts with recent versions of FG and I am not sure what the issue really is (probably something I am doing). I can get things to have a fixed transparency by setting the material to a certain gamma and using a texture with a gamma but I have been unable to change the transparency at run time using the transparency or blend animation.

The other issue here is that in the blurred blade phase the blades should be darker/less transparent closer to the hub/spinner because they are traveling way slower than at the tips of the blades. A blurred blade phase specific model and texture would probably make this possible.

At this point I have more important stuff to tackle than the blurred blase phase stuff so it will have to wait until later as the prop animations are "good enough" for now.

Hvengel (talk) 16:16, 12 July 2014 (UTC)

"When you use XML you are relegating things to either the FDM or to FG itself which will generally be more efficient and "safer" than rolling your own Nasal and much of this will actually happen in C++ space. Also if you do this using FDM XML you take this out of the main loop which is generally a good thing."
This is not true – FDM is still inside the main loop (anything that accesses the property tree is inside the main loop). In fact it would be less efficient (theoretically) to put animation code into the FDM because it's updated unnecessarily – animations are only evaluated each frame. (Direct output of surface position is fine, but processing it doesn't have to be in the FDM.) It's not like adding a small Nasal operation for an animation would have any performance penalty at all – even on the most outdated hardware imaginable. But then again, it'll just be a small difference normally – hardly even 1/10th of a ms.
Emilian: while I agree that the Extra-500 is really slow for me as well, how well it performs is not relevant to this discussion. The Nasal used there is more comparable to "500+600+700+... lines of Nasal code adding up" than "5+5+5+... lines of Nasal code adding up" – because 5 lines of Nasal code takes up no time at all (unless it calls expensive functions and/or uses recursion and/or loops, which the Extra-500 certainly uses some of). The Extra-500 is really complex (as far as I understand it) and is subject to different issues, issues which don't affect small scripts (i.e. 5-liners). Some of the lack of efficiency is not even Nasal code, it's hard coded (e.g. the props.Node interface, which doesn't use cppbind and thus can create unnecessary temporary GC-able objects if used incorrectly). Some of it is the lack of efficiency in the Extra-500's code versus what being accomplished – i.e. it could be much simpler in places (and actually use MapStructure). Some of it is the positioned queries – those are not microscopic yet, but probably will be soon. Et cetera. There's different ways we could prove it's inefficient code. Nasal itself, however, is very efficient from what I've seen and simple animations are not time-wasters at all. Even 100 lines of simple Nasal animations should execute in under ~2-4ms, I would guess, on reasonably modern hardware if it doesn't use certain constructs (e.g. props.globals.getNode("").setValue/getValue, where the node isn't cached, see [1], or other GC nightmares). Even GC'ing is extremely fast on my computer :-). —Philosopher (talk) 13:55, 14 July 2014 (UTC)
Thanks, but no thanks. And btw, you might want to not get things so literally (the "5 lines of nasal" was exactly a reference to this kind of 'evangelism' going on these days with nasal, where to no matter what problem the solution is suggested as "easily done in x lines of nasal", and the extra-500 was an extreme example where that leads to). I'm sorry but I'm not going to drink your cool-aid, and if there's an alternative solution that circumvents nasal I'm going to suggest it, even if it's going to be harder/more complicated to implement, as I'm convinced it will be better performance wise.
I think some apologies towards Hvengel are in order, for abusing his talk page.
I4dnf (talk) 14:34, 14 July 2014 (UTC)

Philosopher is right, the FDM in FG doesn't run in its own thread for the time being, it's just running interleaved with a few other subsystems (e.g. AP) - but FDM computations ARE part of the main loop. At the end of the day, Nasal is just a tool - which will normally be slower than C++, but easier to use for most people. It is true that many XML constructs are usually harder to misuse compared to Nasal, simply because most XML is directly mappped to C++ constructs and loops acting there like a "state machine" that is re-evaluated for each iteration cycle.
But even the C++ code is often fairly naive and not particularly optimized, JSBSim script is fairly simple here - there's at least a dozen of possible optimizations to sneak out better performance last I checked, but it is much harder to introduce constructs that actually show up when profiling, because C++ is so much faster than Nasal obviously, and because it's not subject to GC.
The extra500 is a different matter, there are various coding constructs & patterns in use that are known to be problematic, and it's also suffering from issues that were recently discussed on the forum (e.g. callbacks gobbling up, even copies of identical callbacks running, such as callbacks running FDM-interleaved even though they shouldn't).
Overall, people still need to understand the tools they're using, especially when abstraction layers are involved - no matter if it's Nasal, XML or C++ - obviously, the latter two are usually faster, but there's lots of algorithmically-slow C++ code that doesn't need to be slow at all, it was just never optimized because it seemed "fast enough" - even though it's usually the combination of code interacting with other code that's becoming a challenge. The AI system has a ton of examples for this. I am all for favoring "faster" code, but in this instance it isn't exactly fair to blame it all on Nasal, because those performance issues are not primarily due to Nasal being slower than C++, but due to algorithmic issues, and inferior implementations. We've seen the same debate and uninformed arguments WRT using looping constructs like for/foreach/forindex in Nasal, and people were told to avoid them at all costs - despite the fact that the same problem remains once you run too many iterations of a loop in C++.
I wouldn't say that Nasal is getting a lot of support, there are still a handful of very real issues related to Nasal - but the majority of challenges stem from the fact that we have so many people using it that have zero background in coding, so they're not aware of the implications of using certain coding patterns and constructs, or what is happening under the hood.
But a few of us actually understand how to write sufficiently fast Nasal code for most cases - Thorsten is a great example for this, he's written some hand-optimized Nasal code that would often outperform existing/naive C++ implementations, but he's also religious about doing lots of testing and gathering statistics before he optimizes something.
I understand that's also the method he's using in GLSL/effects. We've offered and provided feedback regarding the Nasal/Canvas side of the extra500, and even offered to get involved to help with certain things-so far, to no avail unfortunately-and now I am frankly spending my time where feedback, help & support are actually honored. --Hooray (talk) 14:51, 14 July 2014 (UTC)

Ubershader Issues

HI, I'm the author of the ubershader and accompanying effects. I noticed on the forums that you're having some issues with it.

Could you please paste somewhere the effect file you use?

Also could you check that the respective objects are not parented to some other object (or an empty) from where they could possibly inherit effects/materials?

The flipped normal behaviour is really weird (and would suggest you have inadvertently enabled the <normalmap-dds> flag)

Also, for the uberhsader the relevant documentation is in $FG_DATA/Docs/model-combined.eff/

(If you're gonna ask why it's not on the wiki, you have already hit the main reason, bitrot, and having to duplicate maintenance efforts. And no, I don't think the wiki should be the authoritative source for documentation)


I4dnf (talk) 18:11, 3 July 2014 (UTC)

Hello Hvengel
I have/had the same problem with the EC135P2 and the Dornier 328 model slow WIP. So far I can remember one thing seems to be is the uvmapping. When two face are overlapped in the :UVmapped it seems to produce this issue. At least it is not a issue with the shader itself. More the way the model is uvmapped.
Can you send a in-sim screenshot of the faulty part and a image of the the matching uvmapping?
Btw: the main culprit is not the vertice numbers- but the objects numbers. So a, let's say 7.000.000 vertice aircraft divided into 1000 objects has a much bigger impact
as a model with twice number of vertices but divided in only 50 objects. Means: combine all meshes into one object in Blender as long you don't need to animate in any way =
One object + those objects which has to be animated (aileron, flap,...)!
--HHS (talk) 19:38, 3 July 2014 (UTC)
Yes, the UV coordinates direction needs to be consistent on the same mesh. You can have overlapping faces as long as they don't share an edge in the UV and/or they don't have one of the coordinates flipped. (i would post some screenshots if not for the innane upload wizard :( )
In the problematic example the middle face will be causing issues (it's U coordinates being flipped, and it shares the UV edge with the left face). In the problematic2 example the B1 (right) face will be causing issues, as it's V coordinates are flipped (mirrored)
UV OK1  
UV OK2  
UV Problem1  
UV Problem2  
I4dnf (talk) 10:44, 4 July 2014 (UTC)

I have very carefully gone over the three objects to make sure that the UV maps had no overlapping or 0 area faces in the UV map. In the case of the cowl I actually removed parts of it that were not part of the main exterior surface. These consisted of things like the cylindrical surfaces for the air intake holes, the edge and internal surfaces of the exhaust cutout, the internal air intake passages (behind the holes on the side of the cowl) and the front ring that is next to the spinner which are all now separate objects now. The cowl in now much simpler (still a fairly complex shape in the chin scoop area) with no folded over edges or inside surfaces.

So here are some screen shots:

Cowl UVMap
Cowl In Sim Normals Normal
Cowl In Sim Normals Flipped

These are high res screen shots (about 4.5 mega pixels each) so you should be able to see all of the necessary details. The background in the UV map screen shot is the actual texture being used. The line and hole detail in the texture was used to create the normal map.

Hvengel (talk) 18:08, 5 July 2014 (UTC) Hal

Hi, I've moved your message here to have the discussion in one place.
I took a look at the blender file. Sorry to say this but the mesh is a mess, and I suspect the somewhat flaky blender-2.6+ .ac export script is choking on it and spitting out garbage.
For example on the cowl object there are 88 n-gons (faces with 5 or more vertices). This can cause issues with the winding order (which determines the respective face/normal orientation), even more so if the script tries to be smart and split those on its own. There is a blender script that's called MeshLint and can help with checking and fixing the meshes. You can find and enable it in the addons tab of the user-settings dialog. Try first manually splitting the n-gons into tris, recalculate normals and then re export the mesh from blender, see if that helps.
I know working with booleans seems easier, but these are the hidden traps in that style of work, and you end up doing twice the work needed on the mesh to fix it up after the quick&dirty boolean operations.
And that's a shame given the amount of work you obviously already put into it.
I4dnf (talk) 19:01, 5 July 2014 (UTC) Hvengel (talk) 08:22, 6 July 2014 (UTC)
Got the MeshLint add in and went through the three meshes that are having issues and removed all n-gons. Kind of time consuming but no too bad. After all I only have to do one side then mirror it to get the other side. After removing all n-gons I then had Blender recalculate the normals and exported the model. The issue is still there.

As a side note the last objects I discovered that had this issue are the exhaust covers. In these I cut the holes by hand since I couldn't get the boolean operation to work. I also cut the exhaust cutouts in the cowl by hand and at one point these were nice clean looking cutouts. But when i did the boolean operation to do the 32 1 inch holes for the filtered air intake Blender decided to mess with the exhaust cutouts. But at that point I don't think there where any n-gons. But the normals problem was still there even before I tried to clean things up. I spent some time cleaning up the air intake holes and this is where the n-gons came from.

I just had a close look at the exhaust covers and the one I looked at did have two n-gons. I fixed those then flipped back to to normal and recalculated the normals and exported it. Opening the .ac file in FG everything looked sort of OK except the inside of the mesh was bright and reflective. This object has the normals of the front pointing outward and the normals of the back areas are pointing inward and these parts of the object are textured black. But the back was acting like it's normals were flipped (IE. the back was black - showing the texture- on the outside when it should be showing this on the inside). Turns out that this is acting just like the cowl and wing fairings. So is unrelated to using a Boolean operation.

Thinking things through a little it appears that all of the objects that are showing up black in the FGRUN 3D preview when the normals are the correct direction are objects where I did cutouts of some sort either by hand or using a Boolean operation in Blender. For most of these I did NOT use a boolean operation.

The export script definitely has issues but, at least with simpler models, works in most cases. The way it behaves when something is not textured is very flawed in that it just fails with more or less hidden and very cryptic error messages. I do UI work for a living and I would never let something that poorly designed out into the wild. If it has such obvious UI issues who knows what kind of issues exist in the actually functionality.

Hvengel (talk) 08:22, 6 July 2014 (UTC)

Most Likely Fix

Pfewww that was a hard one, and well hidden. The perils of transforming stuff in object mode in blender ;)
All these problem objects have negative scaling on at least one of the axes, and when the export script applies the transform, the normals get flipped. You'll notice it right away if you apply the transform first. Which you should do, to all objects, right away, to avoid this cropping up again. Fuselage isn't affected since it's not scaled. Examples below:
Btw, a couple of issues that I noticed that will affect performance: all your meshes have double-sided faces in blender, make them single-sided; your textures have the alpha channel left in, this will affect performance with shaders disabled and will cause funny rendering bugs in Rembrandt. Remove the alpha channel for the textures that are applied to opaque objects.
HTH, and cheers,
I4dnf (talk) 16:06, 6 July 2014 (UTC)