猫史档案馆


论文#1——关于3D渲染公式的推导过程与部分代码实现

用户:ParseYPasyParseYPasy查看:0 回复:4 评论:0 创建时间:2022-03-10T11:59:32


问题:

给定一个点(x,y,z),以及:

关于原点旋转的角度
x轴方向旋转:rx

y轴方向旋转:ry

z轴方向旋转:rz

x轴方向平移:Δx

y轴方向平移:Δy

z轴方向平移:Δz

求其在变换后在平面上的投影坐标。

 

过程

首先画出坐标系。

center_image

我们一般将x轴,y轴与屏幕上的x,y轴对应,而z轴与屏幕垂直,即“距离坐标”。

首先,我们可以很容易地将一个三维点投影为2维:

A(x,y,z) ——> A'(x,y)

但我们不仅需要将这个点投影到屏幕上,还需要施加缩放,即“近大远小”的空间透视。

假如我们令c=1为正常视距,那么对于c<1的情况,就需进行缩小,对于c>1的情况,需要放大。

即:

A'(xz,yz)

这样的图虽然是可以体现透视,但如果我们设定一个坐标点(1,1,1):

它的投影就是(1,1),在屏幕上会特别靠近原点。

因此,我们需要加上缩放因子。

设定因子为scale,那么:

A1(xz*scale,yz*scale)

缩放因子通常定为100,此时点的投影就能适中显示。

之后,我们开始讨论旋转,平移。

旋转与平移会有顺序上的问题,如下:

center_image

我们规定,先进行旋转,后进行平移。

那么,我们来看看旋转。

1.z轴方向上的旋转

对于我们而言,z轴旋转就是在屏幕上顺时针或逆时针旋转:z轴垂直屏幕,我们绕着它旋转就是平行于屏幕旋转。

那么,我们只需要求出A'(即A在屏幕上投影)的旋转后坐标即可。

我们首先需要求得A'关于屏幕原点的绝对角度,如下:

center_image

如下图,推导:

center_image

center_image

那么我们便能推导出z轴旋转后的角度:

center_image

再反过来,推出旋转后的坐标:
center_image
代码效果:

#include <iostream>
#include <cmath>
int main(){
    double x,y;
    double theta = asin(y/sqrt(x*x+y*y)) + rz;
    theta-=(int(theta)/360)*360;
    double x2 = cos(theta)*sqrt(x*x+y*y),
           y2 = sin(theta)*sqrt(x*x+y*y);
}

对于三维坐标点,就是如下的变换:

center_image

其余的x,y轴都基本一致,我们放出所有变换综合的效果:

center_image

最终写法:

center_image

由此,我们完成了旋转部分,接下来的平移就是小儿科了。

令x,y,z轴的偏移量为Δx,Δy,Δz,则最终版本如下:
center_image我们完成了对一个三维坐标点的转换,接下来,投影点坐标如下:

center_image

投影点计算完毕,最终,我们只需要输入数据,并利用画笔将各个投影点连接起来,就可以完成立体图形的渲染。

3D面渲染的论文将在下周左右发布。

 

 

P.S.该技术将被应用于个人的Render2,Render3作品,基于Kitten4,开源且有丰富的渲染组件

简要介绍下,Render2与Render3并不是普通的迭代版本关系,而是并行开发的两个渲染工具,Render2注重平面图形的高效且精致渲染,Render3则主要负责立体图形渲染。

 


回复

上一页1 页 / 共 1下一页
姓梁monkey淡退姓梁monkey淡退

顶!!

点赞0


评论


姓梁monkey淡退姓梁monkey淡退

大佬喵!!

点赞0


评论


糯米Nuomi糯米Nuomi

内容挺好的,感谢感谢

 

点赞0


评论


imgainary_numberimgainary_number

挖!

点赞0


评论