Esempio n. 1
0
    def init(self):
        """ Initializes the vertex buffers and makes them available as shader
        inputs. """

        self.vertexBuffers = []

        for i in xrange(2):
            vertexBuffer = Texture("VertexPositionBuffer-" + str(i))
            vertexBuffer.setup2dTexture(self.split,
                                        self.maxVertexCount / self.split,
                                        Texture.TFloat, Texture.FRgba32)
            vertexBuffer.setClearColor(Vec4(0))
            vertexBuffer.clearImage()

            MemoryMonitor.addTexture("DynamicObjectVtxBuffer" + str(i),
                                     vertexBuffer)
            Globals.render.setShaderInput("dynamicObjectVtxBuffer" + str(i),
                                          vertexBuffer)

            BufferViewerGUI.registerTexture("Vtx Positions " + str(i),
                                            vertexBuffer)
            vertexBuffer.setWrapU(Texture.WMClamp)
            vertexBuffer.setWrapV(Texture.WMClamp)
            vertexBuffer.setMinfilter(Texture.FTNearest)
            vertexBuffer.setMagfilter(Texture.FTNearest)
            self.vertexBuffers.append(vertexBuffer)

        Globals.render.setShaderInput("dynamicVtxSplit", self.split)
    def create(self):
        """ Creates the passes """
        self.cloudStartHeight = 900.0
        self.cloudEndHeight = 3300.0
        self.cloudResolution = 768
        self.cloudResolutionH = 128

        self.voxelGrid = Texture("CloudVoxelGrid")
        self.voxelGrid.setup3dTexture(self.cloudResolution, self.cloudResolution, self.cloudResolutionH, Texture.TFloat, Texture.FR16)
        self.voxelGrid.setWrapU(Texture.WMRepeat)
        self.voxelGrid.setWrapV(Texture.WMRepeat)
        self.voxelGrid.setWrapW(Texture.WMClamp)

        self.cloudNoise = Texture("CloudNoise")
        self.cloudNoise.setup3dTexture(64, 64, 64, Texture.TFloat, Texture.FR16)
        self.cloudNoise.setWrapU(Texture.WMRepeat)
        self.cloudNoise.setWrapV(Texture.WMRepeat)
        self.cloudNoise.setWrapW(Texture.WMRepeat)

        MemoryMonitor.addTexture("CloudVoxelGrid", self.voxelGrid)
        MemoryMonitor.addTexture("CloudNoise", self.cloudNoise)

        self._createInitialGrid()

        self.renderPass = CloudRenderPass()
        self.pipeline.getRenderPassManager().registerPass(self.renderPass)
        self.pipeline.getRenderPassManager().registerStaticVariable("cloudVoxelGrid", self.voxelGrid)
        self.pipeline.getRenderPassManager().registerStaticVariable("cloudStartHeight", self.cloudStartHeight)
        self.pipeline.getRenderPassManager().registerStaticVariable("cloudEndHeight", self.cloudEndHeight)
        self.pipeline.getRenderPassManager().registerStaticVariable("cloudNoise", self.cloudNoise)
        self.pipeline.getRenderPassManager().registerDefine("CLOUDS_ENABLED", 1)
Esempio n. 3
0
    def create(self):
        """ Creates the passes required to compute the occlusion, selecting
        the appropriate pass for the selected technique """

        technique = self.pipeline.settings.occlusionTechnique

        if technique not in self.availableTechniques:
            self.error("Unrecognized technique: " + technique)
            return

        if technique == "None":
            return

        # Create the ambient occlusion pass. The technique is selected in the
        # shader later, based on the defines
        self.aoPass = AmbientOcclusionPass()
        self.pipeline.getRenderPassManager().registerPass(self.aoPass)

        # Create the ambient occlusion blur pass
        self.blurPass = OcclusionBlurPass()
        self.pipeline.getRenderPassManager().registerPass(self.blurPass)

        # Register the configuration defines
        self.pipeline.getRenderPassManager().registerDefine(
            "OCCLUSION_TECHNIQUE_" + technique, 1)
        self.pipeline.getRenderPassManager().registerDefine("USE_OCCLUSION", 1)
        self.pipeline.getRenderPassManager().registerDefine(
            "OCCLUSION_RADIUS", self.pipeline.settings.occlusionRadius)
        self.pipeline.getRenderPassManager().registerDefine(
            "OCCLUSION_STRENGTH", self.pipeline.settings.occlusionStrength)
        self.pipeline.getRenderPassManager().registerDefine(
            "OCCLUSION_SAMPLES", self.pipeline.settings.occlusionSampleCount)
        if self.pipeline.settings.useLowQualityBlur:
            self.pipeline.getRenderPassManager().registerDefine(
                "USE_LOW_QUALITY_BLUR", 1)
        if self.pipeline.settings.useOcclusionNoise:
            self.pipeline.getRenderPassManager().registerDefine(
                "USE_OCCLUSION_NOISE", 1)

        if self.pipeline.settings.useTemporalOcclusion:

            # Create a texture to store the last frame occlusion
            self.lastFrameOcclusionTex = Texture("LastFrameOcclusion")
            self.lastFrameOcclusionTex.setup2dTexture(Globals.resolution.x,
                                                      Globals.resolution.y,
                                                      Texture.TFloat,
                                                      Texture.FR16)
            self.pipeline.getRenderPassManager().registerStaticVariable(
                "lastFrameOcclusion", self.lastFrameOcclusionTex)

            BufferViewerGUI.registerTexture("LastFrameOcclusion",
                                            self.lastFrameOcclusionTex)
            MemoryMonitor.addTexture("LastFrameOcclusion",
                                     self.lastFrameOcclusionTex)
            self.pipeline.getRenderPassManager().registerDefine(
                "USE_TEMPORAL_OCCLUSION", 1)
            self.combinePass = OcclusionCombinePass()
            self.pipeline.getRenderPassManager().registerPass(self.combinePass)
Esempio n. 4
0
    def _createLastFrameBuffers(self):
        """ Creates the buffers which store the last frame depth, as the render
        target matcher cannot handle this """

        self.lastFrameDepth = Texture("LastFrameDepth")
        self.lastFrameDepth.setup2dTexture(Globals.resolution.x, Globals.resolution.y,
            Texture.TFloat, Texture.FR32)
        BufferViewerGUI.registerTexture("LastFrameDepth", self.lastFrameDepth)
        MemoryMonitor.addTexture("LastFrameDepth", self.lastFrameDepth)
        self.renderPassManager.registerStaticVariable("lastFrameDepth", self.lastFrameDepth)
    def create(self):
        """ Creates the passes required to compute the occlusion, selecting
        the appropriate pass for the selected technique """

        technique = self.pipeline.settings.occlusionTechnique

        if technique not in self.availableTechniques:
            self.error("Unrecognized technique: " + technique)
            return

        if technique == "None":
            return

        # Create the ambient occlusion pass. The technique is selected in the 
        # shader later, based on the defines
        self.aoPass = AmbientOcclusionPass()
        self.pipeline.getRenderPassManager().registerPass(self.aoPass)

        # Create the ambient occlusion blur pass
        self.blurPass = OcclusionBlurPass()
        self.pipeline.getRenderPassManager().registerPass(self.blurPass)

        # Register the configuration defines
        self.pipeline.getRenderPassManager().registerDefine("OCCLUSION_TECHNIQUE_" + technique, 1)
        self.pipeline.getRenderPassManager().registerDefine("USE_OCCLUSION", 1)
        self.pipeline.getRenderPassManager().registerDefine("OCCLUSION_RADIUS", 
            self.pipeline.settings.occlusionRadius)
        self.pipeline.getRenderPassManager().registerDefine("OCCLUSION_STRENGTH", 
            self.pipeline.settings.occlusionStrength)
        self.pipeline.getRenderPassManager().registerDefine("OCCLUSION_SAMPLES", 
            self.pipeline.settings.occlusionSampleCount)
        if self.pipeline.settings.useLowQualityBlur:
            self.pipeline.getRenderPassManager().registerDefine("USE_LOW_QUALITY_BLUR", 1)
        if self.pipeline.settings.useOcclusionNoise:
            self.pipeline.getRenderPassManager().registerDefine("USE_OCCLUSION_NOISE", 1)


        if self.pipeline.settings.useTemporalOcclusion:
            
            # Create a texture to store the last frame occlusion
            self.lastFrameOcclusionTex = Texture("LastFrameOcclusion")
            self.lastFrameOcclusionTex.setup2dTexture(Globals.base.win.getXSize(),
                Globals.base.win.getYSize(), Texture.TFloat, Texture.FR16)
            self.pipeline.getRenderPassManager().registerStaticVariable("lastFrameOcclusion", self.lastFrameOcclusionTex)

            BufferViewerGUI.registerTexture("LastFrameOcclusion", self.lastFrameOcclusionTex)
            MemoryMonitor.addTexture("LastFrameOcclusion", self.lastFrameOcclusionTex)
            self.pipeline.getRenderPassManager().registerDefine("USE_TEMPORAL_OCCLUSION", 1)
            self.combinePass = OcclusionCombinePass()
            self.pipeline.getRenderPassManager().registerPass(self.combinePass)
    def initTransparencyPass(self):
        """ Creates the pass which renders the transparent objects into the scene """
        self.transparencyPass = TransparencyPass()
        self.pipeline.getRenderPassManager().registerPass(self.transparencyPass)

        # Create the atomic counter which stores the amount of rendered transparent
        # pixels. For now this a 1x1 texture, as atomic counters are not implemented.
        self.pixelCountBuffer = Texture("MaterialCountBuffer")
        self.pixelCountBuffer.setup2dTexture(1, 1, Texture.TInt, Texture.FR32i)

        # Creates the buffer which stores all transparent pixels. Pixels are inserted
        # into the buffer in the order they are rendered, using the pixelCountBuffer
        # to determine their index 
        self.materialDataBuffer = Texture("MaterialDataBuffer")
        self.materialDataBuffer.setupBufferTexture(self.maxPixelCount, Texture.TFloat, 
            Texture.FRgba32, GeomEnums.UH_static)

        # Creates the list head buffer, which stores the first transparent pixel for
        # each window pixel. The index stored in this buffer is the index into the 
        # materialDataBuffer
        self.listHeadBuffer = Texture("ListHeadBuffer")
        self.listHeadBuffer.setup2dTexture(self.pipeline.getSize().x, self.pipeline.getSize().y, 
            Texture.TInt, Texture.FR32i)

        # Creates the spinlock buffer, which ensures that writing to the listHeadBuffer
        # is sequentially
        self.spinLockBuffer = Texture("SpinLockBuffer")
        self.spinLockBuffer.setup2dTexture(self.pipeline.getSize().x, self.pipeline.getSize().y, 
            Texture.TInt, Texture.FR32i)

        # Set the buffers as input to the main scene. Maybe we can do this more elegant
        target = self.pipeline.showbase.render
        target.setShaderInput("pixelCountBuffer", self.pixelCountBuffer)
        target.setShaderInput("spinLockBuffer", self.spinLockBuffer)
        target.setShaderInput("materialDataBuffer", self.materialDataBuffer)
        target.setShaderInput("listHeadBuffer", self.listHeadBuffer)

        # Provides the buffers as global shader inputs
        self.pipeline.getRenderPassManager().registerStaticVariable("transpPixelCountBuffer", self.pixelCountBuffer)
        self.pipeline.getRenderPassManager().registerStaticVariable("transpSpinLockBuffer", self.spinLockBuffer)
        self.pipeline.getRenderPassManager().registerStaticVariable("transpListHeadBuffer", self.listHeadBuffer)
        self.pipeline.getRenderPassManager().registerStaticVariable("transpMaterialDataBuffer", self.materialDataBuffer)

        # Registers the transparency settings to the shaders
        self.pipeline.getRenderPassManager().registerDefine("USE_TRANSPARENCY", 1)
        self.pipeline.getRenderPassManager().registerDefine("MAX_TRANSPARENCY_LAYERS", 
            self.pipeline.settings.maxTransparencyLayers)

        self.pixelCountBuffer.setClearColor(Vec4(0, 0, 0, 0))
        self.spinLockBuffer.setClearColor(Vec4(0, 0, 0, 0))
        self.listHeadBuffer.setClearColor(Vec4(0, 0, 0, 0))

        MemoryMonitor.addTexture("MaterialCountBuffer", self.pixelCountBuffer)
        MemoryMonitor.addTexture("MaterialDataBuffer", self.materialDataBuffer)
        MemoryMonitor.addTexture("ListHeadBuffer", self.listHeadBuffer)
        MemoryMonitor.addTexture("SpinLockBuffer", self.spinLockBuffer)
Esempio n. 7
0
    def _makeRenderedLightsBuffer(self):
        """ Creates the buffer which stores the indices of all rendered lights """

        bufferSize = 16
        bufferSize += LightLimits.maxLights["PointLight"]
        bufferSize += LightLimits.maxLights["PointLightShadow"]
        bufferSize += LightLimits.maxLights["DirectionalLight"]
        bufferSize += LightLimits.maxLights["DirectionalLightShadow"]
        bufferSize += LightLimits.maxLights["SpotLight"]
        bufferSize += LightLimits.maxLights["SpotLightShadow"]

        self.renderedLightsBuffer = Texture("RenderedLightsBuffer")
        self.renderedLightsBuffer.setupBufferTexture(bufferSize, Texture.TInt, Texture.FR32i, GeomEnums.UHDynamic)

        self.pipeline.getRenderPassManager().registerStaticVariable(
            "renderedLightsBuffer", self.renderedLightsBuffer)

        MemoryMonitor.addTexture("Rendered Lights Buffer", self.renderedLightsBuffer)
Esempio n. 8
0
    def _makeRenderedLightsBuffer(self):
        """ Creates the buffer which stores the indices of all rendered lights """

        bufferSize = 16
        bufferSize += LightLimits.maxLights["PointLight"]
        bufferSize += LightLimits.maxLights["PointLightShadow"]
        bufferSize += LightLimits.maxLights["DirectionalLight"]
        bufferSize += LightLimits.maxLights["DirectionalLightShadow"]
        bufferSize += LightLimits.maxLights["SpotLight"]
        bufferSize += LightLimits.maxLights["SpotLightShadow"]

        self.renderedLightsBuffer = Texture("RenderedLightsBuffer")
        self.renderedLightsBuffer.setupBufferTexture(bufferSize, Texture.TInt,
                                                     Texture.FR32i,
                                                     GeomEnums.UHDynamic)

        self.pipeline.getRenderPassManager().registerStaticVariable(
            "renderedLightsBuffer", self.renderedLightsBuffer)

        MemoryMonitor.addTexture("Rendered Lights Buffer",
                                 self.renderedLightsBuffer)
Esempio n. 9
0
    def create(self):
        """ Creates the passes """
        self.cloudStartHeight = 900.0
        self.cloudEndHeight = 3300.0
        self.cloudResolution = 768
        self.cloudResolutionH = 128

        self.voxelGrid = Texture("CloudVoxelGrid")
        self.voxelGrid.setup3dTexture(self.cloudResolution,
                                      self.cloudResolution,
                                      self.cloudResolutionH, Texture.TFloat,
                                      Texture.FR16)
        self.voxelGrid.setWrapU(Texture.WMRepeat)
        self.voxelGrid.setWrapV(Texture.WMRepeat)
        self.voxelGrid.setWrapW(Texture.WMClamp)

        self.cloudNoise = Texture("CloudNoise")
        self.cloudNoise.setup3dTexture(64, 64, 64, Texture.TFloat,
                                       Texture.FR16)
        self.cloudNoise.setWrapU(Texture.WMRepeat)
        self.cloudNoise.setWrapV(Texture.WMRepeat)
        self.cloudNoise.setWrapW(Texture.WMRepeat)

        MemoryMonitor.addTexture("CloudVoxelGrid", self.voxelGrid)
        MemoryMonitor.addTexture("CloudNoise", self.cloudNoise)

        self._createInitialGrid()

        self.renderPass = CloudRenderPass()
        self.pipeline.getRenderPassManager().registerPass(self.renderPass)
        self.pipeline.getRenderPassManager().registerStaticVariable(
            "cloudVoxelGrid", self.voxelGrid)
        self.pipeline.getRenderPassManager().registerStaticVariable(
            "cloudStartHeight", self.cloudStartHeight)
        self.pipeline.getRenderPassManager().registerStaticVariable(
            "cloudEndHeight", self.cloudEndHeight)
        self.pipeline.getRenderPassManager().registerStaticVariable(
            "cloudNoise", self.cloudNoise)
        self.pipeline.getRenderPassManager().registerDefine(
            "CLOUDS_ENABLED", 1)
    def init(self):
        """ Initializes the vertex buffers and makes them available as shader
        inputs. """

        self.vertexBuffers = []

        for i in xrange(2):
            vertexBuffer = Texture("VertexPositionBuffer-" + str(i))
            vertexBuffer.setup2dTexture(self.split, self.maxVertexCount / self.split, Texture.TFloat, Texture.FRgba32)
            vertexBuffer.setClearColor(Vec4(0))
            vertexBuffer.clearImage()

            MemoryMonitor.addTexture("DynamicObjectVtxBuffer"+str(i), vertexBuffer)
            Globals.render.setShaderInput("dynamicObjectVtxBuffer"+str(i), vertexBuffer)

            BufferViewerGUI.registerTexture("Vtx Positions " + str(i), vertexBuffer)
            vertexBuffer.setWrapU(Texture.WMClamp)
            vertexBuffer.setWrapV(Texture.WMClamp)
            vertexBuffer.setMinfilter(Texture.FTNearest)
            vertexBuffer.setMagfilter(Texture.FTNearest)
            self.vertexBuffers.append(vertexBuffer)

        Globals.render.setShaderInput("dynamicVtxSplit", self.split)
Esempio n. 11
0
    def setup(self):
        """ Setups everything for the GI to work """
        assert (self.distributionSteps % 2 == 0)

        self._createDebugTexts()

        self.pipeline.getRenderPassManager().registerDefine(
            "USE_GLOBAL_ILLUMINATION", 1)
        self.pipeline.getRenderPassManager().registerDefine(
            "GI_SLIDE_COUNT", self.slideCount)
        self.pipeline.getRenderPassManager().registerDefine(
            "GI_QUALITY_LEVEL", self.qualityLevelIndex)

        # make the grid resolution a constant
        self.pipeline.getRenderPassManager().registerDefine(
            "GI_GRID_RESOLUTION", self.voxelGridResolution)

        self.taskManager.addTask(3, self.stepVoxelize)
        self.taskManager.addTask(self.distributionSteps, self.stepDistribute)

        # Create the voxelize pass which is used to voxelize the scene from
        # several directions
        self.voxelizePass = VoxelizePass(self.pipeline)
        self.voxelizePass.setVoxelGridResolution(self.voxelGridResolution)
        self.voxelizePass.setVoxelGridSize(self.voxelGridSize)
        self.voxelizePass.setGridResolutionMultiplier(1)
        self.pipeline.getRenderPassManager().registerPass(self.voxelizePass)

        self.generationTextures = []

        # Create the buffers used to create the voxel grid
        for color in "rgb":
            tex = Texture("VoxelGeneration-" + color)
            tex.setup3dTexture(self.voxelGridResolution,
                               self.voxelGridResolution,
                               self.voxelGridResolution, Texture.TInt,
                               Texture.FR32)
            tex.setClearColor(Vec4(0))
            self.generationTextures.append(tex)
            Globals.render.setShaderInput("voxelGenDest" + color.upper(), tex)

            MemoryMonitor.addTexture("VoxelGenerationTex-" + color.upper(),
                                     tex)

        self.bindTo(Globals.render, "giData")

        self.convertGridTarget = RenderTarget("ConvertGIGrid")
        self.convertGridTarget.setSize(
            self.voxelGridResolution * self.slideCount,
            self.voxelGridResolution * self.slideVertCount)

        if self.pipeline.settings.useDebugAttachments:
            self.convertGridTarget.addColorTexture()
        self.convertGridTarget.prepareOffscreenBuffer()

        # Set a near-filter to the texture
        if self.pipeline.settings.useDebugAttachments:
            self.convertGridTarget.getColorTexture().setMinfilter(
                Texture.FTNearest)
            self.convertGridTarget.getColorTexture().setMagfilter(
                Texture.FTNearest)

        self.clearGridTarget = RenderTarget("ClearGIGrid")
        self.clearGridTarget.setSize(
            self.voxelGridResolution * self.slideCount,
            self.voxelGridResolution * self.slideVertCount)
        if self.pipeline.settings.useDebugAttachments:
            self.clearGridTarget.addColorTexture()
        self.clearGridTarget.prepareOffscreenBuffer()

        for idx, color in enumerate("rgb"):
            self.convertGridTarget.setShaderInput(
                "voxelGenSrc" + color.upper(), self.generationTextures[idx])
            self.clearGridTarget.setShaderInput("voxelGenTex" + color.upper(),
                                                self.generationTextures[idx])

        # Create the data textures
        self.dataTextures = []
        self.directions = ["PosX", "NegX", "PosY", "NegY", "PosZ", "NegZ"]

        for i, direction in enumerate(self.directions):
            tex = Texture("GIDataTex" + direction)
            tex.setup3dTexture(self.voxelGridResolution,
                               self.voxelGridResolution,
                               self.voxelGridResolution, Texture.TFloat,
                               Texture.FR11G11B10)
            MemoryMonitor.addTexture("VoxelDataTex-" + direction, tex)
            self.dataTextures.append(tex)
            self.pipeline.getRenderPassManager().registerStaticVariable(
                "giVoxelData" + direction, tex)

        # Create ping / pong textures
        self.pingDataTextures = []
        self.pongDataTextures = []

        for i, direction in enumerate(self.directions):
            texPing = Texture("GIPingDataTex" + direction)
            texPing.setup3dTexture(self.voxelGridResolution,
                                   self.voxelGridResolution,
                                   self.voxelGridResolution, Texture.TFloat,
                                   Texture.FR11G11B10)
            MemoryMonitor.addTexture("VoxelPingDataTex-" + direction, texPing)
            self.pingDataTextures.append(texPing)

            texPong = Texture("GIPongDataTex" + direction)
            texPong.setup3dTexture(self.voxelGridResolution,
                                   self.voxelGridResolution,
                                   self.voxelGridResolution, Texture.TFloat,
                                   Texture.FR11G11B10)
            MemoryMonitor.addTexture("VoxelPongDataTex-" + direction, texPong)
            self.pongDataTextures.append(texPong)

            self.convertGridTarget.setShaderInput("voxelDataDest" + direction,
                                                  self.pingDataTextures[i])
            # self.clearGridTarget.setShaderInput("voxelDataDest" + str(i), self.pongDataTextures[i])

        # Set texture wrap modes
        for tex in self.pingDataTextures + self.pongDataTextures + self.dataTextures + self.generationTextures:
            tex.setMinfilter(Texture.FTLinear)
            tex.setMagfilter(Texture.FTLinear)
            tex.setWrapU(Texture.WMBorderColor)
            tex.setWrapV(Texture.WMBorderColor)
            tex.setWrapW(Texture.WMBorderColor)
            tex.setAnisotropicDegree(0)
            tex.setBorderColor(Vec4(0))

        for tex in self.dataTextures:
            tex.setMinfilter(Texture.FTLinear)
            tex.setMagfilter(Texture.FTLinear)

        self.distributeTarget = RenderTarget("DistributeVoxels")
        self.distributeTarget.setSize(
            self.voxelGridResolution * self.slideCount,
            self.voxelGridResolution * self.slideVertCount)
        if self.pipeline.settings.useDebugAttachments:
            self.distributeTarget.addColorTexture()
        self.distributeTarget.prepareOffscreenBuffer()

        # Set a near-filter to the texture
        if self.pipeline.settings.useDebugAttachments:
            self.distributeTarget.getColorTexture().setMinfilter(
                Texture.FTNearest)
            self.distributeTarget.getColorTexture().setMagfilter(
                Texture.FTNearest)

        self.distributeTarget.setShaderInput("isLastStep", False)

        # Create solidness texture
        self.voxelSolidTex = Texture("GIDataSolidTex")
        self.voxelSolidTex.setup3dTexture(self.voxelGridResolution,
                                          self.voxelGridResolution,
                                          self.voxelGridResolution,
                                          Texture.TFloat, Texture.FR16)
        self.convertGridTarget.setShaderInput("voxelSolidDest",
                                              self.voxelSolidTex)
        self.distributeTarget.setShaderInput("voxelSolidTex",
                                             self.voxelSolidTex)
        MemoryMonitor.addTexture("VoxelSolidTex", self.voxelSolidTex)

        self.voxelSolidStableTex = Texture("GIDataSolidStableTex")
        self.voxelSolidStableTex.setup3dTexture(self.voxelGridResolution,
                                                self.voxelGridResolution,
                                                self.voxelGridResolution,
                                                Texture.TFloat, Texture.FR16)

        self.distributeTarget.setShaderInput("voxelSolidWriteTex",
                                             self.voxelSolidStableTex)
        self.pipeline.getRenderPassManager().registerStaticVariable(
            "giVoxelSolidTex", self.voxelSolidStableTex)

        # Create the final gi pass
        self.finalPass = GlobalIlluminationPass()
        self.pipeline.getRenderPassManager().registerPass(self.finalPass)
        self.pipeline.getRenderPassManager().registerDynamicVariable(
            "giData", self.bindTo)
        self.pipeline.getRenderPassManager().registerStaticVariable(
            "giReadyState", self.readyStateFlag)

        # Visualize voxels
        if False:
            self.voxelCube = loader.loadModel("Box")
            self.voxelCube.reparentTo(render)
            # self.voxelCube.setTwoSided(True)
            self.voxelCube.node().setFinal(True)
            self.voxelCube.node().setBounds(OmniBoundingVolume())
            self.voxelCube.setInstanceCount(self.voxelGridResolution**3)
            # self.voxelCube.hide()
            self.bindTo(self.voxelCube, "giData")

            for i in xrange(5):
                self.voxelCube.setShaderInput("giDataTex" + str(i),
                                              self.pingDataTextures[i])

        self.disableTargets()
    def setup(self):
        """ Setups everything for the GI to work """
        assert(self.distributionSteps % 2 == 0)

        self._createDebugTexts()

        self.pipeline.getRenderPassManager().registerDefine("USE_GLOBAL_ILLUMINATION", 1)
        self.pipeline.getRenderPassManager().registerDefine("GI_SLIDE_COUNT", self.slideCount)
        self.pipeline.getRenderPassManager().registerDefine("GI_QUALITY_LEVEL", self.qualityLevelIndex)

        # make the grid resolution a constant
        self.pipeline.getRenderPassManager().registerDefine("GI_GRID_RESOLUTION", self.voxelGridResolution)

        self.taskManager.addTask(3, self.stepVoxelize)
        self.taskManager.addTask(self.distributionSteps, self.stepDistribute)

        # Create the voxelize pass which is used to voxelize the scene from
        # several directions
        self.voxelizePass = VoxelizePass(self.pipeline)
        self.voxelizePass.setVoxelGridResolution(self.voxelGridResolution)
        self.voxelizePass.setVoxelGridSize(self.voxelGridSize)
        self.voxelizePass.setGridResolutionMultiplier(1)
        self.pipeline.getRenderPassManager().registerPass(self.voxelizePass)

        self.generationTextures = []

        # Create the buffers used to create the voxel grid
        for color in "rgb":
            tex = Texture("VoxelGeneration-" + color)
            tex.setup3dTexture(self.voxelGridResolution, self.voxelGridResolution, self.voxelGridResolution, Texture.TInt, Texture.FR32)
            tex.setClearColor(Vec4(0))
            self.generationTextures.append(tex)
            Globals.render.setShaderInput("voxelGenDest" + color.upper(), tex)
            
            MemoryMonitor.addTexture("VoxelGenerationTex-" + color.upper(), tex)

        self.bindTo(Globals.render, "giData")

        self.convertGridTarget = RenderTarget("ConvertGIGrid")
        self.convertGridTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideVertCount)

        if self.pipeline.settings.useDebugAttachments:
            self.convertGridTarget.addColorTexture()
        self.convertGridTarget.prepareOffscreenBuffer()

        # Set a near-filter to the texture
        if self.pipeline.settings.useDebugAttachments:
            self.convertGridTarget.getColorTexture().setMinfilter(Texture.FTNearest)
            self.convertGridTarget.getColorTexture().setMagfilter(Texture.FTNearest)

        self.clearGridTarget = RenderTarget("ClearGIGrid")
        self.clearGridTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideVertCount)
        if self.pipeline.settings.useDebugAttachments:
            self.clearGridTarget.addColorTexture()
        self.clearGridTarget.prepareOffscreenBuffer()

        for idx, color in enumerate("rgb"):
            self.convertGridTarget.setShaderInput("voxelGenSrc" + color.upper(), self.generationTextures[idx])
            self.clearGridTarget.setShaderInput("voxelGenTex" + color.upper(), self.generationTextures[idx])


        # Create the data textures
        self.dataTextures = []
        self.directions = ["PosX", "NegX", "PosY", "NegY", "PosZ", "NegZ"]

        for i, direction in enumerate(self.directions):
            tex = Texture("GIDataTex" + direction)
            tex.setup3dTexture(self.voxelGridResolution, self.voxelGridResolution, self.voxelGridResolution, Texture.TFloat, Texture.FR11G11B10)
            MemoryMonitor.addTexture("VoxelDataTex-" + direction, tex)
            self.dataTextures.append(tex)
            self.pipeline.getRenderPassManager().registerStaticVariable("giVoxelData" + direction, tex)


        # Create ping / pong textures
        self.pingDataTextures = []
        self.pongDataTextures = []

        for i, direction in enumerate(self.directions):
            texPing = Texture("GIPingDataTex" + direction)
            texPing.setup3dTexture(self.voxelGridResolution, self.voxelGridResolution, self.voxelGridResolution, Texture.TFloat, Texture.FR11G11B10)
            MemoryMonitor.addTexture("VoxelPingDataTex-" + direction, texPing)
            self.pingDataTextures.append(texPing)

            texPong = Texture("GIPongDataTex" + direction)
            texPong.setup3dTexture(self.voxelGridResolution, self.voxelGridResolution, self.voxelGridResolution, Texture.TFloat, Texture.FR11G11B10)
            MemoryMonitor.addTexture("VoxelPongDataTex-" + direction, texPong)
            self.pongDataTextures.append(texPong)

            self.convertGridTarget.setShaderInput("voxelDataDest"+direction, self.pingDataTextures[i])
            # self.clearGridTarget.setShaderInput("voxelDataDest" + str(i), self.pongDataTextures[i])
        
        # Set texture wrap modes
        for tex in self.pingDataTextures + self.pongDataTextures + self.dataTextures + self.generationTextures:
            tex.setMinfilter(Texture.FTLinear)
            tex.setMagfilter(Texture.FTLinear)
            tex.setWrapU(Texture.WMBorderColor)
            tex.setWrapV(Texture.WMBorderColor)
            tex.setWrapW(Texture.WMBorderColor)
            tex.setAnisotropicDegree(0)
            tex.setBorderColor(Vec4(0))

        for tex in self.dataTextures:
            tex.setMinfilter(Texture.FTLinear)
            tex.setMagfilter(Texture.FTLinear)

        self.distributeTarget = RenderTarget("DistributeVoxels")
        self.distributeTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideVertCount)
        if self.pipeline.settings.useDebugAttachments:
            self.distributeTarget.addColorTexture()
        self.distributeTarget.prepareOffscreenBuffer()

        # Set a near-filter to the texture
        if self.pipeline.settings.useDebugAttachments:
            self.distributeTarget.getColorTexture().setMinfilter(Texture.FTNearest)
            self.distributeTarget.getColorTexture().setMagfilter(Texture.FTNearest)

        self.distributeTarget.setShaderInput("isLastStep", False)

        # Create solidness texture
        self.voxelSolidTex = Texture("GIDataSolidTex")
        self.voxelSolidTex.setup3dTexture(self.voxelGridResolution, self.voxelGridResolution, self.voxelGridResolution, Texture.TFloat, Texture.FR16)
        self.convertGridTarget.setShaderInput("voxelSolidDest", self.voxelSolidTex)
        self.distributeTarget.setShaderInput("voxelSolidTex", self.voxelSolidTex)
        MemoryMonitor.addTexture("VoxelSolidTex", self.voxelSolidTex)

        self.voxelSolidStableTex = Texture("GIDataSolidStableTex")
        self.voxelSolidStableTex.setup3dTexture(self.voxelGridResolution, self.voxelGridResolution, self.voxelGridResolution, Texture.TFloat, Texture.FR16)

        self.distributeTarget.setShaderInput("voxelSolidWriteTex", self.voxelSolidStableTex)
        self.pipeline.getRenderPassManager().registerStaticVariable("giVoxelSolidTex", self.voxelSolidStableTex)





        # Create the final gi pass
        self.finalPass = GlobalIlluminationPass()
        self.pipeline.getRenderPassManager().registerPass(self.finalPass)
        self.pipeline.getRenderPassManager().registerDynamicVariable("giData", self.bindTo)
        self.pipeline.getRenderPassManager().registerStaticVariable("giReadyState", self.readyStateFlag)


        # Visualize voxels
        if False:
            self.voxelCube = loader.loadModel("Box")
            self.voxelCube.reparentTo(render)
            # self.voxelCube.setTwoSided(True)
            self.voxelCube.node().setFinal(True)
            self.voxelCube.node().setBounds(OmniBoundingVolume())
            self.voxelCube.setInstanceCount(self.voxelGridResolution**3)
            # self.voxelCube.hide()
            self.bindTo(self.voxelCube, "giData")
            
            for i in xrange(5):
                self.voxelCube.setShaderInput("giDataTex" + str(i), self.pingDataTextures[i])

        self.disableTargets()
Esempio n. 13
0
    def setup(self):
        """ Setups everything for the GI to work """


        # Create the voxelize pass which is used to voxelize the scene from
        # several directions
        self.voxelizePass = VoxelizePass()
        self.voxelizePass.setVoxelGridResolution(self.voxelGridResolution)
        self.voxelizePass.setVoxelGridSize(self.voxelGridSizeWS)
        self.voxelizePass.initVoxelStorage()
        self.pipeline.getRenderPassManager().registerPass(self.voxelizePass)

        # Create 3D Texture which is a copy of the voxel generation grid but
        # stable, as the generation grid is updated part by part and that would 
        # lead to flickering
        self.voxelStableTex = Texture("VoxelsStable")
        self.voxelStableTex.setup3dTexture(self.voxelGridResolution.x, self.voxelGridResolution.y, 
                                            self.voxelGridResolution.z, Texture.TFloat, Texture.FRgba8)

        # Set appropriate filter types:
        # The stable texture has mipmaps, which are generated during the process.
        # This is required for cone tracing.
        self.voxelStableTex.setMagfilter(SamplerState.FTLinear)
        self.voxelStableTex.setMinfilter(SamplerState.FTLinearMipmapLinear)
        self.voxelStableTex.setWrapU(SamplerState.WMBorderColor)
        self.voxelStableTex.setWrapV(SamplerState.WMBorderColor)
        self.voxelStableTex.setWrapW(SamplerState.WMBorderColor)
        self.voxelStableTex.setBorderColor(Vec4(0,0,0,0))

        MemoryMonitor.addTexture("Voxel Grid Texture", self.voxelStableTex)

        # Setups the render target to convert the voxel grid
        self.convertBuffer = RenderTarget("VoxelConvertBuffer")
        self.convertBuffer.setSize(self.voxelGridResolution.x, self.voxelGridResolution.y)
        self.convertBuffer.setColorWrite(False)
        # self.convertBuffer.addColorTexture()
        self.convertBuffer.prepareOffscreenBuffer()
        self.convertBuffer.setShaderInput("src", self.voxelizePass.getVoxelTex())
        self.convertBuffer.setShaderInput("dest", self.voxelStableTex)
        self.convertBuffer.setActive(False)

        # Store the frame index, we need that to decide which step we are currently
        # doing
        self.frameIndex = 0


        # Create the various render targets to generate the mipmaps of the stable voxel grid
        self.mipmapTargets = []
        computeSize = LVecBase3i(self.voxelGridResolution)
        currentMipmap = 0
        while computeSize.z > 1:
            computeSize /= 2
            target = RenderTarget("GIMiplevel" + str(currentMipmap))
            target.setSize(computeSize.x, computeSize.y)
            target.setColorWrite(False)
            # target.addColorTexture()
            target.prepareOffscreenBuffer()
            target.setActive(False)
            target.setShaderInput("sourceMipmap", currentMipmap)
            target.setShaderInput("source", self.voxelStableTex)
            target.setShaderInput("dest", self.voxelStableTex, False, True, -1, currentMipmap + 1)
            self.mipmapTargets.append(target)
            currentMipmap += 1


        # Create the final gi pass
        self.finalPass = GlobalIlluminationPass()
        self.pipeline.getRenderPassManager().registerPass(self.finalPass)
        self.pipeline.getRenderPassManager().registerDynamicVariable("giVoxelGridData", self.bindTo)
Esempio n. 14
0
    def initTransparencyPass(self):
        """ Creates the pass which renders the transparent objects into the scene """
        self.transparencyPass = TransparencyPass()
        self.pipeline.getRenderPassManager().registerPass(
            self.transparencyPass)

        self.transparencyShadePass = TransparencyShadePass(self.pipeline)
        self.transparencyShadePass.setBatchSize(
            self.pipeline.settings.transparencyBatchSize)
        self.pipeline.getRenderPassManager().registerPass(
            self.transparencyShadePass)

        # Create the atomic counter which stores the amount of rendered transparent
        # pixels. For now this a 1x1 texture, as atomic counters are not implemented.
        self.pixelCountBuffer = Texture("MaterialCountBuffer")
        self.pixelCountBuffer.setup2dTexture(1, 1, Texture.TInt, Texture.FR32i)

        # Creates the buffer which stores all transparent pixels. Pixels are inserted
        # into the buffer in the order they are rendered, using the pixelCountBuffer
        # to determine their index
        self.materialDataBuffer = Texture("MaterialDataBuffer")
        self.materialDataBuffer.setupBufferTexture(self.maxPixelCount,
                                                   Texture.TFloat,
                                                   Texture.FRgba32,
                                                   GeomEnums.UH_static)

        # Creates the list head buffer, which stores the first transparent pixel for
        # each window pixel. The index stored in this buffer is the index into the
        # materialDataBuffer
        self.listHeadBuffer = Texture("ListHeadBuffer")
        self.listHeadBuffer.setup2dTexture(Gloabls.resolution.x,
                                           Globals.resolution.y, Texture.TInt,
                                           Texture.FR32i)

        # Creates the spinlock buffer, which ensures that writing to the listHeadBuffer
        # is sequentially
        self.spinLockBuffer = Texture("SpinLockBuffer")
        self.spinLockBuffer.setup2dTexture(Gloabls.resolution.x,
                                           Globals.resolution.y, Texture.TInt,
                                           Texture.FR32i)

        # Set the buffers as input to the main scene. Maybe we can do this more elegant
        target = self.pipeline.showbase.render
        target.setShaderInput("pixelCountBuffer", self.pixelCountBuffer)
        target.setShaderInput("spinLockBuffer", self.spinLockBuffer)
        target.setShaderInput("materialDataBuffer", self.materialDataBuffer)
        target.setShaderInput("listHeadBuffer", self.listHeadBuffer)

        # Provides the buffers as global shader inputs
        self.pipeline.getRenderPassManager().registerStaticVariable(
            "transpPixelCountBuffer", self.pixelCountBuffer)
        self.pipeline.getRenderPassManager().registerStaticVariable(
            "transpSpinLockBuffer", self.spinLockBuffer)
        self.pipeline.getRenderPassManager().registerStaticVariable(
            "transpListHeadBuffer", self.listHeadBuffer)
        self.pipeline.getRenderPassManager().registerStaticVariable(
            "transpMaterialDataBuffer", self.materialDataBuffer)

        # Registers the transparency settings to the shaders
        self.pipeline.getRenderPassManager().registerDefine(
            "USE_TRANSPARENCY", 1)
        self.pipeline.getRenderPassManager().registerDefine(
            "MAX_TRANSPARENCY_LAYERS",
            self.pipeline.settings.maxTransparencyLayers)

        self.pipeline.getRenderPassManager().registerDefine(
            "TRANSPARENCY_RANGE", self.pipeline.settings.maxTransparencyRange)

        self.pipeline.getRenderPassManager().registerDefine(
            "TRANSPARENCY_BATCH_SIZE",
            self.pipeline.settings.transparencyBatchSize)

        self.pixelCountBuffer.setClearColor(Vec4(0, 0, 0, 0))
        self.spinLockBuffer.setClearColor(Vec4(0, 0, 0, 0))
        self.listHeadBuffer.setClearColor(Vec4(0, 0, 0, 0))

        MemoryMonitor.addTexture("MaterialCountBuffer", self.pixelCountBuffer)
        MemoryMonitor.addTexture("MaterialDataBuffer", self.materialDataBuffer)
        MemoryMonitor.addTexture("ListHeadBuffer", self.listHeadBuffer)
        MemoryMonitor.addTexture("SpinLockBuffer", self.spinLockBuffer)