光线类型
GLSL中的默认光线有以下隐式的内置变量:
raytypeIMG {
highp vec3 gl_OriginIMG;
highp vec3 gl_DirectionIMG;
highp rayprogramIMG gl_PrefixRayProgramIMG;
lowp uint gl_SceneIMG;
highp float gl_MaxDistanceIMG;
mediump ivec2 gl_PixelIMG;
mediump uint gl_BounceCountIMG;
bool gl_IsOutgoingIMG;
bool gl_FlipFacingIMG;
bool gl_RunPrefixProgramIMG;
};
通过添加用户自定义变量界定默认光线的类型。例如,阴影光线如下所示:
layout(binding = 0, occlusion_test_always) raytypeIMG ShadowRay {
vec3 colour;
};
调用glSceneArrayRayBlockSizeIMG,可以界定使用的每个光线类型。调用glGetComponentProgramHandleIMG,可以界定每个组件集应该执行的顶点和光线着色器。创建一个像标准顶点或片段着色器一样的光线着色器。
帧着色器
流程的第一部分便是帧着色器。帧着色器是glsl着色器,根据glDispatchRaysIMG中参数请求的宽度x高度,可以发送零条或多条光线到场景中。注意,不需要通过当前帧着色器中的坐标来积累光线位置,即光线与像素位置不耦合。
layout (rgba8, binding = 0) uniform accumulateonly highp image2D rayTraceDiffuseImage;
layout(max_rays = 1) out;
out ShadowRay shadowRay;
uniform rayprogramIMG defaultRayProgram;
void emitShadowRay(highp vec3 p, highp vec3 normal, highp vec3 dir, highp float maxDistance, vec3 colour) {
shadowRay.gl_OriginIMG = p + depthModifier*normal;
shadowRay.gl_DirectionIMG = dir;
shadowRay.gl_PrefixRayProgramIMG = gl_NullRayProgramIMG;
shadowRay.gl_SceneIMG = uint(gl_DispatchRaysIDIMG);
shadowRay.gl_MaxDistanceIMG = maxDistance;
shadowRay.gl_PixelIMG = gl_FrameCoordIMG;
shadowRay.gl_BounceCountIMG = 0u;
shadowRay.gl_IsOutgoingIMG = true;
shadowRay.gl_FlipFacingIMG = false;
shadowRay.gl_RunPrefixProgramIMG = false;
shadowRay.colour = colour;
emitRayIMG(shadowRay, defaultRayProgram);
}
void main() {
emitShadowRay(vPosition, unpackedNormal, vNormalisedDirectionToLight, length(vDirectionToLight), vec3(1.0,0.0,0.0));
imageAddIMG(rayTraceDiffuseImage, gl_FrameCoordIMG, vec4(0.0,0.0,1.0,0.0));
}
可以看到,帧着色器有一些额外的添加至GLSL中。内置的命令是:
gl_DispatchRaysIDIMG 是输入glDispatchRaysIMG的第一个参数,用于多缓冲。
gl_FrameCoordIMG是目前帧着色器中的坐标。
gl_NullRayProgramIMG是无操作程序,用于比较rayprogramIMGs。
阴影光线具有可用的隐式光线类变量,如上所示,且每个变量在流程中执行某个函数。在帧着色器中,这些变量通常是可编辑而非可读取。
gl_OriginIMG是发送光线的源头。
gl_DirectionIMG是光线发送的方向。
gl_PrefixRayProgramIMG是运行交叉光线着色器之前可运行的前缀光线方案。
gl_SceneIMG是发送光线的场景id.(如上述glBindSceneArrayComponentGroupIMG中指定的参数)
gl_MaxDistanceIMG是光线所能追踪的最大距离,这里不考虑交叉,且运行defaultRayProgram。
gl_PixelIMG是光线发送的原始像素。
gl_BounceCountIMG是光线当前的反射数。(在帧着色器中通常为0)
gl_IsOutgoingIMG即光线向外延伸——详细信息在下一篇文章中讨论。
gl_FlipFacingIMG即是否在下次交叉中翻转表面以再次测试光线。
gl_RunPrefixProgramIMG即是否运行上述的前缀方案。
emitRayIMG是发送光线且将光线传输至交叉测试硬件的GLSL函数,而imageAddIMG是下文即将讨论的累积函数。
shadeRayIMG也可用。该函数可以在给定的光线方案内对光线着色,且不需要进行交叉测试。
光线着色器
当光线与三角形交叉、光线到达最大距离或想要运行前缀方案时,则启动光线着色器。在帧着色器中,我们仅编写光线变量;而在光线着色器中,我们可以读取光线变量,且发送更多光线时还可以编写光线变量。
layout(binding=0, occlusion_test_always) raytypeIMG ShadowRay {
highp vec3 diffuseObjectColor;
highp vec3 ambientObjectColor;
};
layout(binding=1, occlusion_test_never) raytypeIMG ReflectiveRay {
highp vec3 reflectiveColor;
};
layout(rgba8, binding=2) uniform accumulateonly highp image2D reflectionOutput;
in perVertexData {
highp vec3 vertexNormal;
highp vec2 vertexTexCoord;
} vertexData[];
rayInputHandlerIMG(ShadowRay inputRay) {
void main() {
imageAddIMG(reflectionOutput, inputRay.gl_PixelIMG, vec4(inputRay.ambientObjectColor, 0.0));
}
}
rayInputHandlerIMG(ReflectiveRay inputRay) {
layout(max_rays=2) out;
out ShadowRay reflectedShadowRay;
out ReflectiveRay reflectionRay;
评论
查看更多