diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 2743c8b29d..1d34837a58 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -22,15 +22,6 @@ #include "render-utils/forward_simple_frag.h" #include "render-utils/forward_simple_transparent_frag.h" -#include - -#if defined(USE_GLES) -static bool DISABLE_DEFERRED = true; -#else -static const QString RENDER_FORWARD{ "HIFI_RENDER_FORWARD" }; -static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD); -#endif - #include "RenderPipelines.h" //#define SHAPE_ENTITY_USE_FADE_EFFECT @@ -47,8 +38,11 @@ static const float SPHERE_ENTITY_SCALE = 0.5f; ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Parent(entity) { _procedural._vertexSource = simple_vert::getSource(); - _procedural._opaquefragmentSource = DISABLE_DEFERRED ? forward_simple_frag::getSource() : simple_frag::getSource(); - _procedural._transparentfragmentSource = DISABLE_DEFERRED ? forward_simple_transparent_frag::getSource() : simple_transparent_frag::getSource(); + // FIXME: Setup proper uniform slots and use correct pipelines for forward rendering + _procedural._opaquefragmentSource = simple_frag::getSource(); + // FIXME: Transparent procedural entities only seem to work if they use the opaque pipelines + //_procedural._transparentfragmentSource = simple_transparent_frag::getSource(); + _procedural._transparentfragmentSource = simple_frag::getSource(); _procedural._opaqueState->setCullMode(gpu::State::CULL_NONE); _procedural._opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL); PrepareStencil::testMaskDrawShape(*_procedural._opaqueState); @@ -251,9 +245,9 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { if (proceduralRender) { if (render::ShapeKey(args->_globalShapeKey).isWireframe()) { - geometryCache->renderWireShapeColor(batch, geometryShape, outColor); + geometryCache->renderWireShape(batch, geometryShape, outColor); } else { - geometryCache->renderShapeColor(batch, geometryShape, outColor); + geometryCache->renderShape(batch, geometryShape, outColor); } } else if (!useMaterialPipeline()) { // FIXME, support instanced multi-shape rendering using multidraw indirect diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index 0488bb2eb7..c155d5bd7f 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -287,22 +287,25 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm _transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState); for (size_t i = 0; i < NUM_STANDARD_UNIFORMS; ++i) { const std::string& name = STANDARD_UNIFORM_NAMES[i]; - _standardUniformSlots[i] = _opaqueShader->getUniforms().findLocation(name); + _standardOpaqueUniformSlots[i] = _opaqueShader->getUniforms().findLocation(name); + _standardTransparentUniformSlots[i] = _transparentShader->getUniforms().findLocation(name); } _start = usecTimestampNow(); _frameCount = 0; } - batch.setPipeline(color.a < 1.0f ? _transparentPipeline : _opaquePipeline); + bool transparent = color.a < 1.0f; + batch.setPipeline(transparent ? _transparentPipeline : _opaquePipeline); - if (_shaderDirty || _uniformsDirty) { - setupUniforms(); + if (_shaderDirty || _uniformsDirty || _prevTransparent != transparent) { + setupUniforms(transparent); } - if (_shaderDirty || _uniformsDirty || _channelsDirty) { - setupChannels(_shaderDirty || _uniformsDirty); + if (_shaderDirty || _uniformsDirty || _channelsDirty || _prevTransparent != transparent) { + setupChannels(_shaderDirty || _uniformsDirty, transparent); } + _prevTransparent = transparent; _shaderDirty = _uniformsDirty = _channelsDirty = false; for (auto lambda : _uniforms) { @@ -328,12 +331,12 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm } } -void Procedural::setupUniforms() { +void Procedural::setupUniforms(bool transparent) { _uniforms.clear(); // Set any userdata specified uniforms foreach(QString key, _data.uniforms.keys()) { std::string uniformName = key.toLocal8Bit().data(); - int32_t slot = _opaqueShader->getUniforms().findLocation(uniformName); + int32_t slot = (transparent ? _transparentShader : _opaqueShader)->getUniforms().findLocation(uniformName); if (gpu::Shader::INVALID_LOCATION == slot) { continue; } @@ -394,15 +397,17 @@ void Procedural::setupUniforms() { } } - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[TIME]) { + auto uniformSlots = transparent ? _standardTransparentUniformSlots : _standardOpaqueUniformSlots; + + if (gpu::Shader::INVALID_LOCATION != uniformSlots[TIME]) { _uniforms.push_back([=](gpu::Batch& batch) { // Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds float time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND; - batch._glUniform(_standardUniformSlots[TIME], time); + batch._glUniform(uniformSlots[TIME], time); }); } - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[DATE]) { + if (gpu::Shader::INVALID_LOCATION != uniformSlots[DATE]) { _uniforms.push_back([=](gpu::Batch& batch) { QDateTime now = QDateTime::currentDateTimeUtc(); QDate date = now.date(); @@ -415,40 +420,41 @@ void Procedural::setupUniforms() { v.z = date.day(); float fractSeconds = (time.msec() / 1000.0f); v.w = (time.hour() * 3600) + (time.minute() * 60) + time.second() + fractSeconds; - batch._glUniform(_standardUniformSlots[DATE], v); + batch._glUniform(uniformSlots[DATE], v); }); } - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[FRAME_COUNT]) { + if (gpu::Shader::INVALID_LOCATION != uniformSlots[FRAME_COUNT]) { _uniforms.push_back([=](gpu::Batch& batch) { - batch._glUniform(_standardUniformSlots[FRAME_COUNT], ++_frameCount); + batch._glUniform(uniformSlots[FRAME_COUNT], ++_frameCount); }); } - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[SCALE]) { + if (gpu::Shader::INVALID_LOCATION != uniformSlots[SCALE]) { // FIXME move into the 'set once' section, since this doesn't change over time _uniforms.push_back([=](gpu::Batch& batch) { - batch._glUniform(_standardUniformSlots[SCALE], _entityDimensions); + batch._glUniform(uniformSlots[SCALE], _entityDimensions); }); } - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[ORIENTATION]) { + if (gpu::Shader::INVALID_LOCATION != uniformSlots[ORIENTATION]) { // FIXME move into the 'set once' section, since this doesn't change over time _uniforms.push_back([=](gpu::Batch& batch) { - batch._glUniform(_standardUniformSlots[ORIENTATION], _entityOrientation); + batch._glUniform(uniformSlots[ORIENTATION], _entityOrientation); }); } - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[POSITION]) { + if (gpu::Shader::INVALID_LOCATION != uniformSlots[POSITION]) { // FIXME move into the 'set once' section, since this doesn't change over time _uniforms.push_back([=](gpu::Batch& batch) { - batch._glUniform(_standardUniformSlots[POSITION], _entityPosition); + batch._glUniform(uniformSlots[POSITION], _entityPosition); }); } } -void Procedural::setupChannels(bool shouldCreate) { - if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[CHANNEL_RESOLUTION]) { +void Procedural::setupChannels(bool shouldCreate, bool transparent) { + auto uniformSlots = transparent ? _standardTransparentUniformSlots : _standardOpaqueUniformSlots; + if (gpu::Shader::INVALID_LOCATION != uniformSlots[CHANNEL_RESOLUTION]) { if (!shouldCreate) { // Instead of modifying the last element, just remove and recreate it. _uniforms.pop_back(); @@ -460,7 +466,7 @@ void Procedural::setupChannels(bool shouldCreate) { channelSizes[i] = vec3(_channels[i]->getWidth(), _channels[i]->getHeight(), 1.0); } } - batch._glUniform3fv(_standardUniformSlots[CHANNEL_RESOLUTION], MAX_PROCEDURAL_TEXTURE_CHANNELS, &channelSizes[0].x); + batch._glUniform3fv(uniformSlots[CHANNEL_RESOLUTION], MAX_PROCEDURAL_TEXTURE_CHANNELS, &channelSizes[0].x); }); } } diff --git a/libraries/procedural/src/procedural/Procedural.h b/libraries/procedural/src/procedural/Procedural.h index 4e30a003d6..1d3b0b3b5a 100644 --- a/libraries/procedural/src/procedural/Procedural.h +++ b/libraries/procedural/src/procedural/Procedural.h @@ -102,7 +102,8 @@ protected: // Rendering objects UniformLambdas _uniforms; - int32_t _standardUniformSlots[NUM_STANDARD_UNIFORMS]; + int32_t _standardOpaqueUniformSlots[NUM_STANDARD_UNIFORMS]; + int32_t _standardTransparentUniformSlots[NUM_STANDARD_UNIFORMS]; NetworkTexturePointer _channels[MAX_PROCEDURAL_TEXTURE_CHANNELS]; gpu::PipelinePointer _opaquePipeline; gpu::PipelinePointer _transparentPipeline; @@ -119,8 +120,8 @@ protected: private: // This should only be called from the render thread, as it shares data with Procedural::prepare - void setupUniforms(); - void setupChannels(bool shouldCreate); + void setupUniforms(bool transparent); + void setupChannels(bool shouldCreate, bool transparent); std::string replaceProceduralBlock(const std::string& fragmentSource); @@ -128,6 +129,7 @@ private: mutable bool _hasStartedFade { false }; mutable bool _isFading { false }; bool _doesFade { true }; + bool _prevTransparent { false }; }; #endif diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 52dc1d6cac..ecfa9881a3 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -845,20 +845,6 @@ void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape, const glm::v _shapes[shape].drawWire(batch); } -void GeometryCache::renderShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color) { - batch.setInputFormat(getInstancedSolidStreamFormat()); - // Color must be set after input format - batch._glColor4f(color.r, color.g, color.b, color.a); - _shapes[shape].draw(batch); -} - -void GeometryCache::renderWireShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color) { - batch.setInputFormat(getInstancedSolidStreamFormat()); - // Color must be set after input format - batch._glColor4f(color.r, color.g, color.b, color.a); - _shapes[shape].drawWire(batch); -} - void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) { gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT); batch.setInputBuffer(gpu::Stream::COLOR, colorView); @@ -2265,7 +2251,8 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp std::call_once(once, [&]() { auto VS = simple_vert::getShader(); auto PS = DISABLE_DEFERRED ? forward_simple_textured_frag::getShader() : simple_textured_frag::getShader(); - auto PSTransparent = DISABLE_DEFERRED ? forward_simple_textured_transparent_frag::getShader() : simple_transparent_textured_frag::getShader(); + // Use the forward pipeline for both here, otherwise transparents will be unlit + auto PSTransparent = DISABLE_DEFERRED ? forward_simple_textured_transparent_frag::getShader() : forward_simple_textured_transparent_frag::getShader(); auto PSUnlit = DISABLE_DEFERRED ? forward_simple_textured_unlit_frag::getShader() : simple_textured_unlit_frag::getShader(); _simpleShader = gpu::Shader::createProgram(VS, PS); diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index bec166aded..fcbf5ee128 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -253,8 +253,6 @@ public: void renderWireShape(gpu::Batch& batch, Shape shape); void renderShape(gpu::Batch& batch, Shape shape, const glm::vec4& color); void renderWireShape(gpu::Batch& batch, Shape shape, const glm::vec4& color); - void renderShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color); - void renderWireShapeColor(gpu::Batch& batch, Shape shape, const glm::vec4& color); size_t getShapeTriangleCount(Shape shape); void renderCube(gpu::Batch& batch); diff --git a/libraries/render-utils/src/forward_simple.slf b/libraries/render-utils/src/forward_simple.slf index 497afe93a3..ac2aa63697 100644 --- a/libraries/render-utils/src/forward_simple.slf +++ b/libraries/render-utils/src/forward_simple.slf @@ -16,14 +16,12 @@ <@include ForwardGlobalLight.slh@> <$declareEvalSkyboxGlobalColor()$> -<@include gpu/Transform.slh@> -<$declareStandardCameraTransform()$> - // the interpolated normal in vec3 _normal; in vec3 _modelNormal; in vec4 _color; in vec2 _texCoord0; +in vec4 _position; in vec4 _eyePosition; layout(location = 0) out vec4 _fragColor0; @@ -35,12 +33,12 @@ layout(location = 0) out vec4 _fragColor0; #line 2030 void main(void) { - vec3 normal = normalize(_normal.xyz); - vec3 diffuse = _color.rgb; + vec3 normal = normalize(_normal.xyz); + vec3 diffuse = _color.rgb; vec3 specular = DEFAULT_SPECULAR; float shininess = DEFAULT_SHININESS; float emissiveAmount = 0.0; - + #ifdef PROCEDURAL #ifdef PROCEDURAL_V1 @@ -48,7 +46,7 @@ void main(void) { // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline //specular = pow(specular, vec3(2.2)); emissiveAmount = 1.0; -#else +#else emissiveAmount = getProceduralColors(diffuse, specular, shininess); #endif diff --git a/libraries/render-utils/src/forward_simple_textured_unlit.slf b/libraries/render-utils/src/forward_simple_textured_unlit.slf index b65de16c61..0cc241b75e 100644 --- a/libraries/render-utils/src/forward_simple_textured_unlit.slf +++ b/libraries/render-utils/src/forward_simple_textured_unlit.slf @@ -25,11 +25,7 @@ in vec2 _texCoord0; void main(void) { vec4 texel = texture(originalTexture, _texCoord0.st); - float colorAlpha = _color.a; - if (_color.a <= 0.0) { - texel = color_sRGBAToLinear(texel); - colorAlpha = -_color.a; - } + float colorAlpha = _color.a * texel.a; - _fragColor0 = vec4(_color.rgb * texel.rgb * isUnlitEnabled(), colorAlpha * texel.a); + _fragColor0 = vec4(_color.rgb * texel.rgb * isUnlitEnabled(), colorAlpha); } \ No newline at end of file diff --git a/libraries/render-utils/src/forward_simple_transparent.slf b/libraries/render-utils/src/forward_simple_transparent.slf index 4c7a2df6a6..551e10282a 100644 --- a/libraries/render-utils/src/forward_simple_transparent.slf +++ b/libraries/render-utils/src/forward_simple_transparent.slf @@ -16,9 +16,6 @@ <@include ForwardGlobalLight.slh@> <$declareEvalGlobalLightingAlphaBlended()$> -<@include gpu/Transform.slh@> -<$declareStandardCameraTransform()$> - // the interpolated normal in vec3 _normal; in vec3 _modelNormal; @@ -35,12 +32,12 @@ layout(location = 0) out vec4 _fragColor0; #line 2030 void main(void) { - vec3 normal = normalize(_normal.xyz); - vec3 diffuse = _color.rgb; + vec3 normal = normalize(_normal.xyz); + vec3 diffuse = _color.rgb; vec3 specular = DEFAULT_SPECULAR; float shininess = DEFAULT_SHININESS; float emissiveAmount = 0.0; - + #ifdef PROCEDURAL #ifdef PROCEDURAL_V1 @@ -48,7 +45,7 @@ void main(void) { // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline //specular = pow(specular, vec3(2.2)); emissiveAmount = 1.0; -#else +#else emissiveAmount = getProceduralColors(diffuse, specular, shininess); #endif diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index 8e7df452cc..1c2ad9a413 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -28,8 +28,8 @@ in vec4 _position; #line 2030 void main(void) { - vec3 normal = normalize(_normal.xyz); - vec3 diffuse = _color.rgb; + vec3 normal = normalize(_normal.xyz); + vec3 diffuse = _color.rgb; vec3 specular = DEFAULT_SPECULAR; float shininess = DEFAULT_SHININESS; float emissiveAmount = 0.0; @@ -41,7 +41,7 @@ void main(void) { // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline //specular = pow(specular, vec3(2.2)); emissiveAmount = 1.0; -#else +#else emissiveAmount = getProceduralColors(diffuse, specular, shininess); #endif diff --git a/libraries/render-utils/src/simple_fade.slf b/libraries/render-utils/src/simple_fade.slf index ce9251b9a5..1c74612ff0 100644 --- a/libraries/render-utils/src/simple_fade.slf +++ b/libraries/render-utils/src/simple_fade.slf @@ -13,7 +13,6 @@ // <@include DeferredBufferWrite.slh@> -<@include graphics/Material.slh@> <@include Fade.slh@> <$declareFadeFragmentInstanced()$> @@ -39,7 +38,6 @@ void main(void) { <$fetchFadeObjectParamsInstanced(fadeParams)$> applyFade(fadeParams, _worldPosition.xyz, fadeEmissive); - Material material = getMaterial(); vec3 normal = normalize(_normal.xyz); vec3 diffuse = _color.rgb; vec3 specular = DEFAULT_SPECULAR; diff --git a/libraries/render-utils/src/simple_textured_fade.slf b/libraries/render-utils/src/simple_textured_fade.slf index d378e7a5c1..e5ecd94852 100644 --- a/libraries/render-utils/src/simple_textured_fade.slf +++ b/libraries/render-utils/src/simple_textured_fade.slf @@ -14,7 +14,6 @@ <@include gpu/Color.slh@> <@include DeferredBufferWrite.slh@> -<@include graphics/Material.slh@> <@include Fade.slh@> diff --git a/libraries/render-utils/src/simple_transparent.slf b/libraries/render-utils/src/simple_transparent.slf index fe544d1283..65ffe0504a 100644 --- a/libraries/render-utils/src/simple_transparent.slf +++ b/libraries/render-utils/src/simple_transparent.slf @@ -28,8 +28,8 @@ in vec4 _position; #line 2030 void main(void) { - vec3 normal = normalize(_normal.xyz); - vec3 diffuse = _color.rgb; + vec3 normal = normalize(_normal.xyz); + vec3 diffuse = _color.rgb; vec3 specular = DEFAULT_SPECULAR; float shininess = DEFAULT_SHININESS; float emissiveAmount = 0.0; @@ -41,7 +41,7 @@ void main(void) { // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline //specular = pow(specular, vec3(2.2)); emissiveAmount = 1.0; -#else +#else emissiveAmount = getProceduralColors(diffuse, specular, shininess); #endif