Falling Cubes

Falling Cubes example shows two hundred cubes falling across the view port. The cubes have been colored using non-realistic Gooch shading, where the mesh surface color is mixed with warm and cold colors using surface’s normals. Gooch shader has been written in OpenGL GLSL Shading Language. Falling animation is implemented using SmoothedAnimation element.

Show code ยป

fallingcubes.qml:

import Qt3D 1.0
import QtQuick 1.0
import Qt3D.Shapes 1.0

Viewport {
    id: fallingCubes
    width: 800; height: 480
    property color coolColor: Qt.rgba(0.3 + 0.1*Math.random(),
                                      0.3 * Math.random(),
                                      0.5 + 0.1*Math.random())
    Item3D {
        x: -4.2; y: -1.62; scale: 0.23
        Quad {
            x: 18.4; y: 6.8; z: -10; scale: 18
            transform: Rotation3D {
                angle: 90; axis: Qt.vector3d(1.0, 0.0, 0.0)
            }
            effect: Effect {
                property real fade
                SequentialAnimation on fade {
                    id: fadeAnimation
                    property real offset: Math.random()
                    property real duration: 4000+4000*Math.random()
                    running: true; loops: Animation.Infinite
                    NumberAnimation {
                        from: 0.0; to: 1.0
                        duration: fadeAnimation.duration/2
                    }
                    NumberAnimation {
                        from: 1.0; to: 0.0
                        duration: fadeAnimation.duration/2
                    }
                }
                color: Qt.rgba(0.95 + 0.05*Math.random(),
                               0.5 + 0.2*fade,
                               0.1 + 0.1*Math.random())
            }
        }
        Repeater {
            model: 200
            FallingCube { coolColor: fallingCubes.coolColor }
        }
    }
}

FallingCube.qml:

import Qt3D 1.0
import QtQuick 1.0
import Qt3D.Shapes 1.0

Item3D {
    id: fallingCube
    property color coolColor
    function reset() {
        yBehavior.enabled = false;
        fallingCube.y = 25
        yBehavior.enabled = true;
        fallingCube.x = 40*Math.random();
        fallingCube.y = -15
    }
    Component.onCompleted: y = -15
    x: 40*Math.random(); y: 30*Math.random()-10; z: 20*(Math.random()-0.5)
    Behavior on x { SmoothedAnimation { velocity: 2*Math.random() } }
    Behavior on y {
        id: yBehavior
        SmoothedAnimation { velocity: 6+Math.random()*6 }
    }
    Timer {
        interval: 100; repeat: true; running: true
        onTriggered: if (fallingCube.y < -9) fallingCube.reset()
    }
    Cube {
        scale: 2
        effect: GoochShading {
            coolColor: fallingCube.coolColor
            warmColor: Qt.rgba(0.9 + 0.1*Math.random(),
                               0.2 + 0.2*Math.random(),
                               0.2*Math.random())
        }
        transform: Rotation3D {
            axis: Qt.vector3d(Math.random(), Math.random(), Math.random())
            SequentialAnimation on angle {
                id: angleAnimation
                property real offset: 360*Math.random()
                property real duration: 3000+3000*Math.random()
                running: true; loops: Animation.Infinite
                NumberAnimation {
                    from: angleAnimation.offset; to: 360
                    duration: (360-angleAnimation.offset)*angleAnimation.duration/360
                }
                NumberAnimation {
                    from: 0; to: angleAnimation.offset
                    duration: angleAnimation.offset*angleAnimation.duration/360
                }
            }
        }
    }
}

GoochShading.qml:

import Qt3D 1.0
import QtQuick 1.0

ShaderProgram {
    property color warmColor
    property color coolColor
    vertexShader: "
        attribute highp vec4 qt_Vertex;
        attribute highp vec3 qt_Normal;

        uniform lowp vec4 warmColor;
        uniform lowp vec4 coolColor;

        uniform highp mat3 qt_NormalMatrix;
        uniform highp mat4 qt_ModelViewProjectionMatrix;
        uniform highp mat4 qt_ModelViewMatrix;

        varying float facingProjector;

        struct qt_SingleLightParameters {
            mediump vec4 position;
            mediump vec3 spotDirection;
            mediump float spotExponent;
            mediump float spotCutoff;
            mediump float spotCosCutoff;
            mediump float constantAttenuation;
            mediump float linearAttenuation;
            mediump float quadraticAttenuation;
        };
        uniform qt_SingleLightParameters qt_Light;

        void main(void)
        {
            highp vec4 vertex = qt_ModelViewMatrix * qt_Vertex;
            highp vec3 normal = normalize(qt_NormalMatrix * qt_Normal);
            highp vec3 light = normalize(qt_Light.position.xyz - vertex.xyz);
            facingProjector = clamp(dot(normal, light), 0.0, 1.0);
            gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex;
        }
    "
    fragmentShader: "
        uniform lowp vec4 warmColor;
        uniform lowp vec4 coolColor;

        varying float facingProjector;

        void main(void)
        {
            highp float ratio = 0.5 * (facingProjector + 1.0);
            gl_FragColor = mix(warmColor, coolColor, ratio);
        }
    "
}



Leave a Reply

Your email address will not be published. Required fields are marked *

Comment

You may use these tags : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>