光线跟踪程序中的全向光给出了错误的渲染c++; 我试图在C++中的光线跟踪程序中实现全向光源(A.K.A,点光源)。我没有得到预期的结果,但我无法解决问题。也许有人能看出我做错了什么。 我已经包括了负责光线跟踪和灯光的两个功能。ClosestIntersection函数查找最近的交点和三角形。这将在以后的DirectLight功能中使用。 我真的很感激任何帮助 #include <iostream> #include <glm/glm.hpp> #include <SDL.h> #include "SDLauxiliary.h" #include "TestModel.h" #include "math.h" using namespace std; using glm::vec3; using glm::mat3; // ---------------------------------------------------------------------------- // GLOBAL VARIABLES const int SCREEN_WIDTH = 500; const int SCREEN_HEIGHT = 500; SDL_Surface* screen; int t; vector<Triangle> triangles; float focalLength = 900; vec3 cameraPos(0, 0, -4.5); vec3 lightPos(0.5, 0.5, 0); vec3 lightColor = 14.f * vec3(1,1,1); // Translate camera float translation = 0.1; // use this to set translation increment // Rotate camera float yaw; vec3 trueCameraPos; const float PI = 3.1415927; // ---------------------------------------------------------------------------- // CLASSES class Intersection; // ---------------------------------------------------------------------------- // FUNCTIONS void Update(); void Draw(); bool ClosestIntersection(vec3 start, vec3 dir, const vector<Triangle>& triangles, Intersection& closestIntersection); vec3 DirectLight(const Intersection& i); // ---------------------------------------------------------------------------- // STRUCTURES struct Intersection { vec3 position; float distance; int triangleIndex; }; float m = std::numeric_limits<float>::max(); int main(int argc, char* argv[]) { LoadTestModel(triangles); screen = InitializeSDL(SCREEN_WIDTH, SCREEN_HEIGHT); t = SDL_GetTicks(); // Set start value for timer. while (NoQuitMessageSDL()) { Update(); Draw(); } SDL_SaveBMP(screen, "screenshot.bmp"); return 0; } void Update() { // Compute frame time: int t2 = SDL_GetTicks(); float dt = float(t2 - t); t = t2; cout << "Render time: " << dt << " ms." << endl; } } void Draw() { if (SDL_MUSTLOCK(screen)) SDL_LockSurface(screen); for (int y = 0; y<SCREEN_HEIGHT; ++y) { for (int x = 0; x < SCREEN_WIDTH; ++x) { vec3 start = cameraPos; vec3 dir(x - SCREEN_WIDTH / 2, y - SCREEN_HEIGHT / 2, focalLength); Intersection intersection; if (ClosestIntersection(start, dir, triangles, intersection)) { //vec3 theColor = triangles[intersection.triangleIndex].color; vec3 theColor = DirectLight(intersection); PutPixelSDL(screen, x, y, theColor); } else { vec3 color(0, 0, 0); PutPixelSDL(screen, x, y, color); } } } if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); SDL_UpdateRect(screen, 0, 0, 0, 0); } bool ClosestIntersection(vec3 s, vec3 d, const vector<Triangle>& triangles, Intersection& closestIntersection) { closestIntersection.distance = m; for (size_t i = 0; i < triangles.size(); i++) { vec3 v0 = triangles[i].v0; vec3 v1 = triangles[i].v1; vec3 v2 = triangles[i].v2; vec3 u = v1 - v0; vec3 v = v2 - v0; vec3 b = s - v0; vec3 x; // Determinant of A = [-d u v] float det = -d.x * ((u.y * v.z) - (v.y * u.z)) - u.x * ((-d.y * v.z) - (v.y * -d.z)) + v.x * ((-d.y * u.z) - (u.y * -d.z)); // Cramer'r Rule for t = x.x x.x = (b.x * ((u.y * v.z) - (v.y * u.z)) - u.x * ((b.y * v.z) - (v.y * b.z)) + v.x * ((b.y * u.z) - (u.y * b.z))) / det; if (x.x >= 0) { // Cramer'r Rule for u = x.y x.y = (-d.x * ((b.y * v.z) - (v.y * b.z)) - b.x * ((-d.y * v.z) - (v.y * -d.z)) + v.x * ((-d.y * b.z) - (b.y * -d.z))) / det; // Cramer'r Rule for v = x.z x.z = (-d.x * ((u.y * b.z) - (b.y * u.z)) - u.x * ((-d.y * b.z) - (b.y * -d.z)) + b.x * ((-d.y * u.z) - (u.y * -d.z))) / det; if (x.y >= 0 && x.z >= 0 && x.y + x.z <= 1 && x.x < closestIntersection.distance) { closestIntersection.position = x; closestIntersection.distance = x.x; closestIntersection.triangleIndex = i; } } } //end of for loop if (closestIntersection.distance != m) { return true; } else { return false; } } vec3 DirectLight(const Intersection& i) { vec3 n = triangles[i.triangleIndex].normal; vec3 r = lightPos - i.position; float R2 = r.x * r.x + r.y * r.y + r.z * r.z; vec3 D = (lightColor * fmaxf((glm::dot(glm::normalize(r), n)), 0)) / (4 * PI * R2); return D; } #包括 #包括 #包括 #包括“SDLauxiliary.h” #包括“TestModel.h” #包括“math.h” 使用名称空间std; 使用glm::vec3; 使用glm::mat3; // ---------------------------------------------------------------------------- //全局变量 屏幕宽度=500; 屏幕内的常数_高度=500; SDL_表面*屏幕; int t; 矢量三角形; 浮动焦点长度=900; vec3 cameraPos(0,0,-4.5); vec3-lightPos(0.5,0.5,0); vec3-lightColor=14.f*vec3(1,1,1); //平移摄像机 浮点转换=0.1;//使用此选项设置平移增量 //旋转摄像机 浮动偏航; vec3-trueCameraPos; 常数浮点PI=3.1415927; // ---------------------------------------------------------------------------- //班级 等级交叉; // ---------------------------------------------------------------------------- //功能 无效更新(); 无效抽取(); 布尔闭合区间(矢量3开始、矢量3方向、常量矢量和三角形、, 交叉口和封闭区间); vec3直射灯(康斯特交叉口和i); // ---------------------------------------------------------------------------- //结构 结构交点 { vec3位置; 浮动距离; int三角形索引; }; float m=std::numeric_limits::max(); int main(int argc,char*argv[]) { LoadTestModel(三角形); 屏幕=初始值DL(屏幕宽度、屏幕高度); t=SDL_GetTicks();//设置计时器的启动值。 while(NoQuitMessageSDL()) { 更新(); Draw(); } SDL_SaveBMP(屏幕,“screenshot.bmp”); 返回0; } 无效更新() { //计算帧时间: int t2=SDL_GetTicks(); 浮动dt=浮动(t2-t); t=t2; cout

光线跟踪程序中的全向光给出了错误的渲染c++; 我试图在C++中的光线跟踪程序中实现全向光源(A.K.A,点光源)。我没有得到预期的结果,但我无法解决问题。也许有人能看出我做错了什么。 我已经包括了负责光线跟踪和灯光的两个功能。ClosestIntersection函数查找最近的交点和三角形。这将在以后的DirectLight功能中使用。 我真的很感激任何帮助 #include <iostream> #include <glm/glm.hpp> #include <SDL.h> #include "SDLauxiliary.h" #include "TestModel.h" #include "math.h" using namespace std; using glm::vec3; using glm::mat3; // ---------------------------------------------------------------------------- // GLOBAL VARIABLES const int SCREEN_WIDTH = 500; const int SCREEN_HEIGHT = 500; SDL_Surface* screen; int t; vector<Triangle> triangles; float focalLength = 900; vec3 cameraPos(0, 0, -4.5); vec3 lightPos(0.5, 0.5, 0); vec3 lightColor = 14.f * vec3(1,1,1); // Translate camera float translation = 0.1; // use this to set translation increment // Rotate camera float yaw; vec3 trueCameraPos; const float PI = 3.1415927; // ---------------------------------------------------------------------------- // CLASSES class Intersection; // ---------------------------------------------------------------------------- // FUNCTIONS void Update(); void Draw(); bool ClosestIntersection(vec3 start, vec3 dir, const vector<Triangle>& triangles, Intersection& closestIntersection); vec3 DirectLight(const Intersection& i); // ---------------------------------------------------------------------------- // STRUCTURES struct Intersection { vec3 position; float distance; int triangleIndex; }; float m = std::numeric_limits<float>::max(); int main(int argc, char* argv[]) { LoadTestModel(triangles); screen = InitializeSDL(SCREEN_WIDTH, SCREEN_HEIGHT); t = SDL_GetTicks(); // Set start value for timer. while (NoQuitMessageSDL()) { Update(); Draw(); } SDL_SaveBMP(screen, "screenshot.bmp"); return 0; } void Update() { // Compute frame time: int t2 = SDL_GetTicks(); float dt = float(t2 - t); t = t2; cout << "Render time: " << dt << " ms." << endl; } } void Draw() { if (SDL_MUSTLOCK(screen)) SDL_LockSurface(screen); for (int y = 0; y<SCREEN_HEIGHT; ++y) { for (int x = 0; x < SCREEN_WIDTH; ++x) { vec3 start = cameraPos; vec3 dir(x - SCREEN_WIDTH / 2, y - SCREEN_HEIGHT / 2, focalLength); Intersection intersection; if (ClosestIntersection(start, dir, triangles, intersection)) { //vec3 theColor = triangles[intersection.triangleIndex].color; vec3 theColor = DirectLight(intersection); PutPixelSDL(screen, x, y, theColor); } else { vec3 color(0, 0, 0); PutPixelSDL(screen, x, y, color); } } } if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); SDL_UpdateRect(screen, 0, 0, 0, 0); } bool ClosestIntersection(vec3 s, vec3 d, const vector<Triangle>& triangles, Intersection& closestIntersection) { closestIntersection.distance = m; for (size_t i = 0; i < triangles.size(); i++) { vec3 v0 = triangles[i].v0; vec3 v1 = triangles[i].v1; vec3 v2 = triangles[i].v2; vec3 u = v1 - v0; vec3 v = v2 - v0; vec3 b = s - v0; vec3 x; // Determinant of A = [-d u v] float det = -d.x * ((u.y * v.z) - (v.y * u.z)) - u.x * ((-d.y * v.z) - (v.y * -d.z)) + v.x * ((-d.y * u.z) - (u.y * -d.z)); // Cramer'r Rule for t = x.x x.x = (b.x * ((u.y * v.z) - (v.y * u.z)) - u.x * ((b.y * v.z) - (v.y * b.z)) + v.x * ((b.y * u.z) - (u.y * b.z))) / det; if (x.x >= 0) { // Cramer'r Rule for u = x.y x.y = (-d.x * ((b.y * v.z) - (v.y * b.z)) - b.x * ((-d.y * v.z) - (v.y * -d.z)) + v.x * ((-d.y * b.z) - (b.y * -d.z))) / det; // Cramer'r Rule for v = x.z x.z = (-d.x * ((u.y * b.z) - (b.y * u.z)) - u.x * ((-d.y * b.z) - (b.y * -d.z)) + b.x * ((-d.y * u.z) - (u.y * -d.z))) / det; if (x.y >= 0 && x.z >= 0 && x.y + x.z <= 1 && x.x < closestIntersection.distance) { closestIntersection.position = x; closestIntersection.distance = x.x; closestIntersection.triangleIndex = i; } } } //end of for loop if (closestIntersection.distance != m) { return true; } else { return false; } } vec3 DirectLight(const Intersection& i) { vec3 n = triangles[i.triangleIndex].normal; vec3 r = lightPos - i.position; float R2 = r.x * r.x + r.y * r.y + r.z * r.z; vec3 D = (lightColor * fmaxf((glm::dot(glm::normalize(r), n)), 0)) / (4 * PI * R2); return D; } #包括 #包括 #包括 #包括“SDLauxiliary.h” #包括“TestModel.h” #包括“math.h” 使用名称空间std; 使用glm::vec3; 使用glm::mat3; // ---------------------------------------------------------------------------- //全局变量 屏幕宽度=500; 屏幕内的常数_高度=500; SDL_表面*屏幕; int t; 矢量三角形; 浮动焦点长度=900; vec3 cameraPos(0,0,-4.5); vec3-lightPos(0.5,0.5,0); vec3-lightColor=14.f*vec3(1,1,1); //平移摄像机 浮点转换=0.1;//使用此选项设置平移增量 //旋转摄像机 浮动偏航; vec3-trueCameraPos; 常数浮点PI=3.1415927; // ---------------------------------------------------------------------------- //班级 等级交叉; // ---------------------------------------------------------------------------- //功能 无效更新(); 无效抽取(); 布尔闭合区间(矢量3开始、矢量3方向、常量矢量和三角形、, 交叉口和封闭区间); vec3直射灯(康斯特交叉口和i); // ---------------------------------------------------------------------------- //结构 结构交点 { vec3位置; 浮动距离; int三角形索引; }; float m=std::numeric_limits::max(); int main(int argc,char*argv[]) { LoadTestModel(三角形); 屏幕=初始值DL(屏幕宽度、屏幕高度); t=SDL_GetTicks();//设置计时器的启动值。 while(NoQuitMessageSDL()) { 更新(); Draw(); } SDL_SaveBMP(屏幕,“screenshot.bmp”); 返回0; } 无效更新() { //计算帧时间: int t2=SDL_GetTicks(); 浮动dt=浮动(t2-t); t=t2; cout,c++,visual-studio,raytracing,C++,Visual Studio,Raytracing,如果我正确理解了ClosestIntersection中的代码,下面是它对每个三角形的作用: 假设u,v是从三角形的一个顶点到另外两个顶点的向量,d是我们正在考虑的光线方向的反方向 设b是从三角形顶点到摄像机的向量 找到p,q,r,这样b=pd+qu+rv(p,q,r就是代码所称的x.x,x.y,x.z) 如果p>0,q>=0,r>=0,q+r这不是一个非常好的答案,但是我设法让你的代码在没有奇怪的阴影间断的情况下工作。问题发生在ClosestIntersection中,也许Gareth的答案

如果我正确理解了
ClosestIntersection
中的代码,下面是它对每个三角形的作用:

  • 假设u,v是从三角形的一个顶点到另外两个顶点的向量,d是我们正在考虑的光线方向的反方向
  • 设b是从三角形顶点到摄像机的向量
  • 找到p,q,r,这样b=pd+qu+rv(p,q,r就是代码所称的x.x,x.y,x.z)

  • 如果p>0,q>=0,r>=0,q+r这不是一个非常好的答案,但是我设法让你的代码在没有奇怪的阴影间断的情况下工作。问题发生在
    ClosestIntersection
    中,也许Gareth的答案涵盖了它。我现在需要停止看这个问题,但我想向你展示我以前的经历我离开了,我需要一个答案来发布一些代码

    // This starts with some vec3 helper functions which make things
    // easier to look at
    float Dot(const vec3& a, const vec3& b) {
        return a.x * b.x + a.y * b.y + a.z * b.z;
    }
    vec3 Cross(const vec3& a, const vec3& b) {
       return vec3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); 
    }
    float L2(const vec3& v) { return v.x*v.x + v.y*v.y + v.z*v.z; }
    float Abs(const vec3& v) { return std::sqrt(L2(v)); }
    
    // Here is the replacement version of ClosestIntersection
    bool ClosestIntersection(vec3 cam, vec3 dir,
        const vector<Triangle>& triangles, Intersection& closestIntersection) 
    {
        closestIntersection.distance = m;
        vec3 P0 = cam;
        vec3 P1 = cam + dir;
        for (size_t i = 0; i < triangles.size(); ++i) {
            vec3 v0 = triangles[i].v0;
            vec3 v1 = triangles[i].v1;
            vec3 v2 = triangles[i].v2;
            // Dan Sunday
            // http://geomalgorithms.com/a06-_intersect-2.html
            vec3 u = v1 - v0;
            vec3 v = v2 - v0;
            // w = P-v0, solve w = su +tv (s, t are parametric scalars)
    
            vec3 n = Cross(u, v);
            float ri = Dot(n, (v0 - P0)) / Dot(n, (P1 - P0));
            vec3 Pi = P0 + ri * (P1- P0);
            vec3 w = Pi - v0;
    
            // s = w . (n x v) / (u . (n x v))
            // t = w . (n x u) / (v . (n x u))
    
            float s = Dot(w, Cross(n, v)) / Dot(u, Cross(n, v));
            float t = Dot(w, Cross(n, u)) / Dot(v, Cross(n, u));
    
            if(s >= 0 && t >= 0 && s+t <= 1) {
                float dist = Abs(cam - Pi);
                if(dist < closestIntersection.distance) {
                    closestIntersection.position      = Pi;
                    closestIntersection.distance      = dist;
                    closestIntersection.triangleIndex = int(i);
                }
            }
        }
    
        return closestIntersection.distance != m;
    }
    
    //这是从一些vec3助手函数开始的,这些函数
    //更容易看
    浮点数(常数向量3&a、常数向量3&b){
    返回a.x*b.x+a.y*b.y+a.z*b.z;
    }
    vec3交叉(常数vec3&a、常数vec3&b){
    返回vec3(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);
    }
    浮点L2(const vec3&v){返回v.x*v.x+v.y*v.y+v.z*v.z;}
    浮点Abs(constvec3&v){returnstd::sqrt(L2(v));}
    //这是ClosestIntersection的替换版本
    bool ClosestIntersection(vec3凸轮、vec3方向、,
    常量向量和三角形、交点和闭合截面)
    {
    closestIntersection.distance=m;
    vec3 P0=cam;
    vec3 P1=凸轮+方向;
    对于(size_t i=0;i如果(s>=0&&t>=0&&s+t只是出于好奇,为什么要删除此问题的答案?因为我想发布整个代码,而当我更改问题时,人们通常会抱怨。所以我想发布一个新的:)非常感谢!非常感谢您抽出时间:)谢谢您的明确解释!这就是我在花了很长时间才让它发挥作用之后所需要的:)