(SOLVED) How to fix light shape in lighting shader

I’m trying to code a lighting shader and I’m wondering if there is an easy way to get a fragments world position. I tried looking in the normal map example but that code is made for getting position according to screen position, not world. Any ideas? Thanks.

Edit: for a sprite shader btw

You could try calculating the inverse frustum (or just the inverse of the view and projection matrices separately) in the vertex shader, then passing it as an output to the fragment shader.

I tried seeing if I could do that, but the version of glsl that defold uses doesn’t ahve the inverse function and I don’t know a single thing about matrices, let alone inversing one.

I noticed that the default sprite shader gets a world position by default for each of its vertices, so you can simply forward it to the fragment shader and the render pipeline will take care of the interpolation between vertices.

So in the sprite vertex shader:

// positions are in world space
attribute highp vec4 position;
...
var_worldpos = position;

And in the sprite fragment shader:

varying highp vec4 var_worldpos;

You can then reference the fragment’s world position through the var_worldpos variable.

1 Like

wait, if that’s the correct way to do it then i guess thats not my issue, because that’s what I’ve been doing. I’m trying to make a point light and the light keeps pointing towards the bottom left corner rather than encompassing a full circle.

I’m not sure what you mean. You should post your fragment shader code if you need help with your fragment shader, as well as a screenshot of the result you’re getting.

if (light_positions[light_index].w == 1) {
            lowp vec3 light_dir = light_positions[light_index].xyz - var_position.xyz;
            float distance = length(light_dir);
            light_dir = normalize(light_dir);
            float attenuation = 1.0 / (1.0 + (light_linears[light_index].y * distance) + 
                (light_quads[light_index].x * distance * distance));


            // Get View Direction
            lowp vec3 view_dir = normalize(view_pos.xyz - var_position.xyz);

            // Calculate Reflection Direction
            vec3 reflect_dir = normalize(reflect(-light_dir, normal_color.xyz));

            // Calculate Specular
            float specular = pow(max(dot(view_dir, reflect_dir), 0.0), 32);
            spec_color = (specular * light_colors[light_index] * spec_color *spec_strength.x*attenuation);

            float diff = max(0, dot(normal_color.xyz, light_dir.xyz));
            color_diffuse = diff * light_colors[light_index] * attenuation;

            final_color += vec4((color_diffuse + spec_color).xyz * albedo_color.xyz, albedo_color.w);
        }

var_position is the “position” variable passed down from the vertex program.

This is how it looks like:

I had the same issue here: Normal map lighting for 2D Pixel Art sprites - #8 by Pawel and Johnny helped me there, let me quote:

If so, what you are missing is that you need to expand the normal from [0…1] range (since it’s a texture) to [-1…1]:

vec4 normal_sample = texture2D(texture_sampler, offset_coord.xy) * 2.0 - 1.0;
lowp vec3 normal_dir = normalize(normal_sample.xyz);

Let us know, if this is of any help :slight_smile:

1 Like

huh, that seemed to fixed it! And it retains the specular-silhouette effect thingy too. Thanks!

1 Like