From 15849d78b7cca848b87badcfee33db1db70b8b52 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 28 Jun 2016 17:12:09 +0200 Subject: Migrate shadereffects example to be cross-backend ...while demonstrating best practices like file selectors. Task-number: QTBUG-52914 Change-Id: Ibf7bca77b7b142f5ccb956e05efc5be974d53c79 Reviewed-by: Andy Nichols --- .../shadereffects/content/shaders/+hlsl/blur.frag | 18 ++++ .../content/shaders/+hlsl/colorize.frag | 17 ++++ .../shadereffects/content/shaders/+hlsl/genie.vert | 31 +++++++ .../content/shaders/+hlsl/outline.frag | 21 +++++ .../content/shaders/+hlsl/shadow.frag | 20 ++++ .../content/shaders/+hlsl/wobble.frag | 17 ++++ .../quick/shadereffects/content/shaders/blur.frag | 14 +++ .../shadereffects/content/shaders/colorize.frag | 12 +++ .../quick/shadereffects/content/shaders/genie.vert | 21 +++++ .../shadereffects/content/shaders/outline.frag | 16 ++++ .../shadereffects/content/shaders/shadow.frag | 14 +++ .../shadereffects/content/shaders/wobble.frag | 13 +++ .../quick/shadereffects/doc/src/shadereffects.qdoc | 15 +++ examples/quick/shadereffects/shadereffects.qml | 102 ++------------------- examples/quick/shadereffects/shadereffects.qrc | 12 +++ 15 files changed, 249 insertions(+), 94 deletions(-) create mode 100644 examples/quick/shadereffects/content/shaders/+hlsl/blur.frag create mode 100644 examples/quick/shadereffects/content/shaders/+hlsl/colorize.frag create mode 100644 examples/quick/shadereffects/content/shaders/+hlsl/genie.vert create mode 100644 examples/quick/shadereffects/content/shaders/+hlsl/outline.frag create mode 100644 examples/quick/shadereffects/content/shaders/+hlsl/shadow.frag create mode 100644 examples/quick/shadereffects/content/shaders/+hlsl/wobble.frag create mode 100644 examples/quick/shadereffects/content/shaders/blur.frag create mode 100644 examples/quick/shadereffects/content/shaders/colorize.frag create mode 100644 examples/quick/shadereffects/content/shaders/genie.vert create mode 100644 examples/quick/shadereffects/content/shaders/outline.frag create mode 100644 examples/quick/shadereffects/content/shaders/shadow.frag create mode 100644 examples/quick/shadereffects/content/shaders/wobble.frag (limited to 'examples/quick') diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/blur.frag b/examples/quick/shadereffects/content/shaders/+hlsl/blur.frag new file mode 100644 index 0000000000..481a238d2a --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/+hlsl/blur.frag @@ -0,0 +1,18 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float2 delta; +}; + +Texture2D source : register(t0); +SamplerState sourceSampler : register(s0); + +float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET +{ + return (0.0538 * source.Sample(sourceSampler, coord - 3.182 * delta) + + 0.3229 * source.Sample(sourceSampler, coord - 1.364 * delta) + + 0.2466 * source.Sample(sourceSampler, coord) + + 0.3229 * source.Sample(sourceSampler, coord + 1.364 * delta) + + 0.0538 * source.Sample(sourceSampler, coord + 3.182 * delta)) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/colorize.frag b/examples/quick/shadereffects/content/shaders/+hlsl/colorize.frag new file mode 100644 index 0000000000..d6e65b6b10 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/+hlsl/colorize.frag @@ -0,0 +1,17 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float4 tint; +}; + +Texture2D source : register(t0); +SamplerState sourceSampler : register(s0); + +float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET +{ + float4 c = source.Sample(sourceSampler, coord); + float lo = min(min(c.x, c.y), c.z); + float hi = max(max(c.x, c.y), c.z); + return float4(lerp(float3(lo, lo, lo), float3(hi, hi, hi), tint.xyz), c.w) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/genie.vert b/examples/quick/shadereffects/content/shaders/+hlsl/genie.vert new file mode 100644 index 0000000000..40876e7996 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/+hlsl/genie.vert @@ -0,0 +1,31 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float bend; + float minimize; + float side; + float width; + float height; +}; + +struct PSInput +{ + float4 position : SV_POSITION; + float2 coord : TEXCOORD0; +}; + +PSInput main(float4 position : POSITION, float2 coord : TEXCOORD0) +{ + PSInput result; + result.coord = coord; + + float4 pos = position; + pos.y = lerp(position.y, height, minimize); + float t = pos.y / height; + t = (3.0 - 2.0 * t) * t * t; + pos.x = lerp(position.x, side * width, t * bend); + result.position = mul(qt_Matrix, pos); + + return result; +} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/outline.frag b/examples/quick/shadereffects/content/shaders/+hlsl/outline.frag new file mode 100644 index 0000000000..b6e7e51f35 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/+hlsl/outline.frag @@ -0,0 +1,21 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float2 delta; +}; + +Texture2D source : register(t0); +SamplerState sourceSampler : register(s0); + +float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET +{ + float4 tl = source.Sample(sourceSampler, coord - delta); + float4 tr = source.Sample(sourceSampler, coord + float2(delta.x, -delta.y)); + float4 bl = source.Sample(sourceSampler, coord - float2(delta.x, -delta.y)); + float4 br = source.Sample(sourceSampler, coord + delta); + float4 gx = (tl + bl) - (tr + br); + float4 gy = (tl + tr) - (bl + br); + return float4(0.0, 0.0, 0.0, + clamp(dot(sqrt(gx * gx + gy * gy), float4(1.0, 1.0, 1.0, 1.0)), 0.0, 1.0) * qt_Opacity); +} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/shadow.frag b/examples/quick/shadereffects/content/shaders/+hlsl/shadow.frag new file mode 100644 index 0000000000..a86a25e007 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/+hlsl/shadow.frag @@ -0,0 +1,20 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float2 offset; + float2 delta; + float darkness; +}; + +Texture2D source : register(t0); +SamplerState sourceSampler : register(s0); +Texture2D shadow : register(t1); +SamplerState shadowSampler : register(s1); + +float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET +{ + float4 fg = source.Sample(sourceSampler, coord); + float4 bg = shadow.Sample(shadowSampler, coord + delta); + return (fg + float4(0.0, 0.0, 0.0, darkness * bg.a) * (1.0 - fg.a)) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/wobble.frag b/examples/quick/shadereffects/content/shaders/+hlsl/wobble.frag new file mode 100644 index 0000000000..c28612a2fd --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/+hlsl/wobble.frag @@ -0,0 +1,17 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float amplitude; + float frequency; + float time; +}; + +Texture2D source : register(t0); +SamplerState sourceSampler : register(s0); + +float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET +{ + float2 p = sin(time + frequency * coord); + return source.Sample(sourceSampler, coord + amplitude * float2(p.y, -p.x)) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/blur.frag b/examples/quick/shadereffects/content/shaders/blur.frag new file mode 100644 index 0000000000..9173945eed --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/blur.frag @@ -0,0 +1,14 @@ +uniform lowp float qt_Opacity; +uniform sampler2D source; +uniform highp vec2 delta; + +varying highp vec2 qt_TexCoord0; + +void main() +{ + gl_FragColor =(0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta) + + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta) + + 0.2466 * texture2D(source, qt_TexCoord0) + + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta) + + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta)) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/colorize.frag b/examples/quick/shadereffects/content/shaders/colorize.frag new file mode 100644 index 0000000000..1219ef2460 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/colorize.frag @@ -0,0 +1,12 @@ +uniform sampler2D source; +uniform lowp vec4 tint; +uniform lowp float qt_Opacity; + +varying highp vec2 qt_TexCoord0; + +void main() { + lowp vec4 c = texture2D(source, qt_TexCoord0); + lowp float lo = min(min(c.x, c.y), c.z); + lowp float hi = max(max(c.x, c.y), c.z); + gl_FragColor = qt_Opacity * vec4(mix(vec3(lo), vec3(hi), tint.xyz), c.w); +} diff --git a/examples/quick/shadereffects/content/shaders/genie.vert b/examples/quick/shadereffects/content/shaders/genie.vert new file mode 100644 index 0000000000..3ce371819f --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/genie.vert @@ -0,0 +1,21 @@ +attribute highp vec4 qt_Vertex; +attribute highp vec2 qt_MultiTexCoord0; + +uniform highp mat4 qt_Matrix; +uniform highp float bend; +uniform highp float minimize; +uniform highp float side; +uniform highp float width; +uniform highp float height; + +varying highp vec2 qt_TexCoord0; + +void main() { + qt_TexCoord0 = qt_MultiTexCoord0; + highp vec4 pos = qt_Vertex; + pos.y = mix(qt_Vertex.y, height, minimize); + highp float t = pos.y / height; + t = (3. - 2. * t) * t * t; + pos.x = mix(qt_Vertex.x, side * width, t * bend); + gl_Position = qt_Matrix * pos; +} diff --git a/examples/quick/shadereffects/content/shaders/outline.frag b/examples/quick/shadereffects/content/shaders/outline.frag new file mode 100644 index 0000000000..9b46719873 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/outline.frag @@ -0,0 +1,16 @@ +uniform sampler2D source; +uniform highp vec2 delta; +uniform highp float qt_Opacity; + +varying highp vec2 qt_TexCoord0; + +void main() { + lowp vec4 tl = texture2D(source, qt_TexCoord0 - delta); + lowp vec4 tr = texture2D(source, qt_TexCoord0 + vec2(delta.x, -delta.y)); + lowp vec4 bl = texture2D(source, qt_TexCoord0 - vec2(delta.x, -delta.y)); + lowp vec4 br = texture2D(source, qt_TexCoord0 + delta); + mediump vec4 gx = (tl + bl) - (tr + br); + mediump vec4 gy = (tl + tr) - (bl + br); + gl_FragColor.xyz = vec3(0.); + gl_FragColor.w = clamp(dot(sqrt(gx * gx + gy * gy), vec4(1.)), 0., 1.) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/shadow.frag b/examples/quick/shadereffects/content/shaders/shadow.frag new file mode 100644 index 0000000000..8650ee4f4c --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/shadow.frag @@ -0,0 +1,14 @@ +uniform lowp float qt_Opacity; +uniform highp vec2 offset; +uniform sampler2D source; +uniform sampler2D shadow; +uniform highp float darkness; +uniform highp vec2 delta; + +varying highp vec2 qt_TexCoord0; + +void main() { + lowp vec4 fg = texture2D(source, qt_TexCoord0); + lowp vec4 bg = texture2D(shadow, qt_TexCoord0 + delta); + gl_FragColor = (fg + vec4(0., 0., 0., darkness * bg.a) * (1. - fg.a)) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/content/shaders/wobble.frag b/examples/quick/shadereffects/content/shaders/wobble.frag new file mode 100644 index 0000000000..fedbb68254 --- /dev/null +++ b/examples/quick/shadereffects/content/shaders/wobble.frag @@ -0,0 +1,13 @@ +uniform lowp float qt_Opacity; +uniform highp float amplitude; +uniform highp float frequency; +uniform highp float time; +uniform sampler2D source; + +varying highp vec2 qt_TexCoord0; + +void main() +{ + highp vec2 p = sin(time + frequency * qt_TexCoord0); + gl_FragColor = texture2D(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity; +} diff --git a/examples/quick/shadereffects/doc/src/shadereffects.qdoc b/examples/quick/shadereffects/doc/src/shadereffects.qdoc index dc2a2681f5..7b1d68ebb5 100644 --- a/examples/quick/shadereffects/doc/src/shadereffects.qdoc +++ b/examples/quick/shadereffects/doc/src/shadereffects.qdoc @@ -51,6 +51,21 @@ shader: \snippet shadereffects/shadereffects.qml fragment + In order to support multiple graphics APIs, not just OpenGL, the shader + source is not embedded into QML. Instead, file selectors are used to select + the correct variant at runtime. Based on the Qt Quick backend in use, Qt + will automatically select either \c{shaders/wobble.frag} with the GLSL + source code or \c{shaders/+hlsl/wobble.frag} with the HLSL source code. + + \note For simplicity shader source code is used in all variants of the + files. However, with the Direct3D backend of Qt Quick pre-compiled shaders + are also supported. For example, try the following commands in the + \c{content/shaders/+hlsl} directory: \c{move wobble.frag wobble.frag.src} + followed by \c{fxc /E main /T ps_5_0 /Fo wobble.frag wobble.frag.src}. Now + \c wobble.frag contains Direct3D bytecode and that is what gets shipped + with the application instead of the shader source. Further changes are not + necessary, the application will function like before. + You can use any custom property on the ShaderEffect in your shader. This makes animated shader code very easy: \snippet shadereffects/shadereffects.qml properties diff --git a/examples/quick/shadereffects/shadereffects.qml b/examples/quick/shadereffects/shadereffects.qml index 926394ed0f..0c24a7bbf2 100644 --- a/examples/quick/shadereffects/shadereffects.qml +++ b/examples/quick/shadereffects/shadereffects.qml @@ -101,7 +101,7 @@ Rectangle { height: 140 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter - font.pixelSize: 120 + font.pixelSize: 118 font.family: "Times" color: "blue" text: "Qt" @@ -128,17 +128,7 @@ Rectangle { property real time: 0 NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 600 } //! [fragment] - fragmentShader: - "uniform lowp float qt_Opacity;" + - "uniform highp float amplitude;" + - "uniform highp float frequency;" + - "uniform highp float time;" + - "uniform sampler2D source;" + - "varying highp vec2 qt_TexCoord0;" + - "void main() {" + - " highp vec2 p = sin(time + frequency * qt_TexCoord0);" + - " gl_FragColor = texture2D(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity;" + - "}" + fragmentShader: "qrc:shadereffects/content/shaders/wobble.frag" //! [fragment] Slider { id: wobbleSlider @@ -163,32 +153,10 @@ Rectangle { height: theItem.height property variant delta: Qt.size(1.0 / width, 0.0) property variant source: theSource - fragmentShader: " - uniform lowp float qt_Opacity; - uniform sampler2D source; - uniform highp vec2 delta; - varying highp vec2 qt_TexCoord0; - void main() { - gl_FragColor =(0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta) - + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta) - + 0.2466 * texture2D(source, qt_TexCoord0) - + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta) - + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta)) * qt_Opacity; - }" + fragmentShader: "qrc:shadereffects/content/shaders/blur.frag" } } - fragmentShader: " - uniform lowp float qt_Opacity; - uniform sampler2D source; - uniform highp vec2 delta; - varying highp vec2 qt_TexCoord0; - void main() { - gl_FragColor =(0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta) - + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta) - + 0.2466 * texture2D(source, qt_TexCoord0) - + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta) - + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta)) * qt_Opacity; - }" + fragmentShader: "qrc:shadereffects/content/shaders/blur.frag" } } property real angle: 0 @@ -196,19 +164,7 @@ Rectangle { NumberAnimation on angle { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 6000 } property variant delta: Qt.size(offset.x / width, offset.y / height) property real darkness: shadowSlider.value - fragmentShader: " - uniform lowp float qt_Opacity; - uniform highp vec2 offset; - uniform sampler2D source; - uniform sampler2D shadow; - uniform highp float darkness; - uniform highp vec2 delta; - varying highp vec2 qt_TexCoord0; - void main() { - lowp vec4 fg = texture2D(source, qt_TexCoord0); - lowp vec4 bg = texture2D(shadow, qt_TexCoord0 + delta); - gl_FragColor = (fg + vec4(0., 0., 0., darkness * bg.a) * (1. - fg.a)) * qt_Opacity; - }" + fragmentShader: "qrc:shadereffects/content/shaders/shadow.frag" Slider { id: shadowSlider anchors.left: parent.left @@ -222,38 +178,14 @@ Rectangle { height: 160 property variant source: theSource property variant delta: Qt.size(0.5 / width, 0.5 / height) - fragmentShader: " - uniform sampler2D source; - uniform highp vec2 delta; - uniform highp float qt_Opacity; - varying highp vec2 qt_TexCoord0; - void main() { - lowp vec4 tl = texture2D(source, qt_TexCoord0 - delta); - lowp vec4 tr = texture2D(source, qt_TexCoord0 + vec2(delta.x, -delta.y)); - lowp vec4 bl = texture2D(source, qt_TexCoord0 - vec2(delta.x, -delta.y)); - lowp vec4 br = texture2D(source, qt_TexCoord0 + delta); - mediump vec4 gx = (tl + bl) - (tr + br); - mediump vec4 gy = (tl + tr) - (bl + br); - gl_FragColor.xyz = vec3(0.); - gl_FragColor.w = clamp(dot(sqrt(gx * gx + gy * gy), vec4(1.)), 0., 1.) * qt_Opacity; - }" + fragmentShader: "qrc:shadereffects/content/shaders/outline.frag" } ShaderEffect { width: 160 height: 160 property variant source: theSource property color tint: root.sliderToColor(colorizeSlider.value) - fragmentShader: " - uniform sampler2D source; - uniform lowp vec4 tint; - uniform lowp float qt_Opacity; - varying highp vec2 qt_TexCoord0; - void main() { - lowp vec4 c = texture2D(source, qt_TexCoord0); - lowp float lo = min(min(c.x, c.y), c.z); - lowp float hi = max(max(c.x, c.y), c.z); - gl_FragColor = qt_Opacity * vec4(mix(vec3(lo), vec3(hi), tint.xyz), c.w); - }" + fragmentShader: "qrc:shadereffects/content/shaders/colorize.frag" Slider { id: colorizeSlider anchors.left: parent.left @@ -288,25 +220,7 @@ Rectangle { //! [properties] //! [vertex] mesh: Qt.size(10, 10) - vertexShader: " - uniform highp mat4 qt_Matrix; - uniform highp float bend; - uniform highp float minimize; - uniform highp float side; - uniform highp float width; - uniform highp float height; - attribute highp vec4 qt_Vertex; - attribute highp vec2 qt_MultiTexCoord0; - varying highp vec2 qt_TexCoord0; - void main() { - qt_TexCoord0 = qt_MultiTexCoord0; - highp vec4 pos = qt_Vertex; - pos.y = mix(qt_Vertex.y, height, minimize); - highp float t = pos.y / height; - t = (3. - 2. * t) * t * t; - pos.x = mix(qt_Vertex.x, side * width, t * bend); - gl_Position = qt_Matrix * pos; - }" + vertexShader: "qrc:shadereffects/content/shaders/genie.vert" //! [vertex] Slider { id: genieSlider diff --git a/examples/quick/shadereffects/shadereffects.qrc b/examples/quick/shadereffects/shadereffects.qrc index ff296a0155..e66b98a6df 100644 --- a/examples/quick/shadereffects/shadereffects.qrc +++ b/examples/quick/shadereffects/shadereffects.qrc @@ -4,5 +4,17 @@ content/face-smile.png content/qt-logo.png content/Slider.qml + content/shaders/wobble.frag + content/shaders/+hlsl/wobble.frag + content/shaders/blur.frag + content/shaders/+hlsl/blur.frag + content/shaders/shadow.frag + content/shaders/+hlsl/shadow.frag + content/shaders/outline.frag + content/shaders/+hlsl/outline.frag + content/shaders/colorize.frag + content/shaders/+hlsl/colorize.frag + content/shaders/genie.vert + content/shaders/+hlsl/genie.vert -- cgit v1.2.3