Many shaders GLSL in scenes

Started by
8 comments, last by renanrosa 6 years, 10 months ago

Hello guys.

I'm studying GLSL and had a question to apply more than one program.

Example, i have 2 GLSL:

Texture (Code 1):

Vertex:


varying vec2 coord;


void main(void)
{
  
   coord = gl_Vertex.xy;
   
   gl_Position = ftransform(); //gl_ProjectionMatrix *  (gl_ModelViewMatrix * gl_Vertex);
   
}

Frag:


uniform sampler2D text1;
varying vec2 coord;

void main(void)
{   
   
   
   vec4 color = texture2D(text1, coord); 
   gl_FragColor = color;
   
}

And i have the GLSL to light (Code 2):

Vertex:


varying vec3 normal;
varying vec4 pos;
varying vec4 rawpos;

void main() {
  normal = gl_NormalMatrix * gl_Normal;
  gl_Position = ftransform();
  pos = gl_ModelViewMatrix * gl_Vertex;
  rawpos = gl_Vertex;
  gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}

Frag:


varying vec3 normal;
varying vec4 pos;

void main() {
     vec4 color = vec4(1,0,0,1);
     vec4 matspec = vec4(1,1,0,1);
     float shininess = 512;
     vec4 lightspec = vec4(10,10,10,10);
     vec4 lpos = vec4(1,-5,9,1);
     vec4 s = -normalize(-lpos); 
   
     vec3 light = s.xyz;
     vec3 n = normalize(normal);
     vec3 r = -reflect(light, n);
     r = normalize(r);
     vec3 v = -pos.xyz;
     v = normalize(v);
       
     vec4 diffuse  = color * max(0.0, dot(n, s.xyz)) * color;
     vec4 specular;
     if (shininess != 0.0) {
       specular = lightspec * matspec * pow(max(0.0, dot(r, v)), shininess);
     } else {
       specular = vec4(0.0, 0.0, 0.0, 0.0);
     }
   
     gl_FragColor = diffuse + specular;
}
All work correctly.
But when I try to apply both, only the last one is applied to the scene.
I wanted to know how I can put the two together without having to do just one file (.Frag and .Vert).
Because I would like to leave the lights more dynamic, for example (pseudocode):

//ApplyLight uses the program GLSL to Light (Vide code 2)
//applyLight(PositionX, PositionY, PositionZ, Atenuation);

applyLight(1.0f, 2.0f, 0.0f, 4.0f);
applyLight(3.6f, 4.5f, 2.0f, 5.0f);
applyLight(2.0f, 1.0f, 1.1f, 3.6f);
applyLight(0.0f, 2.0f, 4.0f, 4.5f);

//Draw Terrain use the Code 1 and draw a .obj file
drawTerrain();
How could I do that?
Apply more than one program to an object / scene.
Could someone explain me?
Regardless of language, I'm using both android ES and C ++.
Thank you

Advertisement
Are you calling glUseProgram() ?

You can't draw a single model with 2 shader programs. But you can draw the same model twice and call glUseProgram() between the draw calls to switch programs.

Are you calling glUseProgram() ?

You can't draw a single model with 2 shader programs. But you can draw the same model twice and call glUseProgram() between the draw calls to switch programs.

Hi Missionctrl, thank you for your reply.

Yes, i'm calling glUseProgram() in applyLight and drawTerrain (Pseudocode)


void applyLight(float, float, float, float){
    glUseProgram(.......)
    ..........
}
............
void drawTerrain(){
 glUseProgram(.....)

 ................
}

then... i need draw the the same model twice ?

this is slow or compromise the performance ?

Or the result is only one model drawn ?

For what you're trying to do, you would need to pass 4 lights into your shader and draw the scene once. You cannot dynamically combine shaders the way you are trying to. Here is a good tutorial for dealing multiple lights. https://learnopengl.com/#!Lighting/Multiple-lights

Are you calling glUseProgram() ?

You can't draw a single model with 2 shader programs. But you can draw the same model twice and call glUseProgram() between the draw calls to switch programs.

Hi Missionctrl, thank you for your reply.

Yes, i'm calling glUseProgram() in applyLight and drawTerrain (Pseudocode)


void applyLight(float, float, float, float){
    glUseProgram(.......)
    ..........
}
............
void drawTerrain(){
 glUseProgram(.....)

 ................
}

then... i need draw the the same model twice ?

this is slow or compromise the performance ?

Or the result is only one model drawn ?


For what you're trying to do, you would need to pass 4 lights into your shader and draw the scene once. You cannot dynamically combine shaders the way you are trying to. Here is a good tutorial for dealing multiple lights. https://learnopengl.com/#!Lighting/Multiple-lights

Wow, very nice this tutorial, but the light and terrain is a example for "multi shader". I would like to use separate shader for light, SSAO, glow, terrain...and others

But you can draw the same model twice and call glUseProgram() between the draw calls to switch programs.

Did not work :(

Remained only the first

You need to write your GLSL code in a way where you can easily mix multiple bits of code together to make a new shader that does multiple things. I recommend setting up a C preprocessor so that you can use #include as you would in C/C++/HLSL.

But you can draw the same model twice and call glUseProgram() between the draw calls to switch programs.


Did not work :(
Remained only the first

You have to set your depth-compare so that drawing the same model more than once passes the depth test each time (and similarly for any stenciling tests).

The first pass typically uses GL_LESS (or GL_LEQUAL), and following passes use GL_EQUAL.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

On 2017-6-15 at 6:40 PM, YogurtEmperor said:

 

But you can draw the same model twice and call glUseProgram() between the draw calls to switch programs.

 
Did not work  :(
Remained only the first

 

You have to set your depth-compare so that drawing the same model more than once passes the depth test each time (and similarly for any stenciling tests).

The first pass typically uses GL_LESS (or GL_LEQUAL), and following passes use GL_EQUAL.


L. Spiro

 

Can you show to me?

with source-code example.

This topic is closed to new replies.

Advertisement