glsl shader to allow color change of skydome ogre3d

Posted by Tim on Game Development See other posts from Game Development or by Tim
Published on 2014-04-03T05:55:21Z Indexed on 2014/06/03 16:01 UTC
Read the original article Hit count: 500

Filed under:
|
|
|

I'm still very new to all this but learning a lot. I'm putting together an application using Ogre3d as the rendering engine. So far I've got it running, with a simple scene, a day/night cycle system which is working okay.

I'm now moving on to looking at changing the color of the skydome material based on the time of day. What I've done so far is to create a struct to hold the ColourValues for the different aspects of the scene.

struct todColors {
    Ogre::ColourValue sky;
    Ogre::ColourValue ambient;
    Ogre::ColourValue sun;
};

I created an array to store all the colours

todColors   sceneColours [4];

I populated the array with the colours I want to use for the various times of the day. For instance DayTime (when the sun is high in the sky)

sceneColours[2].sky = Ogre::ColourValue(135/255, 206/255, 235/255, 255);
sceneColours[2].ambient = Ogre::ColourValue(135/255, 206/255, 235/255, 255);
sceneColours[2].sun = Ogre::ColourValue(135/255, 206/255, 235/255, 255);

I've got code to work out the time of the day using a float currentHours to store the current hour of the day 10.5 = 10:30 am. This updates constantly and updates the sun as required.

I am then calculating the appropriate colours for the time of day when relevant using

else if( currentHour >= 4 && currentHour < 7) {

    // Lerp from night to morning
    Ogre::ColourValue lerp = Ogre::Math::lerp<Ogre::ColourValue, float>(sceneColours[GT_TOD_NIGHT].sky , sceneColours[GT_TOD_MORNING].sky, (currentHour - 4) / (7 - 4));

}

My original attempt to get this to work was to dynamically generate a material with the new colour and apply that material to the skydome. This, as you can probably guess... didn't go well.

I know it's possible to use shaders where you can pass information such as colour to the shader from the code but I am unsure if there is an existing simple shader to change a colour like this or if I need to create one.

What is involved in creating a shader and material definition that would allow me to change the colour of a material without the overheads of dynamically generating materials all the time?

EDIT : I've created a glsl vertex and fragment shaders as follows.

Vertex

uniform vec4 newColor;

void main()
{
gl_FrontColor = newColor;
gl_Position = ftransform();
}

Fragment

void main()
{
gl_FragColor = gl_Color;
}

I can pass a colour to it using ShaderDesigner and it seems to work. I now need to investigate how to use it within Ogre as a material.

EDIT :

I created a material file like this :

vertex_program colour_vs_test glsl
{
source test.vert
default_params
{
    param_named newColor float4 0.0 0.0 0.0 1
}
}

fragment_program colour_fs_glsl glsl
{
source test.frag
}

material Test/SkyColor
{
technique
{
    pass
    {
        lighting off

        fragment_program_ref colour_fs_glsl
        {
        }
        vertex_program_ref colour_vs_test
        {
        }
    }
}
}

In the code I have tried :

Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName("Test/SkyColor");
Ogre::GpuProgramParametersSharedPtr params = material->getTechnique(0)->getPass(0)->getVertexProgramParameters();
params->setNamedConstant("newcolor", Ogre::Vector4(0.7, 0.5, 0.3, 1));

I've set that as the Skydome material which seems to work initially. I am doing the same with the code that is attempting to lerp between colours, but when I include it there, it all goes black.

Seems like there is now a problem with my colour lerping.

© Game Development or respective owner

Related posts about c++

Related posts about shaders