AR-js-org / AR.js

Image tracking, Location Based AR, Marker tracking. All on the Web.
MIT License
5.43k stars 925 forks source link

[location-based]: <a-camera> near and far clip planes not working as expected #110

Closed nickw1 closed 4 years ago

nickw1 commented 4 years ago

Do you want to request a feature or report a bug? Possible bug.

What is the current behavior? An a-camera is created with the far clipping plane set to 5000 WebGL units (metres), and the near plane set to 0.1 units. Objects seem to always disappear when you move around 500-1000 units away from them - no matter what the value of the far clipping plane is.

If the current behavior is a bug, please provide the steps to reproduce.

See example at

https://hikar.org/webapp/test/clipPlane.html

WASD-controls are enabled so you can move around the scene. By default you look north, you can see ana-text 0.5km (500 units) north (towards -z) from the origin. You should also be able to see another a-text1km (1000 units) north of the origin, due to the far clipping plane value of 5000, however it only comes into view if you move 'north' for a short distance (press W).

These are simple a-texts with position set using the position attribute. The same behaviour occurs if gps-entity-places with latitude and longitude are used. Also, the same behaviour occurs with either gps-camera or gps-projected-camera.

Possibly related to #52? However I do set the logarithmicDepthBuffer to true as suggested.

(Same behaviour occurs with polylines - roads and paths - in my Hikar webapp demo: https://hikar.org/webapp/?lat=51.049&lon=-0.723, z-flghting type flickering and polylines beyond 0.5km - 1km or so cannot be seen)

Please mention other relevant information such as the browser version, Operating System and Device Name Browser: Firefox 75.0 or Chrome 81.0 on Ubuntu 18.04 (same behaviour).

What is the expected behavior? I would expect to see the a-text 1km north.

If this is a feature request, what is motivation or use case for changing the behavior?

nicolocarpignoli commented 4 years ago

are you able to see them using this => https://github.com/aframevr/aframe-inspector ?

edit: also, have you tried giving them a very high scaling?

nickw1 commented 4 years ago

Yes - they all appear in the A-frame Inspector, and are all rendered into the A-Frame Inspector scene as I would expect, without the issues I have described here.

If I increase the scaling from 100 to 1000 they're visible a little further away (e.g. the 1km north entity is visible just to the south of the origin) but not much, and I still get a z-fighting type effect as they transition between being visible and invisible.

nicolocarpignoli commented 4 years ago

do you have added the 'look-at' custom component to each entity?

nicolocarpignoli commented 4 years ago

anyway, it's this very same bug I think: https://github.com/AR-js-org/AR.js/issues/30 Original issue at: https://github.com/jeromeetienne/AR.js/issues/683

nickw1 commented 4 years ago

Ah, sorry, must have missed that one. Yes, it looks the same issue. Maybe it's something to do with the way the camera feed is being rendered, the camera feed is conflicting with objects some distance away? (BTW I did add look-at).

nickw1 commented 4 years ago

To follow up, I have just had a quick look through the source to try and find the webcam code -- it's triggered from ARjs.Source._initSourceWebcam() in three.js/src/threex/threex-artoolkitsource.js. This looks like it simply renders a camera feed onto the screen; it doesn't try to use WebGL to render the feed.

It looks also like an alternative approach, rendering the webcam into a WebGL texture, has been attempted but is never actually called: see ./three.js/src/threex/threex-arvideoinwebgl.js; there's an ArVideoInWebgl() method which takes a WebGL texture as a parameter.

I am wondering if this is the best approach to take? In other words, stream the camera feed into a WebGL texture, draw two unprojected triangles covering the whole of the screen, and texture them using the texture containing the camera feed. This is the recommended approach in an Android OpenGL ES environment, and is the approach I've taken in my (Android) Hikar app. It works fine without any z-fighting issues or unexpected invisibility. Not sure how easy it is to do this in JavaScript but I will take a look; I'd imagine three.js and/or A-Frame might make this fairly easy to do?

EDIT:

https://github.com/willwnekowicz/aframe-passthrough

or

https://github.com/sachaa/aframe-webcam-component could be starting points, though neither have been updated in a while.

I am quite happy to work on fixing this assuming I have time.

jamess922 commented 4 years ago

Hi guys What is the accuracy of the location-based AR could get ,like how many i need to move to see the position of image or model change? I walk 1 meter towards the target,could i really see in the cellphone that i get 1 meter closer to the target

nickw1 commented 4 years ago

Hi jamess922, you should be able to see a noticeable difference as you approach the target. Do bear in mind that GPS accuracy might cause issues if you're very close to a target (sometimes its accuracy is only 6m or so) but in theory it should work fine. BTW the best place to ask general questions (as opposed to bug reporting/feature requests) is the Gitter chat room: https://gitter.im/AR-js/Lobby, or on Stack Overflow.

nicolocarpignoli commented 4 years ago

@nickw1 can we close this? I merged the PR on master

nickw1 commented 4 years ago

Yes, will do!

k7n4n5t3w4rt commented 4 years ago

Thanks for your amazing work. I'm delighted to see that this issue I've been experiencing is fixed. Should it be available in this version now?

<script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar-nft.js"></script>`

UPDATE: Ah, I see from the pull request that it requires the videoTexture: true; property for the arjs attribute of the <a-scene>

    <a-scene
      vr-mode-ui="enabled: false"
      embedded
      arjs="sourceType: webcam; debugUIEnabled: false; videoTexture: true;"
    >
nicolocarpignoli commented 3 years ago

@WebandMobileMaster the code is correct. I see that problem before on iOS and other devices. I do not know honestly the cause or the solution: but you can try to add the entities using javascript and not HTML. This is an example (in the .js file, look only for the "static" load places, not dynamic one, which is using external APIs).

The problem is with events cycle while adding entities with HTML. Instead, I got no error loading them with JS.

Anyway, It is strange as only some users face this (I do not encounter this problem with android nor ios).

nicolocarpignoli commented 3 years ago

Yes I think it is a known bug: https://github.com/AR-js-org/studio/issues/107

Have no time to look into that, maybe @nickw1 can but I think he's pretty busy with new AR.js release.

nickw1 commented 3 years ago

@nicolocarpignoli a little busy at the moment unfortunately, yes, so I may not have the time. @WebandMobileMaster if you try with an <a-box> rather than an image does it work? And remove the look-at component? Wondering whether there is indeed a bug with the southern hemisphere, but if you try with an <a-box> then you're working with the simplest possible primitive.

Specifically does this example work if you set x to your longitude and y to your latitude? If so you should see two boxes a short distance to your north.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>GeoAR.js demo</title>
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
    <script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar-nft.js"></script>
  </head>

  <body style="margin: 0; overflow: hidden;">
    <a-scene
      vr-mode-ui="enabled: false"
      embedded
      arjs="sourceType: webcam; debugUIEnabled: false;"
    >
      <a-box 
        material="color: yellow"
        scale="10 10 10"
        gps-entity-place="longitude: x-0.0005; latitude: y+0.0006;"
      ></a-box>
      <a-box 
        material="color: red"
        scale="10 10 10"
        gps-entity-place="longitude: x-0.0001; latitude: y+0.0004;"
      ></a-box>
      <a-camera gps-camera rotation-reader> </a-camera>
    </a-scene>
  </body>
</html>
nickw1 commented 3 years ago

@WebandMobileMaster note I have edited the example to fix a couple of typos, please make sure you look at the example on the issue page, not via email.