GPU Shader 程序调试方法

转载自: http://blog.csdn.net/pizi0475/article/details/7573939

内容提要:手动调试和使用工具PIX调试Direct3D程序。

      3D绘图中常见问题:

1.模型消失,没有出现在画面上;

2.模型在画面上失真、变形或者闪烁;

3.贴图出现不正常拉扯;

4.使用了错误的贴图、Shader或者RenderState .

       没有固定方法来查找错误的原因,一般尝试改变绘图设置,慢慢缩小问题可能发生的范围。

       模型消失时,第一步检查转换矩阵,尤其是投影矩阵。如果投影矩阵的Z near和Z far范围不够大,3D对象就会落在屏幕坐标系之外而被忽略。可以试着改变投影矩阵的可视范围,看看消失的对象是否会重新出现。必要时检查顶点位置和转换矩阵的相乘结果,看看它们是否会落在画面范围中。还可以把透视投影的矩阵暂时改成正交投影,这样可以查看3D对象的位置是否正确。

       确认矩阵没有问题后,如果画面仍然不正确,问题应该出在模型数据和纹理的正确性上。这时可以暂时把纹理简化。第一个简化通常是关闭光照功能。如果模型在画面上看起来过暗,甚至是完全黑色时,可能是光照的设置出了问题,这时只有关闭光照功能,就可以让模型重新出现。简化纹理还可以把Alpha Test和Blending功能关闭,有时可能贴图的Alpha层完全是黑色,或者纹理使用了错误的Alpha Test比较值,这些错误都有可能让整个对象消失。

       如果关闭Alpha Test和Blending功能后,画面上仍然看不到3D对象,就把纹理做最终的简化,移除所有的贴图,让物表纹理固定地输出单一颜色。如果这个步骤可以让模型出现在画面上,那就可以肯定问题出在贴图设置或Pixel Shader的代码上。

       经过前面3个步骤后,如果模型仍然没有出现在正确的位置上,就在检查模型数据的正确性。第1步在画出模型时,把几何图形的种类由三角形Triangle暂时改成点Point,因为创建三角形数据的Index Buffer有可能发生错误,所以无法组合出正确的模型。暂时先把模型用点Point的类型来画,最起码可以在画面上看到模型的大致形状,如果连大致形状都是错误的,那代表最原始的模型数据就已经出现问题了。

       模型数据的问题有可能出现在GPU读取数据的部分,也有可能在设置顶点数据字段时出现错误。这个部分比较难确认,比较好的方法是通过工具来检查,在C++部分所能做到的检查工作如下:

1.确定顶点数据的大小size正确,

2.确认顶点数据字段设置,让GPU能够获得所以需要用到的数据。

3.在测试时,也可以先把数据简化,暂时只传入顶点的位置Position,忽略发线Normal、颜色Color,以及贴图坐标等,先只使用顶点位置把整个模型用点的方法画出来,只要看到模型的大致形状,再试着去传入其它数据。

        使用上述的方法应该可以把问题范围缩小,这时也许还没有找出真正的原因,但是先把范围缩小后,再通过工具,应该就可以发现问题所在。

        Direct3D调试工具PIX(Performance Investigate for Xbox) for Windows.在Direct SDK的工具下可以找到这个程序。PIX可以查看贴图和模型,绘图结果,顶点和像素着色器调试等功能。注意PIX启动要调试的程序路径必须是英文,否则出现不能运行错误“PIX Experiment File Version Mismatch”。

         使用PIX分为2大步骤:第1步是通过PIX来启动想要调试的程序,并在程序启动后,按工具设置来截取某个画面所使用的Direct3D指令;第2步是在截取画面后关闭绘图程序,PIX接下来应该会切换到回放Direct3D指令的模式。

         PIX先把某个画面中的Direct3D绘图指令截取下来,再把每个指令都视为1个断点,程序员可以从Event窗口中选择其中指令,再通过Render窗口来查看绘图的结果。Render窗口显示的是,从这个画面的起点开始一直运行到说选择断点为止的3D绘图结果。

         PIX可以查看程序中所使用的贴图和模型数据。在Event窗口中找到相对应的SetTexture函数调用,双击函数的第2个参数,即蓝色文字的参数,右下方的窗口中就会显示所使用的贴图。如果要查看模型,选择Event窗口中画出模型的DrawPrimitive和DrawIndexedPrimitive函数调用(单击工具Event窗口最上边的按钮D也可以上下移动到函数调用),再在Detail窗口中选择Mesh,窗口中就会显示坐标转换前和转换后的的模型,还会显示出一个列出所有的顶点数据的列表。双击其中1个顶点,就可以进入Vertex Shader的调试模式。其中查看坐标转换前后的模型非常实用,马上可以看出加载模型是否正确,以及VS处理后是否正确,显示是否超出。Mesh中PreVS的顶点为原始输入坐标值,而PostVS的顶点为处理后的坐标值,即原始输入坐标值XWorld_View_Proj矩阵=处理后的坐标值,其中矩阵为世界,视图,投影三个矩阵的乘积。

        调试Pixel Shader。在Detail窗口的Render模式,在要调试的像素上右击,弹出一个快捷菜单,选择菜单上的Debug This Pixel选项,进入Pixel Shader的调试模式。

        具体的调试操作可以查阅SDK.

        Visual Studil也提供了Shader的调试模式,不过不太实用,Microsoft也没有再对它更新。PIX所提供的调试功能比较完整,也比较实用。

        OpenGL调试工具有glslDevil,GLIntercept和gDEBugger等。

       摘选于彭国伦的《3D绘图程序设计》.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313382.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【.NET Core 3.0】框架之十二 || 跨域 与 Proxy

本文有配套视频:https://www.bilibili.com/video/av58096866/?p8一、为什么会出现跨域的问题跨域问题由来已久,主要是来源于浏览器的”同源策略”。何为同源?只有当协议、端口、和域名都相同的页面,则两个页面具有相同的源。只要…

Boltzmann Machine 入门(1)

根据我的第一篇关于DBM的博文,明白了一个道理,1. v 和h 互相能推测出彼此,表示同一组特征的两种形式,就像时域频域一样。接下来又看了 http://www.cnblogs.com/tianchi/archive/2013/03/14/2959716.html 以热力学分子随机取值变化…

.NET 时间轴:从出生到巨人

点击上方蓝字关注“汪宇杰博客”“ 自1995年互联网战略日以来最雄心勃勃的事业—— 微软.NET战略, 2000年6月30日”2002-02-13.NET Framework 1.0CLR 1.0Visual Studio .NET关键词:跨语言、托管代码2003-04-24.NET Framework 1.1CLR 1.1Visual Studio 2003关键词&am…

Go 语言接口

Go 语言接口 Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。 实例 实例 /* 定义接口 */ type interface_name interface { method_name1 [return_type] method_name2…

Redis缓存雪崩、缓存穿透、热点Key

我们通常使用 缓存 过期时间的策略来帮助我们加速接口的访问速度,减少了后端负载,同时保证功能的更新。 1、缓存穿透 缓存系统,按照KEY去查询VALUE,当KEY对应的VALUE一定不存在的时候并对KEY并发请求量很大的时候,就会对后端造…

Boltzmann Machine 入门(2)

发现RBM 中的能量函数概念需要从Hopfield网络的角度理解,于是找到 http://blog.csdn.net/roger__wong/article/details/43374343 和关于BM的最经典论文 http://www.cs.toronto.edu/~hinton/papers.html#1983-1976 一、限制玻尔兹曼机的感性认识 要回答这个问题大…

针对深度学习的GPU芯片选择

转自:http://timdettmers.com/2014/08/14/which-gpu-for-deep-learning/ It is again and again amazing to see how much speedup you get when you use GPUs for deep learning: Compared to CPUs 10x speedups are typical, but on larger problems one can achi…

C# 8 - Range 和 Index(范围和索引)

C# 7 的 Span C# 7 里面出现了Span这个数据类型,它可以表示另一个数据结构里连续相邻的一串数据,并且它是内存安全的。 例子: 这个图的输出是3,4,5,6。 C# 8 的Range类型 而C# 8里面我们可以从一个序列里面…

第k个排列

1、问题描述 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。 按大小顺序列出所有排列情况,并一一标记,当 n 3 时, 所有排列如下: “123”“132”“213”“231”“312”“321” 给定 n 和 k,返回第 k 个排列。…

DCT变换学习

http://blog.csdn.net/timebomb/article/details/5960624 timebomb的博客 DCT变换的基本思路是将图像分解为88的子块或1616的子块,并对每一个子块进行单独的DCT变换,然后对变换结果进行量化、编码。随着子块尺寸的增加,算法的复杂度急剧上升…

敏捷回顾会议的套路与实践分享

01—关于敏捷回顾会议实践过敏捷的人都知道,在敏捷中会有很多的会议要开,比如计划会议(Planning)、站立会议(Daily Scrum)、评审会议(Review)以及回顾会议(Retrospective…

光栅化坐标映射公式

Direct3D中投影空间内的点坐标与屏幕上(或视口内)点的对应关系, 设屏幕大小为wh,屏幕左上角像素的中心被定义为(0,0),整个屏幕是从(-0.5,-0.5)-(w-0.5,h-0.5), 像素 将投影空间内的x轴上区间(-1.0-1/w, 1.0…

朋友圈

1、题目描述 班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。 给定一个 N * N 的矩阵 M…

.Net Core AA.FrameWork应用框架介绍

开发多年,一直在从社区获取开源的便利,也深感社区力量的重要性,今天开源一个应用基础框架AA.FrameWork,也算是回馈社区,做出一点点贡献,希望能够帮助类似当年入行的我。AA.FrameWork 是基于.NET core流行的开源类库创建…

RBM/DBN训练中的explaining away概念

可以参照 Stanford大神DaphneKoller的概率图模型,里面贝叶斯网络一节讲到了explaining away。我看过之后试着谈谈自己的理解。 explainingaway指的是这样一种情况:对于一个多因一果的问题,假设各种“因”之间都是相互独立的,如果…

.NET Core使用gRPC打造服务间通信基础设施

一、什么是RPCrpc(远程过程调用)是一个古老而新颖的名词,他几乎与http协议同时或更早诞生,也是互联网数据传输过程中非常重要的传输机制。利用这种传输机制,不同进程(或服务)间像调用本地进程中…

排序链表

题目描述 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。 示例 1: 输入: 4->2->1->3 输出: 1->2->3->4示例 2: 输入: -1->5->3->4->0 输出: -1->0->3->4->5解法 思路1,归并排序 publi…

DBN训练学习-A fast Learning algorithm for deep belief nets

转载自:http://blog.sciencenet.cn/blog-110554-889016.html DBN的学习一般都是从Hinton的论文A Fast Learning Algorithm for Deep Belief Nets开始。如果没有相关的背景知识,不知道问题的来由,这篇论文读起来是相当费劲的。 学习过程中主…

程序员家的大闸蟹:青壳、白底、肉多、爆黄,现在是吃大闸蟹的最佳时期

其实,我跟大家一样,也是dotNET跨平台和张队长的忠实粉丝,也是一名程序员。上上周,我在dotNET跨平台的优选商城买了队长推荐人生果,也是第一次吃这个人生果,味道鲜甜、汁水也特别多,但由于快递的…

环形链表II

1、题目描述 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则…