glsl shader to allow color change of skydome ogre3d
- by Tim
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.