1
\$\begingroup\$

I am attempting to implement a day/night cycle using a GLSL fragment shader in a 2D game i'm developing in SFML. I am a novice with shaders with this one being my first.

Currently I am using a lightmap to achieve ambient lighting and spotlights from lightsources (e.g. campfire) which is working nicely. The lightmap shader I am using I got from following an old Alcovegames tutorial, see below:

uniform sampler2D texture;
uniform sampler2D lightmap;

uniform vec4 ambient;
uniform vec2 resolution;
uniform int theta;

float PI_180 = 3.141592653589793 / 180;

vec3 ToGlColour3(in vec3 colour)
{
    float dv = (1.0/255);
    return vec3
    (
        dv * colour.r,
        dv * colour.g,
        dv * colour.b
    );
}

vec4 ToGlColour4(in vec4 colour)
{
    return vec4
    (
        ToGlColour3(colour.rgb),
        (1.0/255) * colour.a
    );
}

void main()
{
    vec4 diffuse = texture2D(texture, gl_TexCoord[0].xy);

    vec2 lightcoord = (gl_FragCoord.xy / resolution.xy);
    vec4 light = texture2D(lightmap, lightcoord);

    vec4 ambientLight = ToGlColour4(ambient);

    float ambientIntensity = ambientLight.a * (sin(theta * PI_180) + 0.5);
    vec3 ambientColour = ambientLight.rgb * ambientIntensity;
    vec3 intensity = (ambientColour + light.rgb);

    vec3 result = diffuse.rgb * intensity;

    gl_FragColor = vec4(result, diffuse.a);
}

The ambientIntesity calculation is my attempt at cycling from night to day. My issue is that it doesn't cycle bright enough to give an adequate daytime effect.

I was thinking I could use the current value of sine(theta) and interpolate from my ambient colour to white (representing fully lit daytime).

I'm just not sure how to achieve this in GLSL. Ideally a solution within GLSL would be possible to help develop my knowledge of shaders.

I appreciate any help, Thanks.

\$\endgroup\$
2
  • \$\begingroup\$ Why are you multiplying your ambient color's alpha and color channels by 1/255.0? That's going to make them very small. Also, it's wasteful as you're doing that calculation on every fragment. You should just scale it before passing setting the uniform. \$\endgroup\$ Jul 14, 2018 at 3:17
  • \$\begingroup\$ @user1118321 I use those methods for normalising the colours that i pass into the shader as they are between 0-255. I understand that it is wasteful, but for now while i'm learning, i'm not too interested in optimisations until i have the shader working as intended, but thanks for pointing it out, i'll make the change now \$\endgroup\$
    – cmpbedes
    Jul 16, 2018 at 7:52

1 Answer 1

1
\$\begingroup\$

you are scaling the ambient lighting by a factor of [-0.5, 1.5]. Ambient light is generally a small value, because it is meant to add a small amount of light to fragments that would otherwise show up as black due to the lightmap. What you want to do is scale the light.rgb color in the range [0,n] where the value of n*light.rgb is the sunlight at peak daytime.

vec3 result = (ambientLight.rgb + n*(sin(...)*0.5+0.5)*light.rgb;
\$\endgroup\$
2
  • \$\begingroup\$ Thanks for providing this solution, could you just clarify where the value of n is coming from? \$\endgroup\$
    – cmpbedes
    Jul 16, 2018 at 7:58
  • \$\begingroup\$ n is just a scale factor for the light value coming from the lightmap texture. Alternatively, you could remove n and scale each pixel rgb value in the texture by n. \$\endgroup\$
    – Kyy13
    Jul 16, 2018 at 17:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .