我正在尝试使https://software.intel.com/sites/default/files/managed/79/e5/OpenGL%20ES%20Tessellation.zip的本机代码在我的Samsung Galaxy S5上运行。我在代码中禁用了Tessellation。
我还更改了代码以使用OpenGLS ES 3.0。
程序运行并成功编译附加的着色器,但是当程序使用编译的着色器调用glLinkProgram时,glLinkProgram崩溃。编译着色器时程序调用glError,此时没有错误。
有人可以帮我解决这个问题吗?
//--------------------------------------------------------------------------------------
// Copyright 2014 Intel Corporation
// All Rights Reserved
//
// Permission is granted to use, copy, distribute and prepare derivative works of this
// software for any purpose and without fee, provided, that the above copyright notice
// and this statement appear in all copies. Intel makes no representations about the
// suitability of this software for any purpose. THIS SOFTWARE IS PROVIDED "AS IS."
// INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, AND ALL LIABILITY,
// INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, FOR THE USE OF THIS SOFTWARE,
// INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY RIGHTS, AND INCLUDING THE
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Intel does not
// assume any responsibility for any errors which may appear in this software nor any
// responsibility to update it.
//--------------------------------------------------------------------------------------
// Generated by ShaderGenerator.exe version 0.13
//--------------------------------------------------------------------------------------
// Fog color in both shaders
// Skybox
const float TessellationHeight = 5500.0; // Height of a 1.0 in the height map (height map * TessellationHeight)
const int NumLights = 2;
const vec3 LightDirections[NumLights] = vec3[]( vec3(-1.0, -1.0, -1.0),
vec3(0.5, -1.0, 1.0) );
const vec3 LightColors[NumLights] = vec3[]( vec3(0.362, 0.526, 0.575),
vec3(0.630, 0.914, 1.0));
// -------------------------------------
layout (std140, row_major) uniform cbPerModelValues
{
mat4 World;
mat4 NormalMatrix;
mat4 WorldViewProjection;
mat4 InverseWorld;
mat4 LightWorldViewProjection;
vec4 BoundingBoxCenterWorldSpace;
vec4 BoundingBoxHalfWorldSpace;
vec4 BoundingBoxCenterObjectSpace;
vec4 BoundingBoxHalfObjectSpace;
};
// -------------------------------------
layout (std140, row_major) uniform cbPerFrameValues
{
mat4 View;
mat4 InverseView;
mat4 Projection;
mat4 ViewProjection;
vec4 AmbientColor;
vec4 LightColor;
vec4 LightDirection;
vec4 EyePosition;
vec4 MaxTessellation;
};
// -------------------------------------
uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform sampler2D Texture2;
// -------------------------------------
#ifdef GLSL_VERTEX_SHADER
precision highp float;
#define POSITION 0
#define NORMAL 1
#define BINORMAL 2
#define TANGENT 3
#define COLOR 4
#define TEXCOORD0 5
// -------------------------------------
layout (location = POSITION) in vec3 Position; // Projected position
layout (location = NORMAL) in vec3 Normal;
layout (location = TANGENT) in vec3 Tangent;
layout (location = BINORMAL) in vec3 Binormal;
layout (location = TEXCOORD0) in vec2 UV0;
// -------------------------------------
out vec4 outPosition;
out vec3 outNormal;
out vec3 outTangent;
out vec3 outBinormal;
out vec2 outUV0;
out vec3 outWorldPosition; // Object space position
#endif //GLSL_VERTEX_SHADER
#ifdef GLSL_FRAGMENT_SHADER
precision highp float;
// -------------------------------------
in vec4 outPosition;
in vec3 outNormal;
in vec3 outTangent;
in vec3 outBinormal;
in vec2 outUV0;
in vec3 outWorldPosition; // Object space position
in vec3 outTriDistance;
// -------------------------------------
vec4 DIFFUSETMP( )
{
return texture(Texture0,(((outUV0)) *(20.0)) );
}
// -------------------------------------
vec4 NORMAL( )
{
return texture(Texture1,(((outUV0)) *(1.0)) ) * 2.0 - 1.0;
}
// -------------------------------------
vec4 AOMAP( )
{
return texture(Texture2,(((outUV0)) *(1.0)) );
}
// -------------------------------------
vec4 DIFFUSE( )
{
vec4 diffuse = DIFFUSETMP() * AOMAP();
#ifdef OPENGL_ES
diffuse.rgb = pow(diffuse.rgb, vec3(2.2));
#endif
return diffuse*vec4(2.0);
}
// -------------------------------------
vec4 AMBIENT( )
{
return DIFFUSE();
}
// -------------------------------------
#endif //GLSL_FRAGMENT_SHADER
#ifdef GLSL_VERTEX_SHADER
// -------------------------------------
void main( )
{
outPosition = vec4( Position, 1.0);
outWorldPosition = (outPosition * World).xyz;
outNormal = Normal * mat3(World);
outTangent = Tangent * mat3(World);
outBinormal = Binormal * mat3(World);
outUV0 = UV0;
}
#endif //GLSL_VERTEX_SHADER
#ifdef GLSL_TESS_CONTROL_SHADER
precision highp float;
#ifdef OPENGL_ES
#extension GL_INTEL_tessellation:require
#endif
layout(vertices = 3) out;
in vec4 outPosition[];
in vec3 outNormal[];
in vec3 outTangent[];
in vec3 outBinormal[];
in vec2 outUV0[];
in vec3 outWorldPosition[];
out vec4 tcPosition[3];
out vec3 tcNormal[3];
out vec3 tcTangent[3];
out vec3 tcBinormal[3];
out vec2 tcUV0[3];
out vec3 tcWorldPosition[3];
float level(float d)
{
d = d/55000.0; // d = [0..1]
float s = clamp(1.0*(d), 0.0, 1.0);
return mix(MaxTessellation.x,1.0, s);
}
void main()
{
tcPosition[gl_InvocationID] = outPosition[gl_InvocationID];
tcWorldPosition[gl_InvocationID] = outWorldPosition[gl_InvocationID];
tcNormal[gl_InvocationID] = outNormal[gl_InvocationID];
tcBinormal[gl_InvocationID] = outBinormal[gl_InvocationID];
tcTangent[gl_InvocationID] = outTangent[gl_InvocationID];
tcUV0[gl_InvocationID] = outUV0[gl_InvocationID];
if(gl_InvocationID == 0) {
vec3 CamPos = EyePosition.xyz;
float d0 = distance(CamPos, outWorldPosition[0]);
float d1 = distance(CamPos, outWorldPosition[1]);
float d2 = distance(CamPos, outWorldPosition[2]);
gl_TessLevelOuter[2] = level(mix(d0,d1,0.5));
gl_TessLevelOuter[0] = level(mix(d1,d2,0.5));
gl_TessLevelOuter[1] = level(mix(d2,d0,0.5));
float inner = max(max(gl_TessLevelOuter[0], gl_TessLevelOuter[1]),gl_TessLevelOuter[2]);
gl_TessLevelInner[0] = inner;
}
}
#endif //GLSL_TESS_CONTROL_SHADER
#ifdef GLSL_TESS_EVALUATION_SHADER
precision highp float;
#ifdef OPENGL_ES
#extension GL_INTEL_tessellation:require
#endif // OPENGL_ES
layout(triangles,fractional_odd_spacing,ccw) in;
in vec4 tcPosition[];
in vec3 tcNormal[];
in vec3 tcTangent[];
in vec3 tcBinormal[];
in vec2 tcUV0[];
in vec3 tcWorldPosition[];
out vec4 outPosition;
out vec3 outNormal;
out vec3 outTangent;
out vec3 outBinormal;
out vec2 outUV0;
out vec3 outWorldPosition;
vec2 interpolate(vec2 a, vec2 b, vec2 c)
{
vec2 p0 = vec2(gl_TessCoord.x) * a;
vec2 p1 = vec2(gl_TessCoord.y) * b;
vec2 p2 = vec2(gl_TessCoord.z) * c;
return p0+p1+p2;
}
vec3 interpolate(vec3 a, vec3 b, vec3 c)
{
vec3 p0 = vec3(gl_TessCoord.x) * a;
vec3 p1 = vec3(gl_TessCoord.y) * b;
vec3 p2 = vec3(gl_TessCoord.z) * c;
return p0+p1+p2;
}
vec4 interpolate(vec4 a, vec4 b, vec4 c)
{
vec4 p0 = vec4(gl_TessCoord.x) * a;
vec4 p1 = vec4(gl_TessCoord.y) * b;
vec4 p2 = vec4(gl_TessCoord.z) * c;
return p0+p1+p2;
}
void main()
{
outPosition = interpolate(tcPosition[0],tcPosition[1],tcPosition[2]);
outUV0 = interpolate(tcUV0[0],tcUV0[1],tcUV0[2]);
outWorldPosition = interpolate(tcWorldPosition[0],tcWorldPosition[1],tcWorldPosition[2]);
outNormal = interpolate(tcNormal[0],tcNormal[1],tcNormal[2]);
outTangent = interpolate(tcTangent[0],tcTangent[1],tcTangent[2]);
outBinormal = interpolate(tcBinormal[0],tcBinormal[1],tcBinormal[2]);
float y = texture(Texture1,(outUV0)).a * TessellationHeight;
outPosition.y = y;
outPosition = outPosition * WorldViewProjection;
gl_Position = outPosition;
}
#endif //GLSL_TESS_EVALUATION_SHADER
#ifdef GLSL_FRAGMENT_SHADER
out vec4 fragColor;// -------------------------------------
void main( )
{
vec4 result = vec4(0.0,0.0,0.0,1.0);
vec3 normal = outNormal;
vec3 tangent = outTangent;
vec3 binormal = outBinormal;
mat3 tangentToWorld = mat3(tangent, binormal, normal);
normal = normalize( tangentToWorld * NORMAL().bgr );
float shadowAmount = 1.0;
// Ambient-related computation
vec3 ambient = AmbientColor.rgb * AMBIENT().rgb;
result.xyz += ambient;
vec3 lightDirection = -LightDirection.xyz;
// Diffuse-related computation
vec3 albedo = DIFFUSE().rgb;
for(int ii=0; ii<NumLights; ++ii) {
lightDirection = -LightDirections[ii];
float nDotL = max( 0.0,dot( normal, lightDirection ) );
vec3 diffuse = LightColors[ii] * nDotL * shadowAmount * albedo;
result.xyz += diffuse * (1.0/float(NumLights));
}
fragColor = result;
const vec4 FogColor = vec4(0.211,0.223,0.226,1.0);
const float MinFogDistance = 5000.0;
const float MaxFogDistance = 75000.0;
float dist = distance(outWorldPosition, EyePosition.xyz);
float fog_factor = clamp((MaxFogDistance - dist)/(MaxFogDistance - MinFogDistance),0.0,1.0);
fragColor = mix(fragColor,FogColor,1.0-fog_factor);
#ifdef OPENGL_ES
fragColor.rgb = pow(fragColor.rgb, vec3(0.454545454545));
#endif
}
#endif //GLSL_FRAGMENT_SHADER
答案 0 :(得分:0)
问题可能来自片段Shader中的数组的动态索引,而不是所有实现都支持。 (参见https://www.khronos.org/files/opengles_shading_language.pdf p103。注意顶点着色器没问题......)
在您的代码中:
for(int ii=0; ii<NumLights; ++ii) {
lightDirection = -LightDirections[ii];
float nDotL = max( 0.0,dot( normal, lightDirection ) );
vec3 diffuse = LightColors[ii] * nDotL * shadowAmount * albedo;
result.xyz += diffuse * (1.0/float(NumLights));
}
尝试使用常量索引进行调试。用xxx [0]替换所有xxx [ii]。如果它以这种方式工作,那么您可能面临这种动态索引限制。
绕过这个问题的一种hackish方法:使用float for循环并在循环体中创建一个int var:
float NumLights_f = float(NumLights);
for(float ii_f=0.; ii_f<NumLights_f; ++ii_f) {
int ii = int(ii_f);
lightDirection = -LightDirections[ii];
float nDotL = max( 0.0,dot( normal, lightDirection ) );
vec3 diffuse = LightColors[ii] * nDotL * shadowAmount * albedo;
result.xyz += diffuse * (1.0/float(NumLights));
}
出于某种原因,它解决了我的类似错误。我不是glsl-es guru,我很好奇为什么这个工作。它可能会以性能损失为代价......是因为循环展开吗? int(ii_f)在展开后就像一个常数?