mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-29 11:12:37 +02:00
Merge pull request #5517 from samcake/punk
Improving the quality of the normal encoding in the Deferred Buffer
This commit is contained in:
commit
0947bf2cd0
8 changed files with 47 additions and 3 deletions
BIN
interface/resources/images/normalFittingScale.dds
Normal file
BIN
interface/resources/images/normalFittingScale.dds
Normal file
Binary file not shown.
|
@ -21,6 +21,23 @@ uniform float glowIntensity;
|
||||||
// the alpha threshold
|
// the alpha threshold
|
||||||
uniform float alphaThreshold;
|
uniform float alphaThreshold;
|
||||||
|
|
||||||
|
uniform sampler2D normalFittingMap;
|
||||||
|
|
||||||
|
vec3 bestFitNormal(vec3 normal) {
|
||||||
|
vec3 absNorm = abs(normal);
|
||||||
|
float maxNAbs = max(absNorm.z, max(absNorm.x, absNorm.y));
|
||||||
|
|
||||||
|
vec2 texcoord = (absNorm.z < maxNAbs ?
|
||||||
|
(absNorm.y < maxNAbs ? absNorm.yz : absNorm.xz) :
|
||||||
|
absNorm.xy);
|
||||||
|
texcoord = (texcoord.x < texcoord.y ? texcoord.yx : texcoord.xy);
|
||||||
|
texcoord.y /= texcoord.x;
|
||||||
|
vec3 cN = normal / maxNAbs;
|
||||||
|
float fittingScale = texture(normalFittingMap, texcoord).a;
|
||||||
|
cN *= fittingScale;
|
||||||
|
return (cN * 0.5 + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
float evalOpaqueFinalAlpha(float alpha, float mapAlpha) {
|
float evalOpaqueFinalAlpha(float alpha, float mapAlpha) {
|
||||||
return mix(alpha * glowIntensity, 1.0 - alpha * glowIntensity, step(mapAlpha, alphaThreshold));
|
return mix(alpha * glowIntensity, 1.0 - alpha * glowIntensity, step(mapAlpha, alphaThreshold));
|
||||||
}
|
}
|
||||||
|
@ -33,7 +50,7 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 diffuse, vec3 specular,
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
_fragColor0 = vec4(diffuse.rgb, alpha);
|
_fragColor0 = vec4(diffuse.rgb, alpha);
|
||||||
_fragColor1 = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
_fragColor1 = vec4(bestFitNormal(normal), 1.0);
|
||||||
_fragColor2 = vec4(specular, shininess / 128.0);
|
_fragColor2 = vec4(specular, shininess / 128.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +61,7 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 diffuse, vec3 s
|
||||||
|
|
||||||
_fragColor0 = vec4(diffuse.rgb, alpha);
|
_fragColor0 = vec4(diffuse.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);
|
||||||
_fragColor1 = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5);
|
_fragColor1 = vec4(bestFitNormal(normal), 0.5);
|
||||||
_fragColor2 = vec4(emissive, shininess / 128.0);
|
_fragColor2 = vec4(emissive, shininess / 128.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) {
|
||||||
_emissiveShader = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PSEmissive));
|
_emissiveShader = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PSEmissive));
|
||||||
|
|
||||||
gpu::Shader::BindingSet slotBindings;
|
gpu::Shader::BindingSet slotBindings;
|
||||||
|
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT));
|
||||||
gpu::Shader::makeProgram(*_simpleShader, slotBindings);
|
gpu::Shader::makeProgram(*_simpleShader, slotBindings);
|
||||||
gpu::Shader::makeProgram(*_emissiveShader, slotBindings);
|
gpu::Shader::makeProgram(*_emissiveShader, slotBindings);
|
||||||
|
|
||||||
|
@ -151,6 +152,8 @@ void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured,
|
||||||
// If it is not textured, bind white texture and keep using textured pipeline
|
// If it is not textured, bind white texture and keep using textured pipeline
|
||||||
batch.setResourceTexture(0, DependencyManager::get<TextureCache>()->getWhiteTexture());
|
batch.setResourceTexture(0, DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
batch.setResourceTexture(NORMAL_FITTING_MAP_SLOT, DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeferredLightingEffect::renderSolidSphere(gpu::Batch& batch, float radius, int slices, int stacks, const glm::vec4& color) {
|
void DeferredLightingEffect::renderSolidSphere(gpu::Batch& batch, float radius, int slices, int stacks, const glm::vec4& color) {
|
||||||
|
|
|
@ -30,7 +30,8 @@ class DeferredLightingEffect : public Dependency {
|
||||||
SINGLETON_DEPENDENCY
|
SINGLETON_DEPENDENCY
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const int NORMAL_FITTING_MAP_SLOT = 10;
|
||||||
|
|
||||||
void init(AbstractViewStateInterface* viewState);
|
void init(AbstractViewStateInterface* viewState);
|
||||||
|
|
||||||
/// Sets up the state necessary to render static untextured geometry with the simple program.
|
/// Sets up the state necessary to render static untextured geometry with the simple program.
|
||||||
|
|
|
@ -105,6 +105,8 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2));
|
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), 3));
|
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), 3));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), 4));
|
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), 4));
|
||||||
|
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT));
|
||||||
|
|
||||||
|
|
||||||
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader));
|
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader));
|
||||||
gpu::Shader::makeProgram(*program, slotBindings);
|
gpu::Shader::makeProgram(*program, slotBindings);
|
||||||
|
@ -180,6 +182,8 @@ void Model::RenderPipelineLib::initLocations(gpu::ShaderPointer& program, Model:
|
||||||
locations.emissiveParams = program->getUniforms().findLocation("emissiveParams");
|
locations.emissiveParams = program->getUniforms().findLocation("emissiveParams");
|
||||||
locations.glowIntensity = program->getUniforms().findLocation("glowIntensity");
|
locations.glowIntensity = program->getUniforms().findLocation("glowIntensity");
|
||||||
|
|
||||||
|
locations.normalFittingMapUnit = program->getTextures().findLocation("normalFittingMap");
|
||||||
|
|
||||||
locations.specularTextureUnit = program->getTextures().findLocation("specularMap");
|
locations.specularTextureUnit = program->getTextures().findLocation("specularMap");
|
||||||
locations.emissiveTextureUnit = program->getTextures().findLocation("emissiveMap");
|
locations.emissiveTextureUnit = program->getTextures().findLocation("emissiveMap");
|
||||||
|
|
||||||
|
@ -1864,6 +1868,10 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
|
||||||
const float DEFAULT_GLOW_INTENSITY = 1.0f; // FIXME - glow is removed
|
const float DEFAULT_GLOW_INTENSITY = 1.0f; // FIXME - glow is removed
|
||||||
batch._glUniform1f(locations->glowIntensity, DEFAULT_GLOW_INTENSITY);
|
batch._glUniform1f(locations->glowIntensity, DEFAULT_GLOW_INTENSITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((locations->normalFittingMapUnit > -1)) {
|
||||||
|
batch.setResourceTexture(locations->normalFittingMapUnit, DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::initWhenReady(render::ScenePointer scene) {
|
bool Model::initWhenReady(render::ScenePointer scene) {
|
||||||
|
|
|
@ -350,6 +350,7 @@ private:
|
||||||
int emissiveTextureUnit;
|
int emissiveTextureUnit;
|
||||||
int emissiveParams;
|
int emissiveParams;
|
||||||
int glowIntensity;
|
int glowIntensity;
|
||||||
|
int normalFittingMapUnit;
|
||||||
int materialBufferUnit;
|
int materialBufferUnit;
|
||||||
int clusterMatrices;
|
int clusterMatrices;
|
||||||
int clusterIndices;
|
int clusterIndices;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <QRunnable>
|
#include <QRunnable>
|
||||||
#include <QThreadPool>
|
#include <QThreadPool>
|
||||||
#include <qimagereader.h>
|
#include <qimagereader.h>
|
||||||
|
#include "PathUtils.h"
|
||||||
|
|
||||||
#include <gpu/Batch.h>
|
#include <gpu/Batch.h>
|
||||||
|
|
||||||
|
@ -129,6 +130,14 @@ const gpu::TexturePointer& TextureCache::getBlackTexture() {
|
||||||
return _blackTexture;
|
return _blackTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const gpu::TexturePointer& TextureCache::getNormalFittingTexture() {
|
||||||
|
if (!_normalFittingTexture) {
|
||||||
|
_normalFittingTexture = getImageTexture(PathUtils::resourcesPath() + "images/normalFittingScale.dds");
|
||||||
|
}
|
||||||
|
return _normalFittingTexture;
|
||||||
|
}
|
||||||
|
|
||||||
/// Extra data for creating textures.
|
/// Extra data for creating textures.
|
||||||
class TextureExtra {
|
class TextureExtra {
|
||||||
public:
|
public:
|
||||||
|
@ -170,6 +179,7 @@ gpu::TexturePointer TextureCache::getImageTexture(const QString& path) {
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QSharedPointer<Resource> TextureCache::createResource(const QUrl& url,
|
QSharedPointer<Resource> TextureCache::createResource(const QUrl& url,
|
||||||
const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra) {
|
const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra) {
|
||||||
const TextureExtra* textureExtra = static_cast<const TextureExtra*>(extra);
|
const TextureExtra* textureExtra = static_cast<const TextureExtra*>(extra);
|
||||||
|
|
|
@ -54,6 +54,9 @@ public:
|
||||||
/// Returns the a black texture (useful for a default).
|
/// Returns the a black texture (useful for a default).
|
||||||
const gpu::TexturePointer& getBlackTexture();
|
const gpu::TexturePointer& getBlackTexture();
|
||||||
|
|
||||||
|
// Returns a map used to compress the normals through a fitting scale algorithm
|
||||||
|
const gpu::TexturePointer& getNormalFittingTexture();
|
||||||
|
|
||||||
/// Returns a texture version of an image file
|
/// Returns a texture version of an image file
|
||||||
static gpu::TexturePointer getImageTexture(const QString& path);
|
static gpu::TexturePointer getImageTexture(const QString& path);
|
||||||
|
|
||||||
|
@ -76,6 +79,7 @@ private:
|
||||||
gpu::TexturePointer _grayTexture;
|
gpu::TexturePointer _grayTexture;
|
||||||
gpu::TexturePointer _blueTexture;
|
gpu::TexturePointer _blueTexture;
|
||||||
gpu::TexturePointer _blackTexture;
|
gpu::TexturePointer _blackTexture;
|
||||||
|
gpu::TexturePointer _normalFittingTexture;
|
||||||
|
|
||||||
QHash<QUrl, QWeakPointer<NetworkTexture> > _dilatableNetworkTextures;
|
QHash<QUrl, QWeakPointer<NetworkTexture> > _dilatableNetworkTextures;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue