I think this is an extremely stupid and newbie question, but then I am a newbie in graphics and openGL. Having drawn a sphere and put a light source nearby, also having specified ambient light, I started experimenting with light and material values and came to a surprising conclusion: the colors which we specify with glColor* do not matter at all when lighting is enabled. Instead, the equivalent is the material's ambient component. Is this conclusion correct? Thanks
If the lighting is enabled, then instead of the vertex color, the material color (well, colors - there are several of them for different types of response to light) is used. Material colors are specified by glMaterial* functions.
If you want to reuse your code, you can use glEnable(GL_COLOR_MATERIAL) and glColorMaterial(GL_AMBIENT_AND_DIFFUSE) to have your old glColor* calls mapped to material color automatically.
(And please switch to shaders as fast as possible - the shader approach is both easier and more powerful)
I suppose you don't use fragment shader yet. From glprogramming.com:
vertex color =
the material emission at that vertex +
the global ambient light scaled by the materials ambient
property at that vertex +
the ambient, diffuse, and specular contributions from all the
light sources, properly attenuated
So yes, vertex color is not used.
Edit: You can also look for GL lightning equation in GL specification (you have one nearby, do you? ^^)
Related
I recently added deferred shading into my engine, and ran across a technique called "light volumes". While being great because it reduces lighting computations to the minimum (executing only fragments in the light volume), I cannot figure out how I could render the rest of the scene with ambient lighting!
I get the following scene without ambient lighting: (the light volume has been highlighted in gray)
Of course, I could always render a fullscreen quad, but I would loose the benefit of this technique.
Any suggestions?
Edit : I finally got it to work thanks to Nicol : ) Here is a new picture :
You do the ambient lighting in a separate pass. Just like you do with lights in general with deferred rendering. That is the general idea, that each light happens in its own pass, with you accumulating the results into the framebuffer by doing additive blending with them.
The ambient light is simply considered another lightsource.
I have an OpenGL shader program which renders a cube. To colour the cube, I pass the normal of each vertex to the vertex shader, and calculate its greyscale shade with respect to a point light source.
However, I now want to also render a red triangle, whose colour is always red and does not depend on lighting. But if I just pass the normal to the vertex shader as before, the triangle's colour will be affected by the light.
What is the best solution for this? Should I calculate the vertex colour before the shaders, and pass that to the vertex shader? Or is that bad practice?
There are two main options:
Use one shader program that is flexible enough to handle both cases.
For a shader that applies basic lighting, it is common to pass in values (typically as uniforms) that determine the weight of the ambient and diffuse terms in the lighting equation. With a shader like this, if you want a solid color for part of your objects, you simply crank up the ambient term all the way by setting the uniform accordingly.
Use different shader programs.
Each one has benefits, and you have to figure out which works best for you.
The main downside of approach 1 is that your shader might do more work than needed. In this example, it will still evaluate the diffuse term of the lighting equation for the solid objects, even though it does not contribute to the final result. If you draw a lot of solid geometry, that could hurt performance.
The main downside of approach 2 is that you have to switch shaders. If you frequently switch between solid and lighted rendering, that can hurt performance. One way to work around this is that you first draw all lighted objects, then all solid objects, so that you have to switch shaders only once per frame. Depending on your software architecture, that may be easy to do, or it could require significant restructuring.
Create another shader program that uses a fixed color as the output, since there are two types of rendering you want to do, is better to separate it accordingly.
I'm just beginning to learn OpenGL. With all of the tutorials I've seen, they demonstrate using a fragment shader to set the color of all the objects in view. What I haven't found yet is how you would use a fragment shader on just one of the objects, giving different objects different colors. How do you do that?
To provide background to the question, I'm drawing a simple scene with a house and a road in 2d. I have discovered how to set the colors of each of my objects (the main body of the house, the window, etc) using the fixed graphics pipeline, I just don't understand how to set the colors using fragment shaders.
Any clarification would be greatly appreciated, including correction if I'm misunderstanding something.
To provide background to the question, I'm drawing a simple scene with a house and a road in 2d. I have discovered how to set the colors of each of my objects (the main body of the house, the window, etc) using the fixed graphics pipeline, I just don't understand how to set the colors using fragment shaders.
As RobertRouhani said, make the color a uniform and change it for each object.
How to apply a fragment shader to only one object in OpenGL?
You can simply change the shader program with glUseProgram and rendering calls after it will use the different shader.
See this: https://gamedev.stackexchange.com/questions/22216/using-multiple-shaders
Before you draw an object with glDrawArrays or glDrawElements, pass the color to a shader as a variable.
http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml
Sample GLSL fragment shader:
uniform vec4 u_color;
void main(void)
{
gl_FragColor = u_color;
}
I would expand on this answer but I am being lazy. Hope it helps somewhat. There are a lot of tutorials online, just search for glsl, glUniform4f, etc.
I am making a shader in witch i am using a spot light, I am trying some shaders that I´ve found in the Internet before I make my own.
I found this GLSL code:
vec4 final_color =
(gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) +
(gl_LightSource[0].ambient * gl_FrontMaterial.ambient);
Does anyone know how can i make this in the RenderMonkey? i know that i cannot use gl_LightSource[0], how can i make it?
In rendermonkey you would need to set variables for the light properties which your shader would use. such a a vec4 for the light's ambient, diffuse, and specular colors. Then some vec3 for the vector to the light / position of the light, etc.
Then you can set these variables to be artist variables, and you can edit them 'live' in the artist Editor on the right.
It's a bit awkward, meaning that you either need to adjust your usage of your shader such that you don't rely on the built in gl_ constructs (so you don't need to edit a shader for it to run both in your program and in RM. Or you need to edit the shaders when you go inbetween. I prefer the former.
I'm already familiar with OpenGL's native lights.
My question is how do I go about rendering lights with Cg?
Do I still need to declare normal OpenGL lights and then use Cg to render the light?Or is it all done with Cg?
If you could point me to some reading material about lighting with Cg that would be great also.
Well, after some experimenting, I figured out that you don't need to use any OpenGL ligthing directive.
All you need to do is write a vertex shader and give it the parameters needed for the lights: light position, light color. You can also send reflectance and shininess parameters for each object to simulate the way you declare material properties in opengl.