Game Development Community

3D Lighting DTS models [solved!]

by Mathias Kahl · in Torque X 3D · 07/29/2009 (6:11 am) · 23 replies

Hello!

I just started trying to work with Torque X a few days ago.
Currently my only valuable source of information is John's book.

Currently I'm trying to get lighting to work with my DTS models.
I'm loading the player model as described in the book. At first I create a template:

private static void CreateTemplate()
        {
            Template = new TorqueObject();

            Template.Name = "Basic Creep Template";
            Template.IsTemplate = true;

            // Die Repräsentation im 3D-Raum erstellen 
            T3DSceneComponent scene = new T3DSceneComponent();
            scene.SceneGroup = Template.Name;
            scene.Position = new Vector3(1020, 1020, 350);
            Template.Components.AddComponent(scene);

            T3DTSRenderComponent dts = new T3DTSRenderComponent();
            dts.ShapeName = @"data/Static Models/Player/Ork/ork2.dts";

            dts.SceneGroupName = Template.Name;
            Template.Components.AddComponent(dts);           
            
            // Physikalische Eigenschaften            
            RigidCollisionManager rigidManager = TorqueObjectDatabase.Instance.FindObject<RigidCollisionManager>("RigidManager");
            T3DRigidComponent physics = new T3DRigidComponent();
            physics.SceneGroupName = Template.Name;
            physics.GravityScale = 1.0f;
            physics.Mass = 30.0f;

            physics.RigidManager = rigidManager;
            physics.CollisionBody.AddCollisionShape(new CollisionBoxShape());
            Template.Components.AddComponent(physics);

            // Den Objekttypen registrieren
            TorqueObjectType typeCreep = TorqueObjectDatabase.Instance.GetObjectType("Creep");
            Template.ObjectType += typeCreep;

            // Das Template ins W&ouml;rterbuch eintragen
            TorqueObjectDatabase.Instance.Dictionary.SetValue<TorqueObject>(Template, Template.Name, null);            
        }

Secondly I spawn it into my scene:
TorqueObject torqueObject = (TorqueObject)Template.CloneT();
            torqueObject.Components.FindComponent<T3DSceneComponent>().Position = pos;
            TorqueObjectDatabase.Instance.Register(torqueObject);

That works. However the model isn't lit (using my own Model created in Milkshape 3D):
bunkernetz.de/~bc/screenshots/erstes-level-2.jpg
Also an other model, which came with Torque Constructor isn't lit (also not the DTS terrain model below):
bunkernetz.de/~bc/screenshots/erstes-level.jpg
That's how I add the light to the scene (according to John's book):
// Beleuchtung
            TorqueObject lightSceneObject = new TorqueObject();
            T3DSceneComponent componentScene = new T3DSceneComponent();
            componentScene.Position = new Vector3(1050, 1050, 400);
            componentScene.SceneGroup = "LightObject";
            lightSceneObject.Components.AddComponent(componentScene);

            DirectionalLight light = new DirectionalLight();
            light.ConstantAttenuation = 1.0f;
            light.LinearAttenuation = 0.0f;
            light.AmbientColor = new Vector3(0.5f, 0.4f, 0.4f);
            light.DiffuseColor = new Vector3(0.75f, 0.75f, 0.75f);
            light.Direction = new Vector3(0, -1, -1);

            T3DLightComponent componentLight = new T3DLightComponent();
            componentLight.SceneGroupName = "LightObject";
            componentLight.IsEnabled = true;
            componentLight.LightList.Add(light);
            lightSceneObject.Components.AddComponent(componentLight);

            TorqueObjectDatabase.Instance.Register(lightSceneObject);

Can someone tell me how to do it right, please? Help would be much appreciated.

About the author

I'm a student of Computer Science (Freie Universität in Berlin, Germany). Currently I'm working on a multiplayer strategy/action game based on Torque X.

Page «Previous 1 2
#1
07/29/2009 (7:23 am)
It looks like you are only missing a light material for your textures of your model. For a texture to be effected by light it needs a light materiel associated with it, and in TorqueX it is done per texture not per model.
Hope this helps.

Alan
Perfect Dork Studios
#2
07/29/2009 (7:34 am)
Thanks very much for your answer, Alan!

Unfortunately I don't know how to associate a light material to a texture. Can you tell me how to do this?

I can create a lighting material and then use it for a sphere that I create in C#, but I simply haven't found out yet how to apply such a lighting material to a existing DTS model.
#3
07/29/2009 (11:31 am)
When i get home i can post more with a example, but for now you should look in chapter 5 around page 351 in john's book there should be an example.
#4
07/29/2009 (12:22 pm)
Thanks for your help! The only thing I found in the book is how to apply a material to a 2D sprite. However, nothing is said about 3D DTS shapes. :-\ I'm playing around with T3DTSRenderComponent.Shape.MaterialList, but not successfully so far.
#5
07/31/2009 (5:08 pm)
By the way I just tried using a FXB file and see what happend:
bunkernetz.de/~bc/screenshots/erstes-level-3.jpg
And I did nothing differently at all:
TorqueObject obj = new TorqueObject();
            obj.Name = "Test Ork";

            T3DSceneComponent scene = new T3DSceneComponent();
            scene.SceneGroup = "Test Ork";
            scene.Position = new Vector3(1024, 1024, 300);
            scene.Rotation = Quaternion.CreateFromYawPitchRoll(0, MathHelper.ToRadians(90), 0);
            obj.Components.AddComponent(scene);

            T3DXNARenderComponent ork = new T3DXNARenderComponent();
            ork.Filename = @"data/Static Models/Player/Ork/ork.FBX";
            ork.SceneGroupName = obj.Name;
            obj.Components.AddComponent(ork);

            TorqueObjectDatabase.Instance.Register(obj);

How come the FXB model is lit but the DTS model isn't? That's really weird. May it be that there is no lighting information in the DTS model?
#6
07/31/2009 (5:50 pm)
Yeah, John's book is missing that detal about the .fbx files. The .fbx file are passed through the XNA content pipeline and receive lighting detail directly from XNA. The .dts shapes are rendered by Torque X shaders and require something that you might be missing: a lighing material definition. Add the following to your levelData.txscene file:

<MyMaterial type="GarageGames.Torque.Materials.LightingMaterial" name="MyMaterial">
<NameMapping>datamodelsMyPlayer</NameMapping>
<TextureFilename>datamodelsMyPlayer</TextureFilename>
<NormalMapFilename>datamodelsMyNormalMapFile</NormalMapFilename>
<SpecularPower>35.0</SpecularPower>
<SpecularIntensity>0.75</SpecularIntensity>
<LightingMode>PerPixel</LightingMode>
</MyMaterial>

If you don't have your very own normal map, just use this simple one.

www.envygames.com/share/BlankNormal.png
http://www.envygames.com/share/BlankNormal.png

John K.
www.envygames.com
#7
08/01/2009 (1:21 pm)
Thank you very much for your answer!

It seems like I did something wrong when adding the Lighting Material, since my model still isn't lit. :-(

Here is my complete scene file:
<?xml version="1.0" encoding="UTF-8"?>
<TorqueSceneData>
  <Version>1.0</Version>
  <SceneData>
    <ObjectTypeDeclaration>
      <LockTypes>false</LockTypes>
      <ObjectTypes />
    </ObjectTypeDeclaration>
    <SceneGraph type="GarageGames.Torque.T3D.T3DSceneGraph" name="SceneGraph" />
  </SceneData>
  <Materials>
    
    <LightingMaterial type="GarageGames.Torque.Materials.LightingMaterial" name="orkhaut">
      <NameMapping>orkhaut</NameMapping>
      <TextureFilename>data/Static Models/Player/Ork/orkhaut.jpg</TextureFilename>
      <NormalMapFilename>data/Static Models/Player/Ork/BlankNormal.png</NormalMapFilename>
      <SpecularPower>35.0</SpecularPower>
      <SpecularIntensity>0.75</SpecularIntensity>
      <LightingMode>PerPixel</LightingMode>
      <EffectFilename>LightingEffect3D</EffectFilename>
    </LightingMaterial>
    
  </Materials>
  <Objects>
    <Sky type="GarageGames.Torque.T3D.Sky" name="Sky">
      <SkyDistance>3</SkyDistance>
      <Sides>
        <string>data\skies\front</string>
        <string>data\skies\right</string>
        <string>data\skies\back</string>
        <string>data\skies\left</string>
        <string>data\skies\top</string>
        <string>data\skies\bottom</string>
      </Sides>
      <RenderBottom>true</RenderBottom>
    </Sky>
    <RigidCollisionManager type="GarageGames.Torque.T3D.RigidCollision.RigidCollisionManager" name="RigidManager">
      <MaxUpdateSetp>0.01</MaxUpdateSetp>
    </RigidCollisionManager>
  </Objects>
</TorqueSceneData>

And that's how I added the model and the light:
TorqueObject obj = new TorqueObject();
            obj.Name = "Ork";

            T3DSceneComponent scene = new T3DSceneComponent();
            scene.Position = new Vector3(1030, 1030, 315);
            scene.SceneGroup = obj.Name;
            scene.Scale = new Vector3(5, 5, 5);
            obj.Components.AddComponent(scene);

            T3DTSRenderComponent model = new T3DTSRenderComponent();
            model.ShapeName = @"data/Static Models/Player/Ork/ork3.dts";
            model.SceneGroupName = obj.Name;
            obj.Components.AddComponent(model);

            TorqueObjectDatabase.Instance.Register(obj);

TorqueObject obj = new TorqueObject();
            obj.Name = "Sun";

            T3DSceneComponent scene = new T3DSceneComponent();
            scene.SceneGroup = "Sun";
            scene.Position = new Vector3(1050, 1050, 400);
            obj.Components.AddComponent(scene);

            DirectionalLight sun = new DirectionalLight();
            sun.ConstantAttenuation = 1.0f;
            sun.LinearAttenuation = 0.0f;
            sun.AmbientColor = new Vector3(0.7f, 0.4f, 0.4f);
            sun.DiffuseColor = new Vector3(0.75f, 0.75f, 0.75f);
            sun.Direction = Vector3.Down;

            T3DLightComponent light = new T3DLightComponent();
            light.SceneGroupName = obj.Name;
            light.IsEnabled = true;
            light.LightList.Add(sun);
            obj.Components.AddComponent(light);

            TorqueObjectDatabase.Instance.Register(obj);

And that's how it looks:
bunkernetz.de/~bc/screenshots/cb-screenshot-001.jpg
The ones that are lit are FBX models, the one that isn't is the DTS version of the model. The environment is a static geometry component from a FBX file. (By the way the shades on the unlit dts model are caused by the texture, it's not shadow)

Maybe I did something wrong in the Lighting Material definition?

#8
08/01/2009 (3:43 pm)
Try removing the file extensions from the image files. Also, make sure the image files are included in your Content project. I think everything else looks fine. Do you want to email me your model? I can take a look. If so, my email address is jkanalakis @ envygames.com

John K.
www.envygames.com
#9
08/01/2009 (8:19 pm)
How are you creating your model? I have created some models in 3DS 2009 and it seems like possibly the DTS exporter doesn't pay attention to the normal maps. I have even looked at the models in the Torque Show Tool and I don't get my normal maps. Something is definitely weird somewhere.

It seems really obtuse that even the show tool will not show the normal maps on the model. From what I can see you have to create a material, and apply it to your material used for the skin.
#10
08/02/2009 (3:00 am)
I created the model in Milkshape 3D. Meanwhile I also tried a model created in 3DS MAX 2009, which also isn't lit. Just now I also downloaded some dts model from the internet, which also isn't lit:
bunkernetz.de/~bc/screenshots/cb-screenshot-003.jpg
The house is a dts, which isn't lit (the shadows are built into the texture). The "detailed" ork left came with Torque Constructor (Reference Shapes / player.dts). And the light green one is still my cheap ork dts model.

So I conclude, that this isn't a problem of the models, but of their integration. Even though there's a chance that none of these models has normals included into them, but that would really suprise me.

Also in Torque ShowTool the model is displayed correctly:
bunkernetz.de/~bc/screenshots/cb-screenshot-004.jpg
Has anyone a working example (visual studio project solution) of a simple scene with a dts model that is lit? Maybe I could compare it to my setup to find the mistake here.

By the way, my current scene:
bunkernetz.de/~bc/upload/levelData.xml

And that's how I include the models:
private void AddTest()
        {
            TorqueObject obj = new TorqueObject();
            obj.Name = "Ork";

            T3DSceneComponent scene = new T3DSceneComponent();
            scene.Position = new Vector3(1030, 1030, 315);
            scene.SceneGroup = obj.Name;
            scene.Scale = new Vector3(5, 5, 5);
            obj.Components.AddComponent(scene);

            T3DTSRenderComponent model = new T3DTSRenderComponent();
            model.ShapeName = @"data/Static Models/Player/Ork/ork3.dts";
            model.SceneGroupName = obj.Name;
            obj.Components.AddComponent(model);

            TorqueObjectDatabase.Instance.Register(obj);
        }

        private void AddTest2()
        {
            TorqueObject obj = new TorqueObject();
            obj.Name = "Ork2";

            T3DSceneComponent scene = new T3DSceneComponent();
            scene.Position = new Vector3(1035, 1030, 315);
            scene.SceneGroup = obj.Name;
            scene.Scale = new Vector3(5, 5, 5);
            obj.Components.AddComponent(scene);

            T3DTSRenderComponent model = new T3DTSRenderComponent();
            model.ShapeName = @"data/Static Models/Player/player.dts";
            model.SceneGroupName = obj.Name;
            obj.Components.AddComponent(model);

            TorqueObjectDatabase.Instance.Register(obj);
        }

        private void AddTest3()
        {
            TorqueObject obj = new TorqueObject();
            obj.Name = "Haus";

            T3DSceneComponent scene = new T3DSceneComponent();
            scene.Position = new Vector3(1000, 950, 315);
            scene.SceneGroup = obj.Name;
            scene.Scale = new Vector3(5, 5, 5);
            obj.Components.AddComponent(scene);

            T3DTSRenderComponent model = new T3DTSRenderComponent();
            model.ShapeName = @"data/Static Models/Haus/house.dts";
            model.SceneGroupName = obj.Name;
            obj.Components.AddComponent(model);

            TorqueObjectDatabase.Instance.Register(obj);
        }

I'm grateful for any further hints.

#11
08/03/2009 (3:15 pm)
Thanks to John Kanalakis' help I solved this issue, finally!

After adding the lighting material definition to the scene, everything should have worked, but it didn't. And by comparing a working solution of John with my code I found the mistake.

The following piece of code caused the model to be lit:
<OrkMaterial type="GarageGames.Torque.Materials.LightingMaterial" name="OrkMaterial">
      <NameMapping>dataStatic ModelsPlayerOrkorkhaut</NameMapping>
      <TextureFilename>dataStatic ModelsPlayerOrkorkhaut</TextureFilename>
      <SpecularPower>35.0</SpecularPower>
      <SpecularIntensity>0.75</SpecularIntensity>
      <LightingMode>PerPixel</LightingMode>
    </OrkMaterial>

However, the same code with forwardslashes instead of backslashes:
<OrkMaterial type="GarageGames.Torque.Materials.LightingMaterial" name="OrkMaterial">
      <NameMapping>data/Static Models/Player/Ork/orkhaut</NameMapping>
      <TextureFilename>data/Static Models/Player/Ork/orkhaut</TextureFilename>
      <SpecularPower>35.0</SpecularPower>
      <SpecularIntensity>0.75</SpecularIntensity>
      <LightingMode>PerPixel</LightingMode>
    </OrkMaterial>

...did not work! I used forwardslashes all of the time, which works perfectly alright when loading models and textures, but however, obviously not when defining Lighting Materials! To be precise,
it seems that the "NameMapping" is the problem here, the texture path may contain forwardslashes instead of backslashes.

I'd say this is a bug. And I'm very happy to have solved this! I almost lost my faith during this whole week where I could not do such a simple thing as lighting a model in the engine-native format DTS.

Thanks again to John Kanalakis! :)
#12
08/03/2009 (5:29 pm)
I was playing around with this over the weekend and couldn't get it to work either. It seems there are a few new lines and I even had to add another before it worked for me. I flipped the slashes but that didn't do it.

I had this:

<LightingMaterial name="bricksMaterial" type="GarageGames.Torque.Materials.LightingMaterial">
      <TextureFilename>datashapesbricks</TextureFilename>
      <NormalMapFilename>datashapesbricks_NRM</NormalMapFilename>
      <SpecularPower>35.000</SpecularPower>
      <SpecularColor>
        <X>1</X>
        <Y>1</Y>
        <Z>1</Z>
        <W>1</W>
      </SpecularColor>
      <SpecularIntensity>0.350</SpecularIntensity>
      <LightingMode>PerPixel</LightingMode>
     <EffectFilename>LightingEffect3D</EffectFilename>
    </LightingMaterial>

I would get this:

smokinskull.com/images/bricks.jpg

After looking at the code posted, I would still get the plain image. I had to change the code to add the line <NormalMapFilename>. I also see the line <NameMapping> which was not in the original code.

<brickMaterial type="GarageGames.Torque.Materials.LightingMaterial" name="bricksMaterial">
      <NameMapping>datashapesbricks</NameMapping> <!--This is the important line-->
      <TextureFilename>datashapesbricks</TextureFilename> 
      <NormalMapFilename>datashapesbricks_NRM.png</NormalMapFilename> <!--This one is pretty important as well-->
      <SpecularPower>35.0</SpecularPower>
      <SpecularIntensity>0.25</SpecularIntensity>
      <LightingMode>PerPixel</LightingMode>
      <EffectFilename>LightingEffect3D</EffectFilename>
    </brickMaterial >

and voila!

smokinskull.com/images/bricks_nrm.jpg
This is why my models would appear flat, as per my post of a few months ago. Now we are cooking!

#13
08/03/2009 (7:28 pm)
Mathias, I'm glad to hear it's working. It's strange that the direction of the slash (forward versus backward) was the culprit. I'll check out the engine code to see if that can be made more universal, like it is for specifying model paths.

John K.
www.envygames.com
#14
08/04/2009 (2:00 pm)
As per my blog post, I tried this with a T2DShape3D without success.
If this should go in the torque 2d section - please let me know, but it was kind of on-topic so I wanted to continue this thread.

I load in a level which contains a t2dStaticSprite with a T2dLightComponent. Enabled is set to true.

Within the level xml in the Materials tag (using back slashes in the name mapping tag), I have
<MyMaterial type="GarageGames.Torque.Materials.LightingMaterial" name="MyMaterial">
        <NameMapping>datashapesringtitle</NameMapping>
        <TextureFilename>data/shapes/aprondefault</TextureFilename>
        <NormalMapFilename>data/shapes/default</NormalMapFilename>
        <SpecularPower>35.0</SpecularPower>
        <SpecularIntensity>0.75</SpecularIntensity>
        <LightingMode>PerPixel</LightingMode>
      </MyMaterial>

Now the ring is made up of several textures. So I just picked one? the aprondefault texture.

Then I create my ring as such:

T2DShape3D shape = new T2DShape3D();
            shape.Name = "RingTitle";
            String _shapeFile = @"data/shapes/ringTitle.dts";
            if (File.Exists(_shapeFile))
            {
                FileStream fs = new FileStream(_shapeFile, FileMode.Open, FileAccess.Read);
                ShapeReader reader = new ShapeReader();
                Shape dtsshape = reader.ReadShape(fs);
                fs.Close();
                FileInfo fi = new FileInfo(_shapeFile);
                dtsshape.FilePath = fi.DirectoryName;
                // remove executable directory so that path is relative to it   
                dtsshape.FilePath = dtsshape.FilePath.Replace(TorqueEngineComponent.Instance.ExecutableDirectory + @"", string.Empty);

                //Shape = dtsshape;
                //String c = dtsshape.ToString();
                shape.Shape = dtsshape;


            }
            else
            {
                Assert.Fatal(false, string.Format("Specified shape file not found: {0}", _shapeFile));
            }

            //set the size of the model in the scene       
            shape.ShapeScale = new Microsoft.Xna.Framework.Vector3(5);

            //set the position of the model in the scene    
            Vector2 pos = new Vector2(1, 25);
            shape.SetPosition(pos, true);

            //the the rotation of the model      
            //must be in radians NOT DEGREES   
            shape.Rotation2 = new Vector3((float)(Math.PI * 0) / 180, (float)(Math.PI * 83) / 180, (float)(Math.PI * 0) / 180);
            
            //set the layer        
            shape.Layer = 0;
            
            TorqueObjectDatabase.Instance.Register(shape);
            shape.AddThread("Main", "spin", true);

It looks the same...

farm3.static.flickr.com/2554/3789404524_bba3f0ae7e.jpg
Am I doing something wrong?
#15
08/04/2009 (2:31 pm)
I don't really *know* how the NameMapping tag works, but in my scene the NameMapping tag always has the exact same value as the TextureFilename tag. Maybe you should try that.

Also, you have to define such a material for every texture of the model that shall be lit. So if you're complete model is to be lit, just define a lighting material for each texture this way.
#16
08/04/2009 (3:11 pm)
My God if that's the case, I'd be better off waiting for John's shader kit and do it globally (I assume that's how it works). I have over 200 texture files due to my create-a-wrestler feature.

When I change the name of the nameMapping, it's completely dark.
So I assume it's working, but John, to your point on my blog, a 3D light is needed?
#17
08/07/2009 (8:56 am)
NameMapping is a index that the material manager uses to associate your Material with your texture. Its like a the name of your Material. That is why it needs to be the same name as your texture file name.
#18
09/05/2009 (2:09 pm)
Hello
My English is week
Im sorry
Im use this solution but the problem not solved and my texture not lighting and not bumping
What is my mistake?
#19
09/12/2009 (7:17 am)
if my informattion aboat my question is less i post my code?
#20
09/12/2009 (8:15 am)
Hello John! Sorry for this late answer.

Yes, to tell what's wrong with your code we need code!
Page «Previous 1 2