mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 05:33:10 +02:00
Merged with 21378
This commit is contained in:
commit
018c0489f4
60 changed files with 3834 additions and 161 deletions
BIN
interface/resources/images/fadeMask.png
Normal file
BIN
interface/resources/images/fadeMask.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
|
@ -945,6 +945,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// Make sure we don't time out during slow operations at startup
|
||||
updateHeartbeat();
|
||||
|
||||
// Now that OpenGL is initialized, we are sure we have a valid context and can create the various pipeline shaders with success.
|
||||
DependencyManager::get<GeometryCache>()->initializeShapePipelines();
|
||||
|
||||
// sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value.
|
||||
// The value will be 0 if the user blew away settings this session, which is both a feature and a bug.
|
||||
|
|
|
@ -55,12 +55,18 @@
|
|||
|
||||
#include "EntityTreeRenderer.h"
|
||||
#include "polyvox_vert.h"
|
||||
#include "polyvox_fade_vert.h"
|
||||
#include "polyvox_frag.h"
|
||||
#include "polyvox_fade_frag.h"
|
||||
|
||||
#include "RenderablePolyVoxEntityItem.h"
|
||||
#include "EntityEditPacketSender.h"
|
||||
#include "PhysicalEntitySimulation.h"
|
||||
|
||||
gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr;
|
||||
gpu::PipelinePointer RenderablePolyVoxEntityItem::_wireframePipeline = nullptr;
|
||||
#include "FadeEffect.h"
|
||||
|
||||
gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipelines[2] = { nullptr, nullptr };
|
||||
gpu::PipelinePointer RenderablePolyVoxEntityItem::_wireframePipelines[2] = { nullptr, nullptr };
|
||||
|
||||
const float MARCHING_CUBE_COLLISION_HULL_OFFSET = 0.5;
|
||||
|
||||
|
@ -733,33 +739,37 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!_pipeline) {
|
||||
gpu::ShaderPointer vertexShader = gpu::Shader::createVertex(std::string(polyvox_vert));
|
||||
gpu::ShaderPointer pixelShader = gpu::Shader::createPixel(std::string(polyvox_frag));
|
||||
if (!_pipelines[0]) {
|
||||
gpu::ShaderPointer vertexShaders[2] = { gpu::Shader::createVertex(std::string(polyvox_vert)), gpu::Shader::createVertex(std::string(polyvox_fade_vert)) };
|
||||
gpu::ShaderPointer pixelShaders[2] = { gpu::Shader::createPixel(std::string(polyvox_frag)), gpu::Shader::createPixel(std::string(polyvox_fade_frag)) };
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("fadeParametersBuffer"), render::ShapePipeline::Slot::BUFFER::FADE_PARAMETERS));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("xMap"), 0));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("yMap"), 1));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("zMap"), 2));
|
||||
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vertexShader, pixelShader);
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), render::ShapePipeline::Slot::MAP::FADE_MASK));
|
||||
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
state->setCullMode(gpu::State::CULL_BACK);
|
||||
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
PrepareStencil::testMaskDrawShape(*state);
|
||||
|
||||
_pipeline = gpu::Pipeline::create(program, state);
|
||||
|
||||
auto wireframeState = std::make_shared<gpu::State>();
|
||||
wireframeState->setCullMode(gpu::State::CULL_BACK);
|
||||
wireframeState->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
wireframeState->setFillMode(gpu::State::FILL_LINE);
|
||||
PrepareStencil::testMaskDrawShape(*wireframeState);
|
||||
|
||||
_wireframePipeline = gpu::Pipeline::create(program, wireframeState);
|
||||
// Two sets of pipelines: normal and fading
|
||||
for (auto i = 0; i < 2; i++) {
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vertexShaders[i], pixelShaders[i]);
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
_pipelines[i] = gpu::Pipeline::create(program, state);
|
||||
_wireframePipelines[i] = gpu::Pipeline::create(program, wireframeState);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_vertexFormat) {
|
||||
|
@ -773,7 +783,8 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
|||
|
||||
// Pick correct Pipeline
|
||||
bool wireframe = (render::ShapeKey(args->_globalShapeKey).isWireframe());
|
||||
auto pipeline = (wireframe ? _wireframePipeline : _pipeline);
|
||||
auto pipelineVariation = isFading() & 1;
|
||||
auto pipeline = (wireframe ? _wireframePipelines[pipelineVariation]: _pipelines[pipelineVariation]);
|
||||
batch.setPipeline(pipeline);
|
||||
|
||||
Transform transform(voxelToWorldMatrix());
|
||||
|
@ -817,6 +828,12 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
|||
batch.setResourceTexture(2, DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
}
|
||||
|
||||
// Apply fade effect
|
||||
if (args->_enableFade) {
|
||||
FadeRenderJob::bindPerBatch(batch, render::ShapePipeline::Slot::MAP::FADE_MASK, render::ShapePipeline::Slot::BUFFER::FADE_PARAMETERS);
|
||||
FadeRenderJob::bindPerItem(batch, pipeline.get(), glm::vec3(0, 0, 0), _fadeStartTime);
|
||||
}
|
||||
|
||||
int voxelVolumeSizeLocation = pipeline->getProgram()->getUniforms().findLocation("voxelVolumeSize");
|
||||
batch._glUniform3f(voxelVolumeSizeLocation, voxelVolumeSize.x, voxelVolumeSize.y, voxelVolumeSize.z);
|
||||
|
||||
|
@ -871,6 +888,13 @@ namespace render {
|
|||
payload->_owner->getRenderableInterface()->render(args);
|
||||
}
|
||||
}
|
||||
|
||||
template <> bool payloadMustFade(const PolyVoxPayload::Pointer& payload) {
|
||||
if (payload && payload->_owner) {
|
||||
return payload->_owner->mustFade();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1619,7 +1643,7 @@ void RenderablePolyVoxEntityItem::bonkNeighbors() {
|
|||
|
||||
void RenderablePolyVoxEntityItem::locationChanged(bool tellPhysics) {
|
||||
EntityItem::locationChanged(tellPhysics);
|
||||
if (!_pipeline || !render::Item::isValidID(_myItem)) {
|
||||
if (!_pipelines[0] || !render::Item::isValidID(_myItem)) {
|
||||
return;
|
||||
}
|
||||
render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace render {
|
|||
template <> const ItemKey payloadGetKey(const PolyVoxPayload::Pointer& payload);
|
||||
template <> const Item::Bound payloadGetBound(const PolyVoxPayload::Pointer& payload);
|
||||
template <> void payloadRender(const PolyVoxPayload::Pointer& payload, RenderArgs* args);
|
||||
template <> bool payloadMustFade(const PolyVoxPayload::Pointer& payload);
|
||||
}
|
||||
|
||||
|
||||
|
@ -147,7 +148,7 @@ public:
|
|||
|
||||
void setVolDataDirty() { withWriteLock([&] { _volDataDirty = true; _meshReady = false; }); }
|
||||
|
||||
// Transparent polyvox didn't seem to be working so disable for now
|
||||
// Transparent polyvox didn't seem to be working so disable for now.
|
||||
bool isTransparent() override { return false; }
|
||||
|
||||
bool getMeshes(MeshProxyList& result) override;
|
||||
|
@ -170,8 +171,9 @@ private:
|
|||
|
||||
const int MATERIAL_GPU_SLOT = 3;
|
||||
render::ItemID _myItem{ render::Item::INVALID_ITEM_ID };
|
||||
static gpu::PipelinePointer _pipeline;
|
||||
static gpu::PipelinePointer _wireframePipeline;
|
||||
|
||||
static gpu::PipelinePointer _pipelines[2];
|
||||
static gpu::PipelinePointer _wireframePipelines[2];
|
||||
|
||||
ShapeInfo _shapeInfo;
|
||||
|
||||
|
@ -206,4 +208,5 @@ private:
|
|||
bool inUserBounds(const PolyVox::SimpleVolume<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle,
|
||||
int x, int y, int z);
|
||||
|
||||
|
||||
#endif // hifi_RenderablePolyVoxEntityItem_h
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <StencilMaskPass.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <PerfStat.h>
|
||||
#include <FadeEffect.h>
|
||||
|
||||
#include <render-utils/simple_vert.h>
|
||||
#include <render-utils/simple_frag.h>
|
||||
|
@ -122,11 +123,13 @@ void RenderableShapeEntityItem::render(RenderArgs* args) {
|
|||
DependencyManager::get<GeometryCache>()->renderShape(batch, MAPPING[_shape]);
|
||||
}
|
||||
} else {
|
||||
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
||||
color.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto pipeline = color.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
|
||||
|
||||
assert(pipeline != nullptr);
|
||||
|
||||
if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
|
||||
geometryCache->renderWireShapeInstance(batch, MAPPING[_shape], color, pipeline);
|
||||
} else {
|
||||
|
|
61
libraries/entities-renderer/src/polyvox_fade.slf
Normal file
61
libraries/entities-renderer/src/polyvox_fade.slf
Normal file
|
@ -0,0 +1,61 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// polyvox_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 2017-06-08
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include model/Material.slh@>
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include Fade.slh@>
|
||||
|
||||
in vec3 _normal;
|
||||
in vec4 _position;
|
||||
in vec4 _worldPosition;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
uniform sampler2D xMap;
|
||||
uniform sampler2D yMap;
|
||||
uniform sampler2D zMap;
|
||||
uniform vec3 voxelVolumeSize;
|
||||
|
||||
// Declare after all samplers to prevent sampler location mix up with voxel shading (sampler locations are hardcoded in RenderablePolyVoxEntityItem)
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
void main(void) {
|
||||
vec3 emissive;
|
||||
applyFade(_worldFadePosition.xyz, emissive);
|
||||
|
||||
vec3 worldNormal = cross(dFdy(_worldPosition.xyz), dFdx(_worldPosition.xyz));
|
||||
worldNormal = normalize(worldNormal);
|
||||
|
||||
float inPositionX = (_worldPosition.x - 0.5) / voxelVolumeSize.x;
|
||||
float inPositionY = (_worldPosition.y - 0.5) / voxelVolumeSize.y;
|
||||
float inPositionZ = (_worldPosition.z - 0.5) / voxelVolumeSize.z;
|
||||
|
||||
vec4 xyDiffuse = texture(xMap, vec2(-inPositionX, -inPositionY));
|
||||
vec4 xzDiffuse = texture(yMap, vec2(-inPositionX, inPositionZ));
|
||||
vec4 yzDiffuse = texture(zMap, vec2(inPositionZ, -inPositionY));
|
||||
|
||||
vec3 xyDiffuseScaled = xyDiffuse.rgb * abs(worldNormal.z);
|
||||
vec3 xzDiffuseScaled = xzDiffuse.rgb * abs(worldNormal.y);
|
||||
vec3 yzDiffuseScaled = yzDiffuse.rgb * abs(worldNormal.x);
|
||||
vec4 diffuse = vec4(xyDiffuseScaled + xzDiffuseScaled + yzDiffuseScaled, 1.0);
|
||||
|
||||
packDeferredFragment(
|
||||
_normal,
|
||||
1.0,
|
||||
vec3(diffuse),
|
||||
DEFAULT_ROUGHNESS,
|
||||
DEFAULT_METALLIC,
|
||||
DEFAULT_EMISSIVE+emissive,
|
||||
DEFAULT_OCCLUSION,
|
||||
DEFAULT_SCATTERING);
|
||||
}
|
35
libraries/entities-renderer/src/polyvox_fade.slv
Normal file
35
libraries/entities-renderer/src/polyvox_fade.slv
Normal file
|
@ -0,0 +1,35 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// polyvox_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Seth Alves on 2015-8-3
|
||||
// Copyright 2015 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
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
|
||||
out vec4 _position;
|
||||
out vec4 _worldPosition;
|
||||
out vec3 _normal;
|
||||
out vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _worldFadePosition)$>
|
||||
_worldPosition = inPosition;
|
||||
}
|
|
@ -455,6 +455,7 @@ public:
|
|||
|
||||
bool isFading() const { return _isFading; }
|
||||
float getFadingRatio() const { return (isFading() ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f); }
|
||||
bool mustFade() const { return _isFading; }
|
||||
|
||||
virtual void emitScriptEvent(const QVariant& message) {}
|
||||
|
||||
|
|
|
@ -457,7 +457,7 @@ void GLBackend::do_glUniform1i(const Batch& batch, size_t paramOffset) {
|
|||
}
|
||||
updatePipeline();
|
||||
|
||||
glUniform1f(
|
||||
glUniform1i(
|
||||
GET_UNIFORM_LOCATION(batch._params[paramOffset + 1]._int),
|
||||
batch._params[paramOffset + 0]._int);
|
||||
(void)CHECK_GL_ERROR();
|
||||
|
|
126
libraries/render-utils/src/Fade.slh
Normal file
126
libraries/render-utils/src/Fade.slh
Normal file
|
@ -0,0 +1,126 @@
|
|||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// Created by Olivier Prat on 04/12/17.
|
||||
// Copyright 2017 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 FADE_SLH@>
|
||||
<@def FADE_SLH@>
|
||||
|
||||
<@func transformModelToFadePos(objectTransform, objectPosition, fadePosition)@>
|
||||
{
|
||||
vec4 objectVector = vec4(<$objectPosition$>.xyz, 0.f);
|
||||
<$transformModelToWorldPos($objectTransform$, objectVector, $fadePosition$)$>
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func declareFadeFragment()@>
|
||||
|
||||
struct FadeParameters
|
||||
{
|
||||
vec4 _baseInvSizeAndLevel;
|
||||
vec4 _noiseInvSizeAndLevel;
|
||||
vec4 _innerEdgeColor;
|
||||
vec4 _outerEdgeColor;
|
||||
vec2 _edgeWidthInvWidth;
|
||||
int _isInverted;
|
||||
float _padding;
|
||||
};
|
||||
|
||||
#define EVENT_CATEGORY_COUNT 5
|
||||
|
||||
uniform fadeParametersBuffer {
|
||||
FadeParameters fadeParameters[EVENT_CATEGORY_COUNT];
|
||||
};
|
||||
uniform int fadeCategory;
|
||||
uniform vec3 fadeNoiseOffset;
|
||||
uniform vec3 fadeBaseOffset;
|
||||
uniform float fadeThreshold;
|
||||
uniform sampler2D fadeMaskMap;
|
||||
|
||||
vec2 hash2D(vec3 position) {
|
||||
return position.xy* vec2(0.1677, 0.221765) + position.z*0.561;
|
||||
}
|
||||
|
||||
float noise3D(vec3 position) {
|
||||
float n = textureLod(fadeMaskMap, hash2D(position), 0).r;
|
||||
return pow(n, 1.0/2.2); // Need to fix this later directly in the texture
|
||||
}
|
||||
|
||||
float evalFadeNoiseGradient(vec3 position) {
|
||||
// Do tri-linear interpolation
|
||||
vec3 noisePosition = position * fadeParameters[fadeCategory]._noiseInvSizeAndLevel.xyz + fadeNoiseOffset;
|
||||
vec3 noisePositionFloored = floor(noisePosition);
|
||||
vec3 noisePositionFraction = fract(noisePosition);
|
||||
|
||||
noisePositionFraction = noisePositionFraction*noisePositionFraction*(3 - 2*noisePositionFraction);
|
||||
|
||||
float noiseLowXLowYLowZ = noise3D(noisePositionFloored);
|
||||
float noiseLowXHighYLowZ = noise3D(noisePositionFloored+vec3(0,1,0));
|
||||
float noiseHighXLowYLowZ = noise3D(noisePositionFloored+vec3(1,0,0));
|
||||
float noiseHighXHighYLowZ = noise3D(noisePositionFloored+vec3(1,1,0));
|
||||
float noiseLowXLowYHighZ = noise3D(noisePositionFloored+vec3(0,0,1));
|
||||
float noiseLowXHighYHighZ = noise3D(noisePositionFloored+vec3(0,1,1));
|
||||
float noiseHighXLowYHighZ = noise3D(noisePositionFloored+vec3(1,0,1));
|
||||
float noiseHighXHighYHighZ = noise3D(noisePositionFloored+vec3(1,1,1));
|
||||
vec4 maskLowZ = vec4(noiseLowXLowYLowZ, noiseLowXHighYLowZ, noiseHighXLowYLowZ, noiseHighXHighYLowZ);
|
||||
vec4 maskHighZ = vec4(noiseLowXLowYHighZ, noiseLowXHighYHighZ, noiseHighXLowYHighZ, noiseHighXHighYHighZ);
|
||||
vec4 maskXY = mix(maskLowZ, maskHighZ, noisePositionFraction.z);
|
||||
vec2 maskY = mix(maskXY.xy, maskXY.zw, noisePositionFraction.x);
|
||||
|
||||
float noise = mix(maskY.x, maskY.y, noisePositionFraction.y);
|
||||
noise -= 0.5; // Center on value 0
|
||||
return noise * fadeParameters[fadeCategory]._noiseInvSizeAndLevel.w;
|
||||
}
|
||||
|
||||
float evalFadeBaseGradient(vec3 position) {
|
||||
float gradient = length((position - fadeBaseOffset) * fadeParameters[fadeCategory]._baseInvSizeAndLevel.xyz);
|
||||
gradient = gradient-0.5; // Center on value 0.5
|
||||
gradient *= fadeParameters[fadeCategory]._baseInvSizeAndLevel.w;
|
||||
return gradient;
|
||||
}
|
||||
|
||||
float evalFadeGradient(vec3 position) {
|
||||
float baseGradient = evalFadeBaseGradient(position);
|
||||
float noiseGradient = evalFadeNoiseGradient(position);
|
||||
float gradient = noiseGradient+baseGradient+0.5;
|
||||
|
||||
return gradient;
|
||||
}
|
||||
|
||||
float evalFadeAlpha(vec3 position) {
|
||||
float cutoff = fadeThreshold;
|
||||
|
||||
return evalFadeGradient(position)-cutoff;
|
||||
}
|
||||
|
||||
void applyFadeClip(vec3 position) {
|
||||
if (evalFadeAlpha(position) < 0) {
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
||||
void applyFade(vec3 position, out vec3 emissive) {
|
||||
float alpha = evalFadeAlpha(position);
|
||||
if (fadeParameters[fadeCategory]._isInverted!=0) {
|
||||
alpha = -alpha;
|
||||
}
|
||||
|
||||
if (alpha < 0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
float edgeMask = alpha * fadeParameters[fadeCategory]._edgeWidthInvWidth.y;
|
||||
float edgeAlpha = 1.0-clamp(edgeMask, 0, 1);
|
||||
|
||||
edgeMask = step(edgeMask, 1.f);
|
||||
edgeAlpha *= edgeAlpha; // Square to have a nice ease out
|
||||
vec4 color = mix(fadeParameters[fadeCategory]._innerEdgeColor, fadeParameters[fadeCategory]._outerEdgeColor, edgeAlpha);
|
||||
emissive = color.rgb * edgeMask * color.a;
|
||||
}
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
<@endif@>
|
873
libraries/render-utils/src/FadeEffect.cpp
Normal file
873
libraries/render-utils/src/FadeEffect.cpp
Normal file
|
@ -0,0 +1,873 @@
|
|||
#include "FadeEffect.h"
|
||||
#include "TextureCache.h"
|
||||
#include "render/Logging.h"
|
||||
|
||||
#include <PathUtils.h>
|
||||
#include <NumericalConstants.h>
|
||||
#include <Interpolate.h>
|
||||
#include <gpu/Context.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
|
||||
#define FADE_MIN_SCALE 0.001
|
||||
#define FADE_MAX_SCALE 10000.0
|
||||
#define FADE_MAX_SPEED 50.f
|
||||
|
||||
inline float parameterToValuePow(float parameter, const double minValue, const double maxOverMinValue) {
|
||||
return (float)(minValue * pow(maxOverMinValue, double(parameter)));
|
||||
}
|
||||
|
||||
inline float valueToParameterPow(float value, const double minValue, const double maxOverMinValue) {
|
||||
return (float)(log(double(value) / minValue) / log(maxOverMinValue));
|
||||
}
|
||||
|
||||
void FadeSwitchJob::configure(const Config& config) {
|
||||
_parameters->_isEditEnabled = config.editFade;
|
||||
}
|
||||
|
||||
void FadeSwitchJob::run(const render::RenderContextPointer& renderContext, const Input& input, Output& output) {
|
||||
auto& normalOutputs = output.edit0().edit0();
|
||||
auto& fadeOutputs = output.edit1();
|
||||
|
||||
// Only shapes are affected by fade at this time.
|
||||
normalOutputs[RenderFetchCullSortTask::LIGHT].edit<render::ItemBounds>() = input.get0()[RenderFetchCullSortTask::LIGHT].get<render::ItemBounds>();
|
||||
normalOutputs[RenderFetchCullSortTask::META].edit<render::ItemBounds>() = input.get0()[RenderFetchCullSortTask::META].get<render::ItemBounds>();
|
||||
normalOutputs[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE].edit<render::ItemBounds>() = input.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE].get<render::ItemBounds>();
|
||||
normalOutputs[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE].edit<render::ItemBounds>() = input.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE].get<render::ItemBounds>();
|
||||
normalOutputs[RenderFetchCullSortTask::BACKGROUND].edit<render::ItemBounds>() = input.get0()[RenderFetchCullSortTask::BACKGROUND].get<render::ItemBounds>();
|
||||
output.edit0().edit1() = input.get1();
|
||||
|
||||
// Find the nearest item that intersects the view direction
|
||||
const render::Item* editedItem = nullptr;
|
||||
if (_parameters->_isEditEnabled) {
|
||||
float nearestOpaqueDistance = std::numeric_limits<float>::max();
|
||||
float nearestTransparentDistance = std::numeric_limits<float>::max();
|
||||
const render::Item* nearestItem;
|
||||
|
||||
editedItem = findNearestItem(renderContext, input.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE], nearestOpaqueDistance);
|
||||
nearestItem = findNearestItem(renderContext, input.get0()[RenderFetchCullSortTask::TRANSPARENT_SHAPE], nearestTransparentDistance);
|
||||
if (nearestTransparentDistance < nearestOpaqueDistance) {
|
||||
editedItem = nearestItem;
|
||||
}
|
||||
|
||||
if (editedItem) {
|
||||
output.edit2() = editedItem->getBound();
|
||||
}
|
||||
}
|
||||
|
||||
// Now, distribute items that need to be faded accross both outputs
|
||||
distribute(renderContext, input.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE], normalOutputs[RenderFetchCullSortTask::OPAQUE_SHAPE], fadeOutputs[OPAQUE_SHAPE], editedItem);
|
||||
distribute(renderContext, input.get0()[RenderFetchCullSortTask::TRANSPARENT_SHAPE], normalOutputs[RenderFetchCullSortTask::TRANSPARENT_SHAPE], fadeOutputs[TRANSPARENT_SHAPE], editedItem);
|
||||
}
|
||||
|
||||
const render::Item* FadeSwitchJob::findNearestItem(const render::RenderContextPointer& renderContext, const render::Varying& input, float& minIsectDistance) const {
|
||||
const glm::vec3 rayOrigin = renderContext->args->getViewFrustum().getPosition();
|
||||
const glm::vec3 rayDirection = renderContext->args->getViewFrustum().getDirection();
|
||||
const auto& inputItems = input.get<render::ItemBounds>();
|
||||
auto& scene = renderContext->_scene;
|
||||
BoxFace face;
|
||||
glm::vec3 normal;
|
||||
float isectDistance;
|
||||
const render::Item* nearestItem = nullptr;
|
||||
const float minDistance = 2.f;
|
||||
|
||||
for (const auto& itemBound : inputItems) {
|
||||
if (!itemBound.bound.contains(rayOrigin) && itemBound.bound.findRayIntersection(rayOrigin, rayDirection, isectDistance, face, normal)) {
|
||||
if (isectDistance>minDistance && isectDistance < minIsectDistance) {
|
||||
auto& item = scene->getItem(itemBound.id);
|
||||
|
||||
if (item.getKey().isShape() && !item.getKey().isMeta()) {
|
||||
nearestItem = &item;
|
||||
minIsectDistance = isectDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nearestItem;
|
||||
}
|
||||
|
||||
void FadeSwitchJob::distribute(const render::RenderContextPointer& renderContext, const render::Varying& input,
|
||||
render::Varying& normalOutput, render::Varying& fadeOutput, const render::Item* editedItem) const {
|
||||
auto& scene = renderContext->_scene;
|
||||
assert(_parameters);
|
||||
const auto& inputItems = input.get<render::ItemBounds>();
|
||||
|
||||
// Clear previous values
|
||||
normalOutput.edit<render::ItemBounds>().clear();
|
||||
fadeOutput.edit<render::ItemBounds>().clear();
|
||||
|
||||
for (const auto& itemBound : inputItems) {
|
||||
auto& item = scene->getItem(itemBound.id);
|
||||
|
||||
if (!item.mustFade() && &item!=editedItem) {
|
||||
// No need to fade
|
||||
normalOutput.edit<render::ItemBounds>().emplace_back(itemBound);
|
||||
}
|
||||
else {
|
||||
fadeOutput.edit<render::ItemBounds>().emplace_back(itemBound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FadeCommonParameters::FadeCommonParameters()
|
||||
{
|
||||
_durations[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN] = 0.f;
|
||||
_durations[FadeJobConfig::BUBBLE_ISECT_OWNER] = 0.f;
|
||||
_durations[FadeJobConfig::BUBBLE_ISECT_TRESPASSER] = 0.f;
|
||||
_durations[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN] = 0.f;
|
||||
_durations[FadeJobConfig::AVATAR_CHANGE] = 0.f;
|
||||
}
|
||||
|
||||
FadeJobConfig::FadeJobConfig()
|
||||
{
|
||||
events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].noiseSize = glm::vec3{ 0.75f, 0.75f, 0.75f };
|
||||
events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].noiseLevel = 1.f;
|
||||
events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].noiseSpeed = glm::vec3{ 0.0f, 0.0f, 0.0f };
|
||||
events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].timing = FadeJobConfig::LINEAR;
|
||||
events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].baseSize = glm::vec3{ 1.0f, 1.0f, 1.0f };
|
||||
events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].baseLevel = 0.f;
|
||||
events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN]._isInverted = false;
|
||||
events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN]._duration = 4.f;
|
||||
events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].edgeWidth = 0.1f;
|
||||
events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].edgeInnerColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 0.0f };
|
||||
events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].edgeOuterColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 1.0f };
|
||||
|
||||
events[FadeJobConfig::BUBBLE_ISECT_OWNER].noiseSize = glm::vec3{ 1.5f, 1.0f/25.f, 0.5f };
|
||||
events[FadeJobConfig::BUBBLE_ISECT_OWNER].noiseLevel = 0.37f;
|
||||
events[FadeJobConfig::BUBBLE_ISECT_OWNER].noiseSpeed = glm::vec3{ 1.0f, 0.2f, 1.0f };
|
||||
events[FadeJobConfig::BUBBLE_ISECT_OWNER].timing = FadeJobConfig::LINEAR;
|
||||
events[FadeJobConfig::BUBBLE_ISECT_OWNER].baseSize = glm::vec3{ 2.0f, 2.0f, 2.0f };
|
||||
events[FadeJobConfig::BUBBLE_ISECT_OWNER].baseLevel = 1.f;
|
||||
events[FadeJobConfig::BUBBLE_ISECT_OWNER]._isInverted = false;
|
||||
events[FadeJobConfig::BUBBLE_ISECT_OWNER]._duration = 4.f;
|
||||
events[FadeJobConfig::BUBBLE_ISECT_OWNER].edgeWidth = 0.02f;
|
||||
events[FadeJobConfig::BUBBLE_ISECT_OWNER].edgeInnerColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 1.0f };
|
||||
events[FadeJobConfig::BUBBLE_ISECT_OWNER].edgeOuterColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 2.0f };
|
||||
|
||||
events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].noiseSize = glm::vec3{ 0.5f, 1.0f / 25.f, 0.5f };
|
||||
events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].noiseLevel = 1.f;
|
||||
events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].noiseSpeed = glm::vec3{ 1.0f, 0.2f, 1.0f };
|
||||
events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].timing = FadeJobConfig::LINEAR;
|
||||
events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].baseSize = glm::vec3{ 2.0f, 2.0f, 2.0f };
|
||||
events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].baseLevel = 0.f;
|
||||
events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER]._isInverted = false;
|
||||
events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER]._duration = 4.f;
|
||||
events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].edgeWidth = 0.025f;
|
||||
events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].edgeInnerColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 1.0f };
|
||||
events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].edgeOuterColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 2.0f };
|
||||
|
||||
events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].noiseSize = glm::vec3{ 10.f, 0.01f, 10.0f };
|
||||
events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].noiseLevel = 0.7f;
|
||||
events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].noiseSpeed = glm::vec3{ 0.0f, -0.5f, 0.0f };
|
||||
events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].timing = FadeJobConfig::LINEAR;
|
||||
events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].baseSize = glm::vec3{ 10000.f, 1.0f, 10000.0f };
|
||||
events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].baseLevel = 1.f;
|
||||
events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN]._isInverted = true;
|
||||
events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN]._duration = 5.f;
|
||||
events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].edgeWidth = 0.229f;
|
||||
events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].edgeInnerColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 0.25f };
|
||||
events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].edgeOuterColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 1.0f };
|
||||
|
||||
events[FadeJobConfig::AVATAR_CHANGE].noiseSize = glm::vec3{ 0.4f, 0.4f, 0.4f };
|
||||
events[FadeJobConfig::AVATAR_CHANGE].noiseLevel = 1.f;
|
||||
events[FadeJobConfig::AVATAR_CHANGE].noiseSpeed = glm::vec3{ 0.0f, 0.0f, 0.0f };
|
||||
events[FadeJobConfig::AVATAR_CHANGE].timing = FadeJobConfig::LINEAR;
|
||||
events[FadeJobConfig::AVATAR_CHANGE].baseSize = glm::vec3{ 0.4f, 0.4f, 0.4f };
|
||||
events[FadeJobConfig::AVATAR_CHANGE].baseLevel = 1.f;
|
||||
events[FadeJobConfig::AVATAR_CHANGE]._isInverted = false;
|
||||
events[FadeJobConfig::AVATAR_CHANGE]._duration = 3.f;
|
||||
events[FadeJobConfig::AVATAR_CHANGE].edgeWidth = 0.05f;
|
||||
events[FadeJobConfig::AVATAR_CHANGE].edgeInnerColor = glm::vec4{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
events[FadeJobConfig::AVATAR_CHANGE].edgeOuterColor = glm::vec4{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
}
|
||||
|
||||
void FadeJobConfig::setEditedCategory(int value) {
|
||||
assert(value < EVENT_CATEGORY_COUNT);
|
||||
editedCategory = std::min<int>(EVENT_CATEGORY_COUNT, value);
|
||||
emit dirtyCategory();
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
void FadeJobConfig::setDuration(float value) {
|
||||
events[editedCategory]._duration = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
float FadeJobConfig::getDuration() const {
|
||||
return events[editedCategory]._duration;
|
||||
}
|
||||
|
||||
void FadeJobConfig::setBaseSizeX(float value) {
|
||||
events[editedCategory].baseSize.x = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE);
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
float FadeJobConfig::getBaseSizeX() const {
|
||||
return valueToParameterPow(events[editedCategory].baseSize.x, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);
|
||||
}
|
||||
|
||||
void FadeJobConfig::setBaseSizeY(float value) {
|
||||
events[editedCategory].baseSize.y = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
float FadeJobConfig::getBaseSizeY() const {
|
||||
return valueToParameterPow(events[editedCategory].baseSize.y, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);
|
||||
}
|
||||
|
||||
void FadeJobConfig::setBaseSizeZ(float value) {
|
||||
events[editedCategory].baseSize.z = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
float FadeJobConfig::getBaseSizeZ() const {
|
||||
return valueToParameterPow(events[editedCategory].baseSize.z, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);
|
||||
}
|
||||
|
||||
void FadeJobConfig::setBaseLevel(float value) {
|
||||
events[editedCategory].baseLevel = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
void FadeJobConfig::setInverted(bool value) {
|
||||
events[editedCategory]._isInverted = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
bool FadeJobConfig::isInverted() const {
|
||||
return events[editedCategory]._isInverted;
|
||||
}
|
||||
|
||||
void FadeJobConfig::setNoiseSizeX(float value) {
|
||||
events[editedCategory].noiseSize.x = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
float FadeJobConfig::getNoiseSizeX() const {
|
||||
return valueToParameterPow(events[editedCategory].noiseSize.x, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);
|
||||
}
|
||||
|
||||
void FadeJobConfig::setNoiseSizeY(float value) {
|
||||
events[editedCategory].noiseSize.y = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
float FadeJobConfig::getNoiseSizeY() const {
|
||||
return valueToParameterPow(events[editedCategory].noiseSize.y, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);
|
||||
}
|
||||
|
||||
void FadeJobConfig::setNoiseSizeZ(float value) {
|
||||
events[editedCategory].noiseSize.z = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
float FadeJobConfig::getNoiseSizeZ() const {
|
||||
return valueToParameterPow(events[editedCategory].noiseSize.z, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);
|
||||
}
|
||||
|
||||
void FadeJobConfig::setNoiseLevel(float value) {
|
||||
events[editedCategory].noiseLevel = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
void FadeJobConfig::setNoiseSpeedX(float value) {
|
||||
events[editedCategory].noiseSpeed.x = powf(value, 3.f)*FADE_MAX_SPEED;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
float FadeJobConfig::getNoiseSpeedX() const {
|
||||
return powf(events[editedCategory].noiseSpeed.x / FADE_MAX_SPEED, 1.f / 3.f);
|
||||
}
|
||||
|
||||
void FadeJobConfig::setNoiseSpeedY(float value) {
|
||||
events[editedCategory].noiseSpeed.y = powf(value, 3.f)*FADE_MAX_SPEED;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
float FadeJobConfig::getNoiseSpeedY() const {
|
||||
return powf(events[editedCategory].noiseSpeed.y / FADE_MAX_SPEED, 1.f / 3.f);
|
||||
}
|
||||
|
||||
void FadeJobConfig::setNoiseSpeedZ(float value) {
|
||||
events[editedCategory].noiseSpeed.z = powf(value, 3.f)*FADE_MAX_SPEED;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
float FadeJobConfig::getNoiseSpeedZ() const {
|
||||
return powf(events[editedCategory].noiseSpeed.z / FADE_MAX_SPEED, 1.f / 3.f);
|
||||
}
|
||||
|
||||
void FadeJobConfig::setEdgeWidth(float value) {
|
||||
events[editedCategory].edgeWidth = value * value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
float FadeJobConfig::getEdgeWidth() const {
|
||||
return sqrtf(events[editedCategory].edgeWidth);
|
||||
}
|
||||
|
||||
void FadeJobConfig::setEdgeInnerColorR(float value) {
|
||||
events[editedCategory].edgeInnerColor.r = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
void FadeJobConfig::setEdgeInnerColorG(float value) {
|
||||
events[editedCategory].edgeInnerColor.g = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
void FadeJobConfig::setEdgeInnerColorB(float value) {
|
||||
events[editedCategory].edgeInnerColor.b = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
void FadeJobConfig::setEdgeInnerIntensity(float value) {
|
||||
events[editedCategory].edgeInnerColor.a = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
void FadeJobConfig::setEdgeOuterColorR(float value) {
|
||||
events[editedCategory].edgeOuterColor.r = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
void FadeJobConfig::setEdgeOuterColorG(float value) {
|
||||
events[editedCategory].edgeOuterColor.g = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
void FadeJobConfig::setEdgeOuterColorB(float value) {
|
||||
events[editedCategory].edgeOuterColor.b = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
void FadeJobConfig::setEdgeOuterIntensity(float value) {
|
||||
events[editedCategory].edgeOuterColor.a = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
void FadeJobConfig::setTiming(int value) {
|
||||
assert(value < TIMING_COUNT);
|
||||
events[editedCategory].timing = value;
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
QString FadeJobConfig::eventNames[EVENT_CATEGORY_COUNT] = {
|
||||
"element_enter_leave_domain",
|
||||
"bubble_isect_owner",
|
||||
"bubble_isect_trespasser",
|
||||
"user_enter_leave_domain",
|
||||
"avatar_change",
|
||||
};
|
||||
|
||||
void FadeJobConfig::save() const {
|
||||
assert(category < EVENT_CATEGORY_COUNT);
|
||||
QJsonObject lProperties;
|
||||
const QString configFile = "config/" + eventNames[editedCategory] + ".json";
|
||||
QUrl path(PathUtils::resourcesPath() + configFile);
|
||||
QFile file(path.toString());
|
||||
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
||||
qWarning() << "Fade event configuration file " << path << " cannot be opened";
|
||||
}
|
||||
else {
|
||||
const auto& event = events[editedCategory];
|
||||
|
||||
lProperties["edgeInnerColor"] = QJsonArray{ event.edgeInnerColor.r, event.edgeInnerColor.g, event.edgeInnerColor.b, event.edgeInnerColor.a };
|
||||
lProperties["edgeOuterColor"] = QJsonArray{ event.edgeOuterColor.r, event.edgeOuterColor.g, event.edgeOuterColor.b, event.edgeOuterColor.a };
|
||||
lProperties["noiseSize"] = QJsonArray{ event.noiseSize.x, event.noiseSize.y, event.noiseSize.z };
|
||||
lProperties["noiseSpeed"] = QJsonArray{ event.noiseSpeed.x, event.noiseSpeed.y, event.noiseSpeed.z };
|
||||
lProperties["baseSize"] = QJsonArray{ event.baseSize.x, event.baseSize.y, event.baseSize.z };
|
||||
lProperties["noiseLevel"] = event.noiseLevel;
|
||||
lProperties["baseLevel"] = event.baseLevel;
|
||||
lProperties["duration"] = event._duration;
|
||||
lProperties["edgeWidth"] = event.edgeWidth;
|
||||
lProperties["timing"] = event.timing;
|
||||
lProperties["isInverted"] = event._isInverted;
|
||||
|
||||
file.write( QJsonDocument(lProperties).toJson() );
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void FadeJobConfig::load() {
|
||||
const QString configFile = "config/" + eventNames[editedCategory] + ".json";
|
||||
|
||||
QUrl path(PathUtils::resourcesPath() + configFile);
|
||||
QFile file(path.toString());
|
||||
if (!file.exists()) {
|
||||
qWarning() << "Fade event configuration file " << path << " does not exist";
|
||||
}
|
||||
else if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
qWarning() << "Fade event configuration file " << path << " cannot be opened";
|
||||
}
|
||||
else {
|
||||
QString fileData = file.readAll();
|
||||
file.close();
|
||||
QJsonParseError error;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(fileData.toUtf8(), &error);
|
||||
if (error.error == error.NoError) {
|
||||
QJsonObject jsonObject = doc.object();
|
||||
QJsonValue value;
|
||||
auto& event = events[editedCategory];
|
||||
|
||||
qCDebug(renderlogging) << "Fade event configuration file" << path << "loaded";
|
||||
|
||||
value = jsonObject["edgeInnerColor"];
|
||||
if (value.isArray()) {
|
||||
QJsonArray data = value.toArray();
|
||||
|
||||
if (data.size() < 4) {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'edgeInnerColor' field. Expected array of size 4";
|
||||
}
|
||||
else {
|
||||
event.edgeInnerColor.r = (float)data.at(0).toDouble();
|
||||
event.edgeInnerColor.g = (float)data.at(1).toDouble();
|
||||
event.edgeInnerColor.b = (float)data.at(2).toDouble();
|
||||
event.edgeInnerColor.a = (float)data.at(3).toDouble();
|
||||
}
|
||||
}
|
||||
else {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'edgeInnerColor' field. Expected array of size 4";
|
||||
}
|
||||
|
||||
value = jsonObject["edgeOuterColor"];
|
||||
if (value.isArray()) {
|
||||
QJsonArray data = value.toArray();
|
||||
|
||||
if (data.size() < 4) {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'edgeOuterColor' field. Expected array of size 4";
|
||||
}
|
||||
else {
|
||||
event.edgeOuterColor.r = (float)data.at(0).toDouble();
|
||||
event.edgeOuterColor.g = (float)data.at(1).toDouble();
|
||||
event.edgeOuterColor.b = (float)data.at(2).toDouble();
|
||||
event.edgeOuterColor.a = (float)data.at(3).toDouble();
|
||||
}
|
||||
}
|
||||
else {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'edgeOuterColor' field. Expected array of size 4";
|
||||
}
|
||||
|
||||
value = jsonObject["noiseSize"];
|
||||
if (value.isArray()) {
|
||||
QJsonArray data = value.toArray();
|
||||
|
||||
if (data.size() < 3) {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'noiseSize' field. Expected array of size 3";
|
||||
}
|
||||
else {
|
||||
event.noiseSize.x = (float)data.at(0).toDouble();
|
||||
event.noiseSize.y = (float)data.at(1).toDouble();
|
||||
event.noiseSize.z = (float)data.at(2).toDouble();
|
||||
}
|
||||
}
|
||||
else {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'noiseSize' field. Expected array of size 3";
|
||||
}
|
||||
|
||||
value = jsonObject["noiseSpeed"];
|
||||
if (value.isArray()) {
|
||||
QJsonArray data = value.toArray();
|
||||
|
||||
if (data.size() < 3) {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'noiseSpeed' field. Expected array of size 3";
|
||||
}
|
||||
else {
|
||||
event.noiseSpeed.x = (float)data.at(0).toDouble();
|
||||
event.noiseSpeed.y = (float)data.at(1).toDouble();
|
||||
event.noiseSpeed.z = (float)data.at(2).toDouble();
|
||||
}
|
||||
}
|
||||
else {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'noiseSpeed' field. Expected array of size 3";
|
||||
}
|
||||
|
||||
value = jsonObject["baseSize"];
|
||||
if (value.isArray()) {
|
||||
QJsonArray data = value.toArray();
|
||||
|
||||
if (data.size() < 3) {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'baseSize' field. Expected array of size 3";
|
||||
}
|
||||
else {
|
||||
event.baseSize.x = (float)data.at(0).toDouble();
|
||||
event.baseSize.y = (float)data.at(1).toDouble();
|
||||
event.baseSize.z = (float)data.at(2).toDouble();
|
||||
}
|
||||
}
|
||||
else {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'baseSize' field. Expected array of size 3";
|
||||
}
|
||||
|
||||
value = jsonObject["noiseLevel"];
|
||||
if (value.isDouble()) {
|
||||
event.noiseLevel = (float)value.toDouble();
|
||||
}
|
||||
else {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'noiseLevel' field. Expected float value";
|
||||
}
|
||||
|
||||
value = jsonObject["baseLevel"];
|
||||
if (value.isDouble()) {
|
||||
event.baseLevel = (float)value.toDouble();
|
||||
}
|
||||
else {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'baseLevel' field. Expected float value";
|
||||
}
|
||||
|
||||
value = jsonObject["duration"];
|
||||
if (value.isDouble()) {
|
||||
event._duration = (float)value.toDouble();
|
||||
}
|
||||
else {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'duration' field. Expected float value";
|
||||
}
|
||||
|
||||
value = jsonObject["edgeWidth"];
|
||||
if (value.isDouble()) {
|
||||
event.edgeWidth = std::min(1.f, std::max(0.f, (float)value.toDouble()));
|
||||
}
|
||||
else {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'edgeWidth' field. Expected float value";
|
||||
}
|
||||
|
||||
value = jsonObject["timing"];
|
||||
if (value.isDouble()) {
|
||||
event.timing = std::max(0, std::min(TIMING_COUNT - 1, value.toInt()));
|
||||
}
|
||||
else {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'timing' field. Expected integer value";
|
||||
}
|
||||
|
||||
value = jsonObject["isInverted"];
|
||||
if (value.isBool()) {
|
||||
event._isInverted = value.toBool();
|
||||
}
|
||||
else {
|
||||
qWarning() << "Fade event configuration file " << path << " contains an invalid 'isInverted' field. Expected boolean value";
|
||||
}
|
||||
|
||||
emit dirty();
|
||||
}
|
||||
else {
|
||||
qWarning() << "Fade event configuration file" << path << "failed to load:" <<
|
||||
error.errorString() << "at offset" << error.offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FadeConfigureJob::FadeConfigureJob(FadeCommonParameters::Pointer commonParams) :
|
||||
_parameters{ commonParams }
|
||||
{
|
||||
auto texturePath = PathUtils::resourcesPath() + "images/fadeMask.png";
|
||||
_fadeMaskMap = DependencyManager::get<TextureCache>()->getImageTexture(texturePath, image::TextureUsage::STRICT_TEXTURE);
|
||||
}
|
||||
|
||||
void FadeConfigureJob::configure(const Config& config) {
|
||||
assert(_parameters);
|
||||
_parameters->_editedCategory = config.editedCategory;
|
||||
_parameters->_isManualThresholdEnabled = config.manualFade;
|
||||
_parameters->_manualThreshold = config.manualThreshold;
|
||||
|
||||
for (auto i = 0; i < FadeJobConfig::EVENT_CATEGORY_COUNT; i++) {
|
||||
auto& configuration = _configurations[i];
|
||||
const auto& eventConfig = config.events[i];
|
||||
|
||||
_parameters->_durations[i] = eventConfig._duration;
|
||||
configuration._baseInvSizeAndLevel.x = 1.f / eventConfig.baseSize.x;
|
||||
configuration._baseInvSizeAndLevel.y = 1.f / eventConfig.baseSize.y;
|
||||
configuration._baseInvSizeAndLevel.z = 1.f / eventConfig.baseSize.z;
|
||||
configuration._baseInvSizeAndLevel.w = eventConfig.baseLevel;
|
||||
configuration._noiseInvSizeAndLevel.x = 1.f / eventConfig.noiseSize.x;
|
||||
configuration._noiseInvSizeAndLevel.y = 1.f / eventConfig.noiseSize.y;
|
||||
configuration._noiseInvSizeAndLevel.z = 1.f / eventConfig.noiseSize.z;
|
||||
configuration._noiseInvSizeAndLevel.w = eventConfig.noiseLevel;
|
||||
configuration._isInverted = eventConfig._isInverted & 1;
|
||||
configuration._edgeWidthInvWidth.x = eventConfig.edgeWidth;
|
||||
configuration._edgeWidthInvWidth.y = 1.f / configuration._edgeWidthInvWidth.x;
|
||||
configuration._innerEdgeColor = eventConfig.edgeInnerColor;
|
||||
configuration._outerEdgeColor = eventConfig.edgeOuterColor;
|
||||
_parameters->_thresholdScale[i] = 1.f + (configuration._edgeWidthInvWidth.x + std::max(0.f, (eventConfig.noiseLevel + eventConfig.baseLevel)*0.5f-0.5f));
|
||||
_parameters->_noiseSpeed[i] = eventConfig.noiseSpeed;
|
||||
_parameters->_timing[i] = (FadeJobConfig::Timing) eventConfig.timing;
|
||||
}
|
||||
_isBufferDirty = true;
|
||||
}
|
||||
|
||||
void FadeConfigureJob::run(const render::RenderContextPointer& renderContext, const Input& input, Output& output) {
|
||||
if (_isBufferDirty || _parameters->_isEditEnabled) {
|
||||
auto& configurations = output.edit1().edit();
|
||||
std::copy(_configurations, _configurations + FadeJobConfig::EVENT_CATEGORY_COUNT, configurations.parameters);
|
||||
if (_parameters->_editedCategory == FadeJobConfig::USER_ENTER_LEAVE_DOMAIN) {
|
||||
configurations.parameters[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN]._baseInvSizeAndLevel.y = 1.0f / input.getDimensions().y;
|
||||
}
|
||||
_isBufferDirty = false;
|
||||
}
|
||||
output.edit0() = _fadeMaskMap;
|
||||
}
|
||||
|
||||
const FadeRenderJob* FadeRenderJob::_currentInstance{ nullptr };
|
||||
gpu::TexturePointer FadeRenderJob::_currentFadeMaskMap;
|
||||
const gpu::BufferView* FadeRenderJob::_currentFadeBuffer{ nullptr };
|
||||
|
||||
void FadeRenderJob::run(const render::RenderContextPointer& renderContext, const Input& inputs) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
const auto& inItems = inputs.get0();
|
||||
|
||||
if (!inItems.empty()) {
|
||||
const auto& lightingModel = inputs.get1();
|
||||
const auto& configuration = inputs.get2();
|
||||
const auto& fadeMaskMap = configuration.get0();
|
||||
const auto& fadeParamBuffer = configuration.get1();
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
render::ShapeKey::Builder defaultKeyBuilder;
|
||||
|
||||
defaultKeyBuilder.withFade();
|
||||
defaultKeyBuilder.withoutCullFace();
|
||||
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
args->_batch = &batch;
|
||||
|
||||
// Very, very ugly hack to keep track of the current fade render job
|
||||
_currentInstance = this;
|
||||
_currentFadeMaskMap = fadeMaskMap;
|
||||
_currentFadeBuffer = &fadeParamBuffer;
|
||||
|
||||
// Update interactive edit effect
|
||||
if (_parameters->_isEditEnabled) {
|
||||
updateFadeEdit(renderContext, inItems.front());
|
||||
}
|
||||
else {
|
||||
_editPreviousTime = 0;
|
||||
}
|
||||
|
||||
// Setup camera, projection and viewport for all items
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
batch.setStateScissorRect(args->_viewport);
|
||||
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
||||
// Setup lighting model for all items;
|
||||
batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
|
||||
|
||||
// From the lighting model define a global shapKey ORED with individiual keys
|
||||
render::ShapeKey::Builder keyBuilder = defaultKeyBuilder;
|
||||
if (lightingModel->isWireframeEnabled()) {
|
||||
keyBuilder.withWireframe();
|
||||
}
|
||||
|
||||
// Prepare fade effect
|
||||
bindPerBatch(batch, fadeMaskMap, render::ShapePipeline::Slot::MAP::FADE_MASK, &fadeParamBuffer, render::ShapePipeline::Slot::BUFFER::FADE_PARAMETERS);
|
||||
|
||||
render::ShapeKey globalKey = keyBuilder.build();
|
||||
args->_globalShapeKey = globalKey._flags.to_ulong();
|
||||
args->_enableFade = true;
|
||||
|
||||
renderShapes(renderContext, _shapePlumber, inItems, -1, globalKey);
|
||||
|
||||
args->_enableFade = false;
|
||||
args->_batch = nullptr;
|
||||
args->_globalShapeKey = 0;
|
||||
|
||||
// Very, very ugly hack to keep track of the current fade render job
|
||||
_currentInstance = nullptr;
|
||||
_currentFadeMaskMap.reset();
|
||||
_currentFadeBuffer = nullptr;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
float FadeRenderJob::computeElementEnterThreshold(double time, const double period, FadeJobConfig::Timing timing) const {
|
||||
assert(period > 0.0);
|
||||
float fadeAlpha = 1.0f;
|
||||
const double INV_FADE_PERIOD = 1.0 / period;
|
||||
double fraction = time * INV_FADE_PERIOD;
|
||||
fraction = std::max(fraction, 0.0);
|
||||
if (fraction < 1.0) {
|
||||
switch (timing) {
|
||||
default:
|
||||
fadeAlpha = (float)fraction;
|
||||
break;
|
||||
case FadeJobConfig::EASE_IN:
|
||||
fadeAlpha = (float)(fraction*fraction*fraction);
|
||||
break;
|
||||
case FadeJobConfig::EASE_OUT:
|
||||
fadeAlpha = 1.f - (float)fraction;
|
||||
fadeAlpha = 1.f- fadeAlpha*fadeAlpha*fadeAlpha;
|
||||
break;
|
||||
case FadeJobConfig::EASE_IN_OUT:
|
||||
fadeAlpha = (float)(fraction*fraction*fraction*(fraction*(fraction * 6 - 15) + 10));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return fadeAlpha;
|
||||
}
|
||||
|
||||
float FadeRenderJob::computeFadePercent(quint64 startTime) {
|
||||
const double time = (double)(int64_t(usecTimestampNow()) - int64_t(startTime)) / (double)(USECS_PER_SECOND);
|
||||
assert(_currentInstance);
|
||||
return _currentInstance->computeElementEnterThreshold(time,
|
||||
_currentInstance->_parameters->_durations[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN],
|
||||
_currentInstance->_parameters->_timing[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN]);
|
||||
}
|
||||
|
||||
void FadeRenderJob::updateFadeEdit(const render::RenderContextPointer& renderContext, const render::ItemBound& itemBounds) {
|
||||
if (_editPreviousTime == 0) {
|
||||
_editPreviousTime = usecTimestampNow();
|
||||
_editTime = 0.0;
|
||||
}
|
||||
|
||||
uint64_t now = usecTimestampNow();
|
||||
const double deltaTime = (int64_t(now) - int64_t(_editPreviousTime)) / double(USECS_PER_SECOND);
|
||||
const int editedCategory = _parameters->_editedCategory;
|
||||
const double eventDuration = (double)_parameters->_durations[editedCategory];
|
||||
const FadeJobConfig::Timing timing = _parameters->_timing[editedCategory];
|
||||
const double waitTime = 0.5; // Wait between fade in and out
|
||||
double cycleTime = fmod(_editTime, (eventDuration + waitTime) * 2.0);
|
||||
bool inverseTime = false;
|
||||
|
||||
_editTime += deltaTime;
|
||||
_editPreviousTime = now;
|
||||
|
||||
if (_parameters->_isManualThresholdEnabled) {
|
||||
_editThreshold = _parameters->_manualThreshold;
|
||||
}
|
||||
else {
|
||||
if (cycleTime < eventDuration) {
|
||||
_editThreshold = 1.f - computeElementEnterThreshold(cycleTime, eventDuration, timing);
|
||||
}
|
||||
else if (cycleTime < (eventDuration + waitTime)) {
|
||||
_editThreshold = 0.f;
|
||||
}
|
||||
else if (cycleTime < (2 * eventDuration + waitTime)) {
|
||||
_editThreshold = computeElementEnterThreshold(cycleTime - (eventDuration + waitTime), eventDuration, timing);
|
||||
inverseTime = true;
|
||||
}
|
||||
else {
|
||||
_editThreshold = 1.f;
|
||||
inverseTime = true;
|
||||
}
|
||||
}
|
||||
|
||||
float threshold = _editThreshold;
|
||||
if (editedCategory != FadeJobConfig::BUBBLE_ISECT_OWNER) {
|
||||
threshold = (threshold - 0.5f)*_parameters->_thresholdScale[editedCategory] + 0.5f;
|
||||
}
|
||||
renderContext->jobConfig->setProperty("threshold", threshold);
|
||||
|
||||
_editNoiseOffset = _parameters->_noiseSpeed[editedCategory] * (float)_editTime;
|
||||
if (inverseTime) {
|
||||
_editNoiseOffset = -_editNoiseOffset;
|
||||
}
|
||||
|
||||
switch (editedCategory) {
|
||||
case FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN:
|
||||
break;
|
||||
|
||||
case FadeJobConfig::BUBBLE_ISECT_OWNER:
|
||||
{
|
||||
const glm::vec3 cameraPos = renderContext->args->getViewFrustum().getPosition();
|
||||
glm::vec3 delta = itemBounds.bound.calcCenter() - cameraPos;
|
||||
float distance = glm::length(delta);
|
||||
|
||||
delta = glm::normalize(delta) * std::max(0.f, distance - 0.5f);
|
||||
|
||||
_editBaseOffset = cameraPos + delta*_editThreshold;
|
||||
_editThreshold = 0.33f;
|
||||
}
|
||||
break;
|
||||
|
||||
case FadeJobConfig::BUBBLE_ISECT_TRESPASSER:
|
||||
{
|
||||
_editBaseOffset = glm::vec3{ 0.f, 0.f, 0.f };
|
||||
}
|
||||
break;
|
||||
|
||||
case FadeJobConfig::USER_ENTER_LEAVE_DOMAIN:
|
||||
{
|
||||
_editBaseOffset = itemBounds.bound.calcCenter();
|
||||
_editBaseOffset.y -= itemBounds.bound.getDimensions().y / 2.f;
|
||||
}
|
||||
break;
|
||||
|
||||
case FadeJobConfig::AVATAR_CHANGE:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void FadeRenderJob::bindPerBatch(gpu::Batch& batch, int fadeMaskMapLocation, int fadeBufferLocation) {
|
||||
assert(_currentFadeMaskMap);
|
||||
assert(_currentFadeBuffer!=nullptr);
|
||||
bindPerBatch(batch, _currentFadeMaskMap, fadeMaskMapLocation, _currentFadeBuffer, fadeBufferLocation);
|
||||
}
|
||||
|
||||
void FadeRenderJob::bindPerBatch(gpu::Batch& batch, gpu::TexturePointer texture, int fadeMaskMapLocation, const gpu::BufferView* buffer, int fadeBufferLocation) {
|
||||
batch.setResourceTexture(fadeMaskMapLocation, texture);
|
||||
batch.setUniformBuffer(fadeBufferLocation, *buffer);
|
||||
}
|
||||
|
||||
void FadeRenderJob::bindPerBatch(gpu::Batch& batch, gpu::TexturePointer texture, const gpu::BufferView* buffer, const gpu::PipelinePointer& pipeline) {
|
||||
auto program = pipeline->getProgram();
|
||||
auto maskMapLocation = program->getTextures().findLocation("fadeMaskMap");
|
||||
auto bufferLocation = program->getUniformBuffers().findLocation("fadeParametersBuffer");
|
||||
bindPerBatch(batch, texture, maskMapLocation, buffer, bufferLocation);
|
||||
}
|
||||
|
||||
bool FadeRenderJob::bindPerItem(gpu::Batch& batch, RenderArgs* args, glm::vec3 offset, quint64 startTime) {
|
||||
return bindPerItem(batch, args->_pipeline->pipeline.get(), offset, startTime);
|
||||
}
|
||||
|
||||
bool FadeRenderJob::bindPerItem(gpu::Batch& batch, const gpu::Pipeline* pipeline, glm::vec3 offset, quint64 startTime) {
|
||||
auto& uniforms = pipeline->getProgram()->getUniforms();
|
||||
auto fadeNoiseOffsetLocation = uniforms.findLocation("fadeNoiseOffset");
|
||||
auto fadeBaseOffsetLocation = uniforms.findLocation("fadeBaseOffset");
|
||||
auto fadeThresholdLocation = uniforms.findLocation("fadeThreshold");
|
||||
auto fadeCategoryLocation = uniforms.findLocation("fadeCategory");
|
||||
|
||||
if (fadeNoiseOffsetLocation >= 0 || fadeBaseOffsetLocation>=0 || fadeThresholdLocation >= 0 || fadeCategoryLocation>=0) {
|
||||
float threshold;
|
||||
int eventCategory = FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN;
|
||||
glm::vec3 noiseOffset = offset;
|
||||
glm::vec3 baseOffset = offset;
|
||||
|
||||
threshold = 1.f-computeFadePercent(startTime);
|
||||
|
||||
// Manage interactive edition override
|
||||
assert(_currentInstance);
|
||||
if (_currentInstance->_parameters->_isEditEnabled) {
|
||||
eventCategory = _currentInstance->_parameters->_editedCategory;
|
||||
threshold = _currentInstance->_editThreshold;
|
||||
noiseOffset += _currentInstance->_editNoiseOffset;
|
||||
// This works supposing offset is the world position of the object that is fading.
|
||||
if (eventCategory != FadeJobConfig::BUBBLE_ISECT_TRESPASSER) {
|
||||
baseOffset = _currentInstance->_editBaseOffset - offset;
|
||||
}
|
||||
}
|
||||
|
||||
if (eventCategory != FadeJobConfig::BUBBLE_ISECT_OWNER) {
|
||||
threshold = (threshold - 0.5f)*_currentInstance->_parameters->_thresholdScale[eventCategory] + 0.5f;
|
||||
}
|
||||
|
||||
batch._glUniform1i(fadeCategoryLocation, eventCategory);
|
||||
batch._glUniform1f(fadeThresholdLocation, threshold);
|
||||
// This is really temporary
|
||||
batch._glUniform3f(fadeNoiseOffsetLocation, noiseOffset.x, noiseOffset.y, noiseOffset.z);
|
||||
// This is really temporary
|
||||
batch._glUniform3f(fadeBaseOffsetLocation, baseOffset.x, baseOffset.y, baseOffset.z);
|
||||
|
||||
return threshold > 0.f;
|
||||
}
|
||||
return false;
|
||||
}
|
333
libraries/render-utils/src/FadeEffect.h
Normal file
333
libraries/render-utils/src/FadeEffect.h
Normal file
|
@ -0,0 +1,333 @@
|
|||
//
|
||||
// FadeEffect.h
|
||||
// libraries/render-utils/src/
|
||||
//
|
||||
// Created by Olivier Prat on 06/06/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
#ifndef hifi_FadeEffect_h
|
||||
#define hifi_FadeEffect_h
|
||||
|
||||
#include <gpu/Pipeline.h>
|
||||
#include <render/ShapePipeline.h>
|
||||
#include <render/RenderFetchCullSortTask.h>
|
||||
|
||||
#include "LightingModel.h"
|
||||
|
||||
class FadeSwitchJobConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool editFade MEMBER editFade NOTIFY dirty)
|
||||
|
||||
public:
|
||||
|
||||
bool editFade{ false };
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
|
||||
};
|
||||
|
||||
class FadeJobConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int editedCategory MEMBER editedCategory WRITE setEditedCategory NOTIFY dirtyCategory)
|
||||
Q_PROPERTY(float duration READ getDuration WRITE setDuration NOTIFY dirty)
|
||||
Q_PROPERTY(float baseSizeX READ getBaseSizeX WRITE setBaseSizeX NOTIFY dirty)
|
||||
Q_PROPERTY(float baseSizeY READ getBaseSizeY WRITE setBaseSizeY NOTIFY dirty)
|
||||
Q_PROPERTY(float baseSizeZ READ getBaseSizeZ WRITE setBaseSizeZ NOTIFY dirty)
|
||||
Q_PROPERTY(float baseLevel READ getBaseLevel WRITE setBaseLevel NOTIFY dirty)
|
||||
Q_PROPERTY(bool _isInverted READ isInverted WRITE setInverted NOTIFY dirty)
|
||||
Q_PROPERTY(float noiseSizeX READ getNoiseSizeX WRITE setNoiseSizeX NOTIFY dirty)
|
||||
Q_PROPERTY(float noiseSizeY READ getNoiseSizeY WRITE setNoiseSizeY NOTIFY dirty)
|
||||
Q_PROPERTY(float noiseSizeZ READ getNoiseSizeZ WRITE setNoiseSizeZ NOTIFY dirty)
|
||||
Q_PROPERTY(float noiseLevel READ getNoiseLevel WRITE setNoiseLevel NOTIFY dirty)
|
||||
Q_PROPERTY(float edgeWidth READ getEdgeWidth WRITE setEdgeWidth NOTIFY dirty)
|
||||
Q_PROPERTY(float edgeInnerColorR READ getEdgeInnerColorR WRITE setEdgeInnerColorR NOTIFY dirty)
|
||||
Q_PROPERTY(float edgeInnerColorG READ getEdgeInnerColorG WRITE setEdgeInnerColorG NOTIFY dirty)
|
||||
Q_PROPERTY(float edgeInnerColorB READ getEdgeInnerColorB WRITE setEdgeInnerColorB NOTIFY dirty)
|
||||
Q_PROPERTY(float edgeInnerIntensity READ getEdgeInnerIntensity WRITE setEdgeInnerIntensity NOTIFY dirty)
|
||||
Q_PROPERTY(float edgeOuterColorR READ getEdgeOuterColorR WRITE setEdgeOuterColorR NOTIFY dirty)
|
||||
Q_PROPERTY(float edgeOuterColorG READ getEdgeOuterColorG WRITE setEdgeOuterColorG NOTIFY dirty)
|
||||
Q_PROPERTY(float edgeOuterColorB READ getEdgeOuterColorB WRITE setEdgeOuterColorB NOTIFY dirty)
|
||||
Q_PROPERTY(float edgeOuterIntensity READ getEdgeOuterIntensity WRITE setEdgeOuterIntensity NOTIFY dirty)
|
||||
Q_PROPERTY(bool manualFade MEMBER manualFade NOTIFY dirty)
|
||||
Q_PROPERTY(float manualThreshold MEMBER manualThreshold NOTIFY dirty)
|
||||
Q_PROPERTY(int timing READ getTiming WRITE setTiming NOTIFY dirty)
|
||||
Q_PROPERTY(float noiseSpeedX READ getNoiseSpeedX WRITE setNoiseSpeedX NOTIFY dirty)
|
||||
Q_PROPERTY(float noiseSpeedY READ getNoiseSpeedY WRITE setNoiseSpeedY NOTIFY dirty)
|
||||
Q_PROPERTY(float noiseSpeedZ READ getNoiseSpeedZ WRITE setNoiseSpeedZ NOTIFY dirty)
|
||||
|
||||
public:
|
||||
|
||||
enum EventCategory {
|
||||
ELEMENT_ENTER_LEAVE_DOMAIN = 0,
|
||||
BUBBLE_ISECT_OWNER,
|
||||
BUBBLE_ISECT_TRESPASSER,
|
||||
USER_ENTER_LEAVE_DOMAIN,
|
||||
AVATAR_CHANGE,
|
||||
|
||||
// Don't forget to modify Fade.slh to reflect the change in number of categories
|
||||
EVENT_CATEGORY_COUNT
|
||||
};
|
||||
|
||||
enum Timing {
|
||||
LINEAR,
|
||||
EASE_IN,
|
||||
EASE_OUT,
|
||||
EASE_IN_OUT,
|
||||
|
||||
TIMING_COUNT
|
||||
};
|
||||
|
||||
FadeJobConfig();
|
||||
|
||||
void setEditedCategory(int value);
|
||||
|
||||
void setDuration(float value);
|
||||
float getDuration() const;
|
||||
|
||||
void setBaseSizeX(float value);
|
||||
float getBaseSizeX() const;
|
||||
|
||||
void setBaseSizeY(float value);
|
||||
float getBaseSizeY() const;
|
||||
|
||||
void setBaseSizeZ(float value);
|
||||
float getBaseSizeZ() const;
|
||||
|
||||
void setBaseLevel(float value);
|
||||
float getBaseLevel() const { return events[editedCategory].baseLevel; }
|
||||
|
||||
void setInverted(bool value);
|
||||
bool isInverted() const;
|
||||
|
||||
void setNoiseSizeX(float value);
|
||||
float getNoiseSizeX() const;
|
||||
|
||||
void setNoiseSizeY(float value);
|
||||
float getNoiseSizeY() const;
|
||||
|
||||
void setNoiseSizeZ(float value);
|
||||
float getNoiseSizeZ() const;
|
||||
|
||||
void setNoiseLevel(float value);
|
||||
float getNoiseLevel() const { return events[editedCategory].noiseLevel; }
|
||||
|
||||
void setNoiseSpeedX(float value);
|
||||
float getNoiseSpeedX() const;
|
||||
|
||||
void setNoiseSpeedY(float value);
|
||||
float getNoiseSpeedY() const;
|
||||
|
||||
void setNoiseSpeedZ(float value);
|
||||
float getNoiseSpeedZ() const;
|
||||
|
||||
void setEdgeWidth(float value);
|
||||
float getEdgeWidth() const;
|
||||
|
||||
void setEdgeInnerColorR(float value);
|
||||
float getEdgeInnerColorR() const { return events[editedCategory].edgeInnerColor.r; }
|
||||
|
||||
void setEdgeInnerColorG(float value);
|
||||
float getEdgeInnerColorG() const { return events[editedCategory].edgeInnerColor.g; }
|
||||
|
||||
void setEdgeInnerColorB(float value);
|
||||
float getEdgeInnerColorB() const { return events[editedCategory].edgeInnerColor.b; }
|
||||
|
||||
void setEdgeInnerIntensity(float value);
|
||||
float getEdgeInnerIntensity() const { return events[editedCategory].edgeInnerColor.a; }
|
||||
|
||||
void setEdgeOuterColorR(float value);
|
||||
float getEdgeOuterColorR() const { return events[editedCategory].edgeOuterColor.r; }
|
||||
|
||||
void setEdgeOuterColorG(float value);
|
||||
float getEdgeOuterColorG() const { return events[editedCategory].edgeOuterColor.g; }
|
||||
|
||||
void setEdgeOuterColorB(float value);
|
||||
float getEdgeOuterColorB() const { return events[editedCategory].edgeOuterColor.b; }
|
||||
|
||||
void setEdgeOuterIntensity(float value);
|
||||
float getEdgeOuterIntensity() const { return events[editedCategory].edgeOuterColor.a; }
|
||||
|
||||
void setTiming(int value);
|
||||
int getTiming() const { return events[editedCategory].timing; }
|
||||
|
||||
bool manualFade{ false };
|
||||
float manualThreshold{ 0.f };
|
||||
int editedCategory{ ELEMENT_ENTER_LEAVE_DOMAIN };
|
||||
|
||||
struct Event {
|
||||
glm::vec4 edgeInnerColor;
|
||||
glm::vec4 edgeOuterColor;
|
||||
glm::vec3 noiseSize;
|
||||
glm::vec3 noiseSpeed;
|
||||
glm::vec3 baseSize;
|
||||
float noiseLevel;
|
||||
float baseLevel;
|
||||
float _duration;
|
||||
float edgeWidth;
|
||||
int timing;
|
||||
bool _isInverted;
|
||||
};
|
||||
|
||||
Event events[EVENT_CATEGORY_COUNT];
|
||||
|
||||
Q_INVOKABLE void save() const;
|
||||
Q_INVOKABLE void load();
|
||||
|
||||
static QString eventNames[EVENT_CATEGORY_COUNT];
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
void dirtyCategory();
|
||||
|
||||
};
|
||||
|
||||
struct FadeCommonParameters
|
||||
{
|
||||
using Pointer = std::shared_ptr<FadeCommonParameters>;
|
||||
|
||||
FadeCommonParameters();
|
||||
|
||||
bool _isEditEnabled{ false };
|
||||
bool _isManualThresholdEnabled{ false };
|
||||
float _manualThreshold{ 0.f };
|
||||
float _thresholdScale[FadeJobConfig::EVENT_CATEGORY_COUNT];
|
||||
int _editedCategory{ FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN };
|
||||
float _durations[FadeJobConfig::EVENT_CATEGORY_COUNT];
|
||||
glm::vec3 _noiseSpeed[FadeJobConfig::EVENT_CATEGORY_COUNT];
|
||||
FadeJobConfig::Timing _timing[FadeJobConfig::EVENT_CATEGORY_COUNT];
|
||||
};
|
||||
|
||||
class FadeSwitchJob {
|
||||
public:
|
||||
|
||||
enum FadeBuckets {
|
||||
OPAQUE_SHAPE = 0,
|
||||
TRANSPARENT_SHAPE,
|
||||
|
||||
NUM_BUCKETS
|
||||
};
|
||||
|
||||
using FadeOutput = render::VaryingArray<render::ItemBounds, FadeBuckets::NUM_BUCKETS>;
|
||||
|
||||
using Input = RenderFetchCullSortTask::Output;
|
||||
using Output = render::VaryingSet3 < RenderFetchCullSortTask::Output, FadeOutput, render::Item::Bound > ;
|
||||
using Config = FadeSwitchJobConfig;
|
||||
using JobModel = render::Job::ModelIO<FadeSwitchJob, Input, Output, Config>;
|
||||
|
||||
FadeSwitchJob(FadeCommonParameters::Pointer commonParams) : _parameters{ commonParams } {}
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output);
|
||||
|
||||
private:
|
||||
|
||||
FadeCommonParameters::Pointer _parameters;
|
||||
|
||||
void distribute(const render::RenderContextPointer& renderContext, const render::Varying& input,
|
||||
render::Varying& normalOutput, render::Varying& fadeOutput, const render::Item* editedItem = nullptr) const;
|
||||
const render::Item* findNearestItem(const render::RenderContextPointer& renderContext, const render::Varying& input, float& minIsectDistance) const;
|
||||
};
|
||||
|
||||
struct FadeParameters
|
||||
{
|
||||
glm::vec4 _baseInvSizeAndLevel;
|
||||
glm::vec4 _noiseInvSizeAndLevel;
|
||||
glm::vec4 _innerEdgeColor;
|
||||
glm::vec4 _outerEdgeColor;
|
||||
glm::vec2 _edgeWidthInvWidth;
|
||||
glm::int32 _isInverted;
|
||||
glm::float32 _padding;
|
||||
};
|
||||
|
||||
struct FadeConfiguration
|
||||
{
|
||||
FadeParameters parameters[FadeJobConfig::EVENT_CATEGORY_COUNT];
|
||||
};
|
||||
|
||||
class FadeConfigureJob {
|
||||
|
||||
public:
|
||||
|
||||
using UniformBuffer = gpu::StructBuffer<FadeConfiguration>;
|
||||
using Input = render::Item::Bound ;
|
||||
using Output = render::VaryingSet2<gpu::TexturePointer, UniformBuffer>;
|
||||
using Config = FadeJobConfig;
|
||||
using JobModel = render::Job::ModelIO<FadeConfigureJob, Input, Output, Config>;
|
||||
|
||||
FadeConfigureJob(FadeCommonParameters::Pointer commonParams);
|
||||
|
||||
const gpu::TexturePointer getFadeMaskMap() const { return _fadeMaskMap; }
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output);
|
||||
|
||||
private:
|
||||
|
||||
FadeCommonParameters::Pointer _parameters;
|
||||
bool _isBufferDirty{ true };
|
||||
gpu::TexturePointer _fadeMaskMap;
|
||||
FadeParameters _configurations[FadeJobConfig::EVENT_CATEGORY_COUNT];
|
||||
};
|
||||
|
||||
|
||||
class FadeRenderJobConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float threshold MEMBER threshold NOTIFY dirty)
|
||||
|
||||
public:
|
||||
|
||||
float threshold{ 0.f };
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
|
||||
};
|
||||
|
||||
class FadeRenderJob {
|
||||
|
||||
public:
|
||||
|
||||
using Config = FadeRenderJobConfig;
|
||||
using Input = render::VaryingSet3<render::ItemBounds, LightingModelPointer, FadeConfigureJob::Output>;
|
||||
using JobModel = render::Job::ModelI<FadeRenderJob, Input, Config>;
|
||||
|
||||
FadeRenderJob(FadeCommonParameters::Pointer commonParams, render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber }, _parameters{ commonParams } {}
|
||||
|
||||
void configure(const Config& config) {}
|
||||
void run(const render::RenderContextPointer& renderContext, const Input& inputs);
|
||||
|
||||
static void bindPerBatch(gpu::Batch& batch, int fadeMaskMapLocation, int fadeBufferLocation);
|
||||
static void bindPerBatch(gpu::Batch& batch, gpu::TexturePointer texture, int fadeMaskMapLocation, const gpu::BufferView* buffer, int fadeBufferLocation);
|
||||
static void bindPerBatch(gpu::Batch& batch, gpu::TexturePointer texture, const gpu::BufferView* buffer, const gpu::PipelinePointer& pipeline);
|
||||
|
||||
static bool bindPerItem(gpu::Batch& batch, RenderArgs* args, glm::vec3 offset, quint64 startTime);
|
||||
static bool bindPerItem(gpu::Batch& batch, const gpu::Pipeline* pipeline, glm::vec3 offset, quint64 startTime);
|
||||
|
||||
static float computeFadePercent(quint64 startTime);
|
||||
|
||||
private:
|
||||
|
||||
static const FadeRenderJob* _currentInstance;
|
||||
static gpu::TexturePointer _currentFadeMaskMap;
|
||||
static const gpu::BufferView* _currentFadeBuffer;
|
||||
|
||||
render::ShapePlumberPointer _shapePlumber;
|
||||
FadeCommonParameters::Pointer _parameters;
|
||||
|
||||
float computeElementEnterThreshold(double time, const double period, FadeJobConfig::Timing timing) const;
|
||||
|
||||
// Everything needed for interactive edition
|
||||
uint64_t _editPreviousTime{ 0 };
|
||||
double _editTime{ 0.0 };
|
||||
float _editThreshold{ 0.f };
|
||||
glm::vec3 _editNoiseOffset{ 0.f, 0.f, 0.f };
|
||||
glm::vec3 _editBaseOffset{ 0.f, 0.f, 0.f };
|
||||
|
||||
void updateFadeEdit(const render::RenderContextPointer& renderContext, const render::ItemBound& itemBounds);
|
||||
};
|
||||
|
||||
#endif // hifi_FadeEffect_h
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "TextureCache.h"
|
||||
#include "RenderUtilsLogging.h"
|
||||
#include "FadeEffect.h"
|
||||
#include "StencilMaskPass.h"
|
||||
|
||||
#include "gpu/StandardShaderLib.h"
|
||||
|
@ -36,6 +37,9 @@
|
|||
#include "simple_vert.h"
|
||||
#include "simple_textured_frag.h"
|
||||
#include "simple_textured_unlit_frag.h"
|
||||
#include "simple_fade_vert.h"
|
||||
#include "simple_textured_fade_frag.h"
|
||||
#include "simple_textured_unlit_fade_frag.h"
|
||||
#include "simple_opaque_web_browser_frag.h"
|
||||
#include "simple_opaque_web_browser_overlay_frag.h"
|
||||
#include "simple_transparent_web_browser_frag.h"
|
||||
|
@ -448,33 +452,13 @@ gpu::Stream::FormatPointer& getInstancedSolidStreamFormat() {
|
|||
|
||||
render::ShapePipelinePointer GeometryCache::_simpleOpaquePipeline;
|
||||
render::ShapePipelinePointer GeometryCache::_simpleTransparentPipeline;
|
||||
render::ShapePipelinePointer GeometryCache::_simpleOpaqueFadePipeline;
|
||||
render::ShapePipelinePointer GeometryCache::_simpleTransparentFadePipeline;
|
||||
render::ShapePipelinePointer GeometryCache::_simpleWirePipeline;
|
||||
|
||||
GeometryCache::GeometryCache() :
|
||||
_nextID(0) {
|
||||
buildShapes();
|
||||
GeometryCache::_simpleOpaquePipeline =
|
||||
std::make_shared<render::ShapePipeline>(getSimplePipeline(false, false, true, false), nullptr,
|
||||
[](const render::ShapePipeline&, gpu::Batch& batch) {
|
||||
// Set the defaults needed for a simple program
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
|
||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
},
|
||||
nullptr
|
||||
);
|
||||
GeometryCache::_simpleTransparentPipeline =
|
||||
std::make_shared<render::ShapePipeline>(getSimplePipeline(false, true, true, false), nullptr,
|
||||
[](const render::ShapePipeline&, gpu::Batch& batch) {
|
||||
// Set the defaults needed for a simple program
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
|
||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
},
|
||||
nullptr
|
||||
);
|
||||
GeometryCache::_simpleWirePipeline =
|
||||
std::make_shared<render::ShapePipeline>(getSimplePipeline(false, false, true, true), nullptr,
|
||||
[](const render::ShapePipeline&, gpu::Batch& batch) {},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
GeometryCache::~GeometryCache() {
|
||||
|
@ -519,6 +503,33 @@ void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) {
|
|||
batch.setInputBuffer(gpu::Stream::COLOR, colorView);
|
||||
}
|
||||
|
||||
void GeometryCache::initializeShapePipelines() {
|
||||
GeometryCache::_simpleOpaquePipeline = getShapePipeline(false, false, true, false);
|
||||
GeometryCache::_simpleTransparentPipeline = getShapePipeline(false, true, true, false);
|
||||
GeometryCache::_simpleOpaqueFadePipeline = getShapePipeline(false, false, true, false, false, true);
|
||||
GeometryCache::_simpleTransparentFadePipeline = getShapePipeline(false, true, true, false, false, true);
|
||||
GeometryCache::_simpleWirePipeline = getShapePipeline(false, false, true, true);
|
||||
}
|
||||
|
||||
render::ShapePipelinePointer GeometryCache::getShapePipeline(bool textured, bool transparent, bool culled,
|
||||
bool unlit, bool depthBias, bool fading) {
|
||||
return std::make_shared<render::ShapePipeline>(getSimplePipeline(textured, transparent, culled, unlit, depthBias, fading), nullptr,
|
||||
[](const render::ShapePipeline&, gpu::Batch& batch) {
|
||||
// Set the defaults needed for a simple program
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
|
||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
render::ShapePipelinePointer GeometryCache::getOpaqueShapePipeline(bool isFading) {
|
||||
return isFading ? _simpleOpaqueFadePipeline : _simpleOpaquePipeline;
|
||||
}
|
||||
|
||||
render::ShapePipelinePointer GeometryCache::getTransparentShapePipeline(bool isFading) {
|
||||
return isFading ? _simpleTransparentFadePipeline : _simpleTransparentPipeline;
|
||||
}
|
||||
|
||||
void GeometryCache::renderShape(gpu::Batch& batch, Shape shape) {
|
||||
batch.setInputFormat(getSolidStreamFormat());
|
||||
_shapes[shape].draw(batch);
|
||||
|
@ -1770,6 +1781,7 @@ public:
|
|||
IS_CULLED_FLAG,
|
||||
IS_UNLIT_FLAG,
|
||||
HAS_DEPTH_BIAS_FLAG,
|
||||
IS_FADING_FLAG,
|
||||
|
||||
NUM_FLAGS,
|
||||
};
|
||||
|
@ -1780,6 +1792,7 @@ public:
|
|||
IS_CULLED = (1 << IS_CULLED_FLAG),
|
||||
IS_UNLIT = (1 << IS_UNLIT_FLAG),
|
||||
HAS_DEPTH_BIAS = (1 << HAS_DEPTH_BIAS_FLAG),
|
||||
IS_FADING = (1 << IS_FADING_FLAG),
|
||||
};
|
||||
typedef unsigned short Flags;
|
||||
|
||||
|
@ -1790,6 +1803,7 @@ public:
|
|||
bool isCulled() const { return isFlag(IS_CULLED); }
|
||||
bool isUnlit() const { return isFlag(IS_UNLIT); }
|
||||
bool hasDepthBias() const { return isFlag(HAS_DEPTH_BIAS); }
|
||||
bool isFading() const { return isFlag(IS_FADING); }
|
||||
|
||||
Flags _flags = 0;
|
||||
short _spare = 0;
|
||||
|
@ -1798,9 +1812,9 @@ public:
|
|||
|
||||
|
||||
SimpleProgramKey(bool textured = false, bool transparent = false, bool culled = true,
|
||||
bool unlit = false, bool depthBias = false) {
|
||||
bool unlit = false, bool depthBias = false, bool fading = false) {
|
||||
_flags = (textured ? IS_TEXTURED : 0) | (transparent ? IS_TRANSPARENT : 0) | (culled ? IS_CULLED : 0) |
|
||||
(unlit ? IS_UNLIT : 0) | (depthBias ? HAS_DEPTH_BIAS : 0);
|
||||
(unlit ? IS_UNLIT : 0) | (depthBias ? HAS_DEPTH_BIAS : 0) | (fading ? IS_FADING : 0);
|
||||
}
|
||||
|
||||
SimpleProgramKey(int bitmask) : _flags(bitmask) {}
|
||||
|
@ -1879,23 +1893,8 @@ void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool tra
|
|||
}
|
||||
}
|
||||
|
||||
gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transparent, bool culled, bool unlit, bool depthBiased) {
|
||||
SimpleProgramKey config { textured, transparent, culled, unlit, depthBiased };
|
||||
|
||||
// Compile the shaders
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&]() {
|
||||
auto VS = gpu::Shader::createVertex(std::string(simple_vert));
|
||||
auto PS = gpu::Shader::createPixel(std::string(simple_textured_frag));
|
||||
auto PSUnlit = gpu::Shader::createPixel(std::string(simple_textured_unlit_frag));
|
||||
|
||||
_simpleShader = gpu::Shader::createProgram(VS, PS);
|
||||
_unlitShader = gpu::Shader::createProgram(VS, PSUnlit);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*_simpleShader, slotBindings);
|
||||
gpu::Shader::makeProgram(*_unlitShader, slotBindings);
|
||||
});
|
||||
gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transparent, bool culled, bool unlit, bool depthBiased, bool fading) {
|
||||
SimpleProgramKey config { textured, transparent, culled, unlit, depthBiased, fading };
|
||||
|
||||
// If the pipeline already exists, return it
|
||||
auto it = _simplePrograms.find(config);
|
||||
|
@ -1903,6 +1902,37 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp
|
|||
return it.value();
|
||||
}
|
||||
|
||||
// Compile the shaders
|
||||
if (!fading) {
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&]() {
|
||||
auto VS = gpu::Shader::createVertex(std::string(simple_vert));
|
||||
auto PS = gpu::Shader::createPixel(std::string(simple_textured_frag));
|
||||
auto PSUnlit = gpu::Shader::createPixel(std::string(simple_textured_unlit_frag));
|
||||
|
||||
_simpleShader = gpu::Shader::createProgram(VS, PS);
|
||||
_unlitShader = gpu::Shader::createProgram(VS, PSUnlit);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*_simpleShader, slotBindings);
|
||||
gpu::Shader::makeProgram(*_unlitShader, slotBindings);
|
||||
});
|
||||
} else {
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&]() {
|
||||
auto VS = gpu::Shader::createVertex(std::string(simple_fade_vert));
|
||||
auto PS = gpu::Shader::createPixel(std::string(simple_textured_fade_frag));
|
||||
auto PSUnlit = gpu::Shader::createPixel(std::string(simple_textured_unlit_fade_frag));
|
||||
|
||||
_simpleFadeShader = gpu::Shader::createProgram(VS, PS);
|
||||
_unlitFadeShader = gpu::Shader::createProgram(VS, PSUnlit);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*_simpleFadeShader, slotBindings);
|
||||
gpu::Shader::makeProgram(*_unlitFadeShader, slotBindings);
|
||||
});
|
||||
}
|
||||
|
||||
// If the pipeline did not exist, make it
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
if (config.isCulled()) {
|
||||
|
@ -1921,11 +1951,12 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp
|
|||
|
||||
if (config.isTransparent()) {
|
||||
PrepareStencil::testMask(*state);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
PrepareStencil::testMaskDrawShape(*state);
|
||||
}
|
||||
|
||||
gpu::ShaderPointer program = (config.isUnlit()) ? _unlitShader : _simpleShader;
|
||||
gpu::ShaderPointer program = (config.isUnlit()) ? (config.isFading() ? _unlitFadeShader : _unlitShader) : (config.isFading() ? _simpleFadeShader : _simpleShader);
|
||||
gpu::PipelinePointer pipeline = gpu::Pipeline::create(program, state);
|
||||
_simplePrograms.insert(config, pipeline);
|
||||
return pipeline;
|
||||
|
@ -1967,19 +1998,23 @@ void renderInstances(gpu::Batch& batch, const glm::vec4& color, bool isWire,
|
|||
}
|
||||
|
||||
void GeometryCache::renderSolidShapeInstance(gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
assert(pipeline != nullptr);
|
||||
renderInstances(batch, color, false, pipeline, shape);
|
||||
}
|
||||
|
||||
void GeometryCache::renderWireShapeInstance(gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
assert(pipeline != nullptr);
|
||||
renderInstances(batch, color, true, pipeline, shape);
|
||||
}
|
||||
|
||||
|
||||
void GeometryCache::renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
assert(pipeline != nullptr);
|
||||
renderInstances(batch, color, false, pipeline, GeometryCache::Sphere);
|
||||
}
|
||||
|
||||
void GeometryCache::renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
assert(pipeline != nullptr);
|
||||
renderInstances(batch, color, true, pipeline, GeometryCache::Sphere);
|
||||
}
|
||||
|
||||
|
@ -1988,6 +2023,7 @@ void GeometryCache::renderWireSphereInstance(gpu::Batch& batch, const glm::vec4&
|
|||
//#define DEBUG_SHAPES
|
||||
|
||||
void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
assert(pipeline != nullptr);
|
||||
#ifdef DEBUG_SHAPES
|
||||
static auto startTime = usecTimestampNow();
|
||||
renderInstances(INSTANCE_NAME, batch, color, pipeline, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
|
@ -2027,5 +2063,6 @@ void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4&
|
|||
|
||||
void GeometryCache::renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
static const std::string INSTANCE_NAME = __FUNCTION__;
|
||||
assert(pipeline != nullptr);
|
||||
renderInstances(batch, color, true, pipeline, GeometryCache::Cube);
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ public:
|
|||
bool unlit = false, bool depthBias = false);
|
||||
// Get the pipeline to render static geometry
|
||||
gpu::PipelinePointer getSimplePipeline(bool textured = false, bool transparent = false, bool culled = true,
|
||||
bool unlit = false, bool depthBias = false);
|
||||
bool unlit = false, bool depthBias = false, bool fading = false);
|
||||
|
||||
void bindOpaqueWebBrowserProgram(gpu::Batch& batch, bool isAA);
|
||||
gpu::PipelinePointer getOpaqueWebBrowserProgram(bool isAA);
|
||||
|
@ -164,9 +164,19 @@ public:
|
|||
void bindTransparentWebBrowserProgram(gpu::Batch& batch, bool isAA);
|
||||
gpu::PipelinePointer getTransparentWebBrowserProgram(bool isAA);
|
||||
|
||||
render::ShapePipelinePointer getOpaqueShapePipeline() { return GeometryCache::_simpleOpaquePipeline; }
|
||||
render::ShapePipelinePointer getTransparentShapePipeline() { return GeometryCache::_simpleTransparentPipeline; }
|
||||
render::ShapePipelinePointer getWireShapePipeline() { return GeometryCache::_simpleWirePipeline; }
|
||||
void initializeShapePipelines();
|
||||
|
||||
render::ShapePipelinePointer getShapePipeline(bool textured = false, bool transparent = false, bool culled = true,
|
||||
bool unlit = false, bool depthBias = false, bool fading = false);
|
||||
|
||||
render::ShapePipelinePointer getOpaqueShapePipeline() { assert(_simpleOpaquePipeline != nullptr); return _simpleOpaquePipeline; }
|
||||
render::ShapePipelinePointer getTransparentShapePipeline() { assert(_simpleTransparentPipeline != nullptr); return _simpleTransparentPipeline; }
|
||||
render::ShapePipelinePointer getOpaqueFadeShapePipeline() { assert(_simpleOpaqueFadePipeline != nullptr); return _simpleOpaqueFadePipeline; }
|
||||
render::ShapePipelinePointer getTransparentFadeShapePipeline() { assert(_simpleTransparentFadePipeline != nullptr); return _simpleTransparentFadePipeline; }
|
||||
render::ShapePipelinePointer getOpaqueShapePipeline(bool isFading);
|
||||
render::ShapePipelinePointer getTransparentShapePipeline(bool isFading);
|
||||
render::ShapePipelinePointer getWireShapePipeline() { assert(_simpleWirePipeline != nullptr); return GeometryCache::_simpleWirePipeline; }
|
||||
|
||||
|
||||
// Static (instanced) geometry
|
||||
void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
||||
|
@ -418,8 +428,12 @@ private:
|
|||
|
||||
gpu::ShaderPointer _simpleShader;
|
||||
gpu::ShaderPointer _unlitShader;
|
||||
gpu::ShaderPointer _simpleFadeShader;
|
||||
gpu::ShaderPointer _unlitFadeShader;
|
||||
static render::ShapePipelinePointer _simpleOpaquePipeline;
|
||||
static render::ShapePipelinePointer _simpleTransparentPipeline;
|
||||
static render::ShapePipelinePointer _simpleOpaqueFadePipeline;
|
||||
static render::ShapePipelinePointer _simpleTransparentFadePipeline;
|
||||
static render::ShapePipelinePointer _simpleOpaqueOverlayPipeline;
|
||||
static render::ShapePipelinePointer _simpleTransparentOverlayPipeline;
|
||||
static render::ShapePipelinePointer _simpleWirePipeline;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "DeferredLightingEffect.h"
|
||||
#include "EntityItem.h"
|
||||
#include "FadeEffect.h"
|
||||
|
||||
using namespace render;
|
||||
|
||||
|
@ -318,6 +319,11 @@ template <> const ShapeKey shapeGetShapeKey(const ModelMeshPartPayload::Pointer&
|
|||
template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, RenderArgs* args) {
|
||||
return payload->render(args);
|
||||
}
|
||||
|
||||
template <> bool payloadMustFade(const ModelMeshPartPayload::Pointer& payload) {
|
||||
return payload->mustFade();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int _meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform) :
|
||||
|
@ -327,6 +333,7 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int _meshIndex, i
|
|||
assert(model && model->isLoaded());
|
||||
_model = model;
|
||||
auto& modelMesh = model->getGeometry()->getMeshes().at(_meshIndex);
|
||||
|
||||
updateMeshPart(modelMesh, partIndex);
|
||||
|
||||
updateTransform(transform, offsetTransform);
|
||||
|
@ -390,10 +397,6 @@ ItemKey ModelMeshPartPayload::getKey() const {
|
|||
builder.withTransparent();
|
||||
}
|
||||
}
|
||||
|
||||
if (_fadeState != FADE_COMPLETE) {
|
||||
builder.withTransparent();
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
@ -465,7 +468,7 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
|||
ShapeKey::Builder builder;
|
||||
builder.withMaterial();
|
||||
|
||||
if (isTranslucent || _fadeState != FADE_COMPLETE) {
|
||||
if (isTranslucent) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
if (hasTangents) {
|
||||
|
@ -486,6 +489,9 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
|||
if (wireframe) {
|
||||
builder.withWireframe();
|
||||
}
|
||||
if (_fadeState != STATE_COMPLETE) {
|
||||
builder.withFade();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
@ -510,9 +516,8 @@ void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) {
|
|||
}
|
||||
}
|
||||
|
||||
if (_fadeState != FADE_COMPLETE) {
|
||||
batch._glColor4f(1.0f, 1.0f, 1.0f, computeFadeAlpha());
|
||||
} else if (!_hasColorAttrib) {
|
||||
// TODO: Get rid of that extra call
|
||||
if (!_hasColorAttrib) {
|
||||
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
@ -525,26 +530,8 @@ void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline:
|
|||
batch.setModelTransform(_transform);
|
||||
}
|
||||
|
||||
float ModelMeshPartPayload::computeFadeAlpha() {
|
||||
if (_fadeState == FADE_WAITING_TO_START) {
|
||||
return 0.0f;
|
||||
}
|
||||
float fadeAlpha = 1.0f;
|
||||
const float INV_FADE_PERIOD = 1.0f / (float)(1 * USECS_PER_SECOND);
|
||||
float fraction = (float)(usecTimestampNow() - _fadeStartTime) * INV_FADE_PERIOD;
|
||||
if (fraction < 1.0f) {
|
||||
fadeAlpha = Interpolate::simpleNonLinearBlend(fraction);
|
||||
}
|
||||
if (fadeAlpha >= 1.0f) {
|
||||
_fadeState = FADE_COMPLETE;
|
||||
// when fade-in completes we flag model for one last "render item update"
|
||||
ModelPointer model = _model.lock();
|
||||
if (model) {
|
||||
model->setRenderItemsNeedUpdate();
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
return Interpolate::simpleNonLinearBlend(fadeAlpha);
|
||||
bool ModelMeshPartPayload::mustFade() const {
|
||||
return _fadeState != STATE_COMPLETE;
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::render(RenderArgs* args) {
|
||||
|
@ -555,14 +542,14 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
|
|||
return; // bail asap
|
||||
}
|
||||
|
||||
if (_fadeState == FADE_WAITING_TO_START) {
|
||||
if (_fadeState == STATE_WAITING_TO_START) {
|
||||
if (model->isLoaded()) {
|
||||
// FIXME as far as I can tell this is the ONLY reason render-util depends on entities.
|
||||
if (EntityItem::getEntitiesShouldFadeFunction()()) {
|
||||
_fadeStartTime = usecTimestampNow();
|
||||
_fadeState = FADE_IN_PROGRESS;
|
||||
_fadeState = STATE_IN_PROGRESS;
|
||||
} else {
|
||||
_fadeState = FADE_COMPLETE;
|
||||
_fadeState = STATE_COMPLETE;
|
||||
}
|
||||
model->setRenderItemsNeedUpdate();
|
||||
} else {
|
||||
|
@ -594,6 +581,17 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
|
|||
// apply material properties
|
||||
bindMaterial(batch, locations, args->_enableTexturing);
|
||||
|
||||
if (args->_enableFade) {
|
||||
// Apply fade effect
|
||||
if (!FadeRenderJob::bindPerItem(batch, args, _transform.getTranslation(), _fadeStartTime)) {
|
||||
_fadeState = STATE_COMPLETE;
|
||||
}
|
||||
}
|
||||
/* else {
|
||||
// TODO : very ugly way to update the fade state. Need to improve this with global fade manager.
|
||||
_fadeState = STATE_COMPLETE;
|
||||
}*/
|
||||
|
||||
args->_details._materialSwitches++;
|
||||
|
||||
// Draw!
|
||||
|
|
|
@ -22,10 +22,7 @@
|
|||
#include <model/Geometry.h>
|
||||
|
||||
#include "Model.h"
|
||||
|
||||
const uint8_t FADE_WAITING_TO_START = 0;
|
||||
const uint8_t FADE_IN_PROGRESS = 1;
|
||||
const uint8_t FADE_COMPLETE = 2;
|
||||
#include "FadeEffect.h"
|
||||
|
||||
class Model;
|
||||
|
||||
|
@ -95,13 +92,12 @@ public:
|
|||
const Transform& boundTransform,
|
||||
const gpu::BufferPointer& buffer);
|
||||
|
||||
float computeFadeAlpha();
|
||||
|
||||
// Render Item interface
|
||||
render::ItemKey getKey() const override;
|
||||
int getLayer() const;
|
||||
render::ShapeKey getShapeKey() const override; // shape interface
|
||||
void render(RenderArgs* args) override;
|
||||
bool mustFade() const;
|
||||
|
||||
// ModelMeshPartPayload functions to perform render
|
||||
void bindMesh(gpu::Batch& batch) override;
|
||||
|
@ -122,8 +118,16 @@ public:
|
|||
bool _materialNeedsUpdate { true };
|
||||
|
||||
private:
|
||||
quint64 _fadeStartTime { 0 };
|
||||
uint8_t _fadeState { FADE_WAITING_TO_START };
|
||||
|
||||
enum State : uint8_t {
|
||||
STATE_WAITING_TO_START = 0,
|
||||
STATE_IN_PROGRESS = 1,
|
||||
STATE_COMPLETE = 2,
|
||||
};
|
||||
|
||||
mutable quint64 _fadeStartTime { 0 };
|
||||
mutable State _fadeState { STATE_WAITING_TO_START } ;
|
||||
|
||||
};
|
||||
|
||||
namespace render {
|
||||
|
@ -132,6 +136,7 @@ namespace render {
|
|||
template <> int payloadGetLayer(const ModelMeshPartPayload::Pointer& payload);
|
||||
template <> const ShapeKey shapeGetShapeKey(const ModelMeshPartPayload::Pointer& payload);
|
||||
template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, RenderArgs* args);
|
||||
template <> bool payloadMustFade(const ModelMeshPartPayload::Pointer& payload);
|
||||
}
|
||||
|
||||
#endif // hifi_MeshPartPayload_h
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "FramebufferCache.h"
|
||||
#include "TextureCache.h"
|
||||
#include "ZoneRenderer.h"
|
||||
#include "FadeEffect.h"
|
||||
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
#include "AntialiasingEffect.h"
|
||||
|
@ -47,22 +48,33 @@ using namespace render;
|
|||
extern void initOverlay3DPipelines(render::ShapePlumber& plumber);
|
||||
extern void initDeferredPipelines(render::ShapePlumber& plumber);
|
||||
|
||||
void RenderDeferredTask::configure(const Config& config)
|
||||
{
|
||||
}
|
||||
|
||||
void RenderDeferredTask::build(JobModel& task, const render::Varying& input, render::Varying& output) {
|
||||
auto items = input.get<Input>();
|
||||
auto commonFadeParameters = std::make_shared<FadeCommonParameters>();
|
||||
const auto fadeSwitchOutputs = task.addJob<FadeSwitchJob>("FadeSwitch", input, commonFadeParameters).get<FadeSwitchJob::Output>();
|
||||
|
||||
const auto& items = fadeSwitchOutputs.get0();
|
||||
const auto& fadeItems = fadeSwitchOutputs.get1();
|
||||
const auto& fadeEditedItem = fadeSwitchOutputs[2];
|
||||
|
||||
const auto fadeConfigureOutputs = task.addJob<FadeConfigureJob>("FadeConfigure", fadeEditedItem, commonFadeParameters).get<FadeConfigureJob::Output>();
|
||||
|
||||
// Prepare the ShapePipelines
|
||||
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
|
||||
initDeferredPipelines(*shapePlumber);
|
||||
|
||||
// Extract opaques / transparents / lights / metas / overlays / background
|
||||
const auto opaques = items[RenderFetchCullSortTask::OPAQUE_SHAPE];
|
||||
const auto transparents = items[RenderFetchCullSortTask::TRANSPARENT_SHAPE];
|
||||
const auto lights = items[RenderFetchCullSortTask::LIGHT];
|
||||
const auto metas = items[RenderFetchCullSortTask::META];
|
||||
const auto overlayOpaques = items[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE];
|
||||
const auto overlayTransparents = items[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE];
|
||||
const auto background = items[RenderFetchCullSortTask::BACKGROUND];
|
||||
const auto spatialSelection = items[RenderFetchCullSortTask::SPATIAL_SELECTION];
|
||||
const auto& opaques = items.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE];
|
||||
const auto& transparents = items.get0()[RenderFetchCullSortTask::TRANSPARENT_SHAPE];
|
||||
const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT];
|
||||
const auto& metas = items.get0()[RenderFetchCullSortTask::META];
|
||||
const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE];
|
||||
const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE];
|
||||
//const auto& background = items.get0()[RenderFetchCullSortTask::BACKGROUND];
|
||||
const auto& spatialSelection = items[1];
|
||||
|
||||
// Filter the non antialiaased overlays
|
||||
const int LAYER_NO_AA = 3;
|
||||
|
@ -77,7 +89,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
|
||||
const auto opaqueRangeTimer = task.addJob<BeginGPURangeTimer>("BeginOpaqueRangeTimer", "DrawOpaques");
|
||||
|
||||
const auto prepareDeferredInputs = PrepareDeferred::Inputs(primaryFramebuffer, lightingModel).hasVarying();
|
||||
const auto prepareDeferredInputs = PrepareDeferred::Inputs(primaryFramebuffer, lightingModel).asVarying();
|
||||
const auto prepareDeferredOutputs = task.addJob<PrepareDeferred>("PrepareDeferred", prepareDeferredInputs);
|
||||
const auto deferredFramebuffer = prepareDeferredOutputs.getN<PrepareDeferred::Outputs>(0);
|
||||
const auto lightingFramebuffer = prepareDeferredOutputs.getN<PrepareDeferred::Outputs>(1);
|
||||
|
@ -86,21 +98,26 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<PrepareStencil>("PrepareStencil", primaryFramebuffer);
|
||||
|
||||
// Render opaque objects in DeferredBuffer
|
||||
const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel).hasVarying();
|
||||
const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel).asVarying();
|
||||
task.addJob<DrawStateSortDeferred>("DrawOpaqueDeferred", opaqueInputs, shapePlumber);
|
||||
|
||||
const auto fadeOpaques = fadeItems[FadeSwitchJob::OPAQUE_SHAPE];
|
||||
const auto fadeOpaqueInputs = FadeRenderJob::Input(fadeOpaques, lightingModel, fadeConfigureOutputs).asVarying();
|
||||
task.addJob<FadeRenderJob>("DrawFadeOpaque", fadeOpaqueInputs, commonFadeParameters, shapePlumber);
|
||||
|
||||
|
||||
task.addJob<EndGPURangeTimer>("OpaqueRangeTimer", opaqueRangeTimer);
|
||||
|
||||
|
||||
// Opaque all rendered
|
||||
|
||||
// Linear Depth Pass
|
||||
const auto linearDepthPassInputs = LinearDepthPass::Inputs(deferredFrameTransform, deferredFramebuffer).hasVarying();
|
||||
const auto linearDepthPassInputs = LinearDepthPass::Inputs(deferredFrameTransform, deferredFramebuffer).asVarying();
|
||||
const auto linearDepthPassOutputs = task.addJob<LinearDepthPass>("LinearDepth", linearDepthPassInputs);
|
||||
const auto linearDepthTarget = linearDepthPassOutputs.getN<LinearDepthPass::Outputs>(0);
|
||||
|
||||
// Curvature pass
|
||||
const auto surfaceGeometryPassInputs = SurfaceGeometryPass::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget).hasVarying();
|
||||
const auto surfaceGeometryPassInputs = SurfaceGeometryPass::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget).asVarying();
|
||||
const auto surfaceGeometryPassOutputs = task.addJob<SurfaceGeometryPass>("SurfaceGeometry", surfaceGeometryPassInputs);
|
||||
const auto surfaceGeometryFramebuffer = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(0);
|
||||
const auto curvatureFramebuffer = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(1);
|
||||
|
@ -111,7 +128,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
const auto scatteringResource = task.addJob<SubsurfaceScattering>("Scattering");
|
||||
|
||||
// AO job
|
||||
const auto ambientOcclusionInputs = AmbientOcclusionEffect::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget).hasVarying();
|
||||
const auto ambientOcclusionInputs = AmbientOcclusionEffect::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget).asVarying();
|
||||
const auto ambientOcclusionOutputs = task.addJob<AmbientOcclusionEffect>("AmbientOcclusion", ambientOcclusionInputs);
|
||||
const auto ambientOcclusionFramebuffer = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Outputs>(0);
|
||||
const auto ambientOcclusionUniforms = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Outputs>(1);
|
||||
|
@ -125,13 +142,13 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
|
||||
// Light Clustering
|
||||
// Create the cluster grid of lights, cpu job for now
|
||||
const auto lightClusteringPassInputs = LightClusteringPass::Inputs(deferredFrameTransform, lightingModel, linearDepthTarget).hasVarying();
|
||||
const auto lightClusteringPassInputs = LightClusteringPass::Inputs(deferredFrameTransform, lightingModel, linearDepthTarget).asVarying();
|
||||
const auto lightClusters = task.addJob<LightClusteringPass>("LightClustering", lightClusteringPassInputs);
|
||||
|
||||
|
||||
// DeferredBuffer is complete, now let's shade it into the LightingBuffer
|
||||
const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel,
|
||||
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters).hasVarying();
|
||||
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters).asVarying();
|
||||
|
||||
task.addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs);
|
||||
|
||||
|
@ -139,12 +156,16 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<DrawBackgroundStage>("DrawBackgroundDeferred", lightingModel);
|
||||
|
||||
// Render transparent objects forward in LightingBuffer
|
||||
const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel).hasVarying();
|
||||
const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel).asVarying();
|
||||
task.addJob<DrawDeferred>("DrawTransparentDeferred", transparentsInputs, shapePlumber);
|
||||
|
||||
const auto fadeTransparents = fadeItems[FadeSwitchJob::TRANSPARENT_SHAPE];
|
||||
const auto fadeTransparentInputs = FadeRenderJob::Input(fadeTransparents, lightingModel, fadeConfigureOutputs).asVarying();
|
||||
task.addJob<FadeRenderJob>("DrawFadeTransparent", fadeTransparentInputs, commonFadeParameters, shapePlumber);
|
||||
|
||||
// LIght Cluster Grid Debuging job
|
||||
{
|
||||
const auto debugLightClustersInputs = DebugLightClusters::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, linearDepthTarget, lightClusters).hasVarying();
|
||||
const auto debugLightClustersInputs = DebugLightClusters::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, linearDepthTarget, lightClusters).asVarying();
|
||||
task.addJob<DebugLightClusters>("DebugLightClusters", debugLightClustersInputs);
|
||||
}
|
||||
|
||||
|
@ -155,6 +176,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<ToneMappingDeferred>("ToneMapping", toneMappingInputs);
|
||||
|
||||
{ // DEbug the bounds of the rendered items, still look at the zbuffer
|
||||
task.addJob<DrawBounds>("DrawFadedOpaqueBounds", fadeOpaques);
|
||||
task.addJob<DrawBounds>("DrawMetaBounds", metas);
|
||||
task.addJob<DrawBounds>("DrawOpaqueBounds", opaques);
|
||||
task.addJob<DrawBounds>("DrawTransparentBounds", transparents);
|
||||
|
@ -164,8 +186,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
}
|
||||
|
||||
// Overlays
|
||||
const auto overlayOpaquesInputs = DrawOverlay3D::Inputs(overlayOpaques, lightingModel).hasVarying();
|
||||
const auto overlayTransparentsInputs = DrawOverlay3D::Inputs(overlayTransparents, lightingModel).hasVarying();
|
||||
const auto overlayOpaquesInputs = DrawOverlay3D::Inputs(overlayOpaques, lightingModel).asVarying();
|
||||
const auto overlayTransparentsInputs = DrawOverlay3D::Inputs(overlayTransparents, lightingModel).asVarying();
|
||||
task.addJob<DrawOverlay3D>("DrawOverlay3DOpaque", overlayOpaquesInputs, true);
|
||||
task.addJob<DrawOverlay3D>("DrawOverlay3DTransparent", overlayTransparentsInputs, false);
|
||||
|
||||
|
@ -181,10 +203,10 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<DebugDeferredBuffer>("DebugDeferredBuffer", debugFramebuffers);
|
||||
|
||||
const auto debugSubsurfaceScatteringInputs = DebugSubsurfaceScattering::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel,
|
||||
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource).hasVarying();
|
||||
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource).asVarying();
|
||||
task.addJob<DebugSubsurfaceScattering>("DebugScattering", debugSubsurfaceScatteringInputs);
|
||||
|
||||
const auto debugAmbientOcclusionInputs = DebugAmbientOcclusion::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget, ambientOcclusionUniforms).hasVarying();
|
||||
const auto debugAmbientOcclusionInputs = DebugAmbientOcclusion::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget, ambientOcclusionUniforms).asVarying();
|
||||
task.addJob<DebugAmbientOcclusion>("DebugAmbientOcclusion", debugAmbientOcclusionInputs);
|
||||
|
||||
// Scene Octree Debugging job
|
||||
|
@ -209,7 +231,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<Antialiasing>("Antialiasing", primaryFramebuffer);
|
||||
|
||||
// Draw 2DWeb non AA
|
||||
const auto nonAAOverlaysInputs = DrawOverlay3D::Inputs(nonAAOverlays, lightingModel).hasVarying();
|
||||
const auto nonAAOverlaysInputs = DrawOverlay3D::Inputs(nonAAOverlays, lightingModel).asVarying();
|
||||
task.addJob<DrawOverlay3D>("Draw2DWebSurfaces", nonAAOverlaysInputs, false);
|
||||
|
||||
task.addJob<EndGPURangeTimer>("ToneAndPostRangeTimer", toneAndPostRangeTimer);
|
||||
|
@ -269,6 +291,7 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs&
|
|||
if (lightingModel->isWireframeEnabled()) {
|
||||
keyBuilder.withWireframe();
|
||||
}
|
||||
|
||||
ShapeKey globalKey = keyBuilder.build();
|
||||
args->_globalShapeKey = globalKey._flags.to_ulong();
|
||||
|
||||
|
@ -310,11 +333,12 @@ void DrawStateSortDeferred::run(const RenderContextPointer& renderContext, const
|
|||
// Setup lighting model for all items;
|
||||
batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
|
||||
|
||||
// From the lighting model define a global shapKey ORED with individiual keys
|
||||
// From the lighting model define a global shapeKey ORED with individiual keys
|
||||
ShapeKey::Builder keyBuilder;
|
||||
if (lightingModel->isWireframeEnabled()) {
|
||||
keyBuilder.withWireframe();
|
||||
}
|
||||
|
||||
ShapeKey globalKey = keyBuilder.build();
|
||||
args->_globalShapeKey = globalKey._flags.to_ulong();
|
||||
|
||||
|
|
|
@ -44,12 +44,11 @@ public:
|
|||
protected:
|
||||
};
|
||||
|
||||
|
||||
class DrawConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY newStats)
|
||||
|
||||
Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
|
||||
|
||||
public:
|
||||
|
||||
int getNumDrawn() { return _numDrawn; }
|
||||
|
@ -163,14 +162,34 @@ public:
|
|||
void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer);
|
||||
};
|
||||
|
||||
class RenderDeferredTaskConfig : public render::Task::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float fadeScale MEMBER fadeScale NOTIFY dirty)
|
||||
Q_PROPERTY(float fadeDuration MEMBER fadeDuration NOTIFY dirty)
|
||||
Q_PROPERTY(bool debugFade MEMBER debugFade NOTIFY dirty)
|
||||
Q_PROPERTY(float debugFadePercent MEMBER debugFadePercent NOTIFY dirty)
|
||||
public:
|
||||
float fadeScale{ 0.5f };
|
||||
float fadeDuration{ 3.0f };
|
||||
float debugFadePercent{ 0.f };
|
||||
bool debugFade{ false };
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
|
||||
};
|
||||
|
||||
class RenderDeferredTask {
|
||||
public:
|
||||
using Input = RenderFetchCullSortTask::Output;
|
||||
using JobModel = render::Task::ModelI<RenderDeferredTask, Input>;
|
||||
using Config = RenderDeferredTaskConfig;
|
||||
using JobModel = render::Task::ModelI<RenderDeferredTask, Input, Config>;
|
||||
|
||||
RenderDeferredTask() {}
|
||||
|
||||
void configure(const Config& config);
|
||||
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs);
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_RenderDeferredTask_h
|
||||
|
|
|
@ -36,14 +36,14 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
|
|||
initForwardPipelines(*shapePlumber);
|
||||
|
||||
// Extract opaques / transparents / lights / metas / overlays / background
|
||||
const auto opaques = items[RenderFetchCullSortTask::OPAQUE_SHAPE];
|
||||
const auto transparents = items[RenderFetchCullSortTask::TRANSPARENT_SHAPE];
|
||||
const auto lights = items[RenderFetchCullSortTask::LIGHT];
|
||||
const auto metas = items[RenderFetchCullSortTask::META];
|
||||
const auto overlayOpaques = items[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE];
|
||||
const auto overlayTransparents = items[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE];
|
||||
const auto background = items[RenderFetchCullSortTask::BACKGROUND];
|
||||
const auto spatialSelection = items[RenderFetchCullSortTask::SPATIAL_SELECTION];
|
||||
const auto& opaques = items.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE];
|
||||
// const auto& transparents = items.get0()[RenderFetchCullSortTask::TRANSPARENT_SHAPE];
|
||||
// const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT];
|
||||
// const auto& metas = items.get0()[RenderFetchCullSortTask::META];
|
||||
// const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE];
|
||||
// const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE];
|
||||
const auto& background = items.get0()[RenderFetchCullSortTask::BACKGROUND];
|
||||
// const auto& spatialSelection = items[1];
|
||||
|
||||
const auto framebuffer = task.addJob<PrepareFramebuffer>("PrepareFramebuffer");
|
||||
|
||||
|
|
|
@ -29,12 +29,25 @@
|
|||
#include "skin_model_shadow_vert.h"
|
||||
#include "skin_model_normal_map_vert.h"
|
||||
|
||||
#include "model_shadow_fade_vert.h"
|
||||
#include "model_lightmap_fade_vert.h"
|
||||
#include "model_lightmap_normal_map_fade_vert.h"
|
||||
#include "skin_model_fade_vert.h"
|
||||
#include "skin_model_shadow_fade_vert.h"
|
||||
#include "skin_model_normal_map_fade_vert.h"
|
||||
|
||||
#include "simple_vert.h"
|
||||
#include "simple_textured_frag.h"
|
||||
#include "simple_textured_unlit_frag.h"
|
||||
#include "simple_transparent_textured_frag.h"
|
||||
#include "simple_transparent_textured_unlit_frag.h"
|
||||
|
||||
#include "simple_fade_vert.h"
|
||||
#include "simple_textured_fade_frag.h"
|
||||
#include "simple_textured_unlit_fade_frag.h"
|
||||
#include "simple_transparent_textured_fade_frag.h"
|
||||
#include "simple_transparent_textured_unlit_fade_frag.h"
|
||||
|
||||
#include "model_frag.h"
|
||||
#include "model_unlit_frag.h"
|
||||
#include "model_shadow_frag.h"
|
||||
|
@ -42,6 +55,16 @@
|
|||
#include "model_normal_specular_map_frag.h"
|
||||
#include "model_specular_map_frag.h"
|
||||
|
||||
#include "model_fade_vert.h"
|
||||
#include "model_normal_map_fade_vert.h"
|
||||
|
||||
#include "model_fade_frag.h"
|
||||
#include "model_shadow_fade_frag.h"
|
||||
#include "model_unlit_fade_frag.h"
|
||||
#include "model_normal_map_fade_frag.h"
|
||||
#include "model_normal_specular_map_fade_frag.h"
|
||||
#include "model_specular_map_fade_frag.h"
|
||||
|
||||
#include "forward_model_frag.h"
|
||||
#include "forward_model_unlit_frag.h"
|
||||
#include "forward_model_normal_map_frag.h"
|
||||
|
@ -55,6 +78,13 @@
|
|||
#include "model_translucent_frag.h"
|
||||
#include "model_translucent_unlit_frag.h"
|
||||
|
||||
#include "model_lightmap_fade_frag.h"
|
||||
#include "model_lightmap_normal_map_fade_frag.h"
|
||||
#include "model_lightmap_normal_specular_map_fade_frag.h"
|
||||
#include "model_lightmap_specular_map_fade_frag.h"
|
||||
#include "model_translucent_fade_frag.h"
|
||||
#include "model_translucent_unlit_fade_frag.h"
|
||||
|
||||
#include "overlay3D_vert.h"
|
||||
#include "overlay3D_frag.h"
|
||||
#include "overlay3D_model_frag.h"
|
||||
|
@ -151,6 +181,16 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
|||
auto skinModelVertex = gpu::Shader::createVertex(std::string(skin_model_vert));
|
||||
auto skinModelNormalMapVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_vert));
|
||||
auto skinModelShadowVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_vert));
|
||||
auto modelLightmapFadeVertex = gpu::Shader::createVertex(std::string(model_lightmap_fade_vert));
|
||||
auto modelLightmapNormalMapFadeVertex = gpu::Shader::createVertex(std::string(model_lightmap_normal_map_fade_vert));
|
||||
auto skinModelFadeVertex = gpu::Shader::createVertex(std::string(skin_model_fade_vert));
|
||||
auto skinModelNormalMapFadeVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_fade_vert));
|
||||
|
||||
auto modelFadeVertex = gpu::Shader::createVertex(std::string(model_fade_vert));
|
||||
auto modelNormalMapFadeVertex = gpu::Shader::createVertex(std::string(model_normal_map_fade_vert));
|
||||
auto simpleFadeVertex = gpu::Shader::createVertex(std::string(simple_fade_vert));
|
||||
auto modelShadowFadeVertex = gpu::Shader::createVertex(std::string(model_shadow_fade_vert));
|
||||
auto skinModelShadowFadeVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_fade_vert));
|
||||
|
||||
// Pixel shaders
|
||||
auto simplePixel = gpu::Shader::createPixel(std::string(simple_textured_frag));
|
||||
|
@ -169,6 +209,23 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
|||
auto modelLightmapNormalMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_map_frag));
|
||||
auto modelLightmapSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_specular_map_frag));
|
||||
auto modelLightmapNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag));
|
||||
auto modelLightmapFadePixel = gpu::Shader::createPixel(std::string(model_lightmap_fade_frag));
|
||||
auto modelLightmapNormalMapFadePixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_map_fade_frag));
|
||||
auto modelLightmapSpecularMapFadePixel = gpu::Shader::createPixel(std::string(model_lightmap_specular_map_fade_frag));
|
||||
auto modelLightmapNormalSpecularMapFadePixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_fade_frag));
|
||||
|
||||
auto modelFadePixel = gpu::Shader::createPixel(std::string(model_fade_frag));
|
||||
auto modelUnlitFadePixel = gpu::Shader::createPixel(std::string(model_unlit_fade_frag));
|
||||
auto modelNormalMapFadePixel = gpu::Shader::createPixel(std::string(model_normal_map_fade_frag));
|
||||
auto modelSpecularMapFadePixel = gpu::Shader::createPixel(std::string(model_specular_map_fade_frag));
|
||||
auto modelNormalSpecularMapFadePixel = gpu::Shader::createPixel(std::string(model_normal_specular_map_fade_frag));
|
||||
auto modelShadowFadePixel = gpu::Shader::createPixel(std::string(model_shadow_fade_frag));
|
||||
auto modelTranslucentFadePixel = gpu::Shader::createPixel(std::string(model_translucent_fade_frag));
|
||||
auto modelTranslucentUnlitFadePixel = gpu::Shader::createPixel(std::string(model_translucent_unlit_fade_frag));
|
||||
auto simpleFadePixel = gpu::Shader::createPixel(std::string(simple_textured_fade_frag));
|
||||
auto simpleUnlitFadePixel = gpu::Shader::createPixel(std::string(simple_textured_unlit_fade_frag));
|
||||
auto simpleTranslucentFadePixel = gpu::Shader::createPixel(std::string(simple_transparent_textured_fade_frag));
|
||||
auto simpleTranslucentUnlitFadePixel = gpu::Shader::createPixel(std::string(simple_transparent_textured_unlit_fade_frag));
|
||||
|
||||
using Key = render::ShapeKey;
|
||||
auto addPipeline = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3);
|
||||
|
@ -195,6 +252,29 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
|||
addPipeline(
|
||||
Key::Builder().withMaterial().withTangents().withSpecular(),
|
||||
modelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withFade(),
|
||||
modelFadeVertex, modelFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withFade(),
|
||||
simpleFadeVertex, simpleFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withUnlit().withFade(),
|
||||
modelFadeVertex, modelUnlitFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withUnlit().withFade(),
|
||||
simpleFadeVertex, simpleUnlitFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTangents().withFade(),
|
||||
modelNormalMapFadeVertex, modelNormalMapFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSpecular().withFade(),
|
||||
modelFadeVertex, modelSpecularMapFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTangents().withSpecular().withFade(),
|
||||
modelNormalMapFadeVertex, modelNormalSpecularMapFadePixel);
|
||||
|
||||
// Translucents
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent(),
|
||||
|
@ -221,6 +301,33 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
|||
// FIXME: Ignore lightmap for translucents meshpart
|
||||
Key::Builder().withMaterial().withTranslucent().withLightmap(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withFade(),
|
||||
modelFadeVertex, modelTranslucentFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withTranslucent().withFade(),
|
||||
simpleFadeVertex, simpleTranslucentFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withUnlit().withFade(),
|
||||
modelFadeVertex, modelTranslucentUnlitFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withTranslucent().withUnlit().withFade(),
|
||||
simpleFadeVertex, simpleTranslucentUnlitFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withTangents().withFade(),
|
||||
modelNormalMapFadeVertex, modelTranslucentFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withSpecular().withFade(),
|
||||
modelFadeVertex, modelTranslucentFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withTangents().withSpecular().withFade(),
|
||||
modelNormalMapFadeVertex, modelTranslucentFadePixel);
|
||||
addPipeline(
|
||||
// FIXME: Ignore lightmap for translucents meshpart
|
||||
Key::Builder().withMaterial().withTranslucent().withLightmap().withFade(),
|
||||
modelFadeVertex, modelTranslucentFadePixel);
|
||||
|
||||
// Lightmapped
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withLightmap(),
|
||||
|
@ -234,6 +341,20 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
|||
addPipeline(
|
||||
Key::Builder().withMaterial().withLightmap().withTangents().withSpecular(),
|
||||
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withLightmap().withFade(),
|
||||
modelLightmapFadeVertex, modelLightmapFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withLightmap().withTangents().withFade(),
|
||||
modelLightmapNormalMapFadeVertex, modelLightmapNormalMapFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withLightmap().withSpecular().withFade(),
|
||||
modelLightmapFadeVertex, modelLightmapSpecularMapFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withLightmap().withTangents().withSpecular().withFade(),
|
||||
modelLightmapNormalMapFadeVertex, modelLightmapNormalSpecularMapFadePixel);
|
||||
|
||||
// Skinned
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned(),
|
||||
|
@ -247,6 +368,20 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
|||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTangents().withSpecular(),
|
||||
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withFade(),
|
||||
skinModelFadeVertex, modelFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTangents().withFade(),
|
||||
skinModelNormalMapFadeVertex, modelNormalMapFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withSpecular().withFade(),
|
||||
skinModelFadeVertex, modelSpecularMapFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTangents().withSpecular().withFade(),
|
||||
skinModelNormalMapFadeVertex, modelNormalSpecularMapFadePixel);
|
||||
|
||||
// Skinned and Translucent
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent(),
|
||||
|
@ -260,6 +395,20 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
|||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents().withSpecular(),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withFade(),
|
||||
skinModelFadeVertex, modelTranslucentFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents().withFade(),
|
||||
skinModelNormalMapFadeVertex, modelTranslucentFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withSpecular().withFade(),
|
||||
skinModelFadeVertex, modelTranslucentFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents().withSpecular().withFade(),
|
||||
skinModelNormalMapFadeVertex, modelTranslucentFadePixel);
|
||||
|
||||
// Depth-only
|
||||
addPipeline(
|
||||
Key::Builder().withDepthOnly(),
|
||||
|
@ -267,6 +416,13 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
|||
addPipeline(
|
||||
Key::Builder().withSkinned().withDepthOnly(),
|
||||
skinModelShadowVertex, modelShadowPixel);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withDepthOnly().withFade(),
|
||||
modelShadowFadeVertex, modelShadowFadePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withDepthOnly().withFade(),
|
||||
skinModelShadowFadeVertex, modelShadowFadePixel);
|
||||
}
|
||||
|
||||
void initForwardPipelines(render::ShapePlumber& plumber) {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <gpu/Context.h>
|
||||
|
||||
#include <ViewFrustum.h>
|
||||
#include "FadeEffect.h"
|
||||
|
||||
#include <render/CullTask.h>
|
||||
#include <render/SortTask.h>
|
||||
|
@ -28,6 +29,12 @@
|
|||
#include "model_shadow_frag.h"
|
||||
#include "skin_model_shadow_frag.h"
|
||||
|
||||
#include "model_shadow_fade_vert.h"
|
||||
#include "skin_model_shadow_fade_vert.h"
|
||||
|
||||
#include "model_shadow_fade_frag.h"
|
||||
#include "skin_model_shadow_fade_frag.h"
|
||||
|
||||
using namespace render;
|
||||
|
||||
void RenderShadowMap::run(const render::RenderContextPointer& renderContext,
|
||||
|
@ -46,6 +53,8 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext,
|
|||
const auto& fbo = shadow->framebuffer;
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
ShapeKey::Builder defaultKeyBuilder;// TODO: support fade on shadows = DependencyManager::get<FadeEffect>()->getKeyBuilder();
|
||||
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
args->_batch = &batch;
|
||||
batch.enableStereo(false);
|
||||
|
@ -62,8 +71,11 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext,
|
|||
batch.setProjectionTransform(shadow->getProjection());
|
||||
batch.setViewTransform(shadow->getView(), false);
|
||||
|
||||
auto shadowPipeline = _shapePlumber->pickPipeline(args, ShapeKey());
|
||||
auto shadowSkinnedPipeline = _shapePlumber->pickPipeline(args, ShapeKey::Builder().withSkinned());
|
||||
auto shadowPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder);
|
||||
auto shadowSkinnedPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withSkinned());
|
||||
|
||||
// Prepare fade effect
|
||||
// TODO: support fade on shadows DependencyManager::get<FadeEffect>()->bindPerBatch(batch);
|
||||
|
||||
std::vector<ShapeKey> skinnedShapeKeys{};
|
||||
|
||||
|
@ -104,15 +116,29 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
|||
auto modelPixel = gpu::Shader::createPixel(std::string(model_shadow_frag));
|
||||
gpu::ShaderPointer modelProgram = gpu::Shader::createProgram(modelVertex, modelPixel);
|
||||
shapePlumber->addPipeline(
|
||||
ShapeKey::Filter::Builder().withoutSkinned(),
|
||||
ShapeKey::Filter::Builder().withoutSkinned().withoutFade(),
|
||||
modelProgram, state);
|
||||
|
||||
auto skinVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_vert));
|
||||
auto skinPixel = gpu::Shader::createPixel(std::string(skin_model_shadow_frag));
|
||||
gpu::ShaderPointer skinProgram = gpu::Shader::createProgram(skinVertex, skinPixel);
|
||||
shapePlumber->addPipeline(
|
||||
ShapeKey::Filter::Builder().withSkinned(),
|
||||
ShapeKey::Filter::Builder().withSkinned().withoutFade(),
|
||||
skinProgram, state);
|
||||
|
||||
auto modelFadeVertex = gpu::Shader::createVertex(std::string(model_shadow_fade_vert));
|
||||
auto modelFadePixel = gpu::Shader::createPixel(std::string(model_shadow_fade_frag));
|
||||
gpu::ShaderPointer modelFadeProgram = gpu::Shader::createProgram(modelFadeVertex, modelFadePixel);
|
||||
shapePlumber->addPipeline(
|
||||
ShapeKey::Filter::Builder().withoutSkinned().withFade(),
|
||||
modelFadeProgram, state);
|
||||
|
||||
auto skinFadeVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_fade_vert));
|
||||
auto skinFadePixel = gpu::Shader::createPixel(std::string(skin_model_shadow_fade_frag));
|
||||
gpu::ShaderPointer skinFadeProgram = gpu::Shader::createProgram(skinFadeVertex, skinFadePixel);
|
||||
shapePlumber->addPipeline(
|
||||
ShapeKey::Filter::Builder().withSkinned().withFade(),
|
||||
skinFadeProgram, state);
|
||||
}
|
||||
|
||||
const auto cachedMode = task.addJob<RenderShadowSetup>("ShadowSetup");
|
||||
|
|
68
libraries/render-utils/src/model_fade.slf
Normal file
68
libraries/render-utils/src/model_fade.slf
Normal file
|
@ -0,0 +1,68 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 04/19/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec4 _worldFadePosition;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
|
||||
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||
<$discardTransparent(opacity)$>;
|
||||
|
||||
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)$>;
|
||||
emissive += fadeEmissive;
|
||||
|
||||
float scattering = getMaterialScattering(mat);
|
||||
|
||||
packDeferredFragment(
|
||||
normalize(_normal.xyz),
|
||||
opacity,
|
||||
albedo,
|
||||
roughness,
|
||||
getMaterialMetallic(mat),
|
||||
emissive,
|
||||
occlusionTex,
|
||||
scattering);
|
||||
}
|
46
libraries/render-utils/src/model_fade.slv
Normal file
46
libraries/render-utils/src/model_fade.slv
Normal file
|
@ -0,0 +1,46 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model_fade.slv
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 04/24/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
|
||||
out vec3 _color;
|
||||
out float _alpha;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec4 _position;
|
||||
out vec4 _worldFadePosition;
|
||||
out vec3 _normal;
|
||||
|
||||
void main(void) {
|
||||
_color = colorToLinearRGB(inColor.xyz);
|
||||
_alpha = inColor.w;
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord1)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToFadePos(obj, inPosition, _worldFadePosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
}
|
52
libraries/render-utils/src/model_lightmap_fade.slf
Normal file
52
libraries/render-utils/src/model_lightmap_fade.slf
Normal file
|
@ -0,0 +1,52 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS)$>
|
||||
<$declareMaterialLightmap()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedo, roughness)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmapVal)$>
|
||||
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(_normal),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a),
|
||||
getMaterialAlbedo(mat) * albedo.rgb * _color,
|
||||
getMaterialRoughness(mat) * roughness,
|
||||
getMaterialMetallic(mat),
|
||||
getMaterialFresnel(mat),
|
||||
lightmapVal+fadeEmissive);
|
||||
}
|
48
libraries/render-utils/src/model_lightmap_fade.slv
Normal file
48
libraries/render-utils/src/model_lightmap_fade.slv
Normal file
|
@ -0,0 +1,48 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
out vec4 _position;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec3 _normal;
|
||||
out vec3 _color;
|
||||
out vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
// pass along the color in linear space
|
||||
_color = colorToLinearRGB(inColor.xyz);
|
||||
|
||||
// and the texture coordinates
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord1)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToFadePos(obj, inPosition, _worldFadePosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_normal_map_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL)$>
|
||||
<$declareMaterialLightmap()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _tangent;
|
||||
in vec3 _color;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedo, roughness, normalTexel)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmapVal)$>
|
||||
|
||||
vec3 viewNormal;
|
||||
<$tangentToViewSpaceLOD(_position, normalTexel, _normal, _tangent, viewNormal)$>
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(viewNormal.xyz),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a),
|
||||
getMaterialAlbedo(mat) * albedo.rgb * _color,
|
||||
getMaterialRoughness(mat),
|
||||
getMaterialMetallic(mat),
|
||||
getMaterialFresnel(mat),
|
||||
lightmapVal+fadeEmissive);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_normal_map_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
out vec4 _position;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec3 _normal;
|
||||
out vec3 _tangent;
|
||||
out vec3 _color;
|
||||
out vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
// pass along the color in linear space
|
||||
_color = colorToLinearRGB(inColor.xyz);
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord1)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToFadePos(obj, inPosition, _worldFadePosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangent)$>
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_normal_specular_map_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC)$>
|
||||
<$declareMaterialLightmap()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _tangent;
|
||||
in vec3 _color;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedo, roughness, normalTexel, metallicTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmapVal)$>
|
||||
|
||||
vec3 viewNormal;
|
||||
<$tangentToViewSpaceLOD(_position, normalTexel, _normal, _tangent, viewNormal)$>
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(viewNormal.xyz),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a),
|
||||
getMaterialAlbedo(mat) * albedo.rgb * _color,
|
||||
getMaterialRoughness(mat) * roughness,
|
||||
getMaterialMetallic(mat) * metallicTex,
|
||||
/*specular, // no use of */ getMaterialFresnel(mat),
|
||||
lightmapVal+fadeEmissive);
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_specular_map_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC)$>
|
||||
<$declareMaterialLightmap()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedo, roughness, _SCRIBE_NULL, metallicTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmapVal)$>
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(_normal),
|
||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a),
|
||||
getMaterialAlbedo(mat) * albedo.rgb * _color,
|
||||
getMaterialRoughness(mat) * roughness,
|
||||
getMaterialMetallic(mat) * metallicTex,
|
||||
/*metallicTex, // no use of */getMaterialFresnel(mat),
|
||||
lightmapVal+fadeEmissive);
|
||||
}
|
72
libraries/render-utils/src/model_normal_map_fade.slf
Normal file
72
libraries/render-utils/src/model_normal_map_fade.slf
Normal file
|
@ -0,0 +1,72 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_normal_map_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 04/19/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, _SCRIBE_NULL, EMISSIVE, OCCLUSION, SCATTERING)$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec4 _worldFadePosition;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _tangent;
|
||||
in vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, _SCRIBE_NULL, emissiveTex, scatteringTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
|
||||
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||
<$discardTransparent(opacity)$>;
|
||||
|
||||
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;
|
||||
<$tangentToViewSpaceLOD(_position, normalTex, _normal, _tangent, viewNormal)$>
|
||||
|
||||
float scattering = getMaterialScattering(mat);
|
||||
<$evalMaterialScattering(scatteringTex, scattering, matKey, scattering)$>;
|
||||
|
||||
packDeferredFragment(
|
||||
viewNormal,
|
||||
opacity,
|
||||
albedo,
|
||||
roughness,
|
||||
getMaterialMetallic(mat),
|
||||
emissive+fadeEmissive,
|
||||
occlusionTex,
|
||||
scattering);
|
||||
}
|
50
libraries/render-utils/src/model_normal_map_fade.slv
Normal file
50
libraries/render-utils/src/model_normal_map_fade.slv
Normal file
|
@ -0,0 +1,50 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_normal_map_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 04/24/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
|
||||
out vec4 _position;
|
||||
out vec4 _worldFadePosition;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec3 _normal;
|
||||
out vec3 _tangent;
|
||||
out vec3 _color;
|
||||
out float _alpha;
|
||||
|
||||
void main(void) {
|
||||
// pass along the color
|
||||
_color = colorToLinearRGB(inColor.rgb);
|
||||
_alpha = inColor.a;
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord1)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToFadePos(obj, inPosition, _worldFadePosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangent)$>
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_normal_specular_map_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC, EMISSIVE, OCCLUSION)$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _tangent;
|
||||
in vec3 _color;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
|
||||
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)&>;
|
||||
<$discardTransparent(opacity)$>;
|
||||
|
||||
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;
|
||||
<$tangentToViewSpaceLOD(_position, normalTex, _normal, _tangent, viewNormal)$>
|
||||
|
||||
float metallic = getMaterialMetallic(mat);
|
||||
<$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>;
|
||||
|
||||
float scattering = getMaterialScattering(mat);
|
||||
|
||||
packDeferredFragment(
|
||||
normalize(viewNormal.xyz),
|
||||
opacity,
|
||||
albedo,
|
||||
roughness,
|
||||
metallic,
|
||||
emissive+fadeEmissive,
|
||||
occlusionTex,
|
||||
scattering);
|
||||
}
|
27
libraries/render-utils/src/model_shadow_fade.slf
Normal file
27
libraries/render-utils/src/model_shadow_fade.slf
Normal file
|
@ -0,0 +1,27 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_shadow_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
layout(location = 0) out vec4 _fragColor;
|
||||
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
applyFadeClip(_worldFadePosition.xyz);
|
||||
|
||||
// pass-through to set z-buffer
|
||||
_fragColor = vec4(1.0, 1.0, 1.0, 0.0);
|
||||
}
|
31
libraries/render-utils/src/model_shadow_fade.slv
Normal file
31
libraries/render-utils/src/model_shadow_fade.slv
Normal file
|
@ -0,0 +1,31 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_shadow_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/045/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
<@include Fade.slh@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
out vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
||||
<$transformModelToFadePos(obj, inPosition, _worldFadePosition)$>
|
||||
}
|
70
libraries/render-utils/src/model_specular_map_fade.slf
Normal file
70
libraries/render-utils/src/model_specular_map_fade.slf
Normal file
|
@ -0,0 +1,70 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_specular_map_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC, EMISSIVE, OCCLUSION)$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
|
||||
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||
<$discardTransparent(opacity)$>;
|
||||
|
||||
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)$>;
|
||||
|
||||
float scattering = getMaterialScattering(mat);
|
||||
|
||||
packDeferredFragment(
|
||||
normalize(_normal),
|
||||
opacity,
|
||||
albedo,
|
||||
roughness,
|
||||
metallic,
|
||||
emissive+fadeEmissive,
|
||||
occlusionTex,
|
||||
scattering);
|
||||
}
|
89
libraries/render-utils/src/model_translucent_fade.slf
Normal file
89
libraries/render-utils/src/model_translucent_fade.slf
Normal file
|
@ -0,0 +1,89 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_translucent_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include DeferredGlobalLight.slh@>
|
||||
|
||||
<$declareEvalGlobalLightingAlphaBlended()$>
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec4 _position;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
|
||||
|
||||
float opacity = getMaterialOpacity(mat) * _alpha;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||
|
||||
vec3 albedo = getMaterialAlbedo(mat);
|
||||
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
||||
albedo *= _color;
|
||||
|
||||
float roughness = getMaterialRoughness(mat);
|
||||
<$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>;
|
||||
|
||||
float metallic = getMaterialMetallic(mat);
|
||||
vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value
|
||||
if (metallic <= 0.5) {
|
||||
metallic = 0.0;
|
||||
} else {
|
||||
fresnel = albedo;
|
||||
metallic = 1.0;
|
||||
}
|
||||
|
||||
vec3 emissive = getMaterialEmissive(mat);
|
||||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragNormal = normalize(_normal);
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
||||
_fragColor = vec4(evalGlobalLightingAlphaBlended(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
occlusionTex,
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
albedo,
|
||||
fresnel,
|
||||
metallic,
|
||||
emissive+fadeEmissive,
|
||||
roughness, opacity),
|
||||
opacity);
|
||||
}
|
48
libraries/render-utils/src/model_translucent_unlit_fade.slf
Normal file
48
libraries/render-utils/src/model_translucent_unlit_fade.slf
Normal file
|
@ -0,0 +1,48 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_translucent_unlit_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$>
|
||||
<@include LightingModel.slh@>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$>
|
||||
|
||||
float opacity = getMaterialOpacity(mat) * _alpha;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||
|
||||
vec3 albedo = getMaterialAlbedo(mat);
|
||||
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
||||
albedo *= _color;
|
||||
albedo += fadeEmissive;
|
||||
_fragColor = vec4(albedo * isUnlitEnabled(), opacity);
|
||||
}
|
52
libraries/render-utils/src/model_unlit_fade.slf
Normal file
52
libraries/render-utils/src/model_unlit_fade.slf
Normal file
|
@ -0,0 +1,52 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_unlit_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
<@include LightingModel.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO)$>
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$>
|
||||
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||
<$discardTransparent(opacity)$>;
|
||||
|
||||
vec3 albedo = getMaterialAlbedo(mat);
|
||||
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
||||
albedo *= _color;
|
||||
albedo += fadeEmissive;
|
||||
packDeferredFragmentUnlit(
|
||||
normalize(_normal),
|
||||
opacity,
|
||||
albedo * isUnlitEnabled());
|
||||
}
|
99
libraries/render-utils/src/simple_fade.slf
Normal file
99
libraries/render-utils/src/simple_fade.slf
Normal file
|
@ -0,0 +1,99 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// simple_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
// the interpolated normal
|
||||
in vec3 _normal;
|
||||
in vec3 _modelNormal;
|
||||
in vec4 _color;
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _position;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
//PROCEDURAL_COMMON_BLOCK
|
||||
|
||||
#line 1001
|
||||
//PROCEDURAL_BLOCK
|
||||
|
||||
#line 2030
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
Material material = getMaterial();
|
||||
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
|
||||
specular = getProceduralColor().rgb;
|
||||
// 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
|
||||
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
const float ALPHA_THRESHOLD = 0.999;
|
||||
if (_color.a < ALPHA_THRESHOLD) {
|
||||
if (emissiveAmount > 0.0) {
|
||||
packDeferredFragmentTranslucent(
|
||||
normal,
|
||||
_color.a,
|
||||
specular+fadeEmissive,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_ROUGHNESS);
|
||||
} else {
|
||||
packDeferredFragmentTranslucent(
|
||||
normal,
|
||||
_color.a,
|
||||
diffuse+fadeEmissive,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_ROUGHNESS);
|
||||
}
|
||||
} else {
|
||||
if (emissiveAmount > 0.0) {
|
||||
packDeferredFragmentLightmap(
|
||||
normal,
|
||||
1.0,
|
||||
diffuse+fadeEmissive,
|
||||
max(0, 1.0 - shininess / 128.0),
|
||||
DEFAULT_METALLIC,
|
||||
specular,
|
||||
specular);
|
||||
} else {
|
||||
packDeferredFragment(
|
||||
normal,
|
||||
1.0,
|
||||
diffuse,
|
||||
max(0, 1.0 - shininess / 128.0),
|
||||
length(specular),
|
||||
DEFAULT_EMISSIVE+fadeEmissive,
|
||||
DEFAULT_OCCLUSION,
|
||||
DEFAULT_SCATTERING);
|
||||
}
|
||||
}
|
||||
}
|
42
libraries/render-utils/src/simple_fade.slv
Normal file
42
libraries/render-utils/src/simple_fade.slv
Normal file
|
@ -0,0 +1,42 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// simple_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/045/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
|
||||
// the interpolated normal
|
||||
out vec3 _normal;
|
||||
out vec3 _modelNormal;
|
||||
out vec4 _color;
|
||||
out vec2 _texCoord0;
|
||||
out vec4 _position;
|
||||
out vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
_color = colorToLinearRGBA(inColor);
|
||||
_texCoord0 = inTexCoord0.st;
|
||||
_position = inPosition;
|
||||
_modelNormal = inNormal.xyz;
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
||||
<$transformModelToFadePos(obj, inPosition, _worldFadePosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
}
|
62
libraries/render-utils/src/simple_textured_fade.slf
Normal file
62
libraries/render-utils/src/simple_textured_fade.slf
Normal file
|
@ -0,0 +1,62 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// simple_textured_fade.slf
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Color.slh@>
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
// the albedo texture
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
in vec3 _normal;
|
||||
in vec4 _color;
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
vec4 texel = texture(originalTexture, _texCoord0);
|
||||
float colorAlpha = _color.a;
|
||||
if (_color.a <= 0.0) {
|
||||
texel = colorToLinearRGBA(texel);
|
||||
colorAlpha = -_color.a;
|
||||
}
|
||||
|
||||
const float ALPHA_THRESHOLD = 0.999;
|
||||
if (colorAlpha * texel.a < ALPHA_THRESHOLD) {
|
||||
packDeferredFragmentTranslucent(
|
||||
normalize(_normal),
|
||||
colorAlpha * texel.a,
|
||||
_color.rgb * texel.rgb + fadeEmissive,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_ROUGHNESS);
|
||||
} else {
|
||||
packDeferredFragment(
|
||||
normalize(_normal),
|
||||
1.0,
|
||||
_color.rgb * texel.rgb,
|
||||
DEFAULT_ROUGHNESS,
|
||||
DEFAULT_METALLIC,
|
||||
DEFAULT_EMISSIVE + fadeEmissive,
|
||||
DEFAULT_OCCLUSION,
|
||||
DEFAULT_SCATTERING);
|
||||
}
|
||||
}
|
56
libraries/render-utils/src/simple_textured_unlit_fade.slf
Normal file
56
libraries/render-utils/src/simple_textured_unlit_fade.slf
Normal file
|
@ -0,0 +1,56 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// simple_textured_unlit_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Color.slh@>
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
// the albedo texture
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
in vec3 _normal;
|
||||
in vec4 _color;
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
vec4 texel = texture(originalTexture, _texCoord0.st);
|
||||
float colorAlpha = _color.a;
|
||||
if (_color.a <= 0.0) {
|
||||
texel = colorToLinearRGBA(texel);
|
||||
colorAlpha = -_color.a;
|
||||
}
|
||||
|
||||
const float ALPHA_THRESHOLD = 0.999;
|
||||
if (colorAlpha * texel.a < ALPHA_THRESHOLD) {
|
||||
packDeferredFragmentTranslucent(
|
||||
normalize(_normal),
|
||||
colorAlpha * texel.a,
|
||||
_color.rgb * texel.rgb+fadeEmissive,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_ROUGHNESS);
|
||||
} else {
|
||||
packDeferredFragmentUnlit(
|
||||
normalize(_normal),
|
||||
1.0,
|
||||
_color.rgb * texel.rgb+fadeEmissive);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// simple_transparent_textured_fade.slf
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Color.slh@>
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
<@include DeferredGlobalLight.slh@>
|
||||
<$declareEvalGlobalLightingAlphaBlended()$>
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
// the albedo texture
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
in vec4 _position;
|
||||
in vec3 _normal;
|
||||
in vec4 _color;
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
vec4 texel = texture(originalTexture, _texCoord0.st);
|
||||
float opacity = _color.a;
|
||||
if (_color.a <= 0.0) {
|
||||
texel = colorToLinearRGBA(texel);
|
||||
opacity = -_color.a;
|
||||
}
|
||||
opacity *= texel.a;
|
||||
vec3 albedo = _color.rgb * texel.rgb;
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragNormal = normalize(_normal);
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
||||
_fragColor0 = vec4(evalGlobalLightingAlphaBlended(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
1.0,
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
albedo,
|
||||
DEFAULT_FRESNEL,
|
||||
0.0f,
|
||||
fadeEmissive,
|
||||
DEFAULT_ROUGHNESS,
|
||||
opacity),
|
||||
opacity);
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// simple_transparent_textured_unlit_fade.slf
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Color.slh@>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
// the albedo texture
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
in vec3 _normal;
|
||||
in vec4 _color;
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
layout(location = 0) out vec4 _fragColor0;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
|
||||
applyFade(_worldFadePosition.xyz, fadeEmissive);
|
||||
|
||||
vec4 texel = texture(originalTexture, _texCoord0.st);
|
||||
float colorAlpha = _color.a;
|
||||
if (_color.a <= 0.0) {
|
||||
texel = colorToLinearRGBA(texel);
|
||||
colorAlpha = -_color.a;
|
||||
}
|
||||
_fragColor0 = vec4(_color.rgb * texel.rgb+fadeEmissive, colorAlpha * texel.a);
|
||||
}
|
55
libraries/render-utils/src/skin_model_fade.slv
Normal file
55
libraries/render-utils/src/skin_model_fade.slv
Normal file
|
@ -0,0 +1,55 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// skin_model_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/045/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include Skinning.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
|
||||
out vec4 _position;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec3 _normal;
|
||||
out vec3 _color;
|
||||
out float _alpha;
|
||||
out vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec4 position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec3 interpolatedNormal = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
skinPositionNormal(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, position, interpolatedNormal);
|
||||
|
||||
// pass along the color
|
||||
_color = colorToLinearRGB(inColor.rgb);
|
||||
_alpha = inColor.a;
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord1)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, position, _position, gl_Position)$>
|
||||
<$transformModelToFadePos(obj, position, _worldFadePosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, interpolatedNormal.xyz, _normal.xyz)$>
|
||||
}
|
64
libraries/render-utils/src/skin_model_normal_map_fade.slv
Normal file
64
libraries/render-utils/src/skin_model_normal_map_fade.slv
Normal file
|
@ -0,0 +1,64 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// skin_model_normal_map_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/045/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include Skinning.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
|
||||
out vec4 _position;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec3 _normal;
|
||||
out vec3 _tangent;
|
||||
out vec3 _color;
|
||||
out float _alpha;
|
||||
out vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec4 position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 interpolatedNormal = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 interpolatedTangent = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
skinPositionNormalTangent(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, inTangent.xyz, position, interpolatedNormal.xyz, interpolatedTangent.xyz);
|
||||
|
||||
// pass along the color
|
||||
_color = colorToLinearRGB(inColor.rgb);
|
||||
_alpha = inColor.a;
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord1)$>
|
||||
|
||||
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
||||
interpolatedTangent = vec4(normalize(interpolatedTangent.xyz), 0.0);
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, position, _position, gl_Position)$>
|
||||
<$transformModelToFadePos(obj, position, _worldFadePosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, interpolatedNormal.xyz, interpolatedNormal.xyz)$>
|
||||
<$transformModelToWorldDir(cam, obj, interpolatedTangent.xyz, interpolatedTangent.xyz)$>
|
||||
|
||||
_normal = interpolatedNormal.xyz;
|
||||
_tangent = interpolatedTangent.xyz;
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_shadow.frag
|
||||
// skin_model_shadow.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 3/24/14.
|
||||
|
|
27
libraries/render-utils/src/skin_model_shadow_fade.slf
Normal file
27
libraries/render-utils/src/skin_model_shadow_fade.slf
Normal file
|
@ -0,0 +1,27 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// skin_model_shadow_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/08/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec4 _worldFadePosition;
|
||||
|
||||
layout(location = 0) out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
applyFadeClip(_worldFadePosition.xyz);
|
||||
|
||||
// pass-through to set z-buffer
|
||||
_fragColor = vec4(1.0, 1.0, 1.0, 0.0);
|
||||
}
|
34
libraries/render-utils/src/skin_model_shadow_fade.slv
Normal file
34
libraries/render-utils/src/skin_model_shadow_fade.slv
Normal file
|
@ -0,0 +1,34 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// skin_model_shadow_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/045/17.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include Fade.slh@>
|
||||
|
||||
<@include Skinning.slh@>
|
||||
|
||||
out vec4 _worldFadePosition;
|
||||
|
||||
void main(void) {
|
||||
vec4 position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
skinPosition(inSkinClusterIndex, inSkinClusterWeight, inPosition, position);
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, position, gl_Position)$>
|
||||
<$transformModelToFadePos(obj, position, _worldFadePosition)$>
|
||||
}
|
|
@ -118,6 +118,8 @@ namespace render {
|
|||
uint32_t _globalShapeKey { 0 };
|
||||
bool _enableTexturing { true };
|
||||
|
||||
bool _enableFade{ false };
|
||||
|
||||
RenderDetails _details;
|
||||
render::ScenePointer _scene;
|
||||
int8_t _cameraMode { -1 };
|
||||
|
|
|
@ -28,7 +28,7 @@ void FilterLayeredItems::run(const RenderContextPointer& renderContext, const It
|
|||
outItems.clear();
|
||||
|
||||
// For each item, filter it into one bucket
|
||||
for (auto itemBound : inItems) {
|
||||
for (auto& itemBound : inItems) {
|
||||
auto& item = scene->getItem(itemBound.id);
|
||||
if (item.getLayer() == _keepLayer) {
|
||||
outItems.emplace_back(itemBound);
|
||||
|
|
|
@ -316,7 +316,7 @@ public:
|
|||
virtual const ItemKey getKey() const = 0;
|
||||
virtual const Bound getBound() const = 0;
|
||||
virtual int getLayer() const = 0;
|
||||
|
||||
virtual bool mustFade() const = 0;
|
||||
virtual void render(RenderArgs* args) = 0;
|
||||
|
||||
virtual const ShapeKey getShapeKey() const = 0;
|
||||
|
@ -364,6 +364,8 @@ public:
|
|||
// Get the layer where the item belongs. 0 by default meaning NOT LAYERED
|
||||
int getLayer() const { return _payload->getLayer(); }
|
||||
|
||||
bool mustFade() const { return _payload->mustFade(); }
|
||||
|
||||
// Render call for the item
|
||||
void render(RenderArgs* args) const { _payload->render(args); }
|
||||
|
||||
|
@ -409,6 +411,7 @@ template <class T> const ItemKey payloadGetKey(const std::shared_ptr<T>& payload
|
|||
template <class T> const Item::Bound payloadGetBound(const std::shared_ptr<T>& payloadData) { return Item::Bound(); }
|
||||
template <class T> int payloadGetLayer(const std::shared_ptr<T>& payloadData) { return 0; }
|
||||
template <class T> void payloadRender(const std::shared_ptr<T>& payloadData, RenderArgs* args) { }
|
||||
template <class T> bool payloadMustFade(const std::shared_ptr<T>& payloadData) { return false; }
|
||||
|
||||
// Shape type interface
|
||||
// This allows shapes to characterize their pipeline via a ShapeKey, to be picked with a subclass of Shape.
|
||||
|
@ -435,7 +438,7 @@ public:
|
|||
virtual const ItemKey getKey() const override { return payloadGetKey<T>(_data); }
|
||||
virtual const Item::Bound getBound() const override { return payloadGetBound<T>(_data); }
|
||||
virtual int getLayer() const override { return payloadGetLayer<T>(_data); }
|
||||
|
||||
virtual bool mustFade() const override { return payloadMustFade<T>(_data); }
|
||||
|
||||
virtual void render(RenderArgs* args) override { payloadRender<T>(_data, args); }
|
||||
|
||||
|
|
|
@ -65,6 +65,5 @@ void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varyin
|
|||
const auto overlayTransparents = task.addJob<DepthSortItems>("DepthSortOverlayTransparent", filteredNonspatialBuckets[TRANSPARENT_SHAPE_BUCKET], DepthSortItems(false));
|
||||
const auto background = filteredNonspatialBuckets[BACKGROUND_BUCKET];
|
||||
|
||||
output = Varying(Output{{
|
||||
opaques, transparents, lights, metas, overlayOpaques, overlayTransparents, background, spatialSelection }});
|
||||
output = Output(BucketList{ opaques, transparents, lights, metas, overlayOpaques, overlayTransparents, background }, spatialSelection);
|
||||
}
|
||||
|
|
|
@ -26,12 +26,12 @@ public:
|
|||
OVERLAY_OPAQUE_SHAPE,
|
||||
OVERLAY_TRANSPARENT_SHAPE,
|
||||
BACKGROUND,
|
||||
SPATIAL_SELECTION,
|
||||
|
||||
NUM_BUCKETS
|
||||
};
|
||||
|
||||
using Output = std::array<render::Varying, Buckets::NUM_BUCKETS>;
|
||||
using BucketList = render::VaryingArray<render::ItemBounds, Buckets::NUM_BUCKETS>;
|
||||
using Output = render::VaryingSet2<BucketList, render::ItemSpatialTree::ItemSelection>;
|
||||
using JobModel = render::Task::ModelO<RenderFetchCullSortTask, Output>;
|
||||
|
||||
RenderFetchCullSortTask() {}
|
||||
|
|
|
@ -76,6 +76,8 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p
|
|||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), Slot::BUFFER::LIGHT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), Slot::BUFFER::LIGHT_AMBIENT_BUFFER));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), Slot::MAP::LIGHT_AMBIENT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), Slot::MAP::FADE_MASK));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("fadeParametersBuffer"), Slot::BUFFER::FADE_PARAMETERS));
|
||||
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
|
@ -94,7 +96,9 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p
|
|||
locations->lightBufferUnit = program->getUniformBuffers().findLocation("lightBuffer");
|
||||
locations->lightAmbientBufferUnit = program->getUniformBuffers().findLocation("lightAmbientBuffer");
|
||||
locations->lightAmbientMapUnit = program->getTextures().findLocation("skyboxMap");
|
||||
|
||||
locations->fadeMaskTextureUnit = program->getTextures().findLocation("fadeMaskMap");
|
||||
locations->fadeParameterBufferUnit = program->getUniformBuffers().findLocation("fadeParametersBuffer");
|
||||
|
||||
ShapeKey key{filter._flags};
|
||||
auto gpuPipeline = gpu::Pipeline::create(program, state);
|
||||
auto shapePipeline = std::make_shared<Pipeline>(gpuPipeline, locations, batchSetter, itemSetter);
|
||||
|
@ -108,7 +112,7 @@ const ShapePipelinePointer ShapePlumber::pickPipeline(RenderArgs* args, const Ke
|
|||
|
||||
PerformanceTimer perfTimer("ShapePlumber::pickPipeline");
|
||||
|
||||
const auto& pipelineIterator = _pipelineMap.find(key);
|
||||
auto pipelineIterator = _pipelineMap.find(key);
|
||||
if (pipelineIterator == _pipelineMap.end()) {
|
||||
// The first time we can't find a pipeline, we should log it
|
||||
if (_missingKeys.find(key) == _missingKeys.end()) {
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
DEPTH_BIAS,
|
||||
WIREFRAME,
|
||||
NO_CULL_FACE,
|
||||
FADE,
|
||||
|
||||
OWN_PIPELINE,
|
||||
INVALID,
|
||||
|
@ -70,6 +71,7 @@ public:
|
|||
Builder& withDepthBias() { _flags.set(DEPTH_BIAS); return (*this); }
|
||||
Builder& withWireframe() { _flags.set(WIREFRAME); return (*this); }
|
||||
Builder& withoutCullFace() { _flags.set(NO_CULL_FACE); return (*this); }
|
||||
Builder& withFade() { _flags.set(FADE); return (*this); }
|
||||
|
||||
Builder& withOwnPipeline() { _flags.set(OWN_PIPELINE); return (*this); }
|
||||
Builder& invalidate() { _flags.set(INVALID); return (*this); }
|
||||
|
@ -128,6 +130,9 @@ public:
|
|||
Builder& withCullFace() { _flags.reset(NO_CULL_FACE); _mask.set(NO_CULL_FACE); return (*this); }
|
||||
Builder& withoutCullFace() { _flags.set(NO_CULL_FACE); _mask.set(NO_CULL_FACE); return (*this); }
|
||||
|
||||
Builder& withFade() { _flags.set(FADE); _mask.set(FADE); return (*this); }
|
||||
Builder& withoutFade() { _flags.reset(FADE); _mask.set(FADE); return (*this); }
|
||||
|
||||
protected:
|
||||
friend class Filter;
|
||||
Flags _flags{0};
|
||||
|
@ -152,6 +157,7 @@ public:
|
|||
bool isDepthBiased() const { return _flags[DEPTH_BIAS]; }
|
||||
bool isWireframe() const { return _flags[WIREFRAME]; }
|
||||
bool isCullFace() const { return !_flags[NO_CULL_FACE]; }
|
||||
bool isFaded() const { return _flags[FADE]; }
|
||||
|
||||
bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; }
|
||||
bool isValid() const { return !_flags[INVALID]; }
|
||||
|
@ -188,6 +194,7 @@ inline QDebug operator<<(QDebug debug, const ShapeKey& key) {
|
|||
<< "isDepthBiased:" << key.isDepthBiased()
|
||||
<< "isWireframe:" << key.isWireframe()
|
||||
<< "isCullFace:" << key.isCullFace()
|
||||
<< "isFaded:" << key.isFaded()
|
||||
<< "]";
|
||||
}
|
||||
} else {
|
||||
|
@ -209,6 +216,7 @@ public:
|
|||
LIGHTING_MODEL,
|
||||
LIGHT,
|
||||
LIGHT_AMBIENT_BUFFER,
|
||||
FADE_PARAMETERS,
|
||||
};
|
||||
|
||||
enum MAP {
|
||||
|
@ -220,6 +228,7 @@ public:
|
|||
OCCLUSION,
|
||||
SCATTERING,
|
||||
LIGHT_AMBIENT,
|
||||
FADE_MASK,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -238,6 +247,8 @@ public:
|
|||
int lightBufferUnit;
|
||||
int lightAmbientBufferUnit;
|
||||
int lightAmbientMapUnit;
|
||||
int fadeMaskTextureUnit;
|
||||
int fadeParameterBufferUnit;
|
||||
};
|
||||
using LocationsPointer = std::shared_ptr<Locations>;
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ public:
|
|||
template <class T> Varying getN (uint8_t index) const { return get<T>()[index]; }
|
||||
template <class T> Varying editN (uint8_t index) { return edit<T>()[index]; }
|
||||
|
||||
bool isNull() const { return _concept == nullptr; }
|
||||
|
||||
protected:
|
||||
class Concept {
|
||||
public:
|
||||
|
@ -93,7 +95,7 @@ public:
|
|||
}
|
||||
virtual uint8_t length() const { return 2; }
|
||||
|
||||
Varying hasVarying() const { return Varying((*this)); }
|
||||
Varying asVarying() const { return Varying((*this)); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -126,7 +128,7 @@ public:
|
|||
}
|
||||
virtual uint8_t length() const { return 3; }
|
||||
|
||||
Varying hasVarying() const { return Varying((*this)); }
|
||||
Varying asVarying() const { return Varying((*this)); }
|
||||
};
|
||||
|
||||
template <class T0, class T1, class T2, class T3>
|
||||
|
@ -163,7 +165,7 @@ public:
|
|||
}
|
||||
virtual uint8_t length() const { return 4; }
|
||||
|
||||
Varying hasVarying() const { return Varying((*this)); }
|
||||
Varying asVarying() const { return Varying((*this)); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -206,7 +208,7 @@ public:
|
|||
}
|
||||
virtual uint8_t length() const { return 5; }
|
||||
|
||||
Varying hasVarying() const { return Varying((*this)); }
|
||||
Varying asVarying() const { return Varying((*this)); }
|
||||
};
|
||||
|
||||
template <class T0, class T1, class T2, class T3, class T4, class T5>
|
||||
|
@ -236,7 +238,7 @@ public:
|
|||
const T5& get5() const { return std::get<5>((*this)).template get<T5>(); }
|
||||
T5& edit5() { return std::get<5>((*this)).template edit<T5>(); }
|
||||
|
||||
Varying hasVarying() const { return Varying((*this)); }
|
||||
Varying asVarying() const { return Varying((*this)); }
|
||||
};
|
||||
|
||||
template <class T0, class T1, class T2, class T3, class T4, class T5, class T6>
|
||||
|
@ -269,7 +271,7 @@ public:
|
|||
const T6& get6() const { return std::get<6>((*this)).template get<T6>(); }
|
||||
T6& edit6() { return std::get<6>((*this)).template edit<T6>(); }
|
||||
|
||||
Varying hasVarying() const { return Varying((*this)); }
|
||||
Varying asVarying() const { return Varying((*this)); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -281,6 +283,11 @@ public:
|
|||
(*this)[i] = Varying(T());
|
||||
}
|
||||
}
|
||||
|
||||
VaryingArray(std::initializer_list<Varying> list) {
|
||||
assert(list.size() == NUM);
|
||||
std::copy(list.begin(), list.end(), std::array<Varying, NUM>::begin());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -38,11 +38,12 @@ Item {
|
|||
}
|
||||
|
||||
Label {
|
||||
id: labelValue
|
||||
text: sliderControl.value.toFixed(root.integral ? 0 : 2)
|
||||
anchors.left: root.left
|
||||
anchors.leftMargin: 200
|
||||
anchors.top: root.top
|
||||
anchors.topMargin: 7
|
||||
anchors.topMargin: 15
|
||||
}
|
||||
|
||||
Binding {
|
||||
|
@ -56,7 +57,7 @@ Item {
|
|||
Slider {
|
||||
id: sliderControl
|
||||
stepSize: root.integral ? 1.0 : 0.0
|
||||
width: 150
|
||||
width: root.width-130
|
||||
height: 20
|
||||
anchors.right: root.right
|
||||
anchors.rightMargin: 8
|
||||
|
|
21
scripts/developer/utilities/render/debugFade.js
Normal file
21
scripts/developer/utilities/render/debugFade.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// debugFade.js
|
||||
// developer/utilities/render
|
||||
//
|
||||
// Olivier Prat, created on 30/04/2017.
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
// Set up the qml ui
|
||||
var qml = Script.resolvePath('fade.qml');
|
||||
var window = new OverlayWindow({
|
||||
title: 'Fade',
|
||||
source: qml,
|
||||
width: 910,
|
||||
height: 610,
|
||||
});
|
||||
window.setPosition(50, 50);
|
||||
window.closed.connect(function() { Script.stop(); });
|
397
scripts/developer/utilities/render/fade.qml
Normal file
397
scripts/developer/utilities/render/fade.qml
Normal file
|
@ -0,0 +1,397 @@
|
|||
//
|
||||
// fade.qml
|
||||
// developer/utilities/render
|
||||
//
|
||||
// Olivier Prat, created on 30/04/2017.
|
||||
// Copyright 2017 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
|
||||
import "configSlider"
|
||||
import "../lib/plotperf"
|
||||
|
||||
Column {
|
||||
id: root
|
||||
property var config: Render.getConfig("RenderMainView.FadeConfigure");
|
||||
property var switchConfig: Render.getConfig("RenderMainView.FadeSwitch");
|
||||
spacing: 8
|
||||
|
||||
Row {
|
||||
spacing: 8
|
||||
|
||||
CheckBox {
|
||||
text: "Edit Fade"
|
||||
checked: root.switchConfig["editFade"]
|
||||
onCheckedChanged: {
|
||||
root.switchConfig["editFade"] = checked;
|
||||
Render.getConfig("RenderMainView.DrawFadedOpaqueBounds").enabled = checked;
|
||||
}
|
||||
}
|
||||
ComboBox {
|
||||
id: categoryBox
|
||||
width: 400
|
||||
model: ["Elements enter/leave domain", "Bubble isect. - Owner POV", "Bubble isect. - Trespasser POV", "Another user leaves/arrives", "Changing an avatar"]
|
||||
Timer {
|
||||
id: postpone
|
||||
interval: 100; running: false; repeat: false
|
||||
onTriggered: { paramWidgetLoader.sourceComponent = paramWidgets }
|
||||
}
|
||||
onCurrentIndexChanged: {
|
||||
root.config["editedCategory"] = currentIndex;
|
||||
// This is a hack to be sure the widgets below properly reflect the change of category: delete the Component
|
||||
// by setting the loader source to Null and then recreate it 100ms later
|
||||
paramWidgetLoader.sourceComponent = undefined;
|
||||
postpone.interval = 100
|
||||
postpone.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
Row {
|
||||
spacing: 8
|
||||
|
||||
CheckBox {
|
||||
text: "Manual"
|
||||
checked: root.config["manualFade"]
|
||||
onCheckedChanged: {
|
||||
root.config["manualFade"] = checked;
|
||||
}
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Threshold"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "manualThreshold"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
}
|
||||
|
||||
Action {
|
||||
id: saveAction
|
||||
text: "Save"
|
||||
onTriggered: {
|
||||
root.config.save()
|
||||
}
|
||||
}
|
||||
Action {
|
||||
id: loadAction
|
||||
text: "Load"
|
||||
onTriggered: {
|
||||
root.config.load()
|
||||
// This is a hack to be sure the widgets below properly reflect the change of category: delete the Component
|
||||
// by setting the loader source to Null and then recreate it 500ms later
|
||||
paramWidgetLoader.sourceComponent = undefined;
|
||||
postpone.interval = 500
|
||||
postpone.start()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: paramWidgets
|
||||
|
||||
Column {
|
||||
spacing: 8
|
||||
|
||||
CheckBox {
|
||||
text: "Invert"
|
||||
checked: root.config["isInverted"]
|
||||
onCheckedChanged: { root.config["isInverted"] = checked }
|
||||
}
|
||||
Row {
|
||||
spacing: 8
|
||||
|
||||
GroupBox {
|
||||
title: "Base Gradient"
|
||||
width: 450
|
||||
Column {
|
||||
spacing: 8
|
||||
|
||||
ConfigSlider {
|
||||
label: "Size X"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "baseSizeX"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Size Y"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "baseSizeY"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Size Z"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "baseSizeZ"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Level"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "baseLevel"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox {
|
||||
title: "Noise Gradient"
|
||||
width: 450
|
||||
Column {
|
||||
spacing: 8
|
||||
|
||||
ConfigSlider {
|
||||
label: "Size X"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "noiseSizeX"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Size Y"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "noiseSizeY"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Size Z"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "noiseSizeZ"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Level"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "noiseLevel"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Row {
|
||||
spacing: 8
|
||||
|
||||
GroupBox {
|
||||
title: "Edge"
|
||||
width: 450
|
||||
Column {
|
||||
spacing: 8
|
||||
|
||||
ConfigSlider {
|
||||
label: "Width"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "edgeWidth"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
GroupBox {
|
||||
title: "Inner color"
|
||||
Column {
|
||||
spacing: 8
|
||||
ConfigSlider {
|
||||
label: "Color R"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "edgeInnerColorR"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Color G"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "edgeInnerColorG"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Color B"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "edgeInnerColorB"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Color intensity"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "edgeInnerIntensity"
|
||||
max: 5.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox {
|
||||
title: "Outer color"
|
||||
Column {
|
||||
spacing: 8
|
||||
ConfigSlider {
|
||||
label: "Color R"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "edgeOuterColorR"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Color G"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "edgeOuterColorG"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Color B"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "edgeOuterColorB"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Color intensity"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "edgeOuterIntensity"
|
||||
max: 5.0
|
||||
min: 0.0
|
||||
width: 400
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
GroupBox {
|
||||
title: "Timing"
|
||||
width: 450
|
||||
Column {
|
||||
spacing: 8
|
||||
|
||||
ConfigSlider {
|
||||
label: "Duration"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "duration"
|
||||
max: 10.0
|
||||
min: 0.1
|
||||
width: 400
|
||||
}
|
||||
ComboBox {
|
||||
width: 400
|
||||
model: ["Linear", "Ease In", "Ease Out", "Ease In / Out"]
|
||||
currentIndex: root.config["timing"]
|
||||
onCurrentIndexChanged: {
|
||||
root.config["timing"] = currentIndex;
|
||||
}
|
||||
}
|
||||
GroupBox {
|
||||
title: "Noise Animation"
|
||||
Column {
|
||||
spacing: 8
|
||||
ConfigSlider {
|
||||
label: "Speed X"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "noiseSpeedX"
|
||||
max: 1.0
|
||||
min: -1.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Speed Y"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "noiseSpeedY"
|
||||
max: 1.0
|
||||
min: -1.0
|
||||
width: 400
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Speed Z"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "noiseSpeedZ"
|
||||
max: 1.0
|
||||
min: -1.0
|
||||
width: 400
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlotPerf {
|
||||
title: "Threshold"
|
||||
height: parent.evalEvenHeight()
|
||||
object: Render.getConfig("RenderMainView.DrawFadeOpaque")
|
||||
valueUnit: "%"
|
||||
valueScale: 0.01
|
||||
valueNumDigits: "1"
|
||||
plots: [
|
||||
{
|
||||
prop: "threshold",
|
||||
label: "Threshold",
|
||||
color: "#FFBB77"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: 8
|
||||
Button {
|
||||
action: saveAction
|
||||
}
|
||||
Button {
|
||||
action: loadAction
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: paramWidgetLoader
|
||||
sourceComponent: paramWidgets
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue