예제 #1
0
class ShadowCreator:

    def __init__(self):
        self.shadowBuffer = base.win.makeTextureBuffer('Shadow Buffer', 2048, 2048)
        self.shadowBuffer.setClearColorActive(True)
        self.shadowBuffer.setClearColor((0, 0, 0, 1))
        self.shadowCamera = base.makeCamera(self.shadowBuffer)
        self.shadowCamera.reparentTo(render)
        self.lens = base.camLens
        self.lens.setAspectRatio(1 / 1)
        self.shadowCamera.node().setLens(self.lens)
        self.shadowCamera.node().setCameraMask(BitMask32.bit(1))
        self.initial = NodePath('initial')
        self.initial.setColor(0.75, 0.75, 0.75, 1, 1)
        self.initial.setTextureOff(2)
        self.initial.setMaterialOff(2)
        self.initial.setLightOff(2)
        self.shadowCamera.node().setInitialState(self.initial.getState())
        self.shadowCamera.setPos(-10, 0, 20)
        self.shadowCamera.lookAt(0, 0, 0)
        self.filters = CommonFilters(self.shadowBuffer, self.shadowCamera)
        self.filters.setBlurSharpen(0.1)
        self.shadowTexture = self.shadowBuffer.getTexture()
        self.imageObject = OnscreenImage(image=self.shadowTexture, pos=(-0.75, 0, 0.75), scale=0.2)
예제 #2
0
    def __init__(self, objectPath, groundPath, lightPos=Vec3(0,0,1)):
        """ ShadowCaster::__init__
        objectPath is the shadow casting object
        groundPath is the shadow receiving object
        lightPos is the lights relative position to the objectPath
        """
        
        # uniq id-number for each shadow
        global shadowCasterObjectCounter
        shadowCasterObjectCounter += 1
        self.objectShadowId = shadowCasterObjectCounter
        
        # the object which will cast shadows
        self.objectPath = objectPath
        
        # get the objects bounds center and radius to
        # define the shadowrendering camera position and filmsize
        try:
            objectBoundRadius = self.objectPath.getBounds().getRadius()
            objectBoundCenter = self.objectPath.getBounds().getCenter()
        except:
            print "failed"
            objectBoundCenter = Point3( 0,0,0 )
            objectBoundRadius = 1
        
        lightPath = objectPath.attachNewNode('lightPath%i'%self.objectShadowId)
        # We can change this position at will to change the angle of the sun.
        lightPath.setPos( objectPath.getParent(), objectBoundCenter )
        self.lightPath = lightPath
        
        # the film size is the diameter of the object
        self.filmSize = objectBoundRadius * 2
        
        # Create an offscreen buffer to render the view of the avatar
        # into a texture.
        self.buffer = base.win.makeTextureBuffer(
            'shadowBuffer%i'%self.objectShadowId, self.texXSize, self.texYSize)

        # The background of this buffer--and the border of the
        # texture--is pure white.
        clearColor = VBase4(1, 1, 1, 1)
        self.buffer.setClearColor(clearColor)
        
        self.tex = self.buffer.getTexture()
        self.tex.setBorderColor(clearColor)
        self.tex.setWrapU(Texture.WMBorderColor)
        self.tex.setWrapV(Texture.WMBorderColor)

        # Set up a display region on this buffer, and create a camera.
        dr = self.buffer.makeDisplayRegion()
        self.camera = Camera('shadowCamera%i'%self.objectShadowId)
        self.cameraPath = self.lightPath.attachNewNode(self.camera)
        self.camera.setScene(self.objectPath)
        dr.setCamera(self.cameraPath)
        
        self.setLightPos( lightPos )
        
        # Use a temporary NodePath to define the initial state for the
        # camera.  The initial state will render everything in a
        # flat-shaded gray, as if it were a shadow.
        initial = NodePath('initial%i'%self.objectShadowId)
        initial.setColor( *SHADOWCOLOR )
        initial.setTextureOff(2)
        self.camera.setInitialState(initial.getState())
        
        # Use an orthographic lens for this camera instead of the
        # usual perspective lens.  An orthographic lens is better to
        # simulate sunlight, which is (almost) orthographic.  We set
        # the film size large enough to render a typical avatar (but
        # not so large that we lose detail in the texture).
        self.lens = OrthographicLens()
        self.lens.setFilmSize(self.filmSize, self.filmSize)
        self.camera.setLens(self.lens)
        
        # Finally, we'll need a unique TextureStage to apply this
        # shadow texture to the world.
        self.stage = TextureStage('shadow%i'%self.objectShadowId)

        # Make sure the shadowing object doesn't get its own shadow
        # applied to it.
        self.objectPath.setTextureOff(self.stage)
        
        # the object which will receive shadows
        self.setGround( groundPath )