2017-12-18 7 views
3

저는 OpenGL에서 일부 응용 프로그램을 개발해 왔습니다. 첫 번째 단계에서는 FBO에 3 개의 색상 텍스처가 첨부 된 값을 씁니다. 두 번째 패스에서는이 세 텍스처를 쉐이더의 샘플러로 연결하고 색상에 대한 계산을 수행합니다. 다음은 두 번째 패스의 셰이더 코드입니다.glGetUniformLocation은 첫 번째 샘플러가 아닌 경우 -1을 반환합니다.

const char* final_fragment_source[] = { 
    "uniform sampler2D rt1;\n" 
    "uniform sampler2D rt2;\n" 
    "uniform sampler2D rt3;\n" 
    "out vec4 color;\n" 
    "void main(){\n" 
    "vec3 bg = vec3(0.0, 0.0, 0.0);\n" 
    "vec4 RGB1 = texture2D(rt1,vec2(gl_FragCoord.xy));\n" 
    "vec4 RGB2 = texture2D(rt2,vec2(gl_FragCoord.xy));\n" 
    "vec4 RGB3 = texture2D(rt3,vec2(gl_FragCoord.xy));\n" 
    "vec3 tempcolor = RGB1.rgb - bg * RGB1.a + bg * RGB3.a + bg * RGB2.rgb * RGB3.a + RGB3.rgb * RGB2.a * 0.0f + bg;\n" 
    "color = vec4(tempcolor,0.25);\n" 
    "} \n" 
}; 

문제는 rt2 및 rt3에 대해 glGetUniformLocation()을 호출 할 때 -1이 발생합니다. 나는 rt1을위한 정확한 위치를 얻는다.

내가

을 시도이 - 난 당신이 조각 쉐이더에서 선언 균일 변수 중 하나를 사용 해달라고하면 다음 드라이버를 최적화하고 -1을 반환하는 변수 수 있다는 것을 알고있다. 여기 분명히 최종 색상 계산에 모든 변수를 사용하고 있습니다.

-이 셰이더 코드에는 컴파일 타임이나 링크 오류가 없습니다. 다음

내가 오류를 glGetError의()를 넣어 시도하고 오류가 발생하지 않습니다이라면 .. 닥터 버크

glUseProgram(fp_render_prog); 
err = glGetError(); 

rt1 = glGetUniformLocation(fp_render_prog, "rt1"); 
err = glGetError(); 

rt2 = glGetUniformLocation(fp_render_prog, "rt2"); 
err = glGetError(); 

rt3 = glGetUniformLocation(fp_render_prog, "rt3"); 
err = glGetError(); 

MVPLocation = glGetUniformLocation(render_prog, "MVP"); 
err = glGetError();`` 

어디서 코드입니다.

사전에 도움을 주셔서 감사합니다.

+2

'RGB2'와 'RGB3'에 0.0을 곱합니다 ('bg = vec3 (0.0, 0.0, 0.0)'). 컴파일러는이를 최적화 할 수 있습니다. – Rabbid76

+2

코멘트 주셔서 고마워요. 방금 쉐이더에서 상수로 bg를 사용하고 최종 곱셈에서이 용어를 사용하므로 문제가 발견되어 최적화 된 RGB1을 유효한 값으로 남겨 둡니다. 이것은 rt1 ans와 연관되어 있으므로 활성 유니폼 만 사용됩니다. bg를 유니폼으로 전달하면 문제가 해결됩니다. 의견을 주셔서 감사합니다. –

답변

0

위치 값 -1은 오류 조건이 아니며, 주어진 균일 성이 필요하지 않음을 의미합니다. 이는 다음을 포함하여 여러 가지 이유로 발생할 수 있습니다.

  • 셰이더에 유니폼 값이 없습니다.
  • 균일 값은 선언되지만 셰이더에서는 사용되지 않습니다.
  • 균일 값은 쉐이더/프로그램에서 선언되고 사용되지만 컴파일러가 값이 필요하지 않다는 것을 증명할 수 있기 때문에 컴파일러가 최적화합니다.
1
glGetUniformLocation(fp_render_prog, "rt3")

glGetUniformLocation(fp_render_prog, "rt2") 및 복귀 -1 rt2rt3 활성화되지 않기 때문에.

참고 glGetUniformLocation의 두번째 매개 변수는 활성 일정한 변수의 이름이어야 :

vec4 RGB2 = texture2D(rt2,vec2(gl_FragCoord.xy)); 
vec4 RGB3 = texture2D(rt3,vec2(gl_FragCoord.xy)); 

RGB2RGB3은 : RGB2RGB3 설정시

rt2rt3 사용하는 0을 곱합니다.0 :

vec3 bg = vec3(0.0, 0.0, 0.0); 
vec3 tempcolor = 
    RGB1.rgb - 
    bg * RGB1.a + 
    bg * RGB3.a + 
    bg * RGB2.rgb * RGB3.a + 
    RGB3.rgb * RGB2.a * 0.0f + 
    bg; 

컴파일러는 최적화 수

vec3 tempcolor = 
    RGB1.rgb - 
    vec3(0.0) * RGB1.a + 
    vec3(0.0) * RGB3.a + 
    vec3(0.0) * RGB2.rgb * RGB3.a + 
    RGB3.rgb * RGB2.a * 0.0f + 
    vec3(0.0); 

을 것과 동일 마지막에 어느 :

vec3 tempcolor = RGB1.rgb; 

rt2rt3가 실행 가능한 코드로 사용되지 않는 원인 균일 변수 rt2rt3비활성임을.


[OpenGL ES 2 사양 - 2.10.4 셰이더 변수 - p. 35] (https://www.khronos.org/registry/OpenGL/specs/es/2.0/es_full_spec_2.0.pdf) :

실행 파일이 실행될 때 유니폼이 실제로 액세스된다는 것을 컴파일러와 링커가 결정하면 유니폼이 활성으로 간주됩니다. 컴파일러와 링커가 결정을 내릴 수없는 경우 유니폼은 활성화 된 것으로 간주됩니다.

.....

이 프로그램 객체 내에서 활성 균일 한 변수의 위치를 ​​찾으려면이 OpenGL ES 2.0 Online Manual Pages. - glGetActiveUniform 참조 명령을

int GetUniformLocation(uint program, const char *name);


를 사용

유니폼 변수 (내장 또는 사용자 정의)는 링크 실행 중에 프로그램 실행 중에 액세스 할 수 있다고 판단되면 활성화 된 것으로 간주됩니다.

관련 문제