cleanup and fix forward procedural rendering

This commit is contained in:
SamGondelman 2018-04-10 17:10:29 -07:00
parent d841eeb6e9
commit e0b2c076ef
12 changed files with 60 additions and 85 deletions

View file

@ -22,15 +22,6 @@
#include "render-utils/forward_simple_frag.h"
#include "render-utils/forward_simple_transparent_frag.h"
#include <QProcess>
#if defined(USE_GLES)
static bool DISABLE_DEFERRED = true;
#else
static const QString RENDER_FORWARD{ "HIFI_RENDER_FORWARD" };
static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD);
#endif
#include "RenderPipelines.h"
//#define SHAPE_ENTITY_USE_FADE_EFFECT
@ -47,8 +38,11 @@ static const float SPHERE_ENTITY_SCALE = 0.5f;
ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {
_procedural._vertexSource = simple_vert::getSource();
_procedural._opaquefragmentSource = DISABLE_DEFERRED ? forward_simple_frag::getSource() : simple_frag::getSource();
_procedural._transparentfragmentSource = DISABLE_DEFERRED ? forward_simple_transparent_frag::getSource() : simple_transparent_frag::getSource();
// FIXME: Setup proper uniform slots and use correct pipelines for forward rendering
_procedural._opaquefragmentSource = simple_frag::getSource();
// FIXME: Transparent procedural entities only seem to work if they use the opaque pipelines
//_procedural._transparentfragmentSource = simple_transparent_frag::getSource();
_procedural._transparentfragmentSource = simple_frag::getSource();
_procedural._opaqueState->setCullMode(gpu::State::CULL_NONE);
_procedural._opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL);
PrepareStencil::testMaskDrawShape(*_procedural._opaqueState);
@ -251,9 +245,9 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
if (proceduralRender) {
if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
geometryCache->renderWireShapeColor(batch, geometryShape, outColor);
geometryCache->renderWireShape(batch, geometryShape, outColor);
} else {
geometryCache->renderShapeColor(batch, geometryShape, outColor);
geometryCache->renderShape(batch, geometryShape, outColor);
}
} else if (!useMaterialPipeline()) {
// FIXME, support instanced multi-shape rendering using multidraw indirect

View file

@ -287,22 +287,25 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm
_transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState);
for (size_t i = 0; i < NUM_STANDARD_UNIFORMS; ++i) {
const std::string& name = STANDARD_UNIFORM_NAMES[i];
_standardUniformSlots[i] = _opaqueShader->getUniforms().findLocation(name);
_standardOpaqueUniformSlots[i] = _opaqueShader->getUniforms().findLocation(name);
_standardTransparentUniformSlots[i] = _transparentShader->getUniforms().findLocation(name);
}
_start = usecTimestampNow();
_frameCount = 0;
}
batch.setPipeline(color.a < 1.0f ? _transparentPipeline : _opaquePipeline);
bool transparent = color.a < 1.0f;
batch.setPipeline(transparent ? _transparentPipeline : _opaquePipeline);
if (_shaderDirty || _uniformsDirty) {
setupUniforms();
if (_shaderDirty || _uniformsDirty || _prevTransparent != transparent) {
setupUniforms(transparent);
}
if (_shaderDirty || _uniformsDirty || _channelsDirty) {
setupChannels(_shaderDirty || _uniformsDirty);
if (_shaderDirty || _uniformsDirty || _channelsDirty || _prevTransparent != transparent) {
setupChannels(_shaderDirty || _uniformsDirty, transparent);
}
_prevTransparent = transparent;
_shaderDirty = _uniformsDirty = _channelsDirty = false;
for (auto lambda : _uniforms) {
@ -328,12 +331,12 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm
}
}
void Procedural::setupUniforms() {
void Procedural::setupUniforms(bool transparent) {
_uniforms.clear();
// Set any userdata specified uniforms
foreach(QString key, _data.uniforms.keys()) {
std::string uniformName = key.toLocal8Bit().data();
int32_t slot = _opaqueShader->getUniforms().findLocation(uniformName);
int32_t slot = (transparent ? _transparentShader : _opaqueShader)->getUniforms().findLocation(uniformName);
if (gpu::Shader::INVALID_LOCATION == slot) {
continue;
}
@ -394,15 +397,17 @@ void Procedural::setupUniforms() {
}
}
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[TIME]) {
auto uniformSlots = transparent ? _standardTransparentUniformSlots : _standardOpaqueUniformSlots;
if (gpu::Shader::INVALID_LOCATION != uniformSlots[TIME]) {
_uniforms.push_back([=](gpu::Batch& batch) {
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
float time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND;
batch._glUniform(_standardUniformSlots[TIME], time);
batch._glUniform(uniformSlots[TIME], time);
});
}
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[DATE]) {
if (gpu::Shader::INVALID_LOCATION != uniformSlots[DATE]) {
_uniforms.push_back([=](gpu::Batch& batch) {
QDateTime now = QDateTime::currentDateTimeUtc();
QDate date = now.date();
@ -415,40 +420,41 @@ void Procedural::setupUniforms() {
v.z = date.day();
float fractSeconds = (time.msec() / 1000.0f);
v.w = (time.hour() * 3600) + (time.minute() * 60) + time.second() + fractSeconds;
batch._glUniform(_standardUniformSlots[DATE], v);
batch._glUniform(uniformSlots[DATE], v);
});
}
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[FRAME_COUNT]) {
if (gpu::Shader::INVALID_LOCATION != uniformSlots[FRAME_COUNT]) {
_uniforms.push_back([=](gpu::Batch& batch) {
batch._glUniform(_standardUniformSlots[FRAME_COUNT], ++_frameCount);
batch._glUniform(uniformSlots[FRAME_COUNT], ++_frameCount);
});
}
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[SCALE]) {
if (gpu::Shader::INVALID_LOCATION != uniformSlots[SCALE]) {
// FIXME move into the 'set once' section, since this doesn't change over time
_uniforms.push_back([=](gpu::Batch& batch) {
batch._glUniform(_standardUniformSlots[SCALE], _entityDimensions);
batch._glUniform(uniformSlots[SCALE], _entityDimensions);
});
}
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[ORIENTATION]) {
if (gpu::Shader::INVALID_LOCATION != uniformSlots[ORIENTATION]) {
// FIXME move into the 'set once' section, since this doesn't change over time
_uniforms.push_back([=](gpu::Batch& batch) {
batch._glUniform(_standardUniformSlots[ORIENTATION], _entityOrientation);
batch._glUniform(uniformSlots[ORIENTATION], _entityOrientation);
});
}
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[POSITION]) {
if (gpu::Shader::INVALID_LOCATION != uniformSlots[POSITION]) {
// FIXME move into the 'set once' section, since this doesn't change over time
_uniforms.push_back([=](gpu::Batch& batch) {
batch._glUniform(_standardUniformSlots[POSITION], _entityPosition);
batch._glUniform(uniformSlots[POSITION], _entityPosition);
});
}
}
void Procedural::setupChannels(bool shouldCreate) {
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[CHANNEL_RESOLUTION]) {
void Procedural::setupChannels(bool shouldCreate, bool transparent) {
auto uniformSlots = transparent ? _standardTransparentUniformSlots : _standardOpaqueUniformSlots;
if (gpu::Shader::INVALID_LOCATION != uniformSlots[CHANNEL_RESOLUTION]) {
if (!shouldCreate) {
// Instead of modifying the last element, just remove and recreate it.
_uniforms.pop_back();
@ -460,7 +466,7 @@ void Procedural::setupChannels(bool shouldCreate) {
channelSizes[i] = vec3(_channels[i]->getWidth(), _channels[i]->getHeight(), 1.0);
}
}
batch._glUniform3fv(_standardUniformSlots[CHANNEL_RESOLUTION], MAX_PROCEDURAL_TEXTURE_CHANNELS, &channelSizes[0].x);
batch._glUniform3fv(uniformSlots[CHANNEL_RESOLUTION], MAX_PROCEDURAL_TEXTURE_CHANNELS, &channelSizes[0].x);
});
}
}

View file

@ -102,7 +102,8 @@ protected:
// Rendering objects
UniformLambdas _uniforms;
int32_t _standardUniformSlots[NUM_STANDARD_UNIFORMS];
int32_t _standardOpaqueUniformSlots[NUM_STANDARD_UNIFORMS];
int32_t _standardTransparentUniformSlots[NUM_STANDARD_UNIFORMS];
NetworkTexturePointer _channels[MAX_PROCEDURAL_TEXTURE_CHANNELS];
gpu::PipelinePointer _opaquePipeline;
gpu::PipelinePointer _transparentPipeline;
@ -119,8 +120,8 @@ protected:
private:
// This should only be called from the render thread, as it shares data with Procedural::prepare
void setupUniforms();
void setupChannels(bool shouldCreate);
void setupUniforms(bool transparent);
void setupChannels(bool shouldCreate, bool transparent);
std::string replaceProceduralBlock(const std::string& fragmentSource);
@ -128,6 +129,7 @@ private:
mutable bool _hasStartedFade { false };
mutable bool _isFading { false };
bool _doesFade { true };
bool _prevTransparent { false };
};
#endif

View file

@ -845,20 +845,6 @@ void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape, const glm::v
_shapes[shape].drawWire(batch);
}
void GeometryCache::renderShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color) {
batch.setInputFormat(getInstancedSolidStreamFormat());
// Color must be set after input format
batch._glColor4f(color.r, color.g, color.b, color.a);
_shapes[shape].draw(batch);
}
void GeometryCache::renderWireShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color) {
batch.setInputFormat(getInstancedSolidStreamFormat());
// Color must be set after input format
batch._glColor4f(color.r, color.g, color.b, color.a);
_shapes[shape].drawWire(batch);
}
void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) {
gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT);
batch.setInputBuffer(gpu::Stream::COLOR, colorView);
@ -2265,7 +2251,8 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp
std::call_once(once, [&]() {
auto VS = simple_vert::getShader();
auto PS = DISABLE_DEFERRED ? forward_simple_textured_frag::getShader() : simple_textured_frag::getShader();
auto PSTransparent = DISABLE_DEFERRED ? forward_simple_textured_transparent_frag::getShader() : simple_transparent_textured_frag::getShader();
// Use the forward pipeline for both here, otherwise transparents will be unlit
auto PSTransparent = DISABLE_DEFERRED ? forward_simple_textured_transparent_frag::getShader() : forward_simple_textured_transparent_frag::getShader();
auto PSUnlit = DISABLE_DEFERRED ? forward_simple_textured_unlit_frag::getShader() : simple_textured_unlit_frag::getShader();
_simpleShader = gpu::Shader::createProgram(VS, PS);

View file

@ -253,8 +253,6 @@ public:
void renderWireShape(gpu::Batch& batch, Shape shape);
void renderShape(gpu::Batch& batch, Shape shape, const glm::vec4& color);
void renderWireShape(gpu::Batch& batch, Shape shape, const glm::vec4& color);
void renderShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color);
void renderWireShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color);
size_t getShapeTriangleCount(Shape shape);
void renderCube(gpu::Batch& batch);

View file

@ -16,14 +16,12 @@
<@include ForwardGlobalLight.slh@>
<$declareEvalSkyboxGlobalColor()$>
<@include gpu/Transform.slh@>
<$declareStandardCameraTransform()$>
// the interpolated normal
in vec3 _normal;
in vec3 _modelNormal;
in vec4 _color;
in vec2 _texCoord0;
in vec4 _position;
in vec4 _eyePosition;
layout(location = 0) out vec4 _fragColor0;
@ -35,12 +33,12 @@ layout(location = 0) out vec4 _fragColor0;
#line 2030
void main(void) {
vec3 normal = normalize(_normal.xyz);
vec3 diffuse = _color.rgb;
vec3 normal = normalize(_normal.xyz);
vec3 diffuse = _color.rgb;
vec3 specular = DEFAULT_SPECULAR;
float shininess = DEFAULT_SHININESS;
float emissiveAmount = 0.0;
#ifdef PROCEDURAL
#ifdef PROCEDURAL_V1
@ -48,7 +46,7 @@ void main(void) {
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
//specular = pow(specular, vec3(2.2));
emissiveAmount = 1.0;
#else
#else
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
#endif

View file

@ -25,11 +25,7 @@ in vec2 _texCoord0;
void main(void) {
vec4 texel = texture(originalTexture, _texCoord0.st);
float colorAlpha = _color.a;
if (_color.a <= 0.0) {
texel = color_sRGBAToLinear(texel);
colorAlpha = -_color.a;
}
float colorAlpha = _color.a * texel.a;
_fragColor0 = vec4(_color.rgb * texel.rgb * isUnlitEnabled(), colorAlpha * texel.a);
_fragColor0 = vec4(_color.rgb * texel.rgb * isUnlitEnabled(), colorAlpha);
}

View file

@ -16,9 +16,6 @@
<@include ForwardGlobalLight.slh@>
<$declareEvalGlobalLightingAlphaBlended()$>
<@include gpu/Transform.slh@>
<$declareStandardCameraTransform()$>
// the interpolated normal
in vec3 _normal;
in vec3 _modelNormal;
@ -35,12 +32,12 @@ layout(location = 0) out vec4 _fragColor0;
#line 2030
void main(void) {
vec3 normal = normalize(_normal.xyz);
vec3 diffuse = _color.rgb;
vec3 normal = normalize(_normal.xyz);
vec3 diffuse = _color.rgb;
vec3 specular = DEFAULT_SPECULAR;
float shininess = DEFAULT_SHININESS;
float emissiveAmount = 0.0;
#ifdef PROCEDURAL
#ifdef PROCEDURAL_V1
@ -48,7 +45,7 @@ void main(void) {
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
//specular = pow(specular, vec3(2.2));
emissiveAmount = 1.0;
#else
#else
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
#endif

View file

@ -28,8 +28,8 @@ in vec4 _position;
#line 2030
void main(void) {
vec3 normal = normalize(_normal.xyz);
vec3 diffuse = _color.rgb;
vec3 normal = normalize(_normal.xyz);
vec3 diffuse = _color.rgb;
vec3 specular = DEFAULT_SPECULAR;
float shininess = DEFAULT_SHININESS;
float emissiveAmount = 0.0;
@ -41,7 +41,7 @@ void main(void) {
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
//specular = pow(specular, vec3(2.2));
emissiveAmount = 1.0;
#else
#else
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
#endif

View file

@ -13,7 +13,6 @@
//
<@include DeferredBufferWrite.slh@>
<@include graphics/Material.slh@>
<@include Fade.slh@>
<$declareFadeFragmentInstanced()$>
@ -39,7 +38,6 @@ void main(void) {
<$fetchFadeObjectParamsInstanced(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material material = getMaterial();
vec3 normal = normalize(_normal.xyz);
vec3 diffuse = _color.rgb;
vec3 specular = DEFAULT_SPECULAR;

View file

@ -14,7 +14,6 @@
<@include gpu/Color.slh@>
<@include DeferredBufferWrite.slh@>
<@include graphics/Material.slh@>
<@include Fade.slh@>

View file

@ -28,8 +28,8 @@ in vec4 _position;
#line 2030
void main(void) {
vec3 normal = normalize(_normal.xyz);
vec3 diffuse = _color.rgb;
vec3 normal = normalize(_normal.xyz);
vec3 diffuse = _color.rgb;
vec3 specular = DEFAULT_SPECULAR;
float shininess = DEFAULT_SHININESS;
float emissiveAmount = 0.0;
@ -41,7 +41,7 @@ void main(void) {
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
//specular = pow(specular, vec3(2.2));
emissiveAmount = 1.0;
#else
#else
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
#endif