- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我开始使用 DirectX(和 SharpDX,因此只能在 C#/hlsl 中编程)并尝试构建我自己的相机类。它应该是可旋转的,允许向前和向后移动以及“横向”移动(经典的第一人称移动通常映射到 A 和 D,在我的例子中加上上下)。为了更容易修复错误模型和世界空间在我的例子中是相同的,透视投影尚未实现,旋转相机也是如此,我的相机应该在正 Z 轴(进入屏幕)中看。我的错误修复模型是一个简单的四边形,其宽度和高度为 1.f,z = 0 并且位于屏幕中央。
为了便于使用,我找到了 DirectX 的 Matrix.LookAtLH()
并使用它来构建我的矩阵,用于从世界坐标到 View 坐标的转换,基于我的相机在世界坐标中的定位,一个向上矢量(现在 - 没有旋转 - 总是正 Y 轴)和世界坐标中的目标点。
我的(顶点)着色器使用与该矩阵的简单乘法:
output.position = mul(position, worldToView);
LookAt-Matrix 的计算方式如下:Matrix.LookAtLH(vec3(0, 0, -1), vec3(0, 0, 0.5f), vec3(0, 1, 0))
导致这张图片:
现在我想将相机向右移动,在本例中是将 1.f 添加到它的 X 坐标。 我的预期结果与之前的四边形相同,向左移动了一点。
我构建了一个新的 LootAt 矩阵,通过相同的向量移动眼睛坐标和目标坐标:
/>Matrix.LookAtLH(vec3(1, 0, -1), vec3(1, 0, 0.5f), vec3(0, 1, 0))
结果是:
我移动相机越多,这种情况就越严重,但屏幕的中心仍然保持四边形的中心。这是否与我对 Matrix.LookAtLH
的潜在误解有关?
最佳答案
当您使用 D3DX 函数时,您必须先转置矩阵,然后再将它们发送到着色器。
来自 here 的更深入的解释:
在线性代数中,向量和矩阵使用标准矩阵乘法算法相乘。因此,有一些关于运算顺序和所涉及矩阵“形状”的规则。数学家通常将向量视为包含单列元素的矩阵,平移乘法看起来像这样:
[ 0, 0, 0, tx] [ x]
[ 0, 0, 0, ty] *[ y]
[ 0, 0, 0, tz] [ z]
[ 0, 0, 0, 1] [ 1]
首先请注意,矩阵乘法根据以下简单规则产生特定行/列配置的结果:
AxB * BxC = AxC.
换句话说,A 行 B 列大小的矩阵乘以 B 行 C 列大小的矩阵将产生 A 行 C 列大小的矩阵。此外,为了正确相乘,两者的 B 必须相等。在这种情况下,我们有 4x4 * 4x1,它产生一个 4x1 或另一个列向量。如果我们改变乘法的顺序,就是 4x1 * 4x4,这是不合法的。
但是,计算机科学家通常将向量视为具有单行的矩阵。这有几个原因,但通常是因为单行代表单个线性内存块或一维数组,因为数组通常被寻址为数组[行][列]。为了避免在代码中使用二维数组,人们简单地使用“行向量”来代替。因此,为了使用矩阵乘法获得所需的结果,我们将顺序交换为 1x4 * 4x4 = 1x4,或 vector * matrix:
[ x, y, z, 1] * [ 0, 0, 0, 0]
[ 0, 0, 0, 0]
[ 0, 0, 0, 0]
[ x, y, z, 1]
请注意必须如何移动平移矩阵的 x、y、z 元素以保留正确的乘法结果(在本例中,它是转置的)。
使用列向量时,典型的变换操作顺序是 P* V * W * v,因为列向量必须排在最后才能产生正确的结果。请记住,矩阵乘法是关联的,而不是可交换的,因此为了获得向量经过世界变换、变换到 View 空间、变换到同质屏幕空间的适当结果,我们必须按此顺序进行乘法。这给了我们(使用关联性)P * (V * (W * v)),因此从内括号工作到外括号,首先是世界转换,然后是 View ,然后是投影。
如果我们使用行向量,则乘法如下:v * W * V * P。使用结合律,我们意识到它只是相同的运算顺序:((v * W) * V) * P。或者世界优先,然后是 View ,然后是投影。
这两种乘法形式同样有效,DX 库选择使用后者,因为它符合内存布局模式,并且允许您从左到右读取转换顺序。
HLSL 支持两种操作顺序。 “*”运算符按元素缩放执行简单的元素,它不执行矩阵乘法。这是使用“mul()”内部操作执行的。如果将一个 4 元素向量作为第一个参数传递给 mul() 内部函数,它会假定您希望将其视为“行向量”。因此,您必须提供以正确顺序相乘并使用正确行/列格式提供的矩阵。这是使用 DX 效果参数从 DX 库传入矩阵时的默认行为。如果您将 4 元素向量作为第二个参数提供给 mul() 内在函数,它会将其视为列向量,并且您必须为列向量提供正确形成和相乘的矩阵。
关于c# - DirectX:世界观察矩阵——我的误解在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21215930/
我想知道是否有一种方法可以重复记录而不进行排序?有时候,我想保持原始顺序,只想删除重复的记录。 是否可以? 顺便说一句,以下是我所知道的有关重复记录的信息,这些记录最终会进行排序。 1。 proc s
我想更新我的 Activity 中依赖于另一个列表的数据的列表。这两个数据列表都是从我的 View 模型的 Activity 中观察到的。从第一个列表获取数据后,我需要在此列表上运行 for 循环以获
我无法理解这个问题。我怎样才能等待 i==2 完成然后再继续其他 i 的操作? class Observable { constructor() { this.observer
我正在观察这样的 Ember Data RecordArray: myArray: function() { return MyRecord.find(); }.property(), isDir
我想在动画开始时观察 strokeEnd 键路径。但是它不起作用,我哪里出错了? - (void)addAnimation { // do animation CABasicAnima
是否可以在 Algorand 中观看某个交易,就像在以太坊中观看某个事件一样? 最佳答案 官方 algod 和 indexer API 目前不支持在 Algorand 上观看交易/事件。 您可以通过使
我有一个可以拖放到其他 View 之上的 View (可以说是类别)。为了检测我在哪个类别 View 之上,我将它们的帧存储在一个帧数组中,这发生在它们不可见叠加层的 onAppear 中。 (这基于
是否可以将观察者添加到可见性更改(即调用 show() 和 hide())时触发的 DOM 元素?谢谢! 最佳答案 如果您想观察任何对 .show() 或 .hide() 的调用,并且可以访问 jQu
我对保存在 NSUserdefaults 中的特定键的值变化感兴趣。然而,我所拥有的并不适合我。 observeValueForKeyPath 不会被触发。 更新:我想我已经发现了这个问题。如果我使用
我正在寻找在 UITableView 顶部实现捏入/捏出,我已经研究了几种方法,包括这个: Similar question 但是,虽然我可以创建一个 UIViewTouch 对象并将其覆盖到我的 U
我有一个在界面中公开的可变数组。我还公开了数组访问器来修改数组。如果数组内发生任何修改,我将不得不使用 KVO 重置并重新计算一些数据。为了支持 KVO,我使用 array accessors如下图:
当 NSPopupButton 发生变化时如何获得方法调用?谢谢! 最佳答案 您只需添加一个操作方法,就像使用 NSButton 或任何其他控件一样。 关于iphone - 观察 NSPopupBut
我正在尝试让键值观察适用于 NSMutableArray。下面是被观察类 MyObservee 的 .h 文件: @interface MyObservee : NSObject { @pri
我很难理解让 Node.js 进程(异步)运行但仍然触发“退出”状态,以便在 CPU 处理完成后我可以做更多事情。 例如,我有一个 Google 地方信息抓取工具,可以在所有可用的 CPU 上高效地分
我正在尝试编写行为类似于kubectl get pods --watch . 这样,每次 pod 的状态发生变化时,我都会被触发。 我创建了一个 go项目(在集群中运行)并添加以下代码: podsWa
我有这个代码: 当时我需要触发Javascript方法或具有给定 id 的 div 隐藏或显示,这将在屏幕调整大小期间发生(因此 u k-hidden-small ),这可以
我想使用 Couchbase,但我想在一些类似于 RethinkDB 的方式实现更改跟踪。 似乎有很多方法可以将更改从 Couchbase 服务器推送给我。 DCP 点击 XDCR 哪一个是正确的选择
虽然 MutationObserver 允许监视 HTMLElement 属性的显式大小更改,但它似乎没有一种方法/配置允许我监视其大小的隐式更改,这些更改是由浏览器。 这是一个例子: const o
我有一个 auto-carousel 指令,它循环访问链接元素的子元素。 但是,子级尚未加载到 DOM 中,因为它们的 ng-if 表达式尚未解析。 如何确保父指令知道其 DOM 树已发生更改?
有没有办法观察 AngularJS 指令中函数表达式的值变化?我有以下 HTML 和 JavaScript,模板中 {{editable()}} 的插值显示该值计算为 true,而检查 Chrome
我是一名优秀的程序员,十分优秀!