【发布时间】:2022-11-11 22:30:36
【问题描述】:
我有一个非常简单的着色器程序,它将一堆位置数据作为 GL_POINTS 生成屏幕对齐的片段正方形,就像正常的大小取决于深度一样,然后在片段着色器中我想绘制一个非常简单的光线追踪每个球体,只有与光相对的球体上的阴影。我去了shadertoy 试图自己解决这个问题。我使用 sphIntersect 函数进行光线-球体相交,并使用 sphNormal 来获取球体上的法线向量以进行照明。问题是球体不与碎片的正方形对齐,导致它们被切断。这是因为我不确定如何匹配球体的投影和顶点位置以使它们对齐。我可以解释一下如何做到这一点吗?
这是一张供参考的图片。
这是我的顶点和片段着色器供参考:
//vertex shader:
#version 460
layout(location = 0) in vec4 position; // position of each point in space
layout(location = 1) in vec4 color; //color of each point in space
layout(location = 2) uniform mat4 view_matrix; // projection * camera matrix
layout(location = 6) uniform mat4 cam_matrix; //just the camera matrix
out vec4 col; // color of vertex
out vec4 posi; // position of vertex
void main() {
vec4 p = view_matrix * vec4(position.xyz, 1.0);
gl_PointSize = clamp(1024.0 * position.w / p.z, 0.0, 4000.0);
gl_Position = p;
col = color;
posi = cam_matrix * position;
}
//fragment shader:
#version 460
in vec4 col; // color of vertex associated with this fragment
in vec4 posi; // position of the vertex associated with this fragment relative to camera
out vec4 f_color;
layout (depth_less) out float gl_FragDepth;
float sphIntersect( in vec3 ro, in vec3 rd, in vec4 sph )
{
vec3 oc = ro - sph.xyz;
float b = dot( oc, rd );
float c = dot( oc, oc ) - sph.w*sph.w;
float h = b*b - c;
if( h<0.0 ) return -1.0;
return -b - sqrt( h );
}
vec3 sphNormal( in vec3 pos, in vec4 sph )
{
return normalize(pos-sph.xyz);
}
void main() {
vec4 c = clamp(col, 0.0, 1.0);
vec2 p = ((2.0*gl_FragCoord.xy)-vec2(1920.0, 1080.0)) / 2.0;
vec3 ro = vec3(0.0, 0.0, -960.0 );
vec3 rd = normalize(vec3(p.x, p.y,960.0));
vec3 lig = normalize(vec3(0.6,0.3,0.1));
vec4 k = vec4(posi.x, posi.y, -posi.z, 2.0*posi.w);
float t = sphIntersect(ro, rd, k);
vec3 ps = ro + (t * rd);
vec3 nor = sphNormal(ps, k);
if(t < 0.0) c = vec4(1.0);
else c.xyz *= clamp(dot(nor,lig), 0.0, 1.0);
f_color = c;
gl_FragDepth = t * 0.0001;
}
【问题讨论】:
-
请参阅Reflection and refraction impossible without recursive ray tracing? 和Ray and ellipsoid intersection accuracy improvement 和Atmospheric scattering GLSL fragment shader 最后一个与您的问题非常相似(它使用椭球周围的QUAD BBOX 渲染气氛......)
-
我会检查这些。另外,为了清楚起见,我不想要任何疯狂的效果,如反射或类似的东西。我只想要一个传球来塑造形状。
标签: opengl glsl raytracing