优化片段着色器中的GLSL代码(iOS 5和OpenGL ES 2.0)
我在片段着色器函数中进行了一些计算(如下),该函数被调用了很多次。我想知道是否有可能优化这段代码。我看了一下,并做了一些修改,但有可能使这段代码更快吗优化片段着色器中的GLSL代码(iOS 5和OpenGL ES 2.0),ios,opengl-es,glsl,Ios,Opengl Es,Glsl,我在片段着色器函数中进行了一些计算(如下),该函数被调用了很多次。我想知道是否有可能优化这段代码。我看了一下,并做了一些修改,但有可能使这段代码更快吗 uniform int mn; highp float Nx; highp float Ny; highp float Nz; highp float invXTMax; highp float invYTMax; int m; int n; highp vec4 func(in highp vec3 texCoords3
uniform int mn;
highp float Nx;
highp float Ny;
highp float Nz;
highp float invXTMax;
highp float invYTMax;
int m;
int n;
highp vec4 func(in highp vec3 texCoords3D)
{
// tile index
int Ti = int(texCoords3D.z * Nz);
// (r, c) position of tile withn texture unit
int r = Ti / n; // integer division
int c = Ti - r * n;
// x/y offsets in pixels of tile origin with the texture unit
highp float xOff = float(c) * Nx;
highp float yOff = float(r) * Ny;
// 2D texture coordinates
highp vec2 texCoords2D;
texCoords2D.x = (Nx * texCoords3D.x + xOff)*invXTMax;
texCoords2D.y = (Ny * texCoords3D.y + yOff)*invYTMax;
return texture2D(uSamplerTex0, texCoords2D);
}
编辑:
为了提供一些上下文,func()用作光线投射设置的一部分。它被称为
对于每个片段,从main()开始执行300次 将代码矢量化非常容易,如下所示:
highp vec3 N;
highp vec2 invTMax;
highp vec4 func(in highp vec3 texCoords3D)
{
// tile index
int Ti = int(texCoords3D.z * N.z);
// (r, c) position of tile within texture unit
int r = Ti / n;
int c = Ti - r * n;
// x/y offsets in pixels of tile origin with the texture unit
highp vec2 Off = vec2( float(c), float(r) ) * N;
// 2D texture coordinates
highp vec2 texCoords2D = ( N * texCoords3D.xy + Off ) * invTMax;
return texture2D(uSamplerTex0, texCoords2D);
}
以确保类似的计算并行运行。修改纹理坐标而不是使用传递到片段着色器的坐标会创建动态纹理读取,并在早期硬件上产生最大的性能影响 检查关于动态纹理查找的最后一节 他们建议将纹理坐标向上移动到片段着色器中。如果我正确理解代码的意图,看起来您可以不出什么问题。在UV(以及纹理)上添加偏移和平铺支持以进行精细调整、缩放和动画?我想是的。用这个
//
// Vertex Shader
//
attribute vec4 position;
attribute vec2 texture;
uniform mat4 modelViewProjectionMatrix;
// tiling parameters:
// -- x and y components of the Tiling (x,y)
// -- x and y components of the Offset (w,z)
// a value of vec4(1.0, 1.0, 0.0, 0.0) means no adjustment
uniform vec4 texture_ST;
// UV calculated in the vertex shader, GL will interpolate over the pixels
// and prefetch the texel to avoid dynamic texture read on pre ES 3.0 hw.
// This should be highp in the fragment shader.
varying vec2 uv;
void main()
{
uv = ((texture.xy * texture_ST.xy) + texture_ST.zw);
gl_Position = modelViewProjectionMatrix * position;
}
对我来说,它似乎并没有占用太多的计算时间…显示更多的上下文。最佳解决方案可能需要更改函数及其与调用方的关系。func()在循环中从主函数调用300次。这是光线投射设置的一部分。对于屏幕上的每个片段,这可能会被调用很多次,因此它确实会占用大量的计算时间。我怀疑它会带来巨大的提升,但您可以尝试在着色器上运行glsl optimizer:我看到的第一个问题是整数。不要那样做;取而代之的是圆形。由于OpenGLES2.0的GLSL中没有圆函数,所以您必须滚动自己的:符号(x)*地板(abs(x)+.5)。