简体   繁体   English

如何在threejs和PyQt app中使背景透明?

[英]how to make background transparent in threejs and PyQt app?

I'm using threejs to show some 3D objects in my PyQt application.我正在使用 threejs 在我的 PyQt 应用程序中显示一些 3D 对象。 After a little searching, I was able to display a cube.经过一番搜索,我能够显示一个立方体。 What I want to do is remove the background from the scene, that is, make it transparent so that we can see the blue color that is set as the background color for the app.我想要做的是从场景中删除背景,即使其透明,以便我们可以看到设置为应用程序背景颜色的蓝色。 I have no idea how I should do this.我不知道我应该怎么做。 Please help.请帮忙。

main.py主程序

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineCore import *
from PyQt5.QtWebEngineWidgets import *
import sys

class QtSchemeHandler(QWebEngineUrlSchemeHandler):
    def requestStarted(self, job):
        request_url = job.requestUrl()
        request_path = request_url.path()
        file = QFile('.' + request_path)
        file.setParent(job)
        job.destroyed.connect(file.deleteLater)
        file_info = QFileInfo(file)
        mime_database = QMimeDatabase()
        mime_type = mime_database.mimeTypeForFile(file_info)
        job.reply(mime_type.name().encode(), file)


class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setStyleSheet('background-color: blue;')
        self.verticalLayout = QVBoxLayout()
        self.setLayout(self.verticalLayout)
        self.browser = QWebEngineView()
        self.scheme_handler = QtSchemeHandler()
        self.browser.page().profile().installUrlSchemeHandler(
            b"qt", self.scheme_handler
        )
        url = QUrl("qt://main")
        url.setPath("/index.html")
        self.browser.load(url)
        self.verticalLayout.addWidget(self.browser)
        self.browser.loadFinished.connect(self.show)


if __name__ == "__main__":
    scheme = QWebEngineUrlScheme(b"qt")
    scheme.setFlags(QWebEngineUrlScheme.CorsEnabled)
    QWebEngineUrlScheme.registerScheme(scheme)
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec_())

index.html index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three js earth</title>
    <style>
        body{
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>

<body>
    
    <canvas class="webgl"></canvas>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js" integrity="sha512-dLxUelApnYxpLt6K2iomGngnHO83iUvZytA3YjDUCjT0HDOHKXnVYdf3hU4JjM8uEhxf9nD1/ey98U3t2vZ0qQ==" crossorigin="anonymous"></script>
    <script type="module">
        
        const canvas = document.querySelector('.webgl');

        // scene setup
        const scene = new THREE.Scene();

        // camera setup
        const fov = 60;
        const aspect = window.innerWidth / window.innerHeight;
        const near = 0.1;
        const far = 10;
        const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
        camera.position.set(0, 0, 3)
        scene.add(camera);
 
        // renderer setup
        const renderer = new THREE.WebGLRenderer({canvas: canvas, antialias: true});

        // 3D Object
        const geometry = new THREE.BoxGeometry(1, 1, 1);
        const material = new THREE.MeshPhongMaterial({color: 0xFF0000});
        const cube = new THREE.Mesh(geometry, material);
        scene.add(cube);

        // point light
        const pointLight = new THREE.PointLight(0xffffff, 1)
        pointLight.position.set(0, 0, 5);
        scene.add(pointLight);

        // handling resizing
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
            render();
        }, false);

        // main loop
        function render(time) {
            cube.rotation.x -= 0.005;
            cube.rotation.y -= 0.005;
            renderer.render(scene, camera);
            requestAnimationFrame(render);
        }
        render();

  </script>
</body>

</html>

First, set the QWebEngineView 's page to have a transparent background.首先,将QWebEngineViewpage设置为透明背景。

In main.py :main.py

    ...
    self.scheme_handler = QtSchemeHandler()
+++ self.browser.page().setBackgroundColor(Qt.GlobalColor.transparent)      
    self.browser.page().profile().installUrlSchemeHandler(
      b"qt", self.scheme_handler
    )
    ...

Then, set the HTML page's background to transparent.然后,将 HTML 页面的背景设置为透明。

In index.html :index.html

    ...
    <style>
      body{
        margin: 0;
        overflow: hidden;
+++     background: rgba(0, 0, 0, 0);
      }
    </style>
    ...

And finally, set the Three.js WebGLRenderer to use a transparent background.最后,将 Three.js WebGLRenderer设置为使用透明背景。

Still in index.html :仍在index.html中:

    // renderer setup
    const renderer = new THREE.WebGLRenderer({
      canvas: canvas, 
      antialias: true, 
+++   alpha: true
    });

显示透明背景的屏幕截图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM