Beispiel #1
0
def makeFilterBuffer(srcbuffer, name, sort, prog):
    blurBuffer=base.win.makeTextureBuffer(name, 512, 512)
    blurBuffer.setSort(sort)
    blurBuffer.setClearColor(Vec4(1,0,0,1))
    blurCamera=base.makeCamera2d(blurBuffer)
    blurScene=NodePath("new Scene")
    blurCamera.node().setScene(blurScene)
    shader = Shader.load(prog)
    card = srcbuffer.getTextureCard()
    card.reparentTo(blurScene)
    card.setShader(shader)
    return blurBuffer
Beispiel #2
0
def makeFilterBuffer(srcbuffer, name, sort, prog):
    blurBuffer = base.win.makeTextureBuffer(name, 512, 512)
    blurBuffer.setSort(sort)
    blurBuffer.setClearColor(Vec4(1, 0, 0, 1))
    blurCamera = base.makeCamera2d(blurBuffer)
    blurScene = NodePath("new Scene")
    blurCamera.node().setScene(blurScene)
    shader = Shader.load(prog)
    card = srcbuffer.getTextureCard()
    card.reparentTo(blurScene)
    card.setShader(shader)
    return blurBuffer
Beispiel #3
0
    def __init__(self):
        base.disableMouse()
        base.setBackgroundColor(0, 0, 0)
        camera.setPos(0, -50, 0)

        # Check video card capabilities.

        if (base.win.getGsg().getSupportsBasicShaders() == 0):
            addTitle(
                "Glow Filter: Video driver reports that shaders are not supported."
            )
            return

        # Post the instructions
        self.title = addTitle("Panda3D: Tutorial - Glow Filter")
        self.inst1 = addInstructions(0.95, "ESC: Quit")
        self.inst2 = addInstructions(0.90, "Space: Toggle Glow Filter On/Off")
        self.inst3 = addInstructions(0.85, "Enter: Toggle Running/Spinning")
        self.inst4 = addInstructions(0.80,
                                     "V: View the render-to-texture results")

        #create the shader that will determime what parts of the scene will glow
        glowShader=Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/glow/glow_shader.sha"))

        # load our model
        self.tron = Actor()
        self.tron.loadModel("models/samples/glow/tron")
        self.tron.loadAnims({"running": "models/samples/glow/tron_anim"})
        self.tron.reparentTo(render)
        self.interval = self.tron.hprInterval(60, Point3(360, 0, 0))
        self.interval.loop()
        self.isRunning = False

        #put some lighting on the tron model
        dlight = DirectionalLight('dlight')
        alight = AmbientLight('alight')
        dlnp = render.attachNewNode(dlight)
        alnp = render.attachNewNode(alight)
        dlight.setColor(Vec4(1.0, 0.7, 0.2, 1))
        alight.setColor(Vec4(0.2, 0.2, 0.2, 1))
        dlnp.setHpr(0, -60, 0)
        render.setLight(dlnp)
        render.setLight(alnp)

        # create the glow buffer. This buffer renders like a normal scene,
        # except that only the glowing materials should show up nonblack.
        glowBuffer = base.win.makeTextureBuffer("Glow scene", 512, 512)
        glowBuffer.setSort(-3)
        glowBuffer.setClearColor(Vec4(0, 0, 0, 1))

        # We have to attach a camera to the glow buffer. The glow camera
        # must have the same frustum as the main camera. As long as the aspect
        # ratios match, the rest will take care of itself.
        glowCamera = base.makeCamera(glowBuffer,
                                     lens=base.cam.node().getLens())

        # Tell the glow camera to use the glow shader
        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setShader(glowShader)
        glowCamera.node().setInitialState(tempnode.getState())

        # set up the pipeline: from glow scene to blur x to blur y to main window.
        blurXBuffer=makeFilterBuffer(glowBuffer,  "Blur X", -2, \
          os.path.join(PANDA_SHADER_PATH, "samples/glow/glow_xblur.sha"))
        blurYBuffer=makeFilterBuffer(blurXBuffer, "Blur Y", -1, \
          os.path.join(PANDA_SHADER_PATH, "samples/glow/glow_yblur.sha"))
        self.finalcard = blurYBuffer.getTextureCard()
        self.finalcard.reparentTo(render2d)
        self.finalcard.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd))

        # Panda contains a built-in viewer that lets you view the results of
        # your render-to-texture operations.  This code configures the viewer.

        self.accept("v", base.bufferViewer.toggleEnable)
        self.accept("V", base.bufferViewer.toggleEnable)
        base.bufferViewer.setPosition("llcorner")
        base.bufferViewer.setLayout("hline")
        base.bufferViewer.setCardSize(0.652, 0)

        # event handling
        self.accept("space", self.toggleGlow)
        self.accept("enter", self.toggleDisplay)
        self.accept("escape", sys.exit, [0])

        self.glowOn = True
Beispiel #4
0
    def __init__(self):
        base.disableMouse()
        camera.setPos(0, -50, 0)

        # Check video card capabilities.

        if (base.win.getGsg().getSupportsBasicShaders() == 0):
            addTitle(
                "Toon Shader: Video driver reports that shaders are not supported."
            )
            return

        # Post the instructions.
        self.title = addTitle(
            "Panda3D: Tutorial - Toon Shading with Normals-Based Inking")
        self.inst1 = addInstructions(0.95, "ESC: Quit")
        self.inst2 = addInstructions(
            0.90, "Up/Down: Increase/Decrease Line Thickness")
        self.inst3 = addInstructions(
            0.85, "Left/Right: Decrease/Increase Line Darkness")
        self.inst4 = addInstructions(0.80,
                                     "V: View the render-to-texture results")

        # This shader's job is to render the model with discrete lighting
        # levels.  The lighting calculations built into the shader assume
        # a single nonattenuating point light.

        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setShader(Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/cartoon/cartoon_lighting.sha")))
        base.cam.node().setInitialState(tempnode.getState())

        # This is the object that represents the single "light", as far
        # the shader is concerned.  It's not a real Panda3D LightNode, but
        # the shader doesn't care about that.

        light = render.attachNewNode("light")
        light.setPos(30, -50, 0)

        # this call puts the light's nodepath into the render state.
        # this enables the shader to access this light by name.

        render.setShaderInput("light", light)

        # The "normals buffer" will contain a picture of the model colorized
        # so that the color of the model is a representation of the model's
        # normal at that point.

        normalsBuffer = base.win.makeTextureBuffer("normalsBuffer", 0, 0)
        normalsBuffer.setClearColor(Vec4(0.5, 0.5, 0.5, 1))
        self.normalsBuffer = normalsBuffer
        normalsCamera = base.makeCamera(normalsBuffer,
                                        lens=base.cam.node().getLens())
        normalsCamera.node().setScene(render)
        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setShader(Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/cartoon/cartoon_normal.sha")))
        normalsCamera.node().setInitialState(tempnode.getState())

        #what we actually do to put edges on screen is apply them as a texture to
        #a transparent screen-fitted card

        drawnScene = normalsBuffer.getTextureCard()
        drawnScene.setTransparency(1)
        drawnScene.setColor(1, 1, 1, 0)
        drawnScene.reparentTo(render2d)
        self.drawnScene = drawnScene

        # this shader accepts, as input, the picture from the normals buffer.
        # it compares each adjacent pixel, looking for discontinuities.
        # wherever a discontinuity exists, it emits black ink.

        self.separation = 0.001
        self.cutoff = 0.3
        inkGen=Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/cartoon/cartoon_ink.sha"))
        drawnScene.setShader(inkGen)
        drawnScene.setShaderInput("separation",
                                  Vec4(self.separation, 0, self.separation, 0))
        drawnScene.setShaderInput(
            "cutoff", Vec4(self.cutoff, self.cutoff, self.cutoff, self.cutoff))

        # Panda contains a built-in viewer that lets you view the results of
        # your render-to-texture operations.  This code configures the viewer.

        self.accept("v", base.bufferViewer.toggleEnable)
        self.accept("V", base.bufferViewer.toggleEnable)
        base.bufferViewer.setPosition("llcorner")

        # Load a dragon model and animate it.

        self.character = Actor()
        self.character.loadModel('models/samples/cartoon/nik_dragon')
        self.character.reparentTo(render)
        self.character.loadAnims({'win': 'models/samples/cartoon/nik_dragon'})
        self.character.loop('win')
        self.character.hprInterval(15, Point3(360, 0, 0)).loop()

        # these allow you to change cartooning parameters in realtime

        self.accept("escape", sys.exit, [0])
        self.accept("arrow_up", self.increaseSeparation)
        self.accept("arrow_down", self.decreaseSeparation)
        self.accept("arrow_left", self.increaseCutoff)
        self.accept("arrow_right", self.decreaseCutoff)
Beispiel #5
0
    def __init__(self):

        # Preliminary capabilities check.

        if (base.win.getGsg().getSupportsBasicShaders()==0):
            self.t=addTitle("Firefly Demo: Video driver reports that shaders are not supported.")
            return
        if (base.win.getGsg().getSupportsDepthTexture()==0):
            self.t=addTitle("Firefly Demo: Video driver reports that depth textures are not supported.")
            return
        
        # This algorithm uses two offscreen buffers, one of which has
        # an auxiliary bitplane, and the offscreen buffers share a single
        # depth buffer.  This is a heck of a complicated buffer setup.

        self.modelbuffer = self.makeFBO("model buffer",1)
        self.lightbuffer = self.makeFBO("light buffer",0)
        
        # Creation of a high-powered buffer can fail, if the graphics card
        # doesn't support the necessary OpenGL extensions.

        if (self.modelbuffer == None) or (self.lightbuffer == None):
            self.t=addTitle("Toon Shader: Video driver does not support multiple render targets")
            return

        # Create four render textures: depth, normal, albedo, and final.
        # attach them to the various bitplanes of the offscreen buffers.

        self.texDepth = Texture()
        self.texDepth.setFormat(Texture.FDepthStencil)
        self.texAlbedo = Texture()
        self.texNormal = Texture()
        self.texFinal = Texture()

        self.modelbuffer.addRenderTexture(self.texDepth,  GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPDepthStencil)
        self.modelbuffer.addRenderTexture(self.texAlbedo, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor)
        self.modelbuffer.addRenderTexture(self.texNormal, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPAuxRgba0)

        self.lightbuffer.addRenderTexture(self.texFinal,  GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor)

        # Set the near and far clipping planes.
        
        base.cam.node().getLens().setNear(50.0)
        base.cam.node().getLens().setFar(500.0)
        lens = base.cam.node().getLens()

        # This algorithm uses three cameras: one to render the models into the
        # model buffer, one to render the lights into the light buffer, and
        # one to render "plain" stuff (non-deferred shaded) stuff into the light
        # buffer.  Each camera has a bitmask to identify it.

        self.modelMask = 1
        self.lightMask = 2
        self.plainMask = 4
        
        self.modelcam=base.makeCamera(self.modelbuffer, lens=lens, scene=render, mask=self.modelMask)
        self.lightcam=base.makeCamera(self.lightbuffer, lens=lens, scene=render, mask=self.lightMask)
        self.plaincam=base.makeCamera(self.lightbuffer, lens=lens, scene=render, mask=self.plainMask)

        # Panda's main camera is not used.
        
        base.cam.node().setActive(0)
        
        # Take explicit control over the order in which the three
        # buffers are rendered.

        self.modelbuffer.setSort(1)
        self.lightbuffer.setSort(2)
        base.win.setSort(3)

        # Within the light buffer, control the order of the two cams.

        self.lightcam.node().getDisplayRegion(0).setSort(1)
        self.plaincam.node().getDisplayRegion(0).setSort(2)

        # By default, panda usually clears the screen before every
        # camera and before every window.  Tell it not to do that.
        # Then, tell it specifically when to clear and what to clear.

        self.modelcam.node().getDisplayRegion(0).disableClears()
        self.lightcam.node().getDisplayRegion(0).disableClears()
        self.plaincam.node().getDisplayRegion(0).disableClears()
        base.cam.node().getDisplayRegion(0).disableClears()
        base.cam2d.node().getDisplayRegion(0).disableClears()
        self.modelbuffer.disableClears()
        base.win.disableClears()

        self.modelbuffer.setClearColorActive(1)
        self.modelbuffer.setClearDepthActive(1)
        self.lightbuffer.setClearColorActive(1)
        self.lightbuffer.setClearColor(Vec4(0,0,0,1))

        # Miscellaneous stuff.
        
        base.disableMouse()
        base.camera.setPos(-9.112,-211.077,46.951)
        base.camera.setHpr(0, -7.5, 2.4)
        base.setBackgroundColor(Vec4(0,0,0,0))
        random.seed()

        # Calculate the projection parameters for the final shader.
        # The math here is too complex to explain in an inline comment,
        # I've put in a full explanation into the HTML intro.

        proj = base.cam.node().getLens().getProjectionMat()
        proj_x = 0.5 * proj.getCell(3,2) / proj.getCell(0,0)
        proj_y = 0.5 * proj.getCell(3,2)
        proj_z = 0.5 * proj.getCell(3,2) / proj.getCell(2,1)
        proj_w = -0.5 - 0.5*proj.getCell(1,2)
        
        # Configure the render state of the model camera.
        
        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setAttrib(AlphaTestAttrib.make(RenderAttrib.MGreaterEqual, 0.5))
        tempnode.setShader(Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/fireflies/fireflies_model.sha")))
        tempnode.setAttrib(DepthTestAttrib.make(RenderAttrib.MLessEqual))
        self.modelcam.node().setInitialState(tempnode.getState())
        
        # Configure the render state of the light camera.

        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setShader(Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/fireflies/fireflies_lighting.sha")))
        tempnode.setShaderInput("texnormal",self.texNormal)
        tempnode.setShaderInput("texalbedo",self.texAlbedo)
        tempnode.setShaderInput("texdepth",self.texDepth)
        tempnode.setShaderInput("proj",Vec4(proj_x,proj_y,proj_z,proj_w))
        tempnode.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOne, ColorBlendAttrib.OOne))
        tempnode.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise))
        # The next line causes problems on Linux.
        #tempnode.setAttrib(DepthTestAttrib.make(RenderAttrib.MGreaterEqual))
        tempnode.setAttrib(DepthWriteAttrib.make(DepthWriteAttrib.MOff))
        self.lightcam.node().setInitialState(tempnode.getState())

        # Configure the render state of the plain camera.
        
        rs = RenderState.makeEmpty()
        self.plaincam.node().setInitialState(rs)
        
        # Clear any render attribs on the root node. This is necessary
        # because by default, panda assigns some attribs to the root
        # node.  These default attribs will override the
        # carefully-configured render attribs that we just attached
        # to the cameras.  The simplest solution is to just clear
        # them all out.

        render.setState(RenderState.makeEmpty())

        # My artist created a model in which some of the polygons
        # don't have textures.  This confuses the shader I wrote. 
        # This little hack guarantees that everything has a texture.
        
        white = loader.loadTexture("models/samples/fireflies/white.jpg")
        render.setTexture(white,0)

        # Create two subroots, to help speed cull traversal.
        
        self.lightroot = NodePath(PandaNode("lightroot"))
        self.lightroot.reparentTo(render)
        self.modelroot = NodePath(PandaNode("modelroot"))
        self.modelroot.reparentTo(render) 
        self.lightroot.hide(BitMask32(self.modelMask))
        self.modelroot.hide(BitMask32(self.lightMask))
        self.modelroot.hide(BitMask32(self.plainMask))

        # Load the model of a forest. Make it visible to the model camera.

        self.forest=NodePath(PandaNode("Forest Root"))
        self.forest.reparentTo(render)

        loader.loadModel( \
          "models/samples/fireflies/background").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage01").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage02").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage03").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage04").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage05").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage06").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage07").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage08").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage09").reparentTo(self.forest)
        self.forest.hide(BitMask32(self.lightMask | self.plainMask))

        # Cause the final results to be rendered into the main window on a card.
        
        cm = CardMaker("card")
        cm.setFrameFullscreenQuad()
        self.card = render2d.attachNewNode(cm.generate())
        self.card.setTexture(self.texFinal)
        
        # Post the instructions.

        self.title = addTitle("Panda3D: Tutorial - Fireflies using Deferred Shading")
        self.inst1 = addInstructions(0.95,"ESC: Quit")
        self.inst2 = addInstructions(0.90,"Up/Down: More / Fewer Fireflies (Count: unknown)")
        self.inst3 = addInstructions(0.85,"Right/Left: Bigger / Smaller Fireflies (Radius: unknown)")
        self.inst4 = addInstructions(0.80,"V: View the render-to-texture results")

        # Panda contains a built-in viewer that lets you view the results of
        # your render-to-texture operations.  This code configures the viewer.

        base.bufferViewer.setPosition("llcorner")
        base.bufferViewer.setCardSize(0,0.40)
        base.bufferViewer.setLayout("vline")
        self.toggleCards()
        self.toggleCards()

        # Firefly parameters

        self.fireflies = []
        self.sequences = []
        self.scaleseqs = []
        self.glowspheres = []
        self.fireflysize = 1.0
        self.spheremodel = loader.loadModel("models/misc/sphere.flt")
        self.setFireflySize(25.0)
        while (len(self.fireflies)<5): self.addFirefly()
        self.updateReadout()

        # these allow you to change parameters in realtime

        self.accept("escape", sys.exit, [0])
        self.accept("arrow_up",   self.incFireflyCount, [1.1111111])
        self.accept("arrow_down", self.decFireflyCount, [0.9000000])
        self.accept("arrow_right", self.setFireflySize, [1.1111111])
        self.accept("arrow_left",  self.setFireflySize, [0.9000000])
        self.accept("v", self.toggleCards)
        self.accept("V", self.toggleCards)

        self.nextadd = 0
        taskMgr.add(self.spawnTask, "spawner")
Beispiel #6
0
    def __init__(self):
        base.disableMouse()
        camera.setPos(0, -50, 0)
        
        # Check video card capabilities.

        if (base.win.getGsg().getSupportsBasicShaders() == 0):
            addTitle("Toon Shader: Video driver reports that shaders are not supported.")
            return

        # Post the instructions.
        self.title = addTitle("Panda3D: Tutorial - Toon Shading with Normals-Based Inking")
        self.inst1 = addInstructions(0.95,"ESC: Quit")
        self.inst2 = addInstructions(0.90,"Up/Down: Increase/Decrease Line Thickness")
        self.inst3 = addInstructions(0.85,"Left/Right: Decrease/Increase Line Darkness")
        self.inst4 = addInstructions(0.80,"V: View the render-to-texture results")

        # This shader's job is to render the model with discrete lighting
        # levels.  The lighting calculations built into the shader assume
        # a single nonattenuating point light.

        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setShader(Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/cartoon/cartoon_lighting.sha")))
        base.cam.node().setInitialState(tempnode.getState())
        
        # This is the object that represents the single "light", as far
        # the shader is concerned.  It's not a real Panda3D LightNode, but
        # the shader doesn't care about that.

        light = render.attachNewNode("light")
        light.setPos(30,-50,0)
                
        # this call puts the light's nodepath into the render state.
        # this enables the shader to access this light by name.

        render.setShaderInput("light", light)

        # The "normals buffer" will contain a picture of the model colorized
        # so that the color of the model is a representation of the model's
        # normal at that point.

        normalsBuffer=base.win.makeTextureBuffer("normalsBuffer", 0, 0)
        normalsBuffer.setClearColor(Vec4(0.5,0.5,0.5,1))
        self.normalsBuffer=normalsBuffer
        normalsCamera=base.makeCamera(normalsBuffer, lens=base.cam.node().getLens())
        normalsCamera.node().setScene(render)
        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setShader(Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/cartoon/cartoon_normal.sha")))
        normalsCamera.node().setInitialState(tempnode.getState())

        #what we actually do to put edges on screen is apply them as a texture to 
        #a transparent screen-fitted card

        drawnScene=normalsBuffer.getTextureCard()
        drawnScene.setTransparency(1)
        drawnScene.setColor(1,1,1,0)
        drawnScene.reparentTo(render2d)
        self.drawnScene = drawnScene

        # this shader accepts, as input, the picture from the normals buffer.
        # it compares each adjacent pixel, looking for discontinuities.
        # wherever a discontinuity exists, it emits black ink.
                
        self.separation = 0.001
        self.cutoff = 0.3
        inkGen=Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/cartoon/cartoon_ink.sha"))
        drawnScene.setShader(inkGen)
        drawnScene.setShaderInput("separation", Vec4(self.separation,0,self.separation,0));
        drawnScene.setShaderInput("cutoff", Vec4(self.cutoff,self.cutoff,self.cutoff,self.cutoff));
        
        # Panda contains a built-in viewer that lets you view the results of
        # your render-to-texture operations.  This code configures the viewer.

        self.accept("v", base.bufferViewer.toggleEnable)
        self.accept("V", base.bufferViewer.toggleEnable)
        base.bufferViewer.setPosition("llcorner")

        # Load a dragon model and animate it.

        self.character=Actor()
        self.character.loadModel('models/samples/cartoon/nik_dragon')
        self.character.reparentTo(render)
        self.character.loadAnims({'win': 'models/samples/cartoon/nik_dragon'})
        self.character.loop('win')
        self.character.hprInterval(15, Point3(360, 0,0)).loop()

        # these allow you to change cartooning parameters in realtime

        self.accept("escape", sys.exit, [0])
        self.accept("arrow_up", self.increaseSeparation)
        self.accept("arrow_down", self.decreaseSeparation)
        self.accept("arrow_left", self.increaseCutoff)
        self.accept("arrow_right", self.decreaseCutoff)
Beispiel #7
0
    def reconfigure(self, fullrebuild, changed):
        """ Reconfigure is called whenever any configuration change is made. """

        configuration = self.configuration

        if (fullrebuild):

            self.cleanup()

            if (len(configuration) == 0):
                return

            auxbits = 0
            needtex = {}
            needtex["color"] = True
            if (configuration.has_key("CartoonInk")):
                needtex["aux"] = True
                auxbits |= AuxBitplaneAttrib.ABOAuxNormal
            if (configuration.has_key("Bloom")):
                needtex["bloom0"] = True
                needtex["bloom1"] = True
                needtex["bloom2"] = True
                needtex["bloom3"] = True
                auxbits |= AuxBitplaneAttrib.ABOGlow
            if (configuration.has_key("ViewGlow")):
                auxbits |= AuxBitplaneAttrib.ABOGlow
            for tex in needtex:
                self.textures[tex] = Texture("scene-" + tex)
                self.textures[tex].setWrapU(Texture.WMClamp)
                self.textures[tex].setWrapV(Texture.WMClamp)
                needtexpix = True

            self.finalQuad = self.manager.renderSceneInto(
                textures=self.textures, auxbits=auxbits)
            if (self.finalQuad == None):
                self.cleanup()
                return False

            if (configuration.has_key("Bloom")):
                bloomconf = configuration["Bloom"]
                bloom0 = self.textures["bloom0"]
                bloom1 = self.textures["bloom1"]
                bloom2 = self.textures["bloom2"]
                bloom3 = self.textures["bloom3"]
                if (bloomconf.size == "large"):
                    scale = 8
                    downsampler = "filter_down4.sha"
                elif (bloomconf.size == "medium"):
                    scale = 4
                    downsampler = "filter_copy.sha"
                else:
                    scale = 2
                    downsampler = "filter_copy.sha"
                self.bloom.append(
                    self.manager.renderQuadInto(colortex=bloom0,
                                                div=2,
                                                align=scale))
                self.bloom.append(
                    self.manager.renderQuadInto(colortex=bloom1,
                                                div=scale,
                                                align=scale))
                self.bloom.append(
                    self.manager.renderQuadInto(colortex=bloom2,
                                                div=scale,
                                                align=scale))
                self.bloom.append(
                    self.manager.renderQuadInto(colortex=bloom3,
                                                div=scale,
                                                align=scale))
                self.bloom[0].setShaderInput("src", self.textures["color"])
                self.bloom[0].setShader(self.loadShader("filter_bloomi.sha"))
                self.bloom[1].setShaderInput("src", bloom0)
                self.bloom[1].setShader(self.loadShader(downsampler))
                self.bloom[2].setShaderInput("src", bloom1)
                self.bloom[2].setShader(self.loadShader("filter_bloomx.sha"))
                self.bloom[3].setShaderInput("src", bloom2)
                self.bloom[3].setShader(self.loadShader("filter_bloomy.sha"))

            text = "//Cg\n"
            text += "void vshader(float4 vtx_position : POSITION,\n"
            text += " out float4 l_position : POSITION,\n"
            text += " uniform float4 texpad_txcolor,\n"
            text += " uniform float4 texpix_txcolor,\n"
            text += " out float4 l_texcoordC : TEXCOORD0,\n"
            if (configuration.has_key("CartoonInk")):
                text += " uniform float4 texpad_txaux,\n"
                text += " uniform float4 texpix_txaux,\n"
                text += " out float4 l_texcoordN : TEXCOORD1,\n"
            if (configuration.has_key("Bloom")):
                text += " uniform float4 texpad_txbloom3,\n"
                text += " out float4 l_texcoordB : TEXCOORD2,\n"
            text += " uniform float4x4 mat_modelproj)\n"
            text += "{\n"
            text += " l_position=mul(mat_modelproj, vtx_position);\n"
            text += " l_texcoordC=(vtx_position.xzxz * texpad_txcolor) + texpad_txcolor;\n"
            if (configuration.has_key("CartoonInk")):
                text += " l_texcoordN=(vtx_position.xzxz * texpad_txaux) + texpad_txaux;\n"
            if (configuration.has_key("Bloom")):
                text += " l_texcoordB=(vtx_position.xzxz * texpad_txbloom3) + texpad_txbloom3;\n"
            if (configuration.has_key("HalfPixelShift")):
                text += " l_texcoordC+=texpix_txcolor*0.5;\n"
                if (configuration.has_key("CartoonInk")):
                    text += " l_texcoordN+=texpix_txaux*0.5;\n"
            text += "}\n"

            text += "void fshader(\n"
            text += "float4 l_texcoordC : TEXCOORD0,\n"
            text += "uniform float4 texpix_txcolor,\n"
            if (configuration.has_key("CartoonInk")):
                text += "float4 l_texcoordN : TEXCOORD1,\n"
                text += "uniform float4 texpix_txaux,\n"
            if (configuration.has_key("Bloom")):
                text += "float4 l_texcoordB : TEXCOORD2,\n"
            for key in self.textures:
                text += "uniform sampler2D k_tx" + key + ",\n"
            if (configuration.has_key("CartoonInk")):
                text += "uniform float4 k_cartoonseparation,\n"
            if (configuration.has_key("VolumetricLighting")):
                text += "uniform float4 k_casterpos,\n"
                text += "uniform float4 k_vlparams,\n"
            text += "out float4 o_color : COLOR)\n"
            text += "{\n"
            text += " o_color = tex2D(k_txcolor, l_texcoordC.xy);\n"
            if (configuration.has_key("CartoonInk")):
                text += CARTOON_BODY
            if (configuration.has_key("Bloom")):
                text += "o_color = saturate(o_color);\n"
                text += "float4 bloom = 0.5*tex2D(k_txbloom3, l_texcoordB.xy);\n"
                text += "o_color = 1-((1-bloom)*(1-o_color));\n"
            if (configuration.has_key("ViewGlow")):
                text += "o_color.r = o_color.a;\n"
            if (configuration.has_key("VolumetricLighting")):
                text += "float decay = 1.0f;\n"
                text += "float2 curcoord = l_texcoordC.xy;\n"
                text += "float2 lightdir = curcoord - k_casterpos.xy;\n"
                text += "lightdir *= k_vlparams.y;\n"
                text += "half4 sample = tex2D(k_txcolor, curcoord);\n"
                text += "float3 vlcolor = sample.rgb * sample.a;\n"
                text += "for (int i = 0; i < k_vlparams.x; i++) {\n"
                text += "  curcoord -= lightdir;\n"
                text += "  sample = tex2D(k_txcolor, curcoord);\n"
                text += "  sample *= sample.a * decay;//*weight\n"
                text += "  vlcolor += sample.rgb;\n"
                text += "  decay *= k_vlparams.z;\n"
                text += "}\n"
                text += "o_color += float4(vlcolor * k_vlparams.w, 1);\n"
            if (configuration.has_key("Inverted")):
                text += "o_color = float4(1, 1, 1, 1) - o_color;\n"
            text += "}\n"

            self.finalQuad.setShader(Shader.make(text))
            for tex in self.textures:
                self.finalQuad.setShaderInput("tx" + tex, self.textures[tex])

        if (changed == "CartoonInk") or fullrebuild:
            if (configuration.has_key("CartoonInk")):
                separation = configuration["CartoonInk"]
                self.finalQuad.setShaderInput(
                    "cartoonseparation", Vec4(separation, 0, separation, 0))

        if (changed == "Bloom") or fullrebuild:
            if (configuration.has_key("Bloom")):
                bloomconf = configuration["Bloom"]
                intensity = bloomconf.intensity * 3.0
                self.bloom[0].setShaderInput("blend", bloomconf.blendx,
                                             bloomconf.blendy,
                                             bloomconf.blendz,
                                             bloomconf.blendw * 2.0)
                self.bloom[0].setShaderInput(
                    "trigger", bloomconf.mintrigger,
                    1.0 / (bloomconf.maxtrigger - bloomconf.mintrigger), 0.0,
                    0.0)
                self.bloom[0].setShaderInput("desat", bloomconf.desat)
                self.bloom[3].setShaderInput("intensity", intensity, intensity,
                                             intensity, intensity)

        if (changed == "VolumetricLighting") or fullrebuild:
            if (configuration.has_key("VolumetricLighting")):
                config = configuration["VolumetricLighting"]
                tcparam = config.density / float(config.numsamples)
                self.finalQuad.setShaderInput("vlparams", config.numsamples,
                                              tcparam, config.decay,
                                              config.exposure)

        self.update()
        return True
Beispiel #8
0
 def loadShader(self, name):
     fn = os.path.join(PANDA_SHADER_PATH, name)
     fn = Filename.fromOsSpecific(fn)
     fn.makeTrueCase()
     return Shader.load(fn)
Beispiel #9
0
    def __init__(self):
        base.disableMouse()
        base.setBackgroundColor(0,0,0)
        camera.setPos(0,-50,0)
        
        # Check video card capabilities.

        if (base.win.getGsg().getSupportsBasicShaders() == 0):
            addTitle("Glow Filter: Video driver reports that shaders are not supported.")
            return

        # Post the instructions
        self.title = addTitle("Panda3D: Tutorial - Glow Filter")
        self.inst1 = addInstructions(0.95,"ESC: Quit")
        self.inst2 = addInstructions(0.90,"Space: Toggle Glow Filter On/Off")
        self.inst3 = addInstructions(0.85,"Enter: Toggle Running/Spinning")
        self.inst4 = addInstructions(0.80,"V: View the render-to-texture results")

        #create the shader that will determime what parts of the scene will glow
        glowShader=Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/glow/glow_shader.sha"))

        # load our model
        self.tron=Actor()
        self.tron.loadModel("models/samples/glow/tron")
        self.tron.loadAnims({"running":"models/samples/glow/tron_anim"})
        self.tron.reparentTo(render)
        self.interval = self.tron.hprInterval(60,Point3(360,0,0))
        self.interval.loop()
        self.isRunning=False

        #put some lighting on the tron model
        dlight = DirectionalLight('dlight')
        alight = AmbientLight('alight')
        dlnp = render.attachNewNode(dlight) 
        alnp = render.attachNewNode(alight)
        dlight.setColor(Vec4(1.0, 0.7, 0.2, 1))
        alight.setColor(Vec4(0.2, 0.2, 0.2, 1))
        dlnp.setHpr(0, -60, 0) 
        render.setLight(dlnp)
        render.setLight(alnp)

        # create the glow buffer. This buffer renders like a normal scene,
        # except that only the glowing materials should show up nonblack.
        glowBuffer=base.win.makeTextureBuffer("Glow scene", 512, 512)
        glowBuffer.setSort(-3)
        glowBuffer.setClearColor(Vec4(0,0,0,1))

        # We have to attach a camera to the glow buffer. The glow camera
        # must have the same frustum as the main camera. As long as the aspect
        # ratios match, the rest will take care of itself.
        glowCamera=base.makeCamera(glowBuffer, lens=base.cam.node().getLens())

        # Tell the glow camera to use the glow shader
        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setShader(glowShader)
        glowCamera.node().setInitialState(tempnode.getState())

        # set up the pipeline: from glow scene to blur x to blur y to main window.
        blurXBuffer=makeFilterBuffer(glowBuffer,  "Blur X", -2, \
          os.path.join(PANDA_SHADER_PATH, "samples/glow/glow_xblur.sha"))
        blurYBuffer=makeFilterBuffer(blurXBuffer, "Blur Y", -1, \
          os.path.join(PANDA_SHADER_PATH, "samples/glow/glow_yblur.sha"))
        self.finalcard = blurYBuffer.getTextureCard()
        self.finalcard.reparentTo(render2d)
        self.finalcard.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd))
        
        # Panda contains a built-in viewer that lets you view the results of
        # your render-to-texture operations.  This code configures the viewer.

        self.accept("v", base.bufferViewer.toggleEnable)
        self.accept("V", base.bufferViewer.toggleEnable)
        base.bufferViewer.setPosition("llcorner")
        base.bufferViewer.setLayout("hline")
        base.bufferViewer.setCardSize(0.652,0)

        # event handling
        self.accept("space", self.toggleGlow)
        self.accept("enter", self.toggleDisplay)
        self.accept("escape", sys.exit, [0])

        self.glowOn=True;
Beispiel #10
0
    def __init__(self):

        # Preliminary capabilities check.

        if (base.win.getGsg().getSupportsBasicShaders() == 0):
            self.t = addTitle(
                "Firefly Demo: Video driver reports that shaders are not supported."
            )
            return
        if (base.win.getGsg().getSupportsDepthTexture() == 0):
            self.t = addTitle(
                "Firefly Demo: Video driver reports that depth textures are not supported."
            )
            return

        # This algorithm uses two offscreen buffers, one of which has
        # an auxiliary bitplane, and the offscreen buffers share a single
        # depth buffer.  This is a heck of a complicated buffer setup.

        self.modelbuffer = self.makeFBO("model buffer", 1)
        self.lightbuffer = self.makeFBO("light buffer", 0)

        # Creation of a high-powered buffer can fail, if the graphics card
        # doesn't support the necessary OpenGL extensions.

        if (self.modelbuffer == None) or (self.lightbuffer == None):
            self.t = addTitle(
                "Toon Shader: Video driver does not support multiple render targets"
            )
            return

        # Create four render textures: depth, normal, albedo, and final.
        # attach them to the various bitplanes of the offscreen buffers.

        self.texDepth = Texture()
        self.texDepth.setFormat(Texture.FDepthStencil)
        self.texAlbedo = Texture()
        self.texNormal = Texture()
        self.texFinal = Texture()

        self.modelbuffer.addRenderTexture(self.texDepth,
                                          GraphicsOutput.RTMBindOrCopy,
                                          GraphicsOutput.RTPDepthStencil)
        self.modelbuffer.addRenderTexture(self.texAlbedo,
                                          GraphicsOutput.RTMBindOrCopy,
                                          GraphicsOutput.RTPColor)
        self.modelbuffer.addRenderTexture(self.texNormal,
                                          GraphicsOutput.RTMBindOrCopy,
                                          GraphicsOutput.RTPAuxRgba0)

        self.lightbuffer.addRenderTexture(self.texFinal,
                                          GraphicsOutput.RTMBindOrCopy,
                                          GraphicsOutput.RTPColor)

        # Set the near and far clipping planes.

        base.cam.node().getLens().setNear(50.0)
        base.cam.node().getLens().setFar(500.0)
        lens = base.cam.node().getLens()

        # This algorithm uses three cameras: one to render the models into the
        # model buffer, one to render the lights into the light buffer, and
        # one to render "plain" stuff (non-deferred shaded) stuff into the light
        # buffer.  Each camera has a bitmask to identify it.

        self.modelMask = 1
        self.lightMask = 2
        self.plainMask = 4

        self.modelcam = base.makeCamera(self.modelbuffer,
                                        lens=lens,
                                        scene=render,
                                        mask=self.modelMask)
        self.lightcam = base.makeCamera(self.lightbuffer,
                                        lens=lens,
                                        scene=render,
                                        mask=self.lightMask)
        self.plaincam = base.makeCamera(self.lightbuffer,
                                        lens=lens,
                                        scene=render,
                                        mask=self.plainMask)

        # Panda's main camera is not used.

        base.cam.node().setActive(0)

        # Take explicit control over the order in which the three
        # buffers are rendered.

        self.modelbuffer.setSort(1)
        self.lightbuffer.setSort(2)
        base.win.setSort(3)

        # Within the light buffer, control the order of the two cams.

        self.lightcam.node().getDisplayRegion(0).setSort(1)
        self.plaincam.node().getDisplayRegion(0).setSort(2)

        # By default, panda usually clears the screen before every
        # camera and before every window.  Tell it not to do that.
        # Then, tell it specifically when to clear and what to clear.

        self.modelcam.node().getDisplayRegion(0).disableClears()
        self.lightcam.node().getDisplayRegion(0).disableClears()
        self.plaincam.node().getDisplayRegion(0).disableClears()
        base.cam.node().getDisplayRegion(0).disableClears()
        base.cam2d.node().getDisplayRegion(0).disableClears()
        self.modelbuffer.disableClears()
        base.win.disableClears()

        self.modelbuffer.setClearColorActive(1)
        self.modelbuffer.setClearDepthActive(1)
        self.lightbuffer.setClearColorActive(1)
        self.lightbuffer.setClearColor(Vec4(0, 0, 0, 1))

        # Miscellaneous stuff.

        base.disableMouse()
        base.camera.setPos(-9.112, -211.077, 46.951)
        base.camera.setHpr(0, -7.5, 2.4)
        base.setBackgroundColor(Vec4(0, 0, 0, 0))
        random.seed()

        # Calculate the projection parameters for the final shader.
        # The math here is too complex to explain in an inline comment,
        # I've put in a full explanation into the HTML intro.

        proj = base.cam.node().getLens().getProjectionMat()
        proj_x = 0.5 * proj.getCell(3, 2) / proj.getCell(0, 0)
        proj_y = 0.5 * proj.getCell(3, 2)
        proj_z = 0.5 * proj.getCell(3, 2) / proj.getCell(2, 1)
        proj_w = -0.5 - 0.5 * proj.getCell(1, 2)

        # Configure the render state of the model camera.

        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setAttrib(
            AlphaTestAttrib.make(RenderAttrib.MGreaterEqual, 0.5))
        tempnode.setShader(Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/fireflies/fireflies_model.sha")))
        tempnode.setAttrib(DepthTestAttrib.make(RenderAttrib.MLessEqual))
        self.modelcam.node().setInitialState(tempnode.getState())

        # Configure the render state of the light camera.

        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setShader(Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/fireflies/fireflies_lighting.sha")))
        tempnode.setShaderInput("texnormal", self.texNormal)
        tempnode.setShaderInput("texalbedo", self.texAlbedo)
        tempnode.setShaderInput("texdepth", self.texDepth)
        tempnode.setShaderInput("proj", Vec4(proj_x, proj_y, proj_z, proj_w))
        tempnode.setAttrib(
            ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOne,
                                  ColorBlendAttrib.OOne))
        tempnode.setAttrib(
            CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise))
        # The next line causes problems on Linux.
        #tempnode.setAttrib(DepthTestAttrib.make(RenderAttrib.MGreaterEqual))
        tempnode.setAttrib(DepthWriteAttrib.make(DepthWriteAttrib.MOff))
        self.lightcam.node().setInitialState(tempnode.getState())

        # Configure the render state of the plain camera.

        rs = RenderState.makeEmpty()
        self.plaincam.node().setInitialState(rs)

        # Clear any render attribs on the root node. This is necessary
        # because by default, panda assigns some attribs to the root
        # node.  These default attribs will override the
        # carefully-configured render attribs that we just attached
        # to the cameras.  The simplest solution is to just clear
        # them all out.

        render.setState(RenderState.makeEmpty())

        # My artist created a model in which some of the polygons
        # don't have textures.  This confuses the shader I wrote.
        # This little hack guarantees that everything has a texture.

        white = loader.loadTexture("models/samples/fireflies/white.jpg")
        render.setTexture(white, 0)

        # Create two subroots, to help speed cull traversal.

        self.lightroot = NodePath(PandaNode("lightroot"))
        self.lightroot.reparentTo(render)
        self.modelroot = NodePath(PandaNode("modelroot"))
        self.modelroot.reparentTo(render)
        self.lightroot.hide(BitMask32(self.modelMask))
        self.modelroot.hide(BitMask32(self.lightMask))
        self.modelroot.hide(BitMask32(self.plainMask))

        # Load the model of a forest. Make it visible to the model camera.

        self.forest = NodePath(PandaNode("Forest Root"))
        self.forest.reparentTo(render)

        loader.loadModel( \
          "models/samples/fireflies/background").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage01").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage02").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage03").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage04").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage05").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage06").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage07").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage08").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage09").reparentTo(self.forest)
        self.forest.hide(BitMask32(self.lightMask | self.plainMask))

        # Cause the final results to be rendered into the main window on a card.

        cm = CardMaker("card")
        cm.setFrameFullscreenQuad()
        self.card = render2d.attachNewNode(cm.generate())
        self.card.setTexture(self.texFinal)

        # Post the instructions.

        self.title = addTitle(
            "Panda3D: Tutorial - Fireflies using Deferred Shading")
        self.inst1 = addInstructions(0.95, "ESC: Quit")
        self.inst2 = addInstructions(
            0.90, "Up/Down: More / Fewer Fireflies (Count: unknown)")
        self.inst3 = addInstructions(
            0.85, "Right/Left: Bigger / Smaller Fireflies (Radius: unknown)")
        self.inst4 = addInstructions(0.80,
                                     "V: View the render-to-texture results")

        # Panda contains a built-in viewer that lets you view the results of
        # your render-to-texture operations.  This code configures the viewer.

        base.bufferViewer.setPosition("llcorner")
        base.bufferViewer.setCardSize(0, 0.40)
        base.bufferViewer.setLayout("vline")
        self.toggleCards()
        self.toggleCards()

        # Firefly parameters

        self.fireflies = []
        self.sequences = []
        self.scaleseqs = []
        self.glowspheres = []
        self.fireflysize = 1.0
        self.spheremodel = loader.loadModel("models/misc/sphere.flt")
        self.setFireflySize(25.0)
        while (len(self.fireflies) < 5):
            self.addFirefly()
        self.updateReadout()

        # these allow you to change parameters in realtime

        self.accept("escape", sys.exit, [0])
        self.accept("arrow_up", self.incFireflyCount, [1.1111111])
        self.accept("arrow_down", self.decFireflyCount, [0.9000000])
        self.accept("arrow_right", self.setFireflySize, [1.1111111])
        self.accept("arrow_left", self.setFireflySize, [0.9000000])
        self.accept("v", self.toggleCards)
        self.accept("V", self.toggleCards)

        self.nextadd = 0
        taskMgr.add(self.spawnTask, "spawner")
Beispiel #11
0
    def reconfigure(self, fullrebuild, changed):

        """ Reconfigure is called whenever any configuration change is made. """

        configuration = self.configuration

        if (fullrebuild):

            self.cleanup()

            if (len(configuration) == 0):
                return

            auxbits = 0
            needtex = {}
            needtex["color"] = True
            if (configuration.has_key("CartoonInk")):
                needtex["aux"] = True
                auxbits |= AuxBitplaneAttrib.ABOAuxNormal
            if (configuration.has_key("Bloom")):
                needtex["bloom0"] = True
                needtex["bloom1"] = True
                needtex["bloom2"] = True
                needtex["bloom3"] = True
                auxbits |= AuxBitplaneAttrib.ABOGlow
            if (configuration.has_key("ViewGlow")):
                auxbits |= AuxBitplaneAttrib.ABOGlow
            for tex in needtex:
                self.textures[tex] = Texture("scene-"+tex)
                self.textures[tex].setWrapU(Texture.WMClamp)
                self.textures[tex].setWrapV(Texture.WMClamp)
                needtexpix = True

            self.finalQuad = self.manager.renderSceneInto(textures = self.textures, auxbits=auxbits)
            if (self.finalQuad == None):
                self.cleanup()
                return False

            if (configuration.has_key("Bloom")):
                bloomconf = configuration["Bloom"]
                bloom0=self.textures["bloom0"]
                bloom1=self.textures["bloom1"]
                bloom2=self.textures["bloom2"]
                bloom3=self.textures["bloom3"]
                if (bloomconf.size == "large"):
                    scale=8
                    downsampler="filter_down4.sha"
                elif (bloomconf.size == "medium"):
                    scale=4
                    downsampler="filter_copy.sha"
                else:
                    scale=2
                    downsampler="filter_copy.sha"
                self.bloom.append(self.manager.renderQuadInto(colortex=bloom0, div=2,     align=scale))
                self.bloom.append(self.manager.renderQuadInto(colortex=bloom1, div=scale, align=scale))
                self.bloom.append(self.manager.renderQuadInto(colortex=bloom2, div=scale, align=scale))
                self.bloom.append(self.manager.renderQuadInto(colortex=bloom3, div=scale, align=scale))
                self.bloom[0].setShaderInput("src", self.textures["color"])
                self.bloom[0].setShader(self.loadShader("filter_bloomi.sha"))
                self.bloom[1].setShaderInput("src", bloom0)
                self.bloom[1].setShader(self.loadShader(downsampler))
                self.bloom[2].setShaderInput("src", bloom1)
                self.bloom[2].setShader(self.loadShader("filter_bloomx.sha"))
                self.bloom[3].setShaderInput("src", bloom2)
                self.bloom[3].setShader(self.loadShader("filter_bloomy.sha"))

            text = "//Cg\n"
            text += "void vshader(float4 vtx_position : POSITION,\n"
            text += " out float4 l_position : POSITION,\n"
            text += " uniform float4 texpad_txcolor,\n"
            text += " uniform float4 texpix_txcolor,\n"
            text += " out float4 l_texcoordC : TEXCOORD0,\n"
            if (configuration.has_key("CartoonInk")):
                text += " uniform float4 texpad_txaux,\n"
                text += " uniform float4 texpix_txaux,\n"
                text += " out float4 l_texcoordN : TEXCOORD1,\n"
            if (configuration.has_key("Bloom")):
                text += " uniform float4 texpad_txbloom3,\n"
                text += " out float4 l_texcoordB : TEXCOORD2,\n"
            text += " uniform float4x4 mat_modelproj)\n"
            text += "{\n"
            text += " l_position=mul(mat_modelproj, vtx_position);\n"
            text += " l_texcoordC=(vtx_position.xzxz * texpad_txcolor) + texpad_txcolor;\n"
            if (configuration.has_key("CartoonInk")):
                text += " l_texcoordN=(vtx_position.xzxz * texpad_txaux) + texpad_txaux;\n"
            if (configuration.has_key("Bloom")):
                text += " l_texcoordB=(vtx_position.xzxz * texpad_txbloom3) + texpad_txbloom3;\n"
            if (configuration.has_key("HalfPixelShift")):
                text += " l_texcoordC+=texpix_txcolor*0.5;\n"
                if (configuration.has_key("CartoonInk")):
                    text += " l_texcoordN+=texpix_txaux*0.5;\n"
            text += "}\n"

            text += "void fshader(\n"
            text += "float4 l_texcoordC : TEXCOORD0,\n"
            text += "uniform float4 texpix_txcolor,\n"
            if (configuration.has_key("CartoonInk")):
                text += "float4 l_texcoordN : TEXCOORD1,\n"
                text += "uniform float4 texpix_txaux,\n"
            if (configuration.has_key("Bloom")):
                text += "float4 l_texcoordB : TEXCOORD2,\n"
            for key in self.textures:
                text += "uniform sampler2D k_tx" + key + ",\n"
            if (configuration.has_key("CartoonInk")):
                text += "uniform float4 k_cartoonseparation,\n"
            if (configuration.has_key("VolumetricLighting")):
                text += "uniform float4 k_casterpos,\n"
                text += "uniform float4 k_vlparams,\n"
            text += "out float4 o_color : COLOR)\n"
            text += "{\n"
            text += " o_color = tex2D(k_txcolor, l_texcoordC.xy);\n"
            if (configuration.has_key("CartoonInk")):
                text += CARTOON_BODY
            if (configuration.has_key("Bloom")):
                text += "o_color = saturate(o_color);\n";
                text += "float4 bloom = 0.5*tex2D(k_txbloom3, l_texcoordB.xy);\n"
                text += "o_color = 1-((1-bloom)*(1-o_color));\n"
            if (configuration.has_key("ViewGlow")):
                text += "o_color.r = o_color.a;\n"
            if (configuration.has_key("VolumetricLighting")):
                text += "float decay = 1.0f;\n"
                text += "float2 curcoord = l_texcoordC.xy;\n"
                text += "float2 lightdir = curcoord - k_casterpos.xy;\n"
                text += "lightdir *= k_vlparams.y;\n"
                text += "half4 sample = tex2D(k_txcolor, curcoord);\n"
                text += "float3 vlcolor = sample.rgb * sample.a;\n"
                text += "for (int i = 0; i < k_vlparams.x; i++) {\n"
                text += "  curcoord -= lightdir;\n"
                text += "  sample = tex2D(k_txcolor, curcoord);\n"
                text += "  sample *= sample.a * decay;//*weight\n"
                text += "  vlcolor += sample.rgb;\n"
                text += "  decay *= k_vlparams.z;\n"
                text += "}\n"
                text += "o_color += float4(vlcolor * k_vlparams.w, 1);\n"
            if (configuration.has_key("Inverted")):
                text += "o_color = float4(1, 1, 1, 1) - o_color;\n"
            text += "}\n"
            
            self.finalQuad.setShader(Shader.make(text))
            for tex in self.textures:
                self.finalQuad.setShaderInput("tx"+tex, self.textures[tex])
        
        if (changed == "CartoonInk") or fullrebuild:
            if (configuration.has_key("CartoonInk")):
                separation = configuration["CartoonInk"]
                self.finalQuad.setShaderInput("cartoonseparation", Vec4(separation,0,separation,0))
        
        if (changed == "Bloom") or fullrebuild:
            if (configuration.has_key("Bloom")):
                bloomconf = configuration["Bloom"]
                intensity = bloomconf.intensity * 3.0
                self.bloom[0].setShaderInput("blend", bloomconf.blendx, bloomconf.blendy, bloomconf.blendz, bloomconf.blendw * 2.0)
                self.bloom[0].setShaderInput("trigger", bloomconf.mintrigger, 1.0/(bloomconf.maxtrigger-bloomconf.mintrigger), 0.0, 0.0)
                self.bloom[0].setShaderInput("desat", bloomconf.desat)
                self.bloom[3].setShaderInput("intensity", intensity, intensity, intensity, intensity)
        
        if (changed == "VolumetricLighting") or fullrebuild:
            if (configuration.has_key("VolumetricLighting")):
                config = configuration["VolumetricLighting"]
                tcparam = config.density / float(config.numsamples)
                self.finalQuad.setShaderInput("vlparams", config.numsamples, tcparam, config.decay, config.exposure)
        
        self.update()
        return True
Beispiel #12
0
 def loadShader(self, name):
     fn = os.path.join(PANDA_SHADER_PATH, name)
     fn = Filename.fromOsSpecific(fn)
     fn.makeTrueCase()
     return Shader.load(fn)