Unexpected behaviour of projectTexture!

Hi,
Just noticed a weird behaviour of projectTexture.
Look at the following example: I load two pandas into a scene and have a projector set in order to project a texture onto the bottom part of Panda1 (at least that’s the intent :wink: ).

What happens is that:
(1) Panda1 gets fully illuminated by the projector
(2) Panda2 who stands completely out of the projector frustum gets illuminated too!

import direct.directbase.DirectStart
from direct.actor import Actor
from pandac.PandaModules import *
from direct.showbase.DirectObject import DirectObject

class World(DirectObject):
   def __init__(self):
      # load and position PANDAS into scene
      panda1 = Actor.Actor('panda.egg')
      panda1.setScale(0.8)
      panda1.reparentTo(render)
      panda1.setPos(0, 0, 0)

      panda2 = Actor.Actor('panda.egg')
      panda2.setScale(0.8)
      panda2.reparentTo(render)
      panda2.setPos(5, 15, 0)

      # prepare texture projector
      proj = render.attachNewNode(LensNode('proj'))
      lens = PerspectiveLens()
      proj.node().setLens(lens)
      proj.reparentTo(render)
      proj.setPos(-6, 0, 3.5)
      proj.setHpr(-90, 0, 0)
      proj.node().showFrustum()

      # texture to be projected onto part of Panda1
      tex = loader.loadTexture('maps/envir-bamboo.png')
      ts  = TextureStage('ts')

      # now project!
      panda1.projectTexture(ts, tex, proj)
      panda2.projectTexture(ts, tex, proj)

w =   World()
run() 

Any explanation???

I believe the texture will wrap even outside of the bounds of the lens. Try something like this to set outside the border black:

tex.setWrapU(Texture.WMBorderColor)
tex.setWrapV(Texture.WMBorderColor)
tex.setBorderColor(VBase4(0, 0, 0, 1))

Thank you so much! I won’t have been able to find the trick by myself reading the docs…

BTW. doing so generates another unexpected side effect: the remaining of the zones are now black (ie the initial textures have been cancelled). Is there any way to simply alter the area under the spot?

Use the MDecal mode, or so, and make the border colour transparent.

Thank you rdb,

For common interest here is the working code:

import direct.directbase.DirectStart
from direct.actor import Actor
from pandac.PandaModules import *
from direct.showbase.DirectObject import DirectObject

class World(DirectObject):
   def __init__(self):
      # load and position PANDAS into scene
      panda1 = Actor.Actor('panda.egg')
      panda1.setScale(0.8)
      panda1.reparentTo(render)
      panda1.setPos(0, 0, 0)

      panda2 = Actor.Actor('panda.egg')
      panda2.setScale(0.8)
      panda2.reparentTo(render)
      panda2.setPos(5, 15, 0)

      # prepare texture projector
      proj = render.attachNewNode(LensNode('proj'))
      lens = PerspectiveLens()
      proj.node().setLens(lens)
      proj.reparentTo(render)
      proj.setPos(-6, 0, 3.5)
      proj.setHpr(-90, 0, 0)
      proj.node().showFrustum()

      # texture to be projected onto part of Panda1
      tex = loader.loadTexture('maps/envir-bamboo.png')
      ts  = TextureStage('ts')
      ts.setSort(1)
      ts.setMode(TextureStage.MDecal)

      tex.setWrapU(Texture.WMBorderColor)
      tex.setWrapV(Texture.WMBorderColor)
      tex.setBorderColor(VBase4(0, 0, 0, 0))
	  
      # now project!
      panda1.projectTexture(ts, tex, proj)
      panda2.projectTexture(ts, tex, proj) # panda2 is not hit by the ray!

w =   World()
run()