标签: raytracing

如何计算圆柱体表面的法线?

我正在研究光线追踪器,并开始向场景中添加圆柱体。我遇到的问题是找到光线击中点的表面法向量。我需要这个才能进行漫射照明。此时我所拥有的是相机光线撞击圆柱体的 3d 点,以及由中心轴上的点定义的实际圆柱体,向量代表轴的方向和半径。所以总结一下我的问题,如何找到具有圆柱体撞击点、半径、其轴上的点和轴的方向向量的点的法线向量?

math raytracing lighting vector-graphics

6
推荐指数
1
解决办法
1万
查看次数

立方体内球体的光线追踪

我正在尝试对立方体内的球体进行光线追踪。立方体由 12 个具有法线的三角形简单构成。

立方体具有单位坐标和单位法线。因此,在其局部空间内(-1 和 1 之间),应该有一个半径为 0.5 的球体。

所以我想我应该在顶点着色器中计算光线:光线原点是插值顶点位置,光线方向是顶点法线(或其相反方向,但我认为这并不重要)。剩下的应该由插值完成。

然后在片段着色器中,我应该计算光线球体交点,如果有的话,更改片段的颜色。

在立方体的正面和背面,结果似乎是正确的,但在左侧、右侧、顶部和底部,结果似乎来自错误的角度。我应该始终看到中间的球体,而那些侧面的情况并非如此。

有人可以告诉我我做错了什么吗?

这是着色器代码:

顶点着色器:

#version 400

layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNor;

uniform mat4 uProj;
uniform mat4 uView;
uniform mat4 uModel;

out vec3 vRayPos;
out vec3 vRayDir;

void main(void)
{
  gl_Position = uProj * uView * uModel * vec4(aPos, 1);
  vRayPos = aPos;
  vRayDir = inverse(mat3(uModel)) * aNor;
}
Run Code Online (Sandbox Code Playgroud)

片段着色器:

#version 400

in vec3 vRayPos;
in vec3 vRayDir;

out vec4 oFrag;

void main(void) …
Run Code Online (Sandbox Code Playgroud)

trace raytracing glsl

6
推荐指数
1
解决办法
952
查看次数

这个在GPU上运行的光线追踪功能,GPU安全吗?

我试图在片段着色器中编写一个简单的光线追踪器。我有这个函数应该创建一个漫射球体,如下所示:

在此处输入图片说明

这是功能:

vec3 GetRayColor(Ray ray)
{
Ray new_ray = ray;
vec3 FinalColor = vec3(1.0f);

bool IntersectionFound = false;
int hit_times = 0;

for (int i = 0; i < RAY_BOUNCE_LIMIT; i++)
{
    RayHitRecord ClosestSphere = IntersectSceneSpheres(new_ray, 0.001f, MAX_RAY_HIT_DISTANCE);

    if (ClosestSphere.Hit == true)
    {
        // Get the final ray direction

        vec3 R;
        R.x = nextFloat(RNG_SEED, -1.0f, 1.0f); 
        R.y = nextFloat(RNG_SEED, -1.0f, 1.0f);
        R.z = nextFloat(RNG_SEED, -1.0f, 1.0f);

        vec3 S = normalize(ClosestSphere.Normal) + normalize(R);
        S = normalize(S);

        new_ray.Origin = ClosestSphere.Point;
        new_ray.Direction = …
Run Code Online (Sandbox Code Playgroud)

c++ opengl raytracing glsl

6
推荐指数
1
解决办法
162
查看次数

有人可以描述Ken Silverman的Voxlap引擎使用的算法吗?

从我收集到的,他使用稀疏的体素八叉树和光线投射.似乎他没有使用opengl或direct3d,当我看到游戏Voxelstein时,看起来微型立方体实际上是被绘制而不是仅仅是一堆2d方形.这让我措手不及我不知道他如何在没有opengl或direct3d的情况下做到这一点.

我试着阅读源代码,但我很难理解发生了什么.我想实现类似的东西,并希望算法这样做.

我对他如何进行渲染,剔除,遮挡和照明感兴趣.任何帮助表示赞赏.

opengl graphics rendering raytracing real-time

5
推荐指数
2
解决办法
4302
查看次数

如何在光线从嵌套对象内部开始时处理折射

我正在为教育目的构建一个简单的光线跟踪器,并希望为对象添加折射.使用Snells Law,我能够在交叉点处递归地创建新的光线.光线跟踪器目前仅支持球体,我使用的场景中我有多个球体嵌套在彼此内部,具有不同的折射率.

如果我从球体外部开始射线,一切看起来都很简单.从场景的折射率开始,一旦击中第一个球体,使用前面的折射率和球体材质的折射率折射光线,直到你击中下一个球体,依此类推.使用交点的法线我可以确定我是进入还是离开球体.

但是,我不明白我应该如何处理球体叶子以及如果光线不在场景的外部开始该怎么办.

  • 我可以只拿一叠折射率并在离开球体时立即上一层吗?
  • 如果我从球体内部开始,我如何确定我必须开始的折射率?

你有三个球体,从外到内的折射率分别为0.9,1.1和0.8.空气指数为1.0

  • 您的相机位于球体外部并指向球体的中心:

    • 起始索引是1.0,你首先用指数0.9击中外部球体并从1.0到0.9折射并保存你的射线现在是0.9材质
    • 你击中了中间球体并注意到材料常数为1.1,因为你已经保存了0.9,你知道你必须折射0.9到1.1然后保存1.1除了0.9之外
    • 你击中内部球体并从1.1折射到0.8并且你已经保存到现在0.9,1.1和0.8
    • 你再次击中内部球体(这次你退出它,所以你检查你保存的值,并知道你必须切换回1.1)
    • ......直到你在外面
  • 现在问题,当相机在球体内时.您不知道必须切换的折射率.

graphics raytracing

5
推荐指数
2
解决办法
2824
查看次数

RayTracing:何时标准化矢量?

我正在重写我的光线追踪器,并试图更好地理解它的某些方面.

我似乎已经解决了关于法线的问题,以及你应该如何将它们乘以变换矩阵的转置的倒数.

我感到困惑的是,我应该将我的方向向量归一化吗?

我正在关注某本书,有时候它会明确说明我的矢量和其他情况的归一化,我发现我需要.

归一化向量的方向相同,单位长度为1?所以我不清楚何时有必要?

谢谢

graphics raytracing vector linear-algebra

5
推荐指数
2
解决办法
5481
查看次数

用于高效光线追踪的数据结构/方法

我正在编写一个3D光线跟踪器作为个人学习项目(Enlight),并遇到了一个有趣的问题,涉及在光线和物体场景之间进行交叉测试.

情况是:

  • 我有许多光线可以与(球体,盒子,平面等)及其组相交的基元.总的来说,我正在调用这些场景对象.
  • 我希望能够通过将它们包装在一个Transform对象中来对具有任意仿射变换的场景对象进行渲染(重要的是,这将使得相同图元的多个实例能够在场景中的不同位置使用,因为图元是不可变的)
  • 场景对象可以存储在边界卷层次结构中(即我正在进行空间分区)
  • 我的交叉测试Ray用于表示部分光线段的对象(起始矢量,标准化方向矢量,起始距离,结束距离)

问题是当光线撞击Transform对象的边界框时,看起来与包含在其中的变换图元进行交叉测试的唯一方法是将变换Ray为坐标变换的坐标空间.这很容易,但是如果光线没有碰到任何变形的物体,我需要回到原始状态Ray继续跟踪.由于Transforms可以嵌套,这意味着我必须Ray为每个完成的交集跟踪维护一整堆s.

这当然是整个应用程序的内部循环和主要性能瓶颈.它将被称为每秒数百万次,所以我渴望最小化复杂性/避免不必要的内存分配.

有一种聪明的方法可以避免分配新Ray的/保持Ray堆栈吗?

或者有一种更聪明的方式完全这样做?

algorithm 3d performance raytracing data-structures

5
推荐指数
1
解决办法
1276
查看次数

有效地计算体素数据的梯度

计算固定大小的体素数据的梯度的最有效方法是什么,例如下面的源代码.请注意,我需要在空间的任何位置使用渐变.渐变将用于估计行进立方体实现中的法线.

#import <array>

struct VoxelData {
    VoxelData(float* data, unsigned int xDim, unsigned int yDim, unsigned int zDim)
    :data(data), xDim(xDim), yDim(yDim), zDim(zDim)
    {}

    std::array<float,3> get_gradient(float x, float y, float z){
        std::array<float,3> res;
        // compute gradient efficiently
        return res;
    }

    float get_density(int x, int y, int z){
        if (x<0 || y<0 || z<0 || x >= xDim || y >= yDim || z >= zDim){
            return 0;
        }
        return data[get_element_index(x, y, z)];
    }

    int get_element_index(int x, int y, int z){
        return x …
Run Code Online (Sandbox Code Playgroud)

c++ raytracing voxel marching-cubes

5
推荐指数
1
解决办法
2465
查看次数

Ray-Triangle Intersection C++

我正在测试光线是否与三角形相交,所以暂时使用下面的代码来测试指定光线之间是否有交点,此时此方向的方向为随机三角形的中点:

Ray<float> *ray = new Ray<float>(Vec3<float>(0), chosenTriangle->GetTriangleMidpoint()); 
Run Code Online (Sandbox Code Playgroud)

旁边是Vec3对象,它用于存储向量操作:

template<typename T>
class Vec3
{
public:
    T x, y, z;
    Vec3() : x(T(0)), y(T(0)), z(T(0)) { }
    Vec3(T xx) : x(xx), y(xx), z(xx) { }

    Vec3(T xx, T yy, T zz) : x(xx), y(yy), z(zz) {}
    Vec3& normalize()
    {
        T nor2 = length2();
        if (nor2 > 0) {
            T invNor = 1 / sqrt(nor2);
            x *= invNor, y *= invNor, z *= invNor;
        }
        return *this;
    }

    Vec3<T> operator * (const T …
Run Code Online (Sandbox Code Playgroud)

c++ 3d graphics geometry raytracing

5
推荐指数
1
解决办法
7008
查看次数

BRDF通常如何实施?

我有一个小的路径跟踪器,我试图弄清楚如何实现一些基本的BRDF。这是我使用的管道的简要说明(无递归):

1) For each pixel:
   1.1) For each sample:
      1.1.1) I construct a path.
      1.1.2) I calculate the contribution of this path.
      1.1.3) I calculate the "probability" of this path.
      1.1.4) Finally, I calculate the overall color value(taking into account number of samples, "probability" and contribution of the path).
   1.2) Take the sum of all samples' values and write it to the pixel.
Run Code Online (Sandbox Code Playgroud)

因此,我在步骤中计算反射光线的方向1.1.1) I construct a path

目前,我已经实现了漫反射,镜面反射,光泽反射和折射。现在,我想实现一个复杂的BRDF,比方说Cook-Torrance BRDF。我看到它包含几个成分(漫反射和镜面反射)。我应该如何追踪这些光线以获得组合?我应该像往常一样在diffuse_ray / specular_ray之间进行选择,然后像往常一样累加值(乘以一些系数)吗?(例如,如果随机值大于0.5,那么我将跟踪漫射射线,否则为-镜面反射)还是应该跟踪多条射线从每个路口?

通常在基于物理的渲染器中如何实现?

PS:如果有人知道关于该主题的一些好文章,我将很高兴看到他们。我尝试阅读pbrt,但对我来说似乎非常复杂且庞大。某些地方的实现方式有所不同,例如相机模型和其他东西。

reflection graphics raytracing render pbr

5
推荐指数
1
解决办法
782
查看次数