Light falloff issue with cloth-or-flag lighting too uniform

I suspect that I am missing something blindingly obvious, but as I’ve been banging my head against it for a while, I thought I’d share.



I have a flag (cloth) with a flagpole next to it, with particle system (fire from the RenParticleControlFrame) nearby. I get nice falloff of the light on the flagpole, but not on the cloth.



If it is possible to get this kind of light falloff on a textured cloth, could someone point me in the direction of what would be good to try?



The code is not yet pretty: I’m in the process of migrating code from homegrown opengl project to jme and still feeling my way around.



   protected void simpleInitGame() {
      display.setTitle("jME Cloth Demo");
      KeyBindingManager.getKeyBindingManager().set("wind",
            KeyInput.KEY_RETURN);

//      ((PointLight) lightState.get(0)).setLocation(new Vector3f(0, -30, 150));
//      lightState.setTwoSidedLighting(true);
      lightState.setEnabled(false);
      cam.setLocation(new Vector3f(0, -30, 100));

      cam.update();
      input.setKeySpeed(30);

       makeACandle();

      cloth = new ClothPatch("cloth", NUMBERNODESX, NUMBERNODESY,
            1f, 10); // name, nodesX, nodesY, springSize, nodeMass
      wind = new Wind(windStrength, windDirection, true, true);
      cloth.addForce(wind);
      gravity = ClothUtils.createBasicGravity();
      cloth.addForce(gravity);
      drag = ClothUtils.createBasicDrag(20f);
      cloth.addForce(drag);

      TextureState ts = display.getRenderer().createTextureState();
      ts.setTexture(TextureManager.loadTexture(Flag.class.getClassLoader()
            .getResource("data/flags/shipcrossedswords2.jpg"),
            Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR));
      cloth.setRenderState(ts);
      cloth.setLightCombineMode( LightState.COMBINE_CLOSEST );
      rootNode.attachChild(cloth);
      int maxNodes = NUMBERNODESX * NUMBERNODESY;
      for (int i = 0; i < maxNodes; i += NUMBERNODESX) {
         cloth.getSystem().getNode(i).position.x *= .8f;
         cloth.getSystem().getNode(i).setMass(Float.POSITIVE_INFINITY);
      }

      Cylinder t = new Cylinder("Cylinder", 20, 50, .5f, 50);
      Quaternion rotQuat = new Quaternion();
      Vector3f angle = new Vector3f( 1,0,0 );
      rotQuat = rotQuat.fromAngleAxis(90 * FastMath.DEG_TO_RAD, angle );
      t.setLocalRotation( rotQuat );
      t.setLocalTranslation( new Vector3f( -10.5f,-15f,0));
       t.setModelBound(new BoundingBox());
       t.updateModelBound();
       rootNode.attachChild(t);

       rootNode.setForceView(true);

       rootNode.updateRenderState();
         
//       buildFastSkyBox();
//      buildSkyBox();

   }

   /**
    *
    */
   private void makeACandle() {
      Node main = new Node("Main node");
       main.setForceView(true);
       AlphaState as1 = display.getRenderer().createAlphaState();
       as1.setBlendEnabled(true);
       as1.setSrcFunction(AlphaState.SB_SRC_ALPHA);
       as1.setDstFunction(AlphaState.DB_ONE);
       as1.setTestEnabled(true);
       as1.setTestFunction(AlphaState.TF_GREATER);
       as1.setEnabled(true);
       TextureState ts2 = display.getRenderer().createTextureState();
       ts2.setTexture(
           TextureManager.loadTexture(
           RenParticleEditor.class.getClassLoader().getResource(
           "jmetest/data/texture/flaresmall.jpg"),
           Texture.MM_LINEAR_LINEAR,
           Texture.FM_LINEAR));
       ts2.setEnabled(true);

       ParticleManager manager = new ParticleManager(300);//RenParticleEditor.manager;
      manager.setGravityForce(new Vector3f(0.0f, 0.0f, 0.0f));
      manager.setEmissionDirection(new Vector3f(0.0f, 1.0f, 0.0f));
      manager.setEmissionMaximumAngle(0.20943952f);
      manager.setSpeed(1.0f);
      manager.setParticlesMinimumLifeTime(1000.0f);
      manager.setStartSize(40.0f);
      manager.setEndSize(40.0f);
      manager.setStartColor(new ColorRGBA(1.0f, 0.312f, 0.121f, 1.0f));
      manager.setEndColor(new ColorRGBA(1.0f, 0.312f, 0.121f, 0.0f));
      manager.setRandomMod(6.0f);
      manager.setControlFlow(true);
      manager.setReleaseRate(300);
      manager.setReleaseVariance(0.0f);
      manager.setInitialVelocity(0.3f);
      manager.setRepeatType(Controller.RT_WRAP);
      
      manager.warmUp(120);
      //  updateFromManager();
      rootNode.setRenderState(ts2);
      main.setRenderState(as1);
      manager.getParticles().addController(manager);
      manager.getParticles().setLocalTranslation(new Vector3f(0, -20f, 10f));
      manager.getParticles().setLocalScale(.013f);
      rootNode.attachChild(manager.getParticles());
      main.attachChild(rootNode);
      rootNode.updateGeometricState(0.0f, true);
      main.updateRenderState();
   }



thanks for any help you can throw my way.....

(there was a crash earlier: I couldn't find this message, but apoligies if this is a dup)


lightState.setEnabled(false);



is set near the top :)

just change that to true...

Regards,
DP

Awesome. That was a big part of it, and this made me realize that yet another problem I had was the light source 0 is created by default and that I needed to disable it by:


      ((PointLight) lightState.get(0)).setEnabled(false);



Which leaves me with the realization that my fire particle source does not, in fact appear to cast any light. Is there an easy way for the particle system to start casting its own light or do I need to create a separate light there.

Or does this mean that I am an ungreatful wretch for even asking?

Thank you very much!

There is no way to just set light for particles. You will have to use a SimpleLightNode!



How i would do this is the following:

Create a PointLight and set its properties and values, just remember to setEnable(true)!

Create a SimpleLightNode and pass the pointlight as parameter.

Attach that simpleLightNode to the rootnode and set its position to that of the particle system!



All you need to do now is to attach that point light to the lightState and also do a rootNode.updateGeometricState(0.0f, true) and rootNode.updateRenderState();



All of this should work!

I still haven’t ran your demo, but if the particle system is moving, i would recomend that you place the SimpleLightNode and the particle system under one node. Then, when moving the particle system, move the node it is attached to instead. This will make sure the light follows the particle system whereever it goes.



but be careful, Each spatial can only have a maximum of 8 lights affecting it, so if your making particle systems on to go on every shot from a machine gun, you might want to think that through. Or use the light ordering utility that finds out the 8 lights that affect the look of the object most and gets rid of the others…



Regards,

DP

Many thanks to both of you. I’ve got it running and most of the way there. You clarified a lot of things that I was very unclear on and I wanted you to know I really appreciated it.



There still does not seem to be any light falloff across the surface of the flag, but let me play with it a day or two and then give an update.



thanks,

om