GLSL中简单光线跟踪器的反射问题
我正在用GLSL 4.0编写一个简单的光线跟踪器,在使用正确的着色(phong)进行基本反射时遇到了一些问题。我在一个“渲染到纹理”(render to texture)着色器(与屏幕对齐的四边形)中编写,我的场景由6个球体和一个平面组成,如下面的代码所述。我使用GLSL中简单光线跟踪器的反射问题,glsl,raytracing,Glsl,Raytracing,我正在用GLSL 4.0编写一个简单的光线跟踪器,在使用正确的着色(phong)进行基本反射时遇到了一些问题。我在一个“渲染到纹理”(render to texture)着色器(与屏幕对齐的四边形)中编写,我的场景由6个球体和一个平面组成,如下面的代码所述。我使用交叉点结构来跟踪交叉点,使用光线结构来跟踪光线。由于GLSL 4.0不允许递归,我正在迭代地投射次光线(通过每次迭代更改光线的方向和原点) #版本400 在vec3-dir中; 脱色; 均匀mat4-mMatrix; 一致mat4矩阵;
交叉点
结构来跟踪交叉点,使用光线
结构来跟踪光线。由于GLSL 4.0不允许递归,我正在迭代地投射次光线(通过每次迭代更改光线的方向和原点)
#版本400
在vec3-dir中;
脱色;
均匀mat4-mMatrix;
一致mat4矩阵;
均匀mat4-mvMatrixScene;
均匀mat4矩阵;
一致mat3正规矩阵//无平移的mv矩阵
均匀vec3光=vec3(6,4,3);
均匀vec4环境=vec4(0.0,0.0,0.0,1.0);
均匀vec4漫反射=vec4(1.0,0.1,0.0,1.0);
均匀vec4镜面反射=vec4(1.0,1.0,1.0,1.0);
均匀浮动环境系数=1.0;
均匀浮动扩散系数=1.0;
均匀浮动镜面反射率=1.0;
常量浮点PI=3.14159265358979;
常数int raytraceDepth=2;
常数int numSpheres=6;
//示例数据结构
结构射线
{
vec3来源;
vec3-dir;
};
结构球
{
vec3中心;
浮动半径;
vec3颜色;
};
结构平面
{
vec3点;
vec3正常;
vec3颜色;
};
结构交点
{
浮动t;//最近命中
vec3点;//命中点
vec3 normal;//normal
int hit;//它击中了吗?
vec3 color;//颜色累积,也可以在struct Ray中实现
};
空心球体_相交(球体sph、光线、输入-输出相交){
vec3 dp=射线原点-sph中心;
vec3d=ray.dir;
浮球r=sph半径;
//球体相交吗?
浮动x=功率(点(d,dp),2.0)-功率(长度(dp),2.0)+功率(r,2.0);
intersect.hit=0;
如果(x>=0){
浮点数u1=点(-d,dp)+sqrt(x);
浮点数u2=点(-d,dp)-sqrt(x);
浮动u=最小值(u1,u2);
if(u=0){
浮点u=-dot((光线原点-pl.point),pl.normal)/x;
if(u 对于(int i=0;i)您使用什么样的球体相交算法?我对代码中的内容有点困惑。
#version 400
in vec3 dir;
out vec4 outcolour;
uniform mat4 mMatrix;
uniform mat4 mvMatrix;
uniform mat4 mvMatrixScene;
uniform mat4 pMatrix;
uniform mat3 normalMatrix; //mv matrix without translation
uniform vec3 light = vec3(6,4,3);
uniform vec4 ambient = vec4(0.0,0.0,0.0,1.0);
uniform vec4 diffuse = vec4(1.0,0.1,0.0,1.0);
uniform vec4 specular = vec4(1.0,1.0,1.0,1.0);
uniform float ambientCoefficent = 1.0;
uniform float diffuseCoefficent = 1.0;
uniform float specularCoefficent = 1.0;
const float PI = 3.14159265358979;
const int raytraceDepth = 2;
const int numSpheres = 6;
//example data structures
struct Ray
{
vec3 origin;
vec3 dir;
};
struct Sphere
{
vec3 centre;
float radius;
vec3 colour;
};
struct Plane
{
vec3 point;
vec3 normal;
vec3 colour;
};
struct Intersection
{
float t; //closest hit
vec3 point; // hit point
vec3 normal; // normal
int hit; //did it hit?
vec3 colour; // colour accumulation, can be also implemented in struct Ray
};
void sphere_intersect(Sphere sph, Ray ray, inout Intersection intersect) {
vec3 dp = ray.origin - sph.centre;
vec3 d = ray.dir;
float r = sph.radius;
// Does the sphere intersect?
float x = pow(dot(d,dp),2.0) - pow(length(dp),2.0) + pow(r,2.0);
intersect.hit = 0;
if (x >= 0) {
float u1 = dot(-d,dp) + sqrt(x);
float u2 = dot(-d,dp) - sqrt(x);
float u = min(u1,u2);
if (u < intersect.t) {
intersect.t = u;
intersect.colour = sph.colour;
intersect.point = ray.origin + intersect.t*d;
intersect.hit = 1;
intersect.normal = (intersect.point - sph.centre) / sph.radius;
}
}
}
void plane_intersect(Plane pl, Ray ray, inout Intersection intersect)
{
float x = dot(ray.dir,pl.normal);
// Assuming no paralel rays otherwise divide by 0 error
float h = dot(pl.point - ray.origin,pl.normal)/x;
intersect.hit = 0;
//intersect.colour = vec3(0.0,0.0,0.0);
intersect.point = vec3(0.0,0.0,0.0);
if (h >=0 ) {
float u = -dot((ray.origin - pl.point),pl.normal)/x;
if (u < intersect.t) {
intersect.t = u;
intersect.point = ray.origin + u*ray.dir;
intersect.normal = pl.normal;
intersect.hit = 1;
// Normal used is y so used x and z for checkerboard pattern
if (int((floor(intersect.point.x) + floor(intersect.point.z)))%2 == 1) {
intersect.colour = pl.colour;
} else {
intersect.colour = vec3(0.0,0.0,0.0);
}
}
}
}
Sphere sphere[numSpheres];
Plane plane;
vec4 local_shading_term(vec3 light, Intersection intersection) {
float q = 10;
float d = length(light - intersection.point);
float s = 10;
vec3 n = normalize(intersection.normal);
vec3 l = normalize(light - intersection.point);
vec3 r = normalize(-reflect(l,n));
vec3 v = -normalize(intersection.point);
vec4 diff = diffuse * diffuseCoefficent * vec4(max(dot(n,l),0));
vec4 spec = specular * specularCoefficent * vec4(pow(max(dot(v,r),0), q));
return (diff + spec) * 250 / (4 * PI * (d + s));
}
void Intersect(Ray ray, inout Intersection intersection)
{
vec3 colour = vec3(0.0,0.0,0.0);
int sphere_hits = 0;
// Sphere intersection
for (int i=0; i<numSpheres; i++) {
sphere_intersect(sphere[i],ray,intersection);
sphere_hits += intersection.hit;
}
if (sphere_hits > 0) {
colour = intersection.colour + vec3(local_shading_term(light,intersection));
}
// Plane intersection
plane_intersect(plane,ray,intersection);
if (sphere_hits == 0 ) {
colour = intersection.colour;
}
intersection.colour = colour;
}
void main()
{
//White
sphere[0].centre = vec3(-2.0, 1.5, -3.5);
sphere[0].radius = 1.5;
sphere[0].colour = vec3(0.8,0.8,0.8);
//Green
sphere[1].centre = vec3(-0.5, 0.0, -2.0);
sphere[1].radius = 0.6;
sphere[1].colour = vec3(0.3,0.8,0.3);
//Blue
sphere[2].centre = vec3(1.0, 0.7, -2.2);
sphere[2].radius = 0.8;
sphere[2].colour = vec3(0.3,0.8,0.8);
//Yellow
sphere[3].centre = vec3(0.7, -0.3, -1.2);
sphere[3].radius = 0.2;
sphere[3].colour = vec3(0.8,0.8,0.3);
//Red
sphere[4].centre = vec3(-0.7, -0.3, -1.2);
sphere[4].radius = 0.2;
sphere[4].colour = vec3(0.8,0.3,0.3);
//Purple
sphere[5].centre = vec3(0.2, -0.2, -1.2);
sphere[5].radius = 0.3;
sphere[5].colour = vec3(0.8,0.3,0.8);
plane.point = vec3(0,-0.5, 0);
plane.normal = vec3(0, 1.0, 0);
plane.colour = vec3(1, 1, 1);
vec4 colour = vec4(0,0,0,1);
Ray ray;
ray.origin = vec3(0.0,0.0,0.0);
ray.dir = normalize(dir);
Intersection intersection;
for (int i=0; i<raytraceDepth; i++) {
intersection.t = 999999999;
Intersect(ray,intersection);
ray.origin = intersection.point;
ray.dir = reflect(ray.dir,intersection.normal);
}
colour = vec4(intersection.colour,0.0);
outcolour = colour;
}