Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenGL中的非随机半球样本_C++_Opengl - Fatal编程技术网

C++ OpenGL中的非随机半球样本

C++ OpenGL中的非随机半球样本,c++,opengl,C++,Opengl,我目前正在使用一种采样方法来跟踪光线,我使用这段代码对半球上的一个随机点进行采样并输出一个向量: vec3 CosWeightedRandomHemisphereDirection( vec3 n, float rand1, float rand2 ) { float Xi1 = rand1; float Xi2 = rand2; float theta = acos(sqrt(1.0-Xi1)); float phi = 2.0 * 3.141592653

我目前正在使用一种采样方法来跟踪光线,我使用这段代码对半球上的一个随机点进行采样并输出一个向量:

vec3 CosWeightedRandomHemisphereDirection( vec3 n, float rand1, float rand2 )
{
    float Xi1 = rand1;
    float Xi2 = rand2;

    float  theta = acos(sqrt(1.0-Xi1));
    float  phi = 2.0 * 3.1415926535897932384626433832795 * Xi2;

    float xs = sin(theta) * cos(phi);
    float ys = cos(theta);
    float zs = sin(theta) * sin(phi);

    vec3 y = n;
    vec3 h = y;
    if (abs(h.x)<=abs(h.y) && abs(h.x)<=abs(h.z))
        h.x= 1.0;
    else if (abs(h.y)<=abs(h.x) &&abs(h.y)<=abs(h.z))
        h.y= 1.0;
    else
        h.z= 1.0;

    vec3 x = normalize(cross(h,y));
    vec3 z = normalize(cross(x,y));

    vec3 direction = xs * x + ys * y + zs * z;
    return normalize(direction);
}
其中sampleDir是6个固定方向之一 此外,由于位置将是固定的,代码可以优化吗

编辑:

我注意到方向仅适用于指向上或下的法线,而不适用于其他法线(我花了一段时间才注意到,因为我一直在使用随机方向)。这是我现在使用的代码

    vec3 FixedHemisphereDirection( vec3 n, vec3 sampleDir)
{
    vec3 x;
    vec3 z;

    if(abs(n.x) < abs(n.y)){
        if(abs(n.x) < abs(n.z)){
            x = vec3(1.0f,0.0f,0.0f);
        }else{
            x = vec3(0.0f,0.0f,1.0f);
        }
    }else{
        if(abs(n.y) < abs(n.z)){
            x = vec3(0.0f,1.0f,0.0f);
        }else{
            x = vec3(0.0f,0.0f,1.0f);
        }
    }

    z = normalize(cross(x,n));
    x = cross(n,z);

    mat3 M = mat3(  x.x, n.x, z.x,
                    x.y, n.y, z.y,
                    x.z, n.z, z.z);
    return M*sampleDir;
}
vec3固定半球方向(vec3 n,vec3 sampleDir)
{
vec3x;
vec3z;
如果(abs(n.x)
单个法线不足以唯一标识半球的局部坐标系。它可以围绕该法线向任何方向旋转

我们首先需要建立局部坐标系。因此,我们需要局部x轴和z轴。y轴已经由法线给定。所有轴应相互正交。因此,我们可以做到以下几点:

x := (1, 0, 0)
z := normalize(cross(x, n))
x := cross(n, z)
如果法线平行于
(1,0,0)
,则应选择另一个x轴,因为叉积将为零

从这些轴,我们可以构造一个变换矩阵:

     / x.x  n.x  z.x \
M := | x.y  n.y  z.y |
     \ x.z  n.z  z.z /
这是将六个给定方向转换为
n
指定的半球方向的矩阵

dir := randomly pick on of the six directions
return M * dir

它不只是随机选取六个向量中的一个吗?不,因为模板向量(0,1,0)指向样本球体,但当我使用它时,它必须指向与法线相同的方向。其他人必须指出,这应该是正常的。等一下,我会发布一个答案。嘿,很抱歉打扰你,我添加了一个编辑,因为我发现了一个问题,你能检查一下吗?看起来不错。你正确调用矩阵构造函数了吗?也就是说,条目的顺序是否可以转换,因此
(x.x,x.y,x.z…
dir := randomly pick on of the six directions
return M * dir