Jump to content
  • Advertisement
Sign in to follow this  
golgoth

GLSL Advanced Lighting!

This topic is 4652 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

Hi all! Everything im trying so far with glsl is going to a dead end... im wondering if anyone has done ligthing in a pipepline that can run 1 to 100 per pixel lights... Abstract; 1 - calculate all lights in one shader then render it! (1 pass)... GLSL loops and arrays has to be statics... wich means, the shader needs to know the light count u ll process to compile... and that is the plan... all lights in one pass sounds good to me! so, harcoding the light count in the shader is not an option! but theres no way to do this so far... looks like a simple problem??? introducing texture state will be even more fun! result = GLSL failed- 2 - One shader Object per light, one frag and one vertex program per light! Need to calculate each light and store attributes in some buffer -- then process vertex/frag result when all lights as been calculated! can this be done? 3 - One Shader Object for all Lights including, one frag and one vertex program per light! this way we could share variables (i hope So) and process all lights in one pass... can this be done? THX

Share this post


Link to post
Share on other sites
Advertisement
Firstly, you are aware that with a fix precision frame buffer at more than 3 lights per object you are going to saturate the frame buffer anyway. Also, 100 lights? Are you insane? seriously, 8 lights per surface per pixel is pushing it still if you want to have any kind of frame rate.

As for your 'questions';

1- GLSL can do it. Loops dont have to be static, however current hardware enforces this, future hardware and compilers might well allow fully dynamic looping in fragment programs.

2- This is more or less defered shading, where you render to texture the scene for each light and then combine them in another pass.

3- I'm not even sure what you are aiming for.

Now, the way I'd do it, would be to produce shader objects for each number of lights from 1 up and then combine them into various shader programs to get a set of shaders which can handle X number of lights.

No, this doesnt mean you have to write all these shaders by hand, just come up with a template and write/use a preprocessor to adapt this template for each number of lights (and even types of lights).

Share this post


Link to post
Share on other sites
Thx Phantom!

I should have said x num light instead of 100!

Now, the way I'd do it, would be to produce shader objects for each number of lights from 1 up and then combine them into various shader programs to get a set of shaders which can handle X number of lights.

great idea!!!


still 2 problem remaining!

first one is regarding Matrix transformation:

when the lights move and the primitives are statics it works well!
but, when primitives moves... lights are moving with them! wich is no good!

[vertex shader] (based on ultimate programming code):


varying vec3 texCoord0;
varying vec3 normal;
varying vec4 pos;
uniform mat4 transform;

void main()
{
// Tranform to clip space.
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

// Set tex coord.
texCoord0 = gl_MultiTexCoord0.xyz;

// Send vertex pos and normal to the pixel shader.
normal = gl_Normal;
pos = gl_Vertex;
}


[Fragment shader]:


struct Light
{
vec4 color;
vec4 position;
float constant;
float linear;
float quadratic;
};


struct Material
{
vec4 matAmbient;
vec4 matDiffuse;
vec4 matSpecular;
vec4 matEmissive;
float matShininess;
};

varying vec3 texCoord0;
varying vec3 normal;
varying vec4 pos;

uniform sampler2D decal;

uniform Light light[4];
uniform Material mat;
uniform vec4 ambientColor;
uniform vec4 cameraPos;
//uniform int lightCount;

void main()
{
vec3 n = normalize(normal);
vec4 ambient = mat.matAmbient * ambientColor;

int lightCount = 4;

vec4 diffuseSum = 0;
vec4 specularSum = 0;
vec4 diffuse;
vec4 specular;
vec4 diffuseLight;
vec4 specularLight;

for (int i = 0; i < 4; i++)
{
// Get light attenuation for point light effect.
float d = distance(pos, light.position);
float attenuationFactor = 1 / (light.constant + light.linear * d + light.quadratic * d * d);

// Calculate diffuse with the attenuation.
vec4 lightVec = normalize(light.position - pos);
float diffuseLight = max(dot(n, lightVec), 0);
diffuseSum += attenuationFactor * light.color * diffuseLight;

// Calculate specular with the attenuation.
vec4 eyeVec = normalize(cameraPos - pos);
vec4 halfVec = normalize(lightVec + eyeVec);
float specularLight = pow(max(dot(n, halfVec), 0), mat.matShininess);

// No diffuse, no specular.
if (diffuseLight <= 0)
specularLight = 0;

specularSum += attenuationFactor * light.color * specularLight;
}

// Get final diffuse and specular values.
diffuse = mat.matDiffuse * diffuseSum;
specular = mat.matSpecular * specularSum;

// Set final light color.
gl_FragColor = (mat.matEmissive + ambient + diffuse + specular) * texture2D(decal, texCoord0);
gl_FragColor.w = 1;
}



I ll like to find a solution for that!


second problem is with this code i cant process anoter pass without having some kind od co-planar flickering... i ve been carefull to free the shader before processing the second pass (shadow pass), but any way i put it... it always comes out with this "Bug"!

any sugestion to improve the code above!?

i m aware this is kind of a lot to ask but i got no other alternatives so far! any help will be really apreciate!

I must add, in one pass, this is the best looking pp light result i ve seen so far! it looks just amasing! and i think it worth fighting for!

thx again!

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!