Ways to set Shader Parameters

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Ways to set Shader Parameters

Post by Vectrotek »

When I post the project I hope someone can help me with a few things..
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Ways to set Shader Parameters

Post by Vectrotek »

These screenshots don't really show the power of Non Linear Inter Buffer Rendering but...
http://irrlicht.sourceforge.net/forum/v ... start=1455
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Ways to set Shader Parameters

Post by Vectrotek »

devsh?.. anyone?.. If you read this, here is a question..

Code: Select all

 
 
 #version 120
 
 // Matrices..
 uniform mat4  M01World;
 uniform sampler2D Image01;     // POSITION!!
 uniform sampler2D Image02;     // RANGE COMPRESSED NORMALS!!
 // uniform sampler2D Image03;
 // uniform sampler2D Image04;
 
 // Note how there is nothing coming from the Vertex Program..
 // The vertex progam handles the screen quad and thats it..
 
 // A unique case: A P/P Shader using the Camera Position!
 // This "Deferred Shading" Post Process Shader uses the Camera Position to calculate Specularity and Diffuse..
 uniform vec3  CameraPosition;
 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 // HOW DO WE FED A STRUCTURE IN GPU CODE FROM AN IRRLICHT APP?
 struct Light   {vec3 Pos; vec3 Col;}; // Structur to hold our lights..
 const int LIGHT_COUNT = 4;
 Light LightsArray [LIGHT_COUNT];
 
 void main()
  {vec2 UVCoordsXY  = gl_TexCoord[0].xy;
   vec3 FragPosRCIN     = texture2D(Image01, UVCoordsXY).xyz; 
   // The Fragment Shader used to create the image for the Normals Buffer
   // needs to deliver those Normals in "Range Compressed" form because 
   // Normals have Positive and Negative values which we need to fit into
   // an RGB Image..
   vec3 RCNormalIN = texture2D(Image02, UVCoordsXY).xyz;
   // They have to be Range Compressed as traditional RGB wont handle negative values..
   vec3 URCNormal = ((RCNormalIN.xyz - 0.5) * 2);  // Now they are Un Range Compressed..
   float SpreadVal = 0.005; // This is just me trying to make the RGB FRAGPOS available space bigger..
   // Some lights..
   LightsArray [0].Col = vec3(1.0  ,  1.0   ,0.0);
   LightsArray [1].Col = vec3(0.0  ,  1.0   ,0.0);
   LightsArray [2].Col = vec3(0.0  ,  0.0   ,0.0);
   LightsArray [3].Col = vec3(0.0 ,  0.0  ,0.0);
   LightsArray [0].Pos = vec3(  10.0,   5.0,  0.0);
   LightsArray [1].Pos = vec3(  0.0,   15.0, 0.0);
   LightsArray [2].Pos = vec3(  0.0,   100.0,   0.0);
   LightsArray [3].Pos = vec3( 100.0,   0.0,   0.0);
   vec3 URCFragPos = ((FragPosRCIN.xyz - 0.5) * 2.0);  // Unrange compress RGB i.e XYZ Fragpos..
   vec3 SpreadURCFragPos =  URCFragPos / SpreadVal;
 
  vec4 XXCAmpos = vec4 (CameraPosition.xyz, 0) * M01World; // Didn't seem to need this matrix mult ?
  vec3 JJJCameraPosition = vec3(CameraPosition.xyz);
  vec3 diffuse;
  vec3 specular;
 
  // With "rounded" surfaces the normals seems to smooth the light which is fine but
  // flat surfaces shows that there is a serious lack in domain..
  // I KNOW THAT XYZ FRAGPOS CAN BE TRIANGULATED (thanks devsh) but for the love of.. How?? ? ? 
  // The whole thing works, it is just this "limited" domain..
  // I know that if I rendered the geometry with Fragpos X, Y and Z like Max Domain RGB Depth it
  // could be really look better but thats alot of inter buffer rendering.. (plus we have only 4 image channels)
 
  // DIFFUSE:
  //  for (int Li = 2; Li < LIGHT_COUNT ; Li++)
  //   {diffuse += max(dot(URCNormal, normalize((LightsArray [Li].Pos * SpreadVal))), 0.0) * LightsArray [Li].Col;
  //   }
  // CAMERA DIFFUSE LIGHT (not looping through all lights right now)
  diffuse += max(dot(URCNormal, normalize((JJJCameraPosition.xyz * SpreadVal) - URCFragPos)), 0.0) * LightsArray [0].Col;
   
  /*
  // SPECULAR:
  for (int Li = 2; Li < LIGHT_COUNT ; Li++)
    {specular += LightsArray [Li].Col
       * (clamp(pow(clamp(dot(normalize((normalize((JJJCameraPosition.xyz * SpreadVal))
       + normalize(LightsArray [Li].Pos * SpreadVal))), URCNormal),0.0,1.0),  77.77 ), 0.0 , 1.0 ) ) ; 
    }
  */    
  // CAMERA SPECULAR LIGHT (not looping through all lights right now)
  specular += LightsArray [0].Col
       * (clamp(pow(clamp(dot(normalize((normalize((JJJCameraPosition.xyz * SpreadVal) - (URCFragPos * 1))
       + (JJJCameraPosition.xyz * SpreadVal) - (URCFragPos * 1))), URCNormal),0.0,1.0),  77.77 ), 0.0 , 1.0 ) ) ; 
  gl_FragColor = vec4((diffuse * 0.5) + specular, 1.0); 
   
   // TRICKS..
   // Range Compress..
   // (0.5 * VALUE.xyz + 0.5);
   // Un - Range Compress..
   // ((VALUE.xyz - 0.5) * 2)
  }  
 
  
  
 
 
vectorcorpse
Posts: 86
Joined: Thu Feb 14, 2008 7:30 pm
Location: Portugal

Re: Ways to set Shader Parameters

Post by vectorcorpse »

Vectrotek you got me curious with something, why on COpenGLSLMaterialRenderer.cpp on the setPixelShaderConstant the variable count feeded to the extGlUniform(s) are being divided by 2 ?!? according to this: https://www.opengl.org/sdk/docs/man/htm ... form.xhtml
the count is needed to set the number of elements on a array
For uniform variable arrays, each element of the array is considered to be of the type indicated in the name of the command (e.g., glUniform3f or glUniform3fv can be used to load a uniform variable array of type vec3). The number of elements of the uniform variable array to be modified is specified by count

Code: Select all

bool COpenGLSLMaterialRenderer::setPixelShaderConstant(const c8* name, const f32* floats, int count)
{
    u32 i;
    const u32 num = UniformInfo.size();
 
    for (i=0; i < num; ++i)
    {
        if (UniformInfo[i].name == name)
            break;
    }
 
    if (i == num)
        return false;
 
#if defined(GL_VERSION_2_0)||defined(GL_ARB_shader_objects)
    GLint Location=0;
    if (Program2)
        Location=Driver->extGlGetUniformLocation(Program2,name);
    else
        Location=Driver->extGlGetUniformLocationARB(Program,name);
 
    bool status = true;
 
    switch (UniformInfo[i].type)
    {
        case GL_FLOAT:
            Driver->extGlUniform1fv(Location, count, floats);
            break;
        case GL_FLOAT_VEC2:
            Driver->extGlUniform2fv(Location, count/2, floats);
            break;
        case GL_FLOAT_VEC3:
            Driver->extGlUniform3fv(Location, count/3, floats);
            break;
        case GL_FLOAT_VEC4:
            Driver->extGlUniform4fv(Location, count/4, floats);
            break;
        case GL_FLOAT_MAT2:
            Driver->extGlUniformMatrix2fv(Location, count/4, false, floats);
            break;
        case GL_FLOAT_MAT3:
            Driver->extGlUniformMatrix3fv(Location, count/9, false, floats);
            break;
        case GL_FLOAT_MAT4:
            Driver->extGlUniformMatrix4fv(Location, count/16, false, floats);
            break;
        case GL_SAMPLER_1D:
        case GL_SAMPLER_2D:
        case GL_SAMPLER_3D:
        case GL_SAMPLER_CUBE:
        case GL_SAMPLER_1D_SHADOW:
        case GL_SAMPLER_2D_SHADOW:
            {
                const GLint id = static_cast<GLint>(*floats);
                Driver->extGlUniform1iv(Location, 1, &id);
            }
            break;
        default:
            status = false;
            break;
    }
    return status;
#else
    return false;
#endif
}
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Ways to set Shader Parameters

Post by Vectrotek »

The "v" in

Code: Select all

extGlUniform1fv
has nothing to do with "vec3" or any vecX for that matter.
(those are Irrlicht data types, where as "extGlUniform1fv" is a OpenGL function)
the "v" in "Xfv" means "vector" as meaning "a Vector into X memory locations" and refers to the fact that it is an "array" of X "Variables".

The "divide by X" in..

Code: Select all

 
    case GL_FLOAT: Driver->extGlUniform1fv(Location, count, floats); break;
    case GL_FLOAT_VEC2: Driver->extGlUniform2fv(Location, count/2, floats); break;
    case GL_FLOAT_VEC3: Driver->extGlUniform3fv(Location, count/3, floats); break;
    case GL_FLOAT_VEC4: Driver->extGlUniform4fv(Location, count/4, floats); break;
 
simply means the following..
"count" for FLOAT is ONE i.e. One float, so 1-count is 1-count,
BUT..
"count/2" for VEC2 (really TWO Floats i.e. "float MyFloatArray[2]").

So you've got TWO "floats" but ONLY ONE "MyFloatArray[2]"s, hence the "count/2" to get it back to ONE ITEM..
Now think of a "MyFloatArray[2]" (VEC_2) as a "..2fv" and
think of a "MyFloatArray[3]" (VEC_3) as a "..3fv" or even
"MyFloatArray[4]" (VEC_4) as a "..4fv".

The "Case Switch" simply SELECTS THE RIGHT GL-FUNCTION to match the Irrlicht Datatype that is being fed to the Shader.

Internally the GL-Function knows (by its name) what its dealing with because of the "Xfv" i.e. "X float Vector", in its name.

The meaning of "v" in the code below means something else again..

Code: Select all

 
void glUniform4f(   GLint location,
    GLfloat v0,  // Means "Variable ZERO"
    GLfloat v1,  // Means "Variable ONE"
    GLfloat v2,  // Means "Variable TWO"
    GLfloat v3); // Means "Variable THREE"
 
I think.. (or imagine reading something like this at some stage) :?

Let me know if it made any sense at all..
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Ways to set Shader Parameters

Post by Vectrotek »

Oh! And with that question you gave me an idea to optimize my smart shader! thanks! :lol:
vectorcorpse
Posts: 86
Joined: Thu Feb 14, 2008 7:30 pm
Location: Portugal

Re: Ways to set Shader Parameters

Post by vectorcorpse »

nice, :D i'm glad my question contributed in some way
also i see the potential of what you are trying to do here, and hoping you succeed, i have a AMD card (Radeon 4850 aka RV770) running on linux with gallium drivers if you need any help to adjust your shaders for this kind of hardware, i can tell you in advance that i had to change a few things on your previews demos (which are really cool) to be able to run them, AMD and also mesa/gallium drivers are not has tolerant has nvidia proprietary drivers, but with the changes it runs on both AMD and Nvidia hardware.

In any case one thing that also interests me is one of your questions
// HOW DO WE FED A STRUCTURE IN GPU CODE FROM AN IRRLICHT APP?
because i have the same problem in another kind of rendering i'm working on that requires passing big data structures to the shaders
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Ways to set Shader Parameters

Post by Vectrotek »

Interesting. I really want to post the project but there is few things I want to do first..
The data is becoming quite large so I need to really skim content off the top,
but the program will be complete and working (on windows at least).

It will be really cool if you could dissect it and let me know about those AMD and Linux matters!

I'll probably, as always post an imperfect project but it will work and it will have some cool content.

Another thing is that discussions (what we're busy with at least) is beginning to scatter over
different forum topics so I thought I might create a Unique Topic Called "Advanced Effects"
or something where matters can remain sensibly together..

I'm not the greatest programmer and I'm not skilled in the "dark arts" like devsh, nadro, cute_alien or mel
and a lot of other guys but it will be cool if this forum topic could lead to perhaps new Irrlicht functions and be useful to everyone
using Irrlicht.. (I enjoy writing though)

Anyhow thanks!
PS Your login handle gives me the hibbie jibbies, but don't change it! I'm getting used to it.. :mrgreen:
vectorcorpse
Posts: 86
Joined: Thu Feb 14, 2008 7:30 pm
Location: Portugal

Re: Ways to set Shader Parameters

Post by vectorcorpse »

btw this just came to my mind, i did not test it but wouldn't this work?

in shader:

Code: Select all

struct LightSource
{
        int Type;
        vec3 Position;
        vec3 Attenuation;
        vec3 Direction;
        vec3 Color;
};
 
uniform LightSource Light[4];
then on irrlicht push the values 1 by 1 with:

Code: Select all

setPixelShaderConstant("Light[0].Type", variable to send to shader struct, 1);
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Ways to set Shader Parameters

Post by Vectrotek »

It probably would, haven't tested it yet.
There might be a #version X issue as well.
vectorcorpse
Posts: 86
Joined: Thu Feb 14, 2008 7:30 pm
Location: Portugal

Re: Ways to set Shader Parameters

Post by vectorcorpse »

well, i just tested it and it does work fine :D ehe
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Ways to set Shader Parameters

Post by Vectrotek »

Nice! Ill try it too..
Post Reply