Qt Quick 3D - Beispiel für benutzerdefinierte Effekte
Demonstriert das Schreiben von benutzerdefinierten Nachbearbeitungseffekten.
Das Beispiel implementiert seine eigenen benutzerdefinierten Post-Processing-Effekte, die dann über SceneEnvironment::effects auf die Szene angewendet werden. Es demonstriert sowohl die einfachste Art von Effekten, die nur über einen Fragment-Shader verfügen, als auch den fortgeschritteneren Fall, bei dem sowohl ein Vertex- als auch ein Fragment-Shader vorhanden sind, wobei die Daten zwischen den beiden weitergegeben werden.
Der einfache Effekt verwendet nur einen einzelnen Fragment-Shader und fügt eine Textureingabe aus einer Bilddatei hinzu:
Effect { id: eff1 property TextureInput tex: TextureInput { id: qtLogo texture: Texture { source: "qt_logo_rect.png" } } passes: Pass { shaders: Shader { id: fs1 stage: Shader.Fragment shader: "effect.frag" } } }
Dieser Effekt verwendet einen sehr einfachen Fragment-Shader, der lediglich die Eingabetextur mit der Szene nimmt und sie mit der Bildtextur multipliziert:
void MAIN() { vec4 c = texture(tex, TEXTURE_UV); FRAGCOLOR = c * texture(INPUT, INPUT_UV); }
Die Shader-Schnipsel in den Dateien .vert
und .frag
werden unter Verwendung der eingebauten Schlüsselwörter geschrieben, wie in der Dokumentation Effect beschrieben. Benutzerdefinierte Eigenschaften mit Basistypen sowie Eigenschaften mit dem Typ TextureInput werden den Shadern automatisch als Uniformen und Sampler zur Verfügung gestellt.
Der zweite Effekt ist etwas komplexer. Er spezifiziert sowohl einen Vertex- als auch einen Fragment-Shader, sowie zwei Eigenschaften: uRed
und uGreen
, mit einer Animation auf uRed
:
Effect { id: eff2 property real uRed: 0.0 SequentialAnimation { running: radioEff2.checked || radioEff3.checked loops: Animation.Infinite NumberAnimation { target: eff2; property: "uRed"; from: 0; to: 1; duration: 2000 } NumberAnimation { target: eff2; property: "uRed"; from: 1; to: 0; duration: 2000 } } property real uGreen: 1.0 Shader { id: vs2 stage: Shader.Vertex shader: "effect2.vert" } Shader { id: fs2 stage: Shader.Fragment shader: "effect2.frag" } passes: Pass { shaders: [ vs2, fs2 ] } }
Der Fragment-Shader für diesen Effekt erzeugt eine Verzerrung durch Änderung der Abtastkoordinaten. Für die Berechnung wird center_vec
verwendet, das aus dem Fragment-Shader stammt. Schließlich passt der Shader die Farbe mithilfe der Uniformen uRed
und uGreen
an. Beachten Sie, dass diese Uniformen nicht im Shader deklariert werden müssen:
VARYING vec2 center_vec; void MAIN() { float radius = 0.25; float dist_to_center = length(center_vec) / radius; vec2 texcoord = INPUT_UV; if (dist_to_center <= 1.0) { float rotation_amount = (1.0 - dist_to_center) * (1.0 - dist_to_center); float r = radians(360.0) * rotation_amount / 4.0; float cos_r = cos(r); float sin_r = sin(r); mat2 rotation = mat2(cos_r, sin_r, -sin_r, cos_r); texcoord = vec2(0.5, 0.5) + rotation * (INPUT_UV - vec2(0.5, 0.5)); } vec4 c = texture(INPUT, texcoord); c.r *= uRed; c.g *= uGreen; FRAGCOLOR = c; }
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.