mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 03:13:09 +02: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
|
// Setup the current Zone Entity lighting
|
||||||
{
|
{
|
||||||
auto stage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
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() {
|
void ModelPackager::listTextures() {
|
||||||
_textures.clear();
|
_textures.clear();
|
||||||
foreach (const FBXMaterial mat, _geometry->materials) {
|
foreach (const FBXMaterial mat, _geometry->materials) {
|
||||||
if (!mat.diffuseTexture.filename.isEmpty() && mat.diffuseTexture.content.isEmpty() &&
|
if (!mat.albedoTexture.filename.isEmpty() && mat.albedoTexture.content.isEmpty() &&
|
||||||
!_textures.contains(mat.diffuseTexture.filename)) {
|
!_textures.contains(mat.albedoTexture.filename)) {
|
||||||
_textures << mat.diffuseTexture.filename;
|
_textures << mat.albedoTexture.filename;
|
||||||
}
|
}
|
||||||
if (!mat.normalTexture.filename.isEmpty() && mat.normalTexture.content.isEmpty() &&
|
if (!mat.normalTexture.filename.isEmpty() && mat.normalTexture.content.isEmpty() &&
|
||||||
!_textures.contains(mat.normalTexture.filename)) {
|
!_textures.contains(mat.normalTexture.filename)) {
|
||||||
|
|
|
@ -273,6 +273,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
||||||
|
|
||||||
if (_hasPreviousZone) {
|
if (_hasPreviousZone) {
|
||||||
sceneKeyLight->resetAmbientSphere();
|
sceneKeyLight->resetAmbientSphere();
|
||||||
|
sceneKeyLight->setAmbientMap(nullptr);
|
||||||
sceneKeyLight->setColor(_previousKeyLightColor);
|
sceneKeyLight->setColor(_previousKeyLightColor);
|
||||||
sceneKeyLight->setIntensity(_previousKeyLightIntensity);
|
sceneKeyLight->setIntensity(_previousKeyLightIntensity);
|
||||||
sceneKeyLight->setAmbientIntensity(_previousKeyLightAmbientIntensity);
|
sceneKeyLight->setAmbientIntensity(_previousKeyLightAmbientIntensity);
|
||||||
|
@ -321,10 +322,11 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
||||||
_ambientTexture.clear();
|
_ambientTexture.clear();
|
||||||
} else {
|
} else {
|
||||||
_ambientTexture = textureCache->getTexture(zone->getKeyLightProperties().getAmbientURL(), CUBE_TEXTURE);
|
_ambientTexture = textureCache->getTexture(zone->getKeyLightProperties().getAmbientURL(), CUBE_TEXTURE);
|
||||||
if (_ambientTexture->getGPUTexture()) {
|
if (_ambientTexture && _ambientTexture->isLoaded() && _ambientTexture->getGPUTexture()) {
|
||||||
_pendingAmbientTexture = false;
|
_pendingAmbientTexture = false;
|
||||||
if (_ambientTexture->getGPUTexture()->getIrradiance()) {
|
if (_ambientTexture->getGPUTexture()->getIrradiance()) {
|
||||||
sceneKeyLight->setAmbientSphere(_ambientTexture->getGPUTexture()->getIrradiance());
|
sceneKeyLight->setAmbientSphere(_ambientTexture->getGPUTexture()->getIrradiance());
|
||||||
|
sceneKeyLight->setAmbientMap(_ambientTexture->getGPUTexture());
|
||||||
isAmbientTextureSet = true;
|
isAmbientTextureSet = true;
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
// Update the Texture of the Skybox with the one pointed by this zone
|
||||||
_skyboxTexture = textureCache->getTexture(zone->getSkyboxProperties().getURL(), CUBE_TEXTURE);
|
_skyboxTexture = textureCache->getTexture(zone->getSkyboxProperties().getURL(), CUBE_TEXTURE);
|
||||||
|
|
||||||
if (_skyboxTexture->getGPUTexture()) {
|
if (_skyboxTexture && _skyboxTexture->isLoaded() && _skyboxTexture->getGPUTexture()) {
|
||||||
auto texture = _skyboxTexture->getGPUTexture();
|
auto texture = _skyboxTexture->getGPUTexture();
|
||||||
skybox->setCubemap(texture);
|
skybox->setCubemap(texture);
|
||||||
_pendingSkyboxTexture = false;
|
_pendingSkyboxTexture = false;
|
||||||
if (!isAmbientTextureSet && texture->getIrradiance()) {
|
if (!isAmbientTextureSet && texture->getIrradiance()) {
|
||||||
sceneKeyLight->setAmbientSphere(texture->getIrradiance());
|
sceneKeyLight->setAmbientSphere(texture->getIrradiance());
|
||||||
|
sceneKeyLight->setAmbientMap(texture);
|
||||||
isAmbientTextureSet = true;
|
isAmbientTextureSet = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -381,6 +384,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
||||||
|
|
||||||
if (!isAmbientTextureSet) {
|
if (!isAmbientTextureSet) {
|
||||||
sceneKeyLight->resetAmbientSphere();
|
sceneKeyLight->resetAmbientSphere();
|
||||||
|
sceneKeyLight->setAmbientMap(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<@include DeferredBufferWrite.slh@>
|
<@include DeferredBufferWrite.slh@>
|
||||||
|
|
||||||
|
|
||||||
// the diffuse texture
|
// the albedo texture
|
||||||
uniform sampler2D originalTexture;
|
uniform sampler2D originalTexture;
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
|
|
|
@ -28,9 +28,6 @@ void main(void) {
|
||||||
vec3 worldNormal = cross(dFdy(_worldPosition.xyz), dFdx(_worldPosition.xyz));
|
vec3 worldNormal = cross(dFdy(_worldPosition.xyz), dFdx(_worldPosition.xyz));
|
||||||
worldNormal = normalize(worldNormal);
|
worldNormal = normalize(worldNormal);
|
||||||
|
|
||||||
vec3 specular = DEFAULT_SPECULAR;
|
|
||||||
float shininess = DEFAULT_SHININESS;
|
|
||||||
|
|
||||||
float inPositionX = (_worldPosition.x - 0.5) / voxelVolumeSize.x;
|
float inPositionX = (_worldPosition.x - 0.5) / voxelVolumeSize.x;
|
||||||
float inPositionY = (_worldPosition.y - 0.5) / voxelVolumeSize.y;
|
float inPositionY = (_worldPosition.y - 0.5) / voxelVolumeSize.y;
|
||||||
float inPositionZ = (_worldPosition.z - 0.5) / voxelVolumeSize.z;
|
float inPositionZ = (_worldPosition.z - 0.5) / voxelVolumeSize.z;
|
||||||
|
@ -44,5 +41,5 @@ void main(void) {
|
||||||
vec3 yzDiffuseScaled = yzDiffuse.rgb * abs(worldNormal.x);
|
vec3 yzDiffuseScaled = yzDiffuse.rgb * abs(worldNormal.x);
|
||||||
vec4 diffuse = vec4(xyDiffuseScaled + xzDiffuseScaled + yzDiffuseScaled, 1.0);
|
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;
|
out vec4 _color;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// pass along the diffuse color
|
// pass along the color
|
||||||
_color = colorToLinearRGBA(inColor);
|
_color = colorToLinearRGBA(inColor);
|
||||||
|
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
|
|
|
@ -865,6 +865,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
}
|
}
|
||||||
} else if (object.name == "Material") {
|
} else if (object.name == "Material") {
|
||||||
FBXMaterial material;
|
FBXMaterial material;
|
||||||
|
if (object.properties.at(1).toByteArray().contains("StingrayPBS")) {
|
||||||
|
material.isPBSMaterial = true;
|
||||||
|
}
|
||||||
foreach (const FBXNode& subobject, object.children) {
|
foreach (const FBXNode& subobject, object.children) {
|
||||||
bool properties = false;
|
bool properties = false;
|
||||||
QByteArray propertyName;
|
QByteArray propertyName;
|
||||||
|
@ -879,7 +882,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
propertyName = "P";
|
propertyName = "P";
|
||||||
index = 4;
|
index = 4;
|
||||||
}
|
}
|
||||||
if (properties) {
|
if (!material.isPBSMaterial && properties) {
|
||||||
foreach (const FBXNode& property, subobject.children) {
|
foreach (const FBXNode& property, subobject.children) {
|
||||||
if (property.name == propertyName) {
|
if (property.name == propertyName) {
|
||||||
if (property.properties.at(0) == "DiffuseColor") {
|
if (property.properties.at(0) == "DiffuseColor") {
|
||||||
|
@ -914,6 +917,44 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
#endif
|
#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)
|
#if defined(DEBUG_FBXREADER)
|
||||||
else {
|
else {
|
||||||
|
@ -1030,18 +1071,35 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
if (connection.properties.at(0) == "OP") {
|
if (connection.properties.at(0) == "OP") {
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
QByteArray type = connection.properties.at(3).toByteArray().toLower();
|
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));
|
diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||||
|
|
||||||
} else if (type.contains("transparentcolor")) { // it should be TransparentColor...
|
} else if (type.contains("transparentcolor")) { // it should be TransparentColor...
|
||||||
// THis is how Maya assign a texture that affect diffuse color AND transparency ?
|
// 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")) {
|
} else if (type.contains("bump")) {
|
||||||
bumpTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
bumpTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||||
} else if (type.contains("normal")) {
|
} else if (type.contains("normal")) {
|
||||||
normalTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
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));
|
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") {
|
} else if (type == "lcl rotation") {
|
||||||
localRotations.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
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") {
|
} else if (type == "d|z") {
|
||||||
zComponents.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
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 {
|
} else {
|
||||||
QString typenam = type.data();
|
QString typenam = type.data();
|
||||||
counter++;
|
counter++;
|
||||||
|
|
|
@ -111,7 +111,7 @@ public:
|
||||||
QString texcoordSetName;
|
QString texcoordSetName;
|
||||||
|
|
||||||
bool isBumpmap{ false };
|
bool isBumpmap{ false };
|
||||||
|
|
||||||
bool isNull() const { return name.isEmpty() && filename.isEmpty() && content.isEmpty(); }
|
bool isNull() const { return name.isEmpty() && filename.isEmpty() && content.isEmpty(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,11 +130,10 @@ class FBXMaterial {
|
||||||
public:
|
public:
|
||||||
FBXMaterial() {};
|
FBXMaterial() {};
|
||||||
FBXMaterial(const glm::vec3& diffuseColor, const glm::vec3& specularColor, const glm::vec3& emissiveColor,
|
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),
|
diffuseColor(diffuseColor),
|
||||||
specularColor(specularColor),
|
specularColor(specularColor),
|
||||||
emissiveColor(emissiveColor),
|
emissiveColor(emissiveColor),
|
||||||
emissiveParams(emissiveParams),
|
|
||||||
shininess(shininess),
|
shininess(shininess),
|
||||||
opacity(opacity) {}
|
opacity(opacity) {}
|
||||||
|
|
||||||
|
@ -144,18 +143,39 @@ public:
|
||||||
float specularFactor = 1.0f;
|
float specularFactor = 1.0f;
|
||||||
|
|
||||||
glm::vec3 emissiveColor{ 0.0f };
|
glm::vec3 emissiveColor{ 0.0f };
|
||||||
glm::vec2 emissiveParams{ 0.0f, 1.0f };
|
|
||||||
float shininess = 23.0f;
|
float shininess = 23.0f;
|
||||||
float opacity = 1.0f;
|
float opacity = 1.0f;
|
||||||
|
|
||||||
|
float metallic{ 0.0f };
|
||||||
|
float roughness{ 1.0f };
|
||||||
|
float emissiveIntensity{ 1.0f };
|
||||||
|
|
||||||
QString materialID;
|
QString materialID;
|
||||||
model::MaterialPointer _material;
|
model::MaterialPointer _material;
|
||||||
|
|
||||||
FBXTexture diffuseTexture;
|
|
||||||
FBXTexture opacityTexture;
|
|
||||||
FBXTexture normalTexture;
|
FBXTexture normalTexture;
|
||||||
|
FBXTexture albedoTexture;
|
||||||
|
FBXTexture opacityTexture;
|
||||||
|
FBXTexture glossTexture;
|
||||||
|
FBXTexture roughnessTexture;
|
||||||
FBXTexture specularTexture;
|
FBXTexture specularTexture;
|
||||||
|
FBXTexture metallicTexture;
|
||||||
FBXTexture emissiveTexture;
|
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;
|
bool needTangentSpace() const;
|
||||||
};
|
};
|
||||||
|
@ -397,11 +417,16 @@ public:
|
||||||
|
|
||||||
|
|
||||||
QHash<QString, QString> diffuseTextures;
|
QHash<QString, QString> diffuseTextures;
|
||||||
|
QHash<QString, QString> transparentTextures;
|
||||||
QHash<QString, QString> bumpTextures;
|
QHash<QString, QString> bumpTextures;
|
||||||
QHash<QString, QString> normalTextures;
|
QHash<QString, QString> normalTextures;
|
||||||
QHash<QString, QString> specularTextures;
|
QHash<QString, QString> specularTextures;
|
||||||
|
QHash<QString, QString> metallicTextures;
|
||||||
|
QHash<QString, QString> roughnessTextures;
|
||||||
|
QHash<QString, QString> shininessTextures;
|
||||||
QHash<QString, QString> emissiveTextures;
|
QHash<QString, QString> emissiveTextures;
|
||||||
QHash<QString, QString> ambientTextures;
|
QHash<QString, QString> ambientTextures;
|
||||||
|
QHash<QString, QString> occlusionTextures;
|
||||||
|
|
||||||
QHash<QString, FBXMaterial> _fbxMaterials;
|
QHash<QString, FBXMaterial> _fbxMaterials;
|
||||||
|
|
||||||
|
|
|
@ -79,11 +79,20 @@ void FBXReader::consolidateFBXMaterials() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
material.diffuseTexture = diffuseTexture;
|
material.albedoTexture = diffuseTexture;
|
||||||
|
|
||||||
detectDifferentUVs = (diffuseTexture.texcoordSet != 0) || (!diffuseTexture.transform.isIdentity());
|
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;
|
FBXTexture normalTexture;
|
||||||
QString bumpTextureID = bumpTextures.value(material.materialID);
|
QString bumpTextureID = bumpTextures.value(material.materialID);
|
||||||
QString normalTextureID = normalTextures.value(material.materialID);
|
QString normalTextureID = normalTextures.value(material.materialID);
|
||||||
|
@ -100,37 +109,66 @@ void FBXReader::consolidateFBXMaterials() {
|
||||||
material.normalTexture = normalTexture;
|
material.normalTexture = normalTexture;
|
||||||
detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity());
|
detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FBXTexture specularTexture;
|
FBXTexture specularTexture;
|
||||||
QString specularTextureID = specularTextures.value(material.materialID);
|
QString specularTextureID = specularTextures.value(material.materialID);
|
||||||
if (!specularTextureID.isNull()) {
|
if (!specularTextureID.isNull()) {
|
||||||
specularTexture = getTexture(specularTextureID);
|
specularTexture = getTexture(specularTextureID);
|
||||||
detectDifferentUVs |= (specularTexture.texcoordSet != 0) || (!specularTexture.transform.isIdentity());
|
detectDifferentUVs |= (specularTexture.texcoordSet != 0) || (!specularTexture.transform.isIdentity());
|
||||||
|
|
||||||
material.specularTexture = specularTexture;
|
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;
|
FBXTexture emissiveTexture;
|
||||||
glm::vec2 emissiveParams(0.f, 1.f);
|
|
||||||
emissiveParams.x = _lightmapOffset;
|
|
||||||
emissiveParams.y = _lightmapLevel;
|
|
||||||
|
|
||||||
QString emissiveTextureID = emissiveTextures.value(material.materialID);
|
QString emissiveTextureID = emissiveTextures.value(material.materialID);
|
||||||
QString ambientTextureID = ambientTextures.value(material.materialID);
|
if (!emissiveTextureID.isNull()) {
|
||||||
if (_loadLightmaps && (!emissiveTextureID.isNull() || !ambientTextureID.isNull())) {
|
emissiveTexture = getTexture(emissiveTextureID);
|
||||||
|
|
||||||
if (!emissiveTextureID.isNull()) {
|
|
||||||
emissiveTexture = getTexture(emissiveTextureID);
|
|
||||||
emissiveParams.y = 4.0f;
|
|
||||||
} else if (!ambientTextureID.isNull()) {
|
|
||||||
emissiveTexture = getTexture(ambientTextureID);
|
|
||||||
}
|
|
||||||
|
|
||||||
material.emissiveParams = emissiveParams;
|
|
||||||
material.emissiveTexture = emissiveTexture;
|
|
||||||
|
|
||||||
detectDifferentUVs |= (emissiveTexture.texcoordSet != 0) || (!emissiveTexture.transform.isIdentity());
|
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
|
// Finally create the true material representation
|
||||||
|
@ -140,13 +178,16 @@ void FBXReader::consolidateFBXMaterials() {
|
||||||
auto diffuse = material.diffuseColor;
|
auto diffuse = material.diffuseColor;
|
||||||
// FIXME: Do not use the Diffuse Factor yet as some FBX models have it set to 0
|
// FIXME: Do not use the Diffuse Factor yet as some FBX models have it set to 0
|
||||||
// diffuse *= material.diffuseFactor;
|
// 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));
|
if (material.isPBSMaterial) {
|
||||||
// FIXME: Do not use the Specular Factor yet as some FBX models have it set to 0
|
material._material->setRoughness(material.roughness);
|
||||||
// metallic *= material.specularFactor;
|
material._material->setMetallic(material.metallic);
|
||||||
material._material->setMetallic(metallic);
|
} else {
|
||||||
material._material->setGloss(material.shininess);
|
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) {
|
if (material.opacity <= 0.0f) {
|
||||||
material._material->setOpacity(1.0f);
|
material._material->setOpacity(1.0f);
|
||||||
|
|
|
@ -558,7 +558,6 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
|
||||||
geometry.materials[materialID] = FBXMaterial(objMaterial.diffuseColor,
|
geometry.materials[materialID] = FBXMaterial(objMaterial.diffuseColor,
|
||||||
objMaterial.specularColor,
|
objMaterial.specularColor,
|
||||||
glm::vec3(0.0f),
|
glm::vec3(0.0f),
|
||||||
glm::vec2(0.0f, 1.0f),
|
|
||||||
objMaterial.shininess,
|
objMaterial.shininess,
|
||||||
objMaterial.opacity);
|
objMaterial.opacity);
|
||||||
FBXMaterial& fbxMaterial = geometry.materials[materialID];
|
FBXMaterial& fbxMaterial = geometry.materials[materialID];
|
||||||
|
@ -567,13 +566,13 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
|
||||||
model::MaterialPointer modelMaterial = fbxMaterial._material;
|
model::MaterialPointer modelMaterial = fbxMaterial._material;
|
||||||
|
|
||||||
if (!objMaterial.diffuseTextureFilename.isEmpty()) {
|
if (!objMaterial.diffuseTextureFilename.isEmpty()) {
|
||||||
fbxMaterial.diffuseTexture.filename = objMaterial.diffuseTextureFilename;
|
fbxMaterial.albedoTexture.filename = objMaterial.diffuseTextureFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
modelMaterial->setEmissive(fbxMaterial.emissiveColor);
|
modelMaterial->setEmissive(fbxMaterial.emissiveColor);
|
||||||
modelMaterial->setDiffuse(fbxMaterial.diffuseColor);
|
modelMaterial->setAlbedo(fbxMaterial.diffuseColor);
|
||||||
modelMaterial->setMetallic(glm::length(fbxMaterial.specularColor));
|
modelMaterial->setMetallic(glm::length(fbxMaterial.specularColor));
|
||||||
modelMaterial->setGloss(fbxMaterial.shininess);
|
modelMaterial->setRoughness(model::Material::shininessToRoughness(fbxMaterial.shininess));
|
||||||
|
|
||||||
if (fbxMaterial.opacity <= 0.0f) {
|
if (fbxMaterial.opacity <= 0.0f) {
|
||||||
modelMaterial->setOpacity(1.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) << " specularColor =" << meshPart.specularColor << "mat =" << meshPart._material->getMetallic();
|
||||||
qCDebug(modelformat) << " emissiveColor =" << meshPart.emissiveColor << "mat =" << meshPart._material->getEmissive();
|
qCDebug(modelformat) << " emissiveColor =" << meshPart.emissiveColor << "mat =" << meshPart._material->getEmissive();
|
||||||
qCDebug(modelformat) << " emissiveParams =" << meshPart.emissiveParams;
|
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) << " opacity =" << meshPart.opacity << "mat =" << meshPart._material->getOpacity();
|
||||||
*/
|
*/
|
||||||
qCDebug(modelformat) << " materialID =" << meshPart.materialID;
|
qCDebug(modelformat) << " materialID =" << meshPart.materialID;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
const Element Element::COLOR_RGBA_32{ VEC4, NUINT8, RGBA };
|
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_UV{ VEC2, FLOAT, UV };
|
||||||
const Element Element::VEC2F_XY{ VEC2, FLOAT, XY };
|
const Element Element::VEC2F_XY{ VEC2, FLOAT, XY };
|
||||||
const Element Element::VEC3F_XYZ{ VEC3, FLOAT, XYZ };
|
const Element Element::VEC3F_XYZ{ VEC3, FLOAT, XYZ };
|
||||||
|
|
|
@ -247,7 +247,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Element COLOR_RGBA_32;
|
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_UV;
|
||||||
static const Element VEC2F_XY;
|
static const Element VEC2F_XY;
|
||||||
static const Element VEC3F_XYZ;
|
static const Element VEC3F_XYZ;
|
||||||
|
|
|
@ -162,8 +162,6 @@ GLBackend::GLShader* compileShader(const Shader& shader) {
|
||||||
char* temp = new char[infoLength] ;
|
char* temp = new char[infoLength] ;
|
||||||
glGetShaderInfoLog(glshader, infoLength, NULL, temp);
|
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");
|
filestream.open("debugshader.glsl.info.txt");
|
||||||
|
@ -172,6 +170,11 @@ GLBackend::GLShader* compileShader(const Shader& shader) {
|
||||||
filestream.close();
|
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;
|
delete[] temp;
|
||||||
|
|
||||||
glDeleteShader(glshader);
|
glDeleteShader(glshader);
|
||||||
|
|
|
@ -145,6 +145,8 @@ public:
|
||||||
switch(dstFormat.getSemantic()) {
|
switch(dstFormat.getSemantic()) {
|
||||||
case gpu::RGB:
|
case gpu::RGB:
|
||||||
case gpu::RGBA:
|
case gpu::RGBA:
|
||||||
|
case gpu::SRGB:
|
||||||
|
case gpu::SRGBA:
|
||||||
texel.internalFormat = GL_RED;
|
texel.internalFormat = GL_RED;
|
||||||
switch (dstFormat.getType()) {
|
switch (dstFormat.getType()) {
|
||||||
case gpu::UINT32: {
|
case gpu::UINT32: {
|
||||||
|
@ -196,7 +198,11 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case gpu::NUINT8: {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case gpu::NINT8: {
|
case gpu::NINT8: {
|
||||||
|
@ -209,6 +215,7 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case gpu::DEPTH:
|
case gpu::DEPTH:
|
||||||
texel.format = GL_DEPTH_COMPONENT; // It's depth component to load it
|
texel.format = GL_DEPTH_COMPONENT; // It's depth component to load it
|
||||||
texel.internalFormat = GL_DEPTH_COMPONENT;
|
texel.internalFormat = GL_DEPTH_COMPONENT;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "Resource.h"
|
#include "Resource.h"
|
||||||
|
|
||||||
#include <algorithm> //min max and more
|
#include <algorithm> //min max and more
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
|
@ -139,6 +140,53 @@ protected:
|
||||||
class Texture : public Resource {
|
class Texture : public Resource {
|
||||||
public:
|
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 {
|
class Pixels {
|
||||||
public:
|
public:
|
||||||
Pixels() {}
|
Pixels() {}
|
||||||
|
@ -343,6 +391,10 @@ public:
|
||||||
|
|
||||||
bool isDefined() const { return _defined; }
|
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
|
// For Cube Texture, it's possible to generate the irradiance spherical harmonics and make them availalbe with the texture
|
||||||
bool generateIrradiance();
|
bool generateIrradiance();
|
||||||
const SHPointer& getIrradiance(uint16 slice = 0) const { return _irradiance; }
|
const SHPointer& getIrradiance(uint16 slice = 0) const { return _irradiance; }
|
||||||
|
@ -380,6 +432,8 @@ protected:
|
||||||
|
|
||||||
Type _type = TEX_1D;
|
Type _type = TEX_1D;
|
||||||
|
|
||||||
|
Usage _usage;
|
||||||
|
|
||||||
SHPointer _irradiance;
|
SHPointer _irradiance;
|
||||||
bool _autoGenerateMips = false;
|
bool _autoGenerateMips = false;
|
||||||
bool _isIrradianceValid = false;
|
bool _isIrradianceValid = false;
|
||||||
|
|
|
@ -136,10 +136,13 @@ bool NetworkGeometry::isLoadedWithTextures() const {
|
||||||
|
|
||||||
if (!_isLoadedWithTextures) {
|
if (!_isLoadedWithTextures) {
|
||||||
for (auto&& material : _materials) {
|
for (auto&& material : _materials) {
|
||||||
if ((material->diffuseTexture && !material->diffuseTexture->isLoaded()) ||
|
if ((material->albedoTexture && !material->albedoTexture->isLoaded()) ||
|
||||||
(material->normalTexture && !material->normalTexture->isLoaded()) ||
|
(material->normalTexture && !material->normalTexture->isLoaded()) ||
|
||||||
(material->specularTexture && !material->specularTexture->isLoaded()) ||
|
(material->roughnessTexture && !material->roughnessTexture->isLoaded()) ||
|
||||||
(material->emissiveTexture && !material->emissiveTexture->isLoaded())) {
|
(material->metallicTexture && !material->metallicTexture->isLoaded()) ||
|
||||||
|
(material->occlusionTexture && !material->occlusionTexture->isLoaded()) ||
|
||||||
|
(material->emissiveTexture && !material->emissiveTexture->isLoaded()) ||
|
||||||
|
(material->lightmapTexture && !material->lightmapTexture->isLoaded())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,15 +157,15 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u
|
||||||
for (auto&& material : _materials) {
|
for (auto&& material : _materials) {
|
||||||
auto networkMaterial = material->_material;
|
auto networkMaterial = material->_material;
|
||||||
auto oldTextureMaps = networkMaterial->getTextureMaps();
|
auto oldTextureMaps = networkMaterial->getTextureMaps();
|
||||||
if (material->diffuseTextureName == name) {
|
if (material->albedoTextureName == name) {
|
||||||
material->diffuseTexture = textureCache->getTexture(url, DEFAULT_TEXTURE);
|
material->albedoTexture = textureCache->getTexture(url, DEFAULT_TEXTURE);
|
||||||
|
|
||||||
auto diffuseMap = model::TextureMapPointer(new model::TextureMap());
|
auto albedoMap = model::TextureMapPointer(new model::TextureMap());
|
||||||
diffuseMap->setTextureSource(material->diffuseTexture->_textureSource);
|
albedoMap->setTextureSource(material->albedoTexture->_textureSource);
|
||||||
diffuseMap->setTextureTransform(
|
albedoMap->setTextureTransform(
|
||||||
oldTextureMaps[model::MaterialKey::DIFFUSE_MAP]->getTextureTransform());
|
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) {
|
} else if (material->normalTextureName == name) {
|
||||||
material->normalTexture = textureCache->getTexture(url);
|
material->normalTexture = textureCache->getTexture(url);
|
||||||
|
|
||||||
|
@ -170,15 +173,31 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u
|
||||||
normalMap->setTextureSource(material->normalTexture->_textureSource);
|
normalMap->setTextureSource(material->normalTexture->_textureSource);
|
||||||
|
|
||||||
networkMaterial->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap);
|
networkMaterial->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap);
|
||||||
} else if (material->specularTextureName == name) {
|
} else if (material->roughnessTextureName == name) {
|
||||||
material->specularTexture = textureCache->getTexture(url);
|
// 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());
|
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) {
|
} 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());
|
auto lightmapMap = model::TextureMapPointer(new model::TextureMap());
|
||||||
lightmapMap->setTextureSource(material->emissiveTexture->_textureSource);
|
lightmapMap->setTextureSource(material->emissiveTexture->_textureSource);
|
||||||
|
@ -200,9 +219,14 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u
|
||||||
QStringList NetworkGeometry::getTextureNames() const {
|
QStringList NetworkGeometry::getTextureNames() const {
|
||||||
QStringList result;
|
QStringList result;
|
||||||
for (auto&& material : _materials) {
|
for (auto&& material : _materials) {
|
||||||
if (!material->diffuseTextureName.isEmpty() && material->diffuseTexture) {
|
if (!material->emissiveTextureName.isEmpty() && material->emissiveTexture) {
|
||||||
QString textureURL = material->diffuseTexture->getURL().toString();
|
QString textureURL = material->emissiveTexture->getURL().toString();
|
||||||
result << material->diffuseTextureName + ":\"" + textureURL + "\"";
|
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) {
|
if (!material->normalTextureName.isEmpty() && material->normalTexture) {
|
||||||
|
@ -210,14 +234,24 @@ QStringList NetworkGeometry::getTextureNames() const {
|
||||||
result << material->normalTextureName + ":\"" + textureURL + "\"";
|
result << material->normalTextureName + ":\"" + textureURL + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!material->specularTextureName.isEmpty() && material->specularTexture) {
|
if (!material->roughnessTextureName.isEmpty() && material->roughnessTexture) {
|
||||||
QString textureURL = material->specularTexture->getURL().toString();
|
QString textureURL = material->roughnessTexture->getURL().toString();
|
||||||
result << material->specularTextureName + ":\"" + textureURL + "\"";
|
result << material->roughnessTextureName + ":\"" + textureURL + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!material->emissiveTextureName.isEmpty() && material->emissiveTexture) {
|
if (!material->metallicTextureName.isEmpty() && material->metallicTexture) {
|
||||||
QString textureURL = material->emissiveTexture->getURL().toString();
|
QString textureURL = material->metallicTexture->getURL().toString();
|
||||||
result << material->emissiveTextureName + ":\"" + textureURL + "\"";
|
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;
|
return networkMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
static model::TextureMapPointer setupNetworkTextureMap(const QUrl& textureBaseUrl,
|
|
||||||
|
static model::TextureMapPointer setupNetworkTextureMap(NetworkGeometry* geometry, const QUrl& textureBaseUrl,
|
||||||
const FBXTexture& texture, TextureType type,
|
const FBXTexture& texture, TextureType type,
|
||||||
NetworkTexturePointer& networkTexture, QString& networkTextureName) {
|
NetworkTexturePointer& networkTexture, QString& networkTextureName) {
|
||||||
auto textureCache = DependencyManager::get<TextureCache>();
|
auto textureCache = DependencyManager::get<TextureCache>();
|
||||||
|
@ -314,6 +349,7 @@ static model::TextureMapPointer setupNetworkTextureMap(const QUrl& textureBaseUr
|
||||||
const auto filename = baseUrl.resolved(QUrl(texture.filename));
|
const auto filename = baseUrl.resolved(QUrl(texture.filename));
|
||||||
|
|
||||||
networkTexture = textureCache->getTexture(filename, type, texture.content);
|
networkTexture = textureCache->getTexture(filename, type, texture.content);
|
||||||
|
QObject::connect(networkTexture.data(), &NetworkTexture::networkTextureCreated, geometry, &NetworkGeometry::textureLoaded);
|
||||||
networkTextureName = texture.name;
|
networkTextureName = texture.name;
|
||||||
|
|
||||||
auto map = std::make_shared<model::TextureMap>();
|
auto map = std::make_shared<model::TextureMap>();
|
||||||
|
@ -321,33 +357,66 @@ static model::TextureMapPointer setupNetworkTextureMap(const QUrl& textureBaseUr
|
||||||
return map;
|
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* networkMaterial = new NetworkMaterial();
|
||||||
networkMaterial->_material = material._material;
|
networkMaterial->_material = material._material;
|
||||||
|
|
||||||
if (!material.diffuseTexture.filename.isEmpty()) {
|
if (!material.albedoTexture.filename.isEmpty()) {
|
||||||
auto diffuseMap = setupNetworkTextureMap(textureBaseUrl, material.diffuseTexture, DEFAULT_TEXTURE,
|
auto albedoMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.albedoTexture, DEFAULT_TEXTURE,
|
||||||
networkMaterial->diffuseTexture, networkMaterial->diffuseTextureName);
|
networkMaterial->albedoTexture, networkMaterial->albedoTextureName);
|
||||||
diffuseMap->setTextureTransform(material.diffuseTexture.transform);
|
albedoMap->setTextureTransform(material.albedoTexture.transform);
|
||||||
networkMaterial->_material->setTextureMap(model::MaterialKey::DIFFUSE_MAP, diffuseMap);
|
material._material->setTextureMap(model::MaterialKey::ALBEDO_MAP, albedoMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!material.normalTexture.filename.isEmpty()) {
|
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),
|
(material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE),
|
||||||
networkMaterial->normalTexture, networkMaterial->normalTextureName);
|
networkMaterial->normalTexture, networkMaterial->normalTextureName);
|
||||||
networkMaterial->_material->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap);
|
networkMaterial->_material->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap);
|
||||||
}
|
}
|
||||||
if (!material.specularTexture.filename.isEmpty()) {
|
|
||||||
auto glossMap = setupNetworkTextureMap(textureBaseUrl, material.specularTexture, SPECULAR_TEXTURE,
|
// Roughness first or gloss maybe
|
||||||
networkMaterial->specularTexture, networkMaterial->specularTextureName);
|
if (!material.roughnessTexture.filename.isEmpty()) {
|
||||||
networkMaterial->_material->setTextureMap(model::MaterialKey::GLOSS_MAP, glossMap);
|
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()) {
|
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);
|
networkMaterial->emissiveTexture, networkMaterial->emissiveTextureName);
|
||||||
lightmapMap->setTextureTransform(material.emissiveTexture.transform);
|
material._material->setTextureMap(model::MaterialKey::EMISSIVE_MAP, emissiveMap);
|
||||||
lightmapMap->setLightmapOffsetScale(material.emissiveParams.x, material.emissiveParams.y);
|
}
|
||||||
networkMaterial->_material->setTextureMap(model::MaterialKey::LIGHTMAP_MAP, lightmapMap);
|
|
||||||
|
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;
|
return networkMaterial;
|
||||||
|
@ -367,7 +436,7 @@ void NetworkGeometry::modelParseSuccess(FBXGeometry* geometry) {
|
||||||
QHash<QString, size_t> fbxMatIDToMatID;
|
QHash<QString, size_t> fbxMatIDToMatID;
|
||||||
foreach(const FBXMaterial& material, _geometry->materials) {
|
foreach(const FBXMaterial& material, _geometry->materials) {
|
||||||
fbxMatIDToMatID[material.materialID] = _materials.size();
|
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.
|
// Fired when something went wrong.
|
||||||
void onFailure(NetworkGeometry& networkGeometry, Error error);
|
void onFailure(NetworkGeometry& networkGeometry, Error error);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void textureLoaded(const QWeakPointer<NetworkTexture>& networkTexture);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void mappingRequestDone(const QByteArray& data);
|
void mappingRequestDone(const QByteArray& data);
|
||||||
void mappingRequestError(QNetworkReply::NetworkError error);
|
void mappingRequestError(QNetworkReply::NetworkError error);
|
||||||
|
@ -115,6 +118,7 @@ protected slots:
|
||||||
void modelParseSuccess(FBXGeometry* geometry);
|
void modelParseSuccess(FBXGeometry* geometry);
|
||||||
void modelParseError(int error, QString str);
|
void modelParseError(int error, QString str);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void attemptRequestInternal();
|
void attemptRequestInternal();
|
||||||
void requestMapping(const QUrl& url);
|
void requestMapping(const QUrl& url);
|
||||||
|
@ -133,6 +137,7 @@ protected:
|
||||||
QUrl _modelUrl;
|
QUrl _modelUrl;
|
||||||
QVariantHash _mapping;
|
QVariantHash _mapping;
|
||||||
QUrl _textureBaseUrl;
|
QUrl _textureBaseUrl;
|
||||||
|
int numTextureLoaded = 0;
|
||||||
|
|
||||||
Resource* _resource = nullptr;
|
Resource* _resource = nullptr;
|
||||||
std::unique_ptr<FBXGeometry> _geometry; // This should go away evenutally once we can put everything we need in the model::AssetPointer
|
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 {
|
class NetworkMaterial {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
model::MaterialPointer _material;
|
model::MaterialPointer _material;
|
||||||
QString diffuseTextureName;
|
|
||||||
QSharedPointer<NetworkTexture> diffuseTexture;
|
|
||||||
QString normalTextureName;
|
|
||||||
QSharedPointer<NetworkTexture> normalTexture;
|
|
||||||
QString specularTextureName;
|
|
||||||
QSharedPointer<NetworkTexture> specularTexture;
|
|
||||||
QString emissiveTextureName;
|
QString emissiveTextureName;
|
||||||
QSharedPointer<NetworkTexture> emissiveTexture;
|
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);
|
return TextureLoaderFunc(model::TextureUsage::createNormalTextureFromNormalImage);
|
||||||
break;
|
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: {
|
case CUSTOM_TEXTURE: {
|
||||||
return _textureLoader;
|
return _textureLoader;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DEFAULT_TEXTURE:
|
case DEFAULT_TEXTURE:
|
||||||
case SPECULAR_TEXTURE:
|
|
||||||
case EMISSIVE_TEXTURE:
|
case EMISSIVE_TEXTURE:
|
||||||
default: {
|
default: {
|
||||||
return TextureLoaderFunc(model::TextureUsage::create2DTextureFromImage);
|
return TextureLoaderFunc(model::TextureUsage::create2DTextureFromImage);
|
||||||
|
@ -335,10 +346,6 @@ void NetworkTexture::setImage(const QImage& image, void* voidTexture, int origin
|
||||||
|
|
||||||
finishedLoading(true);
|
finishedLoading(true);
|
||||||
|
|
||||||
imageLoaded(image);
|
emit networkTextureCreated(qWeakPointerCast<NetworkTexture, Resource> (_self));
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkTexture::imageLoaded(const QImage& image) {
|
|
||||||
// nothing by default
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,20 @@ class NetworkTexture;
|
||||||
|
|
||||||
typedef QSharedPointer<NetworkTexture> NetworkTexturePointer;
|
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.
|
/// Stores cached textures, including render-to-texture targets.
|
||||||
class TextureCache : public ResourceCache, public Dependency {
|
class TextureCache : public ResourceCache, public Dependency {
|
||||||
|
@ -83,8 +96,6 @@ private:
|
||||||
gpu::TexturePointer _blueTexture;
|
gpu::TexturePointer _blueTexture;
|
||||||
gpu::TexturePointer _blackTexture;
|
gpu::TexturePointer _blackTexture;
|
||||||
gpu::TexturePointer _normalFittingTexture;
|
gpu::TexturePointer _normalFittingTexture;
|
||||||
|
|
||||||
QHash<QUrl, QWeakPointer<NetworkTexture> > _dilatableNetworkTextures;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A simple object wrapper for an OpenGL texture.
|
/// A simple object wrapper for an OpenGL texture.
|
||||||
|
@ -114,7 +125,11 @@ public:
|
||||||
int getHeight() const { return _height; }
|
int getHeight() const { return _height; }
|
||||||
|
|
||||||
TextureLoaderFunc getTextureLoader() const;
|
TextureLoaderFunc getTextureLoader() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void networkTextureCreated(const QWeakPointer<NetworkTexture>& self);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void downloadFinished(const QByteArray& data) override;
|
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...
|
// 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);
|
Q_INVOKABLE void setImage(const QImage& image, void* texture, int originalWidth, int originalHeight);
|
||||||
|
|
||||||
virtual void imageLoaded(const QImage& image);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextureType _type;
|
TextureType _type;
|
||||||
|
|
|
@ -130,7 +130,7 @@ void Light::setShowContour(float show) {
|
||||||
if (show <= 0.f) {
|
if (show <= 0.f) {
|
||||||
show = 0.0f;
|
show = 0.0f;
|
||||||
}
|
}
|
||||||
editSchema()._control.w = show;
|
editSchema()._control.z = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Light::setAmbientSphere(const gpu::SphericalHarmonics& sphere) {
|
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) {
|
void Light::setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) {
|
||||||
editSchema()._ambientSphere.assignPreset(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.
|
// 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
|
// Set to non 0 to show it, the value is used as the intensity of the contour color
|
||||||
void setShowContour(float show);
|
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
|
// 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);
|
void setAmbientIntensity(float intensity);
|
||||||
|
@ -108,6 +108,12 @@ public:
|
||||||
const gpu::SphericalHarmonics& getAmbientSphere() const { return getSchema()._ambientSphere; }
|
const gpu::SphericalHarmonics& getAmbientSphere() const { return getSchema()._ambientSphere; }
|
||||||
void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset);
|
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
|
// Schema to access the attribute values of the light
|
||||||
class Schema {
|
class Schema {
|
||||||
public:
|
public:
|
||||||
|
@ -120,7 +126,8 @@ public:
|
||||||
Vec4 _spot{0.0f, 0.0f, 0.0f, 0.0f};
|
Vec4 _spot{0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
Vec4 _shadow{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;
|
gpu::SphericalHarmonics _ambientSphere;
|
||||||
};
|
};
|
||||||
|
@ -133,6 +140,8 @@ protected:
|
||||||
UniformBufferView _schemaBuffer;
|
UniformBufferView _schemaBuffer;
|
||||||
Transform _transform;
|
Transform _transform;
|
||||||
|
|
||||||
|
gpu::TexturePointer _ambientMap;
|
||||||
|
|
||||||
const Schema& getSchema() const { return _schemaBuffer.get<Schema>(); }
|
const Schema& getSchema() const { return _schemaBuffer.get<Schema>(); }
|
||||||
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }
|
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,10 @@ SphericalHarmonics getLightAmbientSphere(Light l) {
|
||||||
return l._ambientSphere;
|
return l._ambientSphere;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float getLightAmbientMapNumMips(Light l) {
|
||||||
|
return l._control.x;
|
||||||
|
}
|
||||||
|
|
||||||
<@if GPU_FEATURE_PROFILE == GPU_CORE @>
|
<@if GPU_FEATURE_PROFILE == GPU_CORE @>
|
||||||
uniform lightBuffer {
|
uniform lightBuffer {
|
||||||
Light light;
|
Light light;
|
||||||
|
|
|
@ -44,37 +44,51 @@ Material& Material::operator= (const Material& material) {
|
||||||
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) {
|
void Material::setEmissive(const Color& emissive, bool isSRGB) {
|
||||||
_key.setEmissive(glm::any(glm::greaterThan(emissive, Color(0.0f))));
|
_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);
|
_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) {
|
void Material::setOpacity(float opacity) {
|
||||||
_key.setTransparent((opacity < 1.0f));
|
_key.setTransparent((opacity < 1.0f));
|
||||||
|
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||||
_schemaBuffer.edit<Schema>()._opacity = opacity;
|
_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) {
|
void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) {
|
||||||
if (textureMap) {
|
if (textureMap) {
|
||||||
_key.setMapChannel(channel, (true));
|
_key.setMapChannel(channel, (true));
|
||||||
|
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||||
_textureMaps[channel] = textureMap;
|
_textureMaps[channel] = textureMap;
|
||||||
} else {
|
} else {
|
||||||
_key.setMapChannel(channel, (false));
|
_key.setMapChannel(channel, (false));
|
||||||
|
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||||
_textureMaps.erase(channel);
|
_textureMaps.erase(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,17 +28,18 @@ class MaterialKey {
|
||||||
public:
|
public:
|
||||||
enum FlagBit {
|
enum FlagBit {
|
||||||
EMISSIVE_VAL_BIT = 0,
|
EMISSIVE_VAL_BIT = 0,
|
||||||
DIFFUSE_VAL_BIT,
|
ALBEDO_VAL_BIT,
|
||||||
METALLIC_VAL_BIT,
|
METALLIC_VAL_BIT,
|
||||||
GLOSS_VAL_BIT,
|
GLOSSY_VAL_BIT,
|
||||||
TRANSPARENT_VAL_BIT,
|
TRANSPARENT_VAL_BIT,
|
||||||
|
|
||||||
EMISSIVE_MAP_BIT,
|
EMISSIVE_MAP_BIT,
|
||||||
DIFFUSE_MAP_BIT,
|
ALBEDO_MAP_BIT,
|
||||||
METALLIC_MAP_BIT,
|
METALLIC_MAP_BIT,
|
||||||
GLOSS_MAP_BIT,
|
ROUGHNESS_MAP_BIT,
|
||||||
TRANSPARENT_MAP_BIT,
|
TRANSPARENT_MAP_BIT,
|
||||||
NORMAL_MAP_BIT,
|
NORMAL_MAP_BIT,
|
||||||
|
OCCLUSION_MAP_BIT,
|
||||||
LIGHTMAP_MAP_BIT,
|
LIGHTMAP_MAP_BIT,
|
||||||
|
|
||||||
NUM_FLAGS,
|
NUM_FLAGS,
|
||||||
|
@ -47,11 +48,12 @@ public:
|
||||||
|
|
||||||
enum MapChannel {
|
enum MapChannel {
|
||||||
EMISSIVE_MAP = 0,
|
EMISSIVE_MAP = 0,
|
||||||
DIFFUSE_MAP,
|
ALBEDO_MAP,
|
||||||
METALLIC_MAP,
|
METALLIC_MAP,
|
||||||
GLOSS_MAP,
|
ROUGHNESS_MAP,
|
||||||
TRANSPARENT_MAP,
|
TRANSPARENT_MAP,
|
||||||
NORMAL_MAP,
|
NORMAL_MAP,
|
||||||
|
OCCLUSION_MAP,
|
||||||
LIGHTMAP_MAP,
|
LIGHTMAP_MAP,
|
||||||
|
|
||||||
NUM_MAP_CHANNELS,
|
NUM_MAP_CHANNELS,
|
||||||
|
@ -71,22 +73,23 @@ public:
|
||||||
MaterialKey build() const { return MaterialKey(_flags); }
|
MaterialKey build() const { return MaterialKey(_flags); }
|
||||||
|
|
||||||
Builder& withEmissive() { _flags.set(EMISSIVE_VAL_BIT); return (*this); }
|
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& 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& withTransparent() { _flags.set(TRANSPARENT_VAL_BIT); return (*this); }
|
||||||
|
|
||||||
Builder& withEmissiveMap() { _flags.set(EMISSIVE_MAP_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& 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& withTransparentMap() { _flags.set(TRANSPARENT_MAP_BIT); return (*this); }
|
||||||
|
|
||||||
Builder& withNormalMap() { _flags.set(NORMAL_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); }
|
Builder& withLightmapMap() { _flags.set(LIGHTMAP_MAP_BIT); return (*this); }
|
||||||
|
|
||||||
// Convenient standard keys that we will keep on using all over the place
|
// 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); }
|
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); }
|
void setEmissiveMap(bool value) { _flags.set(EMISSIVE_MAP_BIT, value); }
|
||||||
bool isEmissiveMap() const { return _flags[EMISSIVE_MAP_BIT]; }
|
bool isEmissiveMap() const { return _flags[EMISSIVE_MAP_BIT]; }
|
||||||
|
|
||||||
void setDiffuse(bool value) { _flags.set(DIFFUSE_VAL_BIT, value); }
|
void setAlbedo(bool value) { _flags.set(ALBEDO_VAL_BIT, value); }
|
||||||
bool isDiffuse() const { return _flags[DIFFUSE_VAL_BIT]; }
|
bool isAlbedo() const { return _flags[ALBEDO_VAL_BIT]; }
|
||||||
|
|
||||||
void setDiffuseMap(bool value) { _flags.set(DIFFUSE_MAP_BIT, value); }
|
void setAlbedoMap(bool value) { _flags.set(ALBEDO_MAP_BIT, value); }
|
||||||
bool isDiffuseMap() const { return _flags[DIFFUSE_MAP_BIT]; }
|
bool isAlbedoMap() const { return _flags[ALBEDO_MAP_BIT]; }
|
||||||
|
|
||||||
void setMetallic(bool value) { _flags.set(METALLIC_VAL_BIT, value); }
|
void setMetallic(bool value) { _flags.set(METALLIC_VAL_BIT, value); }
|
||||||
bool isMetallic() const { return _flags[METALLIC_VAL_BIT]; }
|
bool isMetallic() const { return _flags[METALLIC_VAL_BIT]; }
|
||||||
|
@ -107,11 +110,12 @@ public:
|
||||||
void setMetallicMap(bool value) { _flags.set(METALLIC_MAP_BIT, value); }
|
void setMetallicMap(bool value) { _flags.set(METALLIC_MAP_BIT, value); }
|
||||||
bool isMetallicMap() const { return _flags[METALLIC_MAP_BIT]; }
|
bool isMetallicMap() const { return _flags[METALLIC_MAP_BIT]; }
|
||||||
|
|
||||||
void setGloss(bool value) { _flags.set(GLOSS_VAL_BIT, value); }
|
void setGlossy(bool value) { _flags.set(GLOSSY_VAL_BIT, value); }
|
||||||
bool isGloss() const { return _flags[GLOSS_VAL_BIT]; }
|
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); }
|
void setRoughnessMap(bool value) { _flags.set(ROUGHNESS_MAP_BIT, value); }
|
||||||
bool isGlossMap() const { return _flags[GLOSS_MAP_BIT]; }
|
bool isRoughnessMap() const { return _flags[ROUGHNESS_MAP_BIT]; }
|
||||||
|
|
||||||
void setTransparent(bool value) { _flags.set(TRANSPARENT_VAL_BIT, value); }
|
void setTransparent(bool value) { _flags.set(TRANSPARENT_VAL_BIT, value); }
|
||||||
bool isTransparent() const { return _flags[TRANSPARENT_VAL_BIT]; }
|
bool isTransparent() const { return _flags[TRANSPARENT_VAL_BIT]; }
|
||||||
|
@ -123,6 +127,9 @@ public:
|
||||||
void setNormalMap(bool value) { _flags.set(NORMAL_MAP_BIT, value); }
|
void setNormalMap(bool value) { _flags.set(NORMAL_MAP_BIT, value); }
|
||||||
bool isNormalMap() const { return _flags[NORMAL_MAP_BIT]; }
|
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); }
|
void setLightmapMap(bool value) { _flags.set(LIGHTMAP_MAP_BIT, value); }
|
||||||
bool isLightmapMap() const { return _flags[LIGHTMAP_MAP_BIT]; }
|
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& 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& 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& withoutAlbedo() { _value.reset(MaterialKey::ALBEDO_VAL_BIT); _mask.set(MaterialKey::ALBEDO_VAL_BIT); return (*this); }
|
||||||
Builder& withDiffuse() { _value.set(MaterialKey::DIFFUSE_VAL_BIT); _mask.set(MaterialKey::DIFFUSE_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& withoutAlbedoMap() { _value.reset(MaterialKey::ALBEDO_MAP_BIT); _mask.set(MaterialKey::ALBEDO_MAP_BIT); return (*this); }
|
||||||
Builder& withDiffuseMap() { _value.set(MaterialKey::DIFFUSE_MAP_BIT); _mask.set(MaterialKey::DIFFUSE_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& 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); }
|
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& 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& 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& withoutGlossy() { _value.reset(MaterialKey::GLOSSY_VAL_BIT); _mask.set(MaterialKey::GLOSSY_VAL_BIT); return (*this); }
|
||||||
Builder& withGloss() { _value.set(MaterialKey::GLOSS_VAL_BIT); _mask.set(MaterialKey::GLOSS_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& withoutRoughnessMap() { _value.reset(MaterialKey::ROUGHNESS_MAP_BIT); _mask.set(MaterialKey::ROUGHNESS_MAP_BIT); return (*this); }
|
||||||
Builder& withGlossMap() { _value.set(MaterialKey::GLOSS_MAP_BIT); _mask.set(MaterialKey::GLOSS_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& 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); }
|
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& 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& 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& 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); }
|
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
|
// 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
|
// Item Filter operator testing if a key pass the filter
|
||||||
|
@ -223,29 +233,39 @@ public:
|
||||||
void setEmissive(const Color& emissive, bool isSRGB = true);
|
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); }
|
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);
|
void setOpacity(float opacity);
|
||||||
float getOpacity() const { return _schemaBuffer.get<Schema>()._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
|
// Schema to access the attribute values of the material
|
||||||
class Schema {
|
class Schema {
|
||||||
public:
|
public:
|
||||||
|
glm::vec3 _emissive{ 0.0f }; // No Emissive
|
||||||
glm::vec3 _diffuse{ 0.5f };
|
float _opacity{ 1.0f }; // Opacity = 1 => Not Transparent
|
||||||
float _opacity{1.f};
|
|
||||||
glm::vec3 _metallic{ 0.03f };
|
glm::vec3 _albedo{ 0.5f }; // Grey albedo => isAlbedo
|
||||||
float _gloss{0.1f};
|
float _roughness{ 1.0f }; // Roughness = 1 => Not Glossy
|
||||||
glm::vec3 _emissive{ 0.0f };
|
|
||||||
float _spare0{0.0f};
|
glm::vec3 _fresnel{ 0.03f }; // Fresnel value for a default non metallic
|
||||||
glm::vec4 _spareVec4{0.0f}; // for alignment beauty, Material size == Mat4x4
|
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() {}
|
Schema() {}
|
||||||
};
|
};
|
||||||
|
@ -256,6 +276,9 @@ public:
|
||||||
void setTextureMap(MapChannel channel, const TextureMapPointer& textureMap);
|
void setTextureMap(MapChannel channel, const TextureMapPointer& textureMap);
|
||||||
const TextureMaps& getTextureMaps() const { return _textureMaps; }
|
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:
|
protected:
|
||||||
|
|
||||||
MaterialKey _key;
|
MaterialKey _key;
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
<@def MODEL_MATERIAL_SLH@>
|
<@def MODEL_MATERIAL_SLH@>
|
||||||
|
|
||||||
struct Material {
|
struct Material {
|
||||||
vec4 _diffuse;
|
vec4 _emissiveOpacity;
|
||||||
vec4 _specular;
|
vec4 _albedoRoughness;
|
||||||
vec4 _emissive;
|
vec4 _fresnelMetallic;
|
||||||
vec4 _spare;
|
vec4 _spare;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,41 +26,36 @@ Material getMaterial() {
|
||||||
return _mat;
|
return _mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
<! // TODO: use this code for correct gamma correction
|
vec3 getMaterialEmissive(Material m) { return m._emissiveOpacity.rgb; }
|
||||||
/*
|
float getMaterialOpacity(Material m) { return m._emissiveOpacity.a; }
|
||||||
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;
|
|
||||||
|
|
||||||
if (cs > T) {
|
vec3 getMaterialAlbedo(Material m) { return m._albedoRoughness.rgb; }
|
||||||
return pow((cs * A + B), G);
|
float getMaterialRoughness(Material m) { return m._albedoRoughness.a; }
|
||||||
} else {
|
|
||||||
return cs * C;
|
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@>
|
<@endif@>
|
||||||
|
|
|
@ -212,6 +212,9 @@ void SunSkyStage::setSunAmbientSphere(const gpu::SHPointer& sphere) {
|
||||||
_sunLight->setAmbientSpherePreset(DEFAULT_AMBIENT_SPHERE);
|
_sunLight->setAmbientSpherePreset(DEFAULT_AMBIENT_SPHERE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void SunSkyStage::setSunAmbientMap(const gpu::TexturePointer& map) {
|
||||||
|
_sunLight->setAmbientMap(map);
|
||||||
|
}
|
||||||
|
|
||||||
void SunSkyStage::setSunDirection(const Vec3& direction) {
|
void SunSkyStage::setSunDirection(const Vec3& direction) {
|
||||||
if (!isSunModelEnabled()) {
|
if (!isSunModelEnabled()) {
|
||||||
|
|
|
@ -150,6 +150,7 @@ public:
|
||||||
void setSunAmbientIntensity(float intensity) { _sunLight->setAmbientIntensity(intensity); }
|
void setSunAmbientIntensity(float intensity) { _sunLight->setAmbientIntensity(intensity); }
|
||||||
float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); }
|
float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); }
|
||||||
void setSunAmbientSphere(const gpu::SHPointer& sphere);
|
void setSunAmbientSphere(const gpu::SHPointer& sphere);
|
||||||
|
void setSunAmbientMap(const gpu::TexturePointer& map);
|
||||||
|
|
||||||
// The sun direction is expressed in the world space
|
// The sun direction is expressed in the world space
|
||||||
void setSunDirection(const Vec3& direction);
|
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) {
|
gpu::Texture* TextureUsage::create2DTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||||
QImage image = srcImage;
|
QImage image = srcImage;
|
||||||
bool validAlpha = false;
|
bool validAlpha = false;
|
||||||
|
bool alphaAsMask = true;
|
||||||
|
const uint8 OPAQUE_ALPHA = 255;
|
||||||
|
const uint8 TRANSLUCENT_ALPHA = 0;
|
||||||
if (image.hasAlphaChannel()) {
|
if (image.hasAlphaChannel()) {
|
||||||
|
std::map<uint8, uint32> alphaHistogram;
|
||||||
|
|
||||||
if (image.format() != QImage::Format_ARGB32) {
|
if (image.format() != QImage::Format_ARGB32) {
|
||||||
image = image.convertToFormat(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) {
|
for (int y = 0; y < image.height(); ++y) {
|
||||||
const QRgb* data = reinterpret_cast<const QRgb*>(image.constScanLine(y));
|
const QRgb* data = reinterpret_cast<const QRgb*>(image.constScanLine(y));
|
||||||
for (int x = 0; x < image.width(); ++x) {
|
for (int x = 0; x < image.width(); ++x) {
|
||||||
auto alpha = qAlpha(data[x]);
|
auto alpha = qAlpha(data[x]);
|
||||||
if (alpha != 255) {
|
alphaHistogram[alpha] ++;
|
||||||
|
if (alpha != OPAQUE_ALPHA) {
|
||||||
validAlpha = true;
|
validAlpha = true;
|
||||||
break;
|
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) {
|
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)));
|
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->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||||
theTexture->autoGenerateMips(-1);
|
theTexture->autoGenerateMips(-1);
|
||||||
|
|
||||||
// FIXME queue for transfer to GPU and block on completion
|
// FIXME queue for transfer to GPU and block on completion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return theTexture;
|
return theTexture;
|
||||||
|
@ -223,6 +250,99 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm
|
||||||
return theTexture;
|
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 {
|
class CubeLayout {
|
||||||
public:
|
public:
|
||||||
int _widthRatio = 1;
|
int _widthRatio = 1;
|
||||||
|
@ -473,8 +593,8 @@ gpu::Texture* TextureUsage::createCubeTextureFromImage(const QImage& srcImage, c
|
||||||
theTexture->assignStoredMipFace(0, formatMip, face.byteCount(), face.constBits(), f);
|
theTexture->assignStoredMipFace(0, formatMip, face.byteCount(), face.constBits(), f);
|
||||||
f++;
|
f++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GEnerate irradiance while we are at it
|
// Generate irradiance while we are at it
|
||||||
theTexture->generateIrradiance();
|
theTexture->generateIrradiance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,16 @@ typedef glm::vec3 Color;
|
||||||
class TextureUsage {
|
class TextureUsage {
|
||||||
public:
|
public:
|
||||||
gpu::Texture::Type _type{ gpu::Texture::TEX_2D };
|
gpu::Texture::Type _type{ gpu::Texture::TEX_2D };
|
||||||
Material::MapFlags _materialUsage{ MaterialKey::DIFFUSE_MAP };
|
Material::MapFlags _materialUsage{ MaterialKey::ALBEDO_MAP };
|
||||||
|
|
||||||
int _environmentUsage = 0;
|
int _environmentUsage = 0;
|
||||||
|
|
||||||
static gpu::Texture* create2DTextureFromImage(const QImage& image, const std::string& srcImageName);
|
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* createNormalTextureFromNormalImage(const QImage& image, const std::string& srcImageName);
|
||||||
static gpu::Texture* createNormalTextureFromBumpImage(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* createCubeTextureFromImage(const QImage& image, const std::string& srcImageName);
|
||||||
static gpu::Texture* createLightmapTextureFromImage(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 "GeometryCache.h"
|
||||||
#include "FramebufferCache.h"
|
#include "FramebufferCache.h"
|
||||||
|
#include "TextureCache.h"
|
||||||
#include "DeferredLightingEffect.h"
|
#include "DeferredLightingEffect.h"
|
||||||
|
|
||||||
#include "debug_deferred_buffer_vert.h"
|
#include "debug_deferred_buffer_vert.h"
|
||||||
|
@ -39,7 +40,7 @@ void DebugDeferredBufferConfig::setMode(int newMode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Slot {
|
enum Slot {
|
||||||
Diffuse = 0,
|
Albedo = 0,
|
||||||
Normal,
|
Normal,
|
||||||
Specular,
|
Specular,
|
||||||
Depth,
|
Depth,
|
||||||
|
@ -52,27 +53,54 @@ enum Slot {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const std::string DEFAULT_DIFFUSE_SHADER {
|
static const std::string DEFAULT_ALBEDO_SHADER {
|
||||||
"vec4 getFragmentColor() {"
|
"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() {"
|
"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 {
|
static const std::string DEFAULT_ROUGHNESS_SHADER {
|
||||||
"vec4 getFragmentColor() {"
|
"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 {
|
static const std::string DEFAULT_NORMAL_SHADER {
|
||||||
"vec4 getFragmentColor() {"
|
"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 {
|
static const std::string DEFAULT_DEPTH_SHADER {
|
||||||
"vec4 getFragmentColor() {"
|
"vec4 getFragmentColor() {"
|
||||||
" return vec4(vec3(texture(depthMap, uv).x), 1.0);"
|
" 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{
|
static const std::string DEFAULT_AMBIENT_OCCLUSION_SHADER{
|
||||||
"vec4 getFragmentColor() {"
|
"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 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);"
|
// 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) {
|
std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string customFile) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case DiffuseMode:
|
case AlbedoMode:
|
||||||
return DEFAULT_DIFFUSE_SHADER;
|
return DEFAULT_ALBEDO_SHADER;
|
||||||
case SpecularMode:
|
case MetallicMode:
|
||||||
return DEFAULT_SPECULAR_SHADER;
|
return DEFAULT_METALLIC_SHADER;
|
||||||
case RoughnessMode:
|
case RoughnessMode:
|
||||||
return DEFAULT_ROUGHNESS_SHADER;
|
return DEFAULT_ROUGHNESS_SHADER;
|
||||||
case NormalMode:
|
case NormalMode:
|
||||||
return DEFAULT_NORMAL_SHADER;
|
return DEFAULT_NORMAL_SHADER;
|
||||||
case DepthMode:
|
case DepthMode:
|
||||||
return DEFAULT_DEPTH_SHADER;
|
return DEFAULT_DEPTH_SHADER;
|
||||||
|
case EmissiveMode:
|
||||||
|
return DEFAULT_EMISSIVE_SHADER;
|
||||||
|
case OcclusionMode:
|
||||||
|
return DEFAULT_OCCLUSION_SHADER;
|
||||||
|
case LightmapMode:
|
||||||
|
return DEFAULT_LIGHTMAP_SHADER;
|
||||||
case LightingMode:
|
case LightingMode:
|
||||||
return DEFAULT_LIGHTING_SHADER;
|
return DEFAULT_LIGHTING_SHADER;
|
||||||
case ShadowMode:
|
case ShadowMode:
|
||||||
|
@ -206,14 +240,14 @@ const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::str
|
||||||
const auto program = gpu::Shader::createProgram(vs, ps);
|
const auto program = gpu::Shader::createProgram(vs, ps);
|
||||||
|
|
||||||
gpu::Shader::BindingSet slotBindings;
|
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("normalMap", Normal));
|
||||||
slotBindings.insert(gpu::Shader::Binding("specularMap", Specular));
|
slotBindings.insert(gpu::Shader::Binding("specularMap", Specular));
|
||||||
slotBindings.insert(gpu::Shader::Binding("depthMap", Depth));
|
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("lightingMap", Lighting));
|
||||||
slotBindings.insert(gpu::Shader::Binding("shadowMap", Shadow));
|
slotBindings.insert(gpu::Shader::Binding("shadowMap", Shadow));
|
||||||
slotBindings.insert(gpu::Shader::Binding("pyramidMap", Pyramid));
|
slotBindings.insert(gpu::Shader::Binding("pyramidMap", Pyramid));
|
||||||
slotBindings.insert(gpu::Shader::Binding("occlusionMap", AmbientOcclusion));
|
|
||||||
slotBindings.insert(gpu::Shader::Binding("occlusionBlurredMap", AmbientOcclusionBlurred));
|
slotBindings.insert(gpu::Shader::Binding("occlusionBlurredMap", AmbientOcclusionBlurred));
|
||||||
gpu::Shader::makeProgram(*program, slotBindings);
|
gpu::Shader::makeProgram(*program, slotBindings);
|
||||||
|
|
||||||
|
@ -247,6 +281,7 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
|
||||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||||
const auto geometryBuffer = DependencyManager::get<GeometryCache>();
|
const auto geometryBuffer = DependencyManager::get<GeometryCache>();
|
||||||
const auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
const auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||||
|
const auto textureCache = DependencyManager::get<TextureCache>();
|
||||||
const auto& lightStage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
const auto& lightStage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||||
|
|
||||||
glm::mat4 projMat;
|
glm::mat4 projMat;
|
||||||
|
@ -262,14 +297,19 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
|
||||||
|
|
||||||
batch.setPipeline(getPipeline(_mode, first));
|
batch.setPipeline(getPipeline(_mode, first));
|
||||||
|
|
||||||
batch.setResourceTexture(Diffuse, framebufferCache->getDeferredColorTexture());
|
batch.setResourceTexture(Albedo, framebufferCache->getDeferredColorTexture());
|
||||||
batch.setResourceTexture(Normal, framebufferCache->getDeferredNormalTexture());
|
batch.setResourceTexture(Normal, framebufferCache->getDeferredNormalTexture());
|
||||||
batch.setResourceTexture(Specular, framebufferCache->getDeferredSpecularTexture());
|
batch.setResourceTexture(Specular, framebufferCache->getDeferredSpecularTexture());
|
||||||
batch.setResourceTexture(Depth, framebufferCache->getPrimaryDepthTexture());
|
batch.setResourceTexture(Depth, framebufferCache->getPrimaryDepthTexture());
|
||||||
batch.setResourceTexture(Lighting, framebufferCache->getLightingTexture());
|
batch.setResourceTexture(Lighting, framebufferCache->getLightingTexture());
|
||||||
batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getDepthStencilBuffer());
|
batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getDepthStencilBuffer());
|
||||||
batch.setResourceTexture(Pyramid, framebufferCache->getDepthPyramidTexture());
|
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());
|
batch.setResourceTexture(AmbientOcclusionBlurred, framebufferCache->getOcclusionBlurredTexture());
|
||||||
|
|
||||||
const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
|
const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
|
@ -47,11 +47,14 @@ protected:
|
||||||
|
|
||||||
enum Mode : uint8_t {
|
enum Mode : uint8_t {
|
||||||
// Use Mode suffix to avoid collisions
|
// Use Mode suffix to avoid collisions
|
||||||
DiffuseMode = 0,
|
DepthMode = 0,
|
||||||
SpecularMode,
|
AlbedoMode,
|
||||||
RoughnessMode,
|
|
||||||
NormalMode,
|
NormalMode,
|
||||||
DepthMode,
|
RoughnessMode,
|
||||||
|
MetallicMode,
|
||||||
|
EmissiveMode,
|
||||||
|
OcclusionMode,
|
||||||
|
LightmapMode,
|
||||||
LightingMode,
|
LightingMode,
|
||||||
ShadowMode,
|
ShadowMode,
|
||||||
PyramidDepthMode,
|
PyramidDepthMode,
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
<@def DEFERRED_BUFFER_SLH@>
|
<@def DEFERRED_BUFFER_SLH@>
|
||||||
|
|
||||||
|
|
||||||
// the diffuse texture
|
// the albedo texture
|
||||||
uniform sampler2D diffuseMap;
|
uniform sampler2D albedoMap;
|
||||||
|
|
||||||
// the normal texture
|
// the normal texture
|
||||||
uniform sampler2D normalMap;
|
uniform sampler2D normalMap;
|
||||||
|
@ -34,8 +34,8 @@ uniform sampler2D lightingMap;
|
||||||
struct DeferredTransform {
|
struct DeferredTransform {
|
||||||
mat4 projection;
|
mat4 projection;
|
||||||
mat4 viewInverse;
|
mat4 viewInverse;
|
||||||
|
float stereoSide;
|
||||||
vec4 stereoSide_spareABC;
|
vec3 _spareABC;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std140) uniform deferredTransformBuffer {
|
layout(std140) uniform deferredTransformBuffer {
|
||||||
|
@ -46,10 +46,10 @@ DeferredTransform getDeferredTransform() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getStereoMode(DeferredTransform deferredTransform) {
|
bool getStereoMode(DeferredTransform deferredTransform) {
|
||||||
return (deferredTransform.stereoSide_spareABC.x != 0.0);
|
return (deferredTransform.stereoSide != 0.0);
|
||||||
}
|
}
|
||||||
float getStereoSide(DeferredTransform deferredTransform) {
|
float getStereoSide(DeferredTransform deferredTransform) {
|
||||||
return (deferredTransform.stereoSide_spareABC.x);
|
return (deferredTransform.stereoSide);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) {
|
vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) {
|
||||||
|
@ -64,52 +64,82 @@ vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, v
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DeferredFragment {
|
struct DeferredFragment {
|
||||||
float depthVal;
|
|
||||||
vec4 normalVal;
|
vec4 normalVal;
|
||||||
vec4 diffuseVal;
|
vec4 diffuseVal;
|
||||||
vec4 specularVal;
|
vec4 specularVal;
|
||||||
vec4 position;
|
vec4 position;
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
|
float metallic;
|
||||||
vec3 diffuse;
|
vec3 diffuse;
|
||||||
float obscurance;
|
float obscurance;
|
||||||
vec3 specular;
|
vec3 specular;
|
||||||
float gloss;
|
float roughness;
|
||||||
|
vec3 emissive;
|
||||||
int mode;
|
int mode;
|
||||||
|
float depthVal;
|
||||||
};
|
};
|
||||||
|
|
||||||
const int LIGHT_MAPPED = 1;
|
const int LIGHT_MAPPED = 1;
|
||||||
|
|
||||||
DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec2 texcoord) {
|
vec4 unpackDeferredPosition(DeferredTransform deferredTransform, float depthValue, 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;
|
|
||||||
|
|
||||||
if (getStereoMode(deferredTransform)) {
|
if (getStereoMode(deferredTransform)) {
|
||||||
if (texcoord.x > 0.5) {
|
if (texcoord.x > 0.5) {
|
||||||
texcoord.x -= 0.5;
|
texcoord.x -= 0.5;
|
||||||
}
|
}
|
||||||
texcoord.x *= 2.0;
|
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
|
// Unpack the normal from the map
|
||||||
frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0));
|
frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0));
|
||||||
|
|
||||||
frag.mode = 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.mode = LIGHT_MAPPED;
|
||||||
|
frag.roughness = 2.0 * frag.normalVal.a - 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frag.metallic = frag.diffuseVal.a;
|
||||||
frag.diffuse = frag.diffuseVal.xyz;
|
frag.diffuse = frag.diffuseVal.xyz;
|
||||||
frag.specular = frag.specularVal.xyz;
|
if (frag.metallic <= 0.5) {
|
||||||
frag.gloss = frag.specularVal.w;
|
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;
|
return frag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -40,37 +40,41 @@ float evalOpaqueFinalAlpha(float alpha, float mapAlpha) {
|
||||||
return mix(alpha, 1.0 - alpha, step(mapAlpha, alphaThreshold));
|
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_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) {
|
if (alpha != 1.0) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
_fragColor0 = vec4(albedo, metallic);
|
||||||
_fragColor0 = vec4(diffuse.rgb, 1.0); // Opaque
|
_fragColor1 = vec4(bestFitNormal(normal), 0.5 * clamp(roughness, 0.0, 1.0));
|
||||||
_fragColor1 = vec4(bestFitNormal(normal), 1.0);
|
_fragColor2 = vec4(emissive, occlusion);
|
||||||
_fragColor2 = vec4(specular, shininess / 128.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
if (alpha != 1.0) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
_fragColor0 = vec4(albedo, metallic);
|
||||||
_fragColor0 = vec4(diffuse.rgb, 0.5);
|
_fragColor1 = vec4(bestFitNormal(normal), 0.5 + 0.5 * clamp(roughness, 0.0, 1.0));
|
||||||
_fragColor1 = vec4(bestFitNormal(normal), 0.5);
|
_fragColor2 = vec4(emissive, 1.0);
|
||||||
_fragColor2 = vec4(emissive, shininess / 128.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) {
|
if (alpha <= 0.0) {
|
||||||
discard;
|
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);
|
// _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@>
|
<@endif@>
|
||||||
|
|
|
@ -11,109 +11,116 @@
|
||||||
<@if not DEFERRED_GLOBAL_LIGHT_SLH@>
|
<@if not DEFERRED_GLOBAL_LIGHT_SLH@>
|
||||||
<@def DEFERRED_GLOBAL_LIGHT_SLH@>
|
<@def DEFERRED_GLOBAL_LIGHT_SLH@>
|
||||||
|
|
||||||
|
<@include model/Light.slh@>
|
||||||
<@include DeferredLighting.slh@>
|
<@include DeferredLighting.slh@>
|
||||||
|
|
||||||
<@func declareSkyboxMap()@>
|
<@func declareSkyboxMap()@>
|
||||||
|
// declareSkyboxMap
|
||||||
uniform samplerCube skyboxMap;
|
uniform samplerCube skyboxMap;
|
||||||
|
|
||||||
vec4 evalSkyboxLight(vec3 direction, float lod) {
|
vec4 evalSkyboxLight(vec3 direction, float lod) {
|
||||||
// FIXME
|
// textureQueryLevels is not available until #430, so we require explicit lod
|
||||||
//vec4 skytexel = textureLod(skyboxMap, direction, lod * textureQueryLevels(skyboxMap));
|
// float mipmapLevel = lod * textureQueryLevels(skyboxMap);
|
||||||
vec4 skytexel = texture(skyboxMap, direction);
|
return textureLod(skyboxMap, direction, lod);
|
||||||
return skytexel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
// Everything about light
|
<@func prepareGlobalLight()@>
|
||||||
<@include model/Light.slh@>
|
// 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()@>
|
<@func declareEvalAmbientGlobalColor()@>
|
||||||
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
|
||||||
|
<$prepareGlobalLight()$>
|
||||||
// Need the light now
|
color += albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(light);
|
||||||
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);
|
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func declareEvalAmbientSphereGlobalColor()@>
|
<@func declareEvalAmbientSphereGlobalColor()@>
|
||||||
|
<$declareAmbientFresnel()$>
|
||||||
|
|
||||||
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
|
||||||
// Need the light now
|
<$prepareGlobalLight()$>
|
||||||
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);
|
|
||||||
|
|
||||||
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;
|
return color;
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func declareEvalSkyboxGlobalColor()@>
|
<@func declareEvalSkyboxGlobalColor()@>
|
||||||
|
|
||||||
<$declareSkyboxMap()$>
|
<$declareSkyboxMap()$>
|
||||||
|
<$declareAmbientFresnel()$>
|
||||||
|
|
||||||
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
|
||||||
// Need the light now
|
<$prepareGlobalLight()$>
|
||||||
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);
|
|
||||||
|
|
||||||
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;
|
return color;
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func declareEvalLightmappedColor()@>
|
<@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();
|
Light light = getLight();
|
||||||
|
|
||||||
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
|
// Catch normals perpendicular to the projection plane, hence the magic number for the threshold
|
||||||
float diffuseDot = dot(fragNormal, -getLightDirection(light));
|
// It should be just 0, but we have inaccuracy so we overshoot
|
||||||
|
|
||||||
// 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
|
|
||||||
const float PERPENDICULAR_THRESHOLD = -0.005;
|
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);
|
||||||
//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;
|
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;
|
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);
|
vec3 ambientLight = (1 - lightAttenuation) * lightmap * getLightAmbientIntensity(light);
|
||||||
|
|
||||||
return obscurance * diffuse * (ambientLight + diffuseLight);
|
return obscurance * albedo * (diffuseLight + ambientLight);
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
|
|
|
@ -13,41 +13,55 @@
|
||||||
|
|
||||||
|
|
||||||
<@func declareEvalPBRShading()@>
|
<@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
|
// 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
|
// Diffuse Lighting
|
||||||
float diffuseDot = dot(fragNormal, fragLightDir);
|
float diffuse = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0);
|
||||||
float facingLight = step(0.0, diffuseDot);
|
|
||||||
float diffuse = diffuseDot * facingLight;
|
// Specular Lighting
|
||||||
|
|
||||||
// Specular Lighting depends on the half vector and the gloss
|
|
||||||
vec3 halfDir = normalize(fragEyeDir + fragLightDir);
|
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);
|
return vec4(specular, (1.0 - metallic) * diffuse * (1 - fresnelColor.x));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func declareEvalBlinnRShading()@>
|
<@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
|
// Diffuse Lighting
|
||||||
float diffuseDot = dot(fragNormal, fragLightDir);
|
float diffuseDot = dot(fragNormal, fragLightDir);
|
||||||
float facingLight = step(0.0, diffuseDot);
|
float facingLight = step(0.0, diffuseDot);
|
||||||
float diffuse = diffuseDot * facingLight;
|
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);
|
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;
|
vec3 reflect = specularPower * specular * diffuse;
|
||||||
|
|
||||||
return vec4(reflect, diffuse);
|
return vec4(reflect, diffuse);
|
||||||
|
@ -59,8 +73,8 @@ vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3
|
||||||
<$declareEvalPBRShading()$>
|
<$declareEvalPBRShading()$>
|
||||||
|
|
||||||
// Return xyz the specular/reflection component and w the diffuse component
|
// Return xyz the specular/reflection component and w the diffuse component
|
||||||
vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) {
|
vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 specular, float roughness) {
|
||||||
return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, specular, gloss);
|
return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, metallic, specular, roughness);
|
||||||
}
|
}
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -92,6 +92,11 @@ void DeferredLightingEffect::init() {
|
||||||
// Add the global light to the light stage (for later shadow rendering)
|
// Add the global light to the light stage (for later shadow rendering)
|
||||||
_lightStage.addLight(lp);
|
_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,
|
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;
|
auto& program = _shadowMapEnabled ? _directionalLightShadow : _directionalLight;
|
||||||
LightLocationsPtr locations = _shadowMapEnabled ? _directionalLightShadowLocations : _directionalLightLocations;
|
LightLocationsPtr locations = _shadowMapEnabled ? _directionalLightShadowLocations : _directionalLightLocations;
|
||||||
|
const auto& keyLight = _allocatedLights[_globalLights.front()];
|
||||||
|
|
||||||
// Setup the global directional pass pipeline
|
// Setup the global directional pass pipeline
|
||||||
{
|
{
|
||||||
if (_shadowMapEnabled) {
|
if (_shadowMapEnabled) {
|
||||||
if (_skyboxTexture) {
|
if (keyLight->getAmbientMap()) {
|
||||||
program = _directionalSkyboxLightShadow;
|
program = _directionalSkyboxLightShadow;
|
||||||
locations = _directionalSkyboxLightShadowLocations;
|
locations = _directionalSkyboxLightShadowLocations;
|
||||||
} else if (_ambientLightMode > -1) {
|
} else {
|
||||||
program = _directionalAmbientSphereLightShadow;
|
program = _directionalAmbientSphereLightShadow;
|
||||||
locations = _directionalAmbientSphereLightShadowLocations;
|
locations = _directionalAmbientSphereLightShadowLocations;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_skyboxTexture) {
|
if (keyLight->getAmbientMap()) {
|
||||||
program = _directionalSkyboxLight;
|
program = _directionalSkyboxLight;
|
||||||
locations = _directionalSkyboxLightLocations;
|
locations = _directionalSkyboxLightLocations;
|
||||||
} else if (_ambientLightMode > -1) {
|
} else {
|
||||||
program = _directionalAmbientSphereLight;
|
program = _directionalAmbientSphereLight;
|
||||||
locations = _directionalAmbientSphereLightLocations;
|
locations = _directionalAmbientSphereLightLocations;
|
||||||
}
|
}
|
||||||
|
@ -351,7 +357,7 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
||||||
geometryCache->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
|
geometryCache->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_skyboxTexture) {
|
if (keyLight->getAmbientMap()) {
|
||||||
batch.setResourceTexture(SKYBOX_MAP_UNIT, nullptr);
|
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) {
|
void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int skyboxCubemapUnit) {
|
||||||
PerformanceTimer perfTimer("DLE->setupBatch()");
|
PerformanceTimer perfTimer("DLE->setupBatch()");
|
||||||
auto globalLight = _allocatedLights[_globalLights.front()];
|
auto keyLight = _allocatedLights[_globalLights.front()];
|
||||||
|
|
||||||
if (lightBufferUnit >= 0) {
|
if (lightBufferUnit >= 0) {
|
||||||
batch.setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer());
|
batch.setUniformBuffer(lightBufferUnit, keyLight->getSchemaBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_skyboxTexture && (skyboxCubemapUnit >= 0)) {
|
if (keyLight->getAmbientMap() && (skyboxCubemapUnit >= 0)) {
|
||||||
batch.setResourceTexture(skyboxCubemapUnit, _skyboxTexture);
|
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::ShaderPointer program = gpu::Shader::createProgram(VS, PS);
|
||||||
|
|
||||||
gpu::Shader::BindingSet slotBindings;
|
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("normalMap"), DEFERRED_BUFFER_NORMAL_UNIT));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), DEFERRED_BUFFER_EMISSIVE_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));
|
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();
|
auto globalLight = _allocatedLights.front();
|
||||||
globalLight->setDirection(light->getDirection());
|
globalLight->setDirection(light->getDirection());
|
||||||
globalLight->setColor(light->getColor());
|
globalLight->setColor(light->getColor());
|
||||||
globalLight->setIntensity(light->getIntensity());
|
globalLight->setIntensity(light->getIntensity());
|
||||||
globalLight->setAmbientIntensity(light->getAmbientIntensity());
|
globalLight->setAmbientIntensity(light->getAmbientIntensity());
|
||||||
globalLight->setAmbientSphere(light->getAmbientSphere());
|
globalLight->setAmbientSphere(light->getAmbientSphere());
|
||||||
|
globalLight->setAmbientMap(light->getAmbientMap());
|
||||||
_skyboxTexture = skyboxTexture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
|
model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
|
||||||
|
|
|
@ -49,11 +49,12 @@ public:
|
||||||
void setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int skyboxCubemapUnit);
|
void setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int skyboxCubemapUnit);
|
||||||
|
|
||||||
// update global lighting
|
// update global lighting
|
||||||
void setGlobalLight(const model::LightPointer& light, const gpu::TexturePointer& skyboxTexture);
|
void setGlobalLight(const model::LightPointer& light);
|
||||||
|
|
||||||
const LightStage& getLightStage() { return _lightStage; }
|
const LightStage& getLightStage() { return _lightStage; }
|
||||||
void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; };
|
void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; };
|
||||||
void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; }
|
void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; }
|
||||||
|
bool isAmbientOcclusionEnabled() const { return _ambientOcclusionEnabled; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DeferredLightingEffect() = default;
|
DeferredLightingEffect() = default;
|
||||||
|
@ -95,15 +96,12 @@ private:
|
||||||
std::vector<int> _pointLights;
|
std::vector<int> _pointLights;
|
||||||
std::vector<int> _spotLights;
|
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 describing the uniform buffer with all the parameters common to the deferred shaders
|
||||||
class DeferredTransform {
|
class DeferredTransform {
|
||||||
public:
|
public:
|
||||||
glm::mat4 projection;
|
glm::mat4 projection;
|
||||||
glm::mat4 viewInverse;
|
glm::mat4 viewInverse;
|
||||||
float stereoSide{ 0.f };
|
float stereoSide { 0.f };
|
||||||
float spareA, spareB, spareC;
|
float spareA, spareB, spareC;
|
||||||
|
|
||||||
DeferredTransform() {}
|
DeferredTransform() {}
|
||||||
|
|
|
@ -506,7 +506,7 @@ GeometryCache::GeometryCache() :
|
||||||
std::make_shared<render::ShapePipeline>(getSimplePipeline(), nullptr,
|
std::make_shared<render::ShapePipeline>(getSimplePipeline(), nullptr,
|
||||||
[](const render::ShapePipeline&, gpu::Batch& batch) {
|
[](const render::ShapePipeline&, gpu::Batch& batch) {
|
||||||
// Set the defaults needed for a simple program
|
// 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());
|
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||||
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
|
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
|
||||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
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) {
|
void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled, bool emissive, bool depthBiased) {
|
||||||
batch.setPipeline(getSimplePipeline(textured, culled, emissive, 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) {
|
if (!textured) {
|
||||||
batch.setResourceTexture(render::ShapePipeline::Slot::DIFFUSE_MAP,
|
batch.setResourceTexture(render::ShapePipeline::Slot::ALBEDO_MAP,
|
||||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||||
}
|
}
|
||||||
// Set a default normal map
|
// 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()) {
|
if (drawMaterialKey.isNormalMap()) {
|
||||||
builder.withTangents();
|
builder.withTangents();
|
||||||
}
|
}
|
||||||
if (drawMaterialKey.isGlossMap()) {
|
if (drawMaterialKey.isMetallicMap()) {
|
||||||
builder.withSpecular();
|
builder.withSpecular();
|
||||||
}
|
}
|
||||||
if (drawMaterialKey.isLightmapMap()) {
|
if (drawMaterialKey.isLightmapMap()) {
|
||||||
|
@ -145,20 +145,34 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
||||||
auto textureMaps = _drawMaterial->getTextureMaps();
|
auto textureMaps = _drawMaterial->getTextureMaps();
|
||||||
glm::mat4 texcoordTransform[2];
|
glm::mat4 texcoordTransform[2];
|
||||||
|
|
||||||
// Diffuse
|
// Albedo
|
||||||
if (materialKey.isDiffuseMap()) {
|
if (materialKey.isAlbedoMap()) {
|
||||||
auto diffuseMap = textureMaps[model::MaterialKey::DIFFUSE_MAP];
|
auto albedoMap = textureMaps[model::MaterialKey::ALBEDO_MAP];
|
||||||
if (diffuseMap && diffuseMap->isDefined()) {
|
if (albedoMap && albedoMap->isDefined()) {
|
||||||
batch.setResourceTexture(ShapePipeline::Slot::DIFFUSE_MAP, diffuseMap->getTextureView());
|
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, albedoMap->getTextureView());
|
||||||
|
|
||||||
if (!diffuseMap->getTextureTransform().isIdentity()) {
|
if (!albedoMap->getTextureTransform().isIdentity()) {
|
||||||
diffuseMap->getTextureTransform().getMatrix(texcoordTransform[0]);
|
albedoMap->getTextureTransform().getMatrix(texcoordTransform[0]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
batch.setResourceTexture(ShapePipeline::Slot::DIFFUSE_MAP, textureCache->getGrayTexture());
|
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, textureCache->getGrayTexture());
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
// Normal map
|
||||||
|
@ -167,7 +181,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
||||||
if (normalMap && normalMap->isDefined()) {
|
if (normalMap && normalMap->isDefined()) {
|
||||||
batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, normalMap->getTextureView());
|
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 {
|
} else {
|
||||||
batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, textureCache->getBlueTexture());
|
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);
|
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
|
// Metallic map
|
||||||
if (materialKey.isGlossMap()) {
|
if (materialKey.isMetallicMap()) {
|
||||||
auto specularMap = textureMaps[model::MaterialKey::GLOSS_MAP];
|
auto specularMap = textureMaps[model::MaterialKey::METALLIC_MAP];
|
||||||
if (specularMap && specularMap->isDefined()) {
|
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 {
|
} else {
|
||||||
batch.setResourceTexture(ShapePipeline::Slot::SPECULAR_MAP, textureCache->getBlackTexture());
|
batch.setResourceTexture(ShapePipeline::Slot::METALLIC_MAP, textureCache->getBlackTexture());
|
||||||
}
|
}
|
||||||
} else {
|
} 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()) {
|
if (materialKey.isLightmapMap()) {
|
||||||
auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP];
|
auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP];
|
||||||
|
|
||||||
if (lightmapMap && lightmapMap->isDefined()) {
|
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();
|
auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale();
|
||||||
batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y);
|
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]);
|
lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]);
|
||||||
}
|
}
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
batch.setResourceTexture(ShapePipeline::Slot::LIGHTMAP_MAP, nullptr);
|
batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Texcoord transforms ?
|
// Texcoord transforms ?
|
||||||
|
@ -378,7 +414,7 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
||||||
|
|
||||||
bool isTranslucent = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap();
|
bool isTranslucent = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap();
|
||||||
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
||||||
bool hasSpecular = drawMaterialKey.isGlossMap();
|
bool hasSpecular = drawMaterialKey.isMetallicMap();
|
||||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
||||||
|
|
||||||
bool isSkinned = _isSkinned;
|
bool isSkinned = _isSkinned;
|
||||||
|
|
|
@ -1205,9 +1205,9 @@ void Model::segregateMeshGroups() {
|
||||||
if (showingCollisionHull) {
|
if (showingCollisionHull) {
|
||||||
if (!_collisionHullMaterial) {
|
if (!_collisionHullMaterial) {
|
||||||
_collisionHullMaterial = std::make_shared<model::Material>();
|
_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->setMetallic(0.02f);
|
||||||
_collisionHullMaterial->setGloss(1.0f);
|
_collisionHullMaterial->setRoughness(0.5f);
|
||||||
}
|
}
|
||||||
_renderItemsSet << std::make_shared<MeshPartPayload>(networkMesh._mesh, partIndex, _collisionHullMaterial, transform, offset);
|
_renderItemsSet << std::make_shared<MeshPartPayload>(networkMesh._mesh, partIndex, _collisionHullMaterial, transform, offset);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -66,16 +66,16 @@ void initStencilPipeline(gpu::PipelinePointer& pipeline) {
|
||||||
|
|
||||||
gpu::BufferView getDefaultMaterialBuffer() {
|
gpu::BufferView getDefaultMaterialBuffer() {
|
||||||
model::Material::Schema schema;
|
model::Material::Schema schema;
|
||||||
schema._diffuse = vec3(1.0f);
|
schema._albedo = vec3(1.0f);
|
||||||
schema._opacity = 1.0f;
|
schema._opacity = 1.0f;
|
||||||
schema._metallic = vec3(0.1f);
|
schema._metallic = 0.1f;
|
||||||
schema._gloss = 10.0f;
|
schema._roughness = 0.9f;
|
||||||
return gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(model::Material::Schema), (const gpu::Byte*) &schema));
|
return gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(model::Material::Schema), (const gpu::Byte*) &schema));
|
||||||
}
|
}
|
||||||
|
|
||||||
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
||||||
// Set a default diffuse map
|
// Set a default albedo map
|
||||||
batch.setResourceTexture(render::ShapePipeline::Slot::DIFFUSE_MAP,
|
batch.setResourceTexture(render::ShapePipeline::Slot::ALBEDO_MAP,
|
||||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||||
// Set a default normal map
|
// Set a default normal map
|
||||||
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
|
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
out vec4 _color;
|
out vec4 _color;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// pass along the diffuse color
|
// pass along the color
|
||||||
_color = colorToLinearRGBA(inColor.rgba);
|
_color = colorToLinearRGBA(inColor.rgba);
|
||||||
|
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
|
|
|
@ -44,8 +44,9 @@ void main(void) {
|
||||||
frag.position.xyz,
|
frag.position.xyz,
|
||||||
frag.normal,
|
frag.normal,
|
||||||
frag.diffuse,
|
frag.diffuse,
|
||||||
frag.specular,
|
frag.metallic,
|
||||||
frag.gloss);
|
frag.emissive,
|
||||||
|
frag.roughness);
|
||||||
_fragColor = vec4(color, frag.normalVal.a);
|
_fragColor = vec4(color, frag.normalVal.a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,9 @@ void main(void) {
|
||||||
frag.position.xyz,
|
frag.position.xyz,
|
||||||
frag.normal,
|
frag.normal,
|
||||||
frag.diffuse,
|
frag.diffuse,
|
||||||
frag.specular,
|
frag.metallic,
|
||||||
frag.gloss);
|
frag.emissive,
|
||||||
|
frag.roughness);
|
||||||
_fragColor = vec4(color, frag.normalVal.a);
|
_fragColor = vec4(color, frag.normalVal.a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,9 @@ void main(void) {
|
||||||
frag.position.xyz,
|
frag.position.xyz,
|
||||||
frag.normal,
|
frag.normal,
|
||||||
frag.diffuse,
|
frag.diffuse,
|
||||||
frag.specular,
|
frag.metallic,
|
||||||
frag.gloss);
|
frag.emissive,
|
||||||
|
frag.roughness);
|
||||||
_fragColor = vec4(color, frag.normalVal.a);
|
_fragColor = vec4(color, frag.normalVal.a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,9 @@ void main(void) {
|
||||||
frag.position.xyz,
|
frag.position.xyz,
|
||||||
frag.normal,
|
frag.normal,
|
||||||
frag.diffuse,
|
frag.diffuse,
|
||||||
frag.specular,
|
frag.metallic,
|
||||||
frag.gloss);
|
frag.emissive,
|
||||||
|
frag.roughness);
|
||||||
_fragColor = vec4(color, frag.normalVal.a);
|
_fragColor = vec4(color, frag.normalVal.a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,9 @@ void main(void) {
|
||||||
frag.position.xyz,
|
frag.position.xyz,
|
||||||
frag.normal,
|
frag.normal,
|
||||||
frag.diffuse,
|
frag.diffuse,
|
||||||
frag.specular,
|
frag.metallic,
|
||||||
frag.gloss);
|
frag.emissive,
|
||||||
|
frag.roughness);
|
||||||
|
|
||||||
_fragColor = vec4(color, frag.normalVal.a);
|
_fragColor = vec4(color, frag.normalVal.a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,9 @@ void main(void) {
|
||||||
frag.position.xyz,
|
frag.position.xyz,
|
||||||
frag.normal,
|
frag.normal,
|
||||||
frag.diffuse,
|
frag.diffuse,
|
||||||
frag.specular,
|
frag.metallic,
|
||||||
frag.gloss);
|
frag.emissive,
|
||||||
|
frag.roughness);
|
||||||
|
|
||||||
_fragColor = vec4(color, frag.normalVal.a);
|
_fragColor = vec4(color, frag.normalVal.a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
|
|
||||||
<@include model/Material.slh@>
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
// the diffuse texture
|
<@include MaterialTextures.slh@>
|
||||||
uniform sampler2D diffuseMap;
|
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$>
|
||||||
|
|
||||||
in vec4 _position;
|
in vec4 _position;
|
||||||
in vec3 _normal;
|
in vec3 _normal;
|
||||||
|
@ -25,15 +25,26 @@ in vec2 _texCoord0;
|
||||||
|
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// Fetch diffuse map
|
|
||||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
|
||||||
|
|
||||||
Material mat = getMaterial();
|
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(
|
packDeferredFragment(
|
||||||
normalize(_normal.xyz),
|
normalize(_normal.xyz),
|
||||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedoTex.a),
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
albedo,
|
||||||
getMaterialSpecular(mat),
|
roughness,
|
||||||
getMaterialShininess(mat));
|
getMaterialMetallic(mat),
|
||||||
|
emissive,
|
||||||
|
occlusionTex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<@include DeferredBufferWrite.slh@>
|
<@include DeferredBufferWrite.slh@>
|
||||||
<@include model/Material.slh@>
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
uniform sampler2D diffuseMap;
|
uniform sampler2D albedoMap;
|
||||||
|
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
in vec3 _normal;
|
in vec3 _normal;
|
||||||
|
@ -23,16 +23,17 @@ in vec3 _color;
|
||||||
in float _alpha;
|
in float _alpha;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 texel = texture(diffuseMap, _texCoord0);
|
vec4 texel = texture(albedoMap, _texCoord0);
|
||||||
|
|
||||||
Material mat = getMaterial();
|
Material mat = getMaterial();
|
||||||
vec3 fragColor = getMaterialDiffuse(mat) * texel.rgb * _color;
|
vec3 fragColor = getMaterialAlbedo(mat) * texel.rgb * _color;
|
||||||
|
|
||||||
packDeferredFragmentLightmap(
|
packDeferredFragmentLightmap(
|
||||||
normalize(_normal),
|
normalize(_normal),
|
||||||
texel.a,
|
texel.a,
|
||||||
vec3(1.0),
|
vec3(1.0),
|
||||||
getMaterialSpecular(mat),
|
getMaterialRoughness(mat),
|
||||||
getMaterialShininess(mat),
|
getMaterialMetallic(mat),
|
||||||
|
getMaterialFresnel(mat),
|
||||||
fragColor);
|
fragColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,12 +16,9 @@
|
||||||
|
|
||||||
<@include model/Material.slh@>
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
// the diffuse texture
|
<@include MaterialTextures.slh@>
|
||||||
uniform sampler2D diffuseMap;
|
<$declareMaterialTextures(ALBEDO, ROUGHNESS)$>
|
||||||
|
<$declareMaterialLightmap()$>
|
||||||
// the emissive map texture and parameters
|
|
||||||
uniform sampler2D emissiveMap;
|
|
||||||
uniform vec2 emissiveParams;
|
|
||||||
|
|
||||||
in vec4 _position;
|
in vec4 _position;
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
|
@ -30,16 +27,18 @@ in vec3 _normal;
|
||||||
in vec3 _color;
|
in vec3 _color;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
|
||||||
vec4 emissive = texture(emissiveMap, _texCoord1);
|
|
||||||
|
|
||||||
Material mat = getMaterial();
|
Material mat = getMaterial();
|
||||||
|
int matKey = getMaterialKey(mat);
|
||||||
|
<$fetchMaterialTextures(matKey, _texCoord0, albedo, roughness)$>
|
||||||
|
<$fetchMaterialLightmap(_texCoord1, emissive)$>
|
||||||
|
|
||||||
|
|
||||||
packDeferredFragmentLightmap(
|
packDeferredFragmentLightmap(
|
||||||
normalize(_normal),
|
normalize(_normal),
|
||||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a),
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
getMaterialAlbedo(mat) * albedo.rgb * _color,
|
||||||
getMaterialSpecular(mat),
|
getMaterialRoughness(mat) * roughness,
|
||||||
getMaterialShininess(mat),
|
getMaterialMetallic(mat),
|
||||||
|
getMaterialFresnel(mat),
|
||||||
(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb));
|
(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ out vec3 _normal;
|
||||||
out vec3 _color;
|
out vec3 _color;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// pass along the diffuse color in linear space
|
// pass along the color in linear space
|
||||||
_color = colorToLinearRGB(inColor.xyz);
|
_color = colorToLinearRGB(inColor.xyz);
|
||||||
|
|
||||||
// and the texture coordinates
|
// and the texture coordinates
|
||||||
|
|
|
@ -16,15 +16,9 @@
|
||||||
|
|
||||||
<@include model/Material.slh@>
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
// the diffuse texture
|
<@include MaterialTextures.slh@>
|
||||||
uniform sampler2D diffuseMap;
|
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL)$>
|
||||||
|
<$declareMaterialLightmap()$>
|
||||||
// the normal map texture
|
|
||||||
uniform sampler2D normalMap;
|
|
||||||
|
|
||||||
// the emissive map texture and parameters
|
|
||||||
uniform sampler2D emissiveMap;
|
|
||||||
uniform vec2 emissiveParams;
|
|
||||||
|
|
||||||
in vec4 _position;
|
in vec4 _position;
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
|
@ -34,25 +28,20 @@ in vec3 _tangent;
|
||||||
in vec3 _color;
|
in vec3 _color;
|
||||||
|
|
||||||
void main(void) {
|
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();
|
Material mat = getMaterial();
|
||||||
|
int matKey = getMaterialKey(mat);
|
||||||
|
<$fetchMaterialTextures(matKey, _texCoord0, albedo, roughness, normalTexel)$>
|
||||||
|
<$fetchMaterialLightmap(_texCoord1, lightmapVal)$>
|
||||||
|
|
||||||
|
vec3 viewNormal;
|
||||||
|
<$tangentToViewSpace(normalTexel, _normal, _tangent, viewNormal)$>
|
||||||
|
|
||||||
packDeferredFragmentLightmap(
|
packDeferredFragmentLightmap(
|
||||||
normalize(viewNormal.xyz),
|
normalize(viewNormal.xyz),
|
||||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a),
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
getMaterialAlbedo(mat) * albedo.rgb * _color,
|
||||||
getMaterialSpecular(mat),
|
getMaterialRoughness(mat),
|
||||||
getMaterialShininess(mat),
|
getMaterialMetallic(mat),
|
||||||
(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb));
|
getMaterialFresnel(mat),
|
||||||
|
lightmapVal);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ out vec3 _tangent;
|
||||||
out vec3 _color;
|
out vec3 _color;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// pass along the diffuse color in linear space
|
// pass along the color in linear space
|
||||||
_color = colorToLinearRGB(inColor.xyz);
|
_color = colorToLinearRGB(inColor.xyz);
|
||||||
|
|
||||||
// and the texture coordinates
|
// and the texture coordinates
|
||||||
|
|
|
@ -16,18 +16,9 @@
|
||||||
|
|
||||||
<@include model/Material.slh@>
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
// the diffuse texture
|
<@include MaterialTextures.slh@>
|
||||||
uniform sampler2D diffuseMap;
|
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC)$>
|
||||||
|
<$declareMaterialLightmap()$>
|
||||||
// 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;
|
|
||||||
|
|
||||||
in vec4 _position;
|
in vec4 _position;
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
|
@ -37,26 +28,20 @@ in vec3 _tangent;
|
||||||
in vec3 _color;
|
in vec3 _color;
|
||||||
|
|
||||||
void main(void) {
|
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();
|
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(
|
packDeferredFragmentLightmap(
|
||||||
normalize(viewNormal.xyz),
|
normalize(viewNormal.xyz),
|
||||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a),
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
getMaterialAlbedo(mat) * albedo.rgb * _color,
|
||||||
specular, // no use of getMaterialSpecular(mat)
|
getMaterialRoughness(mat) * roughness,
|
||||||
getMaterialShininess(mat),
|
getMaterialMetallic(mat) * metallicTex,
|
||||||
(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb));
|
/*specular, // no use of */ getMaterialFresnel(mat),
|
||||||
|
lightmapVal);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,9 @@
|
||||||
|
|
||||||
<@include model/Material.slh@>
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
// the diffuse texture
|
<@include MaterialTextures.slh@>
|
||||||
uniform sampler2D diffuseMap;
|
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC)$>
|
||||||
|
<$declareMaterialLightmap()$>
|
||||||
// the emissive map texture and parameters
|
|
||||||
uniform sampler2D emissiveMap;
|
|
||||||
uniform vec2 emissiveParams;
|
|
||||||
|
|
||||||
// the specular texture
|
|
||||||
uniform sampler2D specularMap;
|
|
||||||
|
|
||||||
in vec4 _position;
|
in vec4 _position;
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
|
@ -33,18 +27,17 @@ in vec3 _normal;
|
||||||
in vec3 _color;
|
in vec3 _color;
|
||||||
|
|
||||||
void main(void) {
|
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();
|
Material mat = getMaterial();
|
||||||
|
int matKey = getMaterialKey(mat);
|
||||||
|
<$fetchMaterialTextures(matKey, _texCoord0, albedo, roughness, _SCRIBE_NULL, metallicTex)$>
|
||||||
|
<$fetchMaterialLightmap(_texCoord1, lightmapVal)$>
|
||||||
|
|
||||||
packDeferredFragmentLightmap(
|
packDeferredFragmentLightmap(
|
||||||
normalize(_normal),
|
normalize(_normal),
|
||||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a),
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
getMaterialAlbedo(mat) * albedo.rgb * _color,
|
||||||
specular, // no use of getMaterialSpecular(mat)
|
getMaterialRoughness(mat) * roughness,
|
||||||
getMaterialShininess(mat),
|
getMaterialMetallic(mat) * metallicTex,
|
||||||
(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb));
|
/*metallicTex, // no use of */getMaterialFresnel(mat),
|
||||||
|
lightmapVal);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,8 @@
|
||||||
|
|
||||||
<@include model/Material.slh@>
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
// the diffuse texture
|
<@include MaterialTextures.slh@>
|
||||||
uniform sampler2D diffuseMap;
|
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$>
|
||||||
|
|
||||||
// the normal map texture
|
|
||||||
uniform sampler2D normalMap;
|
|
||||||
|
|
||||||
in vec4 _position;
|
in vec4 _position;
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
|
@ -29,22 +26,29 @@ in vec3 _tangent;
|
||||||
in vec3 _color;
|
in vec3 _color;
|
||||||
|
|
||||||
void main(void) {
|
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();
|
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(
|
packDeferredFragment(
|
||||||
normalize(viewNormal.xyz),
|
viewNormal,
|
||||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedoTex.a),
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
albedo,
|
||||||
getMaterialSpecular(mat),
|
roughness,
|
||||||
getMaterialShininess(mat));
|
getMaterialMetallic(mat),
|
||||||
|
emissive,
|
||||||
|
occlusionTex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ out vec3 _tangent;
|
||||||
out vec3 _color;
|
out vec3 _color;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// pass along the diffuse color
|
// pass along the color
|
||||||
_color = colorToLinearRGB(inColor.xyz);
|
_color = colorToLinearRGB(inColor.xyz);
|
||||||
|
|
||||||
// and the texture coordinates
|
// and the texture coordinates
|
||||||
|
|
|
@ -16,14 +16,8 @@
|
||||||
|
|
||||||
<@include model/Material.slh@>
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
// the diffuse texture
|
<@include MaterialTextures.slh@>
|
||||||
uniform sampler2D diffuseMap;
|
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC, EMISSIVE, OCCLUSION)$>
|
||||||
|
|
||||||
// the normal map texture
|
|
||||||
uniform sampler2D normalMap;
|
|
||||||
|
|
||||||
// the specular map texture
|
|
||||||
uniform sampler2D specularMap;
|
|
||||||
|
|
||||||
in vec4 _position;
|
in vec4 _position;
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
|
@ -32,24 +26,33 @@ in vec3 _tangent;
|
||||||
in vec3 _color;
|
in vec3 _color;
|
||||||
|
|
||||||
void main(void) {
|
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();
|
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(
|
packDeferredFragment(
|
||||||
normalize(viewNormal.xyz),
|
normalize(viewNormal.xyz),
|
||||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedoTex.a),
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
albedo,
|
||||||
specular, //getMaterialSpecular(mat),
|
roughness,
|
||||||
getMaterialShininess(mat));
|
metallic,
|
||||||
|
emissive,
|
||||||
|
occlusionTex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,8 @@
|
||||||
|
|
||||||
<@include model/Material.slh@>
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
// the diffuse texture
|
<@include MaterialTextures.slh@>
|
||||||
uniform sampler2D diffuseMap;
|
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC, EMISSIVE, OCCLUSION)$>
|
||||||
|
|
||||||
// the specular texture
|
|
||||||
uniform sampler2D specularMap;
|
|
||||||
|
|
||||||
in vec4 _position;
|
in vec4 _position;
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
|
@ -29,16 +26,29 @@ in vec3 _color;
|
||||||
|
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// set the diffuse, normal, specular data
|
|
||||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
|
||||||
vec3 specular = texture(specularMap, _texCoord0).rgb;
|
|
||||||
|
|
||||||
Material mat = getMaterial();
|
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(
|
packDeferredFragment(
|
||||||
normalize(_normal),
|
normalize(_normal),
|
||||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedoTex.a),
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * _color,
|
albedo,
|
||||||
specular, //getMaterialSpecular(mat),
|
roughness,
|
||||||
getMaterialShininess(mat));
|
metallic,
|
||||||
|
emissive,
|
||||||
|
occlusionTex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,7 @@
|
||||||
<@include gpu/Transform.slh@>
|
<@include gpu/Transform.slh@>
|
||||||
<$declareStandardCameraTransform()$>
|
<$declareStandardCameraTransform()$>
|
||||||
|
|
||||||
|
uniform sampler2D albedoMap;
|
||||||
|
|
||||||
uniform sampler2D diffuseMap;
|
|
||||||
|
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
in vec4 _position;
|
in vec4 _position;
|
||||||
|
@ -33,15 +31,16 @@ in float _alpha;
|
||||||
out vec4 _fragColor;
|
out vec4 _fragColor;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
vec4 albedo = texture(albedoMap, _texCoord0);
|
||||||
|
|
||||||
Material mat = getMaterial();
|
Material mat = getMaterial();
|
||||||
vec3 fragPosition = _position.xyz;
|
vec3 fragPosition = _position.xyz;
|
||||||
vec3 fragNormal = normalize(_normal);
|
vec3 fragNormal = normalize(_normal);
|
||||||
vec3 fragDiffuse = getMaterialDiffuse(mat) * diffuse.rgb * _color;
|
vec3 fragAlbedo = getMaterialAlbedo(mat) * albedo.rgb * _color;
|
||||||
vec3 fragSpecular = getMaterialSpecular(mat);
|
float fragMetallic = getMaterialMetallic(mat);
|
||||||
float fragGloss = getMaterialShininess(mat) / 128;
|
vec3 fragEmissive = getMaterialEmissive(mat);
|
||||||
float fragOpacity = getMaterialOpacity(mat) * diffuse.a * _alpha;
|
float fragRoughness = getMaterialRoughness(mat);
|
||||||
|
float fragOpacity = getMaterialOpacity(mat) * albedo.a * _alpha;
|
||||||
|
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
|
|
||||||
|
@ -51,8 +50,9 @@ void main(void) {
|
||||||
1.0,
|
1.0,
|
||||||
fragPosition,
|
fragPosition,
|
||||||
fragNormal,
|
fragNormal,
|
||||||
fragDiffuse,
|
fragAlbedo,
|
||||||
fragSpecular,
|
fragMetallic,
|
||||||
fragGloss),
|
fragEmissive,
|
||||||
|
fragRoughness),
|
||||||
fragOpacity);
|
fragOpacity);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
<@include model/Material.slh@>
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
uniform sampler2D diffuseMap;
|
uniform sampler2D albedoMap;
|
||||||
|
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
in vec3 _color;
|
in vec3 _color;
|
||||||
|
@ -23,11 +23,11 @@ in float _alpha;
|
||||||
out vec4 _fragColor;
|
out vec4 _fragColor;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
vec4 albedo = texture(albedoMap, _texCoord0);
|
||||||
|
|
||||||
Material mat = getMaterial();
|
Material mat = getMaterial();
|
||||||
vec3 fragColor = getMaterialDiffuse(mat) * diffuse.rgb * _color;
|
vec3 fragColor = getMaterialAlbedo(mat) * albedo.rgb * _color;
|
||||||
float fragOpacity = getMaterialOpacity(mat) * diffuse.a * _alpha;
|
float fragOpacity = getMaterialOpacity(mat) * albedo.a * _alpha;
|
||||||
|
|
||||||
_fragColor = vec4(fragColor, fragOpacity);
|
_fragColor = vec4(fragColor, fragOpacity);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<@include gpu/Transform.slh@>
|
<@include gpu/Transform.slh@>
|
||||||
<$declareStandardCameraTransform()$>
|
<$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
|
// Need the light now
|
||||||
Light light = getLight();
|
Light light = getLight();
|
||||||
|
@ -28,11 +28,11 @@ vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 d
|
||||||
vec3 fragEyeDir;
|
vec3 fragEyeDir;
|
||||||
<$transformEyeToWorldDir(cam, fragEyeVectorView, 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);
|
return vec4(color, opacity);
|
||||||
}
|
}
|
||||||
|
@ -48,14 +48,15 @@ in float _alpha;
|
||||||
out vec4 _fragColor;
|
out vec4 _fragColor;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 diffuse = texture(originalTexture, _texCoord0);
|
vec4 albedo = texture(originalTexture, _texCoord0);
|
||||||
|
|
||||||
vec3 fragPosition = _position.xyz;
|
vec3 fragPosition = _position.xyz;
|
||||||
vec3 fragNormal = normalize(_normal);
|
vec3 fragNormal = normalize(_normal);
|
||||||
vec3 fragDiffuse = diffuse.rgb * _color;
|
vec3 fragAlbedo = albedo.rgb * _color;
|
||||||
|
float fragMetallic = 0.0;
|
||||||
vec3 fragSpecular = vec3(0.1);
|
vec3 fragSpecular = vec3(0.1);
|
||||||
float fragGloss = 10.0 / 128.0;
|
float fragRoughness = 0.9;
|
||||||
float fragOpacity = diffuse.a;
|
float fragOpacity = albedo.a;
|
||||||
|
|
||||||
if (fragOpacity <= 0.1) {
|
if (fragOpacity <= 0.1) {
|
||||||
discard;
|
discard;
|
||||||
|
@ -64,9 +65,10 @@ void main(void) {
|
||||||
vec4 color = evalGlobalColor(1.0,
|
vec4 color = evalGlobalColor(1.0,
|
||||||
fragPosition,
|
fragPosition,
|
||||||
fragNormal,
|
fragNormal,
|
||||||
fragDiffuse,
|
fragAlbedo,
|
||||||
|
fragMetallic,
|
||||||
fragSpecular,
|
fragSpecular,
|
||||||
fragGloss,
|
fragRoughness,
|
||||||
fragOpacity);
|
fragOpacity);
|
||||||
|
|
||||||
// Apply standard tone mapping
|
// Apply standard tone mapping
|
||||||
|
|
|
@ -20,12 +20,12 @@ in vec3 _color;
|
||||||
out vec4 _fragColor;
|
out vec4 _fragColor;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 diffuse = texture(originalTexture, _texCoord0);
|
vec4 albedo = texture(originalTexture, _texCoord0);
|
||||||
|
|
||||||
if (diffuse.a <= 0.1) {
|
if (albedo.a <= 0.1) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
vec4 color = vec4(diffuse.rgb * _color, diffuse.a);
|
vec4 color = vec4(albedo.rgb * _color, albedo.a);
|
||||||
|
|
||||||
// Apply standard tone mapping
|
// Apply standard tone mapping
|
||||||
_fragColor = vec4(pow(color.xyz, vec3(1.0 / 2.2)), color.w);
|
_fragColor = vec4(pow(color.xyz, vec3(1.0 / 2.2)), color.w);
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<@include gpu/Transform.slh@>
|
<@include gpu/Transform.slh@>
|
||||||
<$declareStandardCameraTransform()$>
|
<$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
|
// Need the light now
|
||||||
Light light = getLight();
|
Light light = getLight();
|
||||||
|
@ -29,11 +29,11 @@ vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 d
|
||||||
vec3 fragEyeDir;
|
vec3 fragEyeDir;
|
||||||
<$transformEyeToWorldDir(cam, fragEyeVectorView, 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);
|
return vec4(color, opacity);
|
||||||
}
|
}
|
||||||
|
@ -49,21 +49,23 @@ in float _alpha;
|
||||||
out vec4 _fragColor;
|
out vec4 _fragColor;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 diffuse = texture(originalTexture, _texCoord0);
|
vec4 albedo = texture(originalTexture, _texCoord0);
|
||||||
|
|
||||||
vec3 fragPosition = _position.xyz;
|
vec3 fragPosition = _position.xyz;
|
||||||
vec3 fragNormal = normalize(_normal);
|
vec3 fragNormal = normalize(_normal);
|
||||||
vec3 fragDiffuse = diffuse.rgb * _color;
|
vec3 fragAlbedo = albedo.rgb * _color;
|
||||||
|
float fragMetallic = 0.0;
|
||||||
vec3 fragSpecular = vec3(0.1);
|
vec3 fragSpecular = vec3(0.1);
|
||||||
float fragGloss = 10.0 / 128.0;
|
float fragRoughness = 0.9;
|
||||||
float fragOpacity = diffuse.a * _alpha;
|
float fragOpacity = albedo.a * _alpha;
|
||||||
|
|
||||||
vec4 color = evalGlobalColor(1.0,
|
vec4 color = evalGlobalColor(1.0,
|
||||||
fragPosition,
|
fragPosition,
|
||||||
fragNormal,
|
fragNormal,
|
||||||
fragDiffuse,
|
fragAlbedo,
|
||||||
|
fragMetallic,
|
||||||
fragSpecular,
|
fragSpecular,
|
||||||
fragGloss,
|
fragRoughness,
|
||||||
fragOpacity);
|
fragOpacity);
|
||||||
|
|
||||||
// Apply standard tone mapping
|
// Apply standard tone mapping
|
||||||
|
|
|
@ -21,7 +21,7 @@ in float _alpha;
|
||||||
out vec4 _fragColor;
|
out vec4 _fragColor;
|
||||||
|
|
||||||
void main(void) {
|
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));
|
vec3 fragNormal = vec3(invViewMat * vec4(frag.normal, 0.0));
|
||||||
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
|
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
|
||||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
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
|
// Eval attenuation
|
||||||
float radialAttenuation = evalLightAttenuation(light, fragLightDistance);
|
float radialAttenuation = evalLightAttenuation(light, fragLightDistance);
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
|
<@include DeferredBufferWrite.slh@>
|
||||||
|
|
||||||
uniform sampler2D Font;
|
uniform sampler2D Font;
|
||||||
uniform bool Outline;
|
uniform bool Outline;
|
||||||
uniform vec4 Color;
|
uniform vec4 Color;
|
||||||
|
@ -17,12 +19,11 @@ uniform vec4 Color;
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
in vec3 _normal;
|
in vec3 _normal;
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
|
/*
|
||||||
layout(location = 0) out vec4 _fragColor0;
|
layout(location = 0) out vec4 _fragColor0;
|
||||||
layout(location = 1) out vec4 _fragColor1;
|
layout(location = 1) out vec4 _fragColor1;
|
||||||
layout(location = 2) out vec4 _fragColor2;
|
layout(location = 2) out vec4 _fragColor2;
|
||||||
|
*/
|
||||||
const float DEFAULT_SHININESS = 10;
|
|
||||||
|
|
||||||
const float gamma = 2.2;
|
const float gamma = 2.2;
|
||||||
const float smoothing = 256.0;
|
const float smoothing = 256.0;
|
||||||
|
@ -53,7 +54,16 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// final color
|
// 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);
|
_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) {
|
if (emissiveAmount > 0.0) {
|
||||||
packDeferredFragmentLightmap(
|
packDeferredFragmentLightmap(
|
||||||
normal, 1.0, diffuse, specular, shininess, specular);
|
normal, 1.0, diffuse, max(0, 1.0 - shininess / 128.0), DEFAULT_METALLIC, specular, specular);
|
||||||
} else {
|
} else {
|
||||||
packDeferredFragment(
|
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$>
|
<$VERSION_HEADER$>
|
||||||
// Generated on <$_SCRIBE_DATE$>
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
//
|
//
|
||||||
// simple.frag
|
// simple_textured.slf
|
||||||
// fragment shader
|
// fragment shader
|
||||||
//
|
//
|
||||||
// Created by Clément Brisset on 5/29/15.
|
// Created by Clément Brisset on 5/29/15.
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
<@include DeferredBufferWrite.slh@>
|
<@include DeferredBufferWrite.slh@>
|
||||||
<@include model/Material.slh@>
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
// the diffuse texture
|
// the albedo texture
|
||||||
uniform sampler2D originalTexture;
|
uniform sampler2D originalTexture;
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
|
@ -31,5 +31,8 @@ void main(void) {
|
||||||
normalize(_normal.xyz),
|
normalize(_normal.xyz),
|
||||||
texel.a,
|
texel.a,
|
||||||
_color.rgb * texel.rgb,
|
_color.rgb * texel.rgb,
|
||||||
DEFAULT_SPECULAR, DEFAULT_SHININESS);
|
DEFAULT_ROUGHNESS,
|
||||||
|
DEFAULT_METALLIC,
|
||||||
|
DEFAULT_EMISSIVE,
|
||||||
|
DEFAULT_OCCLUSION);
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
<@include DeferredBufferWrite.slh@>
|
<@include DeferredBufferWrite.slh@>
|
||||||
|
|
||||||
// the diffuse texture
|
// the albedo texture
|
||||||
uniform sampler2D originalTexture;
|
uniform sampler2D originalTexture;
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
|
@ -29,6 +29,8 @@ void main(void) {
|
||||||
normalize(_normal),
|
normalize(_normal),
|
||||||
texel.a,
|
texel.a,
|
||||||
_color.rgb,
|
_color.rgb,
|
||||||
DEFAULT_SPECULAR, DEFAULT_SHININESS,
|
DEFAULT_ROUGHNESS,
|
||||||
|
DEFAULT_METALLIC,
|
||||||
|
DEFAULT_SPECULAR,
|
||||||
texel.rgb);
|
texel.rgb);
|
||||||
}
|
}
|
|
@ -32,7 +32,7 @@ void main(void) {
|
||||||
|
|
||||||
skinPositionNormal(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, position, interpolatedNormal);
|
skinPositionNormal(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, position, interpolatedNormal);
|
||||||
|
|
||||||
// pass along the diffuse color
|
// pass along the color
|
||||||
_color = colorToLinearRGB(inColor.rgb);
|
_color = colorToLinearRGB(inColor.rgb);
|
||||||
|
|
||||||
// and the texture coordinates
|
// and the texture coordinates
|
||||||
|
|
|
@ -34,7 +34,7 @@ void main(void) {
|
||||||
|
|
||||||
skinPositionNormalTangent(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, inTangent.xyz, position, interpolatedNormal.xyz, interpolatedTangent.xyz);
|
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);
|
_color = colorToLinearRGB(inColor.rgb);
|
||||||
|
|
||||||
// and the texture coordinates
|
// and the texture coordinates
|
||||||
|
|
|
@ -66,7 +66,7 @@ void main(void) {
|
||||||
vec3 fragNormal = vec3(invViewMat * vec4(frag.normal, 0.0));
|
vec3 fragNormal = vec3(invViewMat * vec4(frag.normal, 0.0));
|
||||||
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
|
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
|
||||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
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
|
// Eval attenuation
|
||||||
float radialAttenuation = evalLightAttenuation(light, fragLightDistance);
|
float radialAttenuation = evalLightAttenuation(light, fragLightDistance);
|
||||||
|
|
|
@ -53,10 +53,12 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p
|
||||||
gpu::Shader::BindingSet slotBindings;
|
gpu::Shader::BindingSet slotBindings;
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), Slot::SKINNING_GPU));
|
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("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("normalMap"), Slot::NORMAL_MAP));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), Slot::SPECULAR_MAP));
|
slotBindings.insert(gpu::Shader::Binding(std::string("metallicMap"), Slot::METALLIC_MAP));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), Slot::LIGHTMAP_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("lightBuffer"), Slot::LIGHT_BUFFER));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), Slot::NORMAL_FITTING_MAP));
|
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->texcoordMatrices = program->getUniforms().findLocation("texcoordMatrices");
|
||||||
locations->emissiveParams = program->getUniforms().findLocation("emissiveParams");
|
locations->emissiveParams = program->getUniforms().findLocation("emissiveParams");
|
||||||
locations->normalFittingMapUnit = program->getTextures().findLocation("normalFittingMap");
|
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->normalTextureUnit = program->getTextures().findLocation("normalMap");
|
||||||
locations->specularTextureUnit = program->getTextures().findLocation("specularMap");
|
locations->metallicTextureUnit = program->getTextures().findLocation("metallicMap");
|
||||||
locations->emissiveTextureUnit = program->getTextures().findLocation("emissiveMap");
|
locations->emissiveTextureUnit = program->getTextures().findLocation("emissiveMap");
|
||||||
|
locations->occlusionTextureUnit = program->getTextures().findLocation("occlusionMap");
|
||||||
locations->skinClusterBufferUnit = program->getBuffers().findLocation("skinClusterBuffer");
|
locations->skinClusterBufferUnit = program->getBuffers().findLocation("skinClusterBuffer");
|
||||||
locations->materialBufferUnit = program->getBuffers().findLocation("materialBuffer");
|
locations->materialBufferUnit = program->getBuffers().findLocation("materialBuffer");
|
||||||
locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer");
|
locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer");
|
||||||
|
|
|
@ -195,10 +195,13 @@ public:
|
||||||
public:
|
public:
|
||||||
static const int SKINNING_GPU = 2;
|
static const int SKINNING_GPU = 2;
|
||||||
static const int MATERIAL_GPU = 3;
|
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 NORMAL_MAP = 1;
|
||||||
static const int SPECULAR_MAP = 2;
|
static const int METALLIC_MAP = 2;
|
||||||
static const int LIGHTMAP_MAP = 3;
|
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 LIGHT_BUFFER = 4;
|
||||||
static const int NORMAL_FITTING_MAP = 10;
|
static const int NORMAL_FITTING_MAP = 10;
|
||||||
};
|
};
|
||||||
|
@ -206,10 +209,12 @@ public:
|
||||||
class Locations {
|
class Locations {
|
||||||
public:
|
public:
|
||||||
int texcoordMatrices;
|
int texcoordMatrices;
|
||||||
int diffuseTextureUnit;
|
int albedoTextureUnit;
|
||||||
int normalTextureUnit;
|
int normalTextureUnit;
|
||||||
int specularTextureUnit;
|
int roughnessTextureUnit;
|
||||||
|
int metallicTextureUnit;
|
||||||
int emissiveTextureUnit;
|
int emissiveTextureUnit;
|
||||||
|
int occlusionTextureUnit;
|
||||||
int emissiveParams;
|
int emissiveParams;
|
||||||
int normalFittingMapUnit;
|
int normalFittingMapUnit;
|
||||||
int skinClusterBufferUnit;
|
int skinClusterBufferUnit;
|
||||||
|
|
|
@ -81,6 +81,11 @@ void SceneScripting::KeyLight::setAmbientSphere(const gpu::SHPointer& sphere) {
|
||||||
_skyStage->setSunAmbientSphere(sphere);
|
_skyStage->setSunAmbientSphere(sphere);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneScripting::KeyLight::setAmbientMap(const gpu::TexturePointer& map) {
|
||||||
|
_skyStage->setSunAmbientMap(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
glm::vec3 SceneScripting::KeyLight::getDirection() const {
|
glm::vec3 SceneScripting::KeyLight::getDirection() const {
|
||||||
return _skyStage->getSunDirection();
|
return _skyStage->getSunDirection();
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,7 @@ namespace SceneScripting {
|
||||||
// AmbientTexture is unscriptable - it must be set through the zone entity
|
// AmbientTexture is unscriptable - it must be set through the zone entity
|
||||||
void setAmbientSphere(const gpu::SHPointer& sphere);
|
void setAmbientSphere(const gpu::SHPointer& sphere);
|
||||||
void resetAmbientSphere() { setAmbientSphere(nullptr); }
|
void resetAmbientSphere() { setAmbientSphere(nullptr); }
|
||||||
|
void setAmbientMap(const gpu::TexturePointer& map);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
model::SunSkyStagePointer _skyStage;
|
model::SunSkyStagePointer _skyStage;
|
||||||
|
|
|
@ -24,5 +24,5 @@ void main(void) {
|
||||||
normalize(_normal.xyz),
|
normalize(_normal.xyz),
|
||||||
1.0,
|
1.0,
|
||||||
_color.rgb,
|
_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::Config::Pointer ConfigPointer;
|
||||||
typedef TextTemplate::Pointer TextTemplatePointer;
|
typedef TextTemplate::Pointer TextTemplatePointer;
|
||||||
|
|
||||||
|
const std::string TextTemplate::Tag::NULL_VAR = "_SCRIBE_NULL";
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
TextTemplate::Config::Config() :
|
TextTemplate::Config::Config() :
|
||||||
_includes(),
|
_includes(),
|
||||||
|
@ -370,7 +372,11 @@ bool TextTemplate::convertExpressionToFuncArguments(String& src, std::vector< St
|
||||||
token += c;
|
token += c;
|
||||||
} else if (c == ',') {
|
} else if (c == ',') {
|
||||||
if (!token.empty()) {
|
if (!token.empty()) {
|
||||||
arguments.push_back(token);
|
if (token == Tag::NULL_VAR) {
|
||||||
|
arguments.push_back(Tag::NULL_VAR);
|
||||||
|
} else {
|
||||||
|
arguments.push_back(token);
|
||||||
|
}
|
||||||
nbTokens++;
|
nbTokens++;
|
||||||
}
|
}
|
||||||
token.clear();
|
token.clear();
|
||||||
|
@ -750,7 +756,9 @@ int TextTemplate::evalBlockGeneration(std::ostream& dst, const BlockPointer& blo
|
||||||
paramCache.push_back((*it).second);
|
paramCache.push_back((*it).second);
|
||||||
(*it).second = val;
|
(*it).second = val;
|
||||||
} else {
|
} 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("");
|
paramCache.push_back("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,8 @@ public:
|
||||||
static const char VAR = '$';
|
static const char VAR = '$';
|
||||||
static const char COM = '@';
|
static const char COM = '@';
|
||||||
static const char REM = '!';
|
static const char REM = '!';
|
||||||
|
|
||||||
|
static const std::string NULL_VAR;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Command {
|
class Command {
|
||||||
|
|
Loading…
Reference in a new issue