-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
[core] Very low rendering quality on 4K displays on PLATFORM_WEB
#3372
Comments
@ubkp I would gladly test it but I don't know what you mean by using
The file #output {
width: 100%;
height: 200px;
... Commenting out |
@ypujante When compiling with Option 1. Go to the Option 2. Open your Edit: Option 3. Go to the |
I used option 2 (the options is The result is the same. No difference at all |
@ypujante Do you have this case on a repository or branch that I could download to test? |
Here is the (self contained) project with instructions to build in # build instructions
# mkdir build
# cd build
# cmake .. -DCMAKE_TOOLCHAIN_FILE=/usr/local/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DPLATFORM=Web -DCMAKE_BUILD_TYPE=Debug
# cmake --build . --target raylib_web_cmake Make sure to replace |
Also for the record, I just swapped the embedded raylib (self contained in the project) with master as of this morning. There is no difference. |
@ypujante Okay. I'm rebuilding emscripten here to test. |
@ypujante Thanks for the Unfortunately, I was not able to replicate the issue. Tested it here right now on Firefox (111.0.1 64-bit) and Chromium (117.0.5938.132 64-bit) both running on Linux (Fedora 38 64-bit) and it appears to be rendering correctly for me on both: |
Thank you for testing. Are you on a 4K monitor? I have tested only on Windows and macOS with 4K monitors. Both have the issue. Here is my build in case you want to try it as well (in case it is a build problem) |
@ypujante I tested it on a Tried testing your |
Not sure why .data is required but here it is: |
I also uploaded my "real" test (note that it is 20MB: https://github.com/pongasoft/re-edit/releases/download/v1.6.2/RE-Edit-wasm.tgz). It contains 3 files (note that there is a space in the filename which needs to be converted to %20 when you generate the URL: RE%20Edit.html) This generates the output as seen in the screenshot on my first post |
@ypujante The Here are my results for I really can't notice the edges issue (but that could be my bad eyesight). But by your zoom photos it could be another of those |
Since you have the source code you could also build the native version and compare side by side... |
@ypujante Sure, just a moment to check the HTML/CSS. Just to be sure it's not messing the render. |
@ypujante I trimmed the And it with a My best guess is that this could be another Edit: compiled native on Linux (Fedora 38 64-bit): |
@ypujante @ubkp I'm afraid it could be related to platform/OS/drivers, not sure if it can be controlled from raylib side, or at least I have no idea what it could be related. |
@ypujante This looks fairly close to the problem: |
@ypujante You were on the right track. Following and adapting this tutorial I think these could be the results you're looking for:
|
Thank you for the follow up. So indeed, looking at the more "official" documentation about devicePixelRatio shows the same kind of example. But clearly This entirely fixes the blurry rendering of my "Canvas" entry in my previous example: console.log("window.devicePixelRatio=" + window.devicePixelRatio);
const canvas = document.getElementById('c2d');
var currentWidth = canvas.width;
var currentHeight = canvas.height;
canvas.style.width = currentWidth + "px";
canvas.style.height = currentHeight + "px";
const scale = window.devicePixelRatio;
canvas.width = Math.floor(currentWidth * scale);
canvas.height = Math.floor(currentHeight * scale);
const ctx = canvas.getContext('2d');
ctx.scale(scale, scale);
ctx.font = "27px 'Jetbrains Mono'";
ctx.fillText("The quick brown fox jumps over the lazy dog", 10, 50);
const logo = document.getElementById('logo');
ctx.drawImage(logo, 10, 10, 64, 64); Both the logo and the text are now as sharp as the "Browser" section. Trying to apply a similar modification to the raylib section unfortunately fails with the following errors
Going to investigate this failure further... |
I modified createContext(canvas, useWebGL, setInModule, webGLContextAttributes) {
if (useWebGL && Module.ctx && canvas == Module.canvas) return Module.ctx;
var ctx;
var contextHandle;
if (useWebGL) {
var contextAttributes = {
antialias: false,
alpha: false,
majorVersion: 1
};
if (webGLContextAttributes) {
for (var attribute in webGLContextAttributes) {
contextAttributes[attribute] = webGLContextAttributes[attribute];
}
}
if (typeof GL != "undefined") {
contextHandle = GL.createContext(canvas, contextAttributes);
if (contextHandle) {
ctx = GL.getContext(contextHandle).GLctx;
}
}
} else {
ctx = canvas.getContext("2d");
}
if (!ctx) return null;
if (setInModule) {
if (!useWebGL) assert(typeof GLctx == "undefined", "cannot set in module if GLctx is used, but we are a non-GL context that would replace it");
Module.ctx = ctx;
if (useWebGL) GL.makeContextCurrent(contextHandle);
Module.useWebGL = useWebGL;
Browser.moduleContextCreatedCallbacks.forEach(callback => callback());
Browser.init();
}
return ctx;
}, and the line Not knowing this code (nor even if this code comes from raylib / glfw or emscripten) I do not know what is the relationship between |
@ypujante I don't have access to a compiler right now to test it, but my first try would be setting the devicePixelRatio and canvas fix exactly one line before the canvas initialization by raylib. To be specific, on your shell file, something like this:
|
As I mentioned, It is not working either, because as soon as you do I am going to see if I can do it after the fact using |
The context created is of type |
@ypujante I'm not sure if much can be done on raylib side, it looks like scaling is managed by browser, display and drivers. |
Having a larger canvas and shrinking it via CSS to the browser-width is how high-dpi is handled for most browser-games. GetScreenToWorld2D(GetMousePosition(), camera); |
@ypujante you can use The WebGPU solution could be maybe applied in raylib? @niorad thanks for the additional info! Making the canvas double size could imply an important performance-hit. |
@raysan5 it's true that The WebGPU solution is essentially what I have been trying to do all along and I am working (or at least trying to) work on a solution that would involve implementing these changes in emscripten with a flag to turn it on/off so that the glfw layer does the right thing (scale framebuffer 2x, return mouse coordinates in 1x coordinates). I believe this might require a couple tweaks to raylib once the glfw layer is implemented as there are some assumptions that would not be correct anymore. If I am successful with my changes in emscripten (and they get accepted/integrated), I will submit a PR for raylib as well... |
I have some very good news. I was able to change the emscript layer and raylib layer (some tweaks required for the web platform) so that 4k/retina is supported. The only change from a user point of view is to add a Here is the proof of concept: You must use Chrome as webgpu is not supported by any other browser as far as I know. If you are not on a 4k/retina display then the 2 links will render the same thing. Also dragging the browser window from a 4k screen to a 2k screen (and vice versa) also works perfectly :) Here are the 2 different outputs: Now I need to work with emscript people to see if my changes can be integrated. And if that happens, then I will need to see how to have my changes integrated with raylib hopefully... |
@ypujante thank you very much for investigating this improvement, keep us updated! I'll keep the issue open in the meantime. |
PLATFORM_WEB
As an FYI, I created the pull request for emscripten . The pull request contains 2 more live demos with dynamic switching between 2k/4k (no need to reload the page with a different query string) if you are interested. They demonstrate how to have the canvas taking the fullscreen and resizing as the window gets resized, or have the canvas have a static size (while still allowing for fullscreen rendering which removes the shell). 2 very different code paths which were not easy to both get working... |
@ypujante thanks for the further investigation and the results! It seems the PR is progressing in emscripten side, hopefully it will be merged soon! I think we can close this PR for now as the issue has moved out of raylib. Let me know if that's ok for you, I can reopen it if required. Thank you very much again for all your time and deep investigation of this issue, amazing work! :) |
Technically there are changes that need to happen in raylib as well. I can't issue a PR yet until the changes are integrated into emscripten. |
@ypujante Ok, no problem! Reopening! 😄 |
@raysan5 I am still waiting for the emscripten pull request to be merged but I wanted to let you know that I have forked and pushed the changes required for raylib on my fork In case you are interested to integrate them prior to emscripten changes since it is 100% backward compatible:
Let me know if you want me to create a pull request for it or you still prefer to wait. I am fine either way (but consider revisiting the |
@ypujante Feel free to open a PR for review and further discusdion. |
Closing this issue for now. When/if emscripten changes are merged I might reopen it/revisit it. |
I think the amount of changes and integration cost could be smaller when emscripten merges those reviews... |
@raysan5 I want to apologize for taking more of your time. I just wanted to follow up on your comments about the fact that whenever changes are made you "inherit" the burden of having to understand and maintain it after the fact. I think with the tremendous work on splitting per platform as was accomplished, this opens up the road for user contributed platforms that you do not own/maintain. I am not sure if this is something that is already possible or if you are thinking about it for the future, but maybe something to consider. In this specific instance, if there was a way for me to offer a Essentially a platform plugin sort of thing. How that would be implemented in raylib, or even if it is possible or a direction you would consider is obviously not for me to decide. This is just food for thoughts at this stage. Thank you |
Hi @ypujante, I also want to apologize, I know you put a lot of work and time into this issue and the PR was rejected quite abruptly. At this moment I'm quite overloaded with raylib 5.0 release but after it and Emscripten update, those improvements could be reviewed again if you wish.
Yes. The platform-split is really new and that's one of the objectives: allowing the addition of custom platform backends; actually I'm already aware of some users working on that line and even yesterday @ubkp proposed the addition of As commented on previous posts, it would be great a Note that there is already a As a said, this platform-split redesign is a big change for raylib and I don't know what could be the implications for the future of the library, hopefully it is for good. Thanks again for your time and the work put in raylib. |
@raysan5 what is the proper way for starting a discussion about the topic of using low level emscripten apis (Browser) vs glfw. A github issue? Or a github discussion? And obviously this is not urgent and can wait until you are done with 5.0 release... Just want to create the starting point in order to keep track of it/not forget about it... |
@ypujante I think a GitHub Issue is the best option... |
@raysan5 I just wanted to let you know that my changes in emscripten that are necessary to address this issue are now available in the latest emscripten released yesterday: 3.1.51. From the Changelog:
If you, or anybody else want to make the necessary changes in raylib to be able address this "issue" (or another way to look at it is "enhance raylib to support hi dpi on the web platform") you can now do so. On my side, given the borderline hostile feedback I have received (both on Discord and github) every time I have tried to contribute in making the project better (albeit not by you, but by others), I have decided that I am no longer be contributing to this project directly and I am going to follow the guidance you provided in your comment and simply create my own fork/platform to do this (and future) work. |
NOTE: The code is commented until the build system gets updated to latest emscripten.
Oh! That's great! Thanks you very much for working on this improvement and pushing it to emscripten. I added
I'm really sorry to read that. I never pretended to make you feel unconfortable contributing to raylib project, I always try to be friendly and respectful with all contributors and I sincerely appreciate a lot all the work put on any contribution. I know community could be a bit harsh (specially Discord) but I also think communication could be difficult though those platforms and some words could sound worse than the real feeling behind it. Personally, English is not my first language and sometimes it's difficult for me to find the proper words to not sound rude. In any case, I'm sorry again you leave the project with this feeling, you will be always welcome to contribute again when you want. |
It won't be enough. You also need to use I am currently working on a full blown c++/emscripten port of glfw3 and for my tests I use OpenGL directly and this is the code I have: glfwMakeContextCurrent(fWindow);
glClearColor(fBgRed, fBgGreen, fBgBlue, fBgAlpha);
int width = 0, height = 0;
glfwGetFramebufferSize(fWindow, &width, &height);
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); The real critical part is that the viewport needs to be set with the values coming from
As I pointed out in my comment, you are not the one who have made me feel uncomfortable. |
NOTE: The code is commented until the build system gets updated to latest emscripten.
I have been trying to port my application RE Edit which is a raylib/ImGui application to the web platform to offer a demo (since there is no filesystem access available I cannot really run it in a browser until it is available in wasm...)
I have a prototype running and it looks quite bad:
I have created a small reproducible test case to show the issue which uses raylib only (top is web, bottom is native):
The source code for the test case is this:
Is this a bug in raylib? A bug in glfw3? Or a misconfiguration? I have followed the steps described here but there isn't any mention of the quality of the rendering nor how to make it look better on 4K displays.
The text was updated successfully, but these errors were encountered: