mirror of
https://github.com/overte-org/overte.git
synced 2025-08-11 23:22:58 +02:00
fix view + projection, texture flipping, billboarding
This commit is contained in:
parent
89e6cbbfa4
commit
10de1288c2
26 changed files with 118 additions and 85 deletions
|
@ -3530,8 +3530,9 @@ bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
||||||
bool firstPerson = qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON_LOOK_AT ||
|
bool firstPerson = qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON_LOOK_AT ||
|
||||||
qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON;
|
qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON;
|
||||||
bool overrideAnim = _skeletonModel ? _skeletonModel->getRig().isPlayingOverrideAnimation() : false;
|
bool overrideAnim = _skeletonModel ? _skeletonModel->getRig().isPlayingOverrideAnimation() : false;
|
||||||
|
bool isInMirror = renderArgs->_mirrorDepth > 0;
|
||||||
bool insideHead = cameraInsideHead(renderArgs->getViewFrustum().getPosition());
|
bool insideHead = cameraInsideHead(renderArgs->getViewFrustum().getPosition());
|
||||||
return !defaultMode || (!firstPerson && !insideHead) || (overrideAnim && !insideHead);
|
return !defaultMode || isInMirror || (!firstPerson && !insideHead) || (overrideAnim && !insideHead);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::setRotationRecenterFilterLength(float length) {
|
void MyAvatar::setRotationRecenterFilterLength(float length) {
|
||||||
|
|
|
@ -227,39 +227,13 @@ bool EntityRenderer::passesZoneOcclusionTest(const std::unordered_set<QUuid>& co
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityRenderer::computeMirrorView(ViewFrustum& viewFrustum) const {
|
void EntityRenderer::computeMirrorView(ViewFrustum& viewFrustum) const {
|
||||||
//glm::vec3 mirrorPosition;
|
|
||||||
//glm::quat mirrorRotation;
|
|
||||||
//withReadLock([&]{
|
|
||||||
// mirrorPosition = _entity->getWorldPosition();
|
|
||||||
// mirrorRotation = _entity->getWorldOrientation();
|
|
||||||
//});
|
|
||||||
|
|
||||||
//glm::mat4 mirrorToWorld = glm::translate(mirrorPosition) * glm::mat4_cast(mirrorRotation);
|
|
||||||
//glm::mat4 worldToMirror = glm::inverse(mirrorToWorld);
|
|
||||||
|
|
||||||
//// get mirror camera position by reflecting main camera position's z coordinate in mirror space
|
|
||||||
//glm::vec3 cameraPosition = viewFrustum.getPosition();
|
|
||||||
//glm::quat cameraRotation = viewFrustum.getOrientation();
|
|
||||||
//glm::vec3 localCameraPosition = glm::vec3(worldToMirror * glm::vec4(cameraPosition, 1.0f));
|
|
||||||
//localCameraPosition.z *= -1.0f;
|
|
||||||
//glm::quat localCameraRotation = worldToMirror * glm::mat4_cast(cameraRotation);
|
|
||||||
//glm::vec3 localCameraRotationAngles = glm::eulerAngles(localCameraRotation);
|
|
||||||
//localCameraRotationAngles.y = M_PI - localCameraRotationAngles.y;
|
|
||||||
|
|
||||||
//viewFrustum.setPosition(mirrorToWorld * glm::vec4(localCameraPosition, 1.0f));
|
|
||||||
//viewFrustum.setOrientation(mirrorToWorld * glm::mat4_cast(glm::quat(localCameraRotationAngles)));
|
|
||||||
|
|
||||||
glm::vec3 mirrorPropertiesPosition;
|
glm::vec3 mirrorPropertiesPosition;
|
||||||
glm::quat mirrorPropertiesRotation;
|
glm::quat mirrorPropertiesRotation;
|
||||||
glm::vec3 mirrorPropertiesDimensions;
|
|
||||||
withReadLock([&]{
|
withReadLock([&]{
|
||||||
mirrorPropertiesPosition = _entity->getWorldPosition();
|
mirrorPropertiesPosition = _entity->getWorldPosition();
|
||||||
mirrorPropertiesRotation = _entity->getWorldOrientation();
|
mirrorPropertiesRotation = _entity->getWorldOrientation();
|
||||||
mirrorPropertiesDimensions = _entity->getScaledDimensions();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
glm::vec3 halfMirrorPropertiesDimensions = 0.5f * mirrorPropertiesDimensions;
|
|
||||||
|
|
||||||
glm::mat4 worldFromMirrorRotation = glm::mat4_cast(mirrorPropertiesRotation);
|
glm::mat4 worldFromMirrorRotation = glm::mat4_cast(mirrorPropertiesRotation);
|
||||||
glm::mat4 worldFromMirrorTranslation = glm::translate(mirrorPropertiesPosition);
|
glm::mat4 worldFromMirrorTranslation = glm::translate(mirrorPropertiesPosition);
|
||||||
glm::mat4 worldFromMirror = worldFromMirrorTranslation * worldFromMirrorRotation;
|
glm::mat4 worldFromMirror = worldFromMirrorTranslation * worldFromMirrorRotation;
|
||||||
|
@ -275,19 +249,47 @@ void EntityRenderer::computeMirrorView(ViewFrustum& viewFrustum) const {
|
||||||
// get mirror camera rotation by reflecting main camera rotation in mirror space
|
// get mirror camera rotation by reflecting main camera rotation in mirror space
|
||||||
// TODO: we are assuming here that UP is world y-axis
|
// TODO: we are assuming here that UP is world y-axis
|
||||||
glm::quat mainCameraRotationWorld = viewFrustum.getOrientation();
|
glm::quat mainCameraRotationWorld = viewFrustum.getOrientation();
|
||||||
glm::mat4 mainCameraRotationMirror = mirrorFromWorld * glm::mat4_cast(mainCameraRotationWorld);
|
glm::quat mainCameraRotationMirror = mirrorFromWorld * glm::mat4_cast(mainCameraRotationWorld);
|
||||||
glm::mat4 mirrorCameraRotationMirror = mainCameraRotationMirror;// * glm::scale(vec3(-1.0f, 1.0f, -1.0f));
|
glm::quat mirrorCameraRotationMirror = glm::quat(mainCameraRotationMirror.w, -mainCameraRotationMirror.x, -mainCameraRotationMirror.y, mainCameraRotationMirror.z) *
|
||||||
glm::quat mirrorCameraRotationWorld = worldFromMirror * mirrorCameraRotationMirror;
|
glm::angleAxis((float)M_PI, glm::vec3(0, 1, 0));
|
||||||
|
glm::quat mirrorCameraRotationWorld = worldFromMirror * glm::mat4_cast(mirrorCameraRotationMirror);
|
||||||
|
|
||||||
viewFrustum.setPosition(mirrorCameraPositionWorld);
|
viewFrustum.setPosition(mirrorCameraPositionWorld);
|
||||||
viewFrustum.setOrientation(mirrorCameraRotationWorld);
|
viewFrustum.setOrientation(mirrorCameraRotationWorld);
|
||||||
|
|
||||||
// build frustum using mirror space translation of mirrored camera
|
// modify the near clip plane to be the XY plane of the mirror
|
||||||
//float nearClip = mirrorCameraPositionMirror.z + mirrorPropertiesDimensions.z * 2.0f;
|
// from: https://terathon.com/lengyel/Lengyel-Oblique.pdf
|
||||||
//glm::vec3 upperRight = halfMirrorPropertiesDimensions - mirrorCameraPositionMirror;
|
glm::mat4 view = viewFrustum.getView();
|
||||||
//glm::vec3 bottomLeft = -halfMirrorPropertiesDimensions - mirrorCameraPositionMirror;
|
glm::mat4 projection = viewFrustum.getProjection();
|
||||||
//glm::mat4 frustum = glm::frustum(bottomLeft.x, upperRight.x, bottomLeft.y, upperRight.y, nearClip, viewFrustum.getFarClip());
|
|
||||||
//viewFrustum.setProjection(frustum);
|
//Find the camera-space 4D reflection plane vector
|
||||||
|
glm::vec3 cameraSpacePosition = glm::inverse(view) * glm::vec4(mirrorPropertiesPosition, 1.0f);
|
||||||
|
glm::vec3 cameraSpaceNormal = glm::transpose(view) * (worldFromMirrorRotation * glm::vec4(0, 0, -1, 0));
|
||||||
|
glm::vec4 clipPlane = glm::vec4(cameraSpaceNormal, -glm::dot(cameraSpaceNormal, cameraSpacePosition));
|
||||||
|
if (clipPlane.w > 0.0f) {
|
||||||
|
clipPlane *= -1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the clip-space corner point opposite the clipping plane
|
||||||
|
// as (sign(clipPlane.x), sign(clipPlane.y), 1, 1) and
|
||||||
|
// transform it into camera space by multiplying it
|
||||||
|
// by the inverse of the projection matrix
|
||||||
|
glm::vec4 q;
|
||||||
|
q.x = (glm::sign(clipPlane.x) + projection[0][2]) / projection[0][0];
|
||||||
|
q.y = (glm::sign(clipPlane.y) + projection[1][2]) / projection[1][1];
|
||||||
|
q.z = -1.0f;
|
||||||
|
q.w = (1.0f + projection[2][2]) / projection[2][3];
|
||||||
|
|
||||||
|
// Calculate the scaled plane vector
|
||||||
|
glm::vec4 c = (2.0f / glm::dot(clipPlane, q)) * clipPlane;
|
||||||
|
|
||||||
|
// Replace the third row of the projection matrix
|
||||||
|
projection[0][2] = c.x;
|
||||||
|
projection[1][2] = c.y;
|
||||||
|
projection[2][2] = c.z + 1.0f;
|
||||||
|
projection[3][2] = c.w;
|
||||||
|
|
||||||
|
viewFrustum.setProjection(projection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityRenderer::render(RenderArgs* args) {
|
void EntityRenderer::render(RenderArgs* args) {
|
||||||
|
@ -295,7 +297,7 @@ void EntityRenderer::render(RenderArgs* args) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_visible && (args->_renderMode != RenderArgs::RenderMode::DEFAULT_RENDER_MODE || !_cauterized)) {
|
if (_visible && (!_cauterized || args->_renderMode != RenderArgs::RenderMode::DEFAULT_RENDER_MODE || args->_mirrorDepth > 0)) {
|
||||||
doRender(args);
|
doRender(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,8 +263,9 @@ void GizmoEntityRenderer::doRender(RenderArgs* args) {
|
||||||
|
|
||||||
bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES;
|
bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES;
|
||||||
|
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition(), true));
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition(), true));
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
Pipeline pipelineType = getPipelineType(materials);
|
Pipeline pipelineType = getPipelineType(materials);
|
||||||
|
|
|
@ -103,8 +103,9 @@ void GridEntityRenderer::doRender(RenderArgs* args) {
|
||||||
} else {
|
} else {
|
||||||
transform.setTranslation(renderTransform.getTranslation());
|
transform.setTranslation(renderTransform.getTranslation());
|
||||||
}
|
}
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||||
batch->setModelTransform(transform);
|
batch->setModelTransform(transform);
|
||||||
|
|
||||||
auto minCorner = glm::vec2(-0.5f, -0.5f);
|
auto minCorner = glm::vec2(-0.5f, -0.5f);
|
||||||
|
|
|
@ -147,8 +147,9 @@ void ImageEntityRenderer::doRender(RenderArgs* args) {
|
||||||
|
|
||||||
gpu::Batch* batch = args->_batch;
|
gpu::Batch* batch = args->_batch;
|
||||||
|
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||||
|
|
||||||
float imageWidth = _texture->getWidth();
|
float imageWidth = _texture->getWidth();
|
||||||
float imageHeight = _texture->getHeight();
|
float imageHeight = _texture->getHeight();
|
||||||
|
|
|
@ -47,8 +47,9 @@ void LineEntityRenderer::doRender(RenderArgs* args) {
|
||||||
const auto& modelTransform = getModelTransform();
|
const auto& modelTransform = getModelTransform();
|
||||||
Transform transform = Transform();
|
Transform transform = Transform();
|
||||||
transform.setTranslation(modelTransform.getTranslation());
|
transform.setTranslation(modelTransform.getTranslation());
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
transform.setRotation(BillboardModeHelpers::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), _billboardMode,
|
transform.setRotation(BillboardModeHelpers::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), _billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
if (_linePoints.size() > 1) {
|
if (_linePoints.size() > 1) {
|
||||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, false, false, false, true,
|
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, false, false, false, true,
|
||||||
|
|
|
@ -303,8 +303,9 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) {
|
||||||
proceduralRender = true;
|
proceduralRender = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
if (!proceduralRender) {
|
if (!proceduralRender) {
|
||||||
|
|
|
@ -325,8 +325,9 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
|
||||||
buildPipelines();
|
buildPipelines();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
batch.setPipeline(_pipelines[{args->_renderMethod, isTransparent()}]);
|
batch.setPipeline(_pipelines[{args->_renderMethod, isTransparent()}]);
|
||||||
|
|
|
@ -1860,8 +1860,9 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) {
|
||||||
PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
|
PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
|
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
glm::mat4 rotation = glm::mat4_cast(BillboardModeHelpers::getBillboardRotation(_position, _orientation, _billboardMode,
|
glm::mat4 rotation = glm::mat4_cast(BillboardModeHelpers::getBillboardRotation(_position, _orientation, _billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||||
Transform transform(glm::translate(_position) * rotation * _lastVoxelToLocalMatrix);
|
Transform transform(glm::translate(_position) * rotation * _lastVoxelToLocalMatrix);
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
|
|
|
@ -118,8 +118,9 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
||||||
|
|
||||||
bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES;
|
bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES;
|
||||||
|
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition(),
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition(),
|
||||||
_shape < entity::Shape::Cube || _shape > entity::Shape::Icosahedron));
|
_shape < entity::Shape::Cube || _shape > entity::Shape::Icosahedron));
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
|
|
|
@ -164,8 +164,9 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
||||||
transform = _renderTransform;
|
transform = _renderTransform;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
Pipeline pipelineType = getPipelineType(materials);
|
Pipeline pipelineType = getPipelineType(materials);
|
||||||
|
@ -352,8 +353,9 @@ void entities::TextPayload::render(RenderArgs* args) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), textRenderable->_billboardMode,
|
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), textRenderable->_billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||||
|
|
||||||
float scale = textRenderable->_lineHeight / textRenderer->getFontSize();
|
float scale = textRenderable->_lineHeight / textRenderer->getFontSize();
|
||||||
transform.postTranslate(glm::vec3(-0.5, 0.5, 1.0f + EPSILON / dimensions.z));
|
transform.postTranslate(glm::vec3(-0.5, 0.5, 1.0f + EPSILON / dimensions.z));
|
||||||
|
|
|
@ -320,8 +320,9 @@ void WebEntityRenderer::doRender(RenderArgs* args) {
|
||||||
|
|
||||||
batch.setResourceTexture(0, _texture);
|
batch.setResourceTexture(0, _texture);
|
||||||
|
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
// Turn off jitter for these entities
|
// Turn off jitter for these entities
|
||||||
|
|
|
@ -71,14 +71,15 @@ void CauterizedMeshPartPayload::updateTransformForCauterizedMesh(const Transform
|
||||||
_cauterizedTransform = renderTransform;
|
_cauterizedTransform = renderTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CauterizedMeshPartPayload::bindTransform(gpu::Batch& batch, const Transform& transform, RenderArgs::RenderMode renderMode) const {
|
void CauterizedMeshPartPayload::bindTransform(gpu::Batch& batch, const Transform& transform, RenderArgs::RenderMode renderMode, size_t mirrorDepth) const {
|
||||||
bool useCauterizedMesh = (renderMode != RenderArgs::RenderMode::SHADOW_RENDER_MODE && renderMode != RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) && _enableCauterization;
|
bool useCauterizedMesh = _enableCauterization && (renderMode != RenderArgs::RenderMode::SHADOW_RENDER_MODE && renderMode != RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) &&
|
||||||
|
mirrorDepth == 0;
|
||||||
if (useCauterizedMesh) {
|
if (useCauterizedMesh) {
|
||||||
if (_cauterizedClusterBuffer) {
|
if (_cauterizedClusterBuffer) {
|
||||||
batch.setUniformBuffer(graphics::slot::buffer::Skinning, _cauterizedClusterBuffer);
|
batch.setUniformBuffer(graphics::slot::buffer::Skinning, _cauterizedClusterBuffer);
|
||||||
}
|
}
|
||||||
batch.setModelTransform(_cauterizedTransform);
|
batch.setModelTransform(_cauterizedTransform);
|
||||||
} else {
|
} else {
|
||||||
ModelMeshPartPayload::bindTransform(batch, transform, renderMode);
|
ModelMeshPartPayload::bindTransform(batch, transform, renderMode, mirrorDepth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
|
|
||||||
void updateTransformForCauterizedMesh(const Transform& modelTransform, const Model::MeshState& meshState, bool useDualQuaternionSkinning);
|
void updateTransformForCauterizedMesh(const Transform& modelTransform, const Model::MeshState& meshState, bool useDualQuaternionSkinning);
|
||||||
|
|
||||||
void bindTransform(gpu::Batch& batch, const Transform& transform, RenderArgs::RenderMode renderMode) const override;
|
void bindTransform(gpu::Batch& batch, const Transform& transform, RenderArgs::RenderMode renderMode, size_t mirrorDepth) const override;
|
||||||
|
|
||||||
void setEnableCauterization(bool enableCauterization) { _enableCauterization = enableCauterization; }
|
void setEnableCauterization(bool enableCauterization) { _enableCauterization = enableCauterization; }
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) {
|
||||||
batch.setInputStream(0, _drawMesh->getVertexStream());
|
batch.setInputStream(0, _drawMesh->getVertexStream());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const Transform& transform, RenderArgs::RenderMode renderMode) const {
|
void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const Transform& transform, RenderArgs::RenderMode renderMode, size_t mirrorDepth) const {
|
||||||
if (_clusterBuffer) {
|
if (_clusterBuffer) {
|
||||||
batch.setUniformBuffer(graphics::slot::buffer::Skinning, _clusterBuffer);
|
batch.setUniformBuffer(graphics::slot::buffer::Skinning, _clusterBuffer);
|
||||||
}
|
}
|
||||||
|
@ -300,8 +300,9 @@ Item::Bound ModelMeshPartPayload::getBound(RenderArgs* args) const {
|
||||||
auto worldBound = _adjustedLocalBound;
|
auto worldBound = _adjustedLocalBound;
|
||||||
auto parentTransform = _parentTransform;
|
auto parentTransform = _parentTransform;
|
||||||
if (args) {
|
if (args) {
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
parentTransform.setRotation(BillboardModeHelpers::getBillboardRotation(parentTransform.getTranslation(), parentTransform.getRotation(), _billboardMode,
|
parentTransform.setRotation(BillboardModeHelpers::getBillboardRotation(parentTransform.getTranslation(), parentTransform.getRotation(), _billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||||
}
|
}
|
||||||
worldBound.transform(parentTransform);
|
worldBound.transform(parentTransform);
|
||||||
return worldBound;
|
return worldBound;
|
||||||
|
@ -314,18 +315,19 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
||||||
void ModelMeshPartPayload::render(RenderArgs* args) {
|
void ModelMeshPartPayload::render(RenderArgs* args) {
|
||||||
PerformanceTimer perfTimer("ModelMeshPartPayload::render");
|
PerformanceTimer perfTimer("ModelMeshPartPayload::render");
|
||||||
|
|
||||||
if (!args || (args->_renderMode == RenderArgs::RenderMode::DEFAULT_RENDER_MODE && _cauterized)) {
|
if (!args || (_cauterized && args->_renderMode == RenderArgs::RenderMode::DEFAULT_RENDER_MODE && args->_mirrorDepth == 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::Batch& batch = *(args->_batch);
|
gpu::Batch& batch = *(args->_batch);
|
||||||
|
|
||||||
Transform transform = _parentTransform;
|
Transform transform = _parentTransform;
|
||||||
|
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||||
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||||
|
|
||||||
Transform modelTransform = transform.worldTransform(_localTransform);
|
Transform modelTransform = transform.worldTransform(_localTransform);
|
||||||
bindTransform(batch, modelTransform, args->_renderMode);
|
bindTransform(batch, modelTransform, args->_renderMode, args->_mirrorDepth);
|
||||||
|
|
||||||
//Bind the index buffer and vertex buffer and Blend shapes if needed
|
//Bind the index buffer and vertex buffer and Blend shapes if needed
|
||||||
bindMesh(batch);
|
bindMesh(batch);
|
||||||
|
|
|
@ -37,7 +37,7 @@ public:
|
||||||
|
|
||||||
// ModelMeshPartPayload functions to perform render
|
// ModelMeshPartPayload functions to perform render
|
||||||
void bindMesh(gpu::Batch& batch);
|
void bindMesh(gpu::Batch& batch);
|
||||||
virtual void bindTransform(gpu::Batch& batch, const Transform& transform, RenderArgs::RenderMode renderMode) const;
|
virtual void bindTransform(gpu::Batch& batch, const Transform& transform, RenderArgs::RenderMode renderMode, size_t mirrorDepth) const;
|
||||||
void drawCall(gpu::Batch& batch) const;
|
void drawCall(gpu::Batch& batch) const;
|
||||||
|
|
||||||
void updateKey(const render::ItemKey& key);
|
void updateKey(const render::ItemKey& key);
|
||||||
|
|
|
@ -277,7 +277,7 @@ public:
|
||||||
using Outputs = render::VaryingSet4<render::ItemBound, gpu::FramebufferPointer, RenderArgsPointer, glm::vec2>;
|
using Outputs = render::VaryingSet4<render::ItemBound, gpu::FramebufferPointer, RenderArgsPointer, glm::vec2>;
|
||||||
using JobModel = render::Job::ModelIO<SetupMirrorTask, Input, Outputs>;
|
using JobModel = render::Job::ModelIO<SetupMirrorTask, Input, Outputs>;
|
||||||
|
|
||||||
SetupMirrorTask(size_t mirrorIndex) : _mirrorIndex(mirrorIndex) {}
|
SetupMirrorTask(size_t mirrorIndex, size_t depth) : _mirrorIndex(mirrorIndex), _depth(depth) {}
|
||||||
|
|
||||||
void run(const render::RenderContextPointer& renderContext, const Input& inputs, Outputs& outputs) {
|
void run(const render::RenderContextPointer& renderContext, const Input& inputs, Outputs& outputs) {
|
||||||
auto args = renderContext->args;
|
auto args = renderContext->args;
|
||||||
|
@ -293,12 +293,17 @@ public:
|
||||||
_mirrorFramebuffer.reset(gpu::Framebuffer::create("mirror" + _mirrorIndex, gpu::Element::COLOR_SRGBA_32, inputFramebuffer->getWidth(), inputFramebuffer->getHeight()));
|
_mirrorFramebuffer.reset(gpu::Framebuffer::create("mirror" + _mirrorIndex, gpu::Element::COLOR_SRGBA_32, inputFramebuffer->getWidth(), inputFramebuffer->getHeight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
render::ItemBound mirror = items[_mirrorIndex];
|
||||||
|
|
||||||
_cachedArgsPointer->_renderMode = args->_renderMode;
|
_cachedArgsPointer->_renderMode = args->_renderMode;
|
||||||
_cachedArgsPointer->_blitFramebuffer = args->_blitFramebuffer;
|
_cachedArgsPointer->_blitFramebuffer = args->_blitFramebuffer;
|
||||||
args->_renderMode = RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE;
|
_cachedArgsPointer->_ignoreItem = args->_ignoreItem;
|
||||||
args->_blitFramebuffer = _mirrorFramebuffer;
|
_cachedArgsPointer->_mirrorDepth = args->_mirrorDepth;
|
||||||
|
|
||||||
|
args->_blitFramebuffer = _mirrorFramebuffer;
|
||||||
|
args->_ignoreItem = mirror.id;
|
||||||
|
args->_mirrorDepth = _depth;
|
||||||
|
|
||||||
render::ItemBound mirror = items[_mirrorIndex];
|
|
||||||
ViewFrustum srcViewFrustum = args->getViewFrustum();
|
ViewFrustum srcViewFrustum = args->getViewFrustum();
|
||||||
args->_scene->getItem(mirror.id).computeMirrorView(srcViewFrustum);
|
args->_scene->getItem(mirror.id).computeMirrorView(srcViewFrustum);
|
||||||
|
|
||||||
|
@ -317,6 +322,7 @@ protected:
|
||||||
gpu::FramebufferPointer _mirrorFramebuffer { nullptr };
|
gpu::FramebufferPointer _mirrorFramebuffer { nullptr };
|
||||||
RenderArgsPointer _cachedArgsPointer { std::make_shared<RenderArgs>() };
|
RenderArgsPointer _cachedArgsPointer { std::make_shared<RenderArgs>() };
|
||||||
size_t _mirrorIndex;
|
size_t _mirrorIndex;
|
||||||
|
size_t _depth;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -377,6 +383,8 @@ public:
|
||||||
// Restore the blit framebuffer after we've sampled from it
|
// Restore the blit framebuffer after we've sampled from it
|
||||||
if (cachedArgs) {
|
if (cachedArgs) {
|
||||||
args->_blitFramebuffer = cachedArgs->_blitFramebuffer;
|
args->_blitFramebuffer = cachedArgs->_blitFramebuffer;
|
||||||
|
args->_ignoreItem = cachedArgs->_ignoreItem;
|
||||||
|
args->_mirrorDepth = cachedArgs->_mirrorDepth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,9 +397,10 @@ ShapePlumberPointer DrawMirrorTask::_forwardPipelines = std::make_shared<ShapePl
|
||||||
ShapePlumberPointer DrawMirrorTask::_deferredPipelines = std::make_shared<ShapePlumber>();
|
ShapePlumberPointer DrawMirrorTask::_deferredPipelines = std::make_shared<ShapePlumber>();
|
||||||
|
|
||||||
void RenderMirrorTask::build(JobModel& task, const render::Varying& inputs, render::Varying& output, size_t mirrorIndex, render::CullFunctor cullFunctor, size_t depth) {
|
void RenderMirrorTask::build(JobModel& task, const render::Varying& inputs, render::Varying& output, size_t mirrorIndex, render::CullFunctor cullFunctor, size_t depth) {
|
||||||
const auto setupOutput = task.addJob<SetupMirrorTask>("SetupMirror" + std::to_string(mirrorIndex) + "Depth" + std::to_string(depth), inputs, mirrorIndex);
|
size_t nextDepth = depth + 1;
|
||||||
|
const auto setupOutput = task.addJob<SetupMirrorTask>("SetupMirror" + std::to_string(mirrorIndex) + "Depth" + std::to_string(depth), inputs, mirrorIndex, nextDepth);
|
||||||
|
|
||||||
task.addJob<RenderViewTask>("RenderMirrorView" + std::to_string(mirrorIndex) + "Depth" + std::to_string(depth), cullFunctor, render::ItemKey::TAG_BITS_1, render::ItemKey::TAG_BITS_1, depth + 1);
|
task.addJob<RenderViewTask>("RenderMirrorView" + std::to_string(mirrorIndex) + "Depth" + std::to_string(depth), cullFunctor, render::ItemKey::TAG_BITS_1, render::ItemKey::TAG_BITS_1, nextDepth);
|
||||||
|
|
||||||
task.addJob<DrawMirrorTask>("DrawMirrorTask" + std::to_string(mirrorIndex) + "Depth" + std::to_string(depth), setupOutput);
|
task.addJob<DrawMirrorTask>("DrawMirrorTask" + std::to_string(mirrorIndex) + "Depth" + std::to_string(depth), setupOutput);
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
||||||
|
|
||||||
// Lighting Buffer ready for tone mapping
|
// Lighting Buffer ready for tone mapping
|
||||||
const auto toneMappingInputs = ToneMapAndResample::Input(lightingFramebuffer, destFramebuffer).asVarying();
|
const auto toneMappingInputs = ToneMapAndResample::Input(lightingFramebuffer, destFramebuffer).asVarying();
|
||||||
const auto toneMappedBuffer = task.addJob<ToneMapAndResample>("ToneMapping", toneMappingInputs);
|
const auto toneMappedBuffer = task.addJob<ToneMapAndResample>("ToneMapping", toneMappingInputs, depth);
|
||||||
|
|
||||||
// Debugging task is happening in the "over" layer after tone mapping and just before HUD
|
// Debugging task is happening in the "over" layer after tone mapping and just before HUD
|
||||||
{ // Debug the bounds of the rendered items, still look at the zbuffer
|
{ // Debug the bounds of the rendered items, still look at the zbuffer
|
||||||
|
|
|
@ -173,7 +173,7 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
|
||||||
const auto destFramebuffer = static_cast<gpu::FramebufferPointer>(nullptr);
|
const auto destFramebuffer = static_cast<gpu::FramebufferPointer>(nullptr);
|
||||||
|
|
||||||
const auto toneMappingInputs = ToneMapAndResample::Input(resolvedFramebuffer, destFramebuffer).asVarying();
|
const auto toneMappingInputs = ToneMapAndResample::Input(resolvedFramebuffer, destFramebuffer).asVarying();
|
||||||
const auto toneMappedBuffer = task.addJob<ToneMapAndResample>("ToneMapping", toneMappingInputs);
|
const auto toneMappedBuffer = task.addJob<ToneMapAndResample>("ToneMapping", toneMappingInputs, depth);
|
||||||
// HUD Layer
|
// HUD Layer
|
||||||
const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(toneMappedBuffer, lightingModel, hudOpaque, hudTransparent, hazeFrame).asVarying();
|
const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(toneMappedBuffer, lightingModel, hudOpaque, hudTransparent, hazeFrame).asVarying();
|
||||||
task.addJob<RenderHUDLayerTask>("RenderHUDLayer", renderHUDLayerInputs);
|
task.addJob<RenderHUDLayerTask>("RenderHUDLayer", renderHUDLayerInputs);
|
||||||
|
|
|
@ -16,8 +16,8 @@ void CompositeHUD::run(const RenderContextPointer& renderContext, const gpu::Fra
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
assert(renderContext->args->_context);
|
assert(renderContext->args->_context);
|
||||||
|
|
||||||
// We do not want to render HUD elements in secondary camera
|
// We do not want to render HUD elements in secondary camera or mirrors
|
||||||
if (nsightActive() || renderContext->args->_renderMode == RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) {
|
if (nsightActive() || renderContext->args->_renderMode == RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE || renderContext->args->_mirrorDepth > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,10 @@ using namespace shader::render_utils::program;
|
||||||
gpu::PipelinePointer ToneMapAndResample::_pipeline;
|
gpu::PipelinePointer ToneMapAndResample::_pipeline;
|
||||||
gpu::PipelinePointer ToneMapAndResample::_mirrorPipeline;
|
gpu::PipelinePointer ToneMapAndResample::_mirrorPipeline;
|
||||||
|
|
||||||
ToneMapAndResample::ToneMapAndResample() {
|
ToneMapAndResample::ToneMapAndResample(size_t depth) {
|
||||||
Parameters parameters;
|
Parameters parameters;
|
||||||
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) ¶meters));
|
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) ¶meters));
|
||||||
|
_depth = depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToneMapAndResample::init() {
|
void ToneMapAndResample::init() {
|
||||||
|
@ -95,7 +96,8 @@ void ToneMapAndResample::run(const RenderContextPointer& renderContext, const In
|
||||||
batch.setViewportTransform(destViewport);
|
batch.setViewportTransform(destViewport);
|
||||||
batch.setProjectionTransform(glm::mat4());
|
batch.setProjectionTransform(glm::mat4());
|
||||||
batch.resetViewTransform();
|
batch.resetViewTransform();
|
||||||
batch.setPipeline(args->_renderMode == RenderArgs::MIRROR_RENDER_MODE ? _mirrorPipeline : _pipeline);
|
bool shouldMirror = _depth % 2 == (args->_renderMode != RenderArgs::MIRROR_RENDER_MODE);
|
||||||
|
batch.setPipeline(shouldMirror ? _mirrorPipeline : _pipeline);
|
||||||
|
|
||||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(srcBufferSize, args->_viewport));
|
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(srcBufferSize, args->_viewport));
|
||||||
batch.setUniformBuffer(render_utils::slot::buffer::ToneMappingParams, _parametersBuffer);
|
batch.setUniformBuffer(render_utils::slot::buffer::ToneMappingParams, _parametersBuffer);
|
||||||
|
|
|
@ -49,11 +49,9 @@ signals:
|
||||||
|
|
||||||
class ToneMapAndResample {
|
class ToneMapAndResample {
|
||||||
public:
|
public:
|
||||||
ToneMapAndResample();
|
ToneMapAndResample(size_t depth);
|
||||||
virtual ~ToneMapAndResample() {}
|
virtual ~ToneMapAndResample() {}
|
||||||
|
|
||||||
void render(RenderArgs* args, const gpu::TexturePointer& lightingBuffer, gpu::FramebufferPointer& destinationBuffer);
|
|
||||||
|
|
||||||
void setExposure(float exposure);
|
void setExposure(float exposure);
|
||||||
float getExposure() const { return _parametersBuffer.get<Parameters>()._exposure; }
|
float getExposure() const { return _parametersBuffer.get<Parameters>()._exposure; }
|
||||||
|
|
||||||
|
@ -75,7 +73,8 @@ protected:
|
||||||
|
|
||||||
gpu::FramebufferPointer _destinationFrameBuffer;
|
gpu::FramebufferPointer _destinationFrameBuffer;
|
||||||
|
|
||||||
float _factor{ 2.0f };
|
float _factor { 2.0f };
|
||||||
|
size_t _depth { 0 };
|
||||||
|
|
||||||
gpu::FramebufferPointer getResampledFrameBuffer(const gpu::FramebufferPointer& sourceFramebuffer);
|
gpu::FramebufferPointer getResampledFrameBuffer(const gpu::FramebufferPointer& sourceFramebuffer);
|
||||||
|
|
||||||
|
|
|
@ -159,6 +159,9 @@ namespace render {
|
||||||
bool _takingSnapshot { false };
|
bool _takingSnapshot { false };
|
||||||
StencilMaskMode _stencilMaskMode { StencilMaskMode::NONE };
|
StencilMaskMode _stencilMaskMode { StencilMaskMode::NONE };
|
||||||
std::function<void(gpu::Batch&)> _stencilMaskOperator;
|
std::function<void(gpu::Batch&)> _stencilMaskOperator;
|
||||||
|
|
||||||
|
ItemID _ignoreItem { 0 };
|
||||||
|
size_t _mirrorDepth { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ void FetchNonspatialItems::run(const RenderContextPointer& renderContext, const
|
||||||
outItems.reserve(items.size());
|
outItems.reserve(items.size());
|
||||||
for (auto& id : items) {
|
for (auto& id : items) {
|
||||||
auto& item = scene->getItem(id);
|
auto& item = scene->getItem(id);
|
||||||
if (filter.test(item.getKey()) && item.passesZoneOcclusionTest(CullTest::_containingZones)) {
|
if (id != renderContext->args->_ignoreItem && filter.test(item.getKey()) && item.passesZoneOcclusionTest(CullTest::_containingZones)) {
|
||||||
outItems.emplace_back(ItemBound(id, item.getBound(renderContext->args)));
|
outItems.emplace_back(ItemBound(id, item.getBound(renderContext->args)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
||||||
PerformanceTimer perfTimer("insideFitItems");
|
PerformanceTimer perfTimer("insideFitItems");
|
||||||
for (auto id : inSelection.insideItems) {
|
for (auto id : inSelection.insideItems) {
|
||||||
auto& item = scene->getItem(id);
|
auto& item = scene->getItem(id);
|
||||||
if (filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
if (id != renderContext->args->_ignoreItem && filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
||||||
ItemBound itemBound(id, item.getBound(args));
|
ItemBound itemBound(id, item.getBound(args));
|
||||||
outItems.emplace_back(itemBound);
|
outItems.emplace_back(itemBound);
|
||||||
if (item.getKey().isMetaCullGroup()) {
|
if (item.getKey().isMetaCullGroup()) {
|
||||||
|
@ -205,7 +205,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
||||||
PerformanceTimer perfTimer("insideSmallItems");
|
PerformanceTimer perfTimer("insideSmallItems");
|
||||||
for (auto id : inSelection.insideSubcellItems) {
|
for (auto id : inSelection.insideSubcellItems) {
|
||||||
auto& item = scene->getItem(id);
|
auto& item = scene->getItem(id);
|
||||||
if (filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
if (id != renderContext->args->_ignoreItem && filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
||||||
ItemBound itemBound(id, item.getBound(args));
|
ItemBound itemBound(id, item.getBound(args));
|
||||||
outItems.emplace_back(itemBound);
|
outItems.emplace_back(itemBound);
|
||||||
if (item.getKey().isMetaCullGroup()) {
|
if (item.getKey().isMetaCullGroup()) {
|
||||||
|
@ -220,7 +220,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
||||||
PerformanceTimer perfTimer("partialFitItems");
|
PerformanceTimer perfTimer("partialFitItems");
|
||||||
for (auto id : inSelection.partialItems) {
|
for (auto id : inSelection.partialItems) {
|
||||||
auto& item = scene->getItem(id);
|
auto& item = scene->getItem(id);
|
||||||
if (filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
if (id != renderContext->args->_ignoreItem && filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
||||||
ItemBound itemBound(id, item.getBound(args));
|
ItemBound itemBound(id, item.getBound(args));
|
||||||
outItems.emplace_back(itemBound);
|
outItems.emplace_back(itemBound);
|
||||||
if (item.getKey().isMetaCullGroup()) {
|
if (item.getKey().isMetaCullGroup()) {
|
||||||
|
@ -235,7 +235,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
||||||
PerformanceTimer perfTimer("partialSmallItems");
|
PerformanceTimer perfTimer("partialSmallItems");
|
||||||
for (auto id : inSelection.partialSubcellItems) {
|
for (auto id : inSelection.partialSubcellItems) {
|
||||||
auto& item = scene->getItem(id);
|
auto& item = scene->getItem(id);
|
||||||
if (filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
if (id != renderContext->args->_ignoreItem && filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
||||||
ItemBound itemBound(id, item.getBound(args));
|
ItemBound itemBound(id, item.getBound(args));
|
||||||
outItems.emplace_back(itemBound);
|
outItems.emplace_back(itemBound);
|
||||||
if (item.getKey().isMetaCullGroup()) {
|
if (item.getKey().isMetaCullGroup()) {
|
||||||
|
@ -252,7 +252,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
||||||
PerformanceTimer perfTimer("insideFitItems");
|
PerformanceTimer perfTimer("insideFitItems");
|
||||||
for (auto id : inSelection.insideItems) {
|
for (auto id : inSelection.insideItems) {
|
||||||
auto& item = scene->getItem(id);
|
auto& item = scene->getItem(id);
|
||||||
if (filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
if (id != renderContext->args->_ignoreItem && filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
||||||
ItemBound itemBound(id, item.getBound(args));
|
ItemBound itemBound(id, item.getBound(args));
|
||||||
outItems.emplace_back(itemBound);
|
outItems.emplace_back(itemBound);
|
||||||
if (item.getKey().isMetaCullGroup()) {
|
if (item.getKey().isMetaCullGroup()) {
|
||||||
|
@ -267,7 +267,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
||||||
PerformanceTimer perfTimer("insideSmallItems");
|
PerformanceTimer perfTimer("insideSmallItems");
|
||||||
for (auto id : inSelection.insideSubcellItems) {
|
for (auto id : inSelection.insideSubcellItems) {
|
||||||
auto& item = scene->getItem(id);
|
auto& item = scene->getItem(id);
|
||||||
if (filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
if (id != renderContext->args->_ignoreItem && filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
||||||
ItemBound itemBound(id, item.getBound(args));
|
ItemBound itemBound(id, item.getBound(args));
|
||||||
if (test.solidAngleTest(itemBound.bound)) {
|
if (test.solidAngleTest(itemBound.bound)) {
|
||||||
outItems.emplace_back(itemBound);
|
outItems.emplace_back(itemBound);
|
||||||
|
@ -284,7 +284,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
||||||
PerformanceTimer perfTimer("partialFitItems");
|
PerformanceTimer perfTimer("partialFitItems");
|
||||||
for (auto id : inSelection.partialItems) {
|
for (auto id : inSelection.partialItems) {
|
||||||
auto& item = scene->getItem(id);
|
auto& item = scene->getItem(id);
|
||||||
if (filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
if (id != renderContext->args->_ignoreItem && filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
||||||
ItemBound itemBound(id, item.getBound(args));
|
ItemBound itemBound(id, item.getBound(args));
|
||||||
if (test.frustumTest(itemBound.bound)) {
|
if (test.frustumTest(itemBound.bound)) {
|
||||||
outItems.emplace_back(itemBound);
|
outItems.emplace_back(itemBound);
|
||||||
|
@ -301,7 +301,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
||||||
PerformanceTimer perfTimer("partialSmallItems");
|
PerformanceTimer perfTimer("partialSmallItems");
|
||||||
for (auto id : inSelection.partialSubcellItems) {
|
for (auto id : inSelection.partialSubcellItems) {
|
||||||
auto& item = scene->getItem(id);
|
auto& item = scene->getItem(id);
|
||||||
if (filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
if (id != renderContext->args->_ignoreItem && filter.test(item.getKey()) && test.zoneOcclusionTest(item)) {
|
||||||
ItemBound itemBound(id, item.getBound(args));
|
ItemBound itemBound(id, item.getBound(args));
|
||||||
if (test.frustumTest(itemBound.bound) && test.solidAngleTest(itemBound.bound)) {
|
if (test.frustumTest(itemBound.bound) && test.solidAngleTest(itemBound.bound)) {
|
||||||
outItems.emplace_back(itemBound);
|
outItems.emplace_back(itemBound);
|
||||||
|
|
|
@ -167,7 +167,8 @@ void UpsampleToBlitFramebuffer::run(const RenderContextPointer& renderContext, c
|
||||||
batch.setViewportTransform(viewport);
|
batch.setViewportTransform(viewport);
|
||||||
batch.setProjectionTransform(glm::mat4());
|
batch.setProjectionTransform(glm::mat4());
|
||||||
batch.resetViewTransform();
|
batch.resetViewTransform();
|
||||||
batch.setPipeline(args->_renderMode == RenderArgs::MIRROR_RENDER_MODE ? _mirrorPipeline : _pipeline);
|
bool shouldMirror = _depth % 2 == (args->_renderMode != RenderArgs::MIRROR_RENDER_MODE);
|
||||||
|
batch.setPipeline(shouldMirror ? _mirrorPipeline : _pipeline);
|
||||||
|
|
||||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(bufferSize, viewport));
|
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(bufferSize, viewport));
|
||||||
batch.setResourceTexture(0, sourceFramebuffer->getRenderBuffer(0));
|
batch.setResourceTexture(0, sourceFramebuffer->getRenderBuffer(0));
|
||||||
|
|
|
@ -73,7 +73,7 @@ namespace render {
|
||||||
using Input = gpu::FramebufferPointer;
|
using Input = gpu::FramebufferPointer;
|
||||||
using JobModel = Job::ModelIO<UpsampleToBlitFramebuffer, Input, gpu::FramebufferPointer>;
|
using JobModel = Job::ModelIO<UpsampleToBlitFramebuffer, Input, gpu::FramebufferPointer>;
|
||||||
|
|
||||||
UpsampleToBlitFramebuffer() {}
|
UpsampleToBlitFramebuffer(size_t depth) : _depth(depth) {}
|
||||||
|
|
||||||
void run(const RenderContextPointer& renderContext, const Input& input, gpu::FramebufferPointer& resampledFrameBuffer);
|
void run(const RenderContextPointer& renderContext, const Input& input, gpu::FramebufferPointer& resampledFrameBuffer);
|
||||||
|
|
||||||
|
@ -81,6 +81,8 @@ namespace render {
|
||||||
|
|
||||||
static gpu::PipelinePointer _pipeline;
|
static gpu::PipelinePointer _pipeline;
|
||||||
static gpu::PipelinePointer _mirrorPipeline;
|
static gpu::PipelinePointer _mirrorPipeline;
|
||||||
|
|
||||||
|
size_t _depth;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue