2010-04-13 3 views
5

은 내가 GLSL 버전 인 경우 내 GLSL 쉐이더가 컴파일 가능한하지 않은 것으로 나타났습니다보다 낮은 130는 OpenGL 쉐이딩 언어의 하위 호환성

이전 버전과 호환 쉐이더 소스를 가지고위한 가장 중요한 요소는 무엇인가? 완전 역 호환을 원하지 않지만, GLSL이 130보다 낮은 GPU에서 단순 (포워드 호환) 쉐이더를 실행하는 주요 가이드 라인을 이해하고 싶습니다.

물론 문제가 해결 될 수 있습니다. 프리 프로세서와 함께

하지만 무시할만한 문제가 많이 있습니다.

답변

2

최근 활동으로 인해이 오래된 질문이 떠올랐다. 문제가 해결되었음을 알게되었습니다. 쉽지는 않지만 성공적인 솔루션입니다.이 솔루션은 쉐이더 소스를 컴파일하는 드라이버의 수와 그에 기반한 많은 쉐이더에 의해 입증되었습니다.

기본적으로, 나는 GL_ARB_shading_language_include 확장자를 사용하는 (그리고 나는 또한 그것을 구현하지 않습니다 그 시스템의 소스 처리기를 구현 한), 나는 소스에는 다음이 포함 쉐이더를 정의하는 데 결국 :

// Copyright (C) 2011-2013 Luca Piccioni 
// 
// This program is free software: you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published by 
// the Free Software Foundation, either version 3 of the License, or 
// (at your option) any later version. 
// 
// This program is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
// GNU General Public License for more details. 
// 
// You should have received a copy of the GNU General Public License 
// along with this program. If not, see <http://www.gnu.org/licenses/>. 

// @BeginInterface 

// Shader renderer 

// Symbol defined if running on NVIDIA renderer. 
#define DS_VENDOR_NVIDIA   1 
// Symbol defined if running on ATI/AMD renderer. 
#define DS_VENDOR_AMD    2 
// Symbol defined if running on INTEL renderer 
#define DS_VENDOR_INTEL    3 

// Shader inputs and outputs keywords 
// 
// - ATTRIBUTE: used to mark a vertex shader inputs 
// - SHADER_IN: used to mark a non-vertex shader inputs 
// - SHADER_OUT: used to mark a non-fragment shader output 
// - OUT: used to mark a fragment shader output 
#if __VERSION__ >= 130 

#define ATTRIBUTE in 
#define SHADER_IN in 
#define SHADER_OUT out 
#define OUT out 

#else 

#define ATTRIBUTE attribute 
#define SHADER_IN varying 
#define SHADER_OUT varying 
#define OUT 

#endif 

// Support array attributes 
#if __VERSION__ >= 130 

#define ARRAY_ATTRIBUTE(name, size) name[size] 

#else 

#define ARRAY_ATTRIBUTE(name, size) name[size] 

#endif 

// Uniform blocks 
#if __VERSION__ >= 130 

#define BEGIN_UNIFORM_BLOCK(name) uniform name { 

#define END_UNIFORM_BLOCK() }; 

#else 

#define BEGIN_UNIFORM_BLOCK(name) 

#define END_UNIFORM_BLOCK() 

#endif 

// Input and output blocks 
#if __VERSION__ >= 150 

#define BEGIN_INPUT_BLOCK(name) in name { 
#define END_INPUT_BLOCK() }; 

#define BEGIN_OUTPUT_BLOCK(name) out name { 
#define END_OUTPUT_BLOCK() }; 

#else 

#define BEGIN_INPUT_BLOCK(name) 
#define END_INPUT_BLOCK() 

#define BEGIN_OUTPUT_BLOCK(name) 
#define END_OUTPUT_BLOCK() 

#endif 

// Texturing functions 
#if __VERSION__ >= 130 

#define TEXTURE_2D texture 
#define TEXTURE_3D texture 
#define TEXTURE_RECT texture 
#define TEXTURE_CUBE texture 

#if __VERSION__ >= 150 
#define TEXTURE_SIZE(sampler) textureSize(sampler) 
#else 
#define TEXTURE_SIZE(sampler) sampler ## _Size 
#endif 

#else 

#define TEXTURE_2D texture2D 
#define TEXTURE_3D texture3D 
#define TEXTURE_RECT texture2DRect 
#define TEXTURE_CUBE textureCube 

#endif 

// Invariance 
#if __VERSION__ >= 120 
#define INVARIANT invariant 
#else 
#define INVARIANT 
#endif 

// Attribute location 
#if defined(GL_ARB_explicit_attrib_location) 
#define LOCATION(loc)  layout(location = loc) 
#else 
#define LOCATION(loc) 
#endif 

// Geometry shader layout 
#if __VERSION__ >= 150 
#define GEOMETRY_LAYOUT_IN(from) layout (from) in 
#define GEOMETRY_LAYOUT(to, max) layout (to, max_vertices = max) out 
#else 
#define GEOMETRY_LAYOUT_IN(from) 
#define GEOMETRY_LAYOUT(to, max) 
#endif 

// @EndInterface 

사실 셰이더 소스를 포함하기 전에 셰이더를 포함하면 다양한 컴파일러에서 프레임 워크를 컴파일 할 수 있습니다. 물론 프레임 워크는 실제 시스템 기능을 감지하고 컴파일러 매개 변수를 정의하여 작업을 올바르게 수행해야합니다 (선 두께가 1.0보다 작아서 선 쉐이더를 생각해보십시오).

물론 셰이더 인프라에서 최소 요구 사항을 정의 할 수 있습니다. 셰이더가 GLSL 1.50 또는 그 이후의 코어 프로파일을 필요로하면 더 이상 셰이더를 포함 할 필요가 없습니다.

1
  • 풋 #Version을 110 쉐이더 ATI
  • 에서 ShaderAnalyst
  • 테스트 다른 공급 업체의 실제 그래픽 카드의 LOT에 코드에
  • 시험을의 첫 번째 줄과 같은 #Version을 120
0

"OpenGL Shading Language, Bill Licea-Kane, AMD, SIGGRAPH 2009"을 읽으십시오. 당신은 아마 GLSL-140, 130, 120 버전을 지원하기 위해 응용 프로그램에 다음 코드를 추가 할 필요가 있습니다 :

#version 150 compatibility 
+0

고맙지 만, 전처리기만 사용하여 다른 버전의 셰이더 소스 코드를 컴파일 할 수있게함으로써 호환성 플래그를 피하려고합니다. – Luca

0

쉐이더에서 #Version을 줄을 타고에 코드를 테스트 다양한 GPU 기능을 갖춘 여러 컴퓨터. 셰이더 호환성이 향상 될 것입니다. #version 지시문은 버전 번호가 지정되지 않은 경우 해당 컴퓨터의 GPU가 모든 쉐이더 코드를 실행할 수있는 경우에도 쉐이더가 실패하는 경우가 있습니다.

+0

그래, 처음부터 시스템 기능에 따라 #version 지시어가 런타임에 삽입됩니다. 확장 가능한 엔진을 갖는 것이 필수적입니다. 그러나 대부분의 시스템은 고급 GLSL 기능을 지원합니다. – Luca

+0

#version을 생략하면 GLSL 1.1이 기본값으로 설정됩니다. – Luca