QmlDesigner: Make 3D view grid fade away at distance

Fixes: QDS-10622
Change-Id: I39179e3927bfef5b0e9d99cbbd2ff16886b6dc38
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Miikka Heikkinen
2023-09-12 15:32:34 +03:00
parent 1327a2c7ce
commit fb20ecff57
9 changed files with 127 additions and 77 deletions

View File

@@ -522,7 +522,7 @@ void Edit3DView::createResetColorAction(QAction *syncBackgroundColorAction)
Edit3DViewConfig::setColors(this, edit3dBgColorProperty, bgColors);
Edit3DViewConfig::saveColors(DesignerSettingsKey::EDIT3DVIEW_BACKGROUND_COLOR, bgColors);
QColor gridColor{0xaaaaaa};
QColor gridColor{0xcccccc};
Edit3DViewConfig::setColors(this, edit3dGridColorProperty, {gridColor});
Edit3DViewConfig::saveColors(DesignerSettingsKey::EDIT3DVIEW_GRID_COLOR, {gridColor});

View File

@@ -82,7 +82,7 @@ void DesignerSettings::fromSettings(QSettings *settings)
restoreValue(settings, DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET, true);
restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_BACKGROUND_COLOR,
QStringList{"#222222", "#999999"});
restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_GRID_COLOR, "#aaaaaa");
restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_GRID_COLOR, "#cccccc");
restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_ABSOLUTE, true);
restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_ENABLED, false);
restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION, true);

View File

@@ -54,5 +54,8 @@
<file>mockfiles/qt6/SceneView3D.qml</file>
<file>mockfiles/qt6/SelectionBox.qml</file>
<file>mockfiles/qt6/SpotLightHandle.qml</file>
<file>mockfiles/qt6/GridMaterial.qml</file>
<file>mockfiles/shaders/gridmaterial.frag</file>
<file>mockfiles/shaders/gridmaterial.vert</file>
</qresource>
</RCC>

View File

@@ -26,7 +26,7 @@ Item {
property alias contentItem: contentItem
property color backgroundGradientColorStart: "#222222"
property color backgroundGradientColorEnd: "#999999"
property color gridColor: "#aaaaaa"
property color gridColor: "#cccccc"
property bool syncBackgroundColor: false
enum SelectionMode { Item, Group }

View File

@@ -0,0 +1,22 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtQuick3D
CustomMaterial {
property real alphaStartDepth: 500
property real alphaEndDepth: 40000
property real generalAlpha: 1
property color color: "#000000"
property real density: 50
property bool orthoMode: false
vertexShader: Qt.resolvedUrl("../shaders/gridmaterial.vert")
fragmentShader: Qt.resolvedUrl("../shaders/gridmaterial.frag")
sourceBlend: CustomMaterial.NoBlend
destinationBlend: CustomMaterial.NoBlend
shadingMode: CustomMaterial.Unshaded
depthDrawMode: Material.AlwaysDepthDraw
cullMode: Material.NoCulling
}

View File

@@ -8,38 +8,76 @@ import GridGeometry 1.0
Node {
id: grid
property alias lines: gridGeometry.lines
property alias step: gridGeometry.step
property alias subdivAlpha: subGridMaterial.opacity
property alias gridColor: mainGridMaterial.diffuseColor
property alias gridColor: mainGridMaterial.color
property double density: 2500 / (gridGeometry.step + gridGeometry.step * (1.0 - subGridMaterial.generalAlpha))
property bool orthoMode: false
property double distance: 500
readonly property int minGridStep: 50
readonly property int maxGridStep: 32 * minGridStep
readonly property int gridArea: minGridStep * 512
// Step of the main lines of the grid, between those is always one subdiv line
property int gridStep: 100
// Minimum grid spacing in radians when viewed perpendicularly and lookAt is on origin.
// If spacing would go smaller, gridStep is doubled and line count halved.
// Note that spacing can stay smaller than this after maxGridStep has been reached.
readonly property double minGridRad: 0.1
eulerRotation.x: 90
function calcRad(step)
{
return Math.atan(step / distance)
}
onDistanceChanged: {
if (distance === 0)
return
// Calculate new grid step
let newStep = gridStep
let gridRad = calcRad(newStep)
while (gridRad < minGridRad && newStep < maxGridStep) {
newStep *= 2
if (newStep > maxGridStep)
newStep = maxGridStep
gridRad = calcRad(newStep)
}
while (gridRad > minGridRad * 2 && newStep > minGridStep) {
newStep /= 2
if (newStep < minGridStep)
newStep = minGridStep
gridRad = calcRad(newStep)
}
gridStep = newStep
subGridMaterial.generalAlpha = Math.min(1, 2 * (1 - (minGridRad / gridRad)))
}
// Note: Only one instance of HelperGrid is supported, as the geometry names are fixed
Model { // Main grid lines
readonly property bool _edit3dLocked: true // Make this non-pickable
castsShadows: false
receivesShadows: false
geometry: GridGeometry {
id: gridGeometry
lines: grid.gridArea / grid.gridStep
step: grid.gridStep
name: "3D Edit View Helper Grid"
}
materials: [
DefaultMaterial {
GridMaterial {
id: mainGridMaterial
diffuseColor: "#aaaaaa"
lighting: DefaultMaterial.NoLighting
cullMode: Material.NoCulling
color: "#cccccc"
density: grid.density
orthoMode: grid.orthoMode
}
]
}
Model { // Subdivision lines
readonly property bool _edit3dLocked: true // Make this non-pickable
castsShadows: false
receivesShadows: false
geometry: GridGeometry {
lines: gridGeometry.lines
step: gridGeometry.step
@@ -48,19 +86,17 @@ Node {
}
materials: [
DefaultMaterial {
GridMaterial {
id: subGridMaterial
diffuseColor: mainGridMaterial.diffuseColor
lighting: DefaultMaterial.NoLighting
cullMode: Material.NoCulling
color: mainGridMaterial.color
density: grid.density
orthoMode: grid.orthoMode
}
]
}
Model { // Z Axis
readonly property bool _edit3dLocked: true // Make this non-pickable
castsShadows: false
receivesShadows: false
geometry: GridGeometry {
lines: gridGeometry.lines
step: gridGeometry.step
@@ -68,18 +104,16 @@ Node {
name: "3D Edit View Helper Grid Z Axis"
}
materials: [
DefaultMaterial {
GridMaterial {
id: vCenterLineMaterial
diffuseColor: "#00a1d2"
lighting: DefaultMaterial.NoLighting
cullMode: Material.NoCulling
color: "#00a1d2"
density: grid.density
orthoMode: grid.orthoMode
}
]
}
Model { // X Axis
readonly property bool _edit3dLocked: true // Make this non-pickable
castsShadows: false
receivesShadows: false
eulerRotation.z: 90
geometry: GridGeometry {
lines: gridGeometry.lines
@@ -88,11 +122,11 @@ Node {
name: "3D Edit View Helper Grid X Axis"
}
materials: [
DefaultMaterial {
GridMaterial {
id: hCenterLineMaterial
diffuseColor: "#cb211a"
lighting: DefaultMaterial.NoLighting
cullMode: Material.NoCulling
color: "#cb211a"
density: grid.density
orthoMode: grid.orthoMode
}
]
}

View File

@@ -17,19 +17,6 @@ View3D {
property alias orthoCamera: sceneOrthoCamera
property vector3d cameraLookAt
// This is step of the main line of the grid, between those is always one subdiv line
property int gridStep: 100
property int minGridStep: 50
readonly property int maxGridStep: 32 * minGridStep
readonly property int gridArea: minGridStep * 128
// Minimum grid spacing in radians when viewed perpendicularly and lookAt is on origin.
// If spacing would go smaller, gridStep is doubled and line count halved.
// Note that spacing can stay smaller than this after maxGridStep has been reached.
readonly property double minGridRad: 0.1
// Measuring the distance from camera to lookAt plus the distance of lookAt from grid plane
// gives a reasonable grid spacing in most cases while keeping spacing constant when
// orbiting the camera.
@@ -45,34 +32,6 @@ View3D {
camera: usePerspective ? scenePerspectiveCamera : sceneOrthoCamera
function calcRad()
{
return Math.atan(gridStep / cameraDistance)
}
onCameraDistanceChanged: {
if (cameraDistance === 0)
return
// Calculate new grid step
let gridRad = calcRad()
while (gridRad < minGridRad && gridStep < maxGridStep) {
gridStep *= 2
if (gridStep > maxGridStep)
gridStep = maxGridStep
gridRad = calcRad()
}
while (gridRad > minGridRad * 2 && gridStep > minGridStep) {
gridStep /= 2
if (gridStep < minGridStep)
gridStep = minGridStep
gridRad = calcRad()
}
// Calculate alpha for subgrid. Smaller the perceived spacing, more transparent subgrid is.
helperGrid.subdivAlpha = 2 * (1 - (minGridRad / gridRad))
}
environment: sceneEnv
SceneEnvironment {
id: sceneEnv
@@ -85,13 +44,13 @@ View3D {
HelperGrid {
id: helperGrid
lines: gridArea / gridStep
step: gridStep
orthoMode: !sceneView.usePerspective
distance: sceneView.cameraDistance
}
PointLight {
id: sceneLight
position: usePerspective ? scenePerspectiveCamera.position
position: sceneView.usePerspective ? scenePerspectiveCamera.position
: sceneOrthoCamera.position
quadraticFade: 0
linearFade: 0
@@ -115,7 +74,7 @@ View3D {
y: 600
eulerRotation.x: -45
clipFar: 100000
clipNear: -10000
clipNear: -100000
}
}
}

View File

@@ -0,0 +1,22 @@
VARYING vec3 pos;
VARYING float worldPos;
void MAIN()
{
if (orthoMode) {
// No fadeout in orthographic mode
FRAGCOLOR = vec4(color.xyz, 1);
} else {
vec3 camDir = CAMERA_POSITION - worldPos;
vec3 camLevel = vec3(camDir.x, 0, camDir.z);
float depth;
depth = length(camDir);
float cosAngle = dot(normalize(camDir), normalize(camLevel));
float angleDepth = density * pow(cosAngle, 8);
float alpha = generalAlpha * clamp((1.0 - ((angleDepth * depth - alphaStartDepth) / (alphaEndDepth - alphaStartDepth))), 0, 1);
if (alpha > 0.01)
FRAGCOLOR = vec4(color.x * alpha, color.y * alpha, color.z * alpha, alpha);
else
discard;
}
}

View File

@@ -0,0 +1,10 @@
VARYING vec3 pos;
VARYING vec3 worldPos;
void MAIN()
{
pos = VERTEX;
vec4 pos4 = vec4(pos, 1.0);
POSITION = MODELVIEWPROJECTION_MATRIX * pos4;
worldPos = (MODEL_MATRIX * pos4).xyz;
}