YarUnderoaker

11-08-2010, 04:56 AM

There is my shader fragment program

#version 330 core

precision highp float;

struct frec {

vec4 WorldPosition;

vec3 LightEmissive;

vec3 LightDiffuse;

vec3 LightSpecular;

vec3 Emissive;

vec3 Diffuse;

float DiffusePower;

vec3 Specular;

float SpecularPower;

float Opacity;

float OpacityMask;

vec3 Normal;

vec3 CameraVector;

};

struct lrec {

vec4 WorldPosition;

vec3 Ambient;

vec3 Diffuse;

vec3 Specular;

vec3 SpotDirection;

float SpotCutoff;

float SpotExponent;

float ConstantAtten;

float LinearAtten;

float QuadAtten;

};

in vec4 fWorldPosition;

in vec3 fCameraVector;

out vec4 FragColor;

layout(std140) uniform LightsBlock {

uniform lrec Lights[16];

};

uniform ivec4 LightIndices[16];

uniform int LightNumber;

void GetFragment(inout frec A);

void Illuminate(inout frec A);

void PassFragmentColor(inout frec A);

void main()

{

frec Local0;

Local0.Opacity = 1.0;

GetFragment(Local0);

Illuminate(Local0);

PassFragmentColor(Local0);

}

void GetFragment(inout frec A)

{

A.WorldPosition = fWorldPosition;

A.CameraVector = fCameraVector;

}

void pointLight(inout frec A, lrec B)

{

float nDotVP; // normal . light direction

float nDotHV; // normal . light half vector

float attenuation; // computed attenuation factor

float d; // distance from surface to light source

vec3 VP; // direction from surface to light position

vec3 halfVector; // direction of maximum highlights

// Compute vector from surface to light position

VP = B.WorldPosition.xyz - A.WorldPosition.xyz;

// Compute distance between surface and light position

d = length(VP);

// Normalize the vector from surface to light position

VP = normalize(VP);

// Compute attenuation

attenuation = 1.0 / (B.ConstantAtten + B.LinearAtten * d + B.QuadAtten * d * d);

halfVector = normalize(VP + A.CameraVector);

nDotVP = pow(max(0.0, dot(A.Normal, VP)), A.DiffusePower);

nDotHV = pow(max(0.0, dot(A.Normal, halfVector)), A.SpecularPower);

A.LightEmissive += B.Ambient * attenuation;

A.LightDiffuse += B.Diffuse * nDotVP * attenuation;

A.LightSpecular += B.Specular * nDotHV * attenuation;

}

void spotLight(inout frec A, lrec B)

{

float nDotVP; // normal . light direction

float nDotHV; // normal . light half vector

float spotDot; // cosine of angle between spotlight

float spotAttenuation; // spotlight attenuation factor

float attenuation; // computed attenuation factor

float d; // distance from surface to light source

vec3 VP; // direction from surface to light position

vec3 halfVector; // direction of maximum highlights

// Compute vector from surface to light position

VP = B.WorldPosition.xyz - A.WorldPosition.xyz;

// Compute distance between surface and light position

d = length(VP);

// Normalize the vector from surface to light position

VP = normalize(VP);

// Compute attenuation

attenuation = 1.0 / (B.ConstantAtten + B.LinearAtten * d + B.QuadAtten * d * d);

// See if point on surface is inside cone of illumination

spotDot = dot(-VP, normalize(B.SpotDirection));

if (spotDot < cos(0.01745329251994*B.SpotCutoff))

{

spotAttenuation = 0.0; // light adds no contribution

}

else

{

spotAttenuation = pow(spotDot, B.SpotExponent);

}

// Combine the spotlight and distance attenuation.

attenuation *= spotAttenuation;

halfVector = normalize(VP + A.CameraVector);

nDotVP = pow(max(0.0, dot(A.Normal, VP)), A.DiffusePower);

nDotHV = pow(max(0.0, dot(A.Normal, halfVector)), A.SpecularPower);

A.LightEmissive += B.Ambient * attenuation;

A.LightDiffuse += B.Diffuse * nDotVP * attenuation;

A.LightSpecular += B.Specular * nDotHV * attenuation;

}

void directionalLight(inout frec A, lrec B)

{

float nDotVP; // normal . light direction

float nDotHV; // normal . light half vector

vec3 VP; // direction from surface to light position

vec3 halfVector; // direction of maximum highlights

// Compute vector from surface to light position

VP = normalize(B.WorldPosition.xyz - A.WorldPosition.xyz);

halfVector = normalize(B.SpotDirection + A.CameraVector);

nDotVP = pow(max(0.0, dot(A.Normal, VP)), A.DiffusePower);

nDotHV = pow(max(0.0, dot(A.Normal, halfVector)), A.SpecularPower);

A.LightEmissive += B.Ambient;

A.LightDiffuse += B.Diffuse * nDotVP;

A.LightSpecular += B.Specular * nDotHV;

}

void infiniteSpotLight(inout frec A, lrec B)

{

float nDotVP; // normal . light direction

float nDotHV; // normal . light half vector

vec3 VP; // direction from surface to light position

vec3 halfVector; // direction of maximum highlights

float spotAttenuation;

vec3 Ppli;

vec3 Sdli;

// Compute vector from surface to light position

VP = normalize(B.WorldPosition.xyz - A.WorldPosition.xyz);

halfVector = normalize(B.SpotDirection + A.CameraVector);

nDotVP = pow(max(0.0, dot(A.Normal, VP)), A.DiffusePower);

nDotHV = pow(max(0.0, dot(A.Normal, halfVector)), A.SpecularPower);

Ppli = -VP;

Sdli = B.SpotDirection;

spotAttenuation = pow(dot(Ppli, Sdli), B.SpotExponent);

A.LightEmissive += B.Ambient * spotAttenuation;

A.LightDiffuse += B.Diffuse * nDotVP * spotAttenuation;

A.LightSpecular += B.Specular * nDotHV * spotAttenuation;

}

void Illuminate(inout frec A)

{

A.LightEmissive = vec3(0.0,0.0,0.0);

A.LightDiffuse = vec3(0.0,0.0,0.0);

A.LightSpecular = vec3(0.0,0.0,0.0);

for (int I = 0; I<LightNumber && I<16; I++)

{

int J = LightIndices[I].x;

lrec LightSource = Lights[J];

if (LightSource.WorldPosition.w == 1.0)

{

if (LightSource.SpotCutoff == 180.0)

{

pointLight(A,LightSource);

}

else

{

spotLight(A,LightSource);

}

}

else

{

if (LightSource.SpotCutoff == 180.0)

{

directionalLight(A,LightSource);

}

else

{

infiniteSpotLight(A,LightSource);

}

}

}

vec3 finalColor;

finalColor = A.Emissive*clamp(A.LightEmissive,vec3(0.0),vec3(1. 0));

finalColor += A.Diffuse*clamp(A.LightDiffuse,vec3(0.0),vec3(1.0) );

finalColor += A.Specular*clamp(A.LightSpecular,vec3(0.0),vec3(1. 0));

A.Emissive = finalColor;

}

void PassFragmentColor(inout frec A)

{

FragColor = vec4(A.Emissive, A.Opacity);

}

The fragment object compile successfully, but program linking fail with error

Fragment shader(s) failed to link, vertex shader(s) failed to link.

unexpected error.

unexpected error.

I trying to test it by GPU Shader Analyze

in version 1.53 all fine,

but in version 1.55 fail with error

Internal compilation failure. Possibly caused by GSA not supporting a GLSL feature used in shader.

ERROR: 0:7: error(#132) Syntax error: ';' parse error

ERROR: error(#273) 1 compilation errors. No code generated

Also I trying to simplify the shader, to leave only a one pointLight for first light source, to replace the uniform block to one structured uniform - does not help.

My system

Catalist 10.10 or 10.9

Radeon HD5450

WinXP SP2

#version 330 core

precision highp float;

struct frec {

vec4 WorldPosition;

vec3 LightEmissive;

vec3 LightDiffuse;

vec3 LightSpecular;

vec3 Emissive;

vec3 Diffuse;

float DiffusePower;

vec3 Specular;

float SpecularPower;

float Opacity;

float OpacityMask;

vec3 Normal;

vec3 CameraVector;

};

struct lrec {

vec4 WorldPosition;

vec3 Ambient;

vec3 Diffuse;

vec3 Specular;

vec3 SpotDirection;

float SpotCutoff;

float SpotExponent;

float ConstantAtten;

float LinearAtten;

float QuadAtten;

};

in vec4 fWorldPosition;

in vec3 fCameraVector;

out vec4 FragColor;

layout(std140) uniform LightsBlock {

uniform lrec Lights[16];

};

uniform ivec4 LightIndices[16];

uniform int LightNumber;

void GetFragment(inout frec A);

void Illuminate(inout frec A);

void PassFragmentColor(inout frec A);

void main()

{

frec Local0;

Local0.Opacity = 1.0;

GetFragment(Local0);

Illuminate(Local0);

PassFragmentColor(Local0);

}

void GetFragment(inout frec A)

{

A.WorldPosition = fWorldPosition;

A.CameraVector = fCameraVector;

}

void pointLight(inout frec A, lrec B)

{

float nDotVP; // normal . light direction

float nDotHV; // normal . light half vector

float attenuation; // computed attenuation factor

float d; // distance from surface to light source

vec3 VP; // direction from surface to light position

vec3 halfVector; // direction of maximum highlights

// Compute vector from surface to light position

VP = B.WorldPosition.xyz - A.WorldPosition.xyz;

// Compute distance between surface and light position

d = length(VP);

// Normalize the vector from surface to light position

VP = normalize(VP);

// Compute attenuation

attenuation = 1.0 / (B.ConstantAtten + B.LinearAtten * d + B.QuadAtten * d * d);

halfVector = normalize(VP + A.CameraVector);

nDotVP = pow(max(0.0, dot(A.Normal, VP)), A.DiffusePower);

nDotHV = pow(max(0.0, dot(A.Normal, halfVector)), A.SpecularPower);

A.LightEmissive += B.Ambient * attenuation;

A.LightDiffuse += B.Diffuse * nDotVP * attenuation;

A.LightSpecular += B.Specular * nDotHV * attenuation;

}

void spotLight(inout frec A, lrec B)

{

float nDotVP; // normal . light direction

float nDotHV; // normal . light half vector

float spotDot; // cosine of angle between spotlight

float spotAttenuation; // spotlight attenuation factor

float attenuation; // computed attenuation factor

float d; // distance from surface to light source

vec3 VP; // direction from surface to light position

vec3 halfVector; // direction of maximum highlights

// Compute vector from surface to light position

VP = B.WorldPosition.xyz - A.WorldPosition.xyz;

// Compute distance between surface and light position

d = length(VP);

// Normalize the vector from surface to light position

VP = normalize(VP);

// Compute attenuation

attenuation = 1.0 / (B.ConstantAtten + B.LinearAtten * d + B.QuadAtten * d * d);

// See if point on surface is inside cone of illumination

spotDot = dot(-VP, normalize(B.SpotDirection));

if (spotDot < cos(0.01745329251994*B.SpotCutoff))

{

spotAttenuation = 0.0; // light adds no contribution

}

else

{

spotAttenuation = pow(spotDot, B.SpotExponent);

}

// Combine the spotlight and distance attenuation.

attenuation *= spotAttenuation;

halfVector = normalize(VP + A.CameraVector);

nDotVP = pow(max(0.0, dot(A.Normal, VP)), A.DiffusePower);

nDotHV = pow(max(0.0, dot(A.Normal, halfVector)), A.SpecularPower);

A.LightEmissive += B.Ambient * attenuation;

A.LightDiffuse += B.Diffuse * nDotVP * attenuation;

A.LightSpecular += B.Specular * nDotHV * attenuation;

}

void directionalLight(inout frec A, lrec B)

{

float nDotVP; // normal . light direction

float nDotHV; // normal . light half vector

vec3 VP; // direction from surface to light position

vec3 halfVector; // direction of maximum highlights

// Compute vector from surface to light position

VP = normalize(B.WorldPosition.xyz - A.WorldPosition.xyz);

halfVector = normalize(B.SpotDirection + A.CameraVector);

nDotVP = pow(max(0.0, dot(A.Normal, VP)), A.DiffusePower);

nDotHV = pow(max(0.0, dot(A.Normal, halfVector)), A.SpecularPower);

A.LightEmissive += B.Ambient;

A.LightDiffuse += B.Diffuse * nDotVP;

A.LightSpecular += B.Specular * nDotHV;

}

void infiniteSpotLight(inout frec A, lrec B)

{

float nDotVP; // normal . light direction

float nDotHV; // normal . light half vector

vec3 VP; // direction from surface to light position

vec3 halfVector; // direction of maximum highlights

float spotAttenuation;

vec3 Ppli;

vec3 Sdli;

// Compute vector from surface to light position

VP = normalize(B.WorldPosition.xyz - A.WorldPosition.xyz);

halfVector = normalize(B.SpotDirection + A.CameraVector);

nDotVP = pow(max(0.0, dot(A.Normal, VP)), A.DiffusePower);

nDotHV = pow(max(0.0, dot(A.Normal, halfVector)), A.SpecularPower);

Ppli = -VP;

Sdli = B.SpotDirection;

spotAttenuation = pow(dot(Ppli, Sdli), B.SpotExponent);

A.LightEmissive += B.Ambient * spotAttenuation;

A.LightDiffuse += B.Diffuse * nDotVP * spotAttenuation;

A.LightSpecular += B.Specular * nDotHV * spotAttenuation;

}

void Illuminate(inout frec A)

{

A.LightEmissive = vec3(0.0,0.0,0.0);

A.LightDiffuse = vec3(0.0,0.0,0.0);

A.LightSpecular = vec3(0.0,0.0,0.0);

for (int I = 0; I<LightNumber && I<16; I++)

{

int J = LightIndices[I].x;

lrec LightSource = Lights[J];

if (LightSource.WorldPosition.w == 1.0)

{

if (LightSource.SpotCutoff == 180.0)

{

pointLight(A,LightSource);

}

else

{

spotLight(A,LightSource);

}

}

else

{

if (LightSource.SpotCutoff == 180.0)

{

directionalLight(A,LightSource);

}

else

{

infiniteSpotLight(A,LightSource);

}

}

}

vec3 finalColor;

finalColor = A.Emissive*clamp(A.LightEmissive,vec3(0.0),vec3(1. 0));

finalColor += A.Diffuse*clamp(A.LightDiffuse,vec3(0.0),vec3(1.0) );

finalColor += A.Specular*clamp(A.LightSpecular,vec3(0.0),vec3(1. 0));

A.Emissive = finalColor;

}

void PassFragmentColor(inout frec A)

{

FragColor = vec4(A.Emissive, A.Opacity);

}

The fragment object compile successfully, but program linking fail with error

Fragment shader(s) failed to link, vertex shader(s) failed to link.

unexpected error.

unexpected error.

I trying to test it by GPU Shader Analyze

in version 1.53 all fine,

but in version 1.55 fail with error

Internal compilation failure. Possibly caused by GSA not supporting a GLSL feature used in shader.

ERROR: 0:7: error(#132) Syntax error: ';' parse error

ERROR: error(#273) 1 compilation errors. No code generated

Also I trying to simplify the shader, to leave only a one pointLight for first light source, to replace the uniform block to one structured uniform - does not help.

My system

Catalist 10.10 or 10.9

Radeon HD5450

WinXP SP2