google-ar / sceneform-android-sdk

Sceneform SDK for Android
https://developers.google.com/sceneform/develop/
Apache License 2.0
1.23k stars 604 forks source link

ViewRenderable shows outdated texture for couple of frames #632

Open alexey-pelykh opened 5 years ago

alexey-pelykh commented 5 years ago

Creating a ViewRenderable view let's say TextView with object name and adding it to the scene when object is selected and removed from scene when object is deselected. Then reusing same renderable with different text during next object selection would cause old content being presented for some time until new texture would be available.

This as well causes issue of camera image (since it's another external texture I guess) being rendered until first texture of ViewRenderable is ready.

alexey-pelykh commented 5 years ago

Reviewing this code in Sceneform SDK lead me to a conclusion that viewTexture is being set only after texture has been prepared and is not initialized with anything else, while renderable material still uses this samplerExternal that can cause visual artifacts?

    void prepareForDraw() {
        if (!this.getId().isEmpty()) {
            ViewRenderableInternalData data = (ViewRenderableInternalData)Preconditions.checkNotNull(this.viewRenderableData);
            RenderViewToExternalTexture renderViewToExternalTexture = data.getRenderView();
            if (renderViewToExternalTexture.isAttachedToWindow() && renderViewToExternalTexture.isLaidOut()) {
                boolean hasDrawnToSurfaceTexture = renderViewToExternalTexture.hasDrawnToSurfaceTexture();
                if (hasDrawnToSurfaceTexture) {
                    if (!this.isInitialized) {
                        this.getMaterial().setExternalTexture("viewTexture", renderViewToExternalTexture.getExternalTexture());
                        this.updateSuggestedCollisionShape();
                        this.isInitialized = true;
                    }

                    if (this.renderer != null && this.renderer.isFrontFaceWindingInverted()) {
                        this.getMaterial().setFloat2("offsetUv", 1.0F, 0.0F);
                    }

                    super.prepareForDraw();
                }
            }
        }
    }

Is there a way to control if Renderable is not being actually rendered unless texture is ready and/or updated?

alexey-pelykh commented 5 years ago

Also this causes issue on first frame where ViewRenderable is being rendered:

Frame 1 > Draw 1 Clears the FB with black color Frame 1 > Draw 2 Draws the camera texture using following calls: image Frame 1 > Draw 3 image A ViewRenderable is rendered, without having own texture being set (since it's not yet ready)

Thus reusing already set texture from the camera.

brako commented 4 years ago

Hello, Any update on this? I have exactly the same problem. The first time I display a ViewRenderable, it shows some drawing cache for half a second before the view is rendered.

Thanks