美文网首页
2022-10-29 雾化

2022-10-29 雾化

作者: MrSwilder | 来源:发表于2022-10-30 20:17 被阅读0次

一 、原理

在三维图形学中,术语雾化(fog)用来描述远处的物体看上去较为模糊的现象。在现实中,任何介质中的物体都可能表现出雾化现象,比如水下的物体。

如何实现雾化:

实现雾化的方式有很多种,这里使用最简单的一种:线性雾化(linear fog)。在线性雾化中,某一点的雾化程度取决于它与视点之间的距离,距离越远雾化程度越高。线性雾化有起点和终点,起点表示开始雾化之处,终点表示完全雾化之处,两点之间的某一点的雾化程度与该点与视点的距离呈线性关系。注意,比终点更远的点完全雾化了,即完全看不见了。某一点雾化的程度可以被定义为雾化因子(fog factor),并在线性雾化公式中被计算出来。

<雾化因子> = ( <终点> - <当前点与视点间的距离>) / ( <终点> - <起点> )

这里

<起点> 小于等于 <当前点与视点间的距离> 小于等于 <终点>

如果雾化因子为1.0,表示该点完全没有被雾化,可以很清晰地看到此处的物体。如果其为0.0,就表示该点完全雾化了,此处的物体完全看不见,如图10.8所示。在视线上,起点之前的点的雾化因子为1.0,终点之后的点的雾化因子为0.0 。

在片元着色器中根据雾化因子计算片元的颜色:

<片元颜色> = <物体表面颜色> x <雾化因子> + <雾的颜色> x ( 1 - <雾化因子> )

二、效果

image.png

三、代码

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>雾化</title>
    <style>
        body {
            margin: 0;
            text-align: center;
        }

        #canvas {
            margin: 0;
        }
    </style>
</head>

<body onload="main()">
    <canvas id="canvas" height="800" width="1200"></canvas>
</body>
<script src="/lib/webgl-utils.js"></script>
<script src="/lib/webgl-debug.js"></script>
<script src="/lib/cuon-utils.js"></script>
<script src="/lib/cuon-matrix.js"></script>
<script src="/lib/helper.js"></script>
<script src="/geometry/SphereGeometry.js"></script>
<script src="/texture/Texture2D.js"></script>
<script>
    //顶点着色器
    var VSHADER_SOURCE = /*glsl*/`
        attribute vec2 a_Uv;
        attribute vec4 a_Position;
        uniform mat4 u_MvpMatrix; 
        varying vec2 v_Uv;
        varying float v_dist;
        void main(){ 
            vec4 clip_Position=u_MvpMatrix*a_Position;
            gl_Position=clip_Position;
            v_Uv=a_Uv;
            v_dist=gl_Position.w;
        }`;

    //片元着色器
    var FSHADER_SOURCE = /*glsl*/`
        #ifdef GL_ES
        precision mediump float;
        #endif
        uniform sampler2D u_Texture;
        
        varying vec2 v_Uv;
        varying float v_dist;
        void main(){
            vec3 fogColor=vec3(1.0,1.0,1.0);
            //定义最大最小值
            float fogDistMax=3.6;
            float fogDistMin=3.0;
            //计算雾化因子
            float factor=clamp((fogDistMax-v_dist)/(fogDistMax-fogDistMin),0.0,1.0);
            vec4 baseColor=texture2D(u_Texture,vec2(v_Uv.x,1.0-v_Uv.y));
           gl_FragColor =vec4( mix(baseColor.rgb,fogColor,1.0-1.0*factor),baseColor.a);
        // gl_FragColor=vec4(baseColor.rgb,v_dist*0.5);
       
        }`;

    //声明js需要的相关变量
    var canvas = document.getElementById("canvas");
    var gl = getWebGLContext(canvas);
     //设置视角矩阵的相关信息(视点,视线,上方向)
    var viewMatrix = new Matrix4();



    //设置透视投影矩阵
    var projMatrix = new Matrix4();
    projMatrix.setPerspective(30, canvas.width / canvas.height,0.1, 10);

    const rotateViewMatrix=new Matrix4()


    var currentAngle = [0,0]
    async function main() {
        if (!gl) {
            console.log("你的浏览器不支持WebGL");
            return;
        }

        const program=createProgram(gl,VSHADER_SOURCE,FSHADER_SOURCE)

        if(!program){
            console.error('创建着色器程序失败')
            return
        }

        gl.program=program
        gl.useProgram(program)

        getVariableLocation()

        //绘制球形
        const sphereGeometry=new SphereGeometry(gl,1,180,90)
        const sphere= sphereGeometry.create()
        //绘制纹理
        const texture=Texture2D.initTexture(gl,'./image/earth.jpg', 0)
        //设置底色
        gl.clearColor(0.0,0.0,0.0, 1.0);
       
        var tick = function () {
            viewMatrix.setLookAt(0, 0, 4, 0, 0, 0, 0, 1, 0);
            rotateViewMatrix.setRotate(currentAngle[1],1,0,0)
            rotateViewMatrix.rotate(currentAngle[0],0,1,0)
            viewMatrix.multiply(rotateViewMatrix)

            draw(gl, sphere)
            requestAnimationFrame(tick)
        }
        tick()
        

        registerMouseEvent()
    }

    /**
     * 
     * 注册鼠标事件
     * */
    function registerMouseEvent(){
        //是否按下
        let isDown=false
        let last_X=0,last_Y=0
        canvas.onmousedown=function(e){
            //获取当前鼠标位置
            const x=e.clientX,y=e.clientY
            //获取canvas边界范围
            const bound=e.target.getBoundingClientRect()

            if(bound.left<x&&bound.right>x&&bound.top<y&&bound.bottom>y){

                last_X=x
                last_Y=y
                isDown=true
            }   
           
        }

        canvas.onmousemove=function(e){
            // console.log('鼠标移动',e)
            const x=e.clientX,y=e.clientY
            if(isDown){
               
                const offset_X=x-last_X
                const offset_Y=y-last_Y
                currentAngle[0]+=offset_X/10
                currentAngle[1]+=offset_Y/10
        
             

            }
            last_X=x
            last_Y=y
        }


        canvas.onmouseup=function(e){
            isDown=false
           
        }
    }

    function draw(gl, sphere) {
       

        //设置模型矩阵的相关信息
        var modelMatrix = new Matrix4();

        var mvpMatrix=new Matrix4()
        mvpMatrix.set(projMatrix)
       
        mvpMatrix.multiply(viewMatrix.multiply(modelMatrix));


        //将试图矩阵传给u_ViewMatrix变量
        gl.uniformMatrix4fv(gl.program.mvpMatrix, false, mvpMatrix.elements);

        //开启隐藏面清除
        gl.enable(gl.DEPTH_TEST);

        //清空颜色和深度缓冲区
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        const length=sphere.length

        //绘制图形
        gl.drawElements(gl.TRIANGLES, length, gl.UNSIGNED_SHORT, 0);



    }





</script>

</html>

相关文章

  • 2022-10-29 雾化

    一 、原理 在三维图形学中,术语雾化(fog)用来描述远处的物体看上去较为模糊的现象。在现实中,任何介质中的物体都...

  • 雾化

    黎明前的都市,瘴气笼罩了整个街道,不远处的大楼烟囱装点上斑斓的彩光灯,现在看的时候,烟囱里冒出来的白烟,混在整个阴...

  • 雾化

    在上能量净化的课程中,迷迷糊糊中从身体里拉出来一支手,把我抱住感觉身体不断的震动,眼前一片新的世界,四周都是白色的...

  • 雾化

    娃从老家回来的第二天就开始咳嗽,晚上两点醒过来,啃啃啃的咳,翻来翻去的睡不好。咳嗽是他爸最大的禁忌。一听娃咳嗽,他...

  • 雾化

    林林感冒了,老是咳嗽,而我正处于大姨妈期间,老公昨晚主动提出他睡林林旁边,这有点暖心。昨晚林林反反复复咳...

  • 雾化

    前两天我生病了咳嗽,妈妈带我去看医生,医生说让我做雾化。每天做两次,已经做了3天了,明天还有最后一天。

  • 雾化

    今天带小懒懒继续做雾化,去之前看了一下自己的健康码,是绿码,昨天的核酸检测结果也出来了,阴性。 其实昨天去做之前是...

  • 雾化

    在家给二宝做雾化。晚上还好,他一般睡得很沉,雾化机的声音不影响他。 早上寻思趁着他没醒,上班前再给他做一次雾化,于...

  • 2018-09-23

    呼吸系统的小帮手------雾化吸入疗法 陶炑晗 1雾化吸入是指使用专业的雾化装置,利用高速气流,将药物溶液雾化成...

  • D17. 雾化治疗的那些事

    做了近半年雾化治疗,发现现在雾化的普及度还在逐渐增加,很多家庭都会给小朋友们用雾化治疗。这里就来分享下对于雾化治疗...

网友评论

      本文标题:2022-10-29 雾化

      本文链接:https://www.haomeiwen.com/subject/gulctdtx.html