Created
November 4, 2024 00:02
-
-
Save ScatteredRay/5c189bc8185cd1a006dc70b17c0e8445 to your computer and use it in GitHub Desktop.
TTRender Renderdoc Extract Buffers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import fnmatch | |
import OpenEXR | |
import Imath | |
def WriteEXR(file, header, channels): | |
f = OpenEXR.OutputFile(file, header) | |
f.writePixels(channels) | |
def CombineEXR(outFile, inLayers): | |
# Just use the first header for now. | |
header = OpenEXR.InputFile(inLayers[list(inLayers)[0]]).header() | |
header['channels'] = dict() | |
channels = dict() | |
for layer in inLayers: | |
file = inLayers[layer] | |
f = OpenEXR.InputFile(file) | |
inHeader = f.header() | |
channelList = inHeader['channels'].keys() | |
newChannelList = [layer + "." + c for c in channelList] | |
for c, n in zip(channelList, newChannelList): | |
header['channels'][n] = inHeader['channels'][c] | |
channels.update(dict(zip(newChannelList, f.channels(channelList)))) | |
WriteEXR(outFile, header, channels) | |
def ProcessDirectoryForLayers(bufferdir): | |
bufferFiles = dict() | |
for file in os.listdir(bufferdir): | |
if fnmatch.fnmatch(file, '*.exr'): | |
filename = os.path.join(bufferdir, file) | |
bufname = os.path.splitext(os.path.basename(file))[0] | |
bufferFiles[bufname] = filename | |
return dict(bufferFiles) | |
def MakeEXRFromLayers(outFile, bufferDir): | |
layers = ProcessDirectoryForLayers(bufferDir) | |
CombineEXR(outFile, layers) | |
MakeEXRFromLayers("~\\RenderData\\shot1\\buffers\\shot1.exr", "~\\RenderData\\shot1\\buffers\\") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
savePath = "~\\RenderData\\shot1\\buffers" | |
shadowSavePath = savePath + "\\ShadowDepth" | |
if not os.path.exists(shadowSavePath): | |
os.makedirs(shadowSavePath) | |
if 'renderdoc' not in sys.modules: | |
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "renderdoc\\x64\\Release"))) | |
import renderdoc | |
rd = renderdoc | |
ctx = pyrenderdoc | |
def match(draws, path): | |
for d in draws: | |
if d.name == path: | |
return d | |
ret = match(d.children, path) | |
if ret != None: | |
return ret | |
return None | |
def getDrawcallEnd(drawcall): | |
if len(drawcall.children) == 0: | |
return drawcall | |
return getDrawcallEnd(drawcall.children[len(drawcall.children) - 1]) | |
def saveTargetTexture(controller, resourceId, filename): | |
textureSave = rd.TextureSave() | |
if(resourceId == rd.ResourceId.Null()): | |
return | |
textureSave.resourceId = resourceId | |
textureSave.mip = 0 | |
textureSave.slice.sliceIndex = 0 | |
textureSave.alpha = rd.AlphaMapping.Preserve | |
textureSave.destType = rd.FileType.EXR | |
controller.SaveTexture(textureSave, filename + ".exr") | |
textureSave.destType = rd.FileType.PNG | |
controller.SaveTexture(textureSave, filename + ".png") | |
def savePassTargets(controller, draw): | |
controller.SetFrameEvent(draw.eventId, True) | |
for output in draw.outputs: | |
filename = os.path.join(savePath, ctx.GetResourceName(output)) | |
saveTargetTexture(controller, output, filename) | |
def savePassDepthTarget(controller, draw): | |
controller.SetFrameEvent(draw.eventId, True) | |
output = draw.depthOut | |
filename = os.path.join(savePath, ctx.GetResourceName(output)) | |
saveTargetTexture(controller, output, filename) | |
def saveNamedPassTarget(controller, draw, outputName, saveName): | |
controller.SetFrameEvent(draw.eventId, True) | |
for output in draw.outputs: | |
if(ctx.GetResourceName(output) == outputName): | |
filename = os.path.join(savePath, saveName) | |
saveTargetTexture(controller, output, filename) | |
def saveNamedPassInput(controller, draw, inputName, saveName): | |
controller.SetFrameEvent(draw.eventId, True) | |
pipelineState = controller.GetPipelineState() | |
resources = pipelineState.GetReadOnlyResources(rd.ShaderStage.Pixel) | |
for bra in resources: | |
for resource in bra.resources: | |
input = resource.resourceId | |
if(ctx.GetResourceName(input) == inputName): | |
filename = os.path.join(savePath, saveName) | |
saveTargetTexture(controller, input, filename) | |
def extractDepthBuffer(controller): | |
draws = controller.GetDrawcalls() | |
savePassDepthTarget(controller, getDrawcallEnd(match(draws, "ResolveSceneDepthTexture"))) | |
def extractGBuffer(controller): | |
draws = controller.GetDrawcalls() | |
basePass = match(draws, "BasePass") | |
print(basePass.name) | |
basePassEnd = getDrawcallEnd(basePass) | |
print(basePassEnd.name) | |
savePassTargets(controller, basePassEnd) | |
savePassTargets(controller, getDrawcallEnd(match(draws, "LightCompositionTasks_PreLighting"))) | |
def extractShadowBuffers(controller): | |
draws = controller.GetDrawcalls() | |
shadowedLights = match(draws, "ShadowedLights") | |
for d in shadowedLights.children: | |
lightName = d.name.split('.')[-1] | |
print(lightName) | |
shadowProjection = match(d.children, "ShadowProjectionOnOpaque") | |
if shadowProjection != None: | |
shadowDraw = getDrawcallEnd(shadowProjection) | |
saveNamedPassInput(controller, shadowDraw, "CachedShadowDepthMap", "ShadowDepth\\Lights." + lightName + ".ShadowDepth") | |
saveNamedPassTarget(controller, shadowDraw, "ScreenShadowMaskTexture", "Lights." + lightName + ".ShadowMask") | |
def extract(controller): | |
extractDepthBuffer(controller) | |
extractGBuffer(controller) | |
extractShadowBuffers(controller) | |
if 'pyrenderdoc' in globals(): | |
pyrenderdoc.Replay().BlockInvoke(extract) | |
else: | |
rd.InitialiseReplay(rd.GlobalEnvironment(), []) | |
cap,controller = loadCapture(sys.argv[1]) | |
extract(controller) | |
controller.Shutdown() | |
cap.Shutdown() | |
rd.ShutdownReplay() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment