Reputation: 1421
I understand that if some uniform
variable is not actively contributing to pipeline's output, it is optimized and it should return -1. Consider a fragment shader below.
const char fShader[] = "precision mediump float; \n"
"uniform float uGlobalTime; \n"
"const int iMaxIterations = 6; \n"
"float fCircleSize = 1.0 / (3.0 * pow(2.0, float(iMaxIterations))); \n"
"vec2 Rotate(vec2 uv, float a) \n"
"{ \n"
"return vec2(uv.x * cos(a) - uv.y * sin(a), uv.y * cos(a) + uv.x * sin(a)); \n"
"} \n";
"void main() \n"
"{ \n"
"vec2 uv = vec2(1280.0, 720.0); \n"
"uv = -0.5 * (uv - 2.0 * gl_FragCoord.xy) / uv.x; \n"
"uv = Rotate(uv, uGlobalTime); \n"
"uv *= sin(uGlobalTime) * 0.5 + 1.5; \n"
"float s = 0.3; \n"
"for(int i = 0 ; i < iMaxIterations; ++i) \n"
"{ \n"
"uv = abs(uv) - s; \n"
"uv = Rotate(uv, uGlobalTime); \n"
"s = s / 2.0; \n"
"} \n"
"float c = length(uv) > fCircleSize ? 0.0:1.0; \n"
"gl_FragColor = vec4(c * uGlobalTime, c * uGlobalTime, c * uGlobalTime, 1.0); \n"
"} \n";
This sincerely tries to use passed uniform at several location, and in the final output color as well. But I am still getting -1 as return value. There is no error though. I don;t think anything wrong on my side as well.
Optimization is done, I am sure. I checked no of active uniforms, and there are 2 only. I am using 3. BUT WHY on the earth..., is compiler blind..?? I can get around by using attribute, but why should I?
Edit
Please see my vertex shader as well
const char vShader[] = "attribute vec3 vPosition; \n"
"uniform mat4 uMVMatrix; \n"
"uniform mat4 uPMatrix; \n"
"void main(void) \n"
"{ \n"
"gl_Position = uPMatrix * uMVMatrix * vec4(vPosition, 1.0); \n"
"} \n";
I am listing my own workaround:
adding 3 lines in vertex shader at appropriate locations:
"attribute float vGlobalTime \n"
"varying float globalTime; \n"
"globalTime = vGlobalTime; \n"
and 1 new line in fragment shader:
"varying float globalTime; \n"
And now using globalTime
in all places where I had earlier used uGlobalTime
PS: I have not tested this; but I don't see any reason why it should not work.
Upvotes: 0
Views: 965
Reputation: 1210
There is a wild semicolon at the end of line 7 of your fragment shader C++ source string definition.
const char* source =
"line 1"
"line 2"; // <- semicolon intended?
"line 3+ ignored"; // <- lose string constant which is never assigned to anything
This causes the whole main function of your fragment shader to be skipped and shouldn't even link at all. Did you check for errors after linking your program?
Think about outsourcing your shader code into an external file, which prevents typos like this and also removes the need for recompiling your application each time you change a shader.
bool Shader::compileFromFile(const std::string& filename)
{
std::ifstream stream(filename, std::ios_base::in);
if (!stream.is_open())
return false;
std::string source{std::istreambuf_iterator<char>(stream),
std::istreambuf_iterator<char>()};
return compile(source);
}
Upvotes: 5