Refactored Fade.slh to take into account differences between instanced draw and normal draw

This commit is contained in:
Olivier Prat 2017-07-18 12:49:34 +02:00
parent 10a6ad2ac9
commit dbf0b64dfb
28 changed files with 378 additions and 85 deletions

View file

@ -865,10 +865,10 @@ render::ShapePipelinePointer PolyVoxPayload::shapePipelineFactory(const render::
if (key.isFaded()) {
const auto& fadeEffect = DependencyManager::get<FadeEffect>();
if (key.isWireframe()) {
return std::make_shared<render::ShapePipeline>(_wireframePipelines[1], nullptr, fadeEffect->getBatchSetter(), fadeEffect->getItemSetter());
return std::make_shared<render::ShapePipeline>(_wireframePipelines[1], nullptr, fadeEffect->getBatchSetter(), fadeEffect->getItemUniformSetter());
}
else {
return std::make_shared<render::ShapePipeline>(_pipelines[1], nullptr, fadeEffect->getBatchSetter(), fadeEffect->getItemSetter());
return std::make_shared<render::ShapePipeline>(_pipelines[1], nullptr, fadeEffect->getBatchSetter(), fadeEffect->getItemUniformSetter());
}
}
else {

View file

@ -19,6 +19,7 @@
#include <render-utils/simple_vert.h>
#include <render-utils/simple_frag.h>
#include <FadeEffect.h>
// Sphere entities should fit inside a cube entity of the same size, so a sphere that has dimensions 1x1x1
// is a half unit sphere. However, the geometry cache renders a UNIT sphere, so we need to scale down.
@ -160,10 +161,29 @@ void RenderableShapeEntityItem::render(RenderArgs* args) {
assert(args->_shapePipeline != nullptr);
if (shapeKey.isWireframe()) {
geometryCache->renderWireShapeInstance(args, batch, MAPPING[_shape], color, args->_shapePipeline);
if (shapeKey.isFaded()) {
auto fadeEffect = DependencyManager::get<FadeEffect>();
auto fadeCategory = fadeEffect->getLastCategory();
auto fadeThreshold = fadeEffect->getLastThreshold();
auto fadeNoiseOffset = fadeEffect->getLastNoiseOffset();
auto fadeBaseOffset = fadeEffect->getLastBaseOffset();
auto fadeBaseInvSize = fadeEffect->getLastBaseInvSize();
if (shapeKey.isWireframe()) {
geometryCache->renderWireFadeShapeInstance(args, batch, MAPPING[_shape], color, fadeCategory, fadeThreshold,
fadeNoiseOffset, fadeBaseOffset, fadeBaseInvSize, args->_shapePipeline);
}
else {
geometryCache->renderSolidFadeShapeInstance(args, batch, MAPPING[_shape], color, fadeCategory, fadeThreshold,
fadeNoiseOffset, fadeBaseOffset, fadeBaseInvSize, args->_shapePipeline);
}
} else {
geometryCache->renderSolidShapeInstance(args, batch, MAPPING[_shape], color, args->_shapePipeline);
if (shapeKey.isWireframe()) {
geometryCache->renderWireShapeInstance(args, batch, MAPPING[_shape], color, args->_shapePipeline);
}
else {
geometryCache->renderSolidShapeInstance(args, batch, MAPPING[_shape], color, args->_shapePipeline);
}
}
}

View file

@ -30,7 +30,10 @@ uniform vec3 voxelVolumeSize;
void main(void) {
vec3 emissive;
applyFade(_worldPosition.xyz, emissive);
FadeObjectParams fadeParams;
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, emissive);
vec3 worldNormal = cross(dFdy(_worldPosition.xyz), dFdx(_worldPosition.xyz));
worldNormal = normalize(worldNormal);

View file

@ -9,7 +9,7 @@
<@if not FADE_SLH@>
<@def FADE_SLH@>
<@func declareFadeFragment()@>
<@func declareFadeFragmentCommon()@>
#define CATEGORY_COUNT 5
@ -19,25 +19,28 @@
uniform fadeParametersBuffer {
FadeParameters fadeParameters[CATEGORY_COUNT];
};
uniform int fadeCategory;
uniform vec3 fadeNoiseOffset;
uniform vec3 fadeBaseOffset;
uniform vec3 fadeBaseInvSize;
uniform float fadeThreshold;
uniform sampler2D fadeMaskMap;
struct FadeObjectParams {
int category;
float threshold;
vec3 noiseOffset;
vec3 baseOffset;
vec3 baseInvSize;
};
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
return pow(n, 1.0/2.2); // Remove sRGB. Need to fix this later directly in the texture
}
float evalFadeNoiseGradient(vec3 position) {
float evalFadeNoiseGradient(FadeObjectParams params, vec3 position) {
// Do tri-linear interpolation
vec3 noisePosition = position * fadeParameters[fadeCategory]._noiseInvSizeAndLevel.xyz + fadeNoiseOffset;
vec3 noisePosition = position * fadeParameters[params.category]._noiseInvSizeAndLevel.xyz + params.noiseOffset;
vec3 noisePositionFloored = floor(noisePosition);
vec3 noisePositionFraction = fract(noisePosition);
@ -58,39 +61,37 @@ float evalFadeNoiseGradient(vec3 position) {
float noise = mix(maskY.x, maskY.y, noisePositionFraction.y);
noise -= 0.5; // Center on value 0
return noise * fadeParameters[fadeCategory]._noiseInvSizeAndLevel.w;
return noise * fadeParameters[params.category]._noiseInvSizeAndLevel.w;
}
float evalFadeBaseGradient(vec3 position) {
float gradient = length((position - fadeBaseOffset) * fadeBaseInvSize.xyz);
float evalFadeBaseGradient(FadeObjectParams params, vec3 position) {
float gradient = length((position - params.baseOffset) * params.baseInvSize.xyz);
gradient = gradient-0.5; // Center on value 0.5
gradient *= fadeParameters[fadeCategory]._baseLevel;
gradient *= fadeParameters[params.category]._baseLevel;
return gradient;
}
float evalFadeGradient(vec3 position) {
float baseGradient = evalFadeBaseGradient(position);
float noiseGradient = evalFadeNoiseGradient(position);
float evalFadeGradient(FadeObjectParams params, vec3 position) {
float baseGradient = evalFadeBaseGradient(params, position);
float noiseGradient = evalFadeNoiseGradient(params, position);
float gradient = noiseGradient+baseGradient+0.5;
return gradient;
}
float evalFadeAlpha(vec3 position) {
float cutoff = fadeThreshold;
return evalFadeGradient(position)-cutoff;
float evalFadeAlpha(FadeObjectParams params, vec3 position) {
return evalFadeGradient(params, position)-params.threshold;
}
void applyFadeClip(vec3 position) {
if (evalFadeAlpha(position) < 0) {
void applyFadeClip(FadeObjectParams params, vec3 position) {
if (evalFadeAlpha(params, position) < 0) {
discard;
}
}
void applyFade(vec3 position, out vec3 emissive) {
float alpha = evalFadeAlpha(position);
if (fadeParameters[fadeCategory]._isInverted!=0) {
void applyFade(FadeObjectParams params, vec3 position, out vec3 emissive) {
float alpha = evalFadeAlpha(params, position);
if (fadeParameters[params.category]._isInverted!=0) {
alpha = -alpha;
}
@ -98,15 +99,75 @@ void applyFade(vec3 position, out vec3 emissive) {
discard;
}
float edgeMask = alpha * fadeParameters[fadeCategory]._edgeWidthInvWidth.y;
float edgeMask = alpha * fadeParameters[params.category]._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);
vec4 color = mix(fadeParameters[params.category]._innerEdgeColor, fadeParameters[params.category]._outerEdgeColor, edgeAlpha);
emissive = color.rgb * edgeMask * color.a;
}
<@endfunc@>
<@func declareFadeFragmentUniform()@>
uniform int fadeCategory;
uniform vec3 fadeNoiseOffset;
uniform vec3 fadeBaseOffset;
uniform vec3 fadeBaseInvSize;
uniform float fadeThreshold;
<@endfunc@>
<@func fetchFadeObjectParams(fadeParams)@>
<$fadeParams$>.category = fadeCategory;
<$fadeParams$>.threshold = fadeThreshold;
<$fadeParams$>.noiseOffset = fadeNoiseOffset;
<$fadeParams$>.baseOffset = fadeBaseOffset;
<$fadeParams$>.baseInvSize = fadeBaseInvSize;
<@endfunc@>
<@func declareFadeFragmentVertexInput()@>
in vec4 _fadeData1;
in vec4 _fadeData2;
in vec4 _fadeData3;
<@endfunc@>
<@func fetchFadeObjectParamsInstanced(fadeParams)@>
<$fadeParams$>.category = int(_fadeData1.w);
<$fadeParams$>.threshold = _fadeData2.w;
<$fadeParams$>.noiseOffset = _fadeData1.xyz;
<$fadeParams$>.baseOffset = _fadeData2.xyz;
<$fadeParams$>.baseInvSize = _fadeData3.xyz;
<@endfunc@>
<@func declareFadeFragment()@>
<$declareFadeFragmentCommon()$>
<$declareFadeFragmentUniform()$>
<@endfunc@>
<@func declareFadeFragmentInstanced()@>
<$declareFadeFragmentCommon()$>
<$declareFadeFragmentVertexInput()$>
<@endfunc@>
<@func declareFadeVertexInstanced()@>
in vec4 _texCoord2;
in vec4 _texCoord3;
in vec4 _texCoord4;
out vec4 _fadeData1;
out vec4 _fadeData2;
out vec4 _fadeData3;
<@endfunc@>
<@func passThroughFadeObjectParams()@>
_fadeData1 = _texCoord2;
_fadeData2 = _texCoord3;
_fadeData3 = _texCoord4;
<@endfunc@>
<@endif@>

View file

@ -39,35 +39,67 @@ render::ShapePipeline::BatchSetter FadeEffect::getBatchSetter() const {
};
}
render::ShapePipeline::ItemSetter FadeEffect::getItemSetter() const {
render::ShapePipeline::ItemSetter FadeEffect::getItemUniformSetter() const {
return [](const render::ShapePipeline& shapePipeline, render::Args* args, const render::Item& item) {
if (!render::TransitionStage::isIndexInvalid(item.getTransitionId())) {
auto scene = args->_scene;
auto batch = args->_batch;
auto transitionStage = scene->getStage<render::TransitionStage>(render::TransitionStage::getName());
auto& transitionState = transitionStage->getTransition(item.getTransitionId());
render::ShapeKey shapeKey(args->_globalShapeKey);
auto program = shapePipeline.pipeline->getProgram();
auto& uniforms = program->getUniforms();
auto fadeNoiseOffsetLocation = uniforms.findLocation("fadeNoiseOffset");
auto fadeBaseOffsetLocation = uniforms.findLocation("fadeBaseOffset");
auto fadeBaseInvSizeLocation = uniforms.findLocation("fadeBaseInvSize");
auto fadeThresholdLocation = uniforms.findLocation("fadeThreshold");
auto fadeCategoryLocation = uniforms.findLocation("fadeCategory");
// This is the normal case where we need to push the parameters in uniforms
{
auto program = shapePipeline.pipeline->getProgram();
auto& uniforms = program->getUniforms();
auto fadeNoiseOffsetLocation = uniforms.findLocation("fadeNoiseOffset");
auto fadeBaseOffsetLocation = uniforms.findLocation("fadeBaseOffset");
auto fadeBaseInvSizeLocation = uniforms.findLocation("fadeBaseInvSize");
auto fadeThresholdLocation = uniforms.findLocation("fadeThreshold");
auto fadeCategoryLocation = uniforms.findLocation("fadeCategory");
if (fadeNoiseOffsetLocation >= 0 || fadeBaseInvSizeLocation >= 0 || fadeBaseOffsetLocation >= 0 || fadeThresholdLocation >= 0 || fadeCategoryLocation >= 0) {
const auto fadeCategory = FadeJob::transitionToCategory[transitionState.eventType];
if (fadeNoiseOffsetLocation >= 0 || fadeBaseInvSizeLocation >= 0 || fadeBaseOffsetLocation >= 0 || fadeThresholdLocation >= 0 || fadeCategoryLocation >= 0) {
const auto fadeCategory = FadeJob::transitionToCategory[transitionState.eventType];
batch->_glUniform1i(fadeCategoryLocation, fadeCategory);
batch->_glUniform1f(fadeThresholdLocation, transitionState.threshold);
batch->_glUniform3f(fadeNoiseOffsetLocation, transitionState.noiseOffset.x, transitionState.noiseOffset.y, transitionState.noiseOffset.z);
batch->_glUniform3f(fadeBaseOffsetLocation, transitionState.baseOffset.x, transitionState.baseOffset.y, transitionState.baseOffset.z);
batch->_glUniform3f(fadeBaseInvSizeLocation, transitionState.baseInvSize.x, transitionState.baseInvSize.y, transitionState.baseInvSize.z);
}
batch->_glUniform1i(fadeCategoryLocation, fadeCategory);
batch->_glUniform1f(fadeThresholdLocation, transitionState.threshold);
batch->_glUniform3f(fadeNoiseOffsetLocation, transitionState.noiseOffset.x, transitionState.noiseOffset.y, transitionState.noiseOffset.z);
batch->_glUniform3f(fadeBaseOffsetLocation, transitionState.baseOffset.x, transitionState.baseOffset.y, transitionState.baseOffset.z);
batch->_glUniform3f(fadeBaseInvSizeLocation, transitionState.baseInvSize.x, transitionState.baseInvSize.y, transitionState.baseInvSize.z);
}
}
};
}
render::ShapePipeline::ItemSetter FadeEffect::getItemStoredSetter() {
return [this](const render::ShapePipeline& shapePipeline, render::Args* args, const render::Item& item) {
if (!render::TransitionStage::isIndexInvalid(item.getTransitionId())) {
auto scene = args->_scene;
auto batch = args->_batch;
auto transitionStage = scene->getStage<render::TransitionStage>(render::TransitionStage::getName());
auto& transitionState = transitionStage->getTransition(item.getTransitionId());
const auto fadeCategory = FadeJob::transitionToCategory[transitionState.eventType];
_lastCategory = fadeCategory;
_lastThreshold = transitionState.threshold;
_lastNoiseOffset = transitionState.noiseOffset;
_lastBaseOffset = transitionState.baseOffset;
_lastBaseInvSize = transitionState.baseInvSize;
}
};
}
void FadeEffect::packToAttributes(const int category, const float threshold, const glm::vec3& noiseOffset,
const glm::vec3& baseOffset, const glm::vec3& baseInvSize,
glm::vec4& packedData1, glm::vec4& packedData2, glm::vec4& packedData3) {
packedData1.x = noiseOffset.x;
packedData1.y = noiseOffset.y;
packedData1.z = noiseOffset.z;
packedData1.w = (float)category;
packedData2.x = baseOffset.x;
packedData2.y = baseOffset.y;
packedData2.z = baseOffset.z;
packedData2.w = threshold;
packedData3.x = baseInvSize.x;
packedData3.y = baseInvSize.y;
packedData3.z = baseInvSize.z;
packedData3.w = 0.f;
}

View file

@ -22,13 +22,31 @@ public:
void build(render::Task::TaskConcept& task, const task::Varying& editableItems);
render::ShapePipeline::BatchSetter getBatchSetter() const;
render::ShapePipeline::ItemSetter getItemSetter() const;
render::ShapePipeline::ItemSetter getItemUniformSetter() const;
render::ShapePipeline::ItemSetter getItemStoredSetter();
int getLastCategory() const { return _lastCategory; }
float getLastThreshold() const { return _lastThreshold; }
const glm::vec3& getLastNoiseOffset() const { return _lastNoiseOffset; }
const glm::vec3& getLastBaseOffset() const { return _lastBaseOffset; }
const glm::vec3& getLastBaseInvSize() const { return _lastBaseInvSize; }
static void packToAttributes(const int category, const float threshold, const glm::vec3& noiseOffset,
const glm::vec3& baseOffset, const glm::vec3& baseInvSize,
glm::vec4& packedData1, glm::vec4& packedData2, glm::vec4& packedData3);
private:
gpu::BufferView _configurations;
gpu::TexturePointer _maskMap;
// The last fade set through the stored item setter
int _lastCategory { 0 };
float _lastThreshold { 0.f };
glm::vec3 _lastNoiseOffset { 0.f, 0.f, 0.f };
glm::vec3 _lastBaseOffset { 0.f, 0.f, 0.f };
glm::vec3 _lastBaseInvSize { 1.f, 1.f, 1.f };
explicit FadeEffect();
virtual ~FadeEffect() { }

View file

@ -60,9 +60,11 @@ static const int VERTICES_PER_TRIANGLE = 3;
static const gpu::Element POSITION_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ };
static const gpu::Element NORMAL_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ };
static const gpu::Element COLOR_ELEMENT { gpu::VEC4, gpu::NUINT8, gpu::RGBA };
static const gpu::Element TEXCOORD4_ELEMENT { gpu::VEC4, gpu::HALF, gpu::XYZW };
static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT;
static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT;
static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT;
static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and normals
static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3);
@ -451,6 +453,19 @@ gpu::Stream::FormatPointer& getInstancedSolidStreamFormat() {
return INSTANCED_SOLID_STREAM_FORMAT;
}
gpu::Stream::FormatPointer& getInstancedSolidFadeStreamFormat() {
if (!INSTANCED_SOLID_FADE_STREAM_FORMAT) {
INSTANCED_SOLID_FADE_STREAM_FORMAT = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT);
INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT);
INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD2, gpu::Stream::TEXCOORD2, TEXCOORD4_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD3, gpu::Stream::TEXCOORD3, TEXCOORD4_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD4, gpu::Stream::TEXCOORD4, TEXCOORD4_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
}
return INSTANCED_SOLID_FADE_STREAM_FORMAT;
}
QHash<SimpleProgramKey, gpu::PipelinePointer> GeometryCache::_simplePrograms;
gpu::ShaderPointer GeometryCache::_simpleShader;
@ -535,11 +550,6 @@ void GeometryCache::releaseID(int id) {
_registeredGridBuffers.remove(id);
}
void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) {
gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT);
batch.setInputBuffer(gpu::Stream::COLOR, colorView);
}
void GeometryCache::initializeShapePipelines() {
if (!_simpleOpaquePipeline) {
_simpleOpaquePipeline = getShapePipeline(false, false, true, false);
@ -564,7 +574,7 @@ render::ShapePipelinePointer GeometryCache::getFadingShapePipeline(bool textured
bool unlit, bool depthBias) {
auto fadeEffect = DependencyManager::get<FadeEffect>();
auto fadeBatchSetter = fadeEffect->getBatchSetter();
auto fadeItemSetter = fadeEffect->getItemSetter();
auto fadeItemSetter = fadeEffect->getItemStoredSetter();
return std::make_shared<render::ShapePipeline>(getSimplePipeline(textured, transparent, culled, unlit, depthBias, true), nullptr,
[fadeBatchSetter, fadeItemSetter](const render::ShapePipeline& shapePipeline, gpu::Batch& batch, render::Args* args) {
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO, DependencyManager::get<TextureCache>()->getWhiteTexture());
@ -592,6 +602,11 @@ void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape) {
_shapes[shape].drawWire(batch);
}
void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) {
gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT);
batch.setInputBuffer(gpu::Stream::COLOR, colorView);
}
void GeometryCache::renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer) {
batch.setInputFormat(getInstancedSolidStreamFormat());
setupBatchInstance(batch, colorBuffer);
@ -604,6 +619,32 @@ void GeometryCache::renderWireShapeInstances(gpu::Batch& batch, Shape shape, siz
_shapes[shape].drawWireInstances(batch, count);
}
void setupBatchFadeInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer,
gpu::BufferPointer& fadeBuffer1, gpu::BufferPointer& fadeBuffer2, gpu::BufferPointer& fadeBuffer3) {
gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT);
gpu::BufferView texCoord2View(fadeBuffer1, TEXCOORD4_ELEMENT);
gpu::BufferView texCoord3View(fadeBuffer2, TEXCOORD4_ELEMENT);
gpu::BufferView texCoord4View(fadeBuffer3, TEXCOORD4_ELEMENT);
batch.setInputBuffer(gpu::Stream::COLOR, colorView);
batch.setInputBuffer(gpu::Stream::TEXCOORD2, texCoord2View);
batch.setInputBuffer(gpu::Stream::TEXCOORD3, texCoord3View);
batch.setInputBuffer(gpu::Stream::TEXCOORD4, texCoord4View);
}
void GeometryCache::renderFadeShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer,
gpu::BufferPointer& fadeBuffer1, gpu::BufferPointer& fadeBuffer2, gpu::BufferPointer& fadeBuffer3) {
batch.setInputFormat(getInstancedSolidFadeStreamFormat());
setupBatchFadeInstance(batch, colorBuffer, fadeBuffer1, fadeBuffer2, fadeBuffer3);
_shapes[shape].drawInstances(batch, count);
}
void GeometryCache::renderWireFadeShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer,
gpu::BufferPointer& fadeBuffer1, gpu::BufferPointer& fadeBuffer2, gpu::BufferPointer& fadeBuffer3) {
batch.setInputFormat(getInstancedSolidFadeStreamFormat());
setupBatchFadeInstance(batch, colorBuffer, fadeBuffer1, fadeBuffer2, fadeBuffer3);
_shapes[shape].drawWireInstances(batch, count);
}
void GeometryCache::renderCube(gpu::Batch& batch) {
renderShape(batch, Cube);
}
@ -2046,12 +2087,62 @@ void renderInstances(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color
if (isWire) {
DependencyManager::get<GeometryCache>()->renderWireShapeInstances(batch, shape, data.count(), data.buffers[INSTANCE_COLOR_BUFFER]);
} else {
}
else {
DependencyManager::get<GeometryCache>()->renderShapeInstances(batch, shape, data.count(), data.buffers[INSTANCE_COLOR_BUFFER]);
}
});
}
static const size_t INSTANCE_FADE_BUFFER1 = 1;
static const size_t INSTANCE_FADE_BUFFER2 = 2;
static const size_t INSTANCE_FADE_BUFFER3 = 3;
void renderFadeInstances(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color, int fadeCategory, float fadeThreshold,
const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize, bool isWire,
const render::ShapePipelinePointer& pipeline, GeometryCache::Shape shape) {
// Add pipeline to name
std::string instanceName = (isWire ? "wire_fade_shapes_" : "solid_fade_shapes_") + std::to_string(shape) + "_" + std::to_string(std::hash<render::ShapePipelinePointer>()(pipeline));
// Add color to named buffer
{
gpu::BufferPointer instanceColorBuffer = batch.getNamedBuffer(instanceName, INSTANCE_COLOR_BUFFER);
auto compactColor = toCompactColor(color);
instanceColorBuffer->append(compactColor);
}
// Add fade parameters to named buffers
{
gpu::BufferPointer fadeBuffer1 = batch.getNamedBuffer(instanceName, INSTANCE_FADE_BUFFER1);
gpu::BufferPointer fadeBuffer2 = batch.getNamedBuffer(instanceName, INSTANCE_FADE_BUFFER2);
gpu::BufferPointer fadeBuffer3 = batch.getNamedBuffer(instanceName, INSTANCE_FADE_BUFFER3);
// Pack parameters in 3 vec4s
glm::vec4 fadeData1;
glm::vec4 fadeData2;
glm::vec4 fadeData3;
FadeEffect::packToAttributes(fadeCategory, fadeThreshold, fadeNoiseOffset, fadeBaseOffset, fadeBaseInvSize,
fadeData1, fadeData2, fadeData3);
fadeBuffer1->append(fadeData1);
fadeBuffer2->append(fadeData2);
fadeBuffer3->append(fadeData3);
}
// Add call to named buffer
batch.setupNamedCalls(instanceName, [args, isWire, pipeline, shape](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
auto& buffers = data.buffers;
batch.setPipeline(pipeline->pipeline);
pipeline->prepare(batch, args);
if (isWire) {
DependencyManager::get<GeometryCache>()->renderWireFadeShapeInstances(batch, shape, data.count(),
buffers[INSTANCE_COLOR_BUFFER], buffers[INSTANCE_FADE_BUFFER1], buffers[INSTANCE_FADE_BUFFER2], buffers[INSTANCE_FADE_BUFFER3]);
}
else {
DependencyManager::get<GeometryCache>()->renderFadeShapeInstances(batch, shape, data.count(),
buffers[INSTANCE_COLOR_BUFFER], buffers[INSTANCE_FADE_BUFFER1], buffers[INSTANCE_FADE_BUFFER2], buffers[INSTANCE_FADE_BUFFER3]);
}
});
}
void GeometryCache::renderSolidShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
assert(pipeline != nullptr);
renderInstances(args, batch, color, false, pipeline, shape);
@ -2062,6 +2153,20 @@ void GeometryCache::renderWireShapeInstance(RenderArgs* args, gpu::Batch& batch,
renderInstances(args, batch, color, true, pipeline, shape);
}
void GeometryCache::renderSolidFadeShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color,
int fadeCategory, float fadeThreshold, const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize,
const render::ShapePipelinePointer& pipeline) {
assert(pipeline != nullptr);
renderFadeInstances(args, batch, color, fadeCategory, fadeThreshold, fadeNoiseOffset, fadeBaseOffset, fadeBaseInvSize, false, pipeline, shape);
}
void GeometryCache::renderWireFadeShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color,
int fadeCategory, float fadeThreshold, const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize,
const render::ShapePipelinePointer& pipeline) {
assert(pipeline != nullptr);
renderFadeInstances(args, batch, color, fadeCategory, fadeThreshold, fadeNoiseOffset, fadeBaseOffset, fadeBaseInvSize, true, pipeline, shape);
}
void GeometryCache::renderSolidSphereInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
assert(pipeline != nullptr);
renderInstances(args, batch, color, false, pipeline, GeometryCache::Sphere);

View file

@ -187,6 +187,11 @@ public:
void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
void renderFadeShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer,
gpu::BufferPointer& fadeBuffer1, gpu::BufferPointer& fadeBuffer2, gpu::BufferPointer& fadeBuffer3);
void renderWireFadeShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer,
gpu::BufferPointer& fadeBuffer1, gpu::BufferPointer& fadeBuffer2, gpu::BufferPointer& fadeBuffer3);
void renderSolidShapeInstance(RenderArgs* args, gpu::Batch& batch, Shape shape, const glm::vec4& color = glm::vec4(1),
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline);
void renderSolidShapeInstance(RenderArgs* args, gpu::Batch& batch, Shape shape, const glm::vec3& color,
@ -201,6 +206,13 @@ public:
renderWireShapeInstance(args, batch, shape, glm::vec4(color, 1.0f), pipeline);
}
void renderSolidFadeShapeInstance(RenderArgs* args, gpu::Batch& batch, Shape shape, const glm::vec4& color, int fadeCategory, float fadeThreshold,
const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize,
const render::ShapePipelinePointer& pipeline);
void renderWireFadeShapeInstance(RenderArgs* args, gpu::Batch& batch, Shape shape, const glm::vec4& color, int fadeCategory, float fadeThreshold,
const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize,
const render::ShapePipelinePointer& pipeline);
void renderSolidSphereInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color,
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline);
void renderSolidSphereInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec3& color,

View file

@ -62,7 +62,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
// Prepare the ShapePipelines
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
initDeferredPipelines(*shapePlumber, fadeEffect->getBatchSetter(), fadeEffect->getItemSetter());
initDeferredPipelines(*shapePlumber, fadeEffect->getBatchSetter(), fadeEffect->getItemUniformSetter());
// Extract opaques / transparents / lights / metas / overlays / background
const auto& opaques = items.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE];

View file

@ -31,8 +31,10 @@ in vec2 _texCoord1;
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material mat = getMaterial();
int matKey = getMaterialKey(mat);

View file

@ -32,8 +32,10 @@ in vec4 _worldPosition;
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material mat = getMaterial();
int matKey = getMaterialKey(mat);

View file

@ -33,8 +33,10 @@ in vec4 _worldPosition;
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material mat = getMaterial();
int matKey = getMaterialKey(mat);

View file

@ -33,8 +33,10 @@ in vec4 _worldPosition;
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material mat = getMaterial();
int matKey = getMaterialKey(mat);

View file

@ -32,8 +32,10 @@ in vec4 _worldPosition;
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material mat = getMaterial();
int matKey = getMaterialKey(mat);

View file

@ -32,8 +32,10 @@ in vec3 _color;
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material mat = getMaterial();
int matKey = getMaterialKey(mat);

View file

@ -32,8 +32,10 @@ in vec4 _worldPosition;
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material mat = getMaterial();
int matKey = getMaterialKey(mat);

View file

@ -20,7 +20,10 @@ layout(location = 0) out vec4 _fragColor;
in vec4 _worldPosition;
void main(void) {
applyFadeClip(_worldPosition.xyz);
FadeObjectParams fadeParams;
<$fetchFadeObjectParams(fadeParams)$>
applyFadeClip(fadeParams, _worldPosition.xyz);
// pass-through to set z-buffer
_fragColor = vec4(1.0, 1.0, 1.0, 0.0);

View file

@ -31,8 +31,10 @@ in vec4 _worldPosition;
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material mat = getMaterial();
int matKey = getMaterialKey(mat);

View file

@ -39,8 +39,10 @@ out vec4 _fragColor;
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material mat = getMaterial();
int matKey = getMaterialKey(mat);

View file

@ -30,8 +30,10 @@ out vec4 _fragColor;
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material mat = getMaterial();
int matKey = getMaterialKey(mat);

View file

@ -30,8 +30,10 @@ in vec4 _worldPosition;
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material mat = getMaterial();
int matKey = getMaterialKey(mat);

View file

@ -16,7 +16,7 @@
<@include model/Material.slh@>
<@include Fade.slh@>
<$declareFadeFragment()$>
<$declareFadeFragmentInstanced()$>
// the interpolated normal
in vec3 _normal;
@ -34,8 +34,10 @@ in vec4 _worldPosition;
#line 2030
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParamsInstanced(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
Material material = getMaterial();
vec3 normal = normalize(_normal.xyz);

View file

@ -17,6 +17,9 @@
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
<@include Fade.slh@>
<$declareFadeVertexInstanced()$>
// the interpolated normal
out vec3 _normal;
out vec3 _modelNormal;
@ -37,4 +40,5 @@ void main(void) {
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
<$transformModelToWorldPos(obj, inPosition, _worldPosition)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
<$passThroughFadeObjectParams()$>
}

View file

@ -28,12 +28,14 @@ in vec2 _texCoord0;
in vec4 _worldPosition;
// Declare after all samplers to prevent sampler location mix up with originalTexture
<$declareFadeFragment()$>
<$declareFadeFragmentInstanced()$>
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParamsInstanced(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
vec4 texel = texture(originalTexture, _texCoord0);
float colorAlpha = _color.a;

View file

@ -27,12 +27,14 @@ in vec2 _texCoord0;
in vec4 _worldPosition;
// Declare after all samplers to prevent sampler location mix up with originalTexture
<$declareFadeFragment()$>
<$declareFadeFragmentInstanced()$>
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParamsInstanced(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
vec4 texel = texture(originalTexture, _texCoord0.st);
float colorAlpha = _color.a;

View file

@ -34,12 +34,14 @@ in vec2 _texCoord0;
in vec4 _worldPosition;
// Declare after all samplers to prevent sampler location mix up with originalTexture
<$declareFadeFragment()$>
<$declareFadeFragmentInstanced()$>
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParamsInstanced(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
vec4 texel = texture(originalTexture, _texCoord0.st);
float opacity = _color.a;

View file

@ -28,12 +28,14 @@ in vec4 _worldPosition;
layout(location = 0) out vec4 _fragColor0;
// Declare after all samplers to prevent sampler location mix up with originalTexture
<$declareFadeFragment()$>
<$declareFadeFragmentInstanced()$>
void main(void) {
vec3 fadeEmissive;
FadeObjectParams fadeParams;
applyFade(_worldPosition.xyz, fadeEmissive);
<$fetchFadeObjectParamsInstanced(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
vec4 texel = texture(originalTexture, _texCoord0.st);
float colorAlpha = _color.a;

View file

@ -20,7 +20,10 @@ in vec4 _worldPosition;
layout(location = 0) out vec4 _fragColor;
void main(void) {
applyFadeClip(_worldPosition.xyz);
FadeObjectParams fadeParams;
<$fetchFadeObjectParams(fadeParams)$>
applyFadeClip(fadeParams, _worldPosition.xyz);
// pass-through to set z-buffer
_fragColor = vec4(1.0, 1.0, 1.0, 0.0);