From f27e8868eb730b021c675294ec3ea20619d5f7ce Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 28 Mar 2018 12:25:12 +1300 Subject: [PATCH 1/6] Add HMD JSDoc --- .../src/scripting/HMDScriptingInterface.h | 257 +++++++++++++++++- .../AbstractHMDScriptingInterface.h | 21 ++ tools/jsdoc/plugins/hifi.js | 5 +- 3 files changed, 278 insertions(+), 5 deletions(-) diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index ef8ea95704..1acafab361 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -24,6 +24,36 @@ class QScriptEngine; #include +/**jsdoc + * The HMD API provides access to the HMD used in VR display mode. + * + * @namespace HMD + * @property {Vec3} position - The position of the HMD if currently in VR display mode, otherwise + * {@link Vec3(0)|Vec3.ZERO}. Read-only. + * @property {Quat} orientation - The orientation of the HMD if currently in VR display mode, otherwise + * {@link Quat(0)|Quat.IDENTITY}.Read-only. + * @property {boolean} active - true if the display mode is HMD, otherwise false. Read-only. + * @property {boolean} mounted - true if currently in VR display mode and the HMD is being worn, otherwise + * false. Read-only. + * + * @property {number} playerHeight - The real-world height of the user. Read-only. Currently always returns a + * value of 1.755. + * @property {number} eyeHeight - The real-world height of the user's eyes. Read-only. Currently always returns a + * value of 1.655. + * @property {number} ipd - The inter-pupillary distance (distance between eyes) of the user, used for rendering. Defaults to + * the human average of 0.064 unless set by the HMD. Read-only. + * @property {number} ipdScale=1.0 - A scale factor applied to the ipd property value. + * + * @property {boolean} showTablet - true if the tablet is being displayed, false otherwise. + * Read-only. + * @property {boolean} tabletContextualMode - true if the tablet has been opened in contextual mode, otherwise + * false. In contextual mode, the tablet has been opened at a specific world position and orientation rather + * than at a position and orientation relative to the user. Read-only. + * @property {Uuid} tabletID - The UUID of the tablet body model overlay. + * @property {Uuid} tabletScreenID - The UUID of the tablet's screen overlay. + * @property {Uuid} homeButtonID - The UUID of the tablet's "home" button overlay. + * @property {Uuid} homeButtonHighlightID - The UUID of the tablet's "home" button highlight overlay. + */ class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Dependency { Q_OBJECT Q_PROPERTY(glm::vec3 position READ getPosition) @@ -37,26 +67,200 @@ class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Depen Q_PROPERTY(QUuid tabletScreenID READ getCurrentTabletScreenID WRITE setCurrentTabletScreenID) public: + + /**jsdoc + * Calculate the intersection of a ray with the HUD overlay. + * @function HMD.calculateRayUICollisionPoint + * @param {Vec3} position - The origin of the ray. + * @param {Vec3} direction - The direction of the ray. + * @returns {Vec3} The point of intersection with the HUD overlay if it intersects, otherwise {@link Vec3(0)|Vec3.ZERO}. + */ Q_INVOKABLE glm::vec3 calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction) const; + + /**jsdoc + * Get the 2D HUD overlay coordinates of a 3D point on the HUD overlay. + * 2D HUD overlay coordinates are pixels with the origin at the top left of the overlay. + * @function HMD.overlayFromWorldPoint + * @param {Vec3} position - The point on the HUD overlay in world coordinates. + * @returns {Vec2} The point on the HUD overlay in HUD coordinates. + * @example Draw a square on the HUD overlay in the direction you're looking. + * var hudIntersection = HMD.calculateRayUICollisionPoint(MyAvatar.getHeadPosition(), + * Quat.getForward(MyAvatar.headOrientation)); + * var hudPoint = HMD.overlayFromWorldPoint(hudIntersection); + * + * var DIMENSIONS = { x: 50, y: 50 }; + * var square = Overlays.addOverlay("rectangle", { + * x: hudPoint.x - DIMENSIONS.x / 2, + * y: hudPoint.y - DIMENSIONS.y / 2, + * width: DIMENSIONS.x, + * height: DIMENSIONS.y, + * color: { red: 255, green: 0, blue: 0 } + * }); + * + * Script.scriptEnding.connect(function () { + * Overlays.deleteOverlay(square); + * }); + */ Q_INVOKABLE glm::vec2 overlayFromWorldPoint(const glm::vec3& position) const; + + /**jsdoc + * Get the 3D world coordinates of a 2D point on the HUD overlay. + * 2D HUD overlay coordinates are pixels with the origin at the top left of the overlay. + * @function HMD.worldPointFromOverlay + * @param {Vec2} coordinates - The point on the HUD overlay in HUD coordinates. + * @returns {Vec3} The point on the HUD overlay in world coordinates. + */ Q_INVOKABLE glm::vec3 worldPointFromOverlay(const glm::vec2& overlay) const; + + /**jsdoc + * Get the 2D point on the HUD overlay represented by given spherical coordinates. + * 2D HUD overlay coordinates are pixels with the origin at the top left of the overlay. + * Spherical coordinates are polar coordinates in radians with { x: 0, y: 0 } being the center of the HUD + * overlay. + * @function HMD.sphericalToOverlay + * @param {Vec2} sphericalPos - The point on the HUD overlay in spherical coordinates. + * @returns {Vec2} The point on the HUD overlay in HUD coordinates. + */ Q_INVOKABLE glm::vec2 sphericalToOverlay(const glm::vec2 & sphericalPos) const; + + /**jsdoc + * Get the spherical coordinates of a 2D point on the HUD overlay. + * 2D HUD overlay coordinates are pixels with the origin at the top left of the overlay. + * Spherical coordinates are polar coordinates in radians with { x: 0, y: 0 } being the center of the HUD + * overlay. + * @function HMD.overlayToSpherical + * @param {Vec2} overlayPos - The point on the HUD overlay in HUD coordinates. + * @returns {Vec2} The point on the HUD overlay in spherical coordinates. + */ Q_INVOKABLE glm::vec2 overlayToSpherical(const glm::vec2 & overlayPos) const; + + /**jsdoc + * Recenter the HMD HUD to the current HMD position and orientation. + * @function HMD.centerUI + */ + Q_INVOKABLE void centerUI(); + + + /**jsdoc + * Get the name of the HMD audio input device. + * @function HMD.preferredAudioInput + * @returns {string} The name of the HMD audio input device if in HMD mode, otherwise an empty string. + */ Q_INVOKABLE QString preferredAudioInput() const; + + /**jsdoc + * Get the name of the HMD audio output device. + * @function HMD.preferredAudioOutput + * @returns {string} The name of the HMD audio output device if in HMD mode, otherwise an empty string. + */ Q_INVOKABLE QString preferredAudioOutput() const; + + /**jsdoc + * Check whether there is an HMD available. + * @function HMD.isHMDAvailable + * @param {string} [name=""] - The name of the HMD to check for, e.g., "Oculus Rift". The name is the same as + * may be displayed in Interface's "Display" menu. If no name is specified then any HMD matches. + * @returns {boolean} true if an HMD of the specified name is available, otherwise + * false. + * @example Report on HMD availability. + * print("Is any HMD available: " + HMD.isHMDAvailable()); + * print("Is an Oculus Rift HMD available: " + HMD.isHMDAvailable("Oculus Rift")); + * print("Is a Vive HMD available: " + HMD.isHMDAvailable("OpenVR (Vive)")); + */ Q_INVOKABLE bool isHMDAvailable(const QString& name = ""); + + /**jsdoc + * Check whether there is an HMD head controller available. + * @function HMD.isHeadControllerAvailable + * @param {string} [name=""] - The name of the HMD head controller to check for, e.g., "Oculus". If no name is + * specified then any HMD head controller matches. + * @returns {boolean} true if an HMD head controller of the specified name is available, + * otherwise false. + * @example Report HMD head controller availability. + * print("Is any HMD head controller available: " + HMD.isHeadControllerAvailable()); + * print("Is an Oculus head controller available: " + HMD.isHeadControllerAvailable("Oculus")); + * print("Is a Vive head controller available: " + HMD.isHeadControllerAvailable("OpenVR")); + */ Q_INVOKABLE bool isHeadControllerAvailable(const QString& name = ""); + + /**jsdoc + * Check whether there are HMD hand controllers available. + * @function HMD.isHandControllerAvailable + * @param {string} [name=""] - The name of the HMD hand controller to check for, e.g., "Oculus". If no name is + * specified then any HMD hand controller matches. + * @returns {boolean} true if an HMD hand controller of the specified name is available, + * otherwise false. + * @example Report HMD hand controller availability. + * print("Are any HMD hand controllers available: " + HMD.isHandControllerAvailable()); + * print("Are Oculus hand controllers available: " + HMD.isHandControllerAvailable("Oculus")); + * print("Are Vive hand controllers available: " + HMD.isHandControllerAvailable("OpenVR")); + */ Q_INVOKABLE bool isHandControllerAvailable(const QString& name = ""); + + /**jsdoc + * Check whether there are specific HMD controllers available. + * @function HMD.isSubdeviceContainingNameAvailable + * @param {string} - The name of the HMD controller to check for, e.g., "OculusTouch". + * @returns {boolean} true if an HMD controller with a name containing the specified name is + * available, otherwise false. + * @example Report if particular Oculus controllers are available. + * print("Is an Oculus Touch controller available: " + HMD.isSubdeviceContainingNameAvailable("Touch")); + * print("Is an Oculus Remote controller available: " + HMD.isSubdeviceContainingNameAvailable("Remote")); + */ Q_INVOKABLE bool isSubdeviceContainingNameAvailable(const QString& name); + /**jsdoc + * Signal that models of the HMD hand controllers being used should be displayed. The models are displayed at their actual, + * real-world locations. + * @function HMD.requestShowHandControllers + * @example Show your hand controllers for 10 seconds. + * HMD.requestShowHandControllers(); + * Script.setTimeout(function () { + * HMD.requestHideHandControllers(); + * }, 10000); + */ Q_INVOKABLE void requestShowHandControllers(); + + /**jsdoc + * Signal that it is no longer necessary to display models of the HMD hand controllers being used. If no other scripts + * want the models displayed then they are no longer displayed. + * @function HMD.requestHideHandControllers + */ Q_INVOKABLE void requestHideHandControllers(); + + /**jsdoc + * Check whether any script wants models of the HMD hand controllers displayed. Requests are made and canceled using + * {@link HMD.requestShowHandControllers|requestShowHandControllers} and + * {@link HMD.requestHideHandControllers|requestHideHandControllers}. + * @function HMD.shouldShowHandControllers + * @returns {boolean} true if any script is requesting that HMD hand controller models be displayed. + */ Q_INVOKABLE bool shouldShowHandControllers() const; + + /**jsdoc + * Causes the borders and decorations in HUD windows to be enlarged when the laser intersects them in HMD mode. By default, + * borders and decorations are not enlarged. + * @function HMD.activateHMDHandMouse + */ Q_INVOKABLE void activateHMDHandMouse(); + + /**jsdoc + * Causes the border and decorations in HUD windows to no longer be enlarged when the laser intersects them in HMD mode. By + * default, borders and decorations are not enlarged. + * @function HMD.deactivateHMDHandMouse + */ Q_INVOKABLE void deactivateHMDHandMouse(); + + /**jsdoc + * Suppress the activation of the HMD-provided keyboard, if any. Successful calls should be balanced with a call to + * {@link HMD.unspressKeyboard|unspressKeyboard} within a reasonable amount of time. + * @function HMD.suppressKeyboard + * @returns {boolean} true if the current HMD provides a keyboard and it was successfully suppressed (e.g., it + * isn't being displayed), otherwise false. + */ /// Suppress the activation of any on-screen keyboard so that a script operation will /// not be interrupted by a keyboard popup /// Returns false if there is already an active keyboard displayed. @@ -65,21 +269,68 @@ public: /// call to unsuppressKeyboard() within a reasonable amount of time Q_INVOKABLE bool suppressKeyboard(); + /**jsdoc + * Unsuppress the activation of the HMD-provided keyboard, if any. + * @function HMD.unsuppressKeyboard + */ /// Enable the keyboard following a suppressKeyboard call Q_INVOKABLE void unsuppressKeyboard(); + /**jsdoc + * Check whether the HMD-provided keyboard, if any, is visible. + * @function HMD.isKeyboardVisible + * @returns {boolean} true if the current HMD provides a keyboard and it is visible, otherwise + * false. + */ /// Query the display plugin to determine the current VR keyboard visibility Q_INVOKABLE bool isKeyboardVisible(); - // rotate the overlay UI sphere so that it is centered about the the current HMD position and orientation - Q_INVOKABLE void centerUI(); - + /**jsdoc + * Closes the tablet if it is open. + * @function HMD.closeTablet + */ Q_INVOKABLE void closeTablet(); + /**jsdoc + * Opens the tablet if the tablet is used in the current display mode and it isn't already showing, and sets the tablet to + * contextual mode if requested. In contextual mode, the page displayed on the tablet is wholly controlled by script (i.e., + * the user cannot navigate to another). + * @function HMD.openTablet + * @param {boolean} [contextualMode=false] - If true then the tablet is opened at a specific position and + * orientation already set by the script, otherwise it opens at a position and orientation relative to the user. For + * contextual mode, set the world or local position and orientation of the HMD.tabletID overlay. + */ Q_INVOKABLE void openTablet(bool contextualMode = false); signals: + /**jsdoc + * Triggered when a request to show or hide models of the HMD hand controllers is made using + * {@link HMD.requestShowHandControllers|requestShowHandControllers} or + * {@link HMD.requestHideHandControllers|requestHideHandControllers}. + * @function HMD.shouldShowHandControllersChanged + * @returns {Signal} + * @example Report when showing of hand controllers changes. + * function onShouldShowHandControllersChanged() { + * print("Should show hand controllers: " + HMD.shouldShowHandControllers()); + * } + * HMD.shouldShowHandControllersChanged.connect(onShouldShowHandControllersChanged); + * + * HMD.requestShowHandControllers(); + * Script.setTimeout(function () { + * HMD.requestHideHandControllers(); + * }, 10000); + */ bool shouldShowHandControllersChanged(); + + /**jsdoc + * Triggered when the HMD.mounted property value changes. + * @function HMD.mountedChanged + * @returns {Signal} + * @example Report when there's a change in the HMD being worn. + * HMD.mountedChanged.connect(function () { + * print("Mounted changed. HMD is mounted: " + HMD.mounted); + * }); + */ void mountedChanged(); public: diff --git a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h index f260fa959f..36e1952d3c 100644 --- a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h +++ b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h @@ -12,6 +12,7 @@ #include +// These properties have JSDoc documentation in HMDScriptingInterface.h. class AbstractHMDScriptingInterface : public QObject { Q_OBJECT Q_PROPERTY(bool active READ isHMDMode) @@ -30,7 +31,27 @@ public: bool isHMDMode() const; signals: + /**jsdoc + * Triggered when the HMD.ipdScale property value changes. + * @function HMD.IPDScaleChanged + * @returns {Signal} + */ void IPDScaleChanged(); + + /**jsdoc + * Triggered when Interface's display mode changes and when the user puts on or takes off their HMD. + * @function HMD.displayModeChanged + * @param {boolean} isHMDMode - true if the display mode is HMD, otherwise false. This is the + * same value as provided by HMD.active. + * @returns {Signal} + * @example Report when the display mode changes. + * HMD.displayModeChanged.connect(function (isHMDMode) { + * print("Display mode changed"); + * print("isHMD = " + isHMD); + * print("HMD.active = " + HMD.active); + * print("HMD.mounted = " + HMD.mounted); + * }); + */ void displayModeChanged(bool isHMDMode); private: diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js index 1f73f14b2b..e4da94ccd5 100644 --- a/tools/jsdoc/plugins/hifi.js +++ b/tools/jsdoc/plugins/hifi.js @@ -24,11 +24,12 @@ exports.handlers = { '../../libraries/animation/src', '../../libraries/avatars/src', '../../libraries/controllers/src/controllers/', - '../../libraries/graphics-scripting/src/graphics-scripting/', + '../../libraries/display-plugins/src/display-plugins/', '../../libraries/entities/src', + '../../libraries/graphics-scripting/src/graphics-scripting/', '../../libraries/model-networking/src/model-networking/', - '../../libraries/octree/src', '../../libraries/networking/src', + '../../libraries/octree/src', '../../libraries/physics/src', '../../libraries/pointers/src', '../../libraries/script-engine/src', From b35ee5ce8aece5472e7b8a650192ff6b6ffa667a Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 28 Mar 2018 12:25:49 +1300 Subject: [PATCH 2/6] Fix JSDoc links to Vec3 constants --- libraries/entities/src/EntityItemProperties.cpp | 16 ++++++++-------- .../entities/src/EntityScriptingInterface.h | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index f9a96d2293..90d6d942fd 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -481,13 +481,13 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Vec3} position=0,0,0 - The position of the entity. * @property {Quat} rotation=0,0,0,1 - The orientation of the entity with respect to world coordinates. * @property {Vec3} registrationPoint=0.5,0.5,0.5 - The point in the entity that is set to the entity's position and is rotated - * about, {@link Vec3|Vec3.ZERO} – {@link Vec3|Vec3.ONE}. A value of {@link Vec3|Vec3.ZERO} is the entity's - * minimum x, y, z corner; a value of {@link Vec3|Vec3.ONE} is the entity's maximum x, y, z corner. + * about, {@link Vec3(0)|Vec3.ZERO} – {@link Vec3(0)|Vec3.ONE}. A value of {@link Vec3(0)|Vec3.ZERO} is the entity's + * minimum x, y, z corner; a value of {@link Vec3(0)|Vec3.ONE} is the entity's maximum x, y, z corner. * * @property {Vec3} naturalPosition=0,0,0 - The center of the entity's unscaled mesh model if it has one, otherwise - * {@link Vec3|Vec3.ZERO}. Read-only. + * {@link Vec3(0)|Vec3.ZERO}. Read-only. * @property {Vec3} naturalDimensions - The dimensions of the entity's unscaled mesh model if it has one, otherwise - * {@link Vec3|Vec3.ONE}. Read-only. + * {@link Vec3(0)|Vec3.ONE}. Read-only. * * @property {Vec3} velocity=0,0,0 - The linear velocity of the entity in m/s with respect to world coordinates. * @property {number} damping=0.39347 - How much to slow down the linear velocity of an entity over time, 0.0 @@ -504,13 +504,13 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Vec3} gravity=0,0,0 - The acceleration due to gravity in m/s2 that the entity should move with, in * world coordinates. Set to { x: 0, y: -9.8, z: 0 } to simulate Earth's gravity. Gravity is applied to an * entity's motion only if its dynamic property is true. If changing an entity's - * gravity from {@link Vec3|Vec3.ZERO}, you need to give it a small velocity in order to kick off - * physics simulation. + * gravity from {@link Vec3(0)|Vec3.ZERO}, you need to give it a small velocity in order to kick + * off physics simulation. * The gravity value is applied in addition to the acceleration value. * @property {Vec3} acceleration=0,0,0 - A general acceleration in m/s2 that the entity should move with, in world * coordinates. The acceleration is applied to an entity's motion only if its dynamic property is - * true. If changing an entity's acceleration from {@link Vec3|Vec3.ZERO}, you need to give it a - * small velocity in order to kick off physics simulation. + * true. If changing an entity's acceleration from {@link Vec3(0)|Vec3.ZERO}, you need to give it + * a small velocity in order to kick off physics simulation. * The acceleration value is applied in addition to the gravity value. * @property {number} restitution=0.5 - The "bounciness" of an entity when it collides, 0.0 – * 0.99. The higher the value, the more bouncy. diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 9613a7a310..633f427342 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -699,7 +699,7 @@ public slots: * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. * @param {Vec3} voxelCoords - The voxel coordinates. May be fractional and outside the entity's bounding box. * @returns {Vec3} The world coordinates of the voxelCoords if the entityID is a - * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. + * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. * @example Create a PolyVox cube with the 0,0,0 voxel replaced by a sphere. * // Cube PolyVox with 0,0,0 voxel missing. * var polyVox = Entities.addEntity({ @@ -734,7 +734,7 @@ public slots: * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. * @param {Vec3} worldCoords - The world coordinates. May be outside the entity's bounding box. * @returns {Vec3} The voxel coordinates of the worldCoords if the entityID is a - * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. The value may be fractional. + * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. The value may be fractional. */ // FIXME move to a renderable entity interface Q_INVOKABLE glm::vec3 worldCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 worldCoords); @@ -746,7 +746,7 @@ public slots: * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. * @param {Vec3} voxelCoords - The voxel coordinates. May be fractional and outside the entity's bounding box. * @returns {Vec3} The local coordinates of the voxelCoords if the entityID is a - * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. + * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. * @example Get the world dimensions of a voxel in a PolyVox entity. * var polyVox = Entities.addEntity({ * type: "PolyVox", @@ -768,7 +768,7 @@ public slots: * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. * @param {Vec3} localCoords - The local coordinates. May be outside the entity's bounding box. * @returns {Vec3} The voxel coordinates of the worldCoords if the entityID is a - * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. The value may be fractional. + * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. The value may be fractional. */ // FIXME move to a renderable entity interface Q_INVOKABLE glm::vec3 localCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 localCoords); From 1bcb9738f0a5ee4e7ed50c6bb5581c2cde50f414 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 28 Mar 2018 12:26:08 +1300 Subject: [PATCH 3/6] Miscellaneous fixes noticed in passing --- interface/resources/qml/windows/Decoration.qml | 2 +- libraries/entities/src/EntityItemProperties.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/windows/Decoration.qml b/interface/resources/qml/windows/Decoration.qml index 843ae25596..f8fd9f4e6c 100644 --- a/interface/resources/qml/windows/Decoration.qml +++ b/interface/resources/qml/windows/Decoration.qml @@ -1,5 +1,5 @@ // -// DefaultFrame.qml +// Decoration.qml // // Created by Bradley Austin Davis on 12 Jan 2016 // Copyright 2016 High Fidelity, Inc. diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 90d6d942fd..8602f60e3d 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -476,7 +476,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {boolean} visible=true - Whether or not the entity is rendered. If true then the entity is rendered. * @property {boolean} canCastShadows=true - Whether or not the entity casts shadows. Currently applicable only to * {@link Entities.EntityType|Model} and {@link Entities.EntityType|Shape} entities. Shadows are cast if inside a - * {@link Entities.EntityType|Zone} entity with castShadows enabled in its {@link Entities.EntityProperties-Zone|keyLight} property. + * {@link Entities.EntityType|Zone} entity with castShadows enabled in its + * {@link Entities.EntityProperties-Zone|keyLight} property. * * @property {Vec3} position=0,0,0 - The position of the entity. * @property {Quat} rotation=0,0,0,1 - The orientation of the entity with respect to world coordinates. From 0c069574c59042d59f6b46b881e211f66bb13d33 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 30 Mar 2018 16:35:51 -0700 Subject: [PATCH 4/6] forward pipelines for primitives --- .../src/RenderableShapeEntityItem.cpp | 27 +++++- .../procedural/src/procedural/Procedural.cpp | 63 ++++++++------ .../procedural/src/procedural/Procedural.h | 15 ++-- .../src/procedural/ProceduralSkybox.cpp | 6 +- .../render-utils/src/DefaultMaterials.slh | 23 +++++ .../render-utils/src/DeferredBufferWrite.slh | 9 +- libraries/render-utils/src/GeometryCache.cpp | 75 ++++++++++++---- libraries/render-utils/src/GeometryCache.h | 5 +- libraries/render-utils/src/LightAmbient.slh | 8 +- libraries/render-utils/src/LightingModel.slh | 20 +++-- libraries/render-utils/src/Shadows_shared.slh | 2 - libraries/render-utils/src/forward_simple.slf | 85 ++++++++++++++++++ .../src/forward_simple_textured.slf | 51 +++++++++++ .../forward_simple_textured_transparent.slf | 52 +++++++++++ .../src/forward_simple_textured_unlit.slf | 35 ++++++++ .../src/forward_simple_transparent.slf | 87 +++++++++++++++++++ libraries/render-utils/src/simple.slf | 57 ++++-------- libraries/render-utils/src/simple.slv | 3 +- libraries/render-utils/src/simple_fade.slv | 3 +- .../render-utils/src/simple_textured.slf | 35 ++------ .../render-utils/src/simple_transparent.slf | 65 ++++++++++++++ .../src/simple_transparent_textured.slf | 41 ++------- 22 files changed, 587 insertions(+), 180 deletions(-) create mode 100644 libraries/render-utils/src/DefaultMaterials.slh create mode 100644 libraries/render-utils/src/forward_simple.slf create mode 100644 libraries/render-utils/src/forward_simple_textured.slf create mode 100644 libraries/render-utils/src/forward_simple_textured_transparent.slf create mode 100644 libraries/render-utils/src/forward_simple_textured_unlit.slf create mode 100644 libraries/render-utils/src/forward_simple_transparent.slf create mode 100644 libraries/render-utils/src/simple_transparent.slf diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index b05854da4e..62b2794c94 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -18,6 +18,18 @@ #include "render-utils/simple_vert.h" #include "render-utils/simple_frag.h" +#include "render-utils/simple_transparent_frag.h" +#include "render-utils/forward_simple_frag.h" +#include "render-utils/forward_simple_transparent_frag.h" + +#include + +#if defined(USE_GLES) +static bool DISABLE_DEFERRED = true; +#else +static const QString RENDER_FORWARD{ "HIFI_RENDER_FORWARD" }; +static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD); +#endif #include "RenderPipelines.h" @@ -35,13 +47,20 @@ static const float SPHERE_ENTITY_SCALE = 0.5f; ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Parent(entity) { _procedural._vertexSource = simple_vert::getSource(); - _procedural._fragmentSource = simple_frag::getSource(); + _procedural._opaquefragmentSource = DISABLE_DEFERRED ? forward_simple_frag::getSource() : simple_frag::getSource(); + _procedural._transparentfragmentSource = DISABLE_DEFERRED ? forward_simple_transparent_frag::getSource() : simple_transparent_frag::getSource(); _procedural._opaqueState->setCullMode(gpu::State::CULL_NONE); _procedural._opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL); PrepareStencil::testMaskDrawShape(*_procedural._opaqueState); _procedural._opaqueState->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + _procedural._transparentState->setCullMode(gpu::State::CULL_BACK); + _procedural._transparentState->setDepthTest(true, true, gpu::LESS_EQUAL); + PrepareStencil::testMask(*_procedural._transparentState); + _procedural._transparentState->setBlendFunction(true, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); } bool ShapeEntityRenderer::needsRenderUpdate() const { @@ -216,9 +235,9 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { if (mat) { outColor = glm::vec4(mat->getAlbedo(), mat->getOpacity()); if (_procedural.isReady()) { - _procedural.prepare(batch, _position, _dimensions, _orientation); outColor = _procedural.getColor(outColor); outColor.a *= _procedural.isFading() ? Interpolate::calculateFadeRatio(_procedural.getFadeStartTime()) : 1.0f; + _procedural.prepare(batch, _position, _dimensions, _orientation, outColor); proceduralRender = true; } } @@ -230,9 +249,9 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { if (proceduralRender) { if (render::ShapeKey(args->_globalShapeKey).isWireframe()) { - geometryCache->renderWireShape(batch, geometryShape, outColor); + geometryCache->renderWireShapeColor(batch, geometryShape, outColor); } else { - geometryCache->renderShape(batch, geometryShape, outColor); + geometryCache->renderShapeColor(batch, geometryShape, outColor); } } else if (!useMaterialPipeline()) { // FIXME, support instanced multi-shape rendering using multidraw indirect diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index d8b72c8838..0488bb2eb7 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -219,7 +219,29 @@ bool Procedural::isReady() const { return true; } -void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation) { +std::string Procedural::replaceProceduralBlock(const std::string& fragmentSource) { + std::string fragmentShaderSource = fragmentSource; + size_t replaceIndex = fragmentShaderSource.find(PROCEDURAL_COMMON_BLOCK); + if (replaceIndex != std::string::npos) { + fragmentShaderSource.replace(replaceIndex, PROCEDURAL_COMMON_BLOCK.size(), ProceduralCommon_frag::getSource()); + } + + replaceIndex = fragmentShaderSource.find(PROCEDURAL_VERSION); + if (replaceIndex != std::string::npos) { + if (_data.version == 1) { + fragmentShaderSource.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V1 1"); + } else if (_data.version == 2) { + fragmentShaderSource.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V2 1"); + } + } + replaceIndex = fragmentShaderSource.find(PROCEDURAL_BLOCK); + if (replaceIndex != std::string::npos) { + fragmentShaderSource.replace(replaceIndex, PROCEDURAL_BLOCK.size(), _shaderSource.toLocal8Bit().data()); + } + return fragmentShaderSource; +} + +void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation, const glm::vec4& color) { _entityDimensions = size; _entityPosition = position; _entityOrientation = glm::mat3_cast(orientation); @@ -242,49 +264,36 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm } // Build the fragment shader - std::string fragmentShaderSource = _fragmentSource; - size_t replaceIndex = fragmentShaderSource.find(PROCEDURAL_COMMON_BLOCK); - if (replaceIndex != std::string::npos) { - fragmentShaderSource.replace(replaceIndex, PROCEDURAL_COMMON_BLOCK.size(), ProceduralCommon_frag::getSource()); - } - - replaceIndex = fragmentShaderSource.find(PROCEDURAL_VERSION); - if (replaceIndex != std::string::npos) { - if (_data.version == 1) { - fragmentShaderSource.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V1 1"); - } else if (_data.version == 2) { - fragmentShaderSource.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V2 1"); - } - } - replaceIndex = fragmentShaderSource.find(PROCEDURAL_BLOCK); - if (replaceIndex != std::string::npos) { - fragmentShaderSource.replace(replaceIndex, PROCEDURAL_BLOCK.size(), _shaderSource.toLocal8Bit().data()); - } + std::string opaqueShaderSource = replaceProceduralBlock(_opaquefragmentSource); + std::string transparentShaderSource = replaceProceduralBlock(_transparentfragmentSource); // Leave this here for debugging // qCDebug(procedural) << "FragmentShader:\n" << fragmentShaderSource.c_str(); - _fragmentShader = gpu::Shader::createPixel(fragmentShaderSource); - _shader = gpu::Shader::createProgram(_vertexShader, _fragmentShader); + _opaqueFragmentShader = gpu::Shader::createPixel(opaqueShaderSource); + _opaqueShader = gpu::Shader::createProgram(_vertexShader, _opaqueFragmentShader); + _transparentFragmentShader = gpu::Shader::createPixel(transparentShaderSource); + _transparentShader = gpu::Shader::createProgram(_vertexShader, _transparentFragmentShader); gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("iChannel0"), 0)); slotBindings.insert(gpu::Shader::Binding(std::string("iChannel1"), 1)); slotBindings.insert(gpu::Shader::Binding(std::string("iChannel2"), 2)); slotBindings.insert(gpu::Shader::Binding(std::string("iChannel3"), 3)); - gpu::Shader::makeProgram(*_shader, slotBindings); + gpu::Shader::makeProgram(*_opaqueShader, slotBindings); + gpu::Shader::makeProgram(*_transparentShader, slotBindings); - _opaquePipeline = gpu::Pipeline::create(_shader, _opaqueState); - _transparentPipeline = gpu::Pipeline::create(_shader, _transparentState); + _opaquePipeline = gpu::Pipeline::create(_opaqueShader, _opaqueState); + _transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState); for (size_t i = 0; i < NUM_STANDARD_UNIFORMS; ++i) { const std::string& name = STANDARD_UNIFORM_NAMES[i]; - _standardUniformSlots[i] = _shader->getUniforms().findLocation(name); + _standardUniformSlots[i] = _opaqueShader->getUniforms().findLocation(name); } _start = usecTimestampNow(); _frameCount = 0; } - batch.setPipeline(isFading() ? _transparentPipeline : _opaquePipeline); + batch.setPipeline(color.a < 1.0f ? _transparentPipeline : _opaquePipeline); if (_shaderDirty || _uniformsDirty) { setupUniforms(); @@ -324,7 +333,7 @@ void Procedural::setupUniforms() { // Set any userdata specified uniforms foreach(QString key, _data.uniforms.keys()) { std::string uniformName = key.toLocal8Bit().data(); - int32_t slot = _shader->getUniforms().findLocation(uniformName); + int32_t slot = _opaqueShader->getUniforms().findLocation(uniformName); if (gpu::Shader::INVALID_LOCATION == slot) { continue; } diff --git a/libraries/procedural/src/procedural/Procedural.h b/libraries/procedural/src/procedural/Procedural.h index 9c29a681f0..4e30a003d6 100644 --- a/libraries/procedural/src/procedural/Procedural.h +++ b/libraries/procedural/src/procedural/Procedural.h @@ -55,8 +55,8 @@ public: bool isReady() const; bool isEnabled() const { return _enabled; } - void prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation); - const gpu::ShaderPointer& getShader() const { return _shader; } + void prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation, const glm::vec4& color = glm::vec4(1)); + const gpu::ShaderPointer& getOpaqueShader() const { return _opaqueShader; } glm::vec4 getColor(const glm::vec4& entityColor); quint64 getFadeStartTime() const { return _fadeStartTime; } @@ -65,7 +65,8 @@ public: void setDoesFade(bool doesFade) { _doesFade = doesFade; } std::string _vertexSource; - std::string _fragmentSource; + std::string _opaquefragmentSource; + std::string _transparentfragmentSource; gpu::StatePointer _opaqueState { std::make_shared() }; gpu::StatePointer _transparentState { std::make_shared() }; @@ -106,8 +107,10 @@ protected: gpu::PipelinePointer _opaquePipeline; gpu::PipelinePointer _transparentPipeline; gpu::ShaderPointer _vertexShader; - gpu::ShaderPointer _fragmentShader; - gpu::ShaderPointer _shader; + gpu::ShaderPointer _opaqueFragmentShader; + gpu::ShaderPointer _transparentFragmentShader; + gpu::ShaderPointer _opaqueShader; + gpu::ShaderPointer _transparentShader; // Entity metadata glm::vec3 _entityDimensions; @@ -119,6 +122,8 @@ private: void setupUniforms(); void setupChannels(bool shouldCreate); + std::string replaceProceduralBlock(const std::string& fragmentSource); + mutable quint64 _fadeStartTime { 0 }; mutable bool _hasStartedFade { false }; mutable bool _isFading { false }; diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index 43633e47ad..0c6501928b 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -20,7 +20,7 @@ ProceduralSkybox::ProceduralSkybox() : graphics::Skybox() { _procedural._vertexSource = skybox_vert::getSource(); - _procedural._fragmentSource = skybox_frag::getSource(); + _procedural._opaquefragmentSource = skybox_frag::getSource(); // Adjust the pipeline state for background using the stencil test _procedural.setDoesFade(false); // Must match PrepareStencil::STENCIL_BACKGROUND @@ -61,8 +61,8 @@ void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, auto& procedural = skybox._procedural; procedural.prepare(batch, glm::vec3(0), glm::vec3(1), glm::quat()); - auto textureSlot = procedural.getShader()->getTextures().findLocation("cubeMap"); - auto bufferSlot = procedural.getShader()->getUniformBuffers().findLocation("skyboxBuffer"); + auto textureSlot = procedural.getOpaqueShader()->getTextures().findLocation("cubeMap"); + auto bufferSlot = procedural.getOpaqueShader()->getUniformBuffers().findLocation("skyboxBuffer"); skybox.prepare(batch, textureSlot, bufferSlot); batch.draw(gpu::TRIANGLE_STRIP, 4); } diff --git a/libraries/render-utils/src/DefaultMaterials.slh b/libraries/render-utils/src/DefaultMaterials.slh new file mode 100644 index 0000000000..afb3dc2b28 --- /dev/null +++ b/libraries/render-utils/src/DefaultMaterials.slh @@ -0,0 +1,23 @@ + +<@if not DEFAULT_MATERIAL_SLH@> +<@def DEFAULT_MATERIAL_SLH@> + +const float DEFAULT_ROUGHNESS = 0.9; +const float DEFAULT_SHININESS = 10.0; +const float DEFAULT_METALLIC = 0.0; +const vec3 DEFAULT_SPECULAR = vec3(0.1); +const vec3 DEFAULT_EMISSIVE = vec3(0.0); +const float DEFAULT_OCCLUSION = 1.0; +const float DEFAULT_SCATTERING = 0.0; +const vec3 DEFAULT_FRESNEL = DEFAULT_EMISSIVE; + +<@endif@> diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh index 2f6bfaeb61..49db49af2a 100644 --- a/libraries/render-utils/src/DeferredBufferWrite.slh +++ b/libraries/render-utils/src/DeferredBufferWrite.slh @@ -26,14 +26,7 @@ float evalOpaqueFinalAlpha(float alpha, float mapAlpha) { return mix(alpha, 1.0 - alpha, step(mapAlpha, alphaThreshold)); } -const float DEFAULT_ROUGHNESS = 0.9; -const float DEFAULT_SHININESS = 10.0; -const float DEFAULT_METALLIC = 0.0; -const vec3 DEFAULT_SPECULAR = vec3(0.1); -const vec3 DEFAULT_EMISSIVE = vec3(0.0); -const float DEFAULT_OCCLUSION = 1.0; -const float DEFAULT_SCATTERING = 0.0; -const vec3 DEFAULT_FRESNEL = DEFAULT_EMISSIVE; +<@include DefaultMaterials.slh@> void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 emissive, float occlusion, float scattering) { if (alpha != 1.0) { diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 3fd18a0eaf..52dc1d6cac 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -40,6 +40,7 @@ #include "simple_vert.h" #include "simple_textured_frag.h" +#include "simple_transparent_textured_frag.h" #include "simple_textured_unlit_frag.h" #include "simple_fade_vert.h" #include "simple_textured_fade_frag.h" @@ -49,6 +50,19 @@ #include "glowLine_vert.h" #include "glowLine_frag.h" +#include "forward_simple_textured_frag.h" +#include "forward_simple_textured_transparent_frag.h" +#include "forward_simple_textured_unlit_frag.h" + +#include "DeferredLightingEffect.h" + +#if defined(USE_GLES) +static bool DISABLE_DEFERRED = true; +#else +static const QString RENDER_FORWARD{ "HIFI_RENDER_FORWARD" }; +static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD); +#endif + #include "grid_frag.h" //#define WANT_DEBUG @@ -679,6 +693,7 @@ gpu::Stream::FormatPointer& getInstancedSolidFadeStreamFormat() { QHash GeometryCache::_simplePrograms; gpu::ShaderPointer GeometryCache::_simpleShader; +gpu::ShaderPointer GeometryCache::_transparentShader; gpu::ShaderPointer GeometryCache::_unlitShader; gpu::ShaderPointer GeometryCache::_simpleFadeShader; gpu::ShaderPointer GeometryCache::_unlitFadeShader; @@ -774,8 +789,12 @@ render::ShapePipelinePointer GeometryCache::getShapePipeline(bool textured, bool bool unlit, bool depthBias) { return std::make_shared(getSimplePipeline(textured, transparent, culled, unlit, depthBias, false, true), nullptr, - [](const render::ShapePipeline& , gpu::Batch& batch, render::Args*) { + [](const render::ShapePipeline& pipeline, gpu::Batch& batch, render::Args* args) { batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO, DependencyManager::get()->getWhiteTexture()); + DependencyManager::get()->setupKeyLightBatch(args, batch, + pipeline.pipeline->getProgram()->getUniformBuffers().findLocation("keyLightBuffer"), + pipeline.pipeline->getProgram()->getUniformBuffers().findLocation("lightAmbientBuffer"), + pipeline.pipeline->getProgram()->getUniformBuffers().findLocation("skyboxMap")); } ); } @@ -798,7 +817,7 @@ render::ShapePipelinePointer GeometryCache::getOpaqueShapePipeline(bool isFading return isFading ? _simpleOpaqueFadePipeline : _simpleOpaquePipeline; } -render::ShapePipelinePointer GeometryCache::getTransparentShapePipeline(bool isFading) { +render::ShapePipelinePointer GeometryCache::getTransparentShapePipeline(bool isFading) { return isFading ? _simpleTransparentFadePipeline : _simpleTransparentPipeline; } @@ -826,6 +845,20 @@ void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape, const glm::v _shapes[shape].drawWire(batch); } +void GeometryCache::renderShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color) { + batch.setInputFormat(getInstancedSolidStreamFormat()); + // Color must be set after input format + batch._glColor4f(color.r, color.g, color.b, color.a); + _shapes[shape].draw(batch); +} + +void GeometryCache::renderWireShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color) { + batch.setInputFormat(getInstancedSolidStreamFormat()); + // Color must be set after input format + batch._glColor4f(color.r, color.g, color.b, color.a); + _shapes[shape].drawWire(batch); +} + void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) { gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT); batch.setInputBuffer(gpu::Stream::COLOR, colorView); @@ -843,7 +876,7 @@ void GeometryCache::renderWireShapeInstances(gpu::Batch& batch, Shape shape, siz _shapes[shape].drawWireInstances(batch, count); } -void setupBatchFadeInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer, +void setupBatchFadeInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer, gpu::BufferPointer fadeBuffer1, gpu::BufferPointer fadeBuffer2, gpu::BufferPointer fadeBuffer3) { gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT); gpu::BufferView texCoord2View(fadeBuffer1, TEXCOORD4_ELEMENT); @@ -2003,7 +2036,7 @@ void GeometryCache::renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const auto program = gpu::Shader::createProgram(VS, PS); state->setCullMode(gpu::State::CULL_NONE); state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setBlendFunction(true, + state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); @@ -2231,29 +2264,40 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp static std::once_flag once; std::call_once(once, [&]() { auto VS = simple_vert::getShader(); - auto PS = simple_textured_frag::getShader(); - auto PSUnlit = simple_textured_unlit_frag::getShader(); + auto PS = DISABLE_DEFERRED ? forward_simple_textured_frag::getShader() : simple_textured_frag::getShader(); + auto PSTransparent = DISABLE_DEFERRED ? forward_simple_textured_transparent_frag::getShader() : simple_transparent_textured_frag::getShader(); + auto PSUnlit = DISABLE_DEFERRED ? forward_simple_textured_unlit_frag::getShader() : simple_textured_unlit_frag::getShader(); _simpleShader = gpu::Shader::createProgram(VS, PS); + _transparentShader = gpu::Shader::createProgram(VS, PSTransparent); _unlitShader = gpu::Shader::createProgram(VS, PSUnlit); gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("originalTexture"), render::ShapePipeline::Slot::MAP::ALBEDO)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), render::ShapePipeline::Slot::LIGHTING_MODEL)); + slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), render::ShapePipeline::Slot::KEY_LIGHT)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), render::ShapePipeline::Slot::LIGHT_AMBIENT_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), render::ShapePipeline::Slot::MAP::LIGHT_AMBIENT)); gpu::Shader::makeProgram(*_simpleShader, slotBindings); + gpu::Shader::makeProgram(*_transparentShader, slotBindings); gpu::Shader::makeProgram(*_unlitShader, slotBindings); }); } else { static std::once_flag once; std::call_once(once, [&]() { auto VS = simple_fade_vert::getShader(); - auto PS = simple_textured_fade_frag::getShader(); - auto PSUnlit = simple_textured_unlit_fade_frag::getShader(); + auto PS = DISABLE_DEFERRED ? forward_simple_textured_frag::getShader() : simple_textured_fade_frag::getShader(); + auto PSUnlit = DISABLE_DEFERRED ? forward_simple_textured_unlit_frag::getShader() : simple_textured_unlit_fade_frag::getShader(); _simpleFadeShader = gpu::Shader::createProgram(VS, PS); _unlitFadeShader = gpu::Shader::createProgram(VS, PSUnlit); gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("originalTexture"), render::ShapePipeline::Slot::MAP::ALBEDO)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), render::ShapePipeline::Slot::LIGHTING_MODEL)); + slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), render::ShapePipeline::Slot::KEY_LIGHT)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), render::ShapePipeline::Slot::LIGHT_AMBIENT_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), render::ShapePipeline::Slot::MAP::LIGHT_AMBIENT)); slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), render::ShapePipeline::Slot::MAP::FADE_MASK)); gpu::Shader::makeProgram(*_simpleFadeShader, slotBindings); gpu::Shader::makeProgram(*_unlitFadeShader, slotBindings); @@ -2282,7 +2326,8 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp PrepareStencil::testMaskDrawShapeNoAA(*state); } - gpu::ShaderPointer program = (config.isUnlit()) ? (config.isFading() ? _unlitFadeShader : _unlitShader) : (config.isFading() ? _simpleFadeShader : _simpleShader); + gpu::ShaderPointer program = (config.isUnlit()) ? (config.isFading() ? _unlitFadeShader : _unlitShader) : + (config.isFading() ? _simpleFadeShader : (config.isTransparent() ? _transparentShader : _simpleShader)); gpu::PipelinePointer pipeline = gpu::Pipeline::create(program, state); _simplePrograms.insert(config, pipeline); return pipeline; @@ -2363,11 +2408,11 @@ void renderFadeInstances(RenderArgs* args, gpu::Batch& batch, const glm::vec4& c pipeline->prepare(batch, args); if (isWire) { - DependencyManager::get()->renderWireFadeShapeInstances(batch, shape, data.count(), + DependencyManager::get()->renderWireFadeShapeInstances(batch, shape, data.count(), buffers[INSTANCE_COLOR_BUFFER], buffers[INSTANCE_FADE_BUFFER1], buffers[INSTANCE_FADE_BUFFER2], buffers[INSTANCE_FADE_BUFFER3]); } else { - DependencyManager::get()->renderFadeShapeInstances(batch, shape, data.count(), + DependencyManager::get()->renderFadeShapeInstances(batch, shape, data.count(), buffers[INSTANCE_COLOR_BUFFER], buffers[INSTANCE_FADE_BUFFER1], buffers[INSTANCE_FADE_BUFFER2], buffers[INSTANCE_FADE_BUFFER3]); } }); @@ -2383,15 +2428,15 @@ void GeometryCache::renderWireShapeInstance(RenderArgs* args, gpu::Batch& batch, renderInstances(args, batch, color, true, pipeline, shape); } -void GeometryCache::renderSolidFadeShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color, - int fadeCategory, float fadeThreshold, const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize, +void GeometryCache::renderSolidFadeShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color, + int fadeCategory, float fadeThreshold, const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize, const render::ShapePipelinePointer& pipeline) { assert(pipeline != nullptr); renderFadeInstances(args, batch, color, fadeCategory, fadeThreshold, fadeNoiseOffset, fadeBaseOffset, fadeBaseInvSize, false, pipeline, shape); } -void GeometryCache::renderWireFadeShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color, - int fadeCategory, float fadeThreshold, const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize, +void GeometryCache::renderWireFadeShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color, + int fadeCategory, float fadeThreshold, const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize, const render::ShapePipelinePointer& pipeline) { assert(pipeline != nullptr); renderFadeInstances(args, batch, color, fadeCategory, fadeThreshold, fadeNoiseOffset, fadeBaseOffset, fadeBaseInvSize, true, pipeline, shape); diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index e0ba99b09e..bec166aded 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -253,6 +253,8 @@ public: void renderWireShape(gpu::Batch& batch, Shape shape); void renderShape(gpu::Batch& batch, Shape shape, const glm::vec4& color); void renderWireShape(gpu::Batch& batch, Shape shape, const glm::vec4& color); + void renderShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color); + void renderWireShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color); size_t getShapeTriangleCount(Shape shape); void renderCube(gpu::Batch& batch); @@ -471,6 +473,7 @@ private: QHash _registeredGridBuffers; static gpu::ShaderPointer _simpleShader; + static gpu::ShaderPointer _transparentShader; static gpu::ShaderPointer _unlitShader; static gpu::ShaderPointer _simpleFadeShader; static gpu::ShaderPointer _unlitFadeShader; @@ -478,8 +481,6 @@ private: static render::ShapePipelinePointer _simpleTransparentPipeline; static render::ShapePipelinePointer _simpleOpaqueFadePipeline; static render::ShapePipelinePointer _simpleTransparentFadePipeline; - static render::ShapePipelinePointer _simpleOpaqueOverlayPipeline; - static render::ShapePipelinePointer _simpleTransparentOverlayPipeline; static render::ShapePipelinePointer _simpleWirePipeline; gpu::PipelinePointer _glowLinePipeline; diff --git a/libraries/render-utils/src/LightAmbient.slh b/libraries/render-utils/src/LightAmbient.slh index 008f29da01..b2377d1904 100644 --- a/libraries/render-utils/src/LightAmbient.slh +++ b/libraries/render-utils/src/LightAmbient.slh @@ -111,15 +111,11 @@ void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambie } <@endif@> - if (!(isObscuranceEnabled() > 0.0)) { - obscurance = 1.0; - } + obscurance = mix(1.0, obscurance, isObscuranceEnabled()); float lightEnergy = obscurance * getLightAmbientIntensity(ambient); - if (isAlbedoEnabled() > 0.0) { - diffuse *= albedo; - } + diffuse *= mix(vec3(1), albedo, isAlbedoEnabled()); lightEnergy *= isAmbientEnabled(); diffuse *= lightEnergy * isDiffuseEnabled(); diff --git a/libraries/render-utils/src/LightingModel.slh b/libraries/render-utils/src/LightingModel.slh index 2280d12465..3f615f11db 100644 --- a/libraries/render-utils/src/LightingModel.slh +++ b/libraries/render-utils/src/LightingModel.slh @@ -13,11 +13,19 @@ <@func declareLightingModel()@> +#ifndef PRECISIONQ +#ifdef GL_ES +#define PRECISIONQ highp +#else +#define PRECISIONQ +#endif +#endif + struct LightingModel { - vec4 _UnlitEmissiveLightmapBackground; - vec4 _ScatteringDiffuseSpecularAlbedo; - vec4 _AmbientDirectionalPointSpot; - vec4 _ShowContourObscuranceWireframe; + PRECISIONQ vec4 _UnlitEmissiveLightmapBackground; + PRECISIONQ vec4 _ScatteringDiffuseSpecularAlbedo; + PRECISIONQ vec4 _AmbientDirectionalPointSpot; + PRECISIONQ vec4 _ShowContourObscuranceWireframe; }; uniform lightingModelBuffer{ @@ -256,9 +264,7 @@ void evalFragShading(out vec3 diffuse, out vec3 specular, float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo) { vec4 shading = evalPBRShading(metallic, fresnel, surface); diffuse = vec3(shading.w); - if (isAlbedoEnabled() > 0.0) { - diffuse *= albedo; - } + diffuse *= mix(vec3(1.0), albedo, isAlbedoEnabled()); specular = shading.xyz; } diff --git a/libraries/render-utils/src/Shadows_shared.slh b/libraries/render-utils/src/Shadows_shared.slh index 0d49fc037e..bc8063e018 100644 --- a/libraries/render-utils/src/Shadows_shared.slh +++ b/libraries/render-utils/src/Shadows_shared.slh @@ -1,10 +1,8 @@ // glsl / C++ compatible source as interface for Shadows #ifdef __cplusplus # define MAT4 glm::mat4 -# define VEC3 glm::vec3 #else # define MAT4 mat4 -# define VEC3 vec3 #endif #define SHADOW_CASCADE_MAX_COUNT 4 diff --git a/libraries/render-utils/src/forward_simple.slf b/libraries/render-utils/src/forward_simple.slf new file mode 100644 index 0000000000..497afe93a3 --- /dev/null +++ b/libraries/render-utils/src/forward_simple.slf @@ -0,0 +1,85 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// forward_simple.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/15/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +<@include DefaultMaterials.slh@> + +<@include ForwardGlobalLight.slh@> +<$declareEvalSkyboxGlobalColor()$> + +<@include gpu/Transform.slh@> +<$declareStandardCameraTransform()$> + +// the interpolated normal +in vec3 _normal; +in vec3 _modelNormal; +in vec4 _color; +in vec2 _texCoord0; +in vec4 _eyePosition; + +layout(location = 0) out vec4 _fragColor0; + +//PROCEDURAL_COMMON_BLOCK + +#line 1001 +//PROCEDURAL_BLOCK + +#line 2030 +void main(void) { + vec3 normal = normalize(_normal.xyz); + vec3 diffuse = _color.rgb; + vec3 specular = DEFAULT_SPECULAR; + float shininess = DEFAULT_SHININESS; + float emissiveAmount = 0.0; + +#ifdef PROCEDURAL + +#ifdef PROCEDURAL_V1 + specular = getProceduralColor().rgb; + // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline + //specular = pow(specular, vec3(2.2)); + emissiveAmount = 1.0; +#else + emissiveAmount = getProceduralColors(diffuse, specular, shininess); +#endif + +#endif + + TransformCamera cam = getTransformCamera(); + vec3 fragPosition = _eyePosition.xyz; + + if (emissiveAmount > 0.0) { + _fragColor0 = vec4(evalSkyboxGlobalColor( + cam._viewInverse, + 1.0, + DEFAULT_OCCLUSION, + fragPosition, + normal, + diffuse, + specular, + DEFAULT_METALLIC, + max(0.0, 1.0 - shininess / 128.0)), + 1.0); + } else { + _fragColor0 = vec4(evalSkyboxGlobalColor( + cam._viewInverse, + 1.0, + DEFAULT_OCCLUSION, + fragPosition, + normal, + diffuse, + DEFAULT_FRESNEL, + length(specular), + max(0.0, 1.0 - shininess / 128.0)), + 1.0); + } +} diff --git a/libraries/render-utils/src/forward_simple_textured.slf b/libraries/render-utils/src/forward_simple_textured.slf new file mode 100644 index 0000000000..c88482c208 --- /dev/null +++ b/libraries/render-utils/src/forward_simple_textured.slf @@ -0,0 +1,51 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// forward_simple_textured.slf +// fragment shader +// +// Created by Clément Brisset on 5/29/15. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +<@include DefaultMaterials.slh@> + +<@include ForwardGlobalLight.slh@> +<$declareEvalSkyboxGlobalColor()$> + +<@include gpu/Transform.slh@> +<$declareStandardCameraTransform()$> + +// the albedo texture +uniform sampler2D originalTexture; + +// the interpolated normal +in vec3 _normal; +in vec4 _color; +in vec2 _texCoord0; +in vec4 _eyePosition; + +layout(location = 0) out vec4 _fragColor0; + +void main(void) { + vec4 texel = texture(originalTexture, _texCoord0); + float colorAlpha = _color.a * texel.a; + + TransformCamera cam = getTransformCamera(); + vec3 fragPosition = _eyePosition.xyz; + + _fragColor0 = vec4(evalSkyboxGlobalColor( + cam._viewInverse, + 1.0, + DEFAULT_OCCLUSION, + fragPosition, + normalize(_normal), + _color.rgb * texel.rgb, + DEFAULT_FRESNEL, + DEFAULT_METALLIC, + DEFAULT_ROUGHNESS), + 1.0); +} \ No newline at end of file diff --git a/libraries/render-utils/src/forward_simple_textured_transparent.slf b/libraries/render-utils/src/forward_simple_textured_transparent.slf new file mode 100644 index 0000000000..a8f23907d3 --- /dev/null +++ b/libraries/render-utils/src/forward_simple_textured_transparent.slf @@ -0,0 +1,52 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// forward_simple_textured_transparent.slf +// fragment shader +// +// Created by Clément Brisset on 5/29/15. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +<@include DefaultMaterials.slh@> + +<@include ForwardGlobalLight.slh@> +<$declareEvalGlobalLightingAlphaBlended()$> + +<@include gpu/Transform.slh@> +<$declareStandardCameraTransform()$> + +// the albedo texture +uniform sampler2D originalTexture; + +// the interpolated normal +in vec3 _normal; +in vec4 _color; +in vec2 _texCoord0; +in vec4 _eyePosition; + +layout(location = 0) out vec4 _fragColor0; + +void main(void) { + vec4 texel = texture(originalTexture, _texCoord0); + float colorAlpha = _color.a * texel.a; + + TransformCamera cam = getTransformCamera(); + vec3 fragPosition = _eyePosition.xyz; + + _fragColor0 = vec4(evalGlobalLightingAlphaBlendedWithHaze( + cam._viewInverse, + 1.0, + DEFAULT_OCCLUSION, + fragPosition, + normalize(_normal), + _color.rgb * texel.rgb, + DEFAULT_FRESNEL, + DEFAULT_METALLIC, + DEFAULT_EMISSIVE, + DEFAULT_ROUGHNESS, colorAlpha), + colorAlpha); +} \ No newline at end of file diff --git a/libraries/render-utils/src/forward_simple_textured_unlit.slf b/libraries/render-utils/src/forward_simple_textured_unlit.slf new file mode 100644 index 0000000000..b65de16c61 --- /dev/null +++ b/libraries/render-utils/src/forward_simple_textured_unlit.slf @@ -0,0 +1,35 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// simple_textured_unlit.frag +// fragment shader +// +// Created by Clément Brisset on 5/29/15. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include LightingModel.slh@> +<@include gpu/Color.slh@> + +layout(location = 0) out vec4 _fragColor0; + +// the albedo texture +uniform sampler2D originalTexture; + +in vec4 _color; +in vec2 _texCoord0; + +void main(void) { + vec4 texel = texture(originalTexture, _texCoord0.st); + float colorAlpha = _color.a; + if (_color.a <= 0.0) { + texel = color_sRGBAToLinear(texel); + colorAlpha = -_color.a; + } + + _fragColor0 = vec4(_color.rgb * texel.rgb * isUnlitEnabled(), colorAlpha * texel.a); +} \ No newline at end of file diff --git a/libraries/render-utils/src/forward_simple_transparent.slf b/libraries/render-utils/src/forward_simple_transparent.slf new file mode 100644 index 0000000000..4c7a2df6a6 --- /dev/null +++ b/libraries/render-utils/src/forward_simple_transparent.slf @@ -0,0 +1,87 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// forward_simple_transparent.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/15/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +<@include DefaultMaterials.slh@> + +<@include ForwardGlobalLight.slh@> +<$declareEvalGlobalLightingAlphaBlended()$> + +<@include gpu/Transform.slh@> +<$declareStandardCameraTransform()$> + +// the interpolated normal +in vec3 _normal; +in vec3 _modelNormal; +in vec4 _color; +in vec2 _texCoord0; +in vec4 _eyePosition; + +layout(location = 0) out vec4 _fragColor0; + +//PROCEDURAL_COMMON_BLOCK + +#line 1001 +//PROCEDURAL_BLOCK + +#line 2030 +void main(void) { + vec3 normal = normalize(_normal.xyz); + vec3 diffuse = _color.rgb; + vec3 specular = DEFAULT_SPECULAR; + float shininess = DEFAULT_SHININESS; + float emissiveAmount = 0.0; + +#ifdef PROCEDURAL + +#ifdef PROCEDURAL_V1 + specular = getProceduralColor().rgb; + // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline + //specular = pow(specular, vec3(2.2)); + emissiveAmount = 1.0; +#else + emissiveAmount = getProceduralColors(diffuse, specular, shininess); +#endif + +#endif + + TransformCamera cam = getTransformCamera(); + vec3 fragPosition = _eyePosition.xyz; + + if (emissiveAmount > 0.0) { + _fragColor0 = vec4(evalGlobalLightingAlphaBlendedWithHaze( + cam._viewInverse, + 1.0, + DEFAULT_OCCLUSION, + fragPosition, + normal, + specular, + DEFAULT_FRESNEL, + DEFAULT_METALLIC, + DEFAULT_EMISSIVE, + DEFAULT_ROUGHNESS, _color.a), + _color.a); + } else { + _fragColor0 = vec4(evalGlobalLightingAlphaBlendedWithHaze( + cam._viewInverse, + 1.0, + DEFAULT_OCCLUSION, + fragPosition, + normal, + diffuse, + DEFAULT_FRESNEL, + DEFAULT_METALLIC, + DEFAULT_EMISSIVE, + DEFAULT_ROUGHNESS, _color.a), + _color.a); + } +} diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index 7b32541c63..8e7df452cc 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -13,7 +13,6 @@ // <@include DeferredBufferWrite.slh@> -<@include graphics/Material.slh@> // the interpolated normal in vec3 _normal; @@ -29,7 +28,6 @@ in vec4 _position; #line 2030 void main(void) { - Material material = getMaterial(); vec3 normal = normalize(_normal.xyz); vec3 diffuse = _color.rgb; vec3 specular = DEFAULT_SPECULAR; @@ -49,43 +47,24 @@ void main(void) { #endif - const float ALPHA_THRESHOLD = 0.999; - if (_color.a < ALPHA_THRESHOLD) { - if (emissiveAmount > 0.0) { - packDeferredFragmentTranslucent( - normal, - _color.a, - specular, - DEFAULT_FRESNEL, - DEFAULT_ROUGHNESS); - } else { - packDeferredFragmentTranslucent( - normal, - _color.a, - diffuse, - DEFAULT_FRESNEL, - DEFAULT_ROUGHNESS); - } + if (emissiveAmount > 0.0) { + packDeferredFragmentLightmap( + normal, + 1.0, + diffuse, + max(0.0, 1.0 - shininess / 128.0), + DEFAULT_METALLIC, + specular, + vec3(clamp(emissiveAmount, 0.0, 1.0))); } else { - if (emissiveAmount > 0.0) { - packDeferredFragmentLightmap( - normal, - 1.0, - diffuse, - max(0.0, 1.0 - shininess / 128.0), - DEFAULT_METALLIC, - specular, - vec3(clamp(emissiveAmount, 0.0, 1.0))); - } else { - packDeferredFragment( - normal, - 1.0, - diffuse, - max(0.0, 1.0 - shininess / 128.0), - length(specular), - DEFAULT_EMISSIVE, - DEFAULT_OCCLUSION, - DEFAULT_SCATTERING); - } + packDeferredFragment( + normal, + 1.0, + diffuse, + max(0.0, 1.0 - shininess / 128.0), + length(specular), + DEFAULT_EMISSIVE, + DEFAULT_OCCLUSION, + DEFAULT_SCATTERING); } } diff --git a/libraries/render-utils/src/simple.slv b/libraries/render-utils/src/simple.slv index 0ce6505a65..f63ccb61a6 100644 --- a/libraries/render-utils/src/simple.slv +++ b/libraries/render-utils/src/simple.slv @@ -23,6 +23,7 @@ out vec3 _modelNormal; out vec4 _color; out vec2 _texCoord0; out vec4 _position; +out vec4 _eyePosition; void main(void) { _color = color_sRGBAToLinear(inColor); @@ -33,6 +34,6 @@ void main(void) { // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - <$transformModelToClipPos(cam, obj, inPosition, gl_Position)$> + <$transformModelToEyeAndClipPos(cam, obj, inPosition, _eyePosition, gl_Position)$> <$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$> } \ No newline at end of file diff --git a/libraries/render-utils/src/simple_fade.slv b/libraries/render-utils/src/simple_fade.slv index 85946045ac..6dbe40485a 100644 --- a/libraries/render-utils/src/simple_fade.slv +++ b/libraries/render-utils/src/simple_fade.slv @@ -26,6 +26,7 @@ out vec3 _modelNormal; out vec4 _color; out vec2 _texCoord0; out vec4 _position; +out vec4 _eyePosition; out vec4 _worldPosition; void main(void) { @@ -37,7 +38,7 @@ void main(void) { // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - <$transformModelToClipPos(cam, obj, inPosition, gl_Position)$> + <$transformModelToEyeAndClipPos(cam, obj, inPosition, _eyePosition, gl_Position)$> <$transformModelToWorldPos(obj, inPosition, _worldPosition)$> <$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$> <$passThroughFadeObjectParams()$> diff --git a/libraries/render-utils/src/simple_textured.slf b/libraries/render-utils/src/simple_textured.slf index 4fd734aad5..bb50c9d158 100644 --- a/libraries/render-utils/src/simple_textured.slf +++ b/libraries/render-utils/src/simple_textured.slf @@ -12,9 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include gpu/Color.slh@> <@include DeferredBufferWrite.slh@> -<@include graphics/Material.slh@> // the albedo texture uniform sampler2D originalTexture; @@ -26,29 +24,14 @@ in vec2 _texCoord0; void main(void) { vec4 texel = texture(originalTexture, _texCoord0); - float colorAlpha = _color.a; - if (_color.a <= 0.0) { - texel = color_sRGBAToLinear(texel); - colorAlpha = -_color.a; - } - const float ALPHA_THRESHOLD = 0.999; - if (colorAlpha * texel.a < ALPHA_THRESHOLD) { - packDeferredFragmentTranslucent( - normalize(_normal), - colorAlpha * texel.a, - _color.rgb * texel.rgb, - DEFAULT_FRESNEL, - DEFAULT_ROUGHNESS); - } else { - packDeferredFragment( - normalize(_normal), - 1.0, - _color.rgb * texel.rgb, - DEFAULT_ROUGHNESS, - DEFAULT_METALLIC, - DEFAULT_EMISSIVE, - DEFAULT_OCCLUSION, - DEFAULT_SCATTERING); - } + packDeferredFragment( + normalize(_normal), + 1.0, + _color.rgb * texel.rgb, + DEFAULT_ROUGHNESS, + DEFAULT_METALLIC, + DEFAULT_EMISSIVE, + DEFAULT_OCCLUSION, + DEFAULT_SCATTERING); } \ No newline at end of file diff --git a/libraries/render-utils/src/simple_transparent.slf b/libraries/render-utils/src/simple_transparent.slf new file mode 100644 index 0000000000..fe544d1283 --- /dev/null +++ b/libraries/render-utils/src/simple_transparent.slf @@ -0,0 +1,65 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// simple_transparent.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/15/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include DeferredBufferWrite.slh@> + +// the interpolated normal +in vec3 _normal; +in vec3 _modelNormal; +in vec4 _color; +in vec2 _texCoord0; +in vec4 _position; + +//PROCEDURAL_COMMON_BLOCK + +#line 1001 +//PROCEDURAL_BLOCK + +#line 2030 +void main(void) { + vec3 normal = normalize(_normal.xyz); + vec3 diffuse = _color.rgb; + vec3 specular = DEFAULT_SPECULAR; + float shininess = DEFAULT_SHININESS; + float emissiveAmount = 0.0; + +#ifdef PROCEDURAL + +#ifdef PROCEDURAL_V1 + specular = getProceduralColor().rgb; + // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline + //specular = pow(specular, vec3(2.2)); + emissiveAmount = 1.0; +#else + emissiveAmount = getProceduralColors(diffuse, specular, shininess); +#endif + +#endif + + if (emissiveAmount > 0.0) { + packDeferredFragmentTranslucent( + normal, + _color.a, + specular, + DEFAULT_FRESNEL, + DEFAULT_ROUGHNESS); + } else { + packDeferredFragmentTranslucent( + normal, + _color.a, + diffuse, + DEFAULT_FRESNEL, + DEFAULT_ROUGHNESS); + } +} diff --git a/libraries/render-utils/src/simple_transparent_textured.slf b/libraries/render-utils/src/simple_transparent_textured.slf index c6b0d83914..7c7168ec0f 100644 --- a/libraries/render-utils/src/simple_transparent_textured.slf +++ b/libraries/render-utils/src/simple_transparent_textured.slf @@ -12,51 +12,24 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include gpu/Color.slh@> - <@include DeferredBufferWrite.slh@> -<@include DeferredGlobalLight.slh@> -<$declareEvalGlobalLightingAlphaBlendedWithHaze()$> - -<@include gpu/Transform.slh@> -<$declareStandardCameraTransform()$> // the albedo texture uniform sampler2D originalTexture; // the interpolated normal -in vec4 _position; in vec3 _normal; in vec4 _color; in vec2 _texCoord0; void main(void) { - vec4 texel = texture(originalTexture, _texCoord0.st); - float opacity = _color.a; - if (_color.a <= 0.0) { - texel = color_sRGBAToLinear(texel); - opacity = -_color.a; - } - opacity *= texel.a; - vec3 albedo = _color.rgb * texel.rgb; + vec4 texel = texture(originalTexture, _texCoord0); + float colorAlpha = _color.a * texel.a; - vec3 fragPosition = _position.xyz; - vec3 fragNormal = normalize(_normal); - - TransformCamera cam = getTransformCamera(); - - _fragColor0 = vec4(evalGlobalLightingAlphaBlendedWithHaze( - cam._viewInverse, - 1.0, - 1.0, - fragPosition, - fragNormal, - albedo, + packDeferredFragmentTranslucent( + normalize(_normal), + colorAlpha, + _color.rgb * texel.rgb, DEFAULT_FRESNEL, - 0.0, - vec3(0.0f), - DEFAULT_ROUGHNESS, - opacity), - opacity); - + DEFAULT_ROUGHNESS); } \ No newline at end of file From e0b2c076ef33424c7ff296648d57b645fe71054b Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 10 Apr 2018 17:10:29 -0700 Subject: [PATCH 5/6] cleanup and fix forward procedural rendering --- .../src/RenderableShapeEntityItem.cpp | 20 +++---- .../procedural/src/procedural/Procedural.cpp | 52 +++++++++++-------- .../procedural/src/procedural/Procedural.h | 8 +-- libraries/render-utils/src/GeometryCache.cpp | 17 +----- libraries/render-utils/src/GeometryCache.h | 2 - libraries/render-utils/src/forward_simple.slf | 12 ++--- .../src/forward_simple_textured_unlit.slf | 8 +-- .../src/forward_simple_transparent.slf | 11 ++-- libraries/render-utils/src/simple.slf | 6 +-- libraries/render-utils/src/simple_fade.slf | 2 - .../render-utils/src/simple_textured_fade.slf | 1 - .../render-utils/src/simple_transparent.slf | 6 +-- 12 files changed, 60 insertions(+), 85 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 2743c8b29d..1d34837a58 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -22,15 +22,6 @@ #include "render-utils/forward_simple_frag.h" #include "render-utils/forward_simple_transparent_frag.h" -#include - -#if defined(USE_GLES) -static bool DISABLE_DEFERRED = true; -#else -static const QString RENDER_FORWARD{ "HIFI_RENDER_FORWARD" }; -static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD); -#endif - #include "RenderPipelines.h" //#define SHAPE_ENTITY_USE_FADE_EFFECT @@ -47,8 +38,11 @@ static const float SPHERE_ENTITY_SCALE = 0.5f; ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Parent(entity) { _procedural._vertexSource = simple_vert::getSource(); - _procedural._opaquefragmentSource = DISABLE_DEFERRED ? forward_simple_frag::getSource() : simple_frag::getSource(); - _procedural._transparentfragmentSource = DISABLE_DEFERRED ? forward_simple_transparent_frag::getSource() : simple_transparent_frag::getSource(); + // FIXME: Setup proper uniform slots and use correct pipelines for forward rendering + _procedural._opaquefragmentSource = simple_frag::getSource(); + // FIXME: Transparent procedural entities only seem to work if they use the opaque pipelines + //_procedural._transparentfragmentSource = simple_transparent_frag::getSource(); + _procedural._transparentfragmentSource = simple_frag::getSource(); _procedural._opaqueState->setCullMode(gpu::State::CULL_NONE); _procedural._opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL); PrepareStencil::testMaskDrawShape(*_procedural._opaqueState); @@ -251,9 +245,9 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { if (proceduralRender) { if (render::ShapeKey(args->_globalShapeKey).isWireframe()) { - geometryCache->renderWireShapeColor(batch, geometryShape, outColor); + geometryCache->renderWireShape(batch, geometryShape, outColor); } else { - geometryCache->renderShapeColor(batch, geometryShape, outColor); + geometryCache->renderShape(batch, geometryShape, outColor); } } else if (!useMaterialPipeline()) { // FIXME, support instanced multi-shape rendering using multidraw indirect diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index 0488bb2eb7..c155d5bd7f 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -287,22 +287,25 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm _transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState); for (size_t i = 0; i < NUM_STANDARD_UNIFORMS; ++i) { const std::string& name = STANDARD_UNIFORM_NAMES[i]; - _standardUniformSlots[i] = _opaqueShader->getUniforms().findLocation(name); + _standardOpaqueUniformSlots[i] = _opaqueShader->getUniforms().findLocation(name); + _standardTransparentUniformSlots[i] = _transparentShader->getUniforms().findLocation(name); } _start = usecTimestampNow(); _frameCount = 0; } - batch.setPipeline(color.a < 1.0f ? _transparentPipeline : _opaquePipeline); + bool transparent = color.a < 1.0f; + batch.setPipeline(transparent ? _transparentPipeline : _opaquePipeline); - if (_shaderDirty || _uniformsDirty) { - setupUniforms(); + if (_shaderDirty || _uniformsDirty || _prevTransparent != transparent) { + setupUniforms(transparent); } - if (_shaderDirty || _uniformsDirty || _channelsDirty) { - setupChannels(_shaderDirty || _uniformsDirty); + if (_shaderDirty || _uniformsDirty || _channelsDirty || _prevTransparent != transparent) { + setupChannels(_shaderDirty || _uniformsDirty, transparent); } + _prevTransparent = transparent; _shaderDirty = _uniformsDirty = _channelsDirty = false; for (auto lambda : _uniforms) { @@ -328,12 +331,12 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm } } -void Procedural::setupUniforms() { +void Procedural::setupUniforms(bool transparent) { _uniforms.clear(); // Set any userdata specified uniforms foreach(QString key, _data.uniforms.keys()) { std::string uniformName = key.toLocal8Bit().data(); - int32_t slot = _opaqueShader->getUniforms().findLocation(uniformName); + int32_t slot = (transparent ? _transparentShader : _opaqueShader)->getUniforms().findLocation(uniformName); if (gpu::Shader::INVALID_LOCATION == slot) { continue; } @@ -394,15 +397,17 @@ void Procedural::setupUniforms() { } } - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[TIME]) { + auto uniformSlots = transparent ? _standardTransparentUniformSlots : _standardOpaqueUniformSlots; + + if (gpu::Shader::INVALID_LOCATION != uniformSlots[TIME]) { _uniforms.push_back([=](gpu::Batch& batch) { // Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds float time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND; - batch._glUniform(_standardUniformSlots[TIME], time); + batch._glUniform(uniformSlots[TIME], time); }); } - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[DATE]) { + if (gpu::Shader::INVALID_LOCATION != uniformSlots[DATE]) { _uniforms.push_back([=](gpu::Batch& batch) { QDateTime now = QDateTime::currentDateTimeUtc(); QDate date = now.date(); @@ -415,40 +420,41 @@ void Procedural::setupUniforms() { v.z = date.day(); float fractSeconds = (time.msec() / 1000.0f); v.w = (time.hour() * 3600) + (time.minute() * 60) + time.second() + fractSeconds; - batch._glUniform(_standardUniformSlots[DATE], v); + batch._glUniform(uniformSlots[DATE], v); }); } - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[FRAME_COUNT]) { + if (gpu::Shader::INVALID_LOCATION != uniformSlots[FRAME_COUNT]) { _uniforms.push_back([=](gpu::Batch& batch) { - batch._glUniform(_standardUniformSlots[FRAME_COUNT], ++_frameCount); + batch._glUniform(uniformSlots[FRAME_COUNT], ++_frameCount); }); } - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[SCALE]) { + if (gpu::Shader::INVALID_LOCATION != uniformSlots[SCALE]) { // FIXME move into the 'set once' section, since this doesn't change over time _uniforms.push_back([=](gpu::Batch& batch) { - batch._glUniform(_standardUniformSlots[SCALE], _entityDimensions); + batch._glUniform(uniformSlots[SCALE], _entityDimensions); }); } - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[ORIENTATION]) { + if (gpu::Shader::INVALID_LOCATION != uniformSlots[ORIENTATION]) { // FIXME move into the 'set once' section, since this doesn't change over time _uniforms.push_back([=](gpu::Batch& batch) { - batch._glUniform(_standardUniformSlots[ORIENTATION], _entityOrientation); + batch._glUniform(uniformSlots[ORIENTATION], _entityOrientation); }); } - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[POSITION]) { + if (gpu::Shader::INVALID_LOCATION != uniformSlots[POSITION]) { // FIXME move into the 'set once' section, since this doesn't change over time _uniforms.push_back([=](gpu::Batch& batch) { - batch._glUniform(_standardUniformSlots[POSITION], _entityPosition); + batch._glUniform(uniformSlots[POSITION], _entityPosition); }); } } -void Procedural::setupChannels(bool shouldCreate) { - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[CHANNEL_RESOLUTION]) { +void Procedural::setupChannels(bool shouldCreate, bool transparent) { + auto uniformSlots = transparent ? _standardTransparentUniformSlots : _standardOpaqueUniformSlots; + if (gpu::Shader::INVALID_LOCATION != uniformSlots[CHANNEL_RESOLUTION]) { if (!shouldCreate) { // Instead of modifying the last element, just remove and recreate it. _uniforms.pop_back(); @@ -460,7 +466,7 @@ void Procedural::setupChannels(bool shouldCreate) { channelSizes[i] = vec3(_channels[i]->getWidth(), _channels[i]->getHeight(), 1.0); } } - batch._glUniform3fv(_standardUniformSlots[CHANNEL_RESOLUTION], MAX_PROCEDURAL_TEXTURE_CHANNELS, &channelSizes[0].x); + batch._glUniform3fv(uniformSlots[CHANNEL_RESOLUTION], MAX_PROCEDURAL_TEXTURE_CHANNELS, &channelSizes[0].x); }); } } diff --git a/libraries/procedural/src/procedural/Procedural.h b/libraries/procedural/src/procedural/Procedural.h index 4e30a003d6..1d3b0b3b5a 100644 --- a/libraries/procedural/src/procedural/Procedural.h +++ b/libraries/procedural/src/procedural/Procedural.h @@ -102,7 +102,8 @@ protected: // Rendering objects UniformLambdas _uniforms; - int32_t _standardUniformSlots[NUM_STANDARD_UNIFORMS]; + int32_t _standardOpaqueUniformSlots[NUM_STANDARD_UNIFORMS]; + int32_t _standardTransparentUniformSlots[NUM_STANDARD_UNIFORMS]; NetworkTexturePointer _channels[MAX_PROCEDURAL_TEXTURE_CHANNELS]; gpu::PipelinePointer _opaquePipeline; gpu::PipelinePointer _transparentPipeline; @@ -119,8 +120,8 @@ protected: private: // This should only be called from the render thread, as it shares data with Procedural::prepare - void setupUniforms(); - void setupChannels(bool shouldCreate); + void setupUniforms(bool transparent); + void setupChannels(bool shouldCreate, bool transparent); std::string replaceProceduralBlock(const std::string& fragmentSource); @@ -128,6 +129,7 @@ private: mutable bool _hasStartedFade { false }; mutable bool _isFading { false }; bool _doesFade { true }; + bool _prevTransparent { false }; }; #endif diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 52dc1d6cac..ecfa9881a3 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -845,20 +845,6 @@ void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape, const glm::v _shapes[shape].drawWire(batch); } -void GeometryCache::renderShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color) { - batch.setInputFormat(getInstancedSolidStreamFormat()); - // Color must be set after input format - batch._glColor4f(color.r, color.g, color.b, color.a); - _shapes[shape].draw(batch); -} - -void GeometryCache::renderWireShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color) { - batch.setInputFormat(getInstancedSolidStreamFormat()); - // Color must be set after input format - batch._glColor4f(color.r, color.g, color.b, color.a); - _shapes[shape].drawWire(batch); -} - void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) { gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT); batch.setInputBuffer(gpu::Stream::COLOR, colorView); @@ -2265,7 +2251,8 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp std::call_once(once, [&]() { auto VS = simple_vert::getShader(); auto PS = DISABLE_DEFERRED ? forward_simple_textured_frag::getShader() : simple_textured_frag::getShader(); - auto PSTransparent = DISABLE_DEFERRED ? forward_simple_textured_transparent_frag::getShader() : simple_transparent_textured_frag::getShader(); + // Use the forward pipeline for both here, otherwise transparents will be unlit + auto PSTransparent = DISABLE_DEFERRED ? forward_simple_textured_transparent_frag::getShader() : forward_simple_textured_transparent_frag::getShader(); auto PSUnlit = DISABLE_DEFERRED ? forward_simple_textured_unlit_frag::getShader() : simple_textured_unlit_frag::getShader(); _simpleShader = gpu::Shader::createProgram(VS, PS); diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index bec166aded..fcbf5ee128 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -253,8 +253,6 @@ public: void renderWireShape(gpu::Batch& batch, Shape shape); void renderShape(gpu::Batch& batch, Shape shape, const glm::vec4& color); void renderWireShape(gpu::Batch& batch, Shape shape, const glm::vec4& color); - void renderShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color); - void renderWireShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color); size_t getShapeTriangleCount(Shape shape); void renderCube(gpu::Batch& batch); diff --git a/libraries/render-utils/src/forward_simple.slf b/libraries/render-utils/src/forward_simple.slf index 497afe93a3..ac2aa63697 100644 --- a/libraries/render-utils/src/forward_simple.slf +++ b/libraries/render-utils/src/forward_simple.slf @@ -16,14 +16,12 @@ <@include ForwardGlobalLight.slh@> <$declareEvalSkyboxGlobalColor()$> -<@include gpu/Transform.slh@> -<$declareStandardCameraTransform()$> - // the interpolated normal in vec3 _normal; in vec3 _modelNormal; in vec4 _color; in vec2 _texCoord0; +in vec4 _position; in vec4 _eyePosition; layout(location = 0) out vec4 _fragColor0; @@ -35,12 +33,12 @@ layout(location = 0) out vec4 _fragColor0; #line 2030 void main(void) { - vec3 normal = normalize(_normal.xyz); - vec3 diffuse = _color.rgb; + vec3 normal = normalize(_normal.xyz); + vec3 diffuse = _color.rgb; vec3 specular = DEFAULT_SPECULAR; float shininess = DEFAULT_SHININESS; float emissiveAmount = 0.0; - + #ifdef PROCEDURAL #ifdef PROCEDURAL_V1 @@ -48,7 +46,7 @@ void main(void) { // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline //specular = pow(specular, vec3(2.2)); emissiveAmount = 1.0; -#else +#else emissiveAmount = getProceduralColors(diffuse, specular, shininess); #endif diff --git a/libraries/render-utils/src/forward_simple_textured_unlit.slf b/libraries/render-utils/src/forward_simple_textured_unlit.slf index b65de16c61..0cc241b75e 100644 --- a/libraries/render-utils/src/forward_simple_textured_unlit.slf +++ b/libraries/render-utils/src/forward_simple_textured_unlit.slf @@ -25,11 +25,7 @@ in vec2 _texCoord0; void main(void) { vec4 texel = texture(originalTexture, _texCoord0.st); - float colorAlpha = _color.a; - if (_color.a <= 0.0) { - texel = color_sRGBAToLinear(texel); - colorAlpha = -_color.a; - } + float colorAlpha = _color.a * texel.a; - _fragColor0 = vec4(_color.rgb * texel.rgb * isUnlitEnabled(), colorAlpha * texel.a); + _fragColor0 = vec4(_color.rgb * texel.rgb * isUnlitEnabled(), colorAlpha); } \ No newline at end of file diff --git a/libraries/render-utils/src/forward_simple_transparent.slf b/libraries/render-utils/src/forward_simple_transparent.slf index 4c7a2df6a6..551e10282a 100644 --- a/libraries/render-utils/src/forward_simple_transparent.slf +++ b/libraries/render-utils/src/forward_simple_transparent.slf @@ -16,9 +16,6 @@ <@include ForwardGlobalLight.slh@> <$declareEvalGlobalLightingAlphaBlended()$> -<@include gpu/Transform.slh@> -<$declareStandardCameraTransform()$> - // the interpolated normal in vec3 _normal; in vec3 _modelNormal; @@ -35,12 +32,12 @@ layout(location = 0) out vec4 _fragColor0; #line 2030 void main(void) { - vec3 normal = normalize(_normal.xyz); - vec3 diffuse = _color.rgb; + vec3 normal = normalize(_normal.xyz); + vec3 diffuse = _color.rgb; vec3 specular = DEFAULT_SPECULAR; float shininess = DEFAULT_SHININESS; float emissiveAmount = 0.0; - + #ifdef PROCEDURAL #ifdef PROCEDURAL_V1 @@ -48,7 +45,7 @@ void main(void) { // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline //specular = pow(specular, vec3(2.2)); emissiveAmount = 1.0; -#else +#else emissiveAmount = getProceduralColors(diffuse, specular, shininess); #endif diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index 8e7df452cc..1c2ad9a413 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -28,8 +28,8 @@ in vec4 _position; #line 2030 void main(void) { - vec3 normal = normalize(_normal.xyz); - vec3 diffuse = _color.rgb; + vec3 normal = normalize(_normal.xyz); + vec3 diffuse = _color.rgb; vec3 specular = DEFAULT_SPECULAR; float shininess = DEFAULT_SHININESS; float emissiveAmount = 0.0; @@ -41,7 +41,7 @@ void main(void) { // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline //specular = pow(specular, vec3(2.2)); emissiveAmount = 1.0; -#else +#else emissiveAmount = getProceduralColors(diffuse, specular, shininess); #endif diff --git a/libraries/render-utils/src/simple_fade.slf b/libraries/render-utils/src/simple_fade.slf index ce9251b9a5..1c74612ff0 100644 --- a/libraries/render-utils/src/simple_fade.slf +++ b/libraries/render-utils/src/simple_fade.slf @@ -13,7 +13,6 @@ // <@include DeferredBufferWrite.slh@> -<@include graphics/Material.slh@> <@include Fade.slh@> <$declareFadeFragmentInstanced()$> @@ -39,7 +38,6 @@ void main(void) { <$fetchFadeObjectParamsInstanced(fadeParams)$> applyFade(fadeParams, _worldPosition.xyz, fadeEmissive); - Material material = getMaterial(); vec3 normal = normalize(_normal.xyz); vec3 diffuse = _color.rgb; vec3 specular = DEFAULT_SPECULAR; diff --git a/libraries/render-utils/src/simple_textured_fade.slf b/libraries/render-utils/src/simple_textured_fade.slf index d378e7a5c1..e5ecd94852 100644 --- a/libraries/render-utils/src/simple_textured_fade.slf +++ b/libraries/render-utils/src/simple_textured_fade.slf @@ -14,7 +14,6 @@ <@include gpu/Color.slh@> <@include DeferredBufferWrite.slh@> -<@include graphics/Material.slh@> <@include Fade.slh@> diff --git a/libraries/render-utils/src/simple_transparent.slf b/libraries/render-utils/src/simple_transparent.slf index fe544d1283..65ffe0504a 100644 --- a/libraries/render-utils/src/simple_transparent.slf +++ b/libraries/render-utils/src/simple_transparent.slf @@ -28,8 +28,8 @@ in vec4 _position; #line 2030 void main(void) { - vec3 normal = normalize(_normal.xyz); - vec3 diffuse = _color.rgb; + vec3 normal = normalize(_normal.xyz); + vec3 diffuse = _color.rgb; vec3 specular = DEFAULT_SPECULAR; float shininess = DEFAULT_SHININESS; float emissiveAmount = 0.0; @@ -41,7 +41,7 @@ void main(void) { // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline //specular = pow(specular, vec3(2.2)); emissiveAmount = 1.0; -#else +#else emissiveAmount = getProceduralColors(diffuse, specular, shininess); #endif From c2f0f7ef5f87dd918cde14954eae4e1466ec0432 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 12 Apr 2018 10:54:35 +1200 Subject: [PATCH 6/6] Doc review --- .../src/scripting/HMDScriptingInterface.h | 29 +++++++++++++++---- .../AbstractHMDScriptingInterface.h | 2 +- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 1acafab361..9b2482e73a 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -31,7 +31,7 @@ class QScriptEngine; * @property {Vec3} position - The position of the HMD if currently in VR display mode, otherwise * {@link Vec3(0)|Vec3.ZERO}. Read-only. * @property {Quat} orientation - The orientation of the HMD if currently in VR display mode, otherwise - * {@link Quat(0)|Quat.IDENTITY}.Read-only. + * {@link Quat(0)|Quat.IDENTITY}. Read-only. * @property {boolean} active - true if the display mode is HMD, otherwise false. Read-only. * @property {boolean} mounted - true if currently in VR display mode and the HMD is being worn, otherwise * false. Read-only. @@ -74,6 +74,23 @@ public: * @param {Vec3} position - The origin of the ray. * @param {Vec3} direction - The direction of the ray. * @returns {Vec3} The point of intersection with the HUD overlay if it intersects, otherwise {@link Vec3(0)|Vec3.ZERO}. + * @example Draw a square on the HUD overlay in the direction you're looking. + * var hudIntersection = HMD.calculateRayUICollisionPoint(MyAvatar.getHeadPosition(), + * Quat.getForward(MyAvatar.headOrientation)); + * var hudPoint = HMD.overlayFromWorldPoint(hudIntersection); + * + * var DIMENSIONS = { x: 50, y: 50 }; + * var square = Overlays.addOverlay("rectangle", { + * x: hudPoint.x - DIMENSIONS.x / 2, + * y: hudPoint.y - DIMENSIONS.y / 2, + * width: DIMENSIONS.x, + * height: DIMENSIONS.y, + * color: { red: 255, green: 0, blue: 0 } + * }); + * + * Script.scriptEnding.connect(function () { + * Overlays.deleteOverlay(square); + * }); */ Q_INVOKABLE glm::vec3 calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction) const; @@ -201,7 +218,7 @@ public: /**jsdoc * Check whether there are specific HMD controllers available. * @function HMD.isSubdeviceContainingNameAvailable - * @param {string} - The name of the HMD controller to check for, e.g., "OculusTouch". + * @param {string} name - The name of the HMD controller to check for, e.g., "OculusTouch". * @returns {boolean} true if an HMD controller with a name containing the specified name is * available, otherwise false. * @example Report if particular Oculus controllers are available. @@ -240,15 +257,15 @@ public: /**jsdoc - * Causes the borders and decorations in HUD windows to be enlarged when the laser intersects them in HMD mode. By default, - * borders and decorations are not enlarged. + * Causes the borders in HUD windows to be enlarged when the laser intersects them in HMD mode. By default, borders are not + * enlarged. * @function HMD.activateHMDHandMouse */ Q_INVOKABLE void activateHMDHandMouse(); /**jsdoc - * Causes the border and decorations in HUD windows to no longer be enlarged when the laser intersects them in HMD mode. By - * default, borders and decorations are not enlarged. + * Causes the border in HUD windows to no longer be enlarged when the laser intersects them in HMD mode. By default, + * borders are not enlarged. * @function HMD.deactivateHMDHandMouse */ Q_INVOKABLE void deactivateHMDHandMouse(); diff --git a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h index 36e1952d3c..392fa7e2a2 100644 --- a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h +++ b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h @@ -47,7 +47,7 @@ signals: * @example Report when the display mode changes. * HMD.displayModeChanged.connect(function (isHMDMode) { * print("Display mode changed"); - * print("isHMD = " + isHMD); + * print("isHMD = " + isHMDMode); * print("HMD.active = " + HMD.active); * print("HMD.mounted = " + HMD.mounted); * });