Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weird snap shadow glitch #19

Closed
JonathSpirit opened this issue Oct 8, 2021 · 24 comments
Closed

Weird snap shadow glitch #19

JonathSpirit opened this issue Oct 8, 2021 · 24 comments
Labels
bug Something isn't working

Comments

@JonathSpirit
Copy link
Contributor

shadowSnapBug

When casting to a complex shape, weird shadow snap appear and make it uncomfortable to see.

I created lines between those points :

point 0 x: 160 y: 120
point 1 x: 200 y: 160
point 2 x: 160 y: 200
point 3 x: 120 y: 160

My code is from the example program, with the add of a lighting area :

candle::LightingArea fog(candle::LightingArea::FOG,
                             sf::Vector2f(0.f, 0.f),
                             sf::Vector2f(640.f, 480.f));
    fog.setAreaColor(sf::Color(0,0,0,100));

I used the library imgui-sfml but this should not interfere with candle.

@MiguelMJ
Copy link
Owner

Mmm I'm not sure what it could be exactly, could you try compiling with the debug candle flag and see how the light behaves?

  • DCANDLE_DEBUG

@JonathSpirit
Copy link
Contributor Author

I created a new project with just SFML and candle with MSYS2-MinGW64 x64 on windows

I compiled with this command :

cmake .. -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug -DSFML_ROOT="" -DSFML_DIR="C:\Users\guill\Desktop\temp\candle_test\libsfml\lib\cmake\SFML"

I don't know how to precise a definition to cmake so I directly put it in the cmakefiles :

ADD_DEFINITIONS(-DCANDLE_DEBUG)

but when I add this flag, my window appear but the "isOpen()" function return false and the program just shut. That a really weird behaviour and I don't really know if I skip a step here ...

Animation

Without the requested flag :

Animation2

@JonathSpirit
Copy link
Contributor Author

#include <SFML/Graphics.hpp>
#include "Candle/RadialLight.hpp"
#include "Candle/LightingArea.hpp"

int main(){
    // create window
    sf::RenderWindow w(sf::VideoMode(400, 400), "app");

    // create a light source
    candle::RadialLight light;
    light.setRange(200);
    light.setColor(sf::Color(255,255,255));

    candle::LightingArea fog(candle::LightingArea::FOG,
                             sf::Vector2f(0.f, 0.f),
                             sf::Vector2f(400.f, 400.f));
    fog.setAreaColor(sf::Color(0,0,0,100));

    // create an edge pool
    candle::EdgeVector edges;
    edges.emplace_back(sf::Vector2f(160.f, 120.f),
                       sf::Vector2f(200.f, 160.f));
    edges.emplace_back(sf::Vector2f(200.f, 160.f),
                       sf::Vector2f(160.f, 200.f));
    edges.emplace_back(sf::Vector2f(160.f, 200.f),
                       sf::Vector2f(120.f, 160.f));
    edges.emplace_back(sf::Vector2f(120.f, 160.f),
                       sf::Vector2f(160.f, 120.f));

    // main loop
    while(w.isOpen())
    {
        sf::Event e;
        while( w.pollEvent(e) )
        {
            if(e.type == sf::Event::Closed)
            {
                w.close();
            }
            else if (e.type == sf::Event::MouseMoved)
            {
                sf::Vector2f mp(sf::Mouse::getPosition(w));
                light.setPosition(mp);
                light.castLight(edges.begin(), edges.end());
            }
        }

        fog.clear();
        fog.draw(light);
        fog.display();

        w.clear(sf::Color(255,255,255));
        w.draw(fog);
        w.display();
    }
    return 0;
}

@MiguelMJ
Copy link
Owner

I will try to reproduce the bug to find the error, when I have some time this week. I will keep you updated, thanks for reporting the issue.

@MiguelMJ MiguelMJ added bug Something isn't working help wanted labels Oct 14, 2021
@MiguelMJ MiguelMJ pinned this issue Oct 14, 2021
@MiguelMJ
Copy link
Owner

@all-contributors please add @JonathSpirit for bug report and testing.

@allcontributors
Copy link
Contributor

@MiguelMJ

I've put up a pull request to add @JonathSpirit! 🎉

@JonathSpirit
Copy link
Contributor Author

First of all, I really like this library I think it have a good potential and working with libs SFML is just so simpler, but I really think that there is a lack of "comprehension" in code syntax like nearly no comments, poor variable name and I think we can optimize 2 or 3 things.

I'm gonna try to learn how RadialLight works for now and maybe propose eventual change in the code.

A first weird thing is abnormal number of vertex count for this light :
testVertex

@JonathSpirit
Copy link
Contributor Author

JonathSpirit commented Oct 14, 2021

Another weird glitch :

image

I print in the console every calculated minimum distance on every lines (4 lines). Not only there is a distance of 0 where my mouse is clearly far from them, but a weird white line appear when there is a distance of 0.

edit : (my mouse is not visible in this screenshot but it's on the isolated red circle)
edit 2 : I just remembered math 😩 so the distance of 0 is normal but the glitch still not

@JonathSpirit
Copy link
Contributor Author

In RadialLight.cpp, in RadialLight::castLight :

        for(auto it = begin; it != end; it++){
            auto& s = *it;
            float d1 = s.distance(castPoint);
            std::cout << "distance : " << d1 << std::endl;
            // float d2 = sfu::magnitude(s.m_origin - castPoint);
            // float d3 = sfu::magnitude(s.point(1.f) - castPoint);
            // if(std::max(std::min(d2, d3), d1) <= m_range*std::sqrt(2)){
            if(d1 <= m_range){
                sfu::Line r1(castPoint, s.m_origin);
                sfu::Line r2(castPoint, s.point(1.f));
                float a1 = sfu::angle(r1.m_direction);
                float a2 = sfu::angle(r2.m_direction);
                if(angleInBeam(a1)){
                    rays.push_back(r1);
                    rays.emplace_back(castPoint, a1 - off);
                    rays.emplace_back(castPoint, a1 + off);
                }
                if(angleInBeam(a2)){
                    rays.push_back(r2);
                    rays.emplace_back(castPoint, a2 - off);
                    rays.emplace_back(castPoint, a2 + off);
                }
            }
        }

Here you calculate the distance between every line for (correct me if I'm wrong) avoiding extra ray cast when the line is out of range, but I think that the returned distance from the function Line::distance is not what we want.

My cool paint :) :
image

What we should do is calculating the minimum distance between the cast position and the start/end position of the line and return the smallest of the 2 like this :

    float Line::distance(const sf::Vector2f& point) const{
        sf::Vector2f vec = m_origin - point;
        float distance1 = std::sqrt(vec.x*vec.x + vec.y*vec.y);
        vec = m_direction + m_origin - point;  //<-- getting the second point of the line
        float distance2 = std::sqrt(vec.x*vec.x + vec.y*vec.y);

        return (distance1 < distance2) ? distance1 : distance2;
    }

Before :
before

After (vertex count is still high (another problem to fix) but now if we are to far the count is dropped significantly) :
after

@MiguelMJ
Copy link
Owner

MiguelMJ commented Oct 14, 2021

First of all, I'm glad you like the project and I'm so thankful that you are interested in it. I made the library literally out of a project for personal learning about raycasting (with a very basic knowledge on this kind of topics) that I originally didn't mean to share, but somehow scalated to this. So, I'm aware of that sort of problems in the code (I still cringe at some design decisions I didn't think through enogh). I would love to have more time to maintain and improve it, but that's just not possible right now. This kind of contributions are the only way for it to grow in this moment.

Let's see. First of all, you suppose right. the RadialLight tries to filter out far away edges. The issue with the calculation of the nearest point is in fact something I mentioned in the contributing guidelines, so I'm happy to see that you realized quickly about it. In fact, your version of the distance calculation is what the code does in the commented part of the snippet you shared.

// float d2 = sfu::magnitude(s.m_origin - castPoint);
// float d3 = sfu::magnitude(s.point(1.f) - castPoint);
// if(std::max(std::min(d2, d3), d1) <= m_range*std::sqrt(2)){

The problem with that approach are large edges, you can test it. They are ignored when the start and end points are not in range even though if the line itself is.
image

diagram to show difference between casting against a small and a large edge

Thanks again 😄

edit: make image smaller

@MiguelMJ
Copy link
Owner

Also, one of the pending issues in Candle is the lack of documentation for developers. So there's something you find useful to know while modifying the code, feel free to write it down and I will include it when I get to do it.

@JonathSpirit
Copy link
Contributor Author

JonathSpirit commented Oct 14, 2021

what about taking the globalBounds rectangle of the line and the light and just do some "contains" check ?

image

I think this can work 🤔

@MiguelMJ
Copy link
Owner

Good idea.
I hadn't thought about that. Tilted edges would have bigger rectangles that would "colide" with lights that don't really touch the edges, but actually I think it is still better than the current aproach. Both leave unfiltered edges, but this one wouldn't leave as much.
case where the light doesn't touch the edge although the rectangles collide


By the way:

but a weird white line appear when there is a distance of 0.

I think I know why this happens. A light casts rays towards the start and end point of each segment; so if the distance is 0 (the point is contained in the same line as the segment) the rays casted will have the exact same direction and more than one triangle will be drawn in the same space. Maybe this could be prevented filtering out rays with the exact same direction after sorting them (somewhere around line 205).
example of rays overlapping

@MiguelMJ
Copy link
Owner

And thinking about the original issue

weird shadow snap appear and make it uncomfortable to see

I've noticed that it happens when the ray is horizontal. I'm not sure that this has something to do, but the error might be related with the function module360 in line 54.

About the problem with

but when I add this flag, my window appear but the "isOpen()" function return false and the program just shut. That a really weird behaviour and I don't really know if I skip a step here

Maybe you could try also adding the flag -DRADIAL_LIGHT_FIX (see #10) and see if that helps.

@JonathSpirit
Copy link
Contributor Author

I developed a little demo for the rect :
rect

@JonathSpirit
Copy link
Contributor Author

I've noticed that it happens when the ray is horizontal. I'm not sure that this has something to do, but the error might be related with the function module360 in line 54.

Maybe you could try also adding the flag -DRADIAL_LIGHT_FIX (see #10) and see if that helps.

Gonna check that

@JonathSpirit
Copy link
Contributor Author

I developed a little demo for the rect : rect

If your ok with this new method can I try to pull request it ?
(I should have created this in another issue but there is so much to speak about 😃 )

@MiguelMJ
Copy link
Owner

Of course, make the PR.

@MiguelMJ
Copy link
Owner

@all-contributors please add @JonathSpirit for code and ideas

@allcontributors
Copy link
Contributor

@MiguelMJ

I've put up a pull request to add @JonathSpirit! 🎉

@JonathSpirit
Copy link
Contributor Author

fixed

I think I correctly fixed it, this is due to the calculation in the intersection function

just waiting for #24 to be merged to be able to work on the dev branch

@JonathSpirit
Copy link
Contributor Author

(this fixed the weird white line glitch too)

@MiguelMJ
Copy link
Owner

Of course, tomorrow I'll do the merge. Thanks a lot!

@MiguelMJ
Copy link
Owner

Fixed in #25

@MiguelMJ MiguelMJ unpinned this issue Oct 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants