Jump to content
  • Advertisement
Sign in to follow this  
Vincent_M

Counting "varying" Constraints [GLSL]

This topic is 2589 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I keep getting this error, but I'm not sure this is correct:

[font=Menlo][size=2]ERROR: Implementation limit of 32 varying components exceeded. Unable to allocate 'v_pointLightVector'.[/font]


When the compiler says "component", is it counting each component per vector? Here's the varying code I have so far:

const int MAX_POINTLIGHTS = 4;
const int MAX_SPOTLIGHTS = 4;

varying vec2 v_texCoord;

varying vec3 v_globalLightDirection;

varying vec4 v_pointLightVector[MAX_POINTLIGHTS];

varying vec3 v_spotLightVector[MAX_SPOTLIGHTS];







#ifdef SPECULAR_LIGHTING

varying vec3 v_globalLightHalfVector;

varying vec3 v_pointLightHalfVector[MAX_POINTLIGHTS];

varying vec3 v_spotLightHalfVector[MAX_SPOTLIGHTS];

#endif







#ifndef NORMAL_MAPPING

varying vec3 v_normal;

#endif




As you can see, I support a max of 4 point lights, and 4 spot lights which I'd like to send over to the fragment shader. I will usually send much less than that, and I keep track of the number I send to the shader with a uniform, so I can cull any unnecessary calculations. Also, I can move lots of my calculations from my vertex shader over to my fragment shader. This is aimed for an iPad 2, however, so I'm wondering if it's faster to just transfer varying data between shaders than manually doing calculations in the fragment shader. Right now, I calculate each lights' direction between the light and vertex in the vertex shader, and interpolate them by varying them.

Share this post


Link to post
Share on other sites
Advertisement
A component is a single x,y,z or w value. That is, a vec4 has 4 components , a vec3 has three... float is one etc.
That's the reason that you often calculate lighting in camera space and you can already pre-calculate the light direction/position in camera space and transfer them as uniforms. This will save lot of varying variables.

Share this post


Link to post
Share on other sites
[font="Arial"]So, you're saying calculate them on the CPU, then send them into the shader? The camera and light positions are in local space when sent over. My normal mapping code has to convert everything to tangent space.[/font]

[font="Arial"]Here's what I do in my OpenGL ES 2.0 vertex shader:[/font]

precision mediump float;
precision lowp int;




uniform mat4 u_pvmMat;

const int MAX_POINTLIGHTS = 2;
const int MAX_SPOTLIGHTS = 2;
uniform int u_numPointLights;
uniform int u_numSpotLights;
uniform vec3 u_cameraPosition;
uniform vec3 u_globalLightDirection;
uniform vec3 u_pointLightPosition[MAX_POINTLIGHTS];
uniform vec3 u_spotLightPosition[MAX_SPOTLIGHTS];


attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec3 a_normal;
attribute vec3 a_tangent


varying vec2 v_texCoord;
varying vec3 v_normal;
varying vec3 v_globalLightDirection;
varying vec4 v_pointLightVector[MAX_POINTLIGHTS];
varying vec3 v_spotLightVector[MAX_SPOTLIGHTS];



void main()
{
// find basic output
v_texCoord = a_texCoord;
gl_Position = u_pvmMat * a_position;

int i = 0;
vec3 tempVector;
vec3 a_binormal = cross(a_normal, a_tangent);

// find the global light's vector
v_globalLightDirection.x = dot(u_globalLightDirection, a_tangent);
v_globalLightDirection.y = dot(u_globalLightDirection, a_binormal);
v_globalLightDirection.z = dot(u_globalLightDirection, a_normal);
v_globalLightDirection = normalize(v_globalLightDirection);

// process the point lights
for(i=0;i<u_numPointLights;i++)
{
// find the light's vector
tempVector = u_pointLightPosition - a_position.xyz;
v_pointLightVector.x = dot(tempVector, a_tangent);
v_pointLightVector.y = dot(tempVector, a_binormal);
v_pointLightVector.z = dot(tempVector, a_normal);
v_pointLightVector.w = length(v_pointLightVector.xyz);
v_pointLightVector.xyz = normalize(v_pointLightVector.xyz);
}

// process the spot lights
for(i=0;i<u_numSpotLights;i++)
{
// find the light's vector
tempVector = u_spotLightPosition - a_position.xyz;
v_spotLightVector.x = dot(tempVector, a_tangent);
v_spotLightVector.y = dot(tempVector, a_binormal);
v_spotLightVector.z = dot(tempVector, a_normal);
v_spotLightVector = normalize(v_spotLightVector);
}
}


From the shaders I've seen, it looks like I'd have to send the light positions over on a per-vertex basis when they're translated into tangent space. The results are amazing, but are there any better ways this can be done? Right now, I can only support a max of 2 of each light. My goal was to support 4 each, but no luck there! These are only the maxes too. I'm not sending that many in most cases.

Share this post


Link to post
Share on other sites

From the shaders I've seen, it looks like I'd have to send the light positions over on a per-vertex basis when they're translated into tangent space. The results are amazing, but are there any better ways this can be done? Right now, I can only support a max of 2 of each light. My goal was to support 4 each, but no luck there! These are only the maxes too. I'm not sending that many in most cases.

You should target one space, often camera space is best suited for many light in a single shader pass. Instead of transfering everything in tangent space, transfer the normal from tangent into camera space. In this case you only need one transformation matrix (3x3, you don't need a position, normals need only to be rotated ) , which is 9 components. Every lightvector/position should be precalculated on the CPU (=>camera space) and be send to the fragment shader via uniforms.
In this case you need the inverted tangent space matrix, which is the transposed tangent matrix.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!