discard
在GLSL中,通过使用discard语句可以跳过对片段的渲染。如果在片段着色器中使用discard语句将某个像素丢弃,那么执行会立即终止,并且不会将任何内容写入帧缓冲区。
使用discard语句可以帮助你实现一些特定的效果,例如在某些情况下对片段进行剔除或遮挡。这在处理透明度、深度测试或其他图形渲染技术时非常有用。
discard vs alpha
discard语句和将alpha设置为0 这两种方法在实现相同的效果上是等效的,即丢弃某个片段,使其不参与最终的图像输出。
选择哪种方法更好取决于你的具体需求和场景。下面是一些考虑因素:
精确度:使用discard语句可以直接丢弃整个片段,不进行后续的计算和处理。这可能更高效,因为它避免了不必要的计算和内存写入。而将alpha设置为0可能需要进行一些额外的计算,特别是在混合(blending)和透明度测试(alpha testing)等场景下。
兼容性:使用discard语句时,需要确保目标平台和图形API(例如OpenGL或WebGL)支持该语句。大多数现代的平台和API都支持discard语句,但在某些较旧的硬件或软件中可能存在兼容性问题。而将alpha设置为0是一个更通用的方法,在各种平台和API上都可以使用。
粒度控制:使用discard语句可以更细粒度地控制哪些片段被丢弃。你可以根据具体的条件或规则选择性地丢弃片段。而将alpha设置为0将会影响整个片段的透明度,无法对每个像素进行个别控制。
综上所述,如果你需要精确而高效地丢弃整个片段,同时平台和API支持discard语句,那么使用discard语句可能是更好的选择。如果你需要更通用的方法,或者需要对每个像素进行个别的透明度控制,那么将alpha设置为0可能更适合。
作业
precision mediump float;
void main() {
//TODO: Replace this with a function that draws a checkerboard
discard;
}
提示
要创建一个有规律的一维方块网格,可以使用fract和step函数:
- fract函数用于获取一个值的小数部分,即去除整数部分后的部分。
- step函数用于比较两个值,并返回一个阶梯函数的结果。当第一个值小于等于第二个值时,返回1.0;否则返回0.0。
通过结合使用这两个函数,可以创建一个周期性的方块网格。具体而言,可以使用fract函数将坐标值映射到一个单位区间内(例如[0,1]),然后使用step函数来判断坐标是否在特定区间内。
这样,通过适当的参数设置,就可以实现周期性的方块网格的创建。
bool inTile(vec2 p, float tileSize) {
vec2 ptile = step(0.5, fract(0.5 * p / tileSize));
return ptile.x == ptile.y;
}
答案
precision mediump float;
bool inTile(vec2 p, float tileSize) {
vec2 ptile = step(0.5, fract(0.5 * p / tileSize));
return ptile.x
== ptile.y;
}
void main() {
//TODO: Replace this with a function that draws a checkerboard
if ( inTile(gl_FragCoord.xy, 16.) ) {
gl_FragColor = vec4(1.);
} else {
discard;
}
}