def create(self):
        self.targetV = RenderTarget("OcclusionBlurV")
        self.targetV.addColorTexture()
        self.targetV.setColorBits(16)
        self.targetV.prepareOffscreenBuffer()
 
        self.targetH = RenderTarget("OcclusionBlurH")
        self.targetH.addColorTexture()
        self.targetH.setColorBits(16)
        self.targetH.prepareOffscreenBuffer()

        self.targetH.setShaderInput("processedSourceTex", self.targetV.getColorTexture())
 def create(self):
     self.target = RenderTarget("GlobalIlluminationPass")
     self.target.setHalfResolution()
     self.target.addColorTexture()
     self.target.addAuxTexture()
     self.target.setColorBits(16)
     self.target.setAuxBits(16)
     self.target.prepareOffscreenBuffer()
    def create(self):
        self.target = RenderTarget("ComputeLightTileBounds")
        self.target.setSize(self.size.x, self.size.y)
        self.target.addColorTexture()
        self.target.prepareOffscreenBuffer()

        self.target.getColorTexture().setMagfilter(SamplerState.FTNearest)

        self.makePerTileStorage()
        self.target.setShaderInput("destinationBuffer", self.lightPerTileBuffer)
Example #4
0
class ScatteringPass(RenderPass):

    """ This pass computes the scattering if specified in the settings """

    def __init__(self):
        RenderPass.__init__(self)

    def getID(self):
        return "ScatteringPass"

    def getRequiredInputs(self):
        return {

            # Scattering
            "transmittanceSampler": ["Variables.transmittanceSampler", "Variables.emptyTextureWhite"],
            "inscatterSampler": ["Variables.inscatterSampler", "Variables.emptyTextureWhite"],
            "scatteringOptions": ["Variables.scatteringOptions", "Variables.null"],

            "mainRender": "Variables.mainRender",
            "cameraPosition": "Variables.cameraPosition",
            "mainCam": "Variables.mainCam",

            "wsPositionTex": "DeferredScenePass.wsPosition",
            "basecolorTex": "DeferredScenePass.data3"
            # "viewSpaceNormals": "ViewSpacePass.normals",
            # "viewSpacePosition": "ViewSpacePass.position"
        }

    def create(self):
        self.target = RenderTarget("Scattering")
        self.target.addColorTexture()
        self.target.setColorBits(16)
        self.target.prepareOffscreenBuffer()
 
    def setShaders(self):
        shader = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/ScatteringPass.fragment")
        self.target.setShader(shader)
        return [shader]

    def getOutputs(self):
        return {
            "ScatteringPass.resultTex": lambda: self.target.getColorTexture(),
        }
class AmbientOcclusionPass(RenderPass):

    """ This pass computes the screen space ambient occlusion if enabled in the
     settings. As many samples are required for a good looking result, the pass
     is done at half resolution and then upscaled by the edge preserving blur
     pass """

    def __init__(self):
        RenderPass.__init__(self)

    def getID(self):
        return "AmbientOcclusionPass"

    def getRequiredInputs(self):
        return {
            "frameIndex": "Variables.frameIndex",
            "mainRender": "Variables.mainRender",
            "mainCam": "Variables.mainCam",
            "noiseTexture": "Variables.noise4x4",
            "viewSpaceNormals": "ViewSpacePass.normals",
            "viewSpacePosition": "ViewSpacePass.position"
        }

    def create(self):
        self.target = RenderTarget("AmbientOcclusion")
        self.target.setHalfResolution()
        self.target.addColorTexture()
        self.target.prepareOffscreenBuffer()
 
    def setShaders(self):
        shader = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/ComputeOcclusion.fragment")
        self.target.setShader(shader)
        return [shader]

    def getOutputs(self):
        return {
            "AmbientOcclusionPass.computeResult": lambda: self.target.getColorTexture(),
        }
class TransparencyPass(RenderPass):

    """ This pass reads the per pixel linked lists generated during the deferred
    scene pass and applies them to the rendered image. To sort the lists a bubble
    sort algorithm is used """

    def __init__(self):
        RenderPass.__init__(self)

    def getID(self):
        return "TransparencyPass"

    def getRequiredInputs(self):
        return {
            "sceneTex": "LightingPass.resultTex",
            "cameraPosition": "Variables.cameraPosition",
            "currentMVP": "Variables.currentMVP",
            "positionTex": "DeferredScenePass.wsPosition",
            "mainCam": "Variables.mainCam",
            "mainRender": "Variables.mainRender",
            "fallbackCubemap": "Variables.defaultEnvironmentCubemap",
            "fallbackCubemapMipmaps": "Variables.defaultEnvironmentCubemapMipmaps",
            "depthTex": "DeferredScenePass.depth",

            "pixelCountBuffer": "Variables.transpPixelCountBuffer",
            "spinLockBuffer": "Variables.transpSpinLockBuffer",
            "listHeadBuffer": "Variables.transpListHeadBuffer",
            "materialDataBuffer": "Variables.transpMaterialDataBuffer",

        }

    def setShaders(self):
        shader = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/TransparencyPass.fragment")
        self.target.setShader(shader)

        return [shader]

    def create(self):
        self.target = RenderTarget("TransparencyPass")
        self.target.addColorTexture()
        self.target.setColorBits(16)
        self.target.prepareOffscreenBuffer()

    def getOutputs(self):
        return {
            "TransparencyPass.resultTex": lambda: self.target.getColorTexture(),
        }
Example #7
0
    def create(self):
        # Create voxelize camera
        self.voxelizeCamera = Camera("VoxelizeScene")
        self.voxelizeCamera.setCameraMask(BitMask32.bit(4))
        self.voxelizeCameraNode = Globals.render.attachNewNode(self.voxelizeCamera)
        self.voxelizeLens = OrthographicLens()
        self.voxelizeLens.setFilmSize(self.voxelGridSize.x*2, self.voxelGridSize.y*2)
        self.voxelizeLens.setNearFar(0.0, self.voxelGridSize.x*2)
        self.voxelizeCamera.setLens(self.voxelizeLens)
        self.voxelizeCamera.setTagStateKey("VoxelizePassShader")
        Globals.render.setTag("VoxelizePassShader", "Default")

        # Create voxelize tareet
        self.target = RenderTarget("VoxelizePass")
        self.target.setSize( self.voxelGridResolution.x * 4 )
        self.target.setColorWrite(False)
        self.target.setCreateOverlayQuad(False)
        self.target.setSource(self.voxelizeCameraNode, Globals.base.win)
        self.target.prepareSceneRender()
        self.target.setActive(False)

        self.target.getInternalRegion().setSort(-400)
        self.target.getInternalBuffer().setSort(-399)
 def create(self):
     self.target = RenderTarget("Shadowed Lights")
     self.target.addColorTexture()
     self.target.setColorBits(16)
     self.target.prepareOffscreenBuffer()
     self.target.setClearColor()
Example #9
0
loadPrcFileData("", "textures-power-2 none")

import os

import direct.directbase.DirectStart
from Code.Globals import Globals

Globals.load(base)
from Code.RenderTarget import RenderTarget

import shutil

sz = 2048

target = RenderTarget()
target.setSize(sz, sz)
target.addColorTexture()
target.setColorBits(16)
target.prepareOffscreenBuffer()

vertex_shader = """
#version 400

uniform mat4 p3d_ModelViewProjectionMatrix;

in vec4 p3d_Vertex;
out vec2 texcoord;

void main() {
    gl_Position = vec4(p3d_Vertex.x, p3d_Vertex.z, 0, 1);
class AntialiasingSMAAPass(RenderPass):

    """ This render pass takes the scene color texture as input and performs
    antialiasing. The result is an antialiased scene texture which can be
    processed further. 

    This pass uses temporal SMAA."""

    def __init__(self):
        RenderPass.__init__(self)
        self.currentIndex = PTAInt.emptyArray(1)
        self.currentIndex[0] = 0

    def getID(self):
        return "AntialiasingPass"

    def getRequiredInputs(self):
        return {
            "colorTex": ["TransparencyPass.resultTex", "LightingPass.resultTex"],
            "velocityTex": "DeferredScenePass.velocity"
        }

    def create(self):
        """ Setups the SMAA. The comments are from the SMAA.glsl """
        #  1. The first step is to create two RGBA temporal render targets for holding
        #|edgesTex| and |blendTex|.
        self._setupEdgesBuffer()
        self._setupBlendBuffer()
        self._setupNeighborBuffer()
        self._setupResolveBuffer()

        #  2. Both temporal render targets |edgesTex| and |blendTex| must be cleared
        #     each frame. Do not forget to clear the alpha channel!

        self._edgesBuffer.setClearColor()
        self._blendBuffer.setClearColor()

        #  3. The next step is loading the two supporting precalculated textures,
        #     'areaTex' and 'searchTex'. You'll find them in the 'Textures' folder as
        #     C++ headers, and also as regular DDS files. They'll be needed for the
        #     'SMAABlendingWeightCalculation' pass.
        self.areaTex = Globals.loader.loadTexture(
            "Data/Antialiasing/SMAA_AreaTexGL.png")
        self.searchTex = Globals.loader.loadTexture(
            "Data/Antialiasing/SMAA_SearchTexGL.png")

        #  4. All samplers must be set to linear filtering and clamp.
        for sampler in [self.areaTex, self.searchTex, self._edgesBuffer.getColorTexture(), self._blendBuffer.getColorTexture()]:
            sampler.setMinfilter(Texture.FTLinear)
            sampler.setMagfilter(Texture.FTLinear)
            sampler.setWrapU(Texture.WMClamp)
            sampler.setWrapV(Texture.WMClamp)

        self._blendBuffer.setShaderInput(
            "edgesTex", self._edgesBuffer.getColorTexture())
        self._blendBuffer.setShaderInput("areaTex", self.areaTex)
        self._blendBuffer.setShaderInput("searchTex", self.searchTex)
        self._blendBuffer.setShaderInput("currentIndex", self.currentIndex)

        for buff in self._neighborBuffers:
            buff.setShaderInput("blendTex", self._blendBuffer.getColorTexture())

    def setShaders(self):
        edgeShader = Shader.load(Shader.SLGLSL, 
            "Shader/Antialiasing/SMAA/EdgeDetection.vertex", 
            "Shader/Antialiasing/SMAA/EdgeDetection.fragment")
        self._edgesBuffer.setShader(edgeShader)

        weightsShader = Shader.load(Shader.SLGLSL, 
            "Shader/Antialiasing/SMAA/BlendingWeights.vertex", 
            "Shader/Antialiasing/SMAA/BlendingWeights.fragment")
        self._blendBuffer.setShader(weightsShader)

        neighborShader = Shader.load(Shader.SLGLSL, 
            "Shader/Antialiasing/SMAA/Neighbors.vertex", 
            "Shader/Antialiasing/SMAA/Neighbors.fragment")

        for buff in self._neighborBuffers:
            buff.setShader(neighborShader)

        resolveShader = Shader.load(Shader.SLGLSL, 
            "Shader/Antialiasing/SMAA/Resolve.vertex", 
            "Shader/Antialiasing/SMAA/Resolve.fragment")
        self._resolveBuffer.setShader(resolveShader)

        return [edgeShader, weightsShader, neighborShader, resolveShader]

    def setShaderInput(self, name, value, *args):
        self._edgesBuffer.setShaderInput(name, value, *args)
        for buff in self._neighborBuffers:
            buff.setShaderInput(name, value, *args)
        self._resolveBuffer.setShaderInput(name, value, *args)
        self._blendBuffer.setShaderInput(name, value, *args)


    def _setupEdgesBuffer(self):
        """ Internal method to create the edges buffer """
        self._edgesBuffer = RenderTarget("SMAA-Edges")
        self._edgesBuffer.addColorTexture()
        self._edgesBuffer.prepareOffscreenBuffer()

    def _setupBlendBuffer(self):
        """ Internal method to create the blending buffer """
        self._blendBuffer = RenderTarget("SMAA-Blend")
        self._blendBuffer.addColorTexture()
        self._blendBuffer.prepareOffscreenBuffer()

    def _setupNeighborBuffer(self):
        """ Internal method to create the weighting buffer """

        self._neighborBuffers = []
        for i in xrange(2):
            self._neighborBuffers.append(RenderTarget("SMAA-Neighbors-" + str(i)))
            self._neighborBuffers[i].addColorTexture()
            self._neighborBuffers[i].prepareOffscreenBuffer()

    def _setupResolveBuffer(self):
        """ Creates the buffer which does the final resolve pass """
        self._resolveBuffer = RenderTarget("SMAA-Resolve")
        self._resolveBuffer.addColorTexture()
        self._resolveBuffer.prepareOffscreenBuffer()

    def preRenderUpdate(self):
        """ Selects the correct buffers to write and read to, because they are
        flipped every frame """
        self._neighborBuffers[self.currentIndex[0]].setActive(False)
        self._resolveBuffer.setShaderInput("lastTex",
                                           self._neighborBuffers[self.currentIndex[0]].getColorTexture())
        self.currentIndex[0] = 1 - self.currentIndex[0]
        self._neighborBuffers[self.currentIndex[0]].setActive(True)
        self._resolveBuffer.setShaderInput("currentTex",
                                           self._neighborBuffers[self.currentIndex[0]].getColorTexture())

    def getOutputs(self):
        return {
            "AntialiasingPass.resultTex": lambda: self._resolveBuffer.getColorTexture(),
        }
Example #11
0
    def create(self):
        # Create the atlas target
        self.target = RenderTarget("ShadowAtlas")
        self.target.setSize(self.size)
        self.target.addDepthTexture()
        self.target.setDepthBits(32)
        self.target.setColorWrite(False)
        self.target.setCreateOverlayQuad(False)
        # self.target.setActive(False)
        self.target.setSource(
            NodePath(Camera("tmp")), Globals.base.win)

        self.target.prepareSceneRender()
        self.target.setClearDepth(False)


        # Set the appropriate filter modes
        dTex = self.target.getDepthTexture()
        dTex.setWrapU(SamplerState.WMClamp)
        dTex.setWrapV(SamplerState.WMClamp)

        # Remove the default postprocess quad
        # self.target.getQuad().node().removeAllChildren()
        # self.target.getInternalRegion().setSort(-200)
        self.target.getInternalRegion().disableClears()
        self.target.getInternalBuffer().disableClears()
        # self.target.getInternalBuffer().setSort(-300)


        # Create default initial state
        initialState = NodePath("InitialState")
        initialState.setAttrib(ColorWriteAttrib.make(ColorWriteAttrib.COff))

        # Create a camera for each update
        self.shadowCameras = []
        for i in xrange(self.maxRegions):
            shadowCam = Camera("ShadowComputeCamera")
            shadowCam.setTagStateKey("ShadowPassShader")
            shadowCam.setInitialState(initialState.getState())
            shadowCam.setCameraMask(BitMask32.bit(3))
            shadowCamNode = self.shadowScene.attachNewNode(shadowCam)
            self.shadowCameras.append(shadowCamNode)

        # Create regions
        self.renderRegions = []
        buff = self.target.getInternalBuffer()
        
        for i in xrange(self.maxRegions):
            dr = buff.makeDisplayRegion()
            dr.setSort(1000)
            dr.setClearDepthActive(True)
            dr.setClearDepth(1.0)
            # dr.setClearColorActive(False)
            # dr.setClearColor(Vec4(1,1,1,1))
            dr.setCamera(self.shadowCameras[i])
            dr.setActive(False)
            self.renderRegions.append(dr)

        self.pcfSampleState = SamplerState()
        self.pcfSampleState.setMinfilter(SamplerState.FTShadow)
        self.pcfSampleState.setMagfilter(SamplerState.FTShadow)
        self.pcfSampleState.setWrapU(SamplerState.WMClamp)
        self.pcfSampleState.setWrapV(SamplerState.WMClamp)
class DynamicExposurePass(RenderPass):

    """ This pass handles the dynamic exposure feature, it downscales the
    Scene to get the average brightness and then outputs a new exposure which
    can be used by the lighting pass. """

    def __init__(self, pipeline):
        RenderPass.__init__(self)
        self.pipeline = pipeline

        # Create the storage for the exposure. We cannot simply use the color output
        # as the RenderTargetMatcher would have problems with that (Circular Reference)
        self.lastExposureStorage = Texture("Last Exposure")
        self.lastExposureStorage.setup2dTexture(1, 1, Texture.TFloat, Texture.FR32)

        # Registers the texture so the lighting pass can use it
        self.pipeline.renderPassManager.registerStaticVariable(
            "dynamicExposureTex", self.lastExposureStorage)


    def getID(self):
        return "DynamicExposurePass"

    def getRequiredInputs(self):
        return {
            "colorTex": "LightingPass.resultTex",
            "dt": "Variables.frameDelta"
        }

    def create(self):

        # Fetch the original texture size from the window size
        size = LVecBase2i(Globals.base.win.getXSize(), Globals.base.win.getYSize())

        # Create the first downscale pass which reads the scene texture, does a 
        # 2x2 inplace box filter, and then converts the result to luminance. 
        # Using luminance allows faster downscaling, as we can use texelGather then
        self.downscalePass0 = RenderTarget("Downscale Initial")
        self.downscalePass0.addColorTexture()
        self.downscalePass0.setSize(size.x / 2, size.y / 2)
        self.downscalePass0.prepareOffscreenBuffer()

        # Store the current size of the pass
        workSizeX, workSizeY = int(size.x / 2), int(size.y / 2)

        self.downscalePasses = []
        passIdx = 0
        lastTex = self.downscalePass0.getColorTexture()

        # Scale the scene until there are only a few pixels left. Each pass does a 
        # 4x4 inplace box filter, which is cheap because we can sample the luminance
        # only.
        while workSizeX * workSizeY > 128:
            workSizeX /= 4
            workSizeY /= 4
            passIdx += 1
            scalePass = RenderTarget("Downscale Pass " + str(passIdx))
            scalePass.setSize(workSizeX, workSizeY)
            scalePass.addColorTexture()
            scalePass.prepareOffscreenBuffer()
            scalePass.setShaderInput("luminanceTex", lastTex)
            lastTex = scalePass.getColorTexture()
            self.downscalePasses.append(scalePass)

        # Create the final pass which computes the average of all left pixels,
        # compares that with the last exposure and stores the difference.
        self.finalDownsamplePass = RenderTarget("Downscale Final")
        self.finalDownsamplePass.setSize(1, 1)
        # self.finalDownsamplePass.setColorBits(16)
        # self.finalDownsamplePass.addColorTexture()
        self.finalDownsamplePass.setColorWrite(False)
        self.finalDownsamplePass.prepareOffscreenBuffer()
        self.finalDownsamplePass.setShaderInput("luminanceTex", lastTex)
        self.finalDownsamplePass.setShaderInput("targetExposure", 
            self.pipeline.settings.targetExposure)
        self.finalDownsamplePass.setShaderInput("adaptionSpeed", 
            self.pipeline.settings.brightnessAdaptionSpeed)

        # Clear the storage in the beginning
        self.lastExposureStorage.setClearColor(Vec4(0))
        self.lastExposureStorage.clearImage()

        # Set defines and other inputs
        self.finalDownsamplePass.setShaderInput("lastExposureTex", self.lastExposureStorage)
        self.pipeline.renderPassManager.registerDefine("USE_DYNAMIC_EXPOSURE", 1)

    def setShaders(self):
        shaderFirstPass = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/DownsampleFirstPass.fragment")
        self.downscalePass0.setShader(shaderFirstPass)

        shaderDownsample = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/Downsample.fragment")
        for scalePass in self.downscalePasses:
            scalePass.setShader(shaderDownsample)

        shaderFinal = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/DownsampleFinalPass.fragment")
        self.finalDownsamplePass.setShader(shaderFinal)

        return [shaderFirstPass, shaderDownsample, shaderFinal]

    def setShaderInput(self, name, value, *args):
        self.downscalePass0.setShaderInput(name, value, *args)
        self.finalDownsamplePass.setShaderInput(name, value, *args)

    def getOutputs(self):
        return {
        }
class GlobalIlluminationPass(RenderPass):

    """ This pass performs voxel cone tracing over the previously generated
    voxel grid to compute a diffuse, specular and ambient term which can be
    used later in the lighting pass """

    def __init__(self):
        RenderPass.__init__(self)

    def getID(self):
        return "GlobalIlluminationPass"

    def getRequiredInputs(self):
        return {

            "data0": "DeferredScenePass.data0",
            "data1": "DeferredScenePass.data1",
            "data2": "DeferredScenePass.data2",
            "data3": "DeferredScenePass.data3",
            "giData": "Variables.giVoxelGridData",

            "cameraPosition": "Variables.cameraPosition",
            "mainCam": "Variables.mainCam",
            "mainRender": "Variables.mainRender"
        }

    def create(self):
        self.target = RenderTarget("GlobalIlluminationPass")
        self.target.setHalfResolution()
        self.target.addColorTexture()
        self.target.addAuxTexture()
        self.target.setColorBits(16)
        self.target.setAuxBits(16)
        self.target.prepareOffscreenBuffer()
 
    def setShaders(self):
        shader = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/ComputeGI.fragment")
        self.target.setShader(shader)
        
        return [shader]

    def getOutputs(self):
        return {
            "GlobalIlluminationPass.diffuseResult": lambda: self.target.getColorTexture(),
            "GlobalIlluminationPass.specularResult": lambda: self.target.getAuxTexture(0)
        }
class LightCullingPass(RenderPass):

    """ This pass takes a list of all rendered lights and performs light culling
    per tile. The result is stored in a buffer which then can be used by the lighting
    pass to render the lights.

    The buffer maps 1 pixel per tile, so when using a tile size of 32 then there are 
    50x30 pixels if the window has a size of 1600*960. 

    To cull the lights, the scene depth texture is analyzed and the minimum and
    maximum depth per tile is extracted. We could use compute shaders for this task,
    but they are horribly slow. """

    def __init__(self):
        RenderPass.__init__(self)

    def getID(self):
        return "LightCullingPass"

    def setSize(self, sizeX, sizeY):
        """ Sets the amount of tiles. This is usally screenSize/tileSize """
        self.size = LVecBase2i(sizeX, sizeY)

    def setPatchSize(self, patchSizeX, patchSizeY):
        """ Sets the tile size in pixels """
        self.patchSize = LVecBase2i(patchSizeX, patchSizeY)

    def getRequiredInputs(self):
        return {
            "renderedLightsBuffer": "Variables.renderedLightsBuffer",
            "lights": "Variables.allLights",
            "depth": "DeferredScenePass.depth",
            "mainCam": "Variables.mainCam",
            "mainRender": "Variables.mainRender",
            "cameraPosition": "Variables.cameraPosition"
        }

    def create(self):
        self.target = RenderTarget("ComputeLightTileBounds")
        self.target.setSize(self.size.x, self.size.y)
        self.target.addColorTexture()
        self.target.prepareOffscreenBuffer()

        self.target.getColorTexture().setMagfilter(SamplerState.FTNearest)

        self.makePerTileStorage()
        self.target.setShaderInput("destinationBuffer", self.lightPerTileBuffer)

    def makePerTileStorage(self):
        """ Creates the buffer which stores which lights affect which tiles. 
        The first 16 entries are counters which store how many lights of that
        type were rendered, and the following entries store the light indices """
        self.tileStride = 0
        self.tileStride += 16 # Counters for the light types
        
        self.tileStride += LightLimits.maxPerTileLights["PointLight"]
        self.tileStride += LightLimits.maxPerTileLights["PointLightShadow"]

        self.tileStride += LightLimits.maxPerTileLights["DirectionalLight"]
        self.tileStride += LightLimits.maxPerTileLights["DirectionalLightShadow"]
        
        self.tileStride += LightLimits.maxPerTileLights["SpotLight"]
        self.tileStride += LightLimits.maxPerTileLights["SpotLightShadow"]

        tileBufferSize = self.size.x * self.size.y * self.tileStride
        self.lightPerTileBuffer = Texture("LightsPerTileBuffer")
        self.lightPerTileBuffer.setupBufferTexture(
            tileBufferSize, Texture.TInt, Texture.FR32i, GeomEnums.UHDynamic)

        MemoryMonitor.addTexture("Light Per Tile Buffer", self.lightPerTileBuffer)

    def getDefines(self):
        return {
            "LIGHTING_PER_TILE_STRIDE": self.tileStride
        }
 
    def setShaders(self):
        shader = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/PrecomputeLights.fragment")
        self.target.setShader(shader)

        return [shader]

    def getOutputs(self):
        return {
            "LightCullingPass.lightsPerTile": lambda: self.lightPerTileBuffer
        }
Example #15
0
 def create(self):
     self.target = RenderTarget("Scattering")
     self.target.addColorTexture()
     self.target.setColorBits(16)
     self.target.prepareOffscreenBuffer()
import os

import direct.directbase.DirectStart
from Code.Globals import Globals


Globals.load(base)
from Code.RenderTarget import RenderTarget


import shutil

sz = 2048

target = RenderTarget()
target.setSize(sz, sz)
target.addColorTexture()
target.setColorBits(16)
target.prepareOffscreenBuffer()

vertex_shader = """
#version 400

uniform mat4 p3d_ModelViewProjectionMatrix;

in vec4 p3d_Vertex;
out vec2 texcoord;

void main() {
    gl_Position = vec4(p3d_Vertex.x, p3d_Vertex.z, 0, 1);
Example #17
0
class VoxelizePass(RenderPass):

    """ This pass manages voxelizing the scene from multiple directions to generate
    a 3D voxel grid. It handles the camera setup and provides a simple interface. """

    def __init__(self):
        RenderPass.__init__(self)

    def getID(self):
        return "VoxelizePass"

    def getRequiredInputs(self):
        return {
        }

    def setVoxelGridResolution(self, voxelGridResolution):
        """ Sets the voxel grid resolution, this is the amount of voxels in every
        direction, so the voxel grid will have voxelGridResolution**3 total voxels. """
        self.voxelGridResolution = voxelGridResolution

    def setVoxelGridSize(self, voxelGridSize):
        """ Sets the size of the voxel grid in world space units. This is the
        size going from the mid of the voxel grid, so the effective voxel grid
        will have twice the size specified in voxelGridSize """
        self.voxelGridSize = voxelGridSize

    def setActive(self, active):
        """ Enables and disables this pass """
        self.target.setActive(active)

    def initVoxelStorage(self):
        """ Creates t he 3D Texture to store the voxel generation grid """
        self.voxelGenTex = Texture("VoxelsTemp")
        self.voxelGenTex.setup3dTexture(self.voxelGridResolution.x, self.voxelGridResolution.y, 
                                        self.voxelGridResolution.z, Texture.TInt, Texture.FR32i)

        # Set appropriate filter types
        self.voxelGenTex.setMinfilter(SamplerState.FTNearest)
        self.voxelGenTex.setMagfilter(Texture.FTNearest)
        self.voxelGenTex.setWrapU(Texture.WMClamp)
        self.voxelGenTex.setWrapV(Texture.WMClamp)
        self.voxelGenTex.setWrapW(Texture.WMClamp)
        self.voxelGenTex.setClearColor(Vec4(0))

        # Register texture
        MemoryMonitor.addTexture("Voxel Temp Texture", self.voxelGenTex)

    def getVoxelTex(self):
        """ Returns a handle to the generated voxel texture """
        return self.voxelGenTex

    def clearGrid(self):
        """ Clears the voxel grid """
        self.voxelGenTex.clearImage()

    def create(self):
        # Create voxelize camera
        self.voxelizeCamera = Camera("VoxelizeScene")
        self.voxelizeCamera.setCameraMask(BitMask32.bit(4))
        self.voxelizeCameraNode = Globals.render.attachNewNode(self.voxelizeCamera)
        self.voxelizeLens = OrthographicLens()
        self.voxelizeLens.setFilmSize(self.voxelGridSize.x*2, self.voxelGridSize.y*2)
        self.voxelizeLens.setNearFar(0.0, self.voxelGridSize.x*2)
        self.voxelizeCamera.setLens(self.voxelizeLens)
        self.voxelizeCamera.setTagStateKey("VoxelizePassShader")
        Globals.render.setTag("VoxelizePassShader", "Default")

        # Create voxelize tareet
        self.target = RenderTarget("VoxelizePass")
        self.target.setSize( self.voxelGridResolution.x * 4 )
        self.target.setColorWrite(False)
        self.target.setCreateOverlayQuad(False)
        self.target.setSource(self.voxelizeCameraNode, Globals.base.win)
        self.target.prepareSceneRender()
        self.target.setActive(False)

        self.target.getInternalRegion().setSort(-400)
        self.target.getInternalBuffer().setSort(-399)

    def voxelizeSceneFromDirection(self, gridPos, direction="x"):
        """ Voxelizes the scene from a given direction. This method handles setting 
        the camera position aswell as the near and far plane. If the pass was disabled,
        it also enables this pass.  """
        assert(direction in "x y z".split())
        self.setActive(True)

        if direction == "x":
            self.voxelizeLens.setFilmSize(self.voxelGridSize.y*2, self.voxelGridSize.z*2)
            self.voxelizeLens.setNearFar(0.0, self.voxelGridSize.x*2)
            self.voxelizeCameraNode.setPos(gridPos - Vec3(self.voxelGridSize.x, 0, 0))
            self.voxelizeCameraNode.lookAt(gridPos)
        elif direction == "y":
            self.voxelizeLens.setFilmSize(self.voxelGridSize.x*2, self.voxelGridSize.z*2)
            self.voxelizeLens.setNearFar(0.0, self.voxelGridSize.y*2)
            self.voxelizeCameraNode.setPos(gridPos - Vec3(0, self.voxelGridSize.y, 0))
            self.voxelizeCameraNode.lookAt(gridPos)
        elif direction == "z":
            self.voxelizeLens.setFilmSize(self.voxelGridSize.x*2, self.voxelGridSize.y*2)
            self.voxelizeLens.setNearFar(0.0, self.voxelGridSize.z*2)
            self.voxelizeCameraNode.setPos(gridPos + Vec3(0, 0, self.voxelGridSize.z))
            self.voxelizeCameraNode.lookAt(gridPos)

    def setShaders(self):
        """ Creates the tag state and loades the voxelizer shader """
        voxelizeShader = Shader.load(Shader.SLGLSL, 
            "Shader/GI/Voxelize.vertex",
            "Shader/GI/Voxelize.fragment")

        # Create tag state
        initialState = NodePath("VoxelizerState")
        initialState.setShader(voxelizeShader, 500)
        initialState.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullNone))
        initialState.setDepthWrite(False)
        initialState.setDepthTest(False)
        initialState.setAttrib(DepthTestAttrib.make(DepthTestAttrib.MNone))
        initialState.setShaderInput("giVoxelGenerationTex", self.voxelGenTex)

        # Apply tag state
        self.voxelizeCamera.setTagState("Default", initialState.getState())

        return [voxelizeShader]

    def getOutputs(self):
        return {
        }
Example #18
0
from panda3d.core import *
loadPrcFileData("", "textures-power-2 none")
loadPrcFileData("", "window-type offscreen")
loadPrcFileData("", "win-size 100 100")

# loadPrcFileData("", "notify-level-display error")

import direct.directbase.DirectStart
from Code.Globals import Globals
from Code.RenderTarget import RenderTarget
Globals.load(base)

mip = 0

while TEXTURE_SIZE >= 2:
    target = RenderTarget()
    target.set_size(TEXTURE_SIZE)
    target.add_color_texture(bits=16)
    target.prepare_offscreen_buffer()

    target_stitch = RenderTarget()
    target_stitch.set_size(TEXTURE_SIZE)
    target_stitch.add_color_texture(bits=16)
    target_stitch.prepare_offscreen_buffer()

    with open("../../Shader/DefaultPostProcess.vert.glsl", "r") as handle:
        vertex_shader = handle.read()

    fragment_shader = """
    #version 400
 def create(self):
     self.target = RenderTarget("AmbientOcclusion")
     self.target.setHalfResolution()
     self.target.addColorTexture()
     self.target.prepareOffscreenBuffer()
class ShadowedLightsPass(RenderPass):

    """ This pass processes all lights which have shadows """

    def __init__(self):
        RenderPass.__init__(self)

    def getID(self):
        return "ShadowedLightsPass"

    def getRequiredInputs(self):
        return {

            # Deferred target
            "data0": "DeferredScenePass.data0",
            "data1": "DeferredScenePass.data1",
            "data2": "DeferredScenePass.data2",
            "data3": "DeferredScenePass.data3",
            "depth": "DeferredScenePass.depth",


            # Lighting
            "lightsPerTileBuffer": "LightCullingPass.lightsPerTile",
            "lightingTileCount": "Variables.lightingTileCount",
            "lights": "Variables.allLights",
            "shadowAtlasPCF": "ShadowScenePass.atlasPCF",
            "shadowAtlas": "ShadowScenePass.atlas",
            "shadowSources": "Variables.allShadowSources",
            "directionToFace": "Variables.directionToFaceLookup",

            # IES Profiles
            "IESProfilesTex": "Variables.IESProfilesTex",

            "cameraPosition": "Variables.cameraPosition",
            "mainCam": "Variables.mainCam",
            "mainRender": "Variables.mainRender"

        }

    def create(self):
        self.target = RenderTarget("Shadowed Lights")
        self.target.addColorTexture()
        self.target.setColorBits(16)
        self.target.prepareOffscreenBuffer()
        self.target.setClearColor()
 
    def setShaders(self):
        shader = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/ShadowedLightsPass.fragment")
        self.target.setShader(shader)
        return [shader]

    def getOutputs(self):
        return {
            "ShadowedLightsPass.resultTex": lambda: self.target.getColorTexture(),
        }
Example #21
0
}
"""
shader = Shader.make(Shader.SLGLSL, vertexShader, fragmentShader)





size = 1024
mipidx = 0
blurF = 0.5
while size > 1:
    size /= 2
    blurF *= 1.5

    target = RenderTarget("precompute cubemap")
    target.addColorTexture()
    target.setSize(size, size)
    target.prepareOffscreenBuffer()

    stex = target.getColorTexture()

    target.setShader(shader)
    target.setShaderInput("sourceMap", envmap)
    target.setShaderInput("mipIndex", mipidx)
    target.setShaderInput("blurFactor", blurF)

    for i in xrange(6):

        print "Generating face", i,"for mipmap",mipidx
        target.setShaderInput("directionIndex", i)
class OcclusionBlurPass(RenderPass):

    """ This pass performs a edge preserving blur by comparing the scene normals
    during the blur pass, aswell as as bilateral upscaling the occlusion input. """

    def __init__(self):
        RenderPass.__init__(self)

    def getID(self):
        return "OcclusionBlurPass"

    def getRequiredInputs(self):
        return {
            "sourceTex":  "AmbientOcclusionPass.computeResult", 
            "normalTex": "DeferredScenePass.wsNormal",
        }

    def create(self):
        self.targetV = RenderTarget("OcclusionBlurV")
        self.targetV.addColorTexture()
        self.targetV.setColorBits(16)
        self.targetV.prepareOffscreenBuffer()
 
        self.targetH = RenderTarget("OcclusionBlurH")
        self.targetH.addColorTexture()
        self.targetH.setColorBits(16)
        self.targetH.prepareOffscreenBuffer()

        self.targetH.setShaderInput("processedSourceTex", self.targetV.getColorTexture())

    def setShaders(self):
        shaderV = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/OcclusionBlurV.fragment")
        self.targetV.setShader(shaderV)

        shaderH = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/OcclusionBlurH.fragment")
        self.targetH.setShader(shaderH)

        return [shaderV, shaderH]

    def getOutputs(self):
        return {
            "OcclusionBlurPass.blurResult": lambda: self.targetH.getColorTexture(),
        }

    def setShaderInput(self, name, value):
        self.targetH.setShaderInput(name, value)
        self.targetV.setShaderInput(name, value)
Example #23
0
    // vec3 cubeColor = texture(sourceMap, direction).xyz;

    resultColor = vec4(sum, 1);

}
"""
shader = Shader.make(Shader.SLGLSL, vertexShader, fragmentShader)

size = 1024
mipidx = 0
blurF = 0.5
while size > 1:
    size /= 2
    blurF *= 1.5

    target = RenderTarget("precompute cubemap")
    target.addColorTexture()
    target.setSize(size, size)
    target.prepareOffscreenBuffer()

    stex = target.getColorTexture()

    target.setShader(shader)
    target.setShaderInput("sourceMap", envmap)
    target.setShaderInput("mipIndex", mipidx)
    target.setShaderInput("blurFactor", blurF)

    for i in xrange(6):

        print "Generating face", i, "for mipmap", mipidx
        target.setShaderInput("directionIndex", i)
 def create(self):
     self.target = RenderTarget("Volumetric Lighting")
     self.target.setHalfResolution()
     self.target.addColorTexture()
     self.target.prepareOffscreenBuffer()
 def _setupEdgesBuffer(self):
     """ Internal method to create the edges buffer """
     self._edgesBuffer = RenderTarget("SMAA-Edges")
     self._edgesBuffer.addColorTexture()
     self._edgesBuffer.prepareOffscreenBuffer()
    def create(self):

        # Fetch the original texture size from the window size
        size = LVecBase2i(Globals.base.win.getXSize(), Globals.base.win.getYSize())

        # Create the first downscale pass which reads the scene texture, does a 
        # 2x2 inplace box filter, and then converts the result to luminance. 
        # Using luminance allows faster downscaling, as we can use texelGather then
        self.downscalePass0 = RenderTarget("Downscale Initial")
        self.downscalePass0.addColorTexture()
        self.downscalePass0.setSize(size.x / 2, size.y / 2)
        self.downscalePass0.prepareOffscreenBuffer()

        # Store the current size of the pass
        workSizeX, workSizeY = int(size.x / 2), int(size.y / 2)

        self.downscalePasses = []
        passIdx = 0
        lastTex = self.downscalePass0.getColorTexture()

        # Scale the scene until there are only a few pixels left. Each pass does a 
        # 4x4 inplace box filter, which is cheap because we can sample the luminance
        # only.
        while workSizeX * workSizeY > 128:
            workSizeX /= 4
            workSizeY /= 4
            passIdx += 1
            scalePass = RenderTarget("Downscale Pass " + str(passIdx))
            scalePass.setSize(workSizeX, workSizeY)
            scalePass.addColorTexture()
            scalePass.prepareOffscreenBuffer()
            scalePass.setShaderInput("luminanceTex", lastTex)
            lastTex = scalePass.getColorTexture()
            self.downscalePasses.append(scalePass)

        # Create the final pass which computes the average of all left pixels,
        # compares that with the last exposure and stores the difference.
        self.finalDownsamplePass = RenderTarget("Downscale Final")
        self.finalDownsamplePass.setSize(1, 1)
        # self.finalDownsamplePass.setColorBits(16)
        # self.finalDownsamplePass.addColorTexture()
        self.finalDownsamplePass.setColorWrite(False)
        self.finalDownsamplePass.prepareOffscreenBuffer()
        self.finalDownsamplePass.setShaderInput("luminanceTex", lastTex)
        self.finalDownsamplePass.setShaderInput("targetExposure", 
            self.pipeline.settings.targetExposure)
        self.finalDownsamplePass.setShaderInput("adaptionSpeed", 
            self.pipeline.settings.brightnessAdaptionSpeed)

        # Clear the storage in the beginning
        self.lastExposureStorage.setClearColor(Vec4(0))
        self.lastExposureStorage.clearImage()

        # Set defines and other inputs
        self.finalDownsamplePass.setShaderInput("lastExposureTex", self.lastExposureStorage)
        self.pipeline.renderPassManager.registerDefine("USE_DYNAMIC_EXPOSURE", 1)
 def create(self):
     self.target = RenderTarget("TransparencyPass")
     self.target.addColorTexture()
     self.target.setColorBits(16)
     self.target.prepareOffscreenBuffer()
 def _setupBlendBuffer(self):
     """ Internal method to create the blending buffer """
     self._blendBuffer = RenderTarget("SMAA-Blend")
     self._blendBuffer.addColorTexture()
     self._blendBuffer.prepareOffscreenBuffer()
class VolumetricLightingPass(RenderPass):

    """ This pass computes volumetric lighting at half screen resolution """

    def __init__(self):
        RenderPass.__init__(self)

    def getID(self):
        return "VolumetricLightingPass"

    def getRequiredInputs(self):
        return {

            # Deferred target
            "wsPositionTex": "DeferredScenePass.wsPosition",
            "wsNormalTex": "DeferredScenePass.wsNormal",
            "depthTex": "DeferredScenePass.depth",

            # Lighting
            "lightsPerTileBuffer": "LightCullingPass.lightsPerTile",
            "lightingTileCount": "Variables.lightingTileCount",
            "lights": "Variables.allLights",
            "shadowAtlasPCF": "ShadowScenePass.atlasPCF",
            "shadowAtlas": "ShadowScenePass.atlas",
            "shadowSources": "Variables.allShadowSources",
            "cameraPosition": "Variables.cameraPosition",
            "mainCam": "Variables.mainCam",
            "mainRender": "Variables.mainRender"
        }

    def create(self):
        self.target = RenderTarget("Volumetric Lighting")
        self.target.setHalfResolution()
        self.target.addColorTexture()
        self.target.prepareOffscreenBuffer()

    def setShaders(self):
        shader = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/VolumetricLighting.fragment")
        self.target.setShader(shader)

        return [shader]

    def setShaderInput(self, name, value, *args):
        self.target.setShaderInput(name, value, *args)
        # self.blurTarget.setShaderInput(name, value, *args)

    def getOutputs(self):
        return {
            "VolumetricLightingPass.resultTex": lambda: self.target.getColorTexture(),
        }
 def _setupResolveBuffer(self):
     """ Creates the buffer which does the final resolve pass """
     self._resolveBuffer = RenderTarget("SMAA-Resolve")
     self._resolveBuffer.addColorTexture()
     self._resolveBuffer.prepareOffscreenBuffer()
Example #31
0
os.chdir(curr_dir)

import sys
sys.path.insert(0, "../../")

from panda3d.core import *
loadPrcFile("../../Config/configuration.prc")
loadPrcFileData("", "textures-power-2 none")
loadPrcFileData("", "window-type offscreen")
loadPrcFileData("", "win-size 100 100")

grain_shader = Shader.load(
  Shader.SL_GLSL,
  "../../Shader/DefaultPostProcess.vert.glsl",
  "GrainShader.fragment.glsl")

import direct.directbase.DirectStart

from Code.RenderTarget import RenderTarget

target = RenderTarget()
target.set_size(1024, 1024)
target.add_color_texture(bits=8)
target.prepare_offscreen_buffer()
target.set_shader(grain_shader)

base.graphicsEngine.render_frame()

base.graphicsEngine.extract_texture_data(target["color"], base.win.get_gsg())
target["color"].write("grain.png")
Example #32
0
class ShadowScenePass(RenderPass):

    """ This pass manages rendering the scene from the perspective of the shadow
    sources to generate the shadow maps. It also handles creating and managing
    the different regions of the shadow atlas, aswell as the initial state of
    all cameras assigned to the regions """

    def __init__(self):
        RenderPass.__init__(self)

        self.maxRegions = 8
        self.shadowScene = Globals.base.render

    def setMaxRegions(self, maxRegions):
        """ Sets the maximum amount of regions the atlas has. This is usually
        equal to the maximum number of shadow updates per frame """
        self.maxRegions = maxRegions

    def getID(self):
        return "ShadowScenePass"

    def getRequiredInputs(self):
        return {
            "numUpdates": "Variables.numShadowUpdates",
            "updateSources": "Variables.shadowUpdateSources" 
        }

    def setShaders(self):
        casterShader = Shader.load(Shader.SLGLSL,
            "Shader/DefaultShaders/ShadowCasting/vertex.glsl",
            "Shader/DefaultShaders/ShadowCasting/fragment.glsl")
        initialState = NodePath("ShadowCasterState")
        initialState.setShader(casterShader, 100)
        initialState.setAttrib(ColorWriteAttrib.make(ColorWriteAttrib.COff))
        for camera in self.shadowCameras:
            camera.node().setTagState("Default", initialState.getState())

        casterShaderTransparent = Shader.load(Shader.SLGLSL,
            "Shader/DefaultShaders/TransparentShadowCasting/vertex.glsl",
            "Shader/DefaultShaders/TransparentShadowCasting/fragment.glsl")
        initialState = NodePath("ShadowCasterStateTransparent")
        initialState.setShader(casterShaderTransparent, 100)
        initialState.setAttrib(ColorWriteAttrib.make(ColorWriteAttrib.COff))
        for camera in self.shadowCameras:
            camera.node().setTagState("Transparent", initialState.getState()) 

        return [casterShader, casterShaderTransparent]

    def setSize(self, size):
        """ Sets the shadow atlas size """
        self.size = size

    def setActiveRegionCount(self, activeCount):
        """ Sets the number of active regions, disabling all other regions. If the
        count is less than 1, completely disables the pass """


        if activeCount < 1:
            self.target.setActive(False)
            for region in self.renderRegions:
                region.setActive(False)

        else:
            self.target.setActive(True)
            for index, region in enumerate(self.renderRegions):
                if index < activeCount:
                    region.setActive(True)
                    pass
                else:
                    region.setActive(False)

    def setRegionDimensions(self, index, l, r, b, t):
        """ Sets the dimensions of the n-th region to the given dimensions """
        self.renderRegions[index].setDimensions(l, r, b, t)

    def getRegionCamera(self, index):
        """ Returns the camera of the n-th region """
        return self.shadowCameras[index]

    def create(self):
        # Create the atlas target
        self.target = RenderTarget("ShadowAtlas")
        self.target.setSize(self.size)
        self.target.addDepthTexture()
        self.target.setDepthBits(32)
        self.target.setColorWrite(False)
        self.target.setCreateOverlayQuad(False)
        # self.target.setActive(False)
        self.target.setSource(
            NodePath(Camera("tmp")), Globals.base.win)

        self.target.prepareSceneRender()
        self.target.setClearDepth(False)


        # Set the appropriate filter modes
        dTex = self.target.getDepthTexture()
        dTex.setWrapU(SamplerState.WMClamp)
        dTex.setWrapV(SamplerState.WMClamp)

        # Remove the default postprocess quad
        # self.target.getQuad().node().removeAllChildren()
        # self.target.getInternalRegion().setSort(-200)
        self.target.getInternalRegion().disableClears()
        self.target.getInternalBuffer().disableClears()
        # self.target.getInternalBuffer().setSort(-300)


        # Create default initial state
        initialState = NodePath("InitialState")
        initialState.setAttrib(ColorWriteAttrib.make(ColorWriteAttrib.COff))

        # Create a camera for each update
        self.shadowCameras = []
        for i in xrange(self.maxRegions):
            shadowCam = Camera("ShadowComputeCamera")
            shadowCam.setTagStateKey("ShadowPassShader")
            shadowCam.setInitialState(initialState.getState())
            shadowCam.setCameraMask(BitMask32.bit(3))
            shadowCamNode = self.shadowScene.attachNewNode(shadowCam)
            self.shadowCameras.append(shadowCamNode)

        # Create regions
        self.renderRegions = []
        buff = self.target.getInternalBuffer()
        
        for i in xrange(self.maxRegions):
            dr = buff.makeDisplayRegion()
            dr.setSort(1000)
            dr.setClearDepthActive(True)
            dr.setClearDepth(1.0)
            # dr.setClearColorActive(False)
            # dr.setClearColor(Vec4(1,1,1,1))
            dr.setCamera(self.shadowCameras[i])
            dr.setActive(False)
            self.renderRegions.append(dr)

        self.pcfSampleState = SamplerState()
        self.pcfSampleState.setMinfilter(SamplerState.FTShadow)
        self.pcfSampleState.setMagfilter(SamplerState.FTShadow)
        self.pcfSampleState.setWrapU(SamplerState.WMClamp)
        self.pcfSampleState.setWrapV(SamplerState.WMClamp)

        # Globals.render.setTag("ShadowPassShader", "Default")

    def setShaderInput(self, name, val, *args):
        self.shadowScene.setShaderInput(name, val, *args)

    def getOutputs(self):
        return {
            "ShadowScenePass.atlas": lambda: self.target.getDepthTexture(),
            "ShadowScenePass.atlasPCF": lambda: (self.target.getDepthTexture(), self.pcfSampleState),
        }