Message 1 of 6
Plugin Material extending DirectX Shader issues
Not applicable
04-22-2010
03:22 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Morning all,
I'm actually a C++ programmer who's new to MaxScript, so go easy on me :)
Using Max 2010 SP1, I'm using MaxScript to define a UI for a complex shader by declaring a Material plugin which extends DirectX_9_Shader. I control the shader underneath through the delegate keyword. When editing a scene, the whole thing is working very well indeed. The issues I have are with behaviour when reloading a scene, which I've so far been unable to solve.
Firstly, if I close the material editor then reload my scene, everything works fine. If, however, I reload the scene whilst keeping the material editor open, I get a large number of errors in the format Unknown property: "X" in undefined, where X is the name of a bool value in the delegate controlling a feature. My UI components are initialised using delegate values, so it appears that the delegate shader goes out of scope during the load process. Is there any way I can disable or delay the initialisation of the UI until the delegate is back in scope? I've tried using the loading keyword without success, and also experimented with setting flags in the on Load and on PostLoad handlers too, but this doesn't seem to do the trick. An absolute last resort might be to close the material editor when opening a scene, but it seems that the earliest event I can catch is the onLoad handler, and adding a matEditor.Close() call here doesn't solve the problem. I've started looking into the possibility of registering a callback, which I think may do the trick, but if anyone can suggest a neater solution I'd be very grateful :)
Secondly, the shader allows the artist to select three point lights for lighting visualisation inside Max. I use the following code for getting the data for each light in the shader...
I can't find a way of automatically connecting parameters to the attenuation values of the lights, so instead I have a timer which is called once a second, which copies the light parameters into the relevant shader properties. For neatness (and until I've got everything working correctly), when the artist selects a new light for one of the three slots, I simply store the light's index, then reassign the light pos as part of the timer tick code...
This all works fine whilst editing the scene. However, if you reload the scene with the material editor closed (which is currently necessary because of the first issue!), all three lights are set to the first light index. When you open the material editor and the timer code above is called, the lights are assigned correctly. This seems like designed behaviour, so I copied the tick code into the on PostLoad handler, which I verified is called on load even if the material editor is closed. I also verified that the light indices are valid at this point - they are identical to the indices used when the material editor is subsequently opened and the lighting corrects itself. The problem is that this approach does not fix the problem! Is the shader fx file compiled after (or even during) the on PostLoad handler that would result in the loss of these properties being set? I have also tried forcing a redraw of the scene, but the problem persists.
Apologies for the length (and complexity) of this post! Any advice would be very much appreciated!
Joel.
I'm actually a C++ programmer who's new to MaxScript, so go easy on me :)
Using Max 2010 SP1, I'm using MaxScript to define a UI for a complex shader by declaring a Material plugin which extends DirectX_9_Shader. I control the shader underneath through the delegate keyword. When editing a scene, the whole thing is working very well indeed. The issues I have are with behaviour when reloading a scene, which I've so far been unable to solve.
Firstly, if I close the material editor then reload my scene, everything works fine. If, however, I reload the scene whilst keeping the material editor open, I get a large number of errors in the format Unknown property: "X" in undefined, where X is the name of a bool value in the delegate controlling a feature. My UI components are initialised using delegate values, so it appears that the delegate shader goes out of scope during the load process. Is there any way I can disable or delay the initialisation of the UI until the delegate is back in scope? I've tried using the loading keyword without success, and also experimented with setting flags in the on Load and on PostLoad handlers too, but this doesn't seem to do the trick. An absolute last resort might be to close the material editor when opening a scene, but it seems that the earliest event I can catch is the onLoad handler, and adding a matEditor.Close() call here doesn't solve the problem. I've started looking into the possibility of registering a callback, which I think may do the trick, but if anyone can suggest a neater solution I'd be very grateful :)
Secondly, the shader allows the artist to select three point lights for lighting visualisation inside Max. I use the following code for getting the data for each light in the shader...
float4 PosLightPos0 : POSITION <string UIName = "Point light 1"; string Object = "PointLight"; string Space = "World"; int refID = 0; > = {1.0f, 0.0f, 0.0f, 1.0f};
float4 PosLightCol0 : LIGHTCOLOR <int LightRef = 0; >;
float4 PosLightDir0 : DIRECTION <int LightRef = 0; >;
I can't find a way of automatically connecting parameters to the attenuation values of the lights, so instead I have a timer which is called once a second, which copies the light parameters into the relevant shader properties. For neatness (and until I've got everything working correctly), when the artist selects a new light for one of the three slots, I simply store the light's index, then reassign the light pos as part of the timer tick code...
on light_clock tick do
(
if m_light0 > 0 and not $Lights == undefined then
(
delegate.PosLightPos0 = m_light0
light0.caption = $Lights.name
delegate.PosLightAttnStart0 = $Lights.farAttenStart
delegate.PosLightAttnEnd0 = $Lights.farAttenEnd
)
.. repeated for other two lights
)
This all works fine whilst editing the scene. However, if you reload the scene with the material editor closed (which is currently necessary because of the first issue!), all three lights are set to the first light index. When you open the material editor and the timer code above is called, the lights are assigned correctly. This seems like designed behaviour, so I copied the tick code into the on PostLoad handler, which I verified is called on load even if the material editor is closed. I also verified that the light indices are valid at this point - they are identical to the indices used when the material editor is subsequently opened and the lighting corrects itself. The problem is that this approach does not fix the problem! Is the shader fx file compiled after (or even during) the on PostLoad handler that would result in the loss of these properties being set? I have also tried forcing a redraw of the scene, but the problem persists.
Apologies for the length (and complexity) of this post! Any advice would be very much appreciated!
Joel.