如何使用nVidia Falcor渲染框架进行GPU加速的图片处理
图片处理在很多领域中都有很大的需求,比如计算机视觉等。比较简单且常用的方法是用openCV读取图片,然后用numpy进行图片处理。然而,只有当处理算法能够完全用numpy中提供的矩阵操作实现时,才能够享受numpy的并行加速的优势。如果你的算法需要使用循环去遍历矩阵,这时的效率就会慢到无法接受。
有一种可行的方法是手写cuda kernel,然而笔者的cuda水平并不过关,因此考虑到使用Falcor来进行快速的图片处理。
Falcor
Falcor是nVidia开放的一个渲染框架,用户可以自行编写RenderPass来进行扩充。
每一个RenderPass包括3个重要文件:一个头文件,一个cpp文件和一个shader文件。
对于增加RenderPass需要考虑的只有两个点:
- Pass的输入(cpp文件中定义)
- Pass的算法(Shader)
Pass的输入
如下所示的是Antialiasing Pass中的TAA Pass的输入定义(这些字符串名称将在后面调用Pass时用到)。
namespace
{const std::string kMotionVec = "motionVecs";const std::string kColorIn = "colorIn";const std::string kColorOut = "colorOut";const std::string kAlpha = "alpha";const std::string kColorBoxSigma = "colorBoxSigma";const std::string kShaderFilename = "RenderPasses/Antialiasing/TAA/TAA.ps.slang";
}
定义的输入需要在重载的reflect函数中调用reflection对象的addInput进行添加。如下是TAA Pass的输入添加。
RenderPassReflection TAA::reflect(const CompileData& compileData)
{RenderPassReflection reflection;reflection.addInput(kMotionVec, "Screen-space motion vectors");reflection.addInput(kColorIn, "Color-buffer of the current frame");reflection.addOutput(kColorOut, "Anti-aliased color buffer");return reflection;
}
然后在重载的excute函数中将输入对应的纹理绑定到shader对应的slot上就完成了输入的定义和绑定。
void TAA::execute(RenderContext* pContext, const RenderData& renderData)
{//logInfo("TAA successful execute");const auto& pColorIn = renderData[kColorIn]->asTexture();const auto& pColorOut = renderData[kColorOut]->asTexture();const auto& pMotionVec = renderData[kMotionVec]->asTexture();// Make sure the dimensions matchassert((pColorIn->getWidth() == mpPrevColor->getWidth()) && (pColorIn->getWidth() == pMotionVec->getWidth()));assert((pColorIn->getHeight() == mpPrevColor->getHeight()) && (pColorIn->getHeight() == pMotionVec->getHeight()));assert(pColorIn->getSampleCount() == 1 && mpPrevColor->getSampleCount() == 1 && pMotionVec->getSampleCount() == 1);mpPass["PerFrameCB"]["gAlpha"] = mControls.alpha;mpPass["PerFrameCB"]["gColorBoxSigma"] = mControls.colorBoxSigma;mpPass["gTexColor"] = pColorIn;mpPass["gTexMotionVec"] = pMotionVec;mpPass["gTexPrevColor"] = mpPrevColor;mpPass["gSampler"] = mpLinearSampler;mpPass->execute(pContext, mpFbo);pContext->blit(pColorOut->getSRV(), mpPrevColor->getRTV());
}
Pass算法
Pass算法通过.slang的shader文件定义。具体写法就和普通的HLSL shader大同小异。以下是TAA对应的shader。通过shader就可以简单地实现sample等GPU加速的逐像素操作。
import Utils.Color.ColorHelpers;cbuffer PerFrameCB : register(b0)
{float gAlpha;float gColorBoxSigma;
};Texture2D gTexColor;
Texture2D gTexMotionVec;
Texture2D gTexPrevColor;
SamplerState gSampler;// Catmull-Rom filtering code from http://vec3.ca/bicubic-filtering-in-fewer-taps/
float3 bicubicSampleCatmullRom(Texture2D tex, SamplerState samp, float2 samplePos, float2 texDim)
{float2 invTextureSize = 1.0 / texDim;float2 tc = floor(samplePos - 0.5) + 0.5;float2 f = samplePos - tc;float2 f2 = f * f;float2 f3 = f2 * f;float2 w0 = f2 - 0.5 * (f3 + f);float2 w1 = 1.5 * f3 - 2.5 * f2 + 1;float2 w3 = 0.5 * (f3 - f2);float2 w2 = 1 - w0 - w1 - w3;float2 w12 = w1 + w2;float2 tc0 = (tc - 1) * invTextureSize;float2 tc12 = (tc + w2 / w12) * invTextureSize;float2 tc3 = (tc + 2) * invTextureSize;float3 result =tex.SampleLevel(samp, float2(tc0.x, tc0.y), 0).rgb * (w0.x * w0.y) +tex.SampleLevel(samp, float2(tc0.x, tc12.y), 0).rgb * (w0.x * w12.y) +tex.SampleLevel(samp, float2(tc0.x, tc3.y), 0).rgb * (w0.x * w3.y) +tex.SampleLevel(samp, float2(tc12.x, tc0.y), 0).rgb * (w12.x * w0.y) +tex.SampleLevel(samp, float2(tc12.x, tc12.y), 0).rgb * (w12.x * w12.y) +tex.SampleLevel(samp, float2(tc12.x, tc3.y), 0).rgb * (w12.x * w3.y) +tex.SampleLevel(samp, float2(tc3.x, tc0.y), 0).rgb * (w3.x * w0.y) +tex.SampleLevel(samp, float2(tc3.x, tc12.y), 0).rgb * (w3.x * w12.y) +tex.SampleLevel(samp, float2(tc3.x, tc3.y), 0).rgb * (w3.x * w3.y);return result;
}float4 main(float2 texC : TEXCOORD) : SV_TARGET0
{const int2 offset[8] = { int2(-1, -1), int2(-1, 1),int2( 1, -1), int2( 1, 1), int2( 1, 0), int2( 0, -1), int2( 0, 1), int2(-1, 0), };uint2 texDim;uint levels;gTexColor.GetDimensions(0, texDim.x, texDim.y, levels);float2 pos = texC * texDim;int2 ipos = int2(pos);// Fetch the current pixel color and compute the color bounding box// Details here: http://www.gdcvault.com/play/1023521/From-the-Lab-Bench-Real// and here: http://cwyman.org/papers/siga16_gazeTrackedFoveatedRendering.pdffloat3 color = gTexColor.Load(int3(ipos, 0)).rgb;color = RGBToYCgCo(color);float3 colorAvg = color;float3 colorVar = color * color;[unroll]for (int k = 0; k < 8; k++) {float3 c = gTexColor.Load(int3(ipos + offset[k], 0)).rgb;c = RGBToYCgCo(c);colorAvg += c;colorVar += c * c;}float oneOverNine = 1.0 / 9.0;colorAvg *= oneOverNine;colorVar *= oneOverNine;float3 sigma = sqrt(max(0.0f, colorVar - colorAvg * colorAvg));float3 colorMin = colorAvg - gColorBoxSigma * sigma;float3 colorMax = colorAvg + gColorBoxSigma * sigma; // Find the longest motion vectorfloat2 motion = gTexMotionVec.Load(int3(ipos, 0)).xy;[unroll]for (int a = 0; a < 8; a++) {float2 m = gTexMotionVec.Load(int3(ipos + offset[a], 0)).rg;motion = dot(m, m) > dot(motion, motion) ? m : motion; }// Use motion vector to fetch previous frame color (history)float3 history = bicubicSampleCatmullRom(gTexPrevColor, gSampler, (texC + motion) * texDim, texDim);history = RGBToYCgCo(history);// Anti-flickering, based on Brian Karis talk @Siggraph 2014// https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf// Reduce blend factor when history is near clampingfloat distToClamp = min(abs(colorMin.x - history.x), abs(colorMax.x - history.x));float alpha = clamp((gAlpha * distToClamp) / (distToClamp + colorMax.x - colorMin.x), 0.0f, 1.0f);history = clamp(history, colorMin, colorMax);float3 result = YCgCoToRGB(lerp(history, color, alpha));return float4(result, 0);
}
如何调用Pass
Falcor中提供了Python接口来调用写好的Pass。可以使用Falcor中的Mogwai项目直接读取python脚本并运行。下图是Mogwai读取脚本的示意图:
Falcor还提供了图片读取的Pass,这样就有在脚本中调用进行图片读取,然后使用我们写好的Pass进行图片处理。以下是用python脚本调用TAA Pass的例子:
from falcor import *
import osdef render_graph_DefaultRenderGraph():g = RenderGraph('DefaultRenderGraph')loadRenderPassLibrary('BSDFViewer.dll')loadRenderPassLibrary('AccumulatePass.dll')loadRenderPassLibrary('Antialiasing.dll')loadRenderPassLibrary('DepthPass.dll')loadRenderPassLibrary('SkyBox.dll')loadRenderPassLibrary('DebugPasses.dll')loadRenderPassLibrary('BlitPass.dll')loadRenderPassLibrary('CSM.dll')loadRenderPassLibrary('ErrorMeasurePass.dll')loadRenderPassLibrary('ForwardLightingPass.dll')loadRenderPassLibrary('GBuffer.dll')loadRenderPassLibrary('ImageLoader.dll')loadRenderPassLibrary('MegakernelPathTracer.dll')loadRenderPassLibrary('MinimalPathTracer.dll')loadRenderPassLibrary('PassLibraryTemplate.dll')loadRenderPassLibrary('WhittedRayTracer.dll')loadRenderPassLibrary('PixelInspectorPass.dll')loadRenderPassLibrary('SSAO.dll')loadRenderPassLibrary('SVGFPass.dll')loadRenderPassLibrary('TemporalDelayPass.dll')loadRenderPassLibrary('ToneMapper.dll')loadRenderPassLibrary('Utils.dll')TAA = createPass('TAA', {'alpha': 0.1, 'colorBoxSigma': 1.0})g.addPass(TAA, 'TAA')ImageLoader = createPass('ImageLoader', {'filename': "a.exr", 'mips': False, 'srgb': False, 'arrayIndex': 0, 'mipLevel': 0})g.addPass(ImageLoader, 'ImageLoader_input')ImageLoader_ = createPass('ImageLoader', {'filename': "b.exr", 'mips': False, 'srgb': False, 'arrayIndex': 0, 'mipLevel': 0})g.addPass(ImageLoader_, 'ImageLoader_mv')g.addEdge('ImageLoader_input.dst', 'TAA.colorIn')g.addEdge('ImageLoader_mv.dst', 'TAA.motionVecs')g.markOutput('TAA.colorOut')return g# resizeSwapChain(1280, 720)DefaultRenderGraph = render_graph_DefaultRenderGraph()
try: m.addGraph(DefaultRenderGraph)
except NameError: None# 设置导出的文件夹
fc.outputDir = "D:/12-4/FalcorOutput"# 按顺序处理图片
for i in range(100): renderFrame() # 渲染结果,并且等待GPU处理完成fc.baseFilename = f"result-{i:04d}"fc.capture() # 导出渲染结果time.sleep(3)# 更新image loader的图片DefaultRenderGraph.updatePass('ImageLoader_input', {'filename': "a.exr", 'mips': False, 'srgb': False, 'arrayIndex': 0, 'mipLevel': 0})DefaultRenderGraph.updatePass('ImageLoader_mv', {'filename': "b.exr", 'mips': False, 'srgb': False, 'arrayIndex': 0, 'mipLevel': 0})
如何使用nVidia Falcor渲染框架进行GPU加速的图片处理相关推荐
- ae怎么设置gpu渲染_AECS6 显卡GPU加速方法
显卡 GPU 加速方法 显卡 GPU 加速在预览高清素材和加入特效的时候,可以加快预览速度,做到比较好的即 时预览.会有人问开启 GPU 为什么会加速呢?简单来说,就是显卡自带了内存,会自行去进 行运 ...
- Premiere渲染程序没有GPU加速(CUDA)
文章目录 问题描述 解决方案 参考文献 问题描述 新装的电脑,GPU 是1080,用娱乐大师升级了驱动,Adobe Premiere 却没有上图的 GPU 加速 解决方案 升级驱动 驱动程序 | Ge ...
- Android使用GPU加速JPEG图片解码(Opencl)
转载请标明出处:https://blog.csdn.net/u013752202/article/details/92794209 1.创建opencl kernel (1)创建kerenl并编译sh ...
- NVIDIA Jarvis:一个GPU加速对话人工智能应用的框架
NVIDIA Jarvis:一个GPU加速对话人工智能应用的框架 Introducing NVIDIA Jarvis: A Framework for GPU-Accelerated Conversa ...
- 构建可扩展的GPU加速应用程序(NVIDIA HPC)
构建可扩展的GPU加速应用程序(NVIDIA HPC) 研究人员.科学家和开发人员正在通过加速NVIDIA GPU上的高性能计算(HPC)应用来推进科学发展,NVIDIA GPU具有处理当今最具挑战性 ...
- 深度学习框架:GPU
深度学习框架:GPU Deep Learning Frameworks 深度学习框架通过高级编程接口为设计.训练和验证深度神经网络提供了构建块.广泛使用的深度学习框架如MXNet.PyTorch.Te ...
- 程序怎么启动vasp_构建可扩展的GPU加速应用程序(NVIDIA HPC)
构建可扩展的GPU加速应用程序(NVIDIA HPC) 研究人员.科学家和开发人员正在通过加速NVIDIA GPU上的高性能计算(HPC)应用来推进科学发展,NVIDIA GPU具有处理当今最具挑战性 ...
- NVIDIA专家全面解析Merlin,GPU加速的推荐系统解决方案速速查收
为拓宽选手们的技术视野,腾讯广告算法大赛官方邀请 NVIDIA 及腾讯的技术大咖,倾力打造了"技"高一筹系列专题直播.在6月10日的直播中,NVIDIA 亚太 AI 开发者技术解决 ...
- DAZ STUDIO 4.12 NVIDIA Iray 渲染设置
DAZ STUDIO 4.12 NVIDIA Iray渲染设置 目录 General 常规设置 Render Mode 渲染模式 Progressive Rendering 渐进式渲染 Alpha 阿 ...
最新文章
- C# LINQ(5)
- 探究chrome下的开发工具的各功能
- 微软宣布Azure Function支持Python
- liu四声拼音怎么读_拼音是99%的西安孩子幼升小必备知识!附:幼小拼音学习计划...
- TCSVT | 横看成岭侧成峰:交叉视角地理定位
- dell的1501和640m,买哪个好呢?
- How is S4 Material extened controller loaded
- 移动硬盘计算机无法打开硬盘,移动硬盘无法识别
- 如何解决360浏览器卡死的问题
- 报价管理:用VBA开发灵活的报价系统
- 微信红包发送关键代码
- win10 python安装以及编辑器pycharm安装
- 卡口和电子警察的区别
- SUSE Linux 15 If ‘netstat‘ is not a typo you can use command-not-found to lookup the package...
- php下对港澳台身份证进行验证
- 最喜欢的动画片《长江7号爱地球》
- HTML小游戏9 —— 潜行游戏《侠盗罗宾汉》(附完整源码)
- Access key id should not be null or empty.
- 什么是 PHP? 为什么用 PHP? 有谁在用 PHP?
- 制作映射表并替换字符串中的内容