mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge pull request #7191 from samcake/orange
Better Shading Model and support fr Stingray material
This commit is contained in:
commit
cfce5af8d4
84 changed files with 1556 additions and 662 deletions
51
examples/utilities/tools/render/debugFramebuffer.js
Normal file
51
examples/utilities/tools/render/debugFramebuffer.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// ddebugFramBuffer.js
|
||||
// examples/utilities/tools/render
|
||||
//
|
||||
// Sam Gateau created on 2/18/2016.
|
||||
// Copyright 2016 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
|
||||
//
|
||||
|
||||
var DDB = Render.RenderDeferredTask.DebugDeferredBuffer;
|
||||
oldConfig = DDB.toJSON();
|
||||
DDB.enabled = true;
|
||||
|
||||
|
||||
// Set up the qml ui
|
||||
var qml = Script.resolvePath('framebuffer.qml');
|
||||
var window = new OverlayWindow({
|
||||
title: 'Framebuffer Debug',
|
||||
source: qml,
|
||||
width: 400, height: 400,
|
||||
});
|
||||
window.setPosition(25, 50);
|
||||
window.closed.connect(function() { Script.stop(); });
|
||||
|
||||
// Debug buffer sizing
|
||||
var resizing = false;
|
||||
|
||||
Controller.mousePressEvent.connect(function (e) {
|
||||
if (shouldStartResizing(e.x)) {
|
||||
resizing = true;
|
||||
}
|
||||
});
|
||||
Controller.mouseReleaseEvent.connect(function() { resizing = false; });
|
||||
Controller.mouseMoveEvent.connect(function (e) { resizing && setDebugBufferSize(e.x); });
|
||||
|
||||
|
||||
function shouldStartResizing(eventX) {
|
||||
var x = Math.abs(eventX - Window.innerWidth * (1.0 + DDB.size.x) / 2.0);
|
||||
var mode = DDB.mode;
|
||||
return mode !== -1 && x < 20;
|
||||
}
|
||||
|
||||
function setDebugBufferSize(x) {
|
||||
x = (2.0 * (x / Window.innerWidth) - 1.0); // scale
|
||||
x = Math.min(Math.max(-1, x), 1); // clamp
|
||||
DDB.size = { x: x, y: -1, z: 1, w: 1 };
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(function () { DDB.fromJSON(oldConfig); });
|
52
examples/utilities/tools/render/framebuffer.qml
Normal file
52
examples/utilities/tools/render/framebuffer.qml
Normal file
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// main.qml
|
||||
// examples/utilities/tools/render
|
||||
//
|
||||
// Created by Zach Pomerantz on 2/8/2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
|
||||
Column {
|
||||
spacing: 8
|
||||
Column {
|
||||
id: debug
|
||||
property var config: Render.getConfig("DebugDeferredBuffer")
|
||||
|
||||
function setDebugMode(mode) {
|
||||
debug.config.enabled = (mode != -1);
|
||||
debug.config.mode = mode;
|
||||
}
|
||||
|
||||
Label { text: qsTr("Debug Buffer") }
|
||||
ExclusiveGroup { id: bufferGroup }
|
||||
Repeater {
|
||||
model: [
|
||||
"Off",
|
||||
"Depth",
|
||||
"Albedo",
|
||||
"Normal",
|
||||
"Roughness",
|
||||
"Metallic",
|
||||
"Emissive",
|
||||
"Occlusion",
|
||||
"Lightmap",
|
||||
"Lighting",
|
||||
"Shadow",
|
||||
"Pyramid Depth",
|
||||
"Ambient Occlusion",
|
||||
"Custom Shader"
|
||||
]
|
||||
RadioButton {
|
||||
text: qsTr(modelData)
|
||||
exclusiveGroup: bufferGroup
|
||||
checked: index == 0
|
||||
onCheckedChanged: if (checked) debug.setDebugMode(index - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3816,7 +3816,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
// Setup the current Zone Entity lighting
|
||||
{
|
||||
auto stage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
||||
DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(stage->getSunLight(), stage->getSkybox()->getCubemap());
|
||||
DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(stage->getSunLight());
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -342,9 +342,9 @@ void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename
|
|||
void ModelPackager::listTextures() {
|
||||
_textures.clear();
|
||||
foreach (const FBXMaterial mat, _geometry->materials) {
|
||||
if (!mat.diffuseTexture.filename.isEmpty() && mat.diffuseTexture.content.isEmpty() &&
|
||||
!_textures.contains(mat.diffuseTexture.filename)) {
|
||||
_textures << mat.diffuseTexture.filename;
|
||||
if (!mat.albedoTexture.filename.isEmpty() && mat.albedoTexture.content.isEmpty() &&
|
||||
!_textures.contains(mat.albedoTexture.filename)) {
|
||||
_textures << mat.albedoTexture.filename;
|
||||
}
|
||||
if (!mat.normalTexture.filename.isEmpty() && mat.normalTexture.content.isEmpty() &&
|
||||
!_textures.contains(mat.normalTexture.filename)) {
|
||||
|
|
|
@ -273,6 +273,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
|||
|
||||
if (_hasPreviousZone) {
|
||||
sceneKeyLight->resetAmbientSphere();
|
||||
sceneKeyLight->setAmbientMap(nullptr);
|
||||
sceneKeyLight->setColor(_previousKeyLightColor);
|
||||
sceneKeyLight->setIntensity(_previousKeyLightIntensity);
|
||||
sceneKeyLight->setAmbientIntensity(_previousKeyLightAmbientIntensity);
|
||||
|
@ -321,10 +322,11 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
|||
_ambientTexture.clear();
|
||||
} else {
|
||||
_ambientTexture = textureCache->getTexture(zone->getKeyLightProperties().getAmbientURL(), CUBE_TEXTURE);
|
||||
if (_ambientTexture->getGPUTexture()) {
|
||||
if (_ambientTexture && _ambientTexture->isLoaded() && _ambientTexture->getGPUTexture()) {
|
||||
_pendingAmbientTexture = false;
|
||||
if (_ambientTexture->getGPUTexture()->getIrradiance()) {
|
||||
sceneKeyLight->setAmbientSphere(_ambientTexture->getGPUTexture()->getIrradiance());
|
||||
sceneKeyLight->setAmbientMap(_ambientTexture->getGPUTexture());
|
||||
isAmbientTextureSet = true;
|
||||
}
|
||||
} else {
|
||||
|
@ -354,12 +356,13 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
|||
// Update the Texture of the Skybox with the one pointed by this zone
|
||||
_skyboxTexture = textureCache->getTexture(zone->getSkyboxProperties().getURL(), CUBE_TEXTURE);
|
||||
|
||||
if (_skyboxTexture->getGPUTexture()) {
|
||||
if (_skyboxTexture && _skyboxTexture->isLoaded() && _skyboxTexture->getGPUTexture()) {
|
||||
auto texture = _skyboxTexture->getGPUTexture();
|
||||
skybox->setCubemap(texture);
|
||||
_pendingSkyboxTexture = false;
|
||||
if (!isAmbientTextureSet && texture->getIrradiance()) {
|
||||
sceneKeyLight->setAmbientSphere(texture->getIrradiance());
|
||||
sceneKeyLight->setAmbientMap(texture);
|
||||
isAmbientTextureSet = true;
|
||||
}
|
||||
} else {
|
||||
|
@ -381,6 +384,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
|||
|
||||
if (!isAmbientTextureSet) {
|
||||
sceneKeyLight->resetAmbientSphere();
|
||||
sceneKeyLight->setAmbientMap(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
|
||||
// the diffuse texture
|
||||
// the albedo texture
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
|
|
|
@ -28,9 +28,6 @@ void main(void) {
|
|||
vec3 worldNormal = cross(dFdy(_worldPosition.xyz), dFdx(_worldPosition.xyz));
|
||||
worldNormal = normalize(worldNormal);
|
||||
|
||||
vec3 specular = DEFAULT_SPECULAR;
|
||||
float shininess = DEFAULT_SHININESS;
|
||||
|
||||
float inPositionX = (_worldPosition.x - 0.5) / voxelVolumeSize.x;
|
||||
float inPositionY = (_worldPosition.y - 0.5) / voxelVolumeSize.y;
|
||||
float inPositionZ = (_worldPosition.z - 0.5) / voxelVolumeSize.z;
|
||||
|
@ -44,5 +41,5 @@ void main(void) {
|
|||
vec3 yzDiffuseScaled = yzDiffuse.rgb * abs(worldNormal.x);
|
||||
vec4 diffuse = vec4(xyDiffuseScaled + xzDiffuseScaled + yzDiffuseScaled, 1.0);
|
||||
|
||||
packDeferredFragment(_normal, 1.0, vec3(diffuse), specular, shininess);
|
||||
packDeferredFragment(_normal, 1.0, vec3(diffuse), DEFAULT_ROUGHNESS, DEFAULT_METALLIC, DEFAULT_SPECULAR);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
out vec4 _color;
|
||||
|
||||
void main(void) {
|
||||
// pass along the diffuse color
|
||||
// pass along the color
|
||||
_color = colorToLinearRGBA(inColor);
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
|
|
@ -865,6 +865,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
}
|
||||
} else if (object.name == "Material") {
|
||||
FBXMaterial material;
|
||||
if (object.properties.at(1).toByteArray().contains("StingrayPBS")) {
|
||||
material.isPBSMaterial = true;
|
||||
}
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
bool properties = false;
|
||||
QByteArray propertyName;
|
||||
|
@ -879,7 +882,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
propertyName = "P";
|
||||
index = 4;
|
||||
}
|
||||
if (properties) {
|
||||
if (!material.isPBSMaterial && properties) {
|
||||
foreach (const FBXNode& property, subobject.children) {
|
||||
if (property.name == propertyName) {
|
||||
if (property.properties.at(0) == "DiffuseColor") {
|
||||
|
@ -914,6 +917,44 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
#endif
|
||||
}
|
||||
}
|
||||
} else if (material.isPBSMaterial && properties) {
|
||||
std::vector<std::string> unknowns;
|
||||
foreach(const FBXNode& property, subobject.children) {
|
||||
if (property.name == propertyName) {
|
||||
if (property.properties.at(0) == "Maya|use_normal_map") {
|
||||
material.useNormalMap = (bool)property.properties.at(index).value<double>();
|
||||
|
||||
} else if (property.properties.at(0) == "Maya|base_color") {
|
||||
material.diffuseColor = getVec3(property.properties, index);
|
||||
} else if (property.properties.at(0) == "Maya|use_color_map") {
|
||||
material.useAlbedoMap = (bool) property.properties.at(index).value<double>();
|
||||
|
||||
} else if (property.properties.at(0) == "Maya|roughness") {
|
||||
material.roughness = property.properties.at(index).value<double>();
|
||||
} else if (property.properties.at(0) == "Maya|use_roughness_map") {
|
||||
material.useRoughnessMap = (bool)property.properties.at(index).value<double>();
|
||||
|
||||
} else if (property.properties.at(0) == "Maya|metallic") {
|
||||
material.metallic = property.properties.at(index).value<double>();
|
||||
} else if (property.properties.at(0) == "Maya|use_metallic_map") {
|
||||
material.useMetallicMap = (bool)property.properties.at(index).value<double>();
|
||||
|
||||
} else if (property.properties.at(0) == "Maya|emissive") {
|
||||
material.emissiveColor = getVec3(property.properties, index);
|
||||
} else if (property.properties.at(0) == "Maya|emissive_intensity") {
|
||||
material.emissiveIntensity = property.properties.at(index).value<double>();
|
||||
} else if (property.properties.at(0) == "Maya|use_emissive_map") {
|
||||
material.useEmissiveMap = (bool)property.properties.at(index).value<double>();
|
||||
|
||||
} else if (property.properties.at(0) == "Maya|use_ao_map") {
|
||||
material.useOcclusionMap = (bool)property.properties.at(index).value<double>();
|
||||
|
||||
} else {
|
||||
const QString propname = property.properties.at(0).toString();
|
||||
unknowns.push_back(propname.toStdString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(DEBUG_FBXREADER)
|
||||
else {
|
||||
|
@ -1030,18 +1071,35 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
if (connection.properties.at(0) == "OP") {
|
||||
int counter = 0;
|
||||
QByteArray type = connection.properties.at(3).toByteArray().toLower();
|
||||
if (type.contains("diffuse")) {
|
||||
if ((type.contains("diffuse") && !type.contains("tex_global_diffuse"))) {
|
||||
diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("tex_color_map")) {
|
||||
diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
|
||||
} else if (type.contains("transparentcolor")) { // it should be TransparentColor...
|
||||
// THis is how Maya assign a texture that affect diffuse color AND transparency ?
|
||||
diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
transparentTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("bump")) {
|
||||
bumpTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("normal")) {
|
||||
normalTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("specular") || type.contains("reflection")) {
|
||||
} else if (type.contains("tex_normal_map")) {
|
||||
normalTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if ((type.contains("specular") && !type.contains("tex_global_specular")) || type.contains("reflection")) {
|
||||
specularTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("tex_metallic_map")) {
|
||||
metallicTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("shininess")) {
|
||||
shininessTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("tex_roughness_map")) {
|
||||
roughnessTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("emissive")) {
|
||||
emissiveTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("tex_emissive_map")) {
|
||||
emissiveTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("ambient")) {
|
||||
ambientTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("tex_ao_map")) {
|
||||
occlusionTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
|
||||
} else if (type == "lcl rotation") {
|
||||
localRotations.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
|
@ -1055,14 +1113,6 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
} else if (type == "d|z") {
|
||||
zComponents.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
|
||||
} else if (type.contains("shininess")) {
|
||||
counter++;
|
||||
|
||||
} else if (_loadLightmaps && type.contains("emissive")) {
|
||||
emissiveTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
|
||||
} else if (_loadLightmaps && type.contains("ambient")) {
|
||||
ambientTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else {
|
||||
QString typenam = type.data();
|
||||
counter++;
|
||||
|
|
|
@ -111,7 +111,7 @@ public:
|
|||
QString texcoordSetName;
|
||||
|
||||
bool isBumpmap{ false };
|
||||
|
||||
|
||||
bool isNull() const { return name.isEmpty() && filename.isEmpty() && content.isEmpty(); }
|
||||
};
|
||||
|
||||
|
@ -130,11 +130,10 @@ class FBXMaterial {
|
|||
public:
|
||||
FBXMaterial() {};
|
||||
FBXMaterial(const glm::vec3& diffuseColor, const glm::vec3& specularColor, const glm::vec3& emissiveColor,
|
||||
const glm::vec2& emissiveParams, float shininess, float opacity) :
|
||||
float shininess, float opacity) :
|
||||
diffuseColor(diffuseColor),
|
||||
specularColor(specularColor),
|
||||
emissiveColor(emissiveColor),
|
||||
emissiveParams(emissiveParams),
|
||||
shininess(shininess),
|
||||
opacity(opacity) {}
|
||||
|
||||
|
@ -144,18 +143,39 @@ public:
|
|||
float specularFactor = 1.0f;
|
||||
|
||||
glm::vec3 emissiveColor{ 0.0f };
|
||||
glm::vec2 emissiveParams{ 0.0f, 1.0f };
|
||||
float shininess = 23.0f;
|
||||
float opacity = 1.0f;
|
||||
|
||||
float metallic{ 0.0f };
|
||||
float roughness{ 1.0f };
|
||||
float emissiveIntensity{ 1.0f };
|
||||
|
||||
QString materialID;
|
||||
model::MaterialPointer _material;
|
||||
|
||||
FBXTexture diffuseTexture;
|
||||
FBXTexture opacityTexture;
|
||||
FBXTexture normalTexture;
|
||||
FBXTexture albedoTexture;
|
||||
FBXTexture opacityTexture;
|
||||
FBXTexture glossTexture;
|
||||
FBXTexture roughnessTexture;
|
||||
FBXTexture specularTexture;
|
||||
FBXTexture metallicTexture;
|
||||
FBXTexture emissiveTexture;
|
||||
FBXTexture occlusionTexture;
|
||||
FBXTexture lightmapTexture;
|
||||
glm::vec2 lightmapParams{ 0.0f, 1.0f };
|
||||
|
||||
|
||||
bool isPBSMaterial{ false };
|
||||
// THe use XXXMap are not really used to drive which map are going or not, debug only
|
||||
bool useNormalMap{ false };
|
||||
bool useAlbedoMap{ false };
|
||||
bool useOpacityMap{ false };
|
||||
bool useRoughnessMap{ false };
|
||||
bool useSpecularMap{ false };
|
||||
bool useMetallicMap{ false };
|
||||
bool useEmissiveMap{ false };
|
||||
bool useOcclusionMap{ false };
|
||||
|
||||
bool needTangentSpace() const;
|
||||
};
|
||||
|
@ -397,11 +417,16 @@ public:
|
|||
|
||||
|
||||
QHash<QString, QString> diffuseTextures;
|
||||
QHash<QString, QString> transparentTextures;
|
||||
QHash<QString, QString> bumpTextures;
|
||||
QHash<QString, QString> normalTextures;
|
||||
QHash<QString, QString> specularTextures;
|
||||
QHash<QString, QString> metallicTextures;
|
||||
QHash<QString, QString> roughnessTextures;
|
||||
QHash<QString, QString> shininessTextures;
|
||||
QHash<QString, QString> emissiveTextures;
|
||||
QHash<QString, QString> ambientTextures;
|
||||
QHash<QString, QString> occlusionTextures;
|
||||
|
||||
QHash<QString, FBXMaterial> _fbxMaterials;
|
||||
|
||||
|
|
|
@ -79,11 +79,20 @@ void FBXReader::consolidateFBXMaterials() {
|
|||
}
|
||||
}
|
||||
|
||||
material.diffuseTexture = diffuseTexture;
|
||||
|
||||
material.albedoTexture = diffuseTexture;
|
||||
detectDifferentUVs = (diffuseTexture.texcoordSet != 0) || (!diffuseTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
|
||||
|
||||
FBXTexture transparentTexture;
|
||||
QString transparentTextureID = transparentTextures.value(material.materialID);
|
||||
if (!transparentTextureID.isNull()) {
|
||||
transparentTexture = getTexture(transparentTextureID);
|
||||
|
||||
material.opacityTexture = transparentTexture;
|
||||
detectDifferentUVs |= (transparentTexture.texcoordSet != 0) || (!transparentTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
FBXTexture normalTexture;
|
||||
QString bumpTextureID = bumpTextures.value(material.materialID);
|
||||
QString normalTextureID = normalTextures.value(material.materialID);
|
||||
|
@ -100,37 +109,66 @@ void FBXReader::consolidateFBXMaterials() {
|
|||
material.normalTexture = normalTexture;
|
||||
detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
|
||||
|
||||
FBXTexture specularTexture;
|
||||
QString specularTextureID = specularTextures.value(material.materialID);
|
||||
if (!specularTextureID.isNull()) {
|
||||
specularTexture = getTexture(specularTextureID);
|
||||
detectDifferentUVs |= (specularTexture.texcoordSet != 0) || (!specularTexture.transform.isIdentity());
|
||||
|
||||
material.specularTexture = specularTexture;
|
||||
}
|
||||
|
||||
FBXTexture metallicTexture;
|
||||
QString metallicTextureID = metallicTextures.value(material.materialID);
|
||||
if (!metallicTextureID.isNull()) {
|
||||
metallicTexture = getTexture(metallicTextureID);
|
||||
detectDifferentUVs |= (metallicTexture.texcoordSet != 0) || (!metallicTexture.transform.isIdentity());
|
||||
material.metallicTexture = metallicTexture;
|
||||
}
|
||||
|
||||
FBXTexture roughnessTexture;
|
||||
QString roughnessTextureID = roughnessTextures.value(material.materialID);
|
||||
if (!roughnessTextureID.isNull()) {
|
||||
roughnessTexture = getTexture(roughnessTextureID);
|
||||
material.roughnessTexture = roughnessTexture;
|
||||
detectDifferentUVs |= (roughnessTexture.texcoordSet != 0) || (!roughnessTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
FBXTexture shininessTexture;
|
||||
QString shininessTextureID = shininessTextures.value(material.materialID);
|
||||
if (!shininessTextureID.isNull()) {
|
||||
shininessTexture = getTexture(shininessTextureID);
|
||||
material.glossTexture = shininessTexture;
|
||||
detectDifferentUVs |= (shininessTexture.texcoordSet != 0) || (!shininessTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
FBXTexture emissiveTexture;
|
||||
glm::vec2 emissiveParams(0.f, 1.f);
|
||||
emissiveParams.x = _lightmapOffset;
|
||||
emissiveParams.y = _lightmapLevel;
|
||||
|
||||
QString emissiveTextureID = emissiveTextures.value(material.materialID);
|
||||
QString ambientTextureID = ambientTextures.value(material.materialID);
|
||||
if (_loadLightmaps && (!emissiveTextureID.isNull() || !ambientTextureID.isNull())) {
|
||||
|
||||
if (!emissiveTextureID.isNull()) {
|
||||
emissiveTexture = getTexture(emissiveTextureID);
|
||||
emissiveParams.y = 4.0f;
|
||||
} else if (!ambientTextureID.isNull()) {
|
||||
emissiveTexture = getTexture(ambientTextureID);
|
||||
}
|
||||
|
||||
material.emissiveParams = emissiveParams;
|
||||
material.emissiveTexture = emissiveTexture;
|
||||
|
||||
if (!emissiveTextureID.isNull()) {
|
||||
emissiveTexture = getTexture(emissiveTextureID);
|
||||
detectDifferentUVs |= (emissiveTexture.texcoordSet != 0) || (!emissiveTexture.transform.isIdentity());
|
||||
material.emissiveTexture = emissiveTexture;
|
||||
}
|
||||
|
||||
FBXTexture occlusionTexture;
|
||||
QString occlusionTextureID = occlusionTextures.value(material.materialID);
|
||||
if (!occlusionTextureID.isNull()) {
|
||||
occlusionTexture = getTexture(occlusionTextureID);
|
||||
detectDifferentUVs |= (occlusionTexture.texcoordSet != 0) || (!emissiveTexture.transform.isIdentity());
|
||||
material.occlusionTexture = occlusionTexture;
|
||||
}
|
||||
|
||||
glm::vec2 lightmapParams(0.f, 1.f);
|
||||
lightmapParams.x = _lightmapOffset;
|
||||
lightmapParams.y = _lightmapLevel;
|
||||
|
||||
FBXTexture ambientTexture;
|
||||
QString ambientTextureID = ambientTextures.value(material.materialID);
|
||||
if (_loadLightmaps && !ambientTextureID.isNull()) {
|
||||
ambientTexture = getTexture(ambientTextureID);
|
||||
detectDifferentUVs |= (ambientTexture.texcoordSet != 0) || (!ambientTexture.transform.isIdentity());
|
||||
material.lightmapTexture = ambientTexture;
|
||||
material.lightmapParams = lightmapParams;
|
||||
}
|
||||
|
||||
// Finally create the true material representation
|
||||
|
@ -140,13 +178,16 @@ void FBXReader::consolidateFBXMaterials() {
|
|||
auto diffuse = material.diffuseColor;
|
||||
// FIXME: Do not use the Diffuse Factor yet as some FBX models have it set to 0
|
||||
// diffuse *= material.diffuseFactor;
|
||||
material._material->setDiffuse(diffuse);
|
||||
material._material->setAlbedo(diffuse);
|
||||
|
||||
float metallic = std::max(material.specularColor.x, std::max(material.specularColor.y, material.specularColor.z));
|
||||
// FIXME: Do not use the Specular Factor yet as some FBX models have it set to 0
|
||||
// metallic *= material.specularFactor;
|
||||
material._material->setMetallic(metallic);
|
||||
material._material->setGloss(material.shininess);
|
||||
if (material.isPBSMaterial) {
|
||||
material._material->setRoughness(material.roughness);
|
||||
material._material->setMetallic(material.metallic);
|
||||
} else {
|
||||
material._material->setRoughness(model::Material::shininessToRoughness(material.shininess));
|
||||
float metallic = std::max(material.specularColor.x, std::max(material.specularColor.y, material.specularColor.z));
|
||||
material._material->setMetallic(metallic);
|
||||
}
|
||||
|
||||
if (material.opacity <= 0.0f) {
|
||||
material._material->setOpacity(1.0f);
|
||||
|
|
|
@ -558,7 +558,6 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
|
|||
geometry.materials[materialID] = FBXMaterial(objMaterial.diffuseColor,
|
||||
objMaterial.specularColor,
|
||||
glm::vec3(0.0f),
|
||||
glm::vec2(0.0f, 1.0f),
|
||||
objMaterial.shininess,
|
||||
objMaterial.opacity);
|
||||
FBXMaterial& fbxMaterial = geometry.materials[materialID];
|
||||
|
@ -567,13 +566,13 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
|
|||
model::MaterialPointer modelMaterial = fbxMaterial._material;
|
||||
|
||||
if (!objMaterial.diffuseTextureFilename.isEmpty()) {
|
||||
fbxMaterial.diffuseTexture.filename = objMaterial.diffuseTextureFilename;
|
||||
fbxMaterial.albedoTexture.filename = objMaterial.diffuseTextureFilename;
|
||||
}
|
||||
|
||||
modelMaterial->setEmissive(fbxMaterial.emissiveColor);
|
||||
modelMaterial->setDiffuse(fbxMaterial.diffuseColor);
|
||||
modelMaterial->setAlbedo(fbxMaterial.diffuseColor);
|
||||
modelMaterial->setMetallic(glm::length(fbxMaterial.specularColor));
|
||||
modelMaterial->setGloss(fbxMaterial.shininess);
|
||||
modelMaterial->setRoughness(model::Material::shininessToRoughness(fbxMaterial.shininess));
|
||||
|
||||
if (fbxMaterial.opacity <= 0.0f) {
|
||||
modelMaterial->setOpacity(1.0f);
|
||||
|
@ -617,7 +616,7 @@ void fbxDebugDump(const FBXGeometry& fbxgeo) {
|
|||
qCDebug(modelformat) << " specularColor =" << meshPart.specularColor << "mat =" << meshPart._material->getMetallic();
|
||||
qCDebug(modelformat) << " emissiveColor =" << meshPart.emissiveColor << "mat =" << meshPart._material->getEmissive();
|
||||
qCDebug(modelformat) << " emissiveParams =" << meshPart.emissiveParams;
|
||||
qCDebug(modelformat) << " gloss =" << meshPart.shininess << "mat =" << meshPart._material->getGloss();
|
||||
qCDebug(modelformat) << " gloss =" << meshPart.shininess << "mat =" << meshPart._material->getRoughness();
|
||||
qCDebug(modelformat) << " opacity =" << meshPart.opacity << "mat =" << meshPart._material->getOpacity();
|
||||
*/
|
||||
qCDebug(modelformat) << " materialID =" << meshPart.materialID;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
using namespace gpu;
|
||||
|
||||
const Element Element::COLOR_RGBA_32{ VEC4, NUINT8, RGBA };
|
||||
const Element Element::COLOR_RGBA{ VEC4, FLOAT, RGBA };
|
||||
const Element Element::VEC4F_COLOR_RGBA{ VEC4, FLOAT, RGBA };
|
||||
const Element Element::VEC2F_UV{ VEC2, FLOAT, UV };
|
||||
const Element Element::VEC2F_XY{ VEC2, FLOAT, XY };
|
||||
const Element Element::VEC3F_XYZ{ VEC3, FLOAT, XYZ };
|
||||
|
|
|
@ -247,7 +247,7 @@ public:
|
|||
}
|
||||
|
||||
static const Element COLOR_RGBA_32;
|
||||
static const Element COLOR_RGBA;
|
||||
static const Element VEC4F_COLOR_RGBA;
|
||||
static const Element VEC2F_UV;
|
||||
static const Element VEC2F_XY;
|
||||
static const Element VEC3F_XYZ;
|
||||
|
|
|
@ -162,8 +162,6 @@ GLBackend::GLShader* compileShader(const Shader& shader) {
|
|||
char* temp = new char[infoLength] ;
|
||||
glGetShaderInfoLog(glshader, infoLength, NULL, temp);
|
||||
|
||||
qCWarning(gpulogging) << "GLShader::compileShader - failed to compile the gl shader object:";
|
||||
qCWarning(gpulogging) << temp;
|
||||
|
||||
/*
|
||||
filestream.open("debugshader.glsl.info.txt");
|
||||
|
@ -172,6 +170,11 @@ GLBackend::GLShader* compileShader(const Shader& shader) {
|
|||
filestream.close();
|
||||
}
|
||||
*/
|
||||
|
||||
qCWarning(gpulogging) << "GLShader::compileShader - failed to compile the gl shader object:";
|
||||
qCWarning(gpulogging) << srcstr;
|
||||
qCWarning(gpulogging) << "GLShader::compileShader - errors:";
|
||||
qCWarning(gpulogging) << temp;
|
||||
delete[] temp;
|
||||
|
||||
glDeleteShader(glshader);
|
||||
|
|
|
@ -145,6 +145,8 @@ public:
|
|||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
case gpu::SRGB:
|
||||
case gpu::SRGBA:
|
||||
texel.internalFormat = GL_RED;
|
||||
switch (dstFormat.getType()) {
|
||||
case gpu::UINT32: {
|
||||
|
@ -196,7 +198,11 @@ public:
|
|||
break;
|
||||
}
|
||||
case gpu::NUINT8: {
|
||||
texel.internalFormat = GL_R8;
|
||||
if ((dstFormat.getSemantic() == gpu::SRGB || dstFormat.getSemantic() == gpu::SRGBA)) {
|
||||
texel.internalFormat = GL_SLUMINANCE;
|
||||
} else {
|
||||
texel.internalFormat = GL_R8;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case gpu::NINT8: {
|
||||
|
@ -209,6 +215,7 @@ public:
|
|||
|
||||
}
|
||||
break;
|
||||
|
||||
case gpu::DEPTH:
|
||||
texel.format = GL_DEPTH_COMPONENT; // It's depth component to load it
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "Resource.h"
|
||||
|
||||
#include <algorithm> //min max and more
|
||||
#include <bitset>
|
||||
|
||||
#include <QUrl>
|
||||
|
||||
|
@ -139,6 +140,53 @@ protected:
|
|||
class Texture : public Resource {
|
||||
public:
|
||||
|
||||
class Usage {
|
||||
public:
|
||||
enum FlagBit {
|
||||
COLOR = 0, // Texture is a color map
|
||||
NORMAL, // Texture is a normal map
|
||||
ALPHA, // Texture has an alpha channel
|
||||
ALPHA_MASK, // Texture alpha channel is a Mask 0/1
|
||||
|
||||
NUM_FLAGS,
|
||||
};
|
||||
typedef std::bitset<NUM_FLAGS> Flags;
|
||||
|
||||
// The key is the Flags
|
||||
Flags _flags;
|
||||
|
||||
Usage() : _flags(0) {}
|
||||
Usage(const Flags& flags) : _flags(flags) {}
|
||||
|
||||
bool operator== (const Usage& rhs) const { return _flags == rhs._flags; }
|
||||
bool operator!= (const Usage& rhs) const { return _flags != rhs._flags; }
|
||||
|
||||
class Builder {
|
||||
friend class Usage;
|
||||
Flags _flags{ 0 };
|
||||
public:
|
||||
Builder() {}
|
||||
|
||||
Usage build() const { return Usage(_flags); }
|
||||
|
||||
Builder& withColor() { _flags.set(COLOR); return (*this); }
|
||||
Builder& withNormal() { _flags.set(NORMAL); return (*this); }
|
||||
Builder& withAlpha() { _flags.set(ALPHA); return (*this); }
|
||||
Builder& withAlphaMask() { _flags.set(ALPHA_MASK); return (*this); }
|
||||
};
|
||||
Usage(const Builder& builder) : Usage(builder._flags) {}
|
||||
|
||||
bool isColor() const { return _flags[COLOR]; }
|
||||
bool isNormal() const { return _flags[NORMAL]; }
|
||||
|
||||
bool isAlpha() const { return _flags[ALPHA]; }
|
||||
bool isAlphaMask() const { return _flags[ALPHA_MASK]; }
|
||||
|
||||
|
||||
bool operator==(const Usage& usage) { return (_flags == usage._flags); }
|
||||
bool operator!=(const Usage& usage) { return (_flags != usage._flags); }
|
||||
};
|
||||
|
||||
class Pixels {
|
||||
public:
|
||||
Pixels() {}
|
||||
|
@ -343,6 +391,10 @@ public:
|
|||
|
||||
bool isDefined() const { return _defined; }
|
||||
|
||||
// Usage is a a set of flags providing Semantic about the usage of the Texture.
|
||||
void setUsage(const Usage& usage) { _usage = usage; }
|
||||
Usage getUsage() const { return _usage; }
|
||||
|
||||
// For Cube Texture, it's possible to generate the irradiance spherical harmonics and make them availalbe with the texture
|
||||
bool generateIrradiance();
|
||||
const SHPointer& getIrradiance(uint16 slice = 0) const { return _irradiance; }
|
||||
|
@ -380,6 +432,8 @@ protected:
|
|||
|
||||
Type _type = TEX_1D;
|
||||
|
||||
Usage _usage;
|
||||
|
||||
SHPointer _irradiance;
|
||||
bool _autoGenerateMips = false;
|
||||
bool _isIrradianceValid = false;
|
||||
|
|
|
@ -136,10 +136,13 @@ bool NetworkGeometry::isLoadedWithTextures() const {
|
|||
|
||||
if (!_isLoadedWithTextures) {
|
||||
for (auto&& material : _materials) {
|
||||
if ((material->diffuseTexture && !material->diffuseTexture->isLoaded()) ||
|
||||
if ((material->albedoTexture && !material->albedoTexture->isLoaded()) ||
|
||||
(material->normalTexture && !material->normalTexture->isLoaded()) ||
|
||||
(material->specularTexture && !material->specularTexture->isLoaded()) ||
|
||||
(material->emissiveTexture && !material->emissiveTexture->isLoaded())) {
|
||||
(material->roughnessTexture && !material->roughnessTexture->isLoaded()) ||
|
||||
(material->metallicTexture && !material->metallicTexture->isLoaded()) ||
|
||||
(material->occlusionTexture && !material->occlusionTexture->isLoaded()) ||
|
||||
(material->emissiveTexture && !material->emissiveTexture->isLoaded()) ||
|
||||
(material->lightmapTexture && !material->lightmapTexture->isLoaded())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -154,15 +157,15 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u
|
|||
for (auto&& material : _materials) {
|
||||
auto networkMaterial = material->_material;
|
||||
auto oldTextureMaps = networkMaterial->getTextureMaps();
|
||||
if (material->diffuseTextureName == name) {
|
||||
material->diffuseTexture = textureCache->getTexture(url, DEFAULT_TEXTURE);
|
||||
if (material->albedoTextureName == name) {
|
||||
material->albedoTexture = textureCache->getTexture(url, DEFAULT_TEXTURE);
|
||||
|
||||
auto diffuseMap = model::TextureMapPointer(new model::TextureMap());
|
||||
diffuseMap->setTextureSource(material->diffuseTexture->_textureSource);
|
||||
diffuseMap->setTextureTransform(
|
||||
oldTextureMaps[model::MaterialKey::DIFFUSE_MAP]->getTextureTransform());
|
||||
auto albedoMap = model::TextureMapPointer(new model::TextureMap());
|
||||
albedoMap->setTextureSource(material->albedoTexture->_textureSource);
|
||||
albedoMap->setTextureTransform(
|
||||
oldTextureMaps[model::MaterialKey::ALBEDO_MAP]->getTextureTransform());
|
||||
|
||||
networkMaterial->setTextureMap(model::MaterialKey::DIFFUSE_MAP, diffuseMap);
|
||||
networkMaterial->setTextureMap(model::MaterialKey::ALBEDO_MAP, albedoMap);
|
||||
} else if (material->normalTextureName == name) {
|
||||
material->normalTexture = textureCache->getTexture(url);
|
||||
|
||||
|
@ -170,15 +173,31 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u
|
|||
normalMap->setTextureSource(material->normalTexture->_textureSource);
|
||||
|
||||
networkMaterial->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap);
|
||||
} else if (material->specularTextureName == name) {
|
||||
material->specularTexture = textureCache->getTexture(url);
|
||||
} else if (material->roughnessTextureName == name) {
|
||||
// FIXME: If passing a gloss map instead of a roughmap how to say that ? looking for gloss in the name ?
|
||||
material->roughnessTexture = textureCache->getTexture(url, ROUGHNESS_TEXTURE);
|
||||
|
||||
auto roughnessMap = model::TextureMapPointer(new model::TextureMap());
|
||||
roughnessMap->setTextureSource(material->roughnessTexture->_textureSource);
|
||||
|
||||
networkMaterial->setTextureMap(model::MaterialKey::ROUGHNESS_MAP, roughnessMap);
|
||||
} else if (material->metallicTextureName == name) {
|
||||
// FIXME: If passing a specular map instead of a metallic how to say that ? looking for wtf in the name ?
|
||||
material->metallicTexture = textureCache->getTexture(url, METALLIC_TEXTURE);
|
||||
|
||||
auto glossMap = model::TextureMapPointer(new model::TextureMap());
|
||||
glossMap->setTextureSource(material->specularTexture->_textureSource);
|
||||
glossMap->setTextureSource(material->metallicTexture->_textureSource);
|
||||
|
||||
networkMaterial->setTextureMap(model::MaterialKey::GLOSS_MAP, glossMap);
|
||||
networkMaterial->setTextureMap(model::MaterialKey::METALLIC_MAP, glossMap);
|
||||
} else if (material->emissiveTextureName == name) {
|
||||
material->emissiveTexture = textureCache->getTexture(url);
|
||||
material->emissiveTexture = textureCache->getTexture(url, EMISSIVE_TEXTURE);
|
||||
|
||||
auto emissiveMap = model::TextureMapPointer(new model::TextureMap());
|
||||
emissiveMap->setTextureSource(material->emissiveTexture->_textureSource);
|
||||
|
||||
networkMaterial->setTextureMap(model::MaterialKey::EMISSIVE_MAP, emissiveMap);
|
||||
} else if (material->lightmapTextureName == name) {
|
||||
material->emissiveTexture = textureCache->getTexture(url, LIGHTMAP_TEXTURE);
|
||||
|
||||
auto lightmapMap = model::TextureMapPointer(new model::TextureMap());
|
||||
lightmapMap->setTextureSource(material->emissiveTexture->_textureSource);
|
||||
|
@ -200,9 +219,14 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u
|
|||
QStringList NetworkGeometry::getTextureNames() const {
|
||||
QStringList result;
|
||||
for (auto&& material : _materials) {
|
||||
if (!material->diffuseTextureName.isEmpty() && material->diffuseTexture) {
|
||||
QString textureURL = material->diffuseTexture->getURL().toString();
|
||||
result << material->diffuseTextureName + ":\"" + textureURL + "\"";
|
||||
if (!material->emissiveTextureName.isEmpty() && material->emissiveTexture) {
|
||||
QString textureURL = material->emissiveTexture->getURL().toString();
|
||||
result << material->emissiveTextureName + ":\"" + textureURL + "\"";
|
||||
}
|
||||
|
||||
if (!material->albedoTextureName.isEmpty() && material->albedoTexture) {
|
||||
QString textureURL = material->albedoTexture->getURL().toString();
|
||||
result << material->albedoTextureName + ":\"" + textureURL + "\"";
|
||||
}
|
||||
|
||||
if (!material->normalTextureName.isEmpty() && material->normalTexture) {
|
||||
|
@ -210,14 +234,24 @@ QStringList NetworkGeometry::getTextureNames() const {
|
|||
result << material->normalTextureName + ":\"" + textureURL + "\"";
|
||||
}
|
||||
|
||||
if (!material->specularTextureName.isEmpty() && material->specularTexture) {
|
||||
QString textureURL = material->specularTexture->getURL().toString();
|
||||
result << material->specularTextureName + ":\"" + textureURL + "\"";
|
||||
if (!material->roughnessTextureName.isEmpty() && material->roughnessTexture) {
|
||||
QString textureURL = material->roughnessTexture->getURL().toString();
|
||||
result << material->roughnessTextureName + ":\"" + textureURL + "\"";
|
||||
}
|
||||
|
||||
if (!material->emissiveTextureName.isEmpty() && material->emissiveTexture) {
|
||||
QString textureURL = material->emissiveTexture->getURL().toString();
|
||||
result << material->emissiveTextureName + ":\"" + textureURL + "\"";
|
||||
if (!material->metallicTextureName.isEmpty() && material->metallicTexture) {
|
||||
QString textureURL = material->metallicTexture->getURL().toString();
|
||||
result << material->metallicTextureName + ":\"" + textureURL + "\"";
|
||||
}
|
||||
|
||||
if (!material->occlusionTextureName.isEmpty() && material->occlusionTexture) {
|
||||
QString textureURL = material->occlusionTexture->getURL().toString();
|
||||
result << material->occlusionTextureName + ":\"" + textureURL + "\"";
|
||||
}
|
||||
|
||||
if (!material->lightmapTextureName.isEmpty() && material->lightmapTexture) {
|
||||
QString textureURL = material->lightmapTexture->getURL().toString();
|
||||
result << material->lightmapTextureName + ":\"" + textureURL + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,7 +338,8 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas
|
|||
return networkMesh;
|
||||
}
|
||||
|
||||
static model::TextureMapPointer setupNetworkTextureMap(const QUrl& textureBaseUrl,
|
||||
|
||||
static model::TextureMapPointer setupNetworkTextureMap(NetworkGeometry* geometry, const QUrl& textureBaseUrl,
|
||||
const FBXTexture& texture, TextureType type,
|
||||
NetworkTexturePointer& networkTexture, QString& networkTextureName) {
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
|
@ -314,6 +349,7 @@ static model::TextureMapPointer setupNetworkTextureMap(const QUrl& textureBaseUr
|
|||
const auto filename = baseUrl.resolved(QUrl(texture.filename));
|
||||
|
||||
networkTexture = textureCache->getTexture(filename, type, texture.content);
|
||||
QObject::connect(networkTexture.data(), &NetworkTexture::networkTextureCreated, geometry, &NetworkGeometry::textureLoaded);
|
||||
networkTextureName = texture.name;
|
||||
|
||||
auto map = std::make_shared<model::TextureMap>();
|
||||
|
@ -321,33 +357,66 @@ static model::TextureMapPointer setupNetworkTextureMap(const QUrl& textureBaseUr
|
|||
return map;
|
||||
}
|
||||
|
||||
static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl) {
|
||||
static NetworkMaterial* buildNetworkMaterial(NetworkGeometry* geometry, const FBXMaterial& material, const QUrl& textureBaseUrl) {
|
||||
NetworkMaterial* networkMaterial = new NetworkMaterial();
|
||||
networkMaterial->_material = material._material;
|
||||
|
||||
if (!material.diffuseTexture.filename.isEmpty()) {
|
||||
auto diffuseMap = setupNetworkTextureMap(textureBaseUrl, material.diffuseTexture, DEFAULT_TEXTURE,
|
||||
networkMaterial->diffuseTexture, networkMaterial->diffuseTextureName);
|
||||
diffuseMap->setTextureTransform(material.diffuseTexture.transform);
|
||||
networkMaterial->_material->setTextureMap(model::MaterialKey::DIFFUSE_MAP, diffuseMap);
|
||||
if (!material.albedoTexture.filename.isEmpty()) {
|
||||
auto albedoMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.albedoTexture, DEFAULT_TEXTURE,
|
||||
networkMaterial->albedoTexture, networkMaterial->albedoTextureName);
|
||||
albedoMap->setTextureTransform(material.albedoTexture.transform);
|
||||
material._material->setTextureMap(model::MaterialKey::ALBEDO_MAP, albedoMap);
|
||||
}
|
||||
|
||||
if (!material.normalTexture.filename.isEmpty()) {
|
||||
auto normalMap = setupNetworkTextureMap(textureBaseUrl, material.normalTexture,
|
||||
auto normalMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.normalTexture,
|
||||
(material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE),
|
||||
networkMaterial->normalTexture, networkMaterial->normalTextureName);
|
||||
networkMaterial->_material->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap);
|
||||
}
|
||||
if (!material.specularTexture.filename.isEmpty()) {
|
||||
auto glossMap = setupNetworkTextureMap(textureBaseUrl, material.specularTexture, SPECULAR_TEXTURE,
|
||||
networkMaterial->specularTexture, networkMaterial->specularTextureName);
|
||||
networkMaterial->_material->setTextureMap(model::MaterialKey::GLOSS_MAP, glossMap);
|
||||
|
||||
// Roughness first or gloss maybe
|
||||
if (!material.roughnessTexture.filename.isEmpty()) {
|
||||
auto roughnessMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.roughnessTexture, ROUGHNESS_TEXTURE,
|
||||
networkMaterial->roughnessTexture, networkMaterial->roughnessTextureName);
|
||||
material._material->setTextureMap(model::MaterialKey::ROUGHNESS_MAP, roughnessMap);
|
||||
} else if (!material.glossTexture.filename.isEmpty()) {
|
||||
auto roughnessMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.glossTexture, GLOSS_TEXTURE,
|
||||
networkMaterial->roughnessTexture, networkMaterial->roughnessTextureName);
|
||||
material._material->setTextureMap(model::MaterialKey::ROUGHNESS_MAP, roughnessMap);
|
||||
}
|
||||
|
||||
// Metallic first or specular maybe
|
||||
|
||||
if (!material.metallicTexture.filename.isEmpty()) {
|
||||
auto metallicMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.metallicTexture, METALLIC_TEXTURE,
|
||||
networkMaterial->metallicTexture, networkMaterial->metallicTextureName);
|
||||
material._material->setTextureMap(model::MaterialKey::METALLIC_MAP, metallicMap);
|
||||
} else if (!material.specularTexture.filename.isEmpty()) {
|
||||
|
||||
auto metallicMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.specularTexture, SPECULAR_TEXTURE,
|
||||
networkMaterial->metallicTexture, networkMaterial->metallicTextureName);
|
||||
material._material->setTextureMap(model::MaterialKey::METALLIC_MAP, metallicMap);
|
||||
}
|
||||
|
||||
if (!material.occlusionTexture.filename.isEmpty()) {
|
||||
auto occlusionMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.occlusionTexture, OCCLUSION_TEXTURE,
|
||||
networkMaterial->occlusionTexture, networkMaterial->occlusionTextureName);
|
||||
material._material->setTextureMap(model::MaterialKey::OCCLUSION_MAP, occlusionMap);
|
||||
}
|
||||
|
||||
if (!material.emissiveTexture.filename.isEmpty()) {
|
||||
auto lightmapMap = setupNetworkTextureMap(textureBaseUrl, material.emissiveTexture, LIGHTMAP_TEXTURE,
|
||||
auto emissiveMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.emissiveTexture, EMISSIVE_TEXTURE,
|
||||
networkMaterial->emissiveTexture, networkMaterial->emissiveTextureName);
|
||||
lightmapMap->setTextureTransform(material.emissiveTexture.transform);
|
||||
lightmapMap->setLightmapOffsetScale(material.emissiveParams.x, material.emissiveParams.y);
|
||||
networkMaterial->_material->setTextureMap(model::MaterialKey::LIGHTMAP_MAP, lightmapMap);
|
||||
material._material->setTextureMap(model::MaterialKey::EMISSIVE_MAP, emissiveMap);
|
||||
}
|
||||
|
||||
if (!material.lightmapTexture.filename.isEmpty()) {
|
||||
auto lightmapMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.lightmapTexture, LIGHTMAP_TEXTURE,
|
||||
networkMaterial->lightmapTexture, networkMaterial->lightmapTextureName);
|
||||
lightmapMap->setTextureTransform(material.lightmapTexture.transform);
|
||||
lightmapMap->setLightmapOffsetScale(material.lightmapParams.x, material.lightmapParams.y);
|
||||
material._material->setTextureMap(model::MaterialKey::LIGHTMAP_MAP, lightmapMap);
|
||||
}
|
||||
|
||||
return networkMaterial;
|
||||
|
@ -367,7 +436,7 @@ void NetworkGeometry::modelParseSuccess(FBXGeometry* geometry) {
|
|||
QHash<QString, size_t> fbxMatIDToMatID;
|
||||
foreach(const FBXMaterial& material, _geometry->materials) {
|
||||
fbxMatIDToMatID[material.materialID] = _materials.size();
|
||||
_materials.emplace_back(buildNetworkMaterial(material, _textureBaseUrl));
|
||||
_materials.emplace_back(buildNetworkMaterial(this, material, _textureBaseUrl));
|
||||
}
|
||||
|
||||
|
||||
|
@ -413,3 +482,6 @@ const NetworkMaterial* NetworkGeometry::getShapeMaterial(int shapeID) {
|
|||
}
|
||||
}
|
||||
|
||||
void NetworkGeometry::textureLoaded(const QWeakPointer<NetworkTexture>& networkTexture) {
|
||||
numTextureLoaded++;
|
||||
}
|
||||
|
|
|
@ -105,6 +105,9 @@ signals:
|
|||
// Fired when something went wrong.
|
||||
void onFailure(NetworkGeometry& networkGeometry, Error error);
|
||||
|
||||
public slots:
|
||||
void textureLoaded(const QWeakPointer<NetworkTexture>& networkTexture);
|
||||
|
||||
protected slots:
|
||||
void mappingRequestDone(const QByteArray& data);
|
||||
void mappingRequestError(QNetworkReply::NetworkError error);
|
||||
|
@ -115,6 +118,7 @@ protected slots:
|
|||
void modelParseSuccess(FBXGeometry* geometry);
|
||||
void modelParseError(int error, QString str);
|
||||
|
||||
|
||||
protected:
|
||||
void attemptRequestInternal();
|
||||
void requestMapping(const QUrl& url);
|
||||
|
@ -133,6 +137,7 @@ protected:
|
|||
QUrl _modelUrl;
|
||||
QVariantHash _mapping;
|
||||
QUrl _textureBaseUrl;
|
||||
int numTextureLoaded = 0;
|
||||
|
||||
Resource* _resource = nullptr;
|
||||
std::unique_ptr<FBXGeometry> _geometry; // This should go away evenutally once we can put everything we need in the model::AssetPointer
|
||||
|
@ -173,15 +178,23 @@ public:
|
|||
|
||||
class NetworkMaterial {
|
||||
public:
|
||||
|
||||
model::MaterialPointer _material;
|
||||
QString diffuseTextureName;
|
||||
QSharedPointer<NetworkTexture> diffuseTexture;
|
||||
QString normalTextureName;
|
||||
QSharedPointer<NetworkTexture> normalTexture;
|
||||
QString specularTextureName;
|
||||
QSharedPointer<NetworkTexture> specularTexture;
|
||||
QString emissiveTextureName;
|
||||
QSharedPointer<NetworkTexture> emissiveTexture;
|
||||
QString albedoTextureName;
|
||||
QSharedPointer<NetworkTexture> albedoTexture;
|
||||
QString normalTextureName;
|
||||
QSharedPointer<NetworkTexture> normalTexture;
|
||||
QString roughnessTextureName;
|
||||
QSharedPointer<NetworkTexture> roughnessTexture;
|
||||
QString metallicTextureName;
|
||||
QSharedPointer<NetworkTexture> metallicTexture;
|
||||
QString occlusionTextureName;
|
||||
QSharedPointer<NetworkTexture> occlusionTexture;
|
||||
QString lightmapTextureName;
|
||||
QSharedPointer<NetworkTexture> lightmapTexture;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -212,12 +212,23 @@ NetworkTexture::TextureLoaderFunc NetworkTexture::getTextureLoader() const {
|
|||
return TextureLoaderFunc(model::TextureUsage::createNormalTextureFromNormalImage);
|
||||
break;
|
||||
}
|
||||
case ROUGHNESS_TEXTURE: {
|
||||
return TextureLoaderFunc(model::TextureUsage::createRoughnessTextureFromImage);
|
||||
break;
|
||||
}
|
||||
case GLOSS_TEXTURE: {
|
||||
return TextureLoaderFunc(model::TextureUsage::createRoughnessTextureFromGlossImage);
|
||||
break;
|
||||
}
|
||||
case SPECULAR_TEXTURE: {
|
||||
return TextureLoaderFunc(model::TextureUsage::createMetallicTextureFromImage);
|
||||
break;
|
||||
}
|
||||
case CUSTOM_TEXTURE: {
|
||||
return _textureLoader;
|
||||
break;
|
||||
}
|
||||
case DEFAULT_TEXTURE:
|
||||
case SPECULAR_TEXTURE:
|
||||
case EMISSIVE_TEXTURE:
|
||||
default: {
|
||||
return TextureLoaderFunc(model::TextureUsage::create2DTextureFromImage);
|
||||
|
@ -335,10 +346,6 @@ void NetworkTexture::setImage(const QImage& image, void* voidTexture, int origin
|
|||
|
||||
finishedLoading(true);
|
||||
|
||||
imageLoaded(image);
|
||||
}
|
||||
|
||||
void NetworkTexture::imageLoaded(const QImage& image) {
|
||||
// nothing by default
|
||||
emit networkTextureCreated(qWeakPointerCast<NetworkTexture, Resource> (_self));
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,20 @@ class NetworkTexture;
|
|||
|
||||
typedef QSharedPointer<NetworkTexture> NetworkTexturePointer;
|
||||
|
||||
enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, BUMP_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, CUBE_TEXTURE, LIGHTMAP_TEXTURE, CUSTOM_TEXTURE };
|
||||
enum TextureType {
|
||||
DEFAULT_TEXTURE,
|
||||
NORMAL_TEXTURE,
|
||||
BUMP_TEXTURE,
|
||||
SPECULAR_TEXTURE,
|
||||
METALLIC_TEXTURE = SPECULAR_TEXTURE, // for now spec and metallic texture are the same, converted to grey
|
||||
ROUGHNESS_TEXTURE,
|
||||
GLOSS_TEXTURE,
|
||||
EMISSIVE_TEXTURE,
|
||||
CUBE_TEXTURE,
|
||||
OCCLUSION_TEXTURE,
|
||||
LIGHTMAP_TEXTURE,
|
||||
CUSTOM_TEXTURE
|
||||
};
|
||||
|
||||
/// Stores cached textures, including render-to-texture targets.
|
||||
class TextureCache : public ResourceCache, public Dependency {
|
||||
|
@ -83,8 +96,6 @@ private:
|
|||
gpu::TexturePointer _blueTexture;
|
||||
gpu::TexturePointer _blackTexture;
|
||||
gpu::TexturePointer _normalFittingTexture;
|
||||
|
||||
QHash<QUrl, QWeakPointer<NetworkTexture> > _dilatableNetworkTextures;
|
||||
};
|
||||
|
||||
/// A simple object wrapper for an OpenGL texture.
|
||||
|
@ -114,7 +125,11 @@ public:
|
|||
int getHeight() const { return _height; }
|
||||
|
||||
TextureLoaderFunc getTextureLoader() const;
|
||||
|
||||
|
||||
signals:
|
||||
void networkTextureCreated(const QWeakPointer<NetworkTexture>& self);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual void downloadFinished(const QByteArray& data) override;
|
||||
|
@ -123,8 +138,6 @@ protected:
|
|||
// FIXME: This void* should be a gpu::Texture* but i cannot get it to work for now, moving on...
|
||||
Q_INVOKABLE void setImage(const QImage& image, void* texture, int originalWidth, int originalHeight);
|
||||
|
||||
virtual void imageLoaded(const QImage& image);
|
||||
|
||||
|
||||
private:
|
||||
TextureType _type;
|
||||
|
|
|
@ -130,7 +130,7 @@ void Light::setShowContour(float show) {
|
|||
if (show <= 0.f) {
|
||||
show = 0.0f;
|
||||
}
|
||||
editSchema()._control.w = show;
|
||||
editSchema()._control.z = show;
|
||||
}
|
||||
|
||||
void Light::setAmbientSphere(const gpu::SphericalHarmonics& sphere) {
|
||||
|
@ -140,3 +140,16 @@ void Light::setAmbientSphere(const gpu::SphericalHarmonics& sphere) {
|
|||
void Light::setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) {
|
||||
editSchema()._ambientSphere.assignPreset(preset);
|
||||
}
|
||||
|
||||
void Light::setAmbientMap(gpu::TexturePointer ambientMap) {
|
||||
_ambientMap = ambientMap;
|
||||
if (ambientMap) {
|
||||
setAmbientMapNumMips(_ambientMap->evalNumMips());
|
||||
} else {
|
||||
setAmbientMapNumMips(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Light::setAmbientMapNumMips(uint16_t numMips) {
|
||||
editSchema()._ambientMapNumMips = (float)numMips;
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
// For editing purpose, show the light volume contour.
|
||||
// Set to non 0 to show it, the value is used as the intensity of the contour color
|
||||
void setShowContour(float show);
|
||||
float getShowContour() const { return getSchema()._control.w; }
|
||||
float getShowContour() const { return getSchema()._control.z; }
|
||||
|
||||
// If the light has an ambient (Indirect) component, then the Ambientintensity can be used to control its contribution to the lighting
|
||||
void setAmbientIntensity(float intensity);
|
||||
|
@ -108,6 +108,12 @@ public:
|
|||
const gpu::SphericalHarmonics& getAmbientSphere() const { return getSchema()._ambientSphere; }
|
||||
void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset);
|
||||
|
||||
void setAmbientMap(gpu::TexturePointer ambientMap);
|
||||
gpu::TexturePointer getAmbientMap() const { return _ambientMap; }
|
||||
|
||||
void setAmbientMapNumMips(uint16_t numMips);
|
||||
uint16_t getAmbientMapNumMips() const { return (uint16_t) getSchema()._ambientMapNumMips; }
|
||||
|
||||
// Schema to access the attribute values of the light
|
||||
class Schema {
|
||||
public:
|
||||
|
@ -120,7 +126,8 @@ public:
|
|||
Vec4 _spot{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
Vec4 _shadow{0.0f};
|
||||
|
||||
Vec4 _control{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
float _ambientMapNumMips{ 0.0f };
|
||||
Vec3 _control{ 0.0f, 0.0f, 0.0f };
|
||||
|
||||
gpu::SphericalHarmonics _ambientSphere;
|
||||
};
|
||||
|
@ -133,6 +140,8 @@ protected:
|
|||
UniformBufferView _schemaBuffer;
|
||||
Transform _transform;
|
||||
|
||||
gpu::TexturePointer _ambientMap;
|
||||
|
||||
const Schema& getSchema() const { return _schemaBuffer.get<Schema>(); }
|
||||
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }
|
||||
|
||||
|
|
|
@ -109,6 +109,10 @@ SphericalHarmonics getLightAmbientSphere(Light l) {
|
|||
return l._ambientSphere;
|
||||
}
|
||||
|
||||
float getLightAmbientMapNumMips(Light l) {
|
||||
return l._control.x;
|
||||
}
|
||||
|
||||
<@if GPU_FEATURE_PROFILE == GPU_CORE @>
|
||||
uniform lightBuffer {
|
||||
Light light;
|
||||
|
|
|
@ -44,37 +44,51 @@ Material& Material::operator= (const Material& material) {
|
|||
Material::~Material() {
|
||||
}
|
||||
|
||||
void Material::setDiffuse(const Color& diffuse, bool isSRGB) {
|
||||
_key.setDiffuse(glm::any(glm::greaterThan(diffuse, Color(0.0f))));
|
||||
_schemaBuffer.edit<Schema>()._diffuse = (isSRGB ? ColorUtils::toLinearVec3(diffuse) : diffuse);
|
||||
}
|
||||
|
||||
void Material::setMetallic(float metallic) {
|
||||
_key.setMetallic(metallic > 0.0f);
|
||||
_schemaBuffer.edit<Schema>()._metallic = glm::vec3(metallic);
|
||||
}
|
||||
|
||||
void Material::setEmissive(const Color& emissive, bool isSRGB) {
|
||||
_key.setEmissive(glm::any(glm::greaterThan(emissive, Color(0.0f))));
|
||||
_schemaBuffer.edit<Schema>()._key = (uint32) _key._flags.to_ulong();
|
||||
_schemaBuffer.edit<Schema>()._emissive = (isSRGB ? ColorUtils::toLinearVec3(emissive) : emissive);
|
||||
}
|
||||
|
||||
void Material::setGloss(float gloss) {
|
||||
_key.setGloss((gloss > 0.0f));
|
||||
_schemaBuffer.edit<Schema>()._gloss = gloss;
|
||||
}
|
||||
|
||||
void Material::setOpacity(float opacity) {
|
||||
_key.setTransparent((opacity < 1.0f));
|
||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||
_schemaBuffer.edit<Schema>()._opacity = opacity;
|
||||
}
|
||||
|
||||
void Material::setAlbedo(const Color& albedo, bool isSRGB) {
|
||||
_key.setAlbedo(glm::any(glm::greaterThan(albedo, Color(0.0f))));
|
||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||
_schemaBuffer.edit<Schema>()._albedo = (isSRGB ? ColorUtils::toLinearVec3(albedo) : albedo);
|
||||
}
|
||||
|
||||
void Material::setRoughness(float roughness) {
|
||||
roughness = std::min(1.0f, std::max(roughness, 0.0f));
|
||||
_key.setGlossy((roughness < 1.0f));
|
||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||
_schemaBuffer.edit<Schema>()._roughness = roughness;
|
||||
}
|
||||
|
||||
void Material::setFresnel(const Color& fresnel, bool isSRGB) {
|
||||
//_key.setAlbedo(glm::any(glm::greaterThan(albedo, Color(0.0f))));
|
||||
_schemaBuffer.edit<Schema>()._fresnel = (isSRGB ? ColorUtils::toLinearVec3(fresnel) : fresnel);
|
||||
}
|
||||
|
||||
void Material::setMetallic(float metallic) {
|
||||
_key.setMetallic(metallic > 0.0f);
|
||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||
_schemaBuffer.edit<Schema>()._metallic = metallic;
|
||||
}
|
||||
|
||||
|
||||
void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) {
|
||||
if (textureMap) {
|
||||
_key.setMapChannel(channel, (true));
|
||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||
_textureMaps[channel] = textureMap;
|
||||
} else {
|
||||
_key.setMapChannel(channel, (false));
|
||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||
_textureMaps.erase(channel);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,17 +28,18 @@ class MaterialKey {
|
|||
public:
|
||||
enum FlagBit {
|
||||
EMISSIVE_VAL_BIT = 0,
|
||||
DIFFUSE_VAL_BIT,
|
||||
ALBEDO_VAL_BIT,
|
||||
METALLIC_VAL_BIT,
|
||||
GLOSS_VAL_BIT,
|
||||
GLOSSY_VAL_BIT,
|
||||
TRANSPARENT_VAL_BIT,
|
||||
|
||||
EMISSIVE_MAP_BIT,
|
||||
DIFFUSE_MAP_BIT,
|
||||
ALBEDO_MAP_BIT,
|
||||
METALLIC_MAP_BIT,
|
||||
GLOSS_MAP_BIT,
|
||||
ROUGHNESS_MAP_BIT,
|
||||
TRANSPARENT_MAP_BIT,
|
||||
NORMAL_MAP_BIT,
|
||||
OCCLUSION_MAP_BIT,
|
||||
LIGHTMAP_MAP_BIT,
|
||||
|
||||
NUM_FLAGS,
|
||||
|
@ -47,11 +48,12 @@ public:
|
|||
|
||||
enum MapChannel {
|
||||
EMISSIVE_MAP = 0,
|
||||
DIFFUSE_MAP,
|
||||
ALBEDO_MAP,
|
||||
METALLIC_MAP,
|
||||
GLOSS_MAP,
|
||||
ROUGHNESS_MAP,
|
||||
TRANSPARENT_MAP,
|
||||
NORMAL_MAP,
|
||||
OCCLUSION_MAP,
|
||||
LIGHTMAP_MAP,
|
||||
|
||||
NUM_MAP_CHANNELS,
|
||||
|
@ -71,22 +73,23 @@ public:
|
|||
MaterialKey build() const { return MaterialKey(_flags); }
|
||||
|
||||
Builder& withEmissive() { _flags.set(EMISSIVE_VAL_BIT); return (*this); }
|
||||
Builder& withDiffuse() { _flags.set(DIFFUSE_VAL_BIT); return (*this); }
|
||||
Builder& withAlbedo() { _flags.set(ALBEDO_VAL_BIT); return (*this); }
|
||||
Builder& withMetallic() { _flags.set(METALLIC_VAL_BIT); return (*this); }
|
||||
Builder& withGloss() { _flags.set(GLOSS_VAL_BIT); return (*this); }
|
||||
Builder& withGlossy() { _flags.set(GLOSSY_VAL_BIT); return (*this); }
|
||||
Builder& withTransparent() { _flags.set(TRANSPARENT_VAL_BIT); return (*this); }
|
||||
|
||||
Builder& withEmissiveMap() { _flags.set(EMISSIVE_MAP_BIT); return (*this); }
|
||||
Builder& withDiffuseMap() { _flags.set(DIFFUSE_MAP_BIT); return (*this); }
|
||||
Builder& withAlbedoMap() { _flags.set(ALBEDO_MAP_BIT); return (*this); }
|
||||
Builder& withMetallicMap() { _flags.set(METALLIC_MAP_BIT); return (*this); }
|
||||
Builder& withGlossMap() { _flags.set(GLOSS_MAP_BIT); return (*this); }
|
||||
Builder& withRoughnessMap() { _flags.set(ROUGHNESS_MAP_BIT); return (*this); }
|
||||
Builder& withTransparentMap() { _flags.set(TRANSPARENT_MAP_BIT); return (*this); }
|
||||
|
||||
Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); }
|
||||
Builder& withOcclusionMap() { _flags.set(OCCLUSION_MAP_BIT); return (*this); }
|
||||
Builder& withLightmapMap() { _flags.set(LIGHTMAP_MAP_BIT); return (*this); }
|
||||
|
||||
// Convenient standard keys that we will keep on using all over the place
|
||||
static MaterialKey opaqueDiffuse() { return Builder().withDiffuse().build(); }
|
||||
static MaterialKey opaqueAlbedo() { return Builder().withAlbedo().build(); }
|
||||
};
|
||||
|
||||
void setEmissive(bool value) { _flags.set(EMISSIVE_VAL_BIT, value); }
|
||||
|
@ -95,11 +98,11 @@ public:
|
|||
void setEmissiveMap(bool value) { _flags.set(EMISSIVE_MAP_BIT, value); }
|
||||
bool isEmissiveMap() const { return _flags[EMISSIVE_MAP_BIT]; }
|
||||
|
||||
void setDiffuse(bool value) { _flags.set(DIFFUSE_VAL_BIT, value); }
|
||||
bool isDiffuse() const { return _flags[DIFFUSE_VAL_BIT]; }
|
||||
void setAlbedo(bool value) { _flags.set(ALBEDO_VAL_BIT, value); }
|
||||
bool isAlbedo() const { return _flags[ALBEDO_VAL_BIT]; }
|
||||
|
||||
void setDiffuseMap(bool value) { _flags.set(DIFFUSE_MAP_BIT, value); }
|
||||
bool isDiffuseMap() const { return _flags[DIFFUSE_MAP_BIT]; }
|
||||
void setAlbedoMap(bool value) { _flags.set(ALBEDO_MAP_BIT, value); }
|
||||
bool isAlbedoMap() const { return _flags[ALBEDO_MAP_BIT]; }
|
||||
|
||||
void setMetallic(bool value) { _flags.set(METALLIC_VAL_BIT, value); }
|
||||
bool isMetallic() const { return _flags[METALLIC_VAL_BIT]; }
|
||||
|
@ -107,11 +110,12 @@ public:
|
|||
void setMetallicMap(bool value) { _flags.set(METALLIC_MAP_BIT, value); }
|
||||
bool isMetallicMap() const { return _flags[METALLIC_MAP_BIT]; }
|
||||
|
||||
void setGloss(bool value) { _flags.set(GLOSS_VAL_BIT, value); }
|
||||
bool isGloss() const { return _flags[GLOSS_VAL_BIT]; }
|
||||
void setGlossy(bool value) { _flags.set(GLOSSY_VAL_BIT, value); }
|
||||
bool isGlossy() const { return _flags[GLOSSY_VAL_BIT]; }
|
||||
bool isRough() const { return !_flags[GLOSSY_VAL_BIT]; }
|
||||
|
||||
void setGlossMap(bool value) { _flags.set(GLOSS_MAP_BIT, value); }
|
||||
bool isGlossMap() const { return _flags[GLOSS_MAP_BIT]; }
|
||||
void setRoughnessMap(bool value) { _flags.set(ROUGHNESS_MAP_BIT, value); }
|
||||
bool isRoughnessMap() const { return _flags[ROUGHNESS_MAP_BIT]; }
|
||||
|
||||
void setTransparent(bool value) { _flags.set(TRANSPARENT_VAL_BIT, value); }
|
||||
bool isTransparent() const { return _flags[TRANSPARENT_VAL_BIT]; }
|
||||
|
@ -123,6 +127,9 @@ public:
|
|||
void setNormalMap(bool value) { _flags.set(NORMAL_MAP_BIT, value); }
|
||||
bool isNormalMap() const { return _flags[NORMAL_MAP_BIT]; }
|
||||
|
||||
void setOcclusionMap(bool value) { _flags.set(OCCLUSION_MAP_BIT, value); }
|
||||
bool isOcclusionMap() const { return _flags[OCCLUSION_MAP_BIT]; }
|
||||
|
||||
void setLightmapMap(bool value) { _flags.set(LIGHTMAP_MAP_BIT, value); }
|
||||
bool isLightmapMap() const { return _flags[LIGHTMAP_MAP_BIT]; }
|
||||
|
||||
|
@ -154,11 +161,11 @@ public:
|
|||
Builder& withoutEmissiveMap() { _value.reset(MaterialKey::EMISSIVE_MAP_BIT); _mask.set(MaterialKey::EMISSIVE_MAP_BIT); return (*this); }
|
||||
Builder& withEmissiveMap() { _value.set(MaterialKey::EMISSIVE_MAP_BIT); _mask.set(MaterialKey::EMISSIVE_MAP_BIT); return (*this); }
|
||||
|
||||
Builder& withoutDiffuse() { _value.reset(MaterialKey::DIFFUSE_VAL_BIT); _mask.set(MaterialKey::DIFFUSE_VAL_BIT); return (*this); }
|
||||
Builder& withDiffuse() { _value.set(MaterialKey::DIFFUSE_VAL_BIT); _mask.set(MaterialKey::DIFFUSE_VAL_BIT); return (*this); }
|
||||
Builder& withoutAlbedo() { _value.reset(MaterialKey::ALBEDO_VAL_BIT); _mask.set(MaterialKey::ALBEDO_VAL_BIT); return (*this); }
|
||||
Builder& withAlbedo() { _value.set(MaterialKey::ALBEDO_VAL_BIT); _mask.set(MaterialKey::ALBEDO_VAL_BIT); return (*this); }
|
||||
|
||||
Builder& withoutDiffuseMap() { _value.reset(MaterialKey::DIFFUSE_MAP_BIT); _mask.set(MaterialKey::DIFFUSE_MAP_BIT); return (*this); }
|
||||
Builder& withDiffuseMap() { _value.set(MaterialKey::DIFFUSE_MAP_BIT); _mask.set(MaterialKey::DIFFUSE_MAP_BIT); return (*this); }
|
||||
Builder& withoutAlbedoMap() { _value.reset(MaterialKey::ALBEDO_MAP_BIT); _mask.set(MaterialKey::ALBEDO_MAP_BIT); return (*this); }
|
||||
Builder& withAlbedoMap() { _value.set(MaterialKey::ALBEDO_MAP_BIT); _mask.set(MaterialKey::ALBEDO_MAP_BIT); return (*this); }
|
||||
|
||||
Builder& withoutMetallic() { _value.reset(MaterialKey::METALLIC_VAL_BIT); _mask.set(MaterialKey::METALLIC_VAL_BIT); return (*this); }
|
||||
Builder& withMetallic() { _value.set(MaterialKey::METALLIC_VAL_BIT); _mask.set(MaterialKey::METALLIC_VAL_BIT); return (*this); }
|
||||
|
@ -166,11 +173,11 @@ public:
|
|||
Builder& withoutMetallicMap() { _value.reset(MaterialKey::METALLIC_MAP_BIT); _mask.set(MaterialKey::METALLIC_MAP_BIT); return (*this); }
|
||||
Builder& withMetallicMap() { _value.set(MaterialKey::METALLIC_MAP_BIT); _mask.set(MaterialKey::METALLIC_MAP_BIT); return (*this); }
|
||||
|
||||
Builder& withoutGloss() { _value.reset(MaterialKey::GLOSS_VAL_BIT); _mask.set(MaterialKey::GLOSS_VAL_BIT); return (*this); }
|
||||
Builder& withGloss() { _value.set(MaterialKey::GLOSS_VAL_BIT); _mask.set(MaterialKey::GLOSS_VAL_BIT); return (*this); }
|
||||
Builder& withoutGlossy() { _value.reset(MaterialKey::GLOSSY_VAL_BIT); _mask.set(MaterialKey::GLOSSY_VAL_BIT); return (*this); }
|
||||
Builder& withGlossy() { _value.set(MaterialKey::GLOSSY_VAL_BIT); _mask.set(MaterialKey::GLOSSY_VAL_BIT); return (*this); }
|
||||
|
||||
Builder& withoutGlossMap() { _value.reset(MaterialKey::GLOSS_MAP_BIT); _mask.set(MaterialKey::GLOSS_MAP_BIT); return (*this); }
|
||||
Builder& withGlossMap() { _value.set(MaterialKey::GLOSS_MAP_BIT); _mask.set(MaterialKey::GLOSS_MAP_BIT); return (*this); }
|
||||
Builder& withoutRoughnessMap() { _value.reset(MaterialKey::ROUGHNESS_MAP_BIT); _mask.set(MaterialKey::ROUGHNESS_MAP_BIT); return (*this); }
|
||||
Builder& withRoughnessMap() { _value.set(MaterialKey::ROUGHNESS_MAP_BIT); _mask.set(MaterialKey::ROUGHNESS_MAP_BIT); return (*this); }
|
||||
|
||||
Builder& withoutTransparent() { _value.reset(MaterialKey::TRANSPARENT_VAL_BIT); _mask.set(MaterialKey::TRANSPARENT_VAL_BIT); return (*this); }
|
||||
Builder& withTransparent() { _value.set(MaterialKey::TRANSPARENT_VAL_BIT); _mask.set(MaterialKey::TRANSPARENT_VAL_BIT); return (*this); }
|
||||
|
@ -181,11 +188,14 @@ public:
|
|||
Builder& withoutNormalMap() { _value.reset(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); }
|
||||
Builder& withNormalMap() { _value.set(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); }
|
||||
|
||||
Builder& withoutOcclusionMap() { _value.reset(MaterialKey::OCCLUSION_MAP_BIT); _mask.set(MaterialKey::OCCLUSION_MAP_BIT); return (*this); }
|
||||
Builder& withOcclusionMap() { _value.set(MaterialKey::OCCLUSION_MAP_BIT); _mask.set(MaterialKey::OCCLUSION_MAP_BIT); return (*this); }
|
||||
|
||||
Builder& withoutLightmapMap() { _value.reset(MaterialKey::LIGHTMAP_MAP_BIT); _mask.set(MaterialKey::LIGHTMAP_MAP_BIT); return (*this); }
|
||||
Builder& withLightmapMap() { _value.set(MaterialKey::LIGHTMAP_MAP_BIT); _mask.set(MaterialKey::LIGHTMAP_MAP_BIT); return (*this); }
|
||||
|
||||
// Convenient standard keys that we will keep on using all over the place
|
||||
static MaterialFilter opaqueDiffuse() { return Builder().withDiffuse().withoutTransparent().build(); }
|
||||
static MaterialFilter opaqueAlbedo() { return Builder().withAlbedo().withoutTransparent().build(); }
|
||||
};
|
||||
|
||||
// Item Filter operator testing if a key pass the filter
|
||||
|
@ -223,29 +233,39 @@ public:
|
|||
void setEmissive(const Color& emissive, bool isSRGB = true);
|
||||
Color getEmissive(bool SRGB = true) const { return (SRGB ? ColorUtils::toGamma22Vec3(_schemaBuffer.get<Schema>()._emissive) : _schemaBuffer.get<Schema>()._emissive); }
|
||||
|
||||
void setDiffuse(const Color& diffuse, bool isSRGB = true);
|
||||
Color getDiffuse(bool SRGB = true) const { return (SRGB ? ColorUtils::toGamma22Vec3(_schemaBuffer.get<Schema>()._diffuse) : _schemaBuffer.get<Schema>()._diffuse); }
|
||||
|
||||
void setMetallic(float metallic);
|
||||
float getMetallic() const { return _schemaBuffer.get<Schema>()._metallic.x; }
|
||||
|
||||
void setGloss(float gloss);
|
||||
float getGloss() const { return _schemaBuffer.get<Schema>()._gloss; }
|
||||
|
||||
void setOpacity(float opacity);
|
||||
float getOpacity() const { return _schemaBuffer.get<Schema>()._opacity; }
|
||||
|
||||
void setAlbedo(const Color& albedo, bool isSRGB = true);
|
||||
Color getAlbedo(bool SRGB = true) const { return (SRGB ? ColorUtils::toGamma22Vec3(_schemaBuffer.get<Schema>()._albedo) : _schemaBuffer.get<Schema>()._albedo); }
|
||||
|
||||
void setFresnel(const Color& fresnel, bool isSRGB = true);
|
||||
Color getFresnel(bool SRGB = true) const { return (SRGB ? ColorUtils::toGamma22Vec3(_schemaBuffer.get<Schema>()._fresnel) : _schemaBuffer.get<Schema>()._fresnel); }
|
||||
|
||||
void setMetallic(float metallic);
|
||||
float getMetallic() const { return _schemaBuffer.get<Schema>()._metallic; }
|
||||
|
||||
void setRoughness(float roughness);
|
||||
float getRoughness() const { return _schemaBuffer.get<Schema>()._roughness; }
|
||||
|
||||
// Schema to access the attribute values of the material
|
||||
class Schema {
|
||||
public:
|
||||
|
||||
glm::vec3 _diffuse{ 0.5f };
|
||||
float _opacity{1.f};
|
||||
glm::vec3 _metallic{ 0.03f };
|
||||
float _gloss{0.1f};
|
||||
glm::vec3 _emissive{ 0.0f };
|
||||
float _spare0{0.0f};
|
||||
glm::vec4 _spareVec4{0.0f}; // for alignment beauty, Material size == Mat4x4
|
||||
glm::vec3 _emissive{ 0.0f }; // No Emissive
|
||||
float _opacity{ 1.0f }; // Opacity = 1 => Not Transparent
|
||||
|
||||
glm::vec3 _albedo{ 0.5f }; // Grey albedo => isAlbedo
|
||||
float _roughness{ 1.0f }; // Roughness = 1 => Not Glossy
|
||||
|
||||
glm::vec3 _fresnel{ 0.03f }; // Fresnel value for a default non metallic
|
||||
float _metallic{ 0.0f }; // Not Metallic
|
||||
|
||||
|
||||
glm::vec3 _spare0{ 0.0f };
|
||||
|
||||
uint32_t _key{ 0 }; // a copy of the materialKey
|
||||
|
||||
// for alignment beauty, Material size == Mat4x4
|
||||
|
||||
Schema() {}
|
||||
};
|
||||
|
@ -256,6 +276,9 @@ public:
|
|||
void setTextureMap(MapChannel channel, const TextureMapPointer& textureMap);
|
||||
const TextureMaps& getTextureMaps() const { return _textureMaps; }
|
||||
|
||||
// conversion from legacy material properties to PBR equivalent
|
||||
static float shininessToRoughness(float shininess) { return 1.0f - shininess / 100.0f; }
|
||||
|
||||
protected:
|
||||
|
||||
MaterialKey _key;
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
<@def MODEL_MATERIAL_SLH@>
|
||||
|
||||
struct Material {
|
||||
vec4 _diffuse;
|
||||
vec4 _specular;
|
||||
vec4 _emissive;
|
||||
vec4 _emissiveOpacity;
|
||||
vec4 _albedoRoughness;
|
||||
vec4 _fresnelMetallic;
|
||||
vec4 _spare;
|
||||
};
|
||||
|
||||
|
@ -26,41 +26,36 @@ Material getMaterial() {
|
|||
return _mat;
|
||||
}
|
||||
|
||||
<! // TODO: use this code for correct gamma correction
|
||||
/*
|
||||
float componentSRGBToLinear(float cs) {
|
||||
// sRGB to linear conversion
|
||||
// { cs / 12.92, cs <= 0.04045
|
||||
// cl = {
|
||||
// { ((cs + 0.055)/1.055)^2.4, cs > 0.04045
|
||||
// constants:
|
||||
// T = 0.04045
|
||||
// A = 1 / 1.055 = 0.94786729857
|
||||
// B = 0.055 * A = 0.05213270142
|
||||
// C = 1 / 12.92 = 0.0773993808
|
||||
// G = 2.4
|
||||
const float T = 0.04045;
|
||||
const float A = 0.947867;
|
||||
const float B = 0.052132;
|
||||
const float C = 0.077399;
|
||||
const float G = 2.4;
|
||||
vec3 getMaterialEmissive(Material m) { return m._emissiveOpacity.rgb; }
|
||||
float getMaterialOpacity(Material m) { return m._emissiveOpacity.a; }
|
||||
|
||||
if (cs > T) {
|
||||
return pow((cs * A + B), G);
|
||||
} else {
|
||||
return cs * C;
|
||||
}
|
||||
}
|
||||
vec3 getMaterialAlbedo(Material m) { return m._albedoRoughness.rgb; }
|
||||
float getMaterialRoughness(Material m) { return m._albedoRoughness.a; }
|
||||
|
||||
vec3 getMaterialFresnel(Material m) { return m._fresnelMetallic.rgb; }
|
||||
float getMaterialMetallic(Material m) { return m._fresnelMetallic.a; }
|
||||
|
||||
float getMaterialShininess(Material m) { return 1.0 - getMaterialRoughness(m); }
|
||||
|
||||
int getMaterialKey(Material m) { return floatBitsToInt(m._spare.w); }
|
||||
|
||||
const int EMISSIVE_VAL_BIT = 0x00000001;
|
||||
const int ALBEDO_VAL_BIT = 0x00000002;
|
||||
const int METALLIC_VAL_BIT = 0x00000004;
|
||||
const int GLOSSY_VAL_BIT = 0x00000008;
|
||||
const int TRANSPARENT_VAL_BIT = 0x00000010;
|
||||
|
||||
|
||||
const int EMISSIVE_MAP_BIT = 0x00000020;
|
||||
const int ALBEDO_MAP_BIT = 0x00000040;
|
||||
const int METALLIC_MAP_BIT = 0x00000080;
|
||||
const int ROUGHNESS_MAP_BIT = 0x00000100;
|
||||
const int TRANSPARENT_MAP_BIT = 0x00000200;
|
||||
const int NORMAL_MAP_BIT = 0x00000400;
|
||||
const int OCCLUSION_MAP_BIT = 0x00000800;
|
||||
|
||||
const int LIGHTMAP_MAP_BIT = 0x00001000;
|
||||
|
||||
vec3 SRGBToLinear(vec3 srgb) {
|
||||
return vec3(componentSRGBToLinear(srgb.x),componentSRGBToLinear(srgb.y),componentSRGBToLinear(srgb.z));
|
||||
}
|
||||
vec3 getMaterialDiffuse(Material m) { return (gl_FragCoord.x < 800 ? SRGBToLinear(m._diffuse.rgb) : m._diffuse.rgb); }
|
||||
*/!>
|
||||
|
||||
float getMaterialOpacity(Material m) { return m._diffuse.a; }
|
||||
vec3 getMaterialDiffuse(Material m) { return m._diffuse.rgb; }
|
||||
vec3 getMaterialSpecular(Material m) { return m._specular.rgb; }
|
||||
float getMaterialShininess(Material m) { return m._specular.a; }
|
||||
|
||||
<@endif@>
|
||||
|
|
|
@ -212,6 +212,9 @@ void SunSkyStage::setSunAmbientSphere(const gpu::SHPointer& sphere) {
|
|||
_sunLight->setAmbientSpherePreset(DEFAULT_AMBIENT_SPHERE);
|
||||
}
|
||||
}
|
||||
void SunSkyStage::setSunAmbientMap(const gpu::TexturePointer& map) {
|
||||
_sunLight->setAmbientMap(map);
|
||||
}
|
||||
|
||||
void SunSkyStage::setSunDirection(const Vec3& direction) {
|
||||
if (!isSunModelEnabled()) {
|
||||
|
|
|
@ -150,6 +150,7 @@ public:
|
|||
void setSunAmbientIntensity(float intensity) { _sunLight->setAmbientIntensity(intensity); }
|
||||
float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); }
|
||||
void setSunAmbientSphere(const gpu::SHPointer& sphere);
|
||||
void setSunAmbientMap(const gpu::TexturePointer& map);
|
||||
|
||||
// The sun direction is expressed in the world space
|
||||
void setSunDirection(const Vec3& direction);
|
||||
|
|
|
@ -54,22 +54,38 @@ void TextureMap::setLightmapOffsetScale(float offset, float scale) {
|
|||
gpu::Texture* TextureUsage::create2DTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||
QImage image = srcImage;
|
||||
bool validAlpha = false;
|
||||
bool alphaAsMask = true;
|
||||
const uint8 OPAQUE_ALPHA = 255;
|
||||
const uint8 TRANSLUCENT_ALPHA = 0;
|
||||
if (image.hasAlphaChannel()) {
|
||||
std::map<uint8, uint32> alphaHistogram;
|
||||
|
||||
if (image.format() != QImage::Format_ARGB32) {
|
||||
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||
}
|
||||
|
||||
// Actual alpha channel?
|
||||
// Actual alpha channel? create the histogram
|
||||
for (int y = 0; y < image.height(); ++y) {
|
||||
const QRgb* data = reinterpret_cast<const QRgb*>(image.constScanLine(y));
|
||||
for (int x = 0; x < image.width(); ++x) {
|
||||
auto alpha = qAlpha(data[x]);
|
||||
if (alpha != 255) {
|
||||
alphaHistogram[alpha] ++;
|
||||
if (alpha != OPAQUE_ALPHA) {
|
||||
validAlpha = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If alpha was meaningfull refine
|
||||
if (validAlpha && (alphaHistogram.size() > 1)) {
|
||||
auto totalNumPixels = image.height() * image.width();
|
||||
auto numOpaques = alphaHistogram[OPAQUE_ALPHA];
|
||||
auto numTranslucents = alphaHistogram[TRANSLUCENT_ALPHA];
|
||||
auto numTransparents = totalNumPixels - numOpaques - numTranslucents;
|
||||
|
||||
alphaAsMask = ((numTransparents / (double)totalNumPixels) < 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
if (!validAlpha && image.format() != QImage::Format_RGB888) {
|
||||
|
@ -89,10 +105,21 @@ gpu::Texture* TextureUsage::create2DTextureFromImage(const QImage& srcImage, con
|
|||
}
|
||||
|
||||
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
||||
|
||||
auto usage = gpu::Texture::Usage::Builder().withColor();
|
||||
if (validAlpha) {
|
||||
usage.withAlpha();
|
||||
if (alphaAsMask) {
|
||||
usage.withAlphaMask();
|
||||
}
|
||||
}
|
||||
theTexture->setUsage(usage.build());
|
||||
|
||||
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||
theTexture->autoGenerateMips(-1);
|
||||
|
||||
// FIXME queue for transfer to GPU and block on completion
|
||||
|
||||
}
|
||||
|
||||
return theTexture;
|
||||
|
@ -223,6 +250,99 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm
|
|||
return theTexture;
|
||||
}
|
||||
|
||||
gpu::Texture* TextureUsage::createRoughnessTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||
QImage image = srcImage;
|
||||
if (!image.hasAlphaChannel()) {
|
||||
if (image.format() != QImage::Format_RGB888) {
|
||||
image = image.convertToFormat(QImage::Format_RGB888);
|
||||
}
|
||||
} else {
|
||||
if (image.format() != QImage::Format_ARGB32) {
|
||||
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||
}
|
||||
}
|
||||
|
||||
image = image.convertToFormat(QImage::Format_Grayscale8);
|
||||
|
||||
gpu::Texture* theTexture = nullptr;
|
||||
if ((image.width() > 0) && (image.height() > 0)) {
|
||||
|
||||
gpu::Element formatGPU = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB);
|
||||
gpu::Element formatMip = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB);
|
||||
|
||||
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
||||
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||
theTexture->autoGenerateMips(-1);
|
||||
|
||||
// FIXME queue for transfer to GPU and block on completion
|
||||
}
|
||||
|
||||
return theTexture;
|
||||
}
|
||||
|
||||
gpu::Texture* TextureUsage::createRoughnessTextureFromGlossImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||
QImage image = srcImage;
|
||||
if (!image.hasAlphaChannel()) {
|
||||
if (image.format() != QImage::Format_RGB888) {
|
||||
image = image.convertToFormat(QImage::Format_RGB888);
|
||||
}
|
||||
} else {
|
||||
if (image.format() != QImage::Format_ARGB32) {
|
||||
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||
}
|
||||
}
|
||||
|
||||
// Gloss turned into Rough
|
||||
image.invertPixels(QImage::InvertRgba);
|
||||
|
||||
image = image.convertToFormat(QImage::Format_Grayscale8);
|
||||
|
||||
gpu::Texture* theTexture = nullptr;
|
||||
if ((image.width() > 0) && (image.height() > 0)) {
|
||||
|
||||
gpu::Element formatGPU = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB);
|
||||
gpu::Element formatMip = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB);
|
||||
|
||||
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
||||
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||
theTexture->autoGenerateMips(-1);
|
||||
|
||||
// FIXME queue for transfer to GPU and block on completion
|
||||
}
|
||||
|
||||
return theTexture;
|
||||
}
|
||||
|
||||
gpu::Texture* TextureUsage::createMetallicTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||
QImage image = srcImage;
|
||||
if (!image.hasAlphaChannel()) {
|
||||
if (image.format() != QImage::Format_RGB888) {
|
||||
image = image.convertToFormat(QImage::Format_RGB888);
|
||||
}
|
||||
} else {
|
||||
if (image.format() != QImage::Format_ARGB32) {
|
||||
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||
}
|
||||
}
|
||||
|
||||
image = image.convertToFormat(QImage::Format_Grayscale8);
|
||||
|
||||
gpu::Texture* theTexture = nullptr;
|
||||
if ((image.width() > 0) && (image.height() > 0)) {
|
||||
|
||||
gpu::Element formatGPU = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB);
|
||||
gpu::Element formatMip = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB);
|
||||
|
||||
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
||||
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||
theTexture->autoGenerateMips(-1);
|
||||
|
||||
// FIXME queue for transfer to GPU and block on completion
|
||||
}
|
||||
|
||||
return theTexture;
|
||||
}
|
||||
|
||||
class CubeLayout {
|
||||
public:
|
||||
int _widthRatio = 1;
|
||||
|
@ -473,8 +593,8 @@ gpu::Texture* TextureUsage::createCubeTextureFromImage(const QImage& srcImage, c
|
|||
theTexture->assignStoredMipFace(0, formatMip, face.byteCount(), face.constBits(), f);
|
||||
f++;
|
||||
}
|
||||
|
||||
// GEnerate irradiance while we are at it
|
||||
|
||||
// Generate irradiance while we are at it
|
||||
theTexture->generateIrradiance();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,16 @@ typedef glm::vec3 Color;
|
|||
class TextureUsage {
|
||||
public:
|
||||
gpu::Texture::Type _type{ gpu::Texture::TEX_2D };
|
||||
Material::MapFlags _materialUsage{ MaterialKey::DIFFUSE_MAP };
|
||||
Material::MapFlags _materialUsage{ MaterialKey::ALBEDO_MAP };
|
||||
|
||||
int _environmentUsage = 0;
|
||||
|
||||
static gpu::Texture* create2DTextureFromImage(const QImage& image, const std::string& srcImageName);
|
||||
static gpu::Texture* createNormalTextureFromNormalImage(const QImage& image, const std::string& srcImageName);
|
||||
static gpu::Texture* createNormalTextureFromBumpImage(const QImage& image, const std::string& srcImageName);
|
||||
static gpu::Texture* createRoughnessTextureFromImage(const QImage& image, const std::string& srcImageName);
|
||||
static gpu::Texture* createRoughnessTextureFromGlossImage(const QImage& image, const std::string& srcImageName);
|
||||
static gpu::Texture* createMetallicTextureFromImage(const QImage& image, const std::string& srcImageName);
|
||||
static gpu::Texture* createCubeTextureFromImage(const QImage& image, const std::string& srcImageName);
|
||||
static gpu::Texture* createLightmapTextureFromImage(const QImage& image, const std::string& srcImageName);
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "GeometryCache.h"
|
||||
#include "FramebufferCache.h"
|
||||
#include "TextureCache.h"
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
#include "debug_deferred_buffer_vert.h"
|
||||
|
@ -39,7 +40,7 @@ void DebugDeferredBufferConfig::setMode(int newMode) {
|
|||
}
|
||||
|
||||
enum Slot {
|
||||
Diffuse = 0,
|
||||
Albedo = 0,
|
||||
Normal,
|
||||
Specular,
|
||||
Depth,
|
||||
|
@ -52,27 +53,54 @@ enum Slot {
|
|||
|
||||
|
||||
|
||||
static const std::string DEFAULT_DIFFUSE_SHADER {
|
||||
static const std::string DEFAULT_ALBEDO_SHADER {
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(pow(texture(diffuseMap, uv).xyz, vec3(1.0 / 2.2)), 1.0);"
|
||||
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
||||
" return vec4(pow(frag.diffuse, vec3(1.0 / 2.2)), 1.0);"
|
||||
" }"
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_SPECULAR_SHADER {
|
||||
static const std::string DEFAULT_METALLIC_SHADER {
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(texture(specularMap, uv).xyz, 1.0);"
|
||||
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
||||
" return vec4(vec3(pow(frag.metallic, 1.0 / 2.2)), 1.0);"
|
||||
" }"
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_ROUGHNESS_SHADER {
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(vec3(texture(specularMap, uv).a), 1.0);"
|
||||
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
||||
" return vec4(vec3(pow(frag.roughness, 1.0 / 2.2)), 1.0);"
|
||||
" }"
|
||||
};
|
||||
static const std::string DEFAULT_NORMAL_SHADER {
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(normalize(texture(normalMap, uv).xyz * 2.0 - vec3(1.0)), 1.0);"
|
||||
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
||||
" return vec4(vec3(0.5) + (frag.normal * 0.5), 1.0);"
|
||||
" }"
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_OCCLUSION_SHADER{
|
||||
"vec4 getFragmentColor() {"
|
||||
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
||||
" return vec4(vec3(frag.obscurance), 1.0);"
|
||||
" }"
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_EMISSIVE_SHADER{
|
||||
"vec4 getFragmentColor() {"
|
||||
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
||||
" return (frag.mode != LIGHT_MAPPED ? vec4(pow(frag.emissive, vec3(1.0 / 2.2)), 1.0) : vec4(vec3(0.0), 1.0));"
|
||||
" }"
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_LIGHTMAP_SHADER{
|
||||
"vec4 getFragmentColor() {"
|
||||
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
||||
" return (frag.mode == LIGHT_MAPPED ? vec4(frag.emissive, 1.0) : vec4(vec3(0.0), 1.0));"
|
||||
" }"
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_DEPTH_SHADER {
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(vec3(texture(depthMap, uv).x), 1.0);"
|
||||
|
@ -105,7 +133,7 @@ static const std::string DEFAULT_PYRAMID_DEPTH_SHADER {
|
|||
|
||||
static const std::string DEFAULT_AMBIENT_OCCLUSION_SHADER{
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(vec3(texture(occlusionMap, uv).x), 1.0);"
|
||||
" return vec4(vec3(texture(obscuranceMap, uv).x), 1.0);"
|
||||
// When drawing color " return vec4(vec3(texture(occlusionMap, uv).xyz), 1.0);"
|
||||
// when drawing normal " return vec4(normalize(texture(occlusionMap, uv).xyz * 2.0 - vec3(1.0)), 1.0);"
|
||||
" }"
|
||||
|
@ -144,16 +172,22 @@ DebugDeferredBuffer::DebugDeferredBuffer() {
|
|||
|
||||
std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string customFile) {
|
||||
switch (mode) {
|
||||
case DiffuseMode:
|
||||
return DEFAULT_DIFFUSE_SHADER;
|
||||
case SpecularMode:
|
||||
return DEFAULT_SPECULAR_SHADER;
|
||||
case AlbedoMode:
|
||||
return DEFAULT_ALBEDO_SHADER;
|
||||
case MetallicMode:
|
||||
return DEFAULT_METALLIC_SHADER;
|
||||
case RoughnessMode:
|
||||
return DEFAULT_ROUGHNESS_SHADER;
|
||||
case NormalMode:
|
||||
return DEFAULT_NORMAL_SHADER;
|
||||
case DepthMode:
|
||||
return DEFAULT_DEPTH_SHADER;
|
||||
case EmissiveMode:
|
||||
return DEFAULT_EMISSIVE_SHADER;
|
||||
case OcclusionMode:
|
||||
return DEFAULT_OCCLUSION_SHADER;
|
||||
case LightmapMode:
|
||||
return DEFAULT_LIGHTMAP_SHADER;
|
||||
case LightingMode:
|
||||
return DEFAULT_LIGHTING_SHADER;
|
||||
case ShadowMode:
|
||||
|
@ -206,14 +240,14 @@ const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::str
|
|||
const auto program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding("diffuseMap", Diffuse));
|
||||
slotBindings.insert(gpu::Shader::Binding("albedoMap", Albedo));
|
||||
slotBindings.insert(gpu::Shader::Binding("normalMap", Normal));
|
||||
slotBindings.insert(gpu::Shader::Binding("specularMap", Specular));
|
||||
slotBindings.insert(gpu::Shader::Binding("depthMap", Depth));
|
||||
slotBindings.insert(gpu::Shader::Binding("obscuranceMap", AmbientOcclusion));
|
||||
slotBindings.insert(gpu::Shader::Binding("lightingMap", Lighting));
|
||||
slotBindings.insert(gpu::Shader::Binding("shadowMap", Shadow));
|
||||
slotBindings.insert(gpu::Shader::Binding("pyramidMap", Pyramid));
|
||||
slotBindings.insert(gpu::Shader::Binding("occlusionMap", AmbientOcclusion));
|
||||
slotBindings.insert(gpu::Shader::Binding("occlusionBlurredMap", AmbientOcclusionBlurred));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
|
@ -247,6 +281,7 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
|
|||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
const auto geometryBuffer = DependencyManager::get<GeometryCache>();
|
||||
const auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||
const auto textureCache = DependencyManager::get<TextureCache>();
|
||||
const auto& lightStage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||
|
||||
glm::mat4 projMat;
|
||||
|
@ -262,14 +297,19 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
|
|||
|
||||
batch.setPipeline(getPipeline(_mode, first));
|
||||
|
||||
batch.setResourceTexture(Diffuse, framebufferCache->getDeferredColorTexture());
|
||||
batch.setResourceTexture(Albedo, framebufferCache->getDeferredColorTexture());
|
||||
batch.setResourceTexture(Normal, framebufferCache->getDeferredNormalTexture());
|
||||
batch.setResourceTexture(Specular, framebufferCache->getDeferredSpecularTexture());
|
||||
batch.setResourceTexture(Depth, framebufferCache->getPrimaryDepthTexture());
|
||||
batch.setResourceTexture(Lighting, framebufferCache->getLightingTexture());
|
||||
batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getDepthStencilBuffer());
|
||||
batch.setResourceTexture(Pyramid, framebufferCache->getDepthPyramidTexture());
|
||||
batch.setResourceTexture(AmbientOcclusion, framebufferCache->getOcclusionTexture());
|
||||
if (DependencyManager::get<DeferredLightingEffect>()->isAmbientOcclusionEnabled()) {
|
||||
batch.setResourceTexture(AmbientOcclusion, framebufferCache->getOcclusionTexture());
|
||||
} else {
|
||||
// need to assign the white texture if ao is off
|
||||
batch.setResourceTexture(AmbientOcclusion, textureCache->getWhiteTexture());
|
||||
}
|
||||
batch.setResourceTexture(AmbientOcclusionBlurred, framebufferCache->getOcclusionBlurredTexture());
|
||||
|
||||
const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
|
|
@ -47,11 +47,14 @@ protected:
|
|||
|
||||
enum Mode : uint8_t {
|
||||
// Use Mode suffix to avoid collisions
|
||||
DiffuseMode = 0,
|
||||
SpecularMode,
|
||||
RoughnessMode,
|
||||
DepthMode = 0,
|
||||
AlbedoMode,
|
||||
NormalMode,
|
||||
DepthMode,
|
||||
RoughnessMode,
|
||||
MetallicMode,
|
||||
EmissiveMode,
|
||||
OcclusionMode,
|
||||
LightmapMode,
|
||||
LightingMode,
|
||||
ShadowMode,
|
||||
PyramidDepthMode,
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
<@def DEFERRED_BUFFER_SLH@>
|
||||
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
// the albedo texture
|
||||
uniform sampler2D albedoMap;
|
||||
|
||||
// the normal texture
|
||||
uniform sampler2D normalMap;
|
||||
|
@ -34,8 +34,8 @@ uniform sampler2D lightingMap;
|
|||
struct DeferredTransform {
|
||||
mat4 projection;
|
||||
mat4 viewInverse;
|
||||
|
||||
vec4 stereoSide_spareABC;
|
||||
float stereoSide;
|
||||
vec3 _spareABC;
|
||||
};
|
||||
|
||||
layout(std140) uniform deferredTransformBuffer {
|
||||
|
@ -46,10 +46,10 @@ DeferredTransform getDeferredTransform() {
|
|||
}
|
||||
|
||||
bool getStereoMode(DeferredTransform deferredTransform) {
|
||||
return (deferredTransform.stereoSide_spareABC.x != 0.0);
|
||||
return (deferredTransform.stereoSide != 0.0);
|
||||
}
|
||||
float getStereoSide(DeferredTransform deferredTransform) {
|
||||
return (deferredTransform.stereoSide_spareABC.x);
|
||||
return (deferredTransform.stereoSide);
|
||||
}
|
||||
|
||||
vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) {
|
||||
|
@ -64,52 +64,82 @@ vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, v
|
|||
}
|
||||
|
||||
struct DeferredFragment {
|
||||
float depthVal;
|
||||
vec4 normalVal;
|
||||
vec4 diffuseVal;
|
||||
vec4 specularVal;
|
||||
vec4 position;
|
||||
vec3 normal;
|
||||
float metallic;
|
||||
vec3 diffuse;
|
||||
float obscurance;
|
||||
vec3 specular;
|
||||
float gloss;
|
||||
float roughness;
|
||||
vec3 emissive;
|
||||
int mode;
|
||||
float depthVal;
|
||||
};
|
||||
|
||||
const int LIGHT_MAPPED = 1;
|
||||
|
||||
DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec2 texcoord) {
|
||||
DeferredFragment frag;
|
||||
frag.depthVal = texture(depthMap, texcoord).r;
|
||||
frag.normalVal = texture(normalMap, texcoord);
|
||||
frag.diffuseVal = texture(diffuseMap, texcoord);
|
||||
frag.specularVal = texture(specularMap, texcoord);
|
||||
frag.obscurance = texture(obscuranceMap, texcoord).x;
|
||||
|
||||
vec4 unpackDeferredPosition(DeferredTransform deferredTransform, float depthValue, vec2 texcoord) {
|
||||
if (getStereoMode(deferredTransform)) {
|
||||
if (texcoord.x > 0.5) {
|
||||
texcoord.x -= 0.5;
|
||||
}
|
||||
texcoord.x *= 2.0;
|
||||
}
|
||||
frag.position = evalEyePositionFromZ(deferredTransform, frag.depthVal, texcoord);
|
||||
return evalEyePositionFromZ(deferredTransform, depthValue, texcoord);
|
||||
}
|
||||
|
||||
DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) {
|
||||
|
||||
DeferredFragment frag;
|
||||
frag.depthVal = -1;
|
||||
frag.normalVal = texture(normalMap, texcoord);
|
||||
frag.diffuseVal = texture(albedoMap, texcoord);
|
||||
frag.specularVal = texture(specularMap, texcoord);
|
||||
frag.obscurance = texture(obscuranceMap, texcoord).x;
|
||||
|
||||
// Unpack the normal from the map
|
||||
frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0));
|
||||
|
||||
frag.mode = 0;
|
||||
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
|
||||
frag.emissive = frag.specularVal.xyz;
|
||||
if (frag.normalVal.a < 0.5) {
|
||||
frag.mode = 0;
|
||||
frag.roughness = 2.0 * frag.normalVal.a;
|
||||
} else {
|
||||
frag.mode = LIGHT_MAPPED;
|
||||
frag.roughness = 2.0 * frag.normalVal.a - 1.0;
|
||||
}
|
||||
|
||||
frag.metallic = frag.diffuseVal.a;
|
||||
frag.diffuse = frag.diffuseVal.xyz;
|
||||
frag.specular = frag.specularVal.xyz;
|
||||
frag.gloss = frag.specularVal.w;
|
||||
if (frag.metallic <= 0.5) {
|
||||
frag.metallic = 0.0;
|
||||
frag.specular = vec3(0.03); // Default Di-electric fresnel value
|
||||
} else {
|
||||
frag.specular = vec3(frag.diffuseVal.xyz);
|
||||
frag.metallic = 1.0;
|
||||
}
|
||||
frag.obscurance = min(frag.specularVal.w, frag.obscurance);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec2 texcoord) {
|
||||
|
||||
float depthValue = texture(depthMap, texcoord).r;
|
||||
|
||||
DeferredFragment frag = unpackDeferredFragmentNoPosition(texcoord);
|
||||
|
||||
frag.depthVal = depthValue;
|
||||
frag.position = unpackDeferredPosition(deferredTransform, frag.depthVal, texcoord);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
<@endif@>
|
||||
|
|
|
@ -40,37 +40,41 @@ float evalOpaqueFinalAlpha(float alpha, float mapAlpha) {
|
|||
return mix(alpha, 1.0 - alpha, step(mapAlpha, alphaThreshold));
|
||||
}
|
||||
|
||||
const vec3 DEFAULT_SPECULAR = vec3(0.1);
|
||||
const float DEFAULT_ROUGHNESS = 0.9;
|
||||
const float DEFAULT_SHININESS = 10;
|
||||
const float DEFAULT_METALLIC = 0;
|
||||
const vec3 DEFAULT_SPECULAR = vec3(0.1);
|
||||
const vec3 DEFAULT_EMISSIVE = vec3(0.0);
|
||||
const float DEFAULT_OCCLUSION = 1.0;
|
||||
|
||||
void packDeferredFragment(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) {
|
||||
|
||||
void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 emissive, float occlusion) {
|
||||
if (alpha != 1.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
_fragColor0 = vec4(diffuse.rgb, 1.0); // Opaque
|
||||
_fragColor1 = vec4(bestFitNormal(normal), 1.0);
|
||||
_fragColor2 = vec4(specular, shininess / 128.0);
|
||||
_fragColor0 = vec4(albedo, metallic);
|
||||
_fragColor1 = vec4(bestFitNormal(normal), 0.5 * clamp(roughness, 0.0, 1.0));
|
||||
_fragColor2 = vec4(emissive, occlusion);
|
||||
}
|
||||
|
||||
void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess, vec3 emissive) {
|
||||
|
||||
void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 fresnel, vec3 emissive) {
|
||||
if (alpha != 1.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
_fragColor0 = vec4(diffuse.rgb, 0.5);
|
||||
_fragColor1 = vec4(bestFitNormal(normal), 0.5);
|
||||
_fragColor2 = vec4(emissive, shininess / 128.0);
|
||||
_fragColor0 = vec4(albedo, metallic);
|
||||
_fragColor1 = vec4(bestFitNormal(normal), 0.5 + 0.5 * clamp(roughness, 0.0, 1.0));
|
||||
_fragColor2 = vec4(emissive, 1.0);
|
||||
}
|
||||
|
||||
void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) {
|
||||
void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 albedo, vec3 fresnel, float roughness) {
|
||||
if (alpha <= 0.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
_fragColor0 = vec4(diffuse.rgb, alpha);
|
||||
_fragColor0 = vec4(albedo.rgb, alpha);
|
||||
// _fragColor1 = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
// _fragColor2 = vec4(specular, shininess / 128.0);
|
||||
// _fragColor2 = vec4(fresnel, roughness);
|
||||
}
|
||||
|
||||
<@endif@>
|
||||
|
|
|
@ -11,109 +11,116 @@
|
|||
<@if not DEFERRED_GLOBAL_LIGHT_SLH@>
|
||||
<@def DEFERRED_GLOBAL_LIGHT_SLH@>
|
||||
|
||||
<@include model/Light.slh@>
|
||||
<@include DeferredLighting.slh@>
|
||||
|
||||
<@func declareSkyboxMap()@>
|
||||
|
||||
// declareSkyboxMap
|
||||
uniform samplerCube skyboxMap;
|
||||
|
||||
vec4 evalSkyboxLight(vec3 direction, float lod) {
|
||||
// FIXME
|
||||
//vec4 skytexel = textureLod(skyboxMap, direction, lod * textureQueryLevels(skyboxMap));
|
||||
vec4 skytexel = texture(skyboxMap, direction);
|
||||
return skytexel;
|
||||
// textureQueryLevels is not available until #430, so we require explicit lod
|
||||
// float mipmapLevel = lod * textureQueryLevels(skyboxMap);
|
||||
return textureLod(skyboxMap, direction, lod);
|
||||
}
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
// Everything about light
|
||||
<@include model/Light.slh@>
|
||||
<@func prepareGlobalLight()@>
|
||||
// prepareGlobalLight
|
||||
|
||||
// Transform directions to worldspace
|
||||
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
|
||||
vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0));
|
||||
vec3 fragEyeDir = normalize(fragEyeVector);
|
||||
|
||||
// Get light
|
||||
Light light = getLight();
|
||||
vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value
|
||||
if (metallic > 0.5) {
|
||||
fresnel = albedo;
|
||||
metallic = 1.0;
|
||||
}
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, fresnel, roughness);
|
||||
vec3 color = vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
|
||||
color += emissive;
|
||||
<@endfunc@>
|
||||
|
||||
<@func declareAmbientFresnel()@>
|
||||
vec3 fresnelSchlickAmbient(vec3 fresnelColor, vec3 lightDir, vec3 halfDir, float gloss) {
|
||||
return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * pow(1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5);
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func declareEvalAmbientGlobalColor()@>
|
||||
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
||||
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
|
||||
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
|
||||
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
|
||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||
|
||||
vec3 color = diffuse.rgb * getLightColor(light) * obscurance * getLightAmbientIntensity(light);
|
||||
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||
|
||||
color += vec3(diffuse * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
|
||||
|
||||
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
|
||||
<$prepareGlobalLight()$>
|
||||
color += albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(light);
|
||||
return color;
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func declareEvalAmbientSphereGlobalColor()@>
|
||||
<$declareAmbientFresnel()$>
|
||||
|
||||
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
|
||||
vec3 fragNormal = normalize(vec3(invViewMat * vec4(normal, 0.0)));
|
||||
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
|
||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||
|
||||
vec3 ambientNormal = fragNormal.xyz;
|
||||
vec3 color = diffuse.rgb * evalSphericalLight(getLightAmbientSphere(light), ambientNormal).xyz * obscurance * getLightAmbientIntensity(light);
|
||||
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
|
||||
<$prepareGlobalLight()$>
|
||||
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||
// Diffuse from ambient
|
||||
color += (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
|
||||
|
||||
color += vec3(diffuse * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
|
||||
// Specular highlight from ambient
|
||||
vec3 direction = -reflect(fragEyeDir, fragNormal);
|
||||
vec3 skyboxLight = evalSphericalLight(getLightAmbientSphere(light), direction).xyz;
|
||||
vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness);
|
||||
color += ambientFresnel * skyboxLight.rgb * obscurance * getLightAmbientIntensity(light);
|
||||
|
||||
return color;
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func declareEvalSkyboxGlobalColor()@>
|
||||
|
||||
<$declareSkyboxMap()$>
|
||||
<$declareAmbientFresnel()$>
|
||||
|
||||
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
|
||||
vec3 fragNormal = normalize(vec3(invViewMat * vec4(normal, 0.0)));
|
||||
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
|
||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||
|
||||
vec3 color = diffuse.rgb * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
|
||||
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
|
||||
<$prepareGlobalLight()$>
|
||||
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||
// Diffuse from ambient
|
||||
color += (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
|
||||
|
||||
color += vec3(diffuse * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
|
||||
// Specular highlight from ambient
|
||||
vec3 direction = -reflect(fragEyeDir, fragNormal);
|
||||
float levels = getLightAmbientMapNumMips(light);
|
||||
float lod = min(floor((roughness) * levels), levels);
|
||||
vec4 skyboxLight = evalSkyboxLight(direction, lod);
|
||||
vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness);
|
||||
color += ambientFresnel * skyboxLight.rgb * obscurance * getLightAmbientIntensity(light);
|
||||
|
||||
return color;
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func declareEvalLightmappedColor()@>
|
||||
vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 diffuse, vec3 lightmap) {
|
||||
|
||||
vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 albedo, vec3 lightmap) {
|
||||
Light light = getLight();
|
||||
|
||||
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
|
||||
float diffuseDot = dot(fragNormal, -getLightDirection(light));
|
||||
|
||||
// need to catch normals perpendicular to the projection plane hence the magic number for the threshold
|
||||
// it should be just 0, but we have innacurracy so we need to overshoot
|
||||
// Catch normals perpendicular to the projection plane, hence the magic number for the threshold
|
||||
// It should be just 0, but we have inaccuracy so we overshoot
|
||||
const float PERPENDICULAR_THRESHOLD = -0.005;
|
||||
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); // transform to worldspace
|
||||
float diffuseDot = dot(fragNormal, -getLightDirection(light));
|
||||
float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot);
|
||||
//float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot);
|
||||
// evaluate the shadow test but only relevant for light facing fragments
|
||||
|
||||
// Reevaluate the shadow attenuation for light facing fragments
|
||||
float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation;
|
||||
// diffuse light is the lightmap dimmed by shadow
|
||||
|
||||
// Diffuse light is the lightmap dimmed by shadow
|
||||
vec3 diffuseLight = lightAttenuation * lightmap;
|
||||
|
||||
// ambient is a tiny percentage of the lightmap and only when in the shadow
|
||||
// Ambient light is the lightmap when in shadow
|
||||
vec3 ambientLight = (1 - lightAttenuation) * lightmap * getLightAmbientIntensity(light);
|
||||
|
||||
return obscurance * diffuse * (ambientLight + diffuseLight);
|
||||
return obscurance * albedo * (diffuseLight + ambientLight);
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
|
|
|
@ -13,41 +13,55 @@
|
|||
|
||||
|
||||
<@func declareEvalPBRShading()@>
|
||||
|
||||
vec3 fresnelSchlick(vec3 fresnelColor, vec3 lightDir, vec3 halfDir) {
|
||||
return fresnelColor + (1.0 - fresnelColor) * pow(1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5);
|
||||
}
|
||||
|
||||
float specularDistribution(float roughness, vec3 normal, vec3 halfDir) {
|
||||
float ndoth = clamp(dot(halfDir, normal), 0.0, 1.0);
|
||||
float gloss2 = pow(0.001 + roughness, 4);
|
||||
float denom = (ndoth * ndoth*(gloss2 - 1) + 1);
|
||||
float power = gloss2 / (3.14159 * denom * denom);
|
||||
return power;
|
||||
}
|
||||
<! //NOTE: ANother implementation for specularDistribution
|
||||
float specularDistribution(float roughness, vec3 normal, vec3 halfDir) {
|
||||
float gloss = exp2(10 * (1.0 - roughness) + 1);
|
||||
float power = pow(clamp(dot(halfDir, normal), 0.0, 1.0), gloss);
|
||||
power *= (gloss * 0.125 + 0.25);
|
||||
return power;
|
||||
}
|
||||
!>
|
||||
// Frag Shading returns the diffuse amount as W and the specular rgb as xyz
|
||||
vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) {
|
||||
vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 fresnel, float roughness) {
|
||||
// Diffuse Lighting
|
||||
float diffuseDot = dot(fragNormal, fragLightDir);
|
||||
float facingLight = step(0.0, diffuseDot);
|
||||
float diffuse = diffuseDot * facingLight;
|
||||
|
||||
// Specular Lighting depends on the half vector and the gloss
|
||||
float diffuse = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0);
|
||||
|
||||
// Specular Lighting
|
||||
vec3 halfDir = normalize(fragEyeDir + fragLightDir);
|
||||
vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir,halfDir);
|
||||
float power = specularDistribution(roughness, fragNormal, halfDir);
|
||||
vec3 specular = power * fresnelColor * diffuse;
|
||||
|
||||
float specularPower = pow(max(0.0, dot(halfDir, fragNormal)), gloss * 128.0);
|
||||
specularPower *= (gloss * 128.0 * 0.125 + 0.25);
|
||||
|
||||
float shlickPower = (1.0 - dot(fragLightDir,halfDir));
|
||||
float shlickPower2 = shlickPower * shlickPower;
|
||||
float shlickPower5 = shlickPower2 * shlickPower2 * shlickPower;
|
||||
vec3 fresnel = specular * (1.0 - shlickPower5) + vec3(shlickPower5);
|
||||
vec3 reflect = specularPower * fresnel * diffuse;
|
||||
|
||||
return vec4(reflect, diffuse * (1 - fresnel.x));
|
||||
return vec4(specular, (1.0 - metallic) * diffuse * (1 - fresnelColor.x));
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func declareEvalBlinnRShading()@>
|
||||
|
||||
vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) {
|
||||
vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float roughness) {
|
||||
// Diffuse Lighting
|
||||
float diffuseDot = dot(fragNormal, fragLightDir);
|
||||
float facingLight = step(0.0, diffuseDot);
|
||||
float diffuse = diffuseDot * facingLight;
|
||||
|
||||
// Specular Lighting depends on the half vector and the gloss
|
||||
// Specular Lighting depends on the half vector and the roughness
|
||||
vec3 halfDir = normalize(fragEyeDir + fragLightDir);
|
||||
|
||||
float specularPower = pow(facingLight * max(0.0, dot(halfDir, fragNormal)), gloss * 128.0);
|
||||
float gloss = (1.0 - roughness) * 128.0;
|
||||
glos *= gloss;
|
||||
float specularPower = pow(facingLight * max(0.0, dot(halfDir, fragNormal)), gloss);
|
||||
vec3 reflect = specularPower * specular * diffuse;
|
||||
|
||||
return vec4(reflect, diffuse);
|
||||
|
@ -59,8 +73,8 @@ vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3
|
|||
<$declareEvalPBRShading()$>
|
||||
|
||||
// Return xyz the specular/reflection component and w the diffuse component
|
||||
vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) {
|
||||
return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, specular, gloss);
|
||||
vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 specular, float roughness) {
|
||||
return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, metallic, specular, roughness);
|
||||
}
|
||||
|
||||
<@endif@>
|
||||
|
|
|
@ -92,6 +92,11 @@ void DeferredLightingEffect::init() {
|
|||
// Add the global light to the light stage (for later shadow rendering)
|
||||
_lightStage.addLight(lp);
|
||||
|
||||
lp->setDirection(glm::vec3(-1.0f));
|
||||
lp->setColor(glm::vec3(1.0f));
|
||||
lp->setIntensity(1.0f);
|
||||
lp->setType(model::Light::SUN);
|
||||
lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset::OLD_TOWN_SQUARE);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& color,
|
||||
|
@ -311,22 +316,23 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
|||
{
|
||||
auto& program = _shadowMapEnabled ? _directionalLightShadow : _directionalLight;
|
||||
LightLocationsPtr locations = _shadowMapEnabled ? _directionalLightShadowLocations : _directionalLightLocations;
|
||||
const auto& keyLight = _allocatedLights[_globalLights.front()];
|
||||
|
||||
// Setup the global directional pass pipeline
|
||||
{
|
||||
if (_shadowMapEnabled) {
|
||||
if (_skyboxTexture) {
|
||||
if (keyLight->getAmbientMap()) {
|
||||
program = _directionalSkyboxLightShadow;
|
||||
locations = _directionalSkyboxLightShadowLocations;
|
||||
} else if (_ambientLightMode > -1) {
|
||||
} else {
|
||||
program = _directionalAmbientSphereLightShadow;
|
||||
locations = _directionalAmbientSphereLightShadowLocations;
|
||||
}
|
||||
} else {
|
||||
if (_skyboxTexture) {
|
||||
if (keyLight->getAmbientMap()) {
|
||||
program = _directionalSkyboxLight;
|
||||
locations = _directionalSkyboxLightLocations;
|
||||
} else if (_ambientLightMode > -1) {
|
||||
} else {
|
||||
program = _directionalAmbientSphereLight;
|
||||
locations = _directionalAmbientSphereLightLocations;
|
||||
}
|
||||
|
@ -351,7 +357,7 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
|||
geometryCache->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||
}
|
||||
|
||||
if (_skyboxTexture) {
|
||||
if (keyLight->getAmbientMap()) {
|
||||
batch.setResourceTexture(SKYBOX_MAP_UNIT, nullptr);
|
||||
}
|
||||
}
|
||||
|
@ -490,14 +496,14 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
|||
|
||||
void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int skyboxCubemapUnit) {
|
||||
PerformanceTimer perfTimer("DLE->setupBatch()");
|
||||
auto globalLight = _allocatedLights[_globalLights.front()];
|
||||
auto keyLight = _allocatedLights[_globalLights.front()];
|
||||
|
||||
if (lightBufferUnit >= 0) {
|
||||
batch.setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer());
|
||||
batch.setUniformBuffer(lightBufferUnit, keyLight->getSchemaBuffer());
|
||||
}
|
||||
|
||||
if (_skyboxTexture && (skyboxCubemapUnit >= 0)) {
|
||||
batch.setResourceTexture(skyboxCubemapUnit, _skyboxTexture);
|
||||
if (keyLight->getAmbientMap() && (skyboxCubemapUnit >= 0)) {
|
||||
batch.setResourceTexture(skyboxCubemapUnit, keyLight->getAmbientMap());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -508,7 +514,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
|
|||
gpu::ShaderPointer program = gpu::Shader::createProgram(VS, PS);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), DEFERRED_BUFFER_COLOR_UNIT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), DEFERRED_BUFFER_COLOR_UNIT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), DEFERRED_BUFFER_NORMAL_UNIT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), DEFERRED_BUFFER_EMISSIVE_UNIT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), DEFERRED_BUFFER_DEPTH_UNIT));
|
||||
|
@ -556,15 +562,14 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
|
|||
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light, const gpu::TexturePointer& skyboxTexture) {
|
||||
void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light) {
|
||||
auto globalLight = _allocatedLights.front();
|
||||
globalLight->setDirection(light->getDirection());
|
||||
globalLight->setColor(light->getColor());
|
||||
globalLight->setIntensity(light->getIntensity());
|
||||
globalLight->setAmbientIntensity(light->getAmbientIntensity());
|
||||
globalLight->setAmbientSphere(light->getAmbientSphere());
|
||||
|
||||
_skyboxTexture = skyboxTexture;
|
||||
globalLight->setAmbientMap(light->getAmbientMap());
|
||||
}
|
||||
|
||||
model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
|
||||
|
|
|
@ -49,11 +49,12 @@ public:
|
|||
void setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int skyboxCubemapUnit);
|
||||
|
||||
// update global lighting
|
||||
void setGlobalLight(const model::LightPointer& light, const gpu::TexturePointer& skyboxTexture);
|
||||
void setGlobalLight(const model::LightPointer& light);
|
||||
|
||||
const LightStage& getLightStage() { return _lightStage; }
|
||||
void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; };
|
||||
void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; }
|
||||
bool isAmbientOcclusionEnabled() const { return _ambientOcclusionEnabled; }
|
||||
|
||||
private:
|
||||
DeferredLightingEffect() = default;
|
||||
|
@ -95,15 +96,12 @@ private:
|
|||
std::vector<int> _pointLights;
|
||||
std::vector<int> _spotLights;
|
||||
|
||||
int _ambientLightMode = 0;
|
||||
gpu::TexturePointer _skyboxTexture;
|
||||
|
||||
// Class describing the uniform buffer with all the parameters common to the deferred shaders
|
||||
class DeferredTransform {
|
||||
public:
|
||||
glm::mat4 projection;
|
||||
glm::mat4 viewInverse;
|
||||
float stereoSide{ 0.f };
|
||||
float stereoSide { 0.f };
|
||||
float spareA, spareB, spareC;
|
||||
|
||||
DeferredTransform() {}
|
||||
|
|
|
@ -506,7 +506,7 @@ GeometryCache::GeometryCache() :
|
|||
std::make_shared<render::ShapePipeline>(getSimplePipeline(), nullptr,
|
||||
[](const render::ShapePipeline&, gpu::Batch& batch) {
|
||||
// Set the defaults needed for a simple program
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::DIFFUSE_MAP,
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::ALBEDO_MAP,
|
||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
|
||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||
|
@ -1734,9 +1734,9 @@ inline bool operator==(const SimpleProgramKey& a, const SimpleProgramKey& b) {
|
|||
void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled, bool emissive, bool depthBiased) {
|
||||
batch.setPipeline(getSimplePipeline(textured, culled, emissive, depthBiased));
|
||||
|
||||
// If not textured, set a default diffuse map
|
||||
// If not textured, set a default albedo map
|
||||
if (!textured) {
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::DIFFUSE_MAP,
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::ALBEDO_MAP,
|
||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
}
|
||||
// Set a default normal map
|
||||
|
|
139
libraries/render-utils/src/MaterialTextures.slh
Normal file
139
libraries/render-utils/src/MaterialTextures.slh
Normal file
|
@ -0,0 +1,139 @@
|
|||
<!
|
||||
// MaterialTextures.slh
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Sam Gateau on 2/22/16
|
||||
// Copyright 2016 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
|
||||
!>
|
||||
<@if not MODEL_MATERIAL_TEXTURES_SLH@>
|
||||
<@def MODEL_MATERIAL_TEXTURES_SLH@>
|
||||
|
||||
<@func declareMaterialTextures(withAlbedo, withRoughness, withNormal, withMetallic, withEmissive, withOcclusion)@>
|
||||
|
||||
<@if withAlbedo@>
|
||||
uniform sampler2D albedoMap;
|
||||
vec4 fetchAlbedoMap(vec2 uv) {
|
||||
return texture(albedoMap, uv);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withRoughness@>
|
||||
uniform sampler2D roughnessMap;
|
||||
float fetchRoughnessMap(vec2 uv) {
|
||||
return (texture(roughnessMap, uv).r);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withNormal@>
|
||||
uniform sampler2D normalMap;
|
||||
vec3 fetchNormalMap(vec2 uv) {
|
||||
return texture(normalMap, uv).xyz;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withMetallic@>
|
||||
uniform sampler2D metallicMap;
|
||||
float fetchMetallicMap(vec2 uv) {
|
||||
return (texture(metallicMap, uv).r);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withEmissive@>
|
||||
uniform sampler2D emissiveMap;
|
||||
vec3 fetchEmissiveMap(vec2 uv) {
|
||||
return texture(emissiveMap, uv).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withOcclusion@>
|
||||
uniform sampler2D occlusionMap;
|
||||
float fetchOcclusionMap(vec2 uv) {
|
||||
return texture(occlusionMap, uv).r;
|
||||
}
|
||||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
|
||||
<@func fetchMaterialTextures(matKey, texcoord0, albedo, roughness, normal, metallic, emissive, occlusion)@>
|
||||
<@if albedo@>
|
||||
vec4 <$albedo$> = (((<$matKey$> & ALBEDO_MAP_BIT) != 0) ? fetchAlbedoMap(<$texcoord0$>) : vec4(1.0));
|
||||
<@endif@>
|
||||
<@if roughness@>
|
||||
float <$roughness$> = (((<$matKey$> & ROUGHNESS_MAP_BIT) != 0) ? fetchRoughnessMap(<$texcoord0$>) : 1.0);
|
||||
<@endif@>
|
||||
<@if normal@>
|
||||
vec3 <$normal$> = (((<$matKey$> & NORMAL_MAP_BIT) != 0) ? fetchNormalMap(<$texcoord0$>) : vec3(0.0, 1.0, 0.0));
|
||||
<@endif@>
|
||||
<@if metallic@>
|
||||
float <$metallic$> = (((<$matKey$> & METALLIC_MAP_BIT) != 0) ? fetchMetallicMap(<$texcoord0$>) : 0.0);
|
||||
<@endif@>
|
||||
<@if emissive@>
|
||||
vec3 <$emissive$> = (((<$matKey$> & EMISSIVE_MAP_BIT) != 0) ? fetchEmissiveMap(<$texcoord0$>) : vec3(0.0));
|
||||
<@endif@>
|
||||
<@if occlusion@>
|
||||
float <$occlusion$> = (((<$matKey$> & OCCLUSION_MAP_BIT) != 0) ? fetchOcclusionMap(<$texcoord0$>) : 1.0);
|
||||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
|
||||
<@func declareMaterialLightmap()@>
|
||||
uniform sampler2D emissiveMap;
|
||||
uniform vec2 emissiveParams;
|
||||
vec3 fetchLightmapMap(vec2 uv) {
|
||||
return (vec3(emissiveParams.x) + emissiveParams.y * texture(emissiveMap, uv).rgb);
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func fetchMaterialLightmap(texcoord1, lightmapVal)@>
|
||||
vec3 <$lightmapVal$> = fetchLightmapMap(<$texcoord1$>);
|
||||
<@endfunc@>
|
||||
|
||||
|
||||
<@func tangentToViewSpace(fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@>
|
||||
{
|
||||
vec3 normalizedNormal = normalize(<$interpolatedNormal$>.xyz);
|
||||
vec3 normalizedTangent = normalize(<$interpolatedTangent$>.xyz);
|
||||
vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent));
|
||||
vec3 localNormal = normalize(<$fetchedNormal$> - vec3(0.5, 0.5, 0.5));
|
||||
<$normal$> = vec3(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z);
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialAlbedo(fetchedAlbedo, materialAlbedo, matKey, albedo)@>
|
||||
{
|
||||
<$albedo$>.xyz = (((<$matKey$> & ALBEDO_VAL_BIT) != 0) ? <$materialAlbedo$> : vec3(1.0));
|
||||
|
||||
if (((<$matKey$> & ALBEDO_MAP_BIT) != 0)) {
|
||||
<$albedo$>.xyz *= <$fetchedAlbedo$>.xyz;
|
||||
}
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialRoughness(fetchedRoughness, materialRoughness, matKey, roughness)@>
|
||||
{
|
||||
<$roughness$> = (((<$matKey$> & ROUGHNESS_MAP_BIT) != 0) ? <$fetchedRoughness$> : <$materialRoughness$>);
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialMetallic(fetchedMetallic, materialMetallic, matKey, metallic)@>
|
||||
{
|
||||
<$metallic$> = (((<$matKey$> & METALLIC_MAP_BIT) != 0) ? <$fetchedMetallic$> : <$materialMetallic$>);
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialEmissive(fetchedEmissive, materialEmissive, matKey, emissive)@>
|
||||
{
|
||||
<$emissive$> = (((<$matKey$> & EMISSIVE_MAP_BIT) != 0) ? <$fetchedEmissive$> : <$materialEmissive$>);
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialOcclusion(fetchedOcclusion, matKey, occlusion)@>
|
||||
{
|
||||
<$occlusion$> = <$fetchedOcclusion$>;
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@endif@>
|
|
@ -106,7 +106,7 @@ ShapeKey MeshPartPayload::getShapeKey() const {
|
|||
if (drawMaterialKey.isNormalMap()) {
|
||||
builder.withTangents();
|
||||
}
|
||||
if (drawMaterialKey.isGlossMap()) {
|
||||
if (drawMaterialKey.isMetallicMap()) {
|
||||
builder.withSpecular();
|
||||
}
|
||||
if (drawMaterialKey.isLightmapMap()) {
|
||||
|
@ -145,20 +145,34 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
|||
auto textureMaps = _drawMaterial->getTextureMaps();
|
||||
glm::mat4 texcoordTransform[2];
|
||||
|
||||
// Diffuse
|
||||
if (materialKey.isDiffuseMap()) {
|
||||
auto diffuseMap = textureMaps[model::MaterialKey::DIFFUSE_MAP];
|
||||
if (diffuseMap && diffuseMap->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::DIFFUSE_MAP, diffuseMap->getTextureView());
|
||||
// Albedo
|
||||
if (materialKey.isAlbedoMap()) {
|
||||
auto albedoMap = textureMaps[model::MaterialKey::ALBEDO_MAP];
|
||||
if (albedoMap && albedoMap->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, albedoMap->getTextureView());
|
||||
|
||||
if (!diffuseMap->getTextureTransform().isIdentity()) {
|
||||
diffuseMap->getTextureTransform().getMatrix(texcoordTransform[0]);
|
||||
if (!albedoMap->getTextureTransform().isIdentity()) {
|
||||
albedoMap->getTextureTransform().getMatrix(texcoordTransform[0]);
|
||||
}
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::DIFFUSE_MAP, textureCache->getGrayTexture());
|
||||
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, textureCache->getGrayTexture());
|
||||
}
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::DIFFUSE_MAP, textureCache->getWhiteTexture());
|
||||
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, textureCache->getWhiteTexture());
|
||||
}
|
||||
|
||||
// Roughness map
|
||||
if (materialKey.isRoughnessMap()) {
|
||||
auto roughnessMap = textureMaps[model::MaterialKey::ROUGHNESS_MAP];
|
||||
if (roughnessMap && roughnessMap->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::ROUGHNESS_MAP, roughnessMap->getTextureView());
|
||||
|
||||
// texcoord are assumed to be the same has albedo
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::ROUGHNESS_MAP, textureCache->getWhiteTexture());
|
||||
}
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::ROUGHNESS_MAP, textureCache->getWhiteTexture());
|
||||
}
|
||||
|
||||
// Normal map
|
||||
|
@ -167,7 +181,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
|||
if (normalMap && normalMap->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, normalMap->getTextureView());
|
||||
|
||||
// texcoord are assumed to be the same has diffuse
|
||||
// texcoord are assumed to be the same has albedo
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, textureCache->getBlueTexture());
|
||||
}
|
||||
|
@ -175,26 +189,40 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
|||
batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, nullptr);
|
||||
}
|
||||
|
||||
// TODO: For now gloss map is used as the "specular map in the shading, we ll need to fix that
|
||||
if (materialKey.isGlossMap()) {
|
||||
auto specularMap = textureMaps[model::MaterialKey::GLOSS_MAP];
|
||||
// Metallic map
|
||||
if (materialKey.isMetallicMap()) {
|
||||
auto specularMap = textureMaps[model::MaterialKey::METALLIC_MAP];
|
||||
if (specularMap && specularMap->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::SPECULAR_MAP, specularMap->getTextureView());
|
||||
batch.setResourceTexture(ShapePipeline::Slot::METALLIC_MAP, specularMap->getTextureView());
|
||||
|
||||
// texcoord are assumed to be the same has diffuse
|
||||
// texcoord are assumed to be the same has albedo
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::SPECULAR_MAP, textureCache->getBlackTexture());
|
||||
batch.setResourceTexture(ShapePipeline::Slot::METALLIC_MAP, textureCache->getBlackTexture());
|
||||
}
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::SPECULAR_MAP, nullptr);
|
||||
batch.setResourceTexture(ShapePipeline::Slot::METALLIC_MAP, nullptr);
|
||||
}
|
||||
|
||||
// TODO: For now lightmaop is piped into the emissive map unit, we need to fix that and support for real emissive too
|
||||
// Occlusion map
|
||||
if (materialKey.isOcclusionMap()) {
|
||||
auto specularMap = textureMaps[model::MaterialKey::OCCLUSION_MAP];
|
||||
if (specularMap && specularMap->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::OCCLUSION_MAP, specularMap->getTextureView());
|
||||
|
||||
// texcoord are assumed to be the same has albedo
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::OCCLUSION_MAP, textureCache->getWhiteTexture());
|
||||
}
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::OCCLUSION_MAP, nullptr);
|
||||
}
|
||||
|
||||
// Emissive / Lightmap
|
||||
if (materialKey.isLightmapMap()) {
|
||||
auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP];
|
||||
|
||||
if (lightmapMap && lightmapMap->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::LIGHTMAP_MAP, lightmapMap->getTextureView());
|
||||
batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, lightmapMap->getTextureView());
|
||||
|
||||
auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale();
|
||||
batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y);
|
||||
|
@ -203,10 +231,18 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
|||
lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]);
|
||||
}
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::LIGHTMAP_MAP, textureCache->getGrayTexture());
|
||||
batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, textureCache->getGrayTexture());
|
||||
}
|
||||
} else if (materialKey.isEmissiveMap()) {
|
||||
auto emissiveMap = textureMaps[model::MaterialKey::EMISSIVE_MAP];
|
||||
|
||||
if (emissiveMap && emissiveMap->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, emissiveMap->getTextureView());
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, textureCache->getBlackTexture());
|
||||
}
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::LIGHTMAP_MAP, nullptr);
|
||||
batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, nullptr);
|
||||
}
|
||||
|
||||
// Texcoord transforms ?
|
||||
|
@ -378,7 +414,7 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
|||
|
||||
bool isTranslucent = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap();
|
||||
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
||||
bool hasSpecular = drawMaterialKey.isGlossMap();
|
||||
bool hasSpecular = drawMaterialKey.isMetallicMap();
|
||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
||||
|
||||
bool isSkinned = _isSkinned;
|
||||
|
|
|
@ -1205,9 +1205,9 @@ void Model::segregateMeshGroups() {
|
|||
if (showingCollisionHull) {
|
||||
if (!_collisionHullMaterial) {
|
||||
_collisionHullMaterial = std::make_shared<model::Material>();
|
||||
_collisionHullMaterial->setDiffuse(glm::vec3(1.0f, 0.5f, 0.0f));
|
||||
_collisionHullMaterial->setAlbedo(glm::vec3(1.0f, 0.5f, 0.0f));
|
||||
_collisionHullMaterial->setMetallic(0.02f);
|
||||
_collisionHullMaterial->setGloss(1.0f);
|
||||
_collisionHullMaterial->setRoughness(0.5f);
|
||||
}
|
||||
_renderItemsSet << std::make_shared<MeshPartPayload>(networkMesh._mesh, partIndex, _collisionHullMaterial, transform, offset);
|
||||
} else {
|
||||
|
|
|
@ -66,16 +66,16 @@ void initStencilPipeline(gpu::PipelinePointer& pipeline) {
|
|||
|
||||
gpu::BufferView getDefaultMaterialBuffer() {
|
||||
model::Material::Schema schema;
|
||||
schema._diffuse = vec3(1.0f);
|
||||
schema._albedo = vec3(1.0f);
|
||||
schema._opacity = 1.0f;
|
||||
schema._metallic = vec3(0.1f);
|
||||
schema._gloss = 10.0f;
|
||||
schema._metallic = 0.1f;
|
||||
schema._roughness = 0.9f;
|
||||
return gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(model::Material::Schema), (const gpu::Byte*) &schema));
|
||||
}
|
||||
|
||||
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
||||
// Set a default diffuse map
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::DIFFUSE_MAP,
|
||||
// Set a default albedo map
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::ALBEDO_MAP,
|
||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
// Set a default normal map
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
out vec4 _color;
|
||||
|
||||
void main(void) {
|
||||
// pass along the diffuse color
|
||||
// pass along the color
|
||||
_color = colorToLinearRGBA(inColor.rgba);
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
|
|
@ -44,8 +44,9 @@ void main(void) {
|
|||
frag.position.xyz,
|
||||
frag.normal,
|
||||
frag.diffuse,
|
||||
frag.specular,
|
||||
frag.gloss);
|
||||
frag.metallic,
|
||||
frag.emissive,
|
||||
frag.roughness);
|
||||
_fragColor = vec4(color, frag.normalVal.a);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,8 +46,9 @@ void main(void) {
|
|||
frag.position.xyz,
|
||||
frag.normal,
|
||||
frag.diffuse,
|
||||
frag.specular,
|
||||
frag.gloss);
|
||||
frag.metallic,
|
||||
frag.emissive,
|
||||
frag.roughness);
|
||||
_fragColor = vec4(color, frag.normalVal.a);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,8 +45,9 @@ void main(void) {
|
|||
frag.position.xyz,
|
||||
frag.normal,
|
||||
frag.diffuse,
|
||||
frag.specular,
|
||||
frag.gloss);
|
||||
frag.metallic,
|
||||
frag.emissive,
|
||||
frag.roughness);
|
||||
_fragColor = vec4(color, frag.normalVal.a);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,8 +47,9 @@ void main(void) {
|
|||
frag.position.xyz,
|
||||
frag.normal,
|
||||
frag.diffuse,
|
||||
frag.specular,
|
||||
frag.gloss);
|
||||
frag.metallic,
|
||||
frag.emissive,
|
||||
frag.roughness);
|
||||
_fragColor = vec4(color, frag.normalVal.a);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,8 +45,9 @@ void main(void) {
|
|||
frag.position.xyz,
|
||||
frag.normal,
|
||||
frag.diffuse,
|
||||
frag.specular,
|
||||
frag.gloss);
|
||||
frag.metallic,
|
||||
frag.emissive,
|
||||
frag.roughness);
|
||||
|
||||
_fragColor = vec4(color, frag.normalVal.a);
|
||||
}
|
||||
|
|
|
@ -47,8 +47,9 @@ void main(void) {
|
|||
frag.position.xyz,
|
||||
frag.normal,
|
||||
frag.diffuse,
|
||||
frag.specular,
|
||||
frag.gloss);
|
||||
frag.metallic,
|
||||
frag.emissive,
|
||||
frag.roughness);
|
||||
|
||||
_fragColor = vec4(color, frag.normalVal.a);
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec3 _normal;
|
||||
|
@ -25,15 +25,26 @@ in vec2 _texCoord0;
|
|||
|
||||
|
||||
void main(void) {
|
||||
// Fetch diffuse map
|
||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex, occlusionTex)$>
|
||||
|
||||
vec3 albedo = getMaterialAlbedo(mat);
|
||||
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
||||
albedo *= _color;
|
||||
|
||||
float roughness = getMaterialRoughness(mat);
|
||||
<$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>;
|
||||
|
||||
vec3 emissive = getMaterialEmissive(mat);
|
||||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
packDeferredFragment(
|
||||
normalize(_normal.xyz),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
||||
getMaterialSpecular(mat),
|
||||
getMaterialShininess(mat));
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedoTex.a),
|
||||
albedo,
|
||||
roughness,
|
||||
getMaterialMetallic(mat),
|
||||
emissive,
|
||||
occlusionTex);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<@include DeferredBufferWrite.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2D albedoMap;
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec3 _normal;
|
||||
|
@ -23,16 +23,17 @@ in vec3 _color;
|
|||
in float _alpha;
|
||||
|
||||
void main(void) {
|
||||
vec4 texel = texture(diffuseMap, _texCoord0);
|
||||
vec4 texel = texture(albedoMap, _texCoord0);
|
||||
|
||||
Material mat = getMaterial();
|
||||
vec3 fragColor = getMaterialDiffuse(mat) * texel.rgb * _color;
|
||||
vec3 fragColor = getMaterialAlbedo(mat) * texel.rgb * _color;
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(_normal),
|
||||
texel.a,
|
||||
vec3(1.0),
|
||||
getMaterialSpecular(mat),
|
||||
getMaterialShininess(mat),
|
||||
getMaterialRoughness(mat),
|
||||
getMaterialMetallic(mat),
|
||||
getMaterialFresnel(mat),
|
||||
fragColor);
|
||||
}
|
||||
|
|
|
@ -16,12 +16,9 @@
|
|||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the emissive map texture and parameters
|
||||
uniform sampler2D emissiveMap;
|
||||
uniform vec2 emissiveParams;
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS)$>
|
||||
<$declareMaterialLightmap()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
|
@ -30,16 +27,18 @@ in vec3 _normal;
|
|||
in vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
||||
vec4 emissive = texture(emissiveMap, _texCoord1);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedo, roughness)$>
|
||||
<$fetchMaterialLightmap(_texCoord1, emissive)$>
|
||||
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(_normal),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
||||
getMaterialSpecular(mat),
|
||||
getMaterialShininess(mat),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a),
|
||||
getMaterialAlbedo(mat) * albedo.rgb * _color,
|
||||
getMaterialRoughness(mat) * roughness,
|
||||
getMaterialMetallic(mat),
|
||||
getMaterialFresnel(mat),
|
||||
(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb));
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ out vec3 _normal;
|
|||
out vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
// pass along the diffuse color in linear space
|
||||
// pass along the color in linear space
|
||||
_color = colorToLinearRGB(inColor.xyz);
|
||||
|
||||
// and the texture coordinates
|
||||
|
|
|
@ -16,15 +16,9 @@
|
|||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the normal map texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the emissive map texture and parameters
|
||||
uniform sampler2D emissiveMap;
|
||||
uniform vec2 emissiveParams;
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL)$>
|
||||
<$declareMaterialLightmap()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
|
@ -34,25 +28,20 @@ in vec3 _tangent;
|
|||
in vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
// compute the view normal from the various bits
|
||||
vec3 normalizedNormal = normalize(_normal);
|
||||
vec3 normalizedTangent = normalize(_tangent);
|
||||
vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent));
|
||||
vec3 localNormal = vec3(texture(normalMap, _texCoord0)) - vec3(0.5, 0.5, 0.5);
|
||||
vec4 viewNormal = vec4(normalizedTangent * localNormal.x +
|
||||
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||
|
||||
// set the diffuse, normal, specular data
|
||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
||||
vec4 emissive = texture(emissiveMap, _texCoord1);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedo, roughness, normalTexel)$>
|
||||
<$fetchMaterialLightmap(_texCoord1, lightmapVal)$>
|
||||
|
||||
vec3 viewNormal;
|
||||
<$tangentToViewSpace(normalTexel, _normal, _tangent, viewNormal)$>
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(viewNormal.xyz),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
||||
getMaterialSpecular(mat),
|
||||
getMaterialShininess(mat),
|
||||
(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb));
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a),
|
||||
getMaterialAlbedo(mat) * albedo.rgb * _color,
|
||||
getMaterialRoughness(mat),
|
||||
getMaterialMetallic(mat),
|
||||
getMaterialFresnel(mat),
|
||||
lightmapVal);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ out vec3 _tangent;
|
|||
out vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
// pass along the diffuse color in linear space
|
||||
// pass along the color in linear space
|
||||
_color = colorToLinearRGB(inColor.xyz);
|
||||
|
||||
// and the texture coordinates
|
||||
|
|
|
@ -16,18 +16,9 @@
|
|||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the emissive map texture and parameters
|
||||
uniform sampler2D emissiveMap;
|
||||
uniform vec2 emissiveParams;
|
||||
|
||||
// the normal map texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the specular map texture
|
||||
uniform sampler2D specularMap;
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC)$>
|
||||
<$declareMaterialLightmap()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
|
@ -37,26 +28,20 @@ in vec3 _tangent;
|
|||
in vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
// compute the view normal from the various bits
|
||||
vec3 normalizedNormal = normalize(_normal);
|
||||
vec3 normalizedTangent = normalize(_tangent);
|
||||
vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent));
|
||||
vec3 localNormal = vec3(texture(normalMap, _texCoord0)) - vec3(0.5, 0.5, 0.5);
|
||||
vec4 viewNormal = vec4(normalizedTangent * localNormal.x +
|
||||
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||
|
||||
// set the diffuse, normal, specular data
|
||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
||||
vec3 specular = texture(specularMap, _texCoord0).rgb;
|
||||
vec4 emissive = texture(emissiveMap, _texCoord1);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedo, roughness, normalTexel, metallicTex)$>
|
||||
<$fetchMaterialLightmap(_texCoord1, lightmapVal)$>
|
||||
|
||||
vec3 viewNormal;
|
||||
<$tangentToViewSpace(normalTexel, _normal, _tangent, viewNormal)$>
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(viewNormal.xyz),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
||||
specular, // no use of getMaterialSpecular(mat)
|
||||
getMaterialShininess(mat),
|
||||
(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb));
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a),
|
||||
getMaterialAlbedo(mat) * albedo.rgb * _color,
|
||||
getMaterialRoughness(mat) * roughness,
|
||||
getMaterialMetallic(mat) * metallicTex,
|
||||
/*specular, // no use of */ getMaterialFresnel(mat),
|
||||
lightmapVal);
|
||||
}
|
||||
|
|
|
@ -16,15 +16,9 @@
|
|||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the emissive map texture and parameters
|
||||
uniform sampler2D emissiveMap;
|
||||
uniform vec2 emissiveParams;
|
||||
|
||||
// the specular texture
|
||||
uniform sampler2D specularMap;
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC)$>
|
||||
<$declareMaterialLightmap()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
|
@ -33,18 +27,17 @@ in vec3 _normal;
|
|||
in vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
// set the diffuse, normal, specular data
|
||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
||||
vec3 specular = texture(specularMap, _texCoord0).rgb;
|
||||
vec4 emissive = texture(emissiveMap, _texCoord1);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedo, roughness, _SCRIBE_NULL, metallicTex)$>
|
||||
<$fetchMaterialLightmap(_texCoord1, lightmapVal)$>
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(_normal),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
||||
specular, // no use of getMaterialSpecular(mat)
|
||||
getMaterialShininess(mat),
|
||||
(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb));
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a),
|
||||
getMaterialAlbedo(mat) * albedo.rgb * _color,
|
||||
getMaterialRoughness(mat) * roughness,
|
||||
getMaterialMetallic(mat) * metallicTex,
|
||||
/*metallicTex, // no use of */getMaterialFresnel(mat),
|
||||
lightmapVal);
|
||||
}
|
||||
|
|
|
@ -16,11 +16,8 @@
|
|||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the normal map texture
|
||||
uniform sampler2D normalMap;
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
|
@ -29,22 +26,29 @@ in vec3 _tangent;
|
|||
in vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
// compute the view normal from the various bits
|
||||
vec3 normalizedNormal = normalize(_normal.xyz);
|
||||
vec3 normalizedTangent = normalize(_tangent.xyz);
|
||||
vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent));
|
||||
vec3 localNormal = normalize(vec3(texture(normalMap, _texCoord0.st)) - vec3(0.5, 0.5, 0.5));
|
||||
vec4 viewNormal = vec4(normalizedTangent * localNormal.x +
|
||||
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||
|
||||
vec4 diffuse = texture(diffuseMap, _texCoord0.st);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, _SCRIBE_NULL, emissiveTex, occlusionTex)$>
|
||||
|
||||
vec3 albedo = getMaterialAlbedo(mat);
|
||||
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
||||
albedo *= _color;
|
||||
|
||||
float roughness = getMaterialRoughness(mat);
|
||||
<$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>;
|
||||
|
||||
vec3 emissive = getMaterialEmissive(mat);
|
||||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
vec3 viewNormal;
|
||||
<$tangentToViewSpace(normalTex, _normal, _tangent, viewNormal)$>
|
||||
|
||||
packDeferredFragment(
|
||||
normalize(viewNormal.xyz),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
||||
getMaterialSpecular(mat),
|
||||
getMaterialShininess(mat));
|
||||
viewNormal,
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedoTex.a),
|
||||
albedo,
|
||||
roughness,
|
||||
getMaterialMetallic(mat),
|
||||
emissive,
|
||||
occlusionTex);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ out vec3 _tangent;
|
|||
out vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
// pass along the diffuse color
|
||||
// pass along the color
|
||||
_color = colorToLinearRGB(inColor.xyz);
|
||||
|
||||
// and the texture coordinates
|
||||
|
|
|
@ -16,14 +16,8 @@
|
|||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the normal map texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the specular map texture
|
||||
uniform sampler2D specularMap;
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC, EMISSIVE, OCCLUSION)$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
|
@ -32,24 +26,33 @@ in vec3 _tangent;
|
|||
in vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
// compute the view normal from the various bits
|
||||
vec3 normalizedNormal = normalize(_normal);
|
||||
vec3 normalizedTangent = normalize(_tangent);
|
||||
vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent));
|
||||
vec3 localNormal = normalize(vec3(texture(normalMap, _texCoord0)) - vec3(0.5, 0.5, 0.5));
|
||||
vec4 viewNormal = vec4(normalizedTangent * localNormal.x +
|
||||
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||
|
||||
// set the diffuse, normal, specular data
|
||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
||||
vec3 specular = texture(specularMap, _texCoord0).rgb;
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, occlusionTex)$>
|
||||
|
||||
vec3 albedo = getMaterialAlbedo(mat);
|
||||
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
||||
albedo *= _color;
|
||||
|
||||
float roughness = getMaterialRoughness(mat);
|
||||
<$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>;
|
||||
|
||||
vec3 emissive = getMaterialEmissive(mat);
|
||||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
vec3 viewNormal;
|
||||
<$tangentToViewSpace(normalTex, _normal, _tangent, viewNormal)$>
|
||||
|
||||
float metallic = getMaterialMetallic(mat);
|
||||
<$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>;
|
||||
|
||||
|
||||
packDeferredFragment(
|
||||
normalize(viewNormal.xyz),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
||||
specular, //getMaterialSpecular(mat),
|
||||
getMaterialShininess(mat));
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedoTex.a),
|
||||
albedo,
|
||||
roughness,
|
||||
metallic,
|
||||
emissive,
|
||||
occlusionTex);
|
||||
}
|
||||
|
|
|
@ -16,11 +16,8 @@
|
|||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the specular texture
|
||||
uniform sampler2D specularMap;
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC, EMISSIVE, OCCLUSION)$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
|
@ -29,16 +26,29 @@ in vec3 _color;
|
|||
|
||||
|
||||
void main(void) {
|
||||
// set the diffuse, normal, specular data
|
||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
||||
vec3 specular = texture(specularMap, _texCoord0).rgb;
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, occlusionTex)$>
|
||||
|
||||
vec3 albedo = getMaterialAlbedo(mat);
|
||||
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
||||
albedo *= _color;
|
||||
|
||||
float roughness = getMaterialRoughness(mat);
|
||||
<$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>;
|
||||
|
||||
vec3 emissive = getMaterialEmissive(mat);
|
||||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
float metallic = getMaterialMetallic(mat);
|
||||
<$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>;
|
||||
|
||||
packDeferredFragment(
|
||||
normalize(_normal),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
||||
specular, //getMaterialSpecular(mat),
|
||||
getMaterialShininess(mat));
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedoTex.a),
|
||||
albedo,
|
||||
roughness,
|
||||
metallic,
|
||||
emissive,
|
||||
occlusionTex);
|
||||
}
|
||||
|
|
|
@ -20,9 +20,7 @@
|
|||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2D albedoMap;
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _position;
|
||||
|
@ -33,15 +31,16 @@ in float _alpha;
|
|||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
||||
vec4 albedo = texture(albedoMap, _texCoord0);
|
||||
|
||||
Material mat = getMaterial();
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragNormal = normalize(_normal);
|
||||
vec3 fragDiffuse = getMaterialDiffuse(mat) * diffuse.rgb * _color;
|
||||
vec3 fragSpecular = getMaterialSpecular(mat);
|
||||
float fragGloss = getMaterialShininess(mat) / 128;
|
||||
float fragOpacity = getMaterialOpacity(mat) * diffuse.a * _alpha;
|
||||
vec3 fragAlbedo = getMaterialAlbedo(mat) * albedo.rgb * _color;
|
||||
float fragMetallic = getMaterialMetallic(mat);
|
||||
vec3 fragEmissive = getMaterialEmissive(mat);
|
||||
float fragRoughness = getMaterialRoughness(mat);
|
||||
float fragOpacity = getMaterialOpacity(mat) * albedo.a * _alpha;
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
||||
|
@ -51,8 +50,9 @@ void main(void) {
|
|||
1.0,
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
fragDiffuse,
|
||||
fragSpecular,
|
||||
fragGloss),
|
||||
fragAlbedo,
|
||||
fragMetallic,
|
||||
fragEmissive,
|
||||
fragRoughness),
|
||||
fragOpacity);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2D albedoMap;
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec3 _color;
|
||||
|
@ -23,11 +23,11 @@ in float _alpha;
|
|||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
||||
vec4 albedo = texture(albedoMap, _texCoord0);
|
||||
|
||||
Material mat = getMaterial();
|
||||
vec3 fragColor = getMaterialDiffuse(mat) * diffuse.rgb * _color;
|
||||
float fragOpacity = getMaterialOpacity(mat) * diffuse.a * _alpha;
|
||||
vec3 fragColor = getMaterialAlbedo(mat) * albedo.rgb * _color;
|
||||
float fragOpacity = getMaterialOpacity(mat) * albedo.a * _alpha;
|
||||
|
||||
_fragColor = vec4(fragColor, fragOpacity);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss, float opacity) {
|
||||
vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 specular, float roughness, float opacity) {
|
||||
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
|
@ -28,11 +28,11 @@ vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 d
|
|||
vec3 fragEyeDir;
|
||||
<$transformEyeToWorldDir(cam, fragEyeVectorView, fragEyeDir)$>
|
||||
|
||||
vec3 color = opacity * diffuse.rgb * getLightColor(light) * getLightAmbientIntensity(light);
|
||||
vec3 color = opacity * albedo * getLightColor(light) * getLightAmbientIntensity(light);
|
||||
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, specular, roughness);
|
||||
|
||||
color += vec3(diffuse * shading.w * opacity + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
|
||||
color += vec3(albedo * shading.w * opacity + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
|
||||
|
||||
return vec4(color, opacity);
|
||||
}
|
||||
|
@ -48,14 +48,15 @@ in float _alpha;
|
|||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 diffuse = texture(originalTexture, _texCoord0);
|
||||
vec4 albedo = texture(originalTexture, _texCoord0);
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragNormal = normalize(_normal);
|
||||
vec3 fragDiffuse = diffuse.rgb * _color;
|
||||
vec3 fragAlbedo = albedo.rgb * _color;
|
||||
float fragMetallic = 0.0;
|
||||
vec3 fragSpecular = vec3(0.1);
|
||||
float fragGloss = 10.0 / 128.0;
|
||||
float fragOpacity = diffuse.a;
|
||||
float fragRoughness = 0.9;
|
||||
float fragOpacity = albedo.a;
|
||||
|
||||
if (fragOpacity <= 0.1) {
|
||||
discard;
|
||||
|
@ -64,9 +65,10 @@ void main(void) {
|
|||
vec4 color = evalGlobalColor(1.0,
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
fragDiffuse,
|
||||
fragAlbedo,
|
||||
fragMetallic,
|
||||
fragSpecular,
|
||||
fragGloss,
|
||||
fragRoughness,
|
||||
fragOpacity);
|
||||
|
||||
// Apply standard tone mapping
|
||||
|
|
|
@ -20,12 +20,12 @@ in vec3 _color;
|
|||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 diffuse = texture(originalTexture, _texCoord0);
|
||||
vec4 albedo = texture(originalTexture, _texCoord0);
|
||||
|
||||
if (diffuse.a <= 0.1) {
|
||||
if (albedo.a <= 0.1) {
|
||||
discard;
|
||||
}
|
||||
vec4 color = vec4(diffuse.rgb * _color, diffuse.a);
|
||||
vec4 color = vec4(albedo.rgb * _color, albedo.a);
|
||||
|
||||
// Apply standard tone mapping
|
||||
_fragColor = vec4(pow(color.xyz, vec3(1.0 / 2.2)), color.w);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss, float opacity) {
|
||||
vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 specular, float roughness, float opacity) {
|
||||
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
|
@ -29,11 +29,11 @@ vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 d
|
|||
vec3 fragEyeDir;
|
||||
<$transformEyeToWorldDir(cam, fragEyeVectorView, fragEyeDir)$>
|
||||
|
||||
vec3 color = opacity * diffuse.rgb * getLightColor(light) * getLightAmbientIntensity(light);
|
||||
vec3 color = opacity * albedo * getLightColor(light) * getLightAmbientIntensity(light);
|
||||
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, specular, roughness);
|
||||
|
||||
color += vec3(diffuse * shading.w * opacity + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
|
||||
color += vec3(albedo * shading.w * opacity + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
|
||||
|
||||
return vec4(color, opacity);
|
||||
}
|
||||
|
@ -49,21 +49,23 @@ in float _alpha;
|
|||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 diffuse = texture(originalTexture, _texCoord0);
|
||||
vec4 albedo = texture(originalTexture, _texCoord0);
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragNormal = normalize(_normal);
|
||||
vec3 fragDiffuse = diffuse.rgb * _color;
|
||||
vec3 fragAlbedo = albedo.rgb * _color;
|
||||
float fragMetallic = 0.0;
|
||||
vec3 fragSpecular = vec3(0.1);
|
||||
float fragGloss = 10.0 / 128.0;
|
||||
float fragOpacity = diffuse.a * _alpha;
|
||||
float fragRoughness = 0.9;
|
||||
float fragOpacity = albedo.a * _alpha;
|
||||
|
||||
vec4 color = evalGlobalColor(1.0,
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
fragDiffuse,
|
||||
fragAlbedo,
|
||||
fragMetallic,
|
||||
fragSpecular,
|
||||
fragGloss,
|
||||
fragRoughness,
|
||||
fragOpacity);
|
||||
|
||||
// Apply standard tone mapping
|
||||
|
|
|
@ -21,7 +21,7 @@ in float _alpha;
|
|||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 diffuse = texture(originalTexture, _texCoord0);
|
||||
vec4 albedo = texture(originalTexture, _texCoord0);
|
||||
|
||||
_fragColor = vec4(diffuse.rgb * _color, diffuse.a * _alpha);
|
||||
_fragColor = vec4(albedo.rgb * _color, albedo.a * _alpha);
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ void main(void) {
|
|||
vec3 fragNormal = vec3(invViewMat * vec4(frag.normal, 0.0));
|
||||
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
|
||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||
vec4 shading = evalFragShading(fragNormal, fragLightDir, fragEyeDir, frag.specular, frag.gloss);
|
||||
vec4 shading = evalFragShading(fragNormal, fragLightDir, fragEyeDir, frag.metallic, frag.specular, frag.roughness);
|
||||
|
||||
// Eval attenuation
|
||||
float radialAttenuation = evalLightAttenuation(light, fragLightDistance);
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
// 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@>
|
||||
|
||||
uniform sampler2D Font;
|
||||
uniform bool Outline;
|
||||
uniform vec4 Color;
|
||||
|
@ -17,12 +19,11 @@ uniform vec4 Color;
|
|||
// the interpolated normal
|
||||
in vec3 _normal;
|
||||
in vec2 _texCoord0;
|
||||
|
||||
/*
|
||||
layout(location = 0) out vec4 _fragColor0;
|
||||
layout(location = 1) out vec4 _fragColor1;
|
||||
layout(location = 2) out vec4 _fragColor2;
|
||||
|
||||
const float DEFAULT_SHININESS = 10;
|
||||
*/
|
||||
|
||||
const float gamma = 2.2;
|
||||
const float smoothing = 256.0;
|
||||
|
@ -53,7 +54,16 @@ void main() {
|
|||
}
|
||||
|
||||
// final color
|
||||
_fragColor0 = vec4(Color.rgb, Color.a * a);
|
||||
/* _fragColor0 = vec4(Color.rgb, Color.a * a);
|
||||
_fragColor1 = vec4(normalize(_normal.xyz), 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5);
|
||||
_fragColor2 = vec4(Color.rgb, DEFAULT_SHININESS / 128.0);
|
||||
_fragColor2 = vec4(Color.rgb, 10 / 128.0);
|
||||
*/
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(_normal),
|
||||
Color.a * a,
|
||||
Color.rgb,
|
||||
DEFAULT_ROUGHNESS,
|
||||
DEFAULT_METALLIC,
|
||||
DEFAULT_SPECULAR,
|
||||
Color.rgb);
|
||||
}
|
|
@ -51,9 +51,9 @@ void main(void) {
|
|||
|
||||
if (emissiveAmount > 0.0) {
|
||||
packDeferredFragmentLightmap(
|
||||
normal, 1.0, diffuse, specular, shininess, specular);
|
||||
normal, 1.0, diffuse, max(0, 1.0 - shininess / 128.0), DEFAULT_METALLIC, specular, specular);
|
||||
} else {
|
||||
packDeferredFragment(
|
||||
normal, 1.0, diffuse, specular, shininess);
|
||||
normal, 1.0, diffuse, max(0, 1.0 - shininess / 128.0), length(specular), DEFAULT_EMISSIVE, DEFAULT_OCCLUSION);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// simple.frag
|
||||
// simple_textured.slf
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Clément Brisset on 5/29/15.
|
||||
|
@ -15,7 +15,7 @@
|
|||
<@include DeferredBufferWrite.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
// the albedo texture
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
|
@ -31,5 +31,8 @@ void main(void) {
|
|||
normalize(_normal.xyz),
|
||||
texel.a,
|
||||
_color.rgb * texel.rgb,
|
||||
DEFAULT_SPECULAR, DEFAULT_SHININESS);
|
||||
DEFAULT_ROUGHNESS,
|
||||
DEFAULT_METALLIC,
|
||||
DEFAULT_EMISSIVE,
|
||||
DEFAULT_OCCLUSION);
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
// the albedo texture
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
|
@ -29,6 +29,8 @@ void main(void) {
|
|||
normalize(_normal),
|
||||
texel.a,
|
||||
_color.rgb,
|
||||
DEFAULT_SPECULAR, DEFAULT_SHININESS,
|
||||
DEFAULT_ROUGHNESS,
|
||||
DEFAULT_METALLIC,
|
||||
DEFAULT_SPECULAR,
|
||||
texel.rgb);
|
||||
}
|
|
@ -32,7 +32,7 @@ void main(void) {
|
|||
|
||||
skinPositionNormal(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, position, interpolatedNormal);
|
||||
|
||||
// pass along the diffuse color
|
||||
// pass along the color
|
||||
_color = colorToLinearRGB(inColor.rgb);
|
||||
|
||||
// and the texture coordinates
|
||||
|
|
|
@ -34,7 +34,7 @@ void main(void) {
|
|||
|
||||
skinPositionNormalTangent(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, inTangent.xyz, position, interpolatedNormal.xyz, interpolatedTangent.xyz);
|
||||
|
||||
// pass along the diffuse color
|
||||
// pass along the color
|
||||
_color = colorToLinearRGB(inColor.rgb);
|
||||
|
||||
// and the texture coordinates
|
||||
|
|
|
@ -66,7 +66,7 @@ void main(void) {
|
|||
vec3 fragNormal = vec3(invViewMat * vec4(frag.normal, 0.0));
|
||||
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
|
||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||
vec4 shading = evalFragShading(fragNormal, fragLightDir, fragEyeDir, frag.specular, frag.gloss);
|
||||
vec4 shading = evalFragShading(fragNormal, fragLightDir, fragEyeDir, frag.metallic, frag.specular, frag.roughness);
|
||||
|
||||
// Eval attenuation
|
||||
float radialAttenuation = evalLightAttenuation(light, fragLightDistance);
|
||||
|
|
|
@ -53,10 +53,12 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p
|
|||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), Slot::SKINNING_GPU));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), Slot::MATERIAL_GPU));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), Slot::DIFFUSE_MAP));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("albedoMap"), Slot::ALBEDO_MAP));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("roughnessMap"), Slot::ROUGHNESS_MAP));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), Slot::NORMAL_MAP));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), Slot::SPECULAR_MAP));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), Slot::LIGHTMAP_MAP));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("metallicMap"), Slot::METALLIC_MAP));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), Slot::EMISSIVE_LIGHTMAP_MAP));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("occlusionMap"), Slot::OCCLUSION_MAP));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), Slot::LIGHT_BUFFER));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), Slot::NORMAL_FITTING_MAP));
|
||||
|
||||
|
@ -66,10 +68,12 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p
|
|||
locations->texcoordMatrices = program->getUniforms().findLocation("texcoordMatrices");
|
||||
locations->emissiveParams = program->getUniforms().findLocation("emissiveParams");
|
||||
locations->normalFittingMapUnit = program->getTextures().findLocation("normalFittingMap");
|
||||
locations->diffuseTextureUnit = program->getTextures().findLocation("diffuseMap");
|
||||
locations->albedoTextureUnit = program->getTextures().findLocation("albedoMap");
|
||||
locations->roughnessTextureUnit = program->getTextures().findLocation("roughnessMap");
|
||||
locations->normalTextureUnit = program->getTextures().findLocation("normalMap");
|
||||
locations->specularTextureUnit = program->getTextures().findLocation("specularMap");
|
||||
locations->metallicTextureUnit = program->getTextures().findLocation("metallicMap");
|
||||
locations->emissiveTextureUnit = program->getTextures().findLocation("emissiveMap");
|
||||
locations->occlusionTextureUnit = program->getTextures().findLocation("occlusionMap");
|
||||
locations->skinClusterBufferUnit = program->getBuffers().findLocation("skinClusterBuffer");
|
||||
locations->materialBufferUnit = program->getBuffers().findLocation("materialBuffer");
|
||||
locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer");
|
||||
|
|
|
@ -195,10 +195,13 @@ public:
|
|||
public:
|
||||
static const int SKINNING_GPU = 2;
|
||||
static const int MATERIAL_GPU = 3;
|
||||
static const int DIFFUSE_MAP = 0;
|
||||
static const int ALBEDO_MAP = 0;
|
||||
static const int NORMAL_MAP = 1;
|
||||
static const int SPECULAR_MAP = 2;
|
||||
static const int LIGHTMAP_MAP = 3;
|
||||
static const int METALLIC_MAP = 2;
|
||||
static const int EMISSIVE_LIGHTMAP_MAP = 3;
|
||||
static const int ROUGHNESS_MAP = 4;
|
||||
static const int OCCLUSION_MAP = 5;
|
||||
|
||||
static const int LIGHT_BUFFER = 4;
|
||||
static const int NORMAL_FITTING_MAP = 10;
|
||||
};
|
||||
|
@ -206,10 +209,12 @@ public:
|
|||
class Locations {
|
||||
public:
|
||||
int texcoordMatrices;
|
||||
int diffuseTextureUnit;
|
||||
int albedoTextureUnit;
|
||||
int normalTextureUnit;
|
||||
int specularTextureUnit;
|
||||
int roughnessTextureUnit;
|
||||
int metallicTextureUnit;
|
||||
int emissiveTextureUnit;
|
||||
int occlusionTextureUnit;
|
||||
int emissiveParams;
|
||||
int normalFittingMapUnit;
|
||||
int skinClusterBufferUnit;
|
||||
|
|
|
@ -81,6 +81,11 @@ void SceneScripting::KeyLight::setAmbientSphere(const gpu::SHPointer& sphere) {
|
|||
_skyStage->setSunAmbientSphere(sphere);
|
||||
}
|
||||
|
||||
void SceneScripting::KeyLight::setAmbientMap(const gpu::TexturePointer& map) {
|
||||
_skyStage->setSunAmbientMap(map);
|
||||
}
|
||||
|
||||
|
||||
glm::vec3 SceneScripting::KeyLight::getDirection() const {
|
||||
return _skyStage->getSunDirection();
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ namespace SceneScripting {
|
|||
// AmbientTexture is unscriptable - it must be set through the zone entity
|
||||
void setAmbientSphere(const gpu::SHPointer& sphere);
|
||||
void resetAmbientSphere() { setAmbientSphere(nullptr); }
|
||||
void setAmbientMap(const gpu::TexturePointer& map);
|
||||
|
||||
protected:
|
||||
model::SunSkyStagePointer _skyStage;
|
||||
|
|
|
@ -24,5 +24,5 @@ void main(void) {
|
|||
normalize(_normal.xyz),
|
||||
1.0,
|
||||
_color.rgb,
|
||||
DEFAULT_SPECULAR, DEFAULT_SHININESS);
|
||||
DEFAULT_ROUGHNESS, DEFAULT_METALLIC, DEFAULT_EMISSIVE, DEFAULT_OCCLUSION);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ typedef TextTemplate::Block::Pointer BlockPointer;
|
|||
typedef TextTemplate::Config::Pointer ConfigPointer;
|
||||
typedef TextTemplate::Pointer TextTemplatePointer;
|
||||
|
||||
const std::string TextTemplate::Tag::NULL_VAR = "_SCRIBE_NULL";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
TextTemplate::Config::Config() :
|
||||
_includes(),
|
||||
|
@ -370,7 +372,11 @@ bool TextTemplate::convertExpressionToFuncArguments(String& src, std::vector< St
|
|||
token += c;
|
||||
} else if (c == ',') {
|
||||
if (!token.empty()) {
|
||||
arguments.push_back(token);
|
||||
if (token == Tag::NULL_VAR) {
|
||||
arguments.push_back(Tag::NULL_VAR);
|
||||
} else {
|
||||
arguments.push_back(token);
|
||||
}
|
||||
nbTokens++;
|
||||
}
|
||||
token.clear();
|
||||
|
@ -750,7 +756,9 @@ int TextTemplate::evalBlockGeneration(std::ostream& dst, const BlockPointer& blo
|
|||
paramCache.push_back((*it).second);
|
||||
(*it).second = val;
|
||||
} else {
|
||||
vars.insert(Vars::value_type(funcBlock->command.arguments[i], val));
|
||||
if (val != Tag::NULL_VAR) {
|
||||
vars.insert(Vars::value_type(funcBlock->command.arguments[i], val));
|
||||
}
|
||||
paramCache.push_back("");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ public:
|
|||
static const char VAR = '$';
|
||||
static const char COM = '@';
|
||||
static const char REM = '!';
|
||||
|
||||
static const std::string NULL_VAR;
|
||||
};
|
||||
|
||||
class Command {
|
||||
|
|
Loading…
Reference in a new issue