因为dFdx
必须涵盖每一个案例,
我认为它必须像这个伪代码一样实现:
vecN dFdx( vecN )
{
wait_for_other_to_reach_here();
return calculate_difference();
}
但是看,如果我们传递单变量变量,它很简单。因为变化会插入线性。
示例片段着色器:
in vec3 v_vertex;
void main()
{
// it must be same result for all fragments in one triangle
vec3 dx = dFdx( v_vertex );
vec2 dy = dFdy( v_vertex );
vec3 normal = normalize( cross( dx , dy ) );
....
....
}
答案 0 :(得分:5)
首先,除非使用noperspective
或flat
插值限定符,否则变换不会线性插值。由于透视校正(除非使用正交投影),插值在屏幕空间中将是非线性的。
其次,为什么你认为会发生等待操作?片段着色器并行运行 ,并且GPU确保始终至少在2x2像素四边形上运行片段着色器,在同一个warp / wavefront / SIMD组中完全锁定,即使这包括原语之外的像素。这意味着GPU总是可以计算派生,而不必等待邻居片段赶上。 Modern GL甚至会通过gl_HelperInvocation
输入告诉您片段着色器调用是否只是原语之外的辅助调用。