Skip to content

Commit

Permalink
Support for multi-bounce GI, add "Write to Disk" button, fix bug when…
Browse files Browse the repository at this point in the history
… using a 128³ voxel grid, Add example instancing effect
  • Loading branch information
tobspr committed Aug 13, 2015
1 parent 11e9ad6 commit dc940eb
Show file tree
Hide file tree
Showing 41 changed files with 360 additions and 248 deletions.
8 changes: 8 additions & 0 deletions Code/GUI/BufferViewerGUI.py
Expand Up @@ -193,6 +193,14 @@ def showDetail(self, tex, coord):

backBtn = BetterButton(
self.buffersParent, 230, 2, "Back", callback=self.renderBuffers)
writeBtn = BetterButton(
self.buffersParent, 350, 2, "Write to Disk", callback=partial(self.writeTexToDisk, tex))

def writeTexToDisk(self, tex):
print "Writing",tex,"to disk .."
Globals.base.graphicsEngine.extractTextureData(tex, Globals.base.win.getGsg())
tex.write(tex.getName() + ".png")
print "Done!"

def onMouseOver(self, node, a):
node['frameColor'] = (1, 1, 1, 0.4)
Expand Down
7 changes: 3 additions & 4 deletions Code/GUI/FastText.py
Expand Up @@ -79,6 +79,7 @@ def _prepareFontTextures(self):
self.fontTex.setMinfilter(Texture.FTLinear)
self.fontTex.setMagfilter(Texture.FTLinear)
self.fontTex.setAnisotropicDegree(16)
self.fontTex.setFormat(Texture.FRgba)

def _loadCharset(self):
self.charset = """ !"#$%&'()*+,-./"""
Expand Down Expand Up @@ -109,13 +110,11 @@ def _makeFontShader(self):
texcoord = clamp(p3d_MultiTexCoord0, halfOffset, 1.0 - halfOffset) / vec2(16,6) + offsetCoordReal;
vec4 offset = vec4(gl_InstanceID*size.x*0.56 , 0, 0, 0) +
vec4(pos.x, 0, pos.y, 0);
vec4 finalPos = p3d_Vertex * vec4(size.xxx, 1.0) + offset;
gl_Position = p3d_ModelViewProjectionMatrix * finalPos;
}
""", """
#version 150
#pragma file FastText.fragment
in vec2 texcoord;
uniform sampler2D font;
uniform vec3 color;
Expand Down Expand Up @@ -149,9 +148,9 @@ def _makeSquare(self):
c.setFrame(-0.5, 0.5, -0.5, 0.5)
self.square = NodePath(c.generate())
self.square.setShaderInput("font", self.fontTex)
self.square.setShader(self.fontShader, 100)
self.square.setShader(self.fontShader, 1000)
self.square.setAttrib(
TransparencyAttrib.make(TransparencyAttrib.MAlpha), 100)
TransparencyAttrib.make(TransparencyAttrib.MAlpha), 1000)
self.square.reparentTo(Globals.base.aspect2d)
return self.square

Expand Down
48 changes: 21 additions & 27 deletions Code/GlobalIllumination.py
Expand Up @@ -16,6 +16,7 @@
from SettingsManager import SettingsManager
from MemoryMonitor import MemoryMonitor
from DistributedTaskManager import DistributedTaskManager
from GUI.FastText import FastText

from RenderPasses.GlobalIlluminationPass import GlobalIlluminationPass
from RenderPasses.VoxelizePass import VoxelizePass
Expand Down Expand Up @@ -62,12 +63,12 @@ def __init__(self, pipeline):
self.voxelGridSize = self.pipeline.settings.giVoxelGridSize

# Grid resolution in pixels
self.voxelGridResolution = 64
self.voxelGridResolution = 128

# Has to be a multiple of 2
self.distributionSteps = 30

self.slideCount = int(math.sqrt(self.voxelGridResolution))
self.distributionSteps = 40
self.slideCount = int(self.voxelGridResolution / 8)
self.slideVertCount = self.voxelGridResolution / self.slideCount

self.bounds = BoundingBox()
self.renderCount = 0
Expand All @@ -85,24 +86,16 @@ def __init__(self, pipeline):
self.frameIndex = 0
self.steps = []



def _createDebugTexts(self):
""" Creates a debug overlay to show GI status """
self.debugText = None
self.buildingText = None

if self.pipeline.settings.displayDebugStats:
try:
from .GUI.FastText import FastText
self.debugText = FastText(pos=Vec2(
Globals.base.getAspectRatio() - 0.1, 0.88), rightAligned=True, color=Vec3(1, 1, 0), size=0.03)
self.buildingText = FastText(pos=Vec2(-0.3, 0), rightAligned=False, color=Vec3(1, 1, 0), size=0.03)
self.buildingText.setText("PREPARING GI, PLEASE BE PATIENT ....")

except Exception, msg:
self.debug(
"GI-Debug text is disabled because FastText wasn't loaded")
self.debugText = FastText(pos=Vec2(
Globals.base.getAspectRatio() - 0.1, 0.88), rightAligned=True, color=Vec3(1, 1, 0), size=0.03)
self.buildingText = FastText(pos=Vec2(-0.3, 0), rightAligned=False, color=Vec3(1, 1, 0), size=0.03)
self.buildingText.setText("PREPARING GI, PLEASE BE PATIENT ....")

def stepVoxelize(self, idx):

Expand All @@ -126,14 +119,13 @@ def stepVoxelize(self, idx):
self.buildingText.remove()
self.buildingText = None

self.voxelizePass.voxelizeSceneFromDirection(self.gridPosTemp[0], "yxz"[idx])
self.voxelizePass.voxelizeSceneFromDirection(self.gridPosTemp[0], "xyz"[idx])


def stepDistribute(self, idx):

if idx == 0:
self.convertGridTarget.setActive(True)

self.convertGridTarget.setActive(True)

self.distributeTarget.setActive(True)

Expand All @@ -143,14 +135,14 @@ def stepDistribute(self, idx):

if idx == self.distributionSteps - 1:
self.publishGrid()


dests = self.dataTextures

for i in xrange(5):
self.distributeTarget.setShaderInput("src" + str(i), sources[i])
self.distributeTarget.setShaderInput("dst" + str(i), dests[i])

self.distributeTarget.setShaderInput("isLastStep", idx >= self.distributionSteps-4)

def publishGrid(self):
""" This function gets called when the grid is ready to be used, and updates
the live grid data """
Expand Down Expand Up @@ -219,7 +211,7 @@ def setup(self):
self.bindTo(Globals.render, "giData")

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

if self.pipeline.settings.useDebugAttachments:
self.convertGridTarget.addColorTexture()
Expand All @@ -231,7 +223,7 @@ def setup(self):
self.convertGridTarget.getColorTexture().setMagfilter(Texture.FTNearest)

self.clearGridTarget = RenderTarget("ClearGIGrid")
self.clearGridTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideCount)
self.clearGridTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideVertCount)
if self.pipeline.settings.useDebugAttachments:
self.clearGridTarget.addColorTexture()
self.clearGridTarget.prepareOffscreenBuffer()
Expand All @@ -240,6 +232,7 @@ def setup(self):
self.convertGridTarget.setShaderInput("voxelGenSrc" + color.upper(), self.generationTextures[idx])
self.clearGridTarget.setShaderInput("voxelGenTex" + color.upper(), self.generationTextures[idx])


# Create the data textures
self.dataTextures = []

Expand Down Expand Up @@ -267,10 +260,10 @@ def setup(self):
self.pongDataTextures.append(texPong)

self.convertGridTarget.setShaderInput("voxelDataDest"+str(i), 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:
for tex in self.pingDataTextures + self.pongDataTextures + self.dataTextures + self.generationTextures:
tex.setMinfilter(Texture.FTNearest)
tex.setMagfilter(Texture.FTNearest)
tex.setWrapU(Texture.WMBorderColor)
Expand All @@ -283,7 +276,7 @@ def setup(self):
tex.setMagfilter(Texture.FTLinear)

self.distributeTarget = RenderTarget("DistributeVoxels")
self.distributeTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideCount)
self.distributeTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideVertCount)

if self.pipeline.settings.useDebugAttachments:
self.distributeTarget.addColorTexture()
Expand All @@ -294,6 +287,7 @@ def setup(self):
self.distributeTarget.getColorTexture().setMinfilter(Texture.FTNearest)
self.distributeTarget.getColorTexture().setMagfilter(Texture.FTNearest)


# Create the various render targets to generate the mipmaps of the stable voxel grid
# self.mipmapTargets = []
# computeSize = self.voxelGridResolution
Expand Down Expand Up @@ -326,7 +320,7 @@ def setup(self):
if False:
self.voxelCube = loader.loadModel("Box")
self.voxelCube.reparentTo(render)
self.voxelCube.setTwoSided(True)
# self.voxelCube.setTwoSided(True)
self.voxelCube.node().setFinal(True)
self.voxelCube.node().setBounds(OmniBoundingVolume())
self.voxelCube.setInstanceCount(self.voxelGridResolution**3)
Expand Down
16 changes: 6 additions & 10 deletions Code/LightManager.py
Expand Up @@ -31,6 +31,8 @@
from RenderPasses.ShadowedLightsPass import ShadowedLightsPass
from RenderPasses.ExposurePass import ExposurePass

from GUI.FastText import FastText

pstats_ProcessLights = PStatCollector("App:LightManager:ProcessLights")
pstats_CullLights = PStatCollector("App:LightManager:CullLights")
pstats_PerLightUpdates = PStatCollector("App:LightManager:PerLightUpdates")
Expand Down Expand Up @@ -298,16 +300,10 @@ def _createDebugTexts(self):
self.lightsUpdatedDebugText = None

if self.pipeline.settings.displayDebugStats:
try:
from .GUI.FastText import FastText
self.lightsVisibleDebugText = FastText(pos=Vec2(
Globals.base.getAspectRatio() - 0.1, 0.84), rightAligned=True, color=Vec3(1, 1, 0), size=0.03)
self.lightsUpdatedDebugText = FastText(pos=Vec2(
Globals.base.getAspectRatio() - 0.1, 0.8), rightAligned=True, color=Vec3(1, 1, 0), size=0.03)

except Exception, msg:
self.debug(
"Overlay is disabled because FastText wasn't loaded")
self.lightsVisibleDebugText = FastText(pos=Vec2(
Globals.base.getAspectRatio() - 0.1, 0.84), rightAligned=True, color=Vec3(1, 1, 0), size=0.03)
self.lightsUpdatedDebugText = FastText(pos=Vec2(
Globals.base.getAspectRatio() - 0.1, 0.8), rightAligned=True, color=Vec3(1, 1, 0), size=0.03)

def _queueShadowUpdate(self, sourceIndex):
""" Internal method to add a shadowSource to the list of queued updates. Returns
Expand Down
17 changes: 13 additions & 4 deletions Code/MemoryMonitor.py
Expand Up @@ -21,12 +21,13 @@ def _calculateTexSize(self, tex):

# Assign the texture format a size
textureTypes = {
6: 1, # ALPHA
3: 1, # FRED
6: 1, # ALPHA
7: 3 * 1, # RGB (Unkown type, we will just assume 8 bit)
9: 3 * 1, # FRGBA8
12: 4 * 1, # RGBA (Unkown type, we will just assume 8 bit)
18: 1, # LUMINANCE
19: 2, # LUMINANCE_ALPHA
12: 4 * 1,# RGBA (Unkown type, we will just assume 8 bit)
18: 1, # LUMINANCE
19: 2, # LUMINANCE_ALPHA
16: 4 * 1, # RGBA8
21: 4 * 2, # RGBA16
22: 4 * 4, # RGBA32
Expand All @@ -40,6 +41,7 @@ def _calculateTexSize(self, tex):
35: 4, # FR32
}


# Get format and compute size per component
form = tex.getFormat()
componentSize = 0
Expand All @@ -52,6 +54,13 @@ def _calculateTexSize(self, tex):
# Fetch the amount of pixels
pixelCount = tex.getXSize() * tex.getYSize() * tex.getZSize()

# Check for deprecated formats
deprecated = [18, 19, 6]

if form in deprecated:
# print "DEPRECATED FORMAT:", form, "USED BY",tex.getName()
pass

# Mipmaps take approx 33% of the texture size, so just multiply the pixel
# count by that amount
if tex.usesMipmaps():
Expand Down
3 changes: 0 additions & 3 deletions Code/RenderPasses/AmbientOcclusionPass.py
Expand Up @@ -23,9 +23,6 @@ def getRequiredInputs(self):
"frameIndex": "Variables.frameIndex",
"mainRender": "Variables.mainRender",
"mainCam": "Variables.mainCam",
"noiseTexture": "Variables.noise4x4",
"viewSpaceNormals": "ViewSpacePass.normals",
"viewSpacePosition": "ViewSpacePass.position",
"depthTex": "DeferredScenePass.depth",
"cameraPosition": "Variables.cameraPosition",
"currentViewMat": "Variables.currentViewMat",
Expand Down
3 changes: 2 additions & 1 deletion Code/RenderPasses/ViewSpacePass.py
Expand Up @@ -22,7 +22,8 @@ def getRequiredInputs(self):
"depthTex": "DeferredScenePass.depth",
"mainRender": "Variables.mainRender",
"mainCam": "Variables.mainCam",
"currentViewMat": "Variables.currentViewMat"
"currentViewMat": "Variables.currentViewMat",
"currentProjMatInv": "Variables.currentProjMatInv",
}

def create(self):
Expand Down
5 changes: 3 additions & 2 deletions Code/RenderingPipeline.py
Expand Up @@ -225,6 +225,7 @@ def getDefaultSkybox(self, scale=60000):
skytex.setWrapV(SamplerState.WMRepeat)
skytex.setMinfilter(SamplerState.FTLinear)
skytex.setMagfilter(SamplerState.FTLinear)
skytex.setFormat(Texture.FRed)
skybox.setShaderInput("skytex", skytex)
self.setEffect(skybox, "Effects/Skybox/Skybox.effect", {
"castShadows": False,
Expand Down Expand Up @@ -554,8 +555,8 @@ def _setGuiShaders(self):
shader = Shader.load(Shader.SLGLSL, "Shader/GUI/vertex.glsl", "Shader/GUI/fragment.glsl")
for target in [self.showbase.aspect2d, self.showbase.render2d, self.showbase.pixel2d,
self.showbase.aspect2dp, self.showbase.render2dp, self.showbase.pixel2dp]:
target.setShader(shader, 50)

# target.setShader(shader, 50)
pass

def create(self):
""" Creates the pipeline """
Expand Down
6 changes: 4 additions & 2 deletions Config/configuration.prc
Expand Up @@ -120,7 +120,7 @@ gl-force-fbo-color false


# Set the minimum openGL version
gl-version 3 2
#gl-version 3 2

# Animations on the gpu. This is WIP, the default shader has to get adjusted first!
# hardware-animated-vertices #t
Expand Down Expand Up @@ -172,6 +172,8 @@ gl-debug-object-labels #f




# Default window settings
depth-bits 0
color-bits 0
color-bits 0

9 changes: 5 additions & 4 deletions Config/pipeline.ini
Expand Up @@ -86,7 +86,7 @@

# Size of the generated cubemap for the scattering, used for the ambient term
# and reflections
scatteringCubemapSize = 256
scatteringCubemapSize = 128


[SSLR]
Expand All @@ -111,8 +111,9 @@
# Todo: Write explanation of all techniques
occlusionTechnique = "HBAO"

# Radius of the occlusion
occlusionRadius = 1.0
# Radius of the occlusion in pixels, higher pixels mean better results but also
# worse performance.
occlusionRadius = 10.0

# Strength of the occlusion. 1.0 is default
occlusionStrength = 1.0
Expand Down Expand Up @@ -266,4 +267,4 @@

# Wheter to a attach a color texture to buffers which don't really produce
# a useful color texture. This is mainly helpful for debugging
useDebugAttachments = True
useDebugAttachments = False
Binary file modified Data/Textures/font.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit dc940eb

Please sign in to comment.