图片处理在很多领域中都有很大的需求,比如计算机视觉等。比较简单且常用的方法是用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加速的图片处理相关推荐

  1. ae怎么设置gpu渲染_AECS6 显卡GPU加速方法

    显卡 GPU 加速方法 显卡 GPU 加速在预览高清素材和加入特效的时候,可以加快预览速度,做到比较好的即 时预览.会有人问开启 GPU 为什么会加速呢?简单来说,就是显卡自带了内存,会自行去进 行运 ...

  2. Premiere渲染程序没有GPU加速(CUDA)

    文章目录 问题描述 解决方案 参考文献 问题描述 新装的电脑,GPU 是1080,用娱乐大师升级了驱动,Adobe Premiere 却没有上图的 GPU 加速 解决方案 升级驱动 驱动程序 | Ge ...

  3. Android使用GPU加速JPEG图片解码(Opencl)

    转载请标明出处:https://blog.csdn.net/u013752202/article/details/92794209 1.创建opencl kernel (1)创建kerenl并编译sh ...

  4. NVIDIA Jarvis:一个GPU加速对话人工智能应用的框架

    NVIDIA Jarvis:一个GPU加速对话人工智能应用的框架 Introducing NVIDIA Jarvis: A Framework for GPU-Accelerated Conversa ...

  5. 构建可扩展的GPU加速应用程序(NVIDIA HPC)

    构建可扩展的GPU加速应用程序(NVIDIA HPC) 研究人员.科学家和开发人员正在通过加速NVIDIA GPU上的高性能计算(HPC)应用来推进科学发展,NVIDIA GPU具有处理当今最具挑战性 ...

  6. 深度学习框架:GPU

    深度学习框架:GPU Deep Learning Frameworks 深度学习框架通过高级编程接口为设计.训练和验证深度神经网络提供了构建块.广泛使用的深度学习框架如MXNet.PyTorch.Te ...

  7. 程序怎么启动vasp_构建可扩展的GPU加速应用程序(NVIDIA HPC)

    构建可扩展的GPU加速应用程序(NVIDIA HPC) 研究人员.科学家和开发人员正在通过加速NVIDIA GPU上的高性能计算(HPC)应用来推进科学发展,NVIDIA GPU具有处理当今最具挑战性 ...

  8. NVIDIA专家全面解析Merlin,GPU加速的推荐系统解决方案速速查收

    为拓宽选手们的技术视野,腾讯广告算法大赛官方邀请 NVIDIA 及腾讯的技术大咖,倾力打造了"技"高一筹系列专题直播.在6月10日的直播中,NVIDIA 亚太 AI 开发者技术解决 ...

  9. DAZ STUDIO 4.12 NVIDIA Iray 渲染设置

    DAZ STUDIO 4.12 NVIDIA Iray渲染设置 目录 General 常规设置 Render Mode 渲染模式 Progressive Rendering 渐进式渲染 Alpha 阿 ...

最新文章

  1. C# LINQ(5)
  2. 探究chrome下的开发工具的各功能
  3. 微软宣布Azure Function支持Python
  4. liu四声拼音怎么读_拼音是99%的西安孩子幼升小必备知识!附:幼小拼音学习计划...
  5. TCSVT | 横看成岭侧成峰:交叉视角地理定位
  6. dell的1501和640m,买哪个好呢?
  7. How is S4 Material extened controller loaded
  8. 移动硬盘计算机无法打开硬盘,移动硬盘无法识别
  9. 如何解决360浏览器卡死的问题
  10. 报价管理:用VBA开发灵活的报价系统
  11. 微信红包发送关键代码
  12. win10 python安装以及编辑器pycharm安装
  13. 卡口和电子警察的区别
  14. SUSE Linux 15 If ‘netstat‘ is not a typo you can use command-not-found to lookup the package...
  15. php下对港澳台身份证进行验证
  16. 最喜欢的动画片《长江7号爱地球》
  17. HTML小游戏9 —— 潜行游戏《侠盗罗宾汉》(附完整源码)
  18. Access key id should not be null or empty.
  19. 什么是 PHP? 为什么用 PHP? 有谁在用 PHP?
  20. 制作映射表并替换字符串中的内容

热门文章

  1. js学习笔记d1【P1-P7】
  2. 微软劝你别再使用 IE 浏览器
  3. VB将excel的页面设置设为一页宽一页高
  4. 蚂蚁森林版本更新,大家喜欢吗
  5. BZOJ3668 起床困难综合症
  6. 华为q1设置虚拟服务器,华为Q1路由器上网设置方法【图文】
  7. vue项目高度未占满全屏,可以给app.vue页面设置样式,来让高度撑开全屏
  8. 用python脚本分类和改名照片和视频
  9. WPF 后面板设置16进制颜色,透明;
  10. Thinkphp5.1中间件的用法