最近一直在通过https://learnopengl-cn.readth...来学习现代OpenGL使用,想通过OpenGL实现一个火星以及火星上地面站与火星附近卫星的相对运动的图像。
先说下我是在win10系统下,使用vs2015 glfw库 glew库来进行编程的。
我先用assimp库导入obj格式的火星模型,并且通过坐标矩阵的变换,将火星放大了4倍,并且按y轴随时间缓慢旋转。
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
model = glm::rotate(model, (GLfloat)glfwGetTime() * 0.050f, glm::vec3(0.0f, 1.0f, 0.0f));//沿y轴,按时间变化旋转
model = glm::scale(model, glm::vec3(4.0f));
然后我再导入了obj格式的地面站模型,我想让地面站模型贴着火星表面,然后随着火星一起转动。
我一开始想法是,找到火星模型读进来的mesh对象里面的顶点参数,随意取一个顶点的位置就是火星的表面,然后把地面站模型通过model矩阵位移到该顶点的位置(其中也要注意之前火星被放大了四倍)。
但是实际操作之后,并不是我想的那样,这里就不列代码了,我觉得我思路不对= =。
问题1:
我想知道导入了两个模型,如何控制它们的相对运动?(我也看了几遍坐标变换的内容,我知道模型一开始都是局部空间,然后通过model矩阵变换到世界空间,但是我不清楚,位移的程度)
问题2:
模型一开始应该是在标准化设备坐标范围内吧(就是xyz三个轴都是[-1,1]范围),但是我看了下我导入的火星obj文件内容,里面顶点超过了这个范围呢,我有点奇怪。
我的理解标准化设备坐标和局部空间坐标应该是一个意思吧。
问题3:
我地面站模型导入之后,我想画出它发射信号的范围(即下面图片紫色的笼罩光),我应该是通过几何着色器,从地面站的部分顶点,对它变形,来做吗。
PHPz2017-04-17 15:25:18
まず、各モデルの中心がモデル座標系の原点にあることを確認するのが最善です。
相対運動は、火星の回転と同じように、時間の関数として平行移動または回転パラメータを設定するだけで実現できます。座標を変換する場合、モデル座標系からグローバル座標系に直接変換する必要はありません。Modern OpenGL は変換インターフェイスも提供しません。 glm を使用して自由に変換できます。たとえば、最初に 2 つのオブジェクトを特定の位置に変換し、次にそのうちの 1 つを相対変位に変換したり、両方のオブジェクトの位置を個別に計算してから変換したりできます。
あなたが話している標準化されたデバイス座標範囲は、Canonical ビュー ボリュームを意味するはずですよね?後で投影変換を行う必要があるため、投影変換によってワールド座標系が正規ビュー ボリュームに変換されるため、モデルの座標範囲は重要ではありません。
これを実装するには多くの方法がありますが、個人的にはジオメトリ シェーダを使用する必要はないと考えていますが、どの方法を使用するかは、光が遮られるかどうかなどの特定の状況によって異なります。
大まかなデモ
阿神2017-04-17 15:25:18
地上局を独自のモデル空間から火星のモデル空間に移動します (おそらく特定の角度とスケールで回転し、火星の半径に相当する距離を平行移動します?)
ビューと投影は火星と同じです
それでいいでしょうか?
質問 1: 正規化されたデバイス座標 (ndc) はローカル空間座標 (モデル空間?) ではありません
添付画像の出典
モデルの xyz が [-1, 1] の範囲である必要はありません。モデル内の座標は後でさまざまな変換を受けるため、この範囲内であっても外であっても影響は限定的です。
質問 3: 範囲がどのように定義され、または「変形」されるのかがわかりません。提供された図から判断すると、シェーダーである必要はなく、円錐を直接描画するのと同じくらい簡単かもしれません。
PHP中文网2017-04-17 15:25:18
私がロードした火星モデルの中心は、ローカル座標空間 = = の中心に直接ありません。 3 番目の質問もあります。このライトは具体的にどのようにすればよいでしょうか。
私の現在のアイデアは、火星の表面上の点を円錐の発射点として取り、それから円錐を描き(まだ描き方がわかりません)、それを衛星によって打ち上げられた円錐とドッキングすることです。 。これを実装する良い方法はありますか?