Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Alternative to Set Effect Constant Vector Element?

Author
Message
revenant chaos
Valued Member
17
Years of Service
User Offline
Joined: 21st Mar 2007
Location: Robbinsdale, MN
Posted: 27th Feb 2017 14:40 Edited at: 27th Feb 2017 14:42
Hi everyone, Over the last few months I've been developing a skeletal animation plugin for DBPro which has a few advantages over the existing solutions. It uses gpu skinning shaders to perform mesh deformation much like the fastbone shaders which are already available, however in recent testing I've found that darkshader's Set Effect Constant Vector Element command is responsible for almost 50% of the time spent in my update routine. After a bit of searching the forums I came across this DGDK thread which shows how to pass vector arrays into shaders without requiring darkshader's commands. After many wasted hours trying to interface with DBP's cSpecialEffect class within Purebasic I've given up and come here seeking assistance. I am hoping that someone who is able to compile DBPro's source would be willing to wrap the relevant ID3DXEffect member functions into commands which operate through sMesh pointers. I intend to start preparing the code for compilation as a proper DBPro plugin soon either way, but it would be awesome to have this off my mind before initial release.
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 27th Feb 2017 19:17
Sounds very useful. It would certainly simplify some of my shader demos. Might be worth asking Rudolpho.
Kuper
16
Years of Service
User Offline
Joined: 25th Feb 2008
Playing: Planescape:Torment
Posted: 27th Feb 2017 21:11 Edited at: 27th Feb 2017 21:13
Quote: "Set Effect Constant Vector Element command is responsible for almost 50% of the time spent in my update routine"

You mean that it slows FPS down? Set effect constants/vectors work very fast as I know

Quote: "skeletal animation plugin for DBPro which has a few advantages over the existing solutions"

There was Enchacement Animations plugin somewhere here on TGC
revenant chaos
Valued Member
17
Years of Service
User Offline
Joined: 21st Mar 2007
Location: Robbinsdale, MN
Posted: 28th Feb 2017 06:43
Quote: "You mean that it slows FPS down? Set effect constants/vectors work very fast as I know"
Yes, calling Set Effect Constant Vector Element to update the shader's bone matrix palette arrays takes about as long as updating an object's entire skeleton. I need to call this command 3 times per-bone per-update, and it seems that I could get a nice speed boost by writing the matrices to memory and passing a pointer into dx's SetVectorArray() method.

Quote: "There was Enchacement Animations plugin somewhere here on TGC"
Unfortunately Enhanced Animations builds upon dbpro's existing animation system, meaning it has many of the same short-comings. My plugin will support up to 80 weighted bones per mesh (uses palette of 3x4 matrices); has no limits to the number of non-weighted bones, works with the vertexdata commands, and performs full updates independent of the sync command (making it considerably faster with multi-camera setups, and can retrieve bone transforms pre-sync without workarounds).

The thing is, currently when only 1 camera is used my system is actually a bit slower than using a fastbone shader with the native commands. Adding additional renders immediately puts mine ahead, so if I can at least reduce the time spent on updating bonepalette arrays I am confident that the plugin can be faster in all occasions.
Ortu
DBPro Master
16
Years of Service
User Offline
Joined: 21st Nov 2007
Location: Austin, TX
Posted: 28th Feb 2017 18:58
I'm not familiar with dark shader, but do you have to set each vector element individually?

Can you not use the core command: set effect constant vector(effectNum, constant$, vectorNum)?

I would think that this should cut your processing down to one call per bone per update.
http://games.joshkirklin.com/sulium

A single player RPG featuring a branching, player driven storyline of meaningful choices and multiple endings alongside challenging active combat and intelligent AI.
revenant chaos
Valued Member
17
Years of Service
User Offline
Joined: 21st Mar 2007
Location: Robbinsdale, MN
Posted: 28th Feb 2017 19:47
Quote: "I'm not familiar with dark shader, but do you have to set each vector element individually?"

The command's name is a bit misleading; Set Effect Constant Vector Element is used to set float4 elements within shader arrays whereas Set Effect Constant Vector is used to set the value of individual float4 constants. The only sensible way I see to pass a large number of index-able matrices into a shader requires the use of float4 arrays.
Rudolpho
18
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 3rd Mar 2017 23:15
That sounds quite odd that that function would be that slow. I would have thought that constants were buffered internally and only updated to the GPU when next referenced after a change to the data has been recorded (this is how I handle constant buffers in my DX11 plugin), but from what you're saying it sounds like it might be pushing the constant data to the GPU (and thus potentially incurring GPU stalls where it cannot do any other work until this transfer completes) for each vector element update. If this is true that would be a most severe bottleneck indeed.

I could provide array setting functionality for constants in DBPro9Ex when I get the time.
For the record it should be technically possible to call the necessary functions directly from DBPro, using IanM's dll for calling function pointers. If you're interested in this and / or want a weekend programming project the steps would go roughly like so:

1) Call the GetObjectData() function from DBProBasic3DDebug.dll (you'll need to load it as a dll and use CALL DLL for this) to get a pointer to the raw data structure representing an object that has the target effect set. This is necessary as it appears to be the only (round-about) way to get to the effect pointer from an external source; there is no GetEffectDataPointer() or similar function exported in any of the core dll's.

2) Now you have to calculate lots of offsets to the individual data members of the sObject structure. You can find details on these in the DarkGDK headers, or the open source version of DBPro (beware that the latter is not 100% compatible with older versions due to changes to the object, as well as other structures brought about due to GameGuru development). Basically you'll want to trace the same path as Fallout used in the DarkGDK post you linked to in your opening post.

3) Once you've located it, the effect pointer points to a COM interface. You'll want to find its vtable - this is simply where the first 4 bytes pointed to by the pointer leads. The address of the SetVectorArray() function can is number 32 from the top of the zero-based vtable; this is followed by the GetVectorArray() function at index 33.

4) In order to call these functions you'll need a raw memory buffer. You can for example create a suitably sized memblock to hold all your float values; this will then act as your array. (DBPro's arrays are in fact implemented as a table of lists, which means that the array data is not guaranteed to be contiguous in memory, so you can't use an array pointer directly).

5) Once you have all this set up you can call the functions from the effect interface using IanM's CALL FUNCTION PTR function.


Happy hacking
revenant chaos
Valued Member
17
Years of Service
User Offline
Joined: 21st Mar 2007
Location: Robbinsdale, MN
Posted: 4th Mar 2017 08:25 Edited at: 4th Mar 2017 08:26
Hi Rudolpho. I appreciate your detailed response, but for the most part I was already ahead of ya. Fortunately before responding I decided to give it a go one last time and got it working I had gotten as far as accessing the sMeshShader structure, and could peek the effect's name string but for some reason could not access the cSpecialEffect class pointer which preceded it... turned out to be a structure misalignment which tells me I must be looking at outdated versions of the dbpro headers. After that was out of the way, it was smooth sailing thanks to your vtable reminder With the appropriate changes my animation library is now faster than DBPro's native library in all occasions, and now even more so than ever when multiple camera renders are required. Thanks for motivating me to give it another go!

Login to post a reply

Server time is: 2024-04-26 11:04:56
Your offset time is: 2024-04-26 11:04:56