haze on most entities, working on skybox

This commit is contained in:
SamGondelman 2019-07-10 18:32:43 -07:00 committed by SamGondelman
parent bd2003fa01
commit d545ba5bc6
39 changed files with 268 additions and 182 deletions

View file

@ -268,6 +268,7 @@ macro(AUTOSCRIBE_SHADER_LIB)
set(PROGRAM_ENUMS "namespace program { enum {\n") set(PROGRAM_ENUMS "namespace program { enum {\n")
foreach(PROGRAM_FILE ${SHADER_PROGRAM_FILES}) foreach(PROGRAM_FILE ${SHADER_PROGRAM_FILES})
get_filename_component(PROGRAM_NAME ${PROGRAM_FILE} NAME_WE) get_filename_component(PROGRAM_NAME ${PROGRAM_FILE} NAME_WE)
get_filename_component(PROGRAM_FOLDER ${PROGRAM_FILE} DIRECTORY)
file(READ ${PROGRAM_FILE} PROGRAM_CONFIG) file(READ ${PROGRAM_FILE} PROGRAM_CONFIG)
set(AUTOSCRIBE_PROGRAM_VERTEX ${PROGRAM_NAME}) set(AUTOSCRIBE_PROGRAM_VERTEX ${PROGRAM_NAME})
set(AUTOSCRIBE_PROGRAM_FRAGMENT ${PROGRAM_NAME}) set(AUTOSCRIBE_PROGRAM_FRAGMENT ${PROGRAM_NAME})
@ -315,7 +316,9 @@ macro(AUTOSCRIBE_SHADER_LIB)
if (HAS_FRAGMENT EQUAL -1) if (HAS_FRAGMENT EQUAL -1)
set(DEFINES "${VERTEX_DEFINES}") set(DEFINES "${VERTEX_DEFINES}")
set(SHADER_LIST "") set(SHADER_LIST "")
set(SHADER_FILE "${SRC_FOLDER}/${VERTEX_NAME}.slv") unset(SHADER_FILE)
unset(SHADER_FILE CACHE)
find_file(SHADER_FILE "${VERTEX_NAME}.slv" PATHS "${PROGRAM_FOLDER}" PATH_SUFFIXES "..")
AUTOSCRIBE_SHADER(${ALL_SHADER_HEADERS}) AUTOSCRIBE_SHADER(${ALL_SHADER_HEADERS})
string(CONCAT VERTEX_ENUMS "${VERTEX_ENUMS}" "${SHADER_LIST}") string(CONCAT VERTEX_ENUMS "${VERTEX_ENUMS}" "${SHADER_LIST}")
else() else()
@ -331,7 +334,9 @@ macro(AUTOSCRIBE_SHADER_LIB)
if (HAS_VERTEX EQUAL -1) if (HAS_VERTEX EQUAL -1)
set(DEFINES "${FRAGMENT_DEFINES}") set(DEFINES "${FRAGMENT_DEFINES}")
set(SHADER_LIST "") set(SHADER_LIST "")
set(SHADER_FILE "${SRC_FOLDER}/${FRAGMENT_NAME}.slf") unset(SHADER_FILE)
unset(SHADER_FILE CACHE)
find_file(SHADER_FILE "${FRAGMENT_NAME}.slf" PATHS "${PROGRAM_FOLDER}" PATH_SUFFIXES "..")
AUTOSCRIBE_SHADER(${ALL_SHADER_HEADERS}) AUTOSCRIBE_SHADER(${ALL_SHADER_HEADERS})
string(CONCAT FRAGMENT_ENUMS "${FRAGMENT_ENUMS}" "${SHADER_LIST}") string(CONCAT FRAGMENT_ENUMS "${FRAGMENT_ENUMS}" "${SHADER_LIST}")
else() else()

View file

@ -259,7 +259,7 @@ void GraphicsEngine::render_performFrame() {
batch.enableSkybox(true); batch.enableSkybox(true);
batch.enableStereo(isStereo); batch.enableStereo(isStereo);
batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() }); batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() });
_splashScreen->render(batch, viewFrustum); _splashScreen->render(batch, viewFrustum, renderArgs._renderMethod == RenderArgs::RenderMethod::FORWARD);
}); });
} else { } else {
{ {

View file

@ -23,7 +23,7 @@ static uint8_t CUSTOM_PIPELINE_NUMBER = 0;
static gpu::Stream::FormatPointer _vertexFormat; static gpu::Stream::FormatPointer _vertexFormat;
static std::weak_ptr<gpu::Pipeline> _texturedPipeline; static std::weak_ptr<gpu::Pipeline> _texturedPipeline;
static ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, gpu::Batch& batch) { static ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, RenderArgs* args) {
auto texturedPipeline = _texturedPipeline.lock(); auto texturedPipeline = _texturedPipeline.lock();
if (!texturedPipeline) { if (!texturedPipeline) {
auto state = std::make_shared<gpu::State>(); auto state = std::make_shared<gpu::State>();

View file

@ -34,9 +34,7 @@
#include "EntityTreeRenderer.h" #include "EntityTreeRenderer.h"
#ifdef POLYVOX_ENTITY_USE_FADE_EFFECT #include <FadeEffect.h>
# include <FadeEffect.h>
#endif
#if defined(__GNUC__) && !defined(__clang__) #if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push #pragma GCC diagnostic push
@ -1553,52 +1551,49 @@ using namespace render;
using namespace render::entities; using namespace render::entities;
static uint8_t CUSTOM_PIPELINE_NUMBER; static uint8_t CUSTOM_PIPELINE_NUMBER;
static gpu::PipelinePointer _pipelines[2]; static std::map<std::tuple<bool, bool, bool>, ShapePipelinePointer> _pipelines;
static gpu::PipelinePointer _wireframePipelines[2];
static gpu::Stream::FormatPointer _vertexFormat; static gpu::Stream::FormatPointer _vertexFormat;
ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, gpu::Batch& batch) { ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, RenderArgs* args) {
if (!_pipelines[0]) { // FIXME: custom pipelines like this don't handle shadows or renderLayers correctly
if (_pipelines.empty()) {
using namespace shader::entities_renderer::program; using namespace shader::entities_renderer::program;
int programsIds[2] = { polyvox, polyvox_fade };
auto state = std::make_shared<gpu::State>(); static const std::vector<std::tuple<bool, bool, uint32_t>> keys = {
state->setCullMode(gpu::State::CULL_BACK); std::make_tuple(false, false, polyvox), std::make_tuple(true, false, polyvox_forward)
state->setDepthTest(true, true, gpu::LESS_EQUAL); #ifdef POLYVOX_ENTITY_USE_FADE_EFFECT
PrepareStencil::testMaskDrawShape(*state); , std::make_tuple(false, true, polyvox_fade), std::make_tuple(true, true, polyvox_forward_fade)
#else
, std::make_tuple(false, true, polyvox), std::make_tuple(true, true, polyvox_forward)
#endif
};
for (auto& key : keys) {
for (int i = 0; i < 2; ++i) {
bool wireframe = i != 0;
auto wireframeState = std::make_shared<gpu::State>(); auto state = std::make_shared<gpu::State>();
wireframeState->setCullMode(gpu::State::CULL_BACK); state->setCullMode(gpu::State::CULL_BACK);
wireframeState->setDepthTest(true, true, gpu::LESS_EQUAL); state->setDepthTest(true, true, gpu::LESS_EQUAL);
wireframeState->setFillMode(gpu::State::FILL_LINE); PrepareStencil::testMaskDrawShape(*state);
PrepareStencil::testMaskDrawShape(*wireframeState);
// Two sets of pipelines: normal and fading if (wireframe) {
for (auto i = 0; i < 2; i++) { state->setFillMode(gpu::State::FILL_LINE);
gpu::ShaderPointer program = gpu::Shader::createProgram(programsIds[i]); }
_pipelines[i] = gpu::Pipeline::create(program, state);
_wireframePipelines[i] = gpu::Pipeline::create(program, wireframeState); auto pipeline = gpu::Pipeline::create(gpu::Shader::createProgram(std::get<2>(key)), state);
if (std::get<1>(key)) {
_pipelines[std::make_tuple(std::get<0>(key), std::get<1>(key), wireframe)] = std::make_shared<render::ShapePipeline>(pipeline, nullptr, nullptr, nullptr);
} else {
const auto& fadeEffect = DependencyManager::get<FadeEffect>();
_pipelines[std::make_tuple(std::get<0>(key), std::get<1>(key), wireframe)] = std::make_shared<render::ShapePipeline>(pipeline, nullptr,
fadeEffect->getBatchSetter(), fadeEffect->getItemUniformSetter());
}
}
} }
} }
#ifdef POLYVOX_ENTITY_USE_FADE_EFFECT return _pipelines[std::make_tuple(args->_renderMethod == Args::RenderMethod::FORWARD, key.isFaded(), key.isWireframe())];
if (key.isFaded()) {
const auto& fadeEffect = DependencyManager::get<FadeEffect>();
if (key.isWireframe()) {
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->getItemUniformSetter());
}
} else {
#endif
if (key.isWireframe()) {
return std::make_shared<render::ShapePipeline>(_wireframePipelines[0], nullptr, nullptr, nullptr);
} else {
return std::make_shared<render::ShapePipeline>(_pipelines[0], nullptr, nullptr, nullptr);
}
#ifdef POLYVOX_ENTITY_USE_FADE_EFFECT
}
#endif
} }
PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) : Parent(entity) { PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {

View file

@ -22,7 +22,7 @@
LAYOUT(binding=0) uniform sampler2D _texture; LAYOUT(binding=0) uniform sampler2D _texture;
<@if not HIFI_USE_FORWARD@> <@if not HIFI_USE_FORWARD@>
layout(location=0) in vec3 _normalWS; layout(location=0) in vec3 _normalWS;
<@endif@> <@endif@>
layout(location=1) in vec2 _texCoord; layout(location=1) in vec2 _texCoord;
layout(location=2) in vec4 _color; layout(location=2) in vec4 _color;

View file

@ -28,7 +28,7 @@
<@include DefaultMaterials.slh@> <@include DefaultMaterials.slh@>
<@include GlobalLight.slh@> <@include GlobalLight.slh@>
<$declareEvalSkyboxGlobalColor()$> <$declareEvalSkyboxGlobalColor(_SCRIBE_NULL, HIFI_USE_FORWARD)$>
<@include gpu/Transform.slh@> <@include gpu/Transform.slh@>
<$declareStandardCameraTransform()$> <$declareStandardCameraTransform()$>
@ -52,7 +52,9 @@
LAYOUT(binding=0) uniform polyvoxParamsBuffer { LAYOUT(binding=0) uniform polyvoxParamsBuffer {
PolyvoxParams params; PolyvoxParams params;
}; };
<@else@> <@endif@>
<@if HIFI_USE_SHADOW or HIFI_USE_FORWARD@>
layout(location=0) out vec4 _fragColor0; layout(location=0) out vec4 _fragColor0;
<@endif@> <@endif@>
@ -101,7 +103,7 @@ void main(void) {
DEFAULT_SCATTERING); DEFAULT_SCATTERING);
<@else@> <@else@>
TransformCamera cam = getTransformCamera(); TransformCamera cam = getTransformCamera();
vec4 color = vec4(evalSkyboxGlobalColor( _fragColor0 = vec4(evalSkyboxGlobalColor(
cam._viewInverse, cam._viewInverse,
1.0, 1.0,
DEFAULT_OCCLUSION, DEFAULT_OCCLUSION,

View file

@ -98,7 +98,7 @@ void Haze::setHazeGlareColor(const glm::vec3 hazeGlareColor) {
void Haze::setHazeActive(const bool isHazeActive) { void Haze::setHazeActive(const bool isHazeActive) {
auto& params = _hazeParametersBuffer.get<Parameters>(); auto& params = _hazeParametersBuffer.get<Parameters>();
if (((params.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE )&& !isHazeActive) { if (((params.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) && !isHazeActive) {
_hazeParametersBuffer.edit<Parameters>().hazeMode &= ~HAZE_MODE_IS_ACTIVE; _hazeParametersBuffer.edit<Parameters>().hazeMode &= ~HAZE_MODE_IS_ACTIVE;
} else if (((params.hazeMode & HAZE_MODE_IS_ACTIVE) != HAZE_MODE_IS_ACTIVE) && isHazeActive) { } else if (((params.hazeMode & HAZE_MODE_IS_ACTIVE) != HAZE_MODE_IS_ACTIVE) && isHazeActive) {
_hazeParametersBuffer.edit<Parameters>().hazeMode |= HAZE_MODE_IS_ACTIVE; _hazeParametersBuffer.edit<Parameters>().hazeMode |= HAZE_MODE_IS_ACTIVE;

View file

@ -10,7 +10,7 @@
<@if not HAZE_SLH@> <@if not HAZE_SLH@>
<@def HAZE_SLH@> <@def HAZE_SLH@>
<@include render-utils/ShaderConstants.h@> <@include graphics/ShaderConstants.h@>
const int HAZE_MODE_IS_ACTIVE = 1 << 0; const int HAZE_MODE_IS_ACTIVE = 1 << 0;
const int HAZE_MODE_IS_ALTITUDE_BASED = 1 << 1; const int HAZE_MODE_IS_ALTITUDE_BASED = 1 << 1;
@ -38,8 +38,7 @@ struct HazeParams {
float hazeKeyLightAltitudeFactor; float hazeKeyLightAltitudeFactor;
}; };
// See ShapePipeline::Slot::BUFFER in ShapePipeline.h LAYOUT_STD140(binding=GRAPHICS_BUFFER_HAZE_PARAMS) uniform hazeBuffer {
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_HAZE_PARAMS) uniform hazeBuffer {
HazeParams hazeParams; HazeParams hazeParams;
}; };

View file

@ -32,6 +32,8 @@
#define GRAPHICS_TEXTURE_SKYBOX 11 #define GRAPHICS_TEXTURE_SKYBOX 11
#define GRAPHICS_BUFFER_SKYBOX_PARAMS 5 #define GRAPHICS_BUFFER_SKYBOX_PARAMS 5
#define GRAPHICS_BUFFER_HAZE_PARAMS 7
// <! // <!
namespace graphics { namespace slot { namespace graphics { namespace slot {
@ -43,7 +45,8 @@ enum Buffer {
Light = GRAPHICS_BUFFER_LIGHT, Light = GRAPHICS_BUFFER_LIGHT,
KeyLight = GRAPHICS_BUFFER_KEY_LIGHT, KeyLight = GRAPHICS_BUFFER_KEY_LIGHT,
AmbientLight = GRAPHICS_BUFFER_AMBIENT_LIGHT, AmbientLight = GRAPHICS_BUFFER_AMBIENT_LIGHT,
SkyboxParams = GRAPHICS_BUFFER_SKYBOX_PARAMS SkyboxParams = GRAPHICS_BUFFER_SKYBOX_PARAMS,
HazeParams = GRAPHICS_BUFFER_HAZE_PARAMS
}; };
} // namespace buffer } // namespace buffer

View file

@ -73,29 +73,29 @@ void Skybox::prepare(gpu::Batch& batch) const {
} }
} }
void Skybox::render(gpu::Batch& batch, const ViewFrustum& frustum) const { void Skybox::render(gpu::Batch& batch, const ViewFrustum& frustum, bool forward) const {
updateSchemaBuffer(); updateSchemaBuffer();
Skybox::render(batch, frustum, (*this)); Skybox::render(batch, frustum, (*this), forward);
} }
void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { static std::map<bool, gpu::PipelinePointer> _pipelines;
// Create the static shared elements used to render the skybox
static gpu::BufferPointer theConstants; void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox, bool forward) {
static gpu::PipelinePointer thePipeline; if (_pipelines.empty()) {
static std::once_flag once; static const std::vector<std::tuple<bool, uint32_t>> keys = {
std::call_once(once, [&] { std::make_tuple(false, shader::graphics::program::skybox),
{ std::make_tuple(true, shader::graphics::program::skybox_forward)
auto skyShader = gpu::Shader::createProgram(shader::graphics::program::skybox); };
auto skyState = std::make_shared<gpu::State>(); for (auto& key : keys) {
auto state = std::make_shared<gpu::State>();
// Must match PrepareStencil::STENCIL_BACKGROUND // Must match PrepareStencil::STENCIL_BACKGROUND
const int8_t STENCIL_BACKGROUND = 0; const int8_t STENCIL_BACKGROUND = 0;
skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_BACKGROUND, 0xFF, gpu::EQUAL, state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_BACKGROUND, 0xFF, gpu::EQUAL,
gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
thePipeline = gpu::Pipeline::create(skyShader, skyState); _pipelines[std::get<0>(key)] = gpu::Pipeline::create(gpu::Shader::createProgram(std::get<1>(key)), state);
} }
}); }
// Render // Render
glm::mat4 projMat; glm::mat4 projMat;
@ -111,7 +111,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky
batch.setViewTransform(viewTransform); batch.setViewTransform(viewTransform);
batch.setModelTransform(Transform()); // only for Mac batch.setModelTransform(Transform()); // only for Mac
batch.setPipeline(thePipeline); batch.setPipeline(_pipelines[forward]);
skybox.prepare(batch); skybox.prepare(batch);
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);

View file

@ -44,9 +44,9 @@ public:
virtual void clear(); virtual void clear();
void prepare(gpu::Batch& batch) const; void prepare(gpu::Batch& batch) const;
virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const; virtual void render(gpu::Batch& batch, const ViewFrustum& frustum, bool forward) const;
static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox); static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox, bool forward);
const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; } const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; }

View file

@ -1,8 +1,7 @@
<@include gpu/Config.slh@> <@include gpu/Config.slh@>
<$VERSION_HEADER$> <$VERSION_HEADER$>
// <$_SCRIBE_FILENAME$>
// Generated on <$_SCRIBE_DATE$> // Generated on <$_SCRIBE_DATE$>
// skybox.frag
// fragment shader
// //
// Created by Sam Gateau on 5/5/2015. // Created by Sam Gateau on 5/5/2015.
// Copyright 2015 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
@ -12,6 +11,10 @@
// //
<@include graphics/ShaderConstants.h@> <@include graphics/ShaderConstants.h@>
<@if HIFI_USE_FORWARD@>
<@include graphics/Haze.slh@>
<@endif@>
LAYOUT(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap; LAYOUT(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
struct Skybox { struct Skybox {
@ -36,4 +39,9 @@ void main(void) {
vec3 skyboxColor = skybox.color.rgb; vec3 skyboxColor = skybox.color.rgb;
_fragColor = vec4(mix(vec3(1.0), skyboxTexel, float(skybox.color.a > 0.0)) * _fragColor = vec4(mix(vec3(1.0), skyboxTexel, float(skybox.color.a > 0.0)) *
mix(vec3(1.0), skyboxColor, float(skybox.color.a < 1.0)), 1.0); mix(vec3(1.0), skyboxColor, float(skybox.color.a < 1.0)), 1.0);
<@if HIFI_USE_FORWARD@>
_fragColor = vec4(hazeParams.hazeColor, 1);
<@endif@>
} }

View file

@ -0,0 +1 @@
DEFINES forward:f

View file

@ -1,8 +1,7 @@
<@include gpu/Config.slh@> <@include gpu/Config.slh@>
<$VERSION_HEADER$> <$VERSION_HEADER$>
// <$_SCRIBE_FILENAME$>
// Generated on <$_SCRIBE_DATE$> // Generated on <$_SCRIBE_DATE$>
// skybox.vert
// vertex shader
// //
// Created by Sam Gateau on 5/5/2015. // Created by Sam Gateau on 5/5/2015.
// Copyright 2015 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
@ -12,7 +11,6 @@
// //
<@include gpu/Transform.slh@> <@include gpu/Transform.slh@>
<$declareStandardTransform()$> <$declareStandardTransform()$>
layout(location=0) out vec3 _normal; layout(location=0) out vec3 _normal;

View file

@ -18,6 +18,7 @@
#include <shaders/Shaders.h> #include <shaders/Shaders.h>
ProceduralSkybox::ProceduralSkybox(uint64_t created) : graphics::Skybox(), _created(created) { ProceduralSkybox::ProceduralSkybox(uint64_t created) : graphics::Skybox(), _created(created) {
// FIXME: support forward rendering for procedural skyboxes (needs haze calculation)
_procedural._vertexSource = gpu::Shader::createVertex(shader::graphics::vertex::skybox)->getSource(); _procedural._vertexSource = gpu::Shader::createVertex(shader::graphics::vertex::skybox)->getSource();
_procedural._opaqueFragmentSource = shader::Source::get(shader::procedural::fragment::proceduralSkybox); _procedural._opaqueFragmentSource = shader::Source::get(shader::procedural::fragment::proceduralSkybox);
// Adjust the pipeline state for background using the stencil test // Adjust the pipeline state for background using the stencil test
@ -40,15 +41,15 @@ void ProceduralSkybox::clear() {
Skybox::clear(); Skybox::clear();
} }
void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& frustum) const { void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& frustum, bool forward) const {
if (_procedural.isReady()) { if (_procedural.isReady()) {
ProceduralSkybox::render(batch, frustum, (*this)); ProceduralSkybox::render(batch, frustum, (*this), forward);
} else { } else {
Skybox::render(batch, frustum); Skybox::render(batch, frustum, forward);
} }
} }
void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const ProceduralSkybox& skybox) { void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const ProceduralSkybox& skybox, bool forward) {
glm::mat4 projMat; glm::mat4 projMat;
viewFrustum.evalProjectionMatrix(projMat); viewFrustum.evalProjectionMatrix(projMat);

View file

@ -26,8 +26,8 @@ public:
bool empty() override; bool empty() override;
void clear() override; void clear() override;
void render(gpu::Batch& batch, const ViewFrustum& frustum) const override; void render(gpu::Batch& batch, const ViewFrustum& frustum, bool forward) const override;
static void render(gpu::Batch& batch, const ViewFrustum& frustum, const ProceduralSkybox& skybox); static void render(gpu::Batch& batch, const ViewFrustum& frustum, const ProceduralSkybox& skybox, bool forward);
uint64_t getCreated() const { return _created; } uint64_t getCreated() const { return _created; }

View file

@ -13,6 +13,8 @@
#include <gpu/Context.h> #include <gpu/Context.h>
#include <graphics/ShaderConstants.h>
std::string BackgroundStage::_stageName { "BACKGROUND_STAGE"}; std::string BackgroundStage::_stageName { "BACKGROUND_STAGE"};
const BackgroundStage::Index BackgroundStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX }; const BackgroundStage::Index BackgroundStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX };
@ -71,6 +73,8 @@ void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext,
} }
} }
const auto& hazeFrame = inputs.get2();
if (skybox && !skybox->empty()) { if (skybox && !skybox->empty()) {
PerformanceTimer perfTimer("skybox"); PerformanceTimer perfTimer("skybox");
auto args = renderContext->args; auto args = renderContext->args;
@ -91,7 +95,18 @@ void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext,
batch.setProjectionTransform(projMat); batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat); batch.setViewTransform(viewMat);
skybox->render(batch, args->getViewFrustum()); // If we're using forward rendering, we need to calculate haze
if (args->_renderMethod == render::Args::RenderMethod::FORWARD) {
const auto& hazeStage = args->_scene->getStage<HazeStage>();
if (hazeStage && hazeFrame->_hazes.size() > 0) {
const auto& hazePointer = hazeStage->getHaze(hazeFrame->_hazes.front());
if (hazePointer) {
batch.setUniformBuffer(graphics::slot::buffer::Buffer::HazeParams, hazePointer->getHazeParametersBuffer());
}
}
}
skybox->render(batch, args->getViewFrustum(), args->_renderMethod == render::Args::RenderMethod::FORWARD);
}); });
args->_batch = nullptr; args->_batch = nullptr;
} }

View file

@ -16,6 +16,7 @@
#include <unordered_map> #include <unordered_map>
#include <render/IndexedContainer.h> #include <render/IndexedContainer.h>
#include <render/Stage.h> #include <render/Stage.h>
#include "HazeStage.h"
#include "LightingModel.h" #include "LightingModel.h"
@ -81,7 +82,7 @@ public:
class DrawBackgroundStage { class DrawBackgroundStage {
public: public:
using Inputs = render::VaryingSet2<LightingModelPointer, BackgroundStage::FramePointer>; using Inputs = render::VaryingSet3<LightingModelPointer, BackgroundStage::FramePointer, HazeStage::FramePointer>;
using JobModel = render::Job::ModelI<DrawBackgroundStage, Inputs>; using JobModel = render::Job::ModelI<DrawBackgroundStage, Inputs>;
DrawBackgroundStage() {} DrawBackgroundStage() {}

View file

@ -432,7 +432,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
if (hazeStage && hazeFrame->_hazes.size() > 0) { if (hazeStage && hazeFrame->_hazes.size() > 0) {
const auto& hazePointer = hazeStage->getHaze(hazeFrame->_hazes.front()); const auto& hazePointer = hazeStage->getHaze(hazeFrame->_hazes.front());
if (hazePointer) { if (hazePointer) {
batch.setUniformBuffer(ru::Buffer::HazeParams, hazePointer->getHazeParametersBuffer()); batch.setUniformBuffer(graphics::slot::buffer::Buffer::HazeParams, hazePointer->getHazeParametersBuffer());
} }
} }
@ -655,7 +655,6 @@ void DefaultLightingSetup::run(const RenderContextPointer& renderContext) {
if (!_defaultHaze) { if (!_defaultHaze) {
auto hazeStage = renderContext->_scene->getStage<HazeStage>(); auto hazeStage = renderContext->_scene->getStage<HazeStage>();
if (hazeStage) { if (hazeStage) {
auto haze = std::make_shared<graphics::Haze>(); auto haze = std::make_shared<graphics::Haze>();
_defaultHaze = haze; _defaultHaze = haze;

View file

@ -78,7 +78,7 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(outputFramebufferSize, args->_viewport)); batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(outputFramebufferSize, args->_viewport));
batch.setPipeline(_hazePipeline); batch.setPipeline(_hazePipeline);
batch.setUniformBuffer(ru::Buffer::HazeParams, haze->getHazeParametersBuffer()); batch.setUniformBuffer(graphics::slot::buffer::Buffer::HazeParams, haze->getHazeParametersBuffer());
batch.setUniformBuffer(ru::Buffer::DeferredFrameTransform, transformBuffer->getFrameTransformBuffer()); batch.setUniformBuffer(ru::Buffer::DeferredFrameTransform, transformBuffer->getFrameTransformBuffer());
batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer());

View file

@ -98,9 +98,9 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa
<@endfunc@> <@endfunc@>
<@include Haze.slh@> <@include graphics/Haze.slh@>
<@func declareEvalSkyboxGlobalColor(supportScattering)@> <@func declareEvalSkyboxGlobalColor(supportScattering, computeHaze)@>
<$declareLightingAmbient(_SCRIBE_NULL, 1, _SCRIBE_NULL, $supportScattering$)$> <$declareLightingAmbient(_SCRIBE_NULL, 1, _SCRIBE_NULL, $supportScattering$)$>
<$declareLightingDirectional($supportScattering$)$> <$declareLightingDirectional($supportScattering$)$>
@ -109,13 +109,13 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa
<$declareDeferredCurvature()$> <$declareDeferredCurvature()$>
<@endif@> <@endif@>
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 normalWS,
vec3 albedo, vec3 fresnel, float metallic, float roughness vec3 albedo, vec3 fresnel, float metallic, float roughness
<@if supportScattering@> <@if supportScattering@>
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature , float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
<@endif@> <@endif@>
) { ) {
<$prepareGlobalLight(position, normal)$> <$prepareGlobalLight(positionES, normalWS)$>
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS); SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
@ -130,6 +130,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
color += ambientDiffuse; color += ambientDiffuse;
color += ambientSpecular; color += ambientSpecular;
// Directional
vec3 directionalDiffuse; vec3 directionalDiffuse;
vec3 directionalSpecular; vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation
@ -140,9 +141,24 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
color += directionalDiffuse; color += directionalDiffuse;
color += directionalSpecular; color += directionalSpecular;
// Attenuate the light if haze effect selected // Haze
if ((isHazeEnabled() > 0.0) && (hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) { if (isHazeEnabled() > 0.0) {
color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS); if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
}
<@if computeHaze@>
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
vec4 hazeColor = computeHazeColor(
positionES, // fragment position in eye coordinates
fragPositionWS, // fragment position in world coordinates
invViewMat[3].xyz, // eye position in world coordinates
lightDirection // keylight direction vector in world coordinates
);
color = mix(color.rgb, hazeColor.rgb, hazeColor.a);
}
<@endif@>
} }
return color; return color;
@ -181,8 +197,8 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur
<$declareLightingDirectional()$> <$declareLightingDirectional()$>
vec3 evalGlobalLightingAlphaBlended( vec3 evalGlobalLightingAlphaBlended(
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 normalWS, mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 normalWS,
vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity)
{ {
<$prepareGlobalLight(positionES, normalWS)$> <$prepareGlobalLight(positionES, normalWS)$>
@ -204,23 +220,29 @@ vec3 evalGlobalLightingAlphaBlended(
color += evalSpecularWithOpacity(ambientSpecular + directionalSpecular, opacity); color += evalSpecularWithOpacity(ambientSpecular + directionalSpecular, opacity);
// Haze // Haze
if ((isHazeEnabled() > 0.0) && (hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) { if (isHazeEnabled() > 0.0) {
vec4 hazeColor = computeHazeColor( if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
positionES, // fragment position in eye coordinates color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
fragPositionWS, // fragment position in world coordinates }
invViewMat[3].xyz, // eye position in world coordinates
lightDirection // keylight direction vector in world coordinates
);
color = mix(color.rgb, hazeColor.rgb, hazeColor.a); if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
vec4 hazeColor = computeHazeColor(
positionES, // fragment position in eye coordinates
fragPositionWS, // fragment position in world coordinates
invViewMat[3].xyz, // eye position in world coordinates
lightDirection // keylight direction vector in world coordinates
);
color = mix(color.rgb, hazeColor.rgb, hazeColor.a);
}
} }
return color; return color;
} }
vec3 evalGlobalLightingAlphaBlended( vec3 evalGlobalLightingAlphaBlended(
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 positionWS, mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 normalWS,
vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, SurfaceData surface, float opacity, vec3 prevLighting) vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, SurfaceData surface, float opacity, vec3 prevLighting)
{ {
<$fetchGlobalLight()$> <$fetchGlobalLight()$>
@ -241,15 +263,23 @@ vec3 evalGlobalLightingAlphaBlended(
color += evalSpecularWithOpacity(ambientSpecular + directionalSpecular, opacity); color += evalSpecularWithOpacity(ambientSpecular + directionalSpecular, opacity);
// Haze // Haze
if ((isHazeEnabled() > 0.0) && (hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) { if (isHazeEnabled() > 0.0) {
vec4 hazeColor = computeHazeColor( vec3 fragPositionWS = vec3(invViewMat * vec4(positionES, 1.0));
positionES, // fragment position in eye coordinates
positionWS, // fragment position in world coordinates
invViewMat[3].xyz, // eye position in world coordinates
lightDirection // keylight direction vector
);
color = mix(color.rgb, hazeColor.rgb, hazeColor.a); if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
}
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
vec4 hazeColor = computeHazeColor(
positionES, // fragment position in eye coordinates
fragPositionWS, // fragment position in world coordinates
invViewMat[3].xyz, // eye position in world coordinates
lightDirection // keylight direction vector in world coordinates
);
color = mix(color.rgb, hazeColor.rgb, hazeColor.a);
}
} }
return color; return color;

View file

@ -19,7 +19,7 @@
<@include LightingModel.slh@> <@include LightingModel.slh@>
<$declareLightBuffer()$> <$declareLightBuffer()$>
<@include Haze.slh@> <@include graphics/Haze.slh@>
LAYOUT(binding=RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH) uniform sampler2D linearDepthMap; LAYOUT(binding=RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH) uniform sampler2D linearDepthMap;

View file

@ -59,13 +59,21 @@ void DrawLayered3D::run(const RenderContextPointer& renderContext, const Inputs&
const auto& inItems = inputs.get0(); const auto& inItems = inputs.get0();
const auto& lightingModel = inputs.get1(); const auto& lightingModel = inputs.get1();
const auto jitter = inputs.get2(); const auto& hazeFrame = inputs.get2();
const auto jitter = inputs.get3();
config->setNumDrawn((int)inItems.size()); config->setNumDrawn((int)inItems.size());
emit config->numDrawnChanged(); emit config->numDrawnChanged();
RenderArgs* args = renderContext->args; RenderArgs* args = renderContext->args;
graphics::HazePointer haze;
const auto& hazeStage = renderContext->args->_scene->getStage<HazeStage>();
if (hazeStage && hazeFrame->_hazes.size() > 0) {
// We use _hazes.back() here because the last haze object will always have haze disabled.
haze = hazeStage->getHaze(hazeFrame->_hazes.back());
}
// Clear the framebuffer without stereo // Clear the framebuffer without stereo
// Needs to be distinct from the other batch because using the clear call // Needs to be distinct from the other batch because using the clear call
// while stereo is enabled triggers a warning // while stereo is enabled triggers a warning
@ -96,6 +104,10 @@ void DrawLayered3D::run(const RenderContextPointer& renderContext, const Inputs&
batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer());
batch.setResourceTexture(ru::Texture::AmbientFresnel, lightingModel->getAmbientFresnelLUT()); batch.setResourceTexture(ru::Texture::AmbientFresnel, lightingModel->getAmbientFresnelLUT());
if (haze) {
batch.setUniformBuffer(graphics::slot::buffer::Buffer::HazeParams, haze->getHazeParametersBuffer());
}
if (_opaquePass) { if (_opaquePass) {
renderStateSortShapes(renderContext, _shapePlumber, inItems, _maxDrawn); renderStateSortShapes(renderContext, _shapePlumber, inItems, _maxDrawn);
} else { } else {

View file

@ -11,10 +11,9 @@
#include <gpu/Pipeline.h> #include <gpu/Pipeline.h>
#include "LightStage.h" #include "LightStage.h"
#include "HazeStage.h"
#include "LightingModel.h" #include "LightingModel.h"
class BeginGPURangeTimer { class BeginGPURangeTimer {
public: public:
using JobModel = render::Job::ModelO<BeginGPURangeTimer, gpu::RangeTimerPointer>; using JobModel = render::Job::ModelO<BeginGPURangeTimer, gpu::RangeTimerPointer>;
@ -62,7 +61,7 @@ protected:
class DrawLayered3D { class DrawLayered3D {
public: public:
using Inputs = render::VaryingSet3<render::ItemBounds, LightingModelPointer, glm::vec2>; using Inputs = render::VaryingSet4<render::ItemBounds, LightingModelPointer, HazeStage::FramePointer, glm::vec2>;
using Config = DrawLayered3DConfig; using Config = DrawLayered3DConfig;
using JobModel = render::Job::ModelI<DrawLayered3D, Inputs, Config>; using JobModel = render::Job::ModelI<DrawLayered3D, Inputs, Config>;

View file

@ -207,7 +207,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
task.addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs); task.addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs);
// Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job // Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job
const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame).asVarying(); const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame, hazeFrame).asVarying();
task.addJob<DrawBackgroundStage>("DrawBackgroundDeferred", backgroundInputs); task.addJob<DrawBackgroundStage>("DrawBackgroundDeferred", backgroundInputs);
const auto drawHazeInputs = render::Varying(DrawHaze::Inputs(hazeFrame, lightingFramebuffer, linearDepthTarget, deferredFrameTransform, lightingModel, lightFrame)); const auto drawHazeInputs = render::Varying(DrawHaze::Inputs(hazeFrame, lightingFramebuffer, linearDepthTarget, deferredFrameTransform, lightingModel, lightFrame));
@ -225,8 +225,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
task.addJob<EndGPURangeTimer>("HighlightRangeTimer", outlineRangeTimer); task.addJob<EndGPURangeTimer>("HighlightRangeTimer", outlineRangeTimer);
// Layered Over (in front) // Layered Over (in front)
const auto inFrontOpaquesInputs = DrawLayered3D::Inputs(inFrontOpaque, lightingModel, jitter).asVarying(); const auto inFrontOpaquesInputs = DrawLayered3D::Inputs(inFrontOpaque, lightingModel, hazeFrame, jitter).asVarying();
const auto inFrontTransparentsInputs = DrawLayered3D::Inputs(inFrontTransparent, lightingModel, jitter).asVarying(); const auto inFrontTransparentsInputs = DrawLayered3D::Inputs(inFrontTransparent, lightingModel, hazeFrame, jitter).asVarying();
task.addJob<DrawLayered3D>("DrawInFrontOpaque", inFrontOpaquesInputs, true); task.addJob<DrawLayered3D>("DrawInFrontOpaque", inFrontOpaquesInputs, true);
task.addJob<DrawLayered3D>("DrawInFrontTransparent", inFrontTransparentsInputs, false); task.addJob<DrawLayered3D>("DrawInFrontTransparent", inFrontTransparentsInputs, false);
@ -254,7 +254,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
const auto primaryFramebuffer = task.addJob<render::UpsampleToBlitFramebuffer>("PrimaryBufferUpscale", toneMappedBuffer); const auto primaryFramebuffer = task.addJob<render::UpsampleToBlitFramebuffer>("PrimaryBufferUpscale", toneMappedBuffer);
// HUD Layer // HUD Layer
const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(primaryFramebuffer, lightingModel, hudOpaque, hudTransparent).asVarying(); const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(primaryFramebuffer, lightingModel, hudOpaque, hudTransparent, hazeFrame).asVarying();
task.addJob<RenderHUDLayerTask>("RenderHUDLayer", renderHUDLayerInputs); task.addJob<RenderHUDLayerTask>("RenderHUDLayer", renderHUDLayerInputs);
} }
@ -506,7 +506,7 @@ void RenderTransparentDeferred::run(const RenderContextPointer& renderContext, c
if (hazeStage && hazeFrame->_hazes.size() > 0) { if (hazeStage && hazeFrame->_hazes.size() > 0) {
const auto& hazePointer = hazeStage->getHaze(hazeFrame->_hazes.front()); const auto& hazePointer = hazeStage->getHaze(hazeFrame->_hazes.front());
if (hazePointer) { if (hazePointer) {
batch.setUniformBuffer(ru::Buffer::HazeParams, hazePointer->getHazeParametersBuffer()); batch.setUniformBuffer(graphics::slot::buffer::Buffer::HazeParams, hazePointer->getHazeParametersBuffer());
} }
} }

View file

@ -90,6 +90,7 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
const auto currentStageFrames = lightingStageInputs.get0(); const auto currentStageFrames = lightingStageInputs.get0();
const auto lightFrame = currentStageFrames[0]; const auto lightFrame = currentStageFrames[0];
const auto backgroundFrame = currentStageFrames[1]; const auto backgroundFrame = currentStageFrames[1];
const auto hazeFrame = currentStageFrames[2];
const auto& zones = lightingStageInputs[1]; const auto& zones = lightingStageInputs[1];
@ -111,21 +112,21 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
task.addJob<PrepareStencil>("PrepareStencil", scaledPrimaryFramebuffer); task.addJob<PrepareStencil>("PrepareStencil", scaledPrimaryFramebuffer);
// Draw opaques forward // Draw opaques forward
const auto opaqueInputs = DrawForward::Inputs(opaques, lightingModel).asVarying(); const auto opaqueInputs = DrawForward::Inputs(opaques, lightingModel, hazeFrame).asVarying();
task.addJob<DrawForward>("DrawOpaques", opaqueInputs, shapePlumber, true); task.addJob<DrawForward>("DrawOpaques", opaqueInputs, shapePlumber, true);
// Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job // Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job
const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame).asVarying(); const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame, hazeFrame).asVarying();
task.addJob<DrawBackgroundStage>("DrawBackgroundForward", backgroundInputs); task.addJob<DrawBackgroundStage>("DrawBackgroundForward", backgroundInputs);
// Draw transparent objects forward // Draw transparent objects forward
const auto transparentInputs = DrawForward::Inputs(transparents, lightingModel).asVarying(); const auto transparentInputs = DrawForward::Inputs(transparents, lightingModel, hazeFrame).asVarying();
task.addJob<DrawForward>("DrawTransparents", transparentInputs, shapePlumber, false); task.addJob<DrawForward>("DrawTransparents", transparentInputs, shapePlumber, false);
// Layered // Layered
const auto nullJitter = Varying(glm::vec2(0.0f, 0.0f)); const auto nullJitter = Varying(glm::vec2(0.0f, 0.0f));
const auto inFrontOpaquesInputs = DrawLayered3D::Inputs(inFrontOpaque, lightingModel, nullJitter).asVarying(); const auto inFrontOpaquesInputs = DrawLayered3D::Inputs(inFrontOpaque, lightingModel, hazeFrame, nullJitter).asVarying();
const auto inFrontTransparentsInputs = DrawLayered3D::Inputs(inFrontTransparent, lightingModel, nullJitter).asVarying(); const auto inFrontTransparentsInputs = DrawLayered3D::Inputs(inFrontTransparent, lightingModel, hazeFrame, nullJitter).asVarying();
task.addJob<DrawLayered3D>("DrawInFrontOpaque", inFrontOpaquesInputs, true); task.addJob<DrawLayered3D>("DrawInFrontOpaque", inFrontOpaquesInputs, true);
task.addJob<DrawLayered3D>("DrawInFrontTransparent", inFrontTransparentsInputs, false); task.addJob<DrawLayered3D>("DrawInFrontTransparent", inFrontTransparentsInputs, false);
@ -167,7 +168,7 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
const auto primaryFramebuffer = task.addJob<render::UpsampleToBlitFramebuffer>("PrimaryBufferUpscale", toneMappedBuffer); const auto primaryFramebuffer = task.addJob<render::UpsampleToBlitFramebuffer>("PrimaryBufferUpscale", toneMappedBuffer);
// HUD Layer // HUD Layer
const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(primaryFramebuffer, lightingModel, hudOpaque, hudTransparent).asVarying(); const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(primaryFramebuffer, lightingModel, hudOpaque, hudTransparent, hazeFrame).asVarying();
task.addJob<RenderHUDLayerTask>("RenderHUDLayer", renderHUDLayerInputs); task.addJob<RenderHUDLayerTask>("RenderHUDLayer", renderHUDLayerInputs);
} }
@ -258,11 +259,17 @@ void DrawForward::run(const RenderContextPointer& renderContext, const Inputs& i
const auto& inItems = inputs.get0(); const auto& inItems = inputs.get0();
const auto& lightingModel = inputs.get1(); const auto& lightingModel = inputs.get1();
const auto& hazeFrame = inputs.get2();
graphics::HazePointer haze;
const auto& hazeStage = renderContext->args->_scene->getStage<HazeStage>();
if (hazeStage && hazeFrame->_hazes.size() > 0) {
haze = hazeStage->getHaze(hazeFrame->_hazes.front());
}
gpu::doInBatch("DrawForward::run", args->_context, [&](gpu::Batch& batch) { gpu::doInBatch("DrawForward::run", args->_context, [&](gpu::Batch& batch) {
args->_batch = &batch; args->_batch = &batch;
// Setup projection // Setup projection
glm::mat4 projMat; glm::mat4 projMat;
Transform viewMat; Transform viewMat;
@ -276,6 +283,10 @@ void DrawForward::run(const RenderContextPointer& renderContext, const Inputs& i
batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer());
batch.setResourceTexture(ru::Texture::AmbientFresnel, lightingModel->getAmbientFresnelLUT()); batch.setResourceTexture(ru::Texture::AmbientFresnel, lightingModel->getAmbientFresnelLUT());
if (haze) {
batch.setUniformBuffer(graphics::slot::buffer::Buffer::HazeParams, haze->getHazeParametersBuffer());
}
// From the lighting model define a global shapeKey ORED with individiual keys // From the lighting model define a global shapeKey ORED with individiual keys
ShapeKey::Builder keyBuilder; ShapeKey::Builder keyBuilder;
if (lightingModel->isWireframeEnabled()) { if (lightingModel->isWireframeEnabled()) {

View file

@ -96,7 +96,7 @@ private:
class DrawForward{ class DrawForward{
public: public:
using Inputs = render::VaryingSet2<render::ItemBounds, LightingModelPointer>; using Inputs = render::VaryingSet3<render::ItemBounds, LightingModelPointer, HazeStage::FramePointer>;
using JobModel = render::Job::ModelI<DrawForward, Inputs>; using JobModel = render::Job::ModelI<DrawForward, Inputs>;
DrawForward(const render::ShapePlumberPointer& shapePlumber, bool opaquePass) : _shapePlumber(shapePlumber), _opaquePass(opaquePass) {} DrawForward(const render::ShapePlumberPointer& shapePlumber, bool opaquePass) : _shapePlumber(shapePlumber), _opaquePass(opaquePass) {}

View file

@ -47,14 +47,15 @@ void RenderHUDLayerTask::build(JobModel& task, const render::Varying& input, ren
const auto& lightingModel = inputs[1]; const auto& lightingModel = inputs[1];
const auto& hudOpaque = inputs[2]; const auto& hudOpaque = inputs[2];
const auto& hudTransparent = inputs[3]; const auto& hudTransparent = inputs[3];
const auto& hazeFrame = inputs[4];
// Composite the HUD and HUD overlays // Composite the HUD and HUD overlays
task.addJob<CompositeHUD>("HUD", primaryFramebuffer); task.addJob<CompositeHUD>("HUD", primaryFramebuffer);
// And HUD Layer objects // And HUD Layer objects
const auto nullJitter = Varying(glm::vec2(0.0f, 0.0f)); const auto nullJitter = Varying(glm::vec2(0.0f, 0.0f));
const auto hudOpaquesInputs = DrawLayered3D::Inputs(hudOpaque, lightingModel, nullJitter).asVarying(); const auto hudOpaquesInputs = DrawLayered3D::Inputs(hudOpaque, lightingModel, hazeFrame, nullJitter).asVarying();
const auto hudTransparentsInputs = DrawLayered3D::Inputs(hudTransparent, lightingModel, nullJitter).asVarying(); const auto hudTransparentsInputs = DrawLayered3D::Inputs(hudTransparent, lightingModel, hazeFrame, nullJitter).asVarying();
task.addJob<DrawLayered3D>("DrawHUDOpaque", hudOpaquesInputs, true); task.addJob<DrawLayered3D>("DrawHUDOpaque", hudOpaquesInputs, true);
task.addJob<DrawLayered3D>("DrawHUDTransparent", hudTransparentsInputs, false); task.addJob<DrawLayered3D>("DrawHUDTransparent", hudTransparentsInputs, false);
} }

View file

@ -10,7 +10,7 @@
#define hifi_RenderHUDLayerTask_h #define hifi_RenderHUDLayerTask_h
#include "LightingModel.h" #include "LightingModel.h"
#include "HazeStage.h"
class CompositeHUD { class CompositeHUD {
public: public:
@ -25,7 +25,7 @@ public:
class RenderHUDLayerTask { class RenderHUDLayerTask {
public: public:
// Framebuffer where to draw, lighting model, opaque items, transparent items // Framebuffer where to draw, lighting model, opaque items, transparent items
using Input = render::VaryingSet4<gpu::FramebufferPointer, LightingModelPointer, render::ItemBounds, render::ItemBounds>; using Input = render::VaryingSet5<gpu::FramebufferPointer, LightingModelPointer, render::ItemBounds, render::ItemBounds, HazeStage::FramePointer>;
using JobModel = render::Task::ModelI<RenderHUDLayerTask, Input>; using JobModel = render::Task::ModelI<RenderHUDLayerTask, Input>;
void build(JobModel& task, const render::Varying& input, render::Varying& output); void build(JobModel& task, const render::Varying& input, render::Varying& output);

View file

@ -15,7 +15,7 @@
<@include render-utils/ShaderConstants.h@> <@include render-utils/ShaderConstants.h@>
<@include GlobalLight.slh@> <@include GlobalLight.slh@>
<$declareEvalSkyboxGlobalColor(isScattering)$> <$declareEvalSkyboxGlobalColor(isScattering, _SCRIBE_NULL)$>
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01; layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
#define _texCoord0 _texCoord01.xy #define _texCoord0 _texCoord01.xy

View file

@ -15,7 +15,7 @@
<@include render-utils/ShaderConstants.h@> <@include render-utils/ShaderConstants.h@>
<@include GlobalLight.slh@> <@include GlobalLight.slh@>
<$declareEvalSkyboxGlobalColor(isScattering)$> <$declareEvalSkyboxGlobalColor(isScattering, _SCRIBE_NULL)$>
<@include Shadow.slh@> <@include Shadow.slh@>

View file

@ -26,7 +26,7 @@
<@endif@> <@endif@>
<$declareEvalGlobalLightingAlphaBlended()$> <$declareEvalGlobalLightingAlphaBlended()$>
<@else@> <@else@>
<$declareEvalSkyboxGlobalColor()$> <$declareEvalSkyboxGlobalColor(_SCRIBE_NULL, HIFI_USE_FORWARD)$>
<@endif@> <@endif@>
<@include gpu/Transform.slh@> <@include gpu/Transform.slh@>
<$declareStandardCameraTransform()$> <$declareStandardCameraTransform()$>
@ -195,6 +195,7 @@ void main(void) {
<@else@> <@else@>
vec3 fragNormalWS = _normalWS; vec3 fragNormalWS = _normalWS;
<@endif@> <@endif@>
fragNormalWS = normalize(fragNormalWS);
<@if HIFI_USE_FORWARD@> <@if HIFI_USE_FORWARD@>
TransformCamera cam = getTransformCamera(); TransformCamera cam = getTransformCamera();
@ -253,7 +254,7 @@ void main(void) {
<@if not HIFI_USE_TRANSLUCENT@> <@if not HIFI_USE_TRANSLUCENT@>
<@if not HIFI_USE_LIGHTMAP@> <@if not HIFI_USE_LIGHTMAP@>
packDeferredFragment( packDeferredFragment(
normalize(fragNormalWS), fragNormalWS,
opacity, opacity,
albedo, albedo,
roughness, roughness,
@ -267,7 +268,7 @@ void main(void) {
scattering); scattering);
<@else@> <@else@>
packDeferredFragmentLightmap( packDeferredFragmentLightmap(
normalize(fragNormalWS), fragNormalWS,
evalOpaqueFinalAlpha(getMaterialOpacity(mat), opacity), evalOpaqueFinalAlpha(getMaterialOpacity(mat), opacity),
albedo, albedo,
roughness, roughness,
@ -301,7 +302,7 @@ void main(void) {
1.0, 1.0,
occlusion, occlusion,
_positionES.xyz, _positionES.xyz,
fragPositionWS, fragNormalWS,
albedo, albedo,
fresnel, fresnel,
metallic, metallic,

View file

@ -68,7 +68,6 @@
#define RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT 12 #define RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT 12
// Haze // Haze
#define RENDER_UTILS_BUFFER_HAZE_PARAMS 7
#define RENDER_UTILS_TEXTURE_HAZE_COLOR 0 #define RENDER_UTILS_TEXTURE_HAZE_COLOR 0
#define RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH 1 #define RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH 1
@ -143,7 +142,6 @@ enum Buffer {
DeferredFrameTransform = RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM, DeferredFrameTransform = RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM,
LightModel = RENDER_UTILS_BUFFER_LIGHT_MODEL, LightModel = RENDER_UTILS_BUFFER_LIGHT_MODEL,
AmbientLight = RENDER_UTILS_BUFFER_AMBIENT_LIGHT, AmbientLight = RENDER_UTILS_BUFFER_AMBIENT_LIGHT,
HazeParams = RENDER_UTILS_BUFFER_HAZE_PARAMS,
FadeParameters = RENDER_UTILS_BUFFER_FADE_PARAMS, FadeParameters = RENDER_UTILS_BUFFER_FADE_PARAMS,
FadeObjectParameters = RENDER_UTILS_BUFFER_FADE_OBJECT_PARAMS, FadeObjectParameters = RENDER_UTILS_BUFFER_FADE_OBJECT_PARAMS,
LightClusterFrustumGrid = RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID, LightClusterFrustumGrid = RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID,

View file

@ -13,10 +13,10 @@
<@include DefaultMaterials.slh@> <@include DefaultMaterials.slh@>
<@include GlobalLight.slh@> <@include GlobalLight.slh@>
<@if HIFI_USE_FORWARD@> <@if HIFI_USE_TRANSLUCENT@>
<$declareEvalSkyboxGlobalColor()$>
<@else@>
<$declareEvalGlobalLightingAlphaBlended()$> <$declareEvalGlobalLightingAlphaBlended()$>
<@else@>
<$declareEvalSkyboxGlobalColor(_SCRIBE_NULL, HIFI_USE_FORWARD)$>
<@endif@> <@endif@>
<@include gpu/Transform.slh@> <@include gpu/Transform.slh@>
@ -65,19 +65,7 @@ void main() {
TransformCamera cam = getTransformCamera(); TransformCamera cam = getTransformCamera();
vec3 fragPosition = _positionES.xyz; vec3 fragPosition = _positionES.xyz;
<@if HIFI_USE_FORWARD@> <@if HIFI_USE_TRANSLUCENT@>
_fragColor0 = vec4(evalSkyboxGlobalColor(
cam._viewInverse,
1.0,
DEFAULT_OCCLUSION,
fragPosition,
normalize(_normalWS),
_color.rgb,
DEFAULT_FRESNEL,
DEFAULT_METALLIC,
DEFAULT_ROUGHNESS),
alpha);
<@else@>
_fragColor0 = vec4(evalGlobalLightingAlphaBlended( _fragColor0 = vec4(evalGlobalLightingAlphaBlended(
cam._viewInverse, cam._viewInverse,
1.0, 1.0,
@ -90,6 +78,18 @@ void main() {
DEFAULT_EMISSIVE, DEFAULT_EMISSIVE,
DEFAULT_ROUGHNESS, alpha), DEFAULT_ROUGHNESS, alpha),
alpha); alpha);
<@else@>
_fragColor0 = vec4(evalSkyboxGlobalColor(
cam._viewInverse,
1.0,
DEFAULT_OCCLUSION,
fragPosition,
normalize(_normalWS),
_color.rgb,
DEFAULT_FRESNEL,
DEFAULT_METALLIC,
DEFAULT_ROUGHNESS),
alpha);
<@endif@> <@endif@>
<@else@> <@else@>
packDeferredFragment( packDeferredFragment(

View file

@ -26,12 +26,12 @@
<@endif@> <@endif@>
<@if not HIFI_USE_UNLIT@> <@if not HIFI_USE_UNLIT@>
<@if HIFI_USE_FORWARD@> <@if HIFI_USE_TRANSLUCENT@>
<@include GlobalLight.slh@>
<$declareEvalSkyboxGlobalColor()$>
<@elif HIFI_USE_TRANSLUCENT@>
<@include GlobalLight.slh@> <@include GlobalLight.slh@>
<$declareEvalGlobalLightingAlphaBlended()$> <$declareEvalGlobalLightingAlphaBlended()$>
<@elif HIFI_USE_FORWARD@>
<@include GlobalLight.slh@>
<$declareEvalSkyboxGlobalColor(_SCRIBE_NULL, HIFI_USE_FORWARD)$>
<@else@> <@else@>
<@include DeferredBufferWrite.slh@> <@include DeferredBufferWrite.slh@>
<@endif@> <@endif@>
@ -88,19 +88,7 @@ void main(void) {
<@endif@> <@endif@>
<@if not HIFI_USE_UNLIT@> <@if not HIFI_USE_UNLIT@>
<@if HIFI_USE_FORWARD@> <@if HIFI_USE_TRANSLUCENT@>
_fragColor0 = vec4(evalSkyboxGlobalColor(
cam._viewInverse,
1.0,
DEFAULT_OCCLUSION,
fragPosition,
normalize(_normalWS) * (2.0 * float(gl_FrontFacing) - 1.0),
texel.rgb,
fresnel,
metallic,
DEFAULT_ROUGHNESS),
texel.a);
<@elif HIFI_USE_TRANSLUCENT@>
_fragColor0 = vec4(evalGlobalLightingAlphaBlended( _fragColor0 = vec4(evalGlobalLightingAlphaBlended(
cam._viewInverse, cam._viewInverse,
1.0, 1.0,
@ -117,6 +105,18 @@ void main(void) {
, ,
DEFAULT_ROUGHNESS, texel.a), DEFAULT_ROUGHNESS, texel.a),
texel.a); texel.a);
<@elif HIFI_USE_FORWARD@>
_fragColor0 = vec4(evalSkyboxGlobalColor(
cam._viewInverse,
1.0,
DEFAULT_OCCLUSION,
fragPosition,
normalize(_normalWS) * (2.0 * float(gl_FrontFacing) - 1.0),
texel.rgb,
fresnel,
metallic,
DEFAULT_ROUGHNESS),
texel.a);
<@else@> <@else@>
packDeferredFragment( packDeferredFragment(
normalize(_normalWS) * (2.0 * float(gl_FrontFacing) - 1.0), normalize(_normalWS) * (2.0 * float(gl_FrontFacing) - 1.0),

View file

@ -21,7 +21,9 @@
LAYOUT(binding=0) uniform sampler2D webTexture; LAYOUT(binding=0) uniform sampler2D webTexture;
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS; <@if not HIFI_USE_FORWARD@>
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
<@endif@>
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color; layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01; layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
#define _texCoord0 _texCoord01.xy #define _texCoord0 _texCoord01.xy

View file

@ -17,7 +17,9 @@
<@include render-utils/ShaderConstants.h@> <@include render-utils/ShaderConstants.h@>
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS; <@if not HIFI_USE_FORWARD@>
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
<@endif@>
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color; layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01; layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
@ -28,5 +30,8 @@ void main(void) {
TransformCamera cam = getTransformCamera(); TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject(); TransformObject obj = getTransformObject();
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$> <$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
<@if not HIFI_USE_FORWARD@>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$> <$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
<@endif@>
} }

View file

@ -104,7 +104,7 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p
locations->fadeMaskTextureUnit = reflection.validTexture(render_utils::slot::texture::FadeMask); locations->fadeMaskTextureUnit = reflection.validTexture(render_utils::slot::texture::FadeMask);
locations->fadeParameterBufferUnit = reflection.validUniformBuffer(render_utils::slot::buffer::FadeParameters); locations->fadeParameterBufferUnit = reflection.validUniformBuffer(render_utils::slot::buffer::FadeParameters);
locations->fadeObjectParameterBufferUnit = reflection.validUniformBuffer(render_utils::slot::buffer::FadeObjectParameters); locations->fadeObjectParameterBufferUnit = reflection.validUniformBuffer(render_utils::slot::buffer::FadeObjectParameters);
locations->hazeParameterBufferUnit = reflection.validUniformBuffer(render_utils::slot::buffer::HazeParams); locations->hazeParameterBufferUnit = reflection.validUniformBuffer(graphics::slot::buffer::HazeParams);
if (key.isTranslucent()) { if (key.isTranslucent()) {
locations->lightClusterGridBufferUnit = reflection.validUniformBuffer(render_utils::slot::buffer::LightClusterGrid); locations->lightClusterGridBufferUnit = reflection.validUniformBuffer(render_utils::slot::buffer::LightClusterGrid);
locations->lightClusterContentBufferUnit = reflection.validUniformBuffer(render_utils::slot::buffer::LightClusterContent); locations->lightClusterContentBufferUnit = reflection.validUniformBuffer(render_utils::slot::buffer::LightClusterContent);
@ -134,7 +134,7 @@ const ShapePipelinePointer ShapePlumber::pickPipeline(RenderArgs* args, const Ke
auto factoryIt = ShapePipeline::_globalCustomFactoryMap.find(key.getCustom()); auto factoryIt = ShapePipeline::_globalCustomFactoryMap.find(key.getCustom());
if ((factoryIt != ShapePipeline::_globalCustomFactoryMap.end()) && (factoryIt)->second) { if ((factoryIt != ShapePipeline::_globalCustomFactoryMap.end()) && (factoryIt)->second) {
// found a factory for the custom key, can now generate a shape pipeline for this case: // found a factory for the custom key, can now generate a shape pipeline for this case:
addPipelineHelper(Filter(key), key, 0, (factoryIt)->second(*this, key, *(args->_batch))); addPipelineHelper(Filter(key), key, 0, (factoryIt)->second(*this, key, args));
return pickPipeline(args, key); return pickPipeline(args, key);
} else { } else {

View file

@ -272,7 +272,7 @@ protected:
ItemSetter _itemSetter; ItemSetter _itemSetter;
public: public:
using CustomKey = uint8_t; using CustomKey = uint8_t;
using CustomFactory = std::function<std::shared_ptr<ShapePipeline> (const ShapePlumber& plumber, const ShapeKey& key, gpu::Batch& batch)>; using CustomFactory = std::function<std::shared_ptr<ShapePipeline> (const ShapePlumber& plumber, const ShapeKey& key, RenderArgs* args)>;
using CustomFactoryMap = std::map<CustomKey, CustomFactory>; using CustomFactoryMap = std::map<CustomKey, CustomFactory>;
static CustomFactoryMap _globalCustomFactoryMap; static CustomFactoryMap _globalCustomFactoryMap;