【问题标题】:Three.js - Fisheye effectThree.js - 鱼眼效果
【发布时间】:2012-11-01 20:59:55
【问题描述】:

所以,我搞砸了three.js,效果很好。我唯一想不通的是如何制作具有真正鱼眼效果的相机。

这怎么可能? camera.setLens()?

【问题讨论】:

  • 你得到答案了吗?

标签: camera three.js fisheye


【解决方案1】:

可以通过高视野获得鱼眼效果。

            var fishCamera = new THREE.PerspectiveCamera( 110, window.innerWidth / window.innerHeight, 1, 1100 );
            var normalCamera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1100 );

或设置

camera.fov = 110 
camera.updateProjectionMatrix();

此处的实时示例: http://mrdoob.github.com/three.js/examples/canvas_geometry_panorama_fisheye.html

【讨论】:

    【解决方案2】:

    一种方法是在相机上设置大视野:

    new THREE.PerspectiveCamera(140, ... )
    

    这在技术上不是鱼眼效果,但它可能是您正在寻找的效果。

    在真正的相机镜头中,获得大视场且不失真可能会使镜头变得相当昂贵,但在计算机图形学中,这是一种简单的方法。

    一个真实的fisheye lens 扭曲了图像,使直线变得弯曲,就像这张图片:

    如果你想用这种扭曲创建一个实际的鱼眼效果,你必须修改几何,如Three.js's fisheye example。在该示例中,几何体实际上是预先修改的,但对于更高级的场景,您可能需要使用顶点着色器来动态更新顶点。

    【讨论】:

    • 我尝试使用 setLens 和/或更改视角,但效果不如预期。我将尝试更具体地解决这个问题,以便要求一个好的答案:所以,我的物理设置如下:投影仪在球体内投影,投影仪上连接着一个真正的鱼眼镜头。所需软件:真正的问题是,我要投影的图像/3d 场景需要显示为鱼眼,以获得满意的效果。 Microsoft 已经完成了这方面的示例:youtube.com/watch?v=-YLdYlN6FhI&feature=related
    【解决方案3】:

    将相机放在反射球内。确保球体是双面的。如果要在场景中移动相机和球体,请将其作为父级。像魅力一样工作:

    http://tileableart.com/code/NOCosmos/test.html

    借自:

    http://mrdoob.github.io/three.js/examples/webgl_materials_cubemap_dynamic2.html

    cubeCamera = new THREE.CubeCamera( 1, 3000, 1024);
                cubeCamera.renderTarget.minFilter = THREE.LinearMipMapLinearFilter;
    scene.add( cubeCamera );
    camParent.add(cubeCamera);
    var material = new THREE.MeshBasicMaterial( { envMap: cubeCamera.renderTarget } );
    material.side = THREE.DoubleSide;
    sphere = new THREE.Mesh( new THREE.SphereGeometry( 2, 60, 30 ), material );
    

    【讨论】:

      【解决方案4】:

      广角镜头的焦距通常很短。

      要实现超广角,我们需要缩短焦距。

      请注意,鱼眼镜头是超广角镜头。

      要缩短焦距(或实现超广角),只需增加 FOV(视野),因为 FOV 与焦距成反比。

      示例:

      var camera_1 = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );
      
      var camera_2 = new THREE.PerspectiveCamera( 80, width / height, 1, 1000 );
      

      这里的 camera_2 是一个更广的角度设置。

      注意

      要达到预期的效果,可能需要调整相机位置。

      【讨论】:

        【解决方案5】:

        使用 Giliam de Carpentier 的镜头失真着色器可以实现鱼眼效果。

        着色器代码:

        function getDistortionShaderDefinition()
        {
            return {
        
                uniforms: {
                    "tDiffuse":         { type: "t", value: null },
                    "strength":         { type: "f", value: 0 },
                    "height":           { type: "f", value: 1 },
                    "aspectRatio":      { type: "f", value: 1 },
                    "cylindricalRatio": { type: "f", value: 1 }
                },
        
                vertexShader: [
                    "uniform float strength;",          // s: 0 = perspective, 1 = stereographic
                    "uniform float height;",            // h: tan(verticalFOVInRadians / 2)
                    "uniform float aspectRatio;",       // a: screenWidth / screenHeight
                    "uniform float cylindricalRatio;",  // c: cylindrical distortion ratio. 1 = spherical
        
                    "varying vec3 vUV;",                // output to interpolate over screen
                    "varying vec2 vUVDot;",             // output to interpolate over screen
        
                    "void main() {",
                        "gl_Position = projectionMatrix * (modelViewMatrix * vec4(position, 1.0));",
        
                        "float scaledHeight = strength * height;",
                        "float cylAspectRatio = aspectRatio * cylindricalRatio;",
                        "float aspectDiagSq = aspectRatio * aspectRatio + 1.0;",
                        "float diagSq = scaledHeight * scaledHeight * aspectDiagSq;",
                        "vec2 signedUV = (2.0 * uv + vec2(-1.0, -1.0));",
        
                        "float z = 0.5 * sqrt(diagSq + 1.0) + 0.5;",
                        "float ny = (z - 1.0) / (cylAspectRatio * cylAspectRatio + 1.0);",
        
                        "vUVDot = sqrt(ny) * vec2(cylAspectRatio, 1.0) * signedUV;",
                        "vUV = vec3(0.5, 0.5, 1.0) * z + vec3(-0.5, -0.5, 0.0);",
                        "vUV.xy += uv;",
                    "}"
                ].join("\n"),
        
                fragmentShader: [
                    "uniform sampler2D tDiffuse;",      // sampler of rendered scene?s render target
                    "varying vec3 vUV;",                // interpolated vertex output data
                    "varying vec2 vUVDot;",             // interpolated vertex output data
        
                    "void main() {",
                        "vec3 uv = dot(vUVDot, vUVDot) * vec3(-0.5, -0.5, -1.0) + vUV;",
                        "gl_FragColor = texture2DProj(tDiffuse, uv);",
                    "}"
                ].join("\n")
        
            };
        }
        

        一种使用效果器设置效果器的方法(假设 scenerenderer 已创建):

        // Create camera
        camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 1, 1000000 );
        camera.position.z = 800;
        
        // Create effect composer
        composer = new THREE.EffectComposer( renderer );
        composer.addPass( new THREE.RenderPass( scene, camera ) );
        
        // Add distortion effect to effect composer
        var effect = new THREE.ShaderPass( getDistortionShaderDefinition() );
        composer.addPass( effect );
        effect.renderToScreen = true;
        
        // Setup distortion effect
        var horizontalFOV = 140;
        var strength = 0.5;
        var cylindricalRatio = 2;
        var height = Math.tan(THREE.Math.degToRad(horizontalFOV) / 2) / camera.aspect;
        
        camera.fov = Math.atan(height) * 2 * 180 / 3.1415926535;
        camera.updateProjectionMatrix();
        
        effect.uniforms[ "strength" ].value = strength;
        effect.uniforms[ "height" ].value = height;
        effect.uniforms[ "aspectRatio" ].value = camera.aspect;
        effect.uniforms[ "cylindricalRatio" ].value = cylindricalRatio;
        

        需要以下脚本,例如可以从 three.js GitHub page 找到它们:

        <script src="examples/js/postprocessing/EffectComposer.js"></script>
        <script src="examples/js/postprocessing/RenderPass.js"></script>
        <script src="examples/js/postprocessing/MaskPass.js"></script>
        <script src="examples/js/postprocessing/ShaderPass.js"></script>
        <script src="examples/js/shaders/CopyShader.js"></script>
        

        Giliam 示例的链接:http://www.decarpentier.nl/downloads/lensdistortion-webgl/lensdistortion-webgl.html

        Giliam 关于镜头畸变的文章链接:http://www.decarpentier.nl/lens-distortion

        使用镜头畸变效果的测试图片:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-05-20
          • 1970-01-01
          • 1970-01-01
          • 2016-01-06
          • 1970-01-01
          • 2011-05-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多