Code Monkey home page Code Monkey logo

glsl.qml's Introduction

GLSL.qml

Tell you how to use glsl in qml type ShaderEffect.

qml中的glsl学习。

注意:直接对 Item 的 layer.effect 设置着色器时,要设置 layer.enabled: true

线性渐变

import QtQuick 2.0

ShaderEffect {
    id: root
    width: 400
    height: 400

    //![1]
    property size uResolution: Qt.size(root.width, root.height)
    //![1]
    fragmentShader: "
            uniform vec2 uResolution;
            void main() {
                vec2 position = gl_FragCoord.xy/uResolution;
                float gradient = position.x;
                gl_FragColor = vec4(0., gradient, 0., 1.);
            }"
}

效果如下:

doc/images/001.png

进阶:

import QtQuick 2.0

ShaderEffect {
    id: root
    width: 400
    height: 400

    property real value: 0
    NumberAnimation on value {
        duration: 2500
        from: 0
        to: 3
        loops: Animation.Infinite
    }

    //![1]
    property size uResolution: Qt.size(root.width, root.height)
    //![1]

    //![2]
    // gl_FragCoord 这个片段独有的变量存放了当前片段相对窗口的坐标。
    // 这个值是从顶点生成片段之后对图元进行固定函数插值的结果
    // 你可以通过除法 gl_FragCoord.xy/uResolution 来把你的像素坐标转化到 0.0 ≤ xy ≤ 1.0 这个范围
    // 这在很多时候能大大简化像素着色器的计算。
    // 这也是 gl_FragColor 的绝佳取值范围,现在让我们来看一些渐变!
    fragmentShader:"
            uniform vec2 uResolution;
            uniform float value;
            void main() {
                vec2 position = gl_FragCoord.xy/uResolution;
                float gradient = (position.x+position.y)/value;
                gl_FragColor = vec4(0., gradient, 0., 1.);
            }"
    // 通过修改 float gradient = position.x; 横向
    // 通过修改 float gradient = position.y; 竖向
    // float gradient = (position.x+position.y)/2.; 斜向
    //![2]

}

2D 圆盘

import QtQuick 2.0

ShaderEffect {
    id: root
    width: 400
    height: 400
    property size uResolution: Qt.size(root.width, root.height)

    fragmentShader:"
            uniform vec2 uResolution;
            void main() {
                vec2 center = vec2(uResolution.x/2., uResolution.y/2.);

                // 2
                float radius = uResolution.x/2.;

                // 3
                vec2 position = gl_FragCoord.xy - center;

                // 4
                if (length(position) > radius) {
                  gl_FragColor = vec4(vec3(0.), 1.);
                } else {
                  gl_FragColor = vec4(vec3(1.), 1.);
                }
            }"
}

doc/images/002.png

  1. 圆盘的 center 会处于你屏幕的正**。

  2. 圆盘的 radius 会是你屏幕宽度的一半。

  3. position 是当前像素的坐标相对圆盘圆心的偏移值。可以想象成是一个向量从圆盘圆心指向当前位置。

  4. length() 用于计算向量长度,在这个例子里长度是根据勾股定理 √(position.x²+position.y²) 来计算的。

    A.如果结果比 radius 大,说明当前像素在圆盘区域外,那么就染成黑色。

    B.否则,说明当前像素在圆盘区域内,染成白色。

作为对这个行为的补充说明,可以参看 圆形方程 (x-a)²+(y-b)² = r² 。注意 r 是半径, ab 是圆心,而 xy 是圆上所有点集。

圆盘是平面上被圆形围住的一块区域,上面的 if-else 语句会准确的把它画出来!

细圆环

import QtQuick 2.0

ShaderEffect {
    id: root
    width: 400
    height: 400
    smooth: true
    property size uResolution: Qt.size(root.width, root.height)
    fragmentShader:"
            uniform vec2 uResolution;
            void main() {
                vec2 center = vec2(uResolution.x/2., uResolution.y/2.);
                float radius = uResolution.x/2.;
                vec2 position = gl_FragCoord.xy - center;
                float thickness = radius/50.;

                if ((length(position) > radius) || (length(position) < radius-thickness)) {
                    gl_FragColor = vec4(vec3(0.), 1.);
                } else {
                    gl_FragColor = vec4(vec3(1.), 1.);
                }
            }"
}

doc/images/003.png

试着根据 radius 创建一个叫 thickness 的新变量,并在 if-else 条件中使用。

3D球体

import QtQuick 2.0

ShaderEffect {
    id: root
    width: 400
    height: 400
    smooth: true
    property size uResolution: Qt.size(root.width, root.height)
    fragmentShader:"
            uniform vec2 uResolution;
            void main() {
                vec2 center = vec2(uResolution.x/2., uResolution.y/2.);
                float radius = uResolution.x/2.;
                vec2 position = gl_FragCoord.xy - center;
                float thickness = radius/50.;
                float z = sqrt(radius*radius - position.x*position.x - position.y*position.y);
                z /= radius;
                gl_FragColor = vec4(vec3(z), 1.);
            }"
}

doc/images/004.png


为新手准备的 Codea 着色器(Shader)教程

OpenGL ES像素着色器教程

glsl.qml's People

Contributors

qyvlik avatar

Watchers

James Cloos avatar wangyyovo avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.