mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-13 13:13:02 +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 ||
|
||||
qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON;
|
||||
bool overrideAnim = _skeletonModel ? _skeletonModel->getRig().isPlayingOverrideAnimation() : false;
|
||||
bool isInMirror = renderArgs->_mirrorDepth > 0;
|
||||
bool insideHead = cameraInsideHead(renderArgs->getViewFrustum().getPosition());
|
||||
return !defaultMode || (!firstPerson && !insideHead) || (overrideAnim && !insideHead);
|
||||
return !defaultMode || isInMirror || (!firstPerson && !insideHead) || (overrideAnim && !insideHead);
|
||||
}
|
||||
|
||||
void MyAvatar::setRotationRecenterFilterLength(float length) {
|
||||
|
|
|
@ -227,39 +227,13 @@ bool EntityRenderer::passesZoneOcclusionTest(const std::unordered_set<QUuid>& co
|
|||
}
|
||||
|
||||
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::quat mirrorPropertiesRotation;
|
||||
glm::vec3 mirrorPropertiesDimensions;
|
||||
withReadLock([&]{
|
||||
mirrorPropertiesPosition = _entity->getWorldPosition();
|
||||
mirrorPropertiesRotation = _entity->getWorldOrientation();
|
||||
mirrorPropertiesDimensions = _entity->getScaledDimensions();
|
||||
});
|
||||
|
||||
glm::vec3 halfMirrorPropertiesDimensions = 0.5f * mirrorPropertiesDimensions;
|
||||
|
||||
glm::mat4 worldFromMirrorRotation = glm::mat4_cast(mirrorPropertiesRotation);
|
||||
glm::mat4 worldFromMirrorTranslation = glm::translate(mirrorPropertiesPosition);
|
||||
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
|
||||
// TODO: we are assuming here that UP is world y-axis
|
||||
glm::quat mainCameraRotationWorld = viewFrustum.getOrientation();
|
||||
glm::mat4 mainCameraRotationMirror = mirrorFromWorld * glm::mat4_cast(mainCameraRotationWorld);
|
||||
glm::mat4 mirrorCameraRotationMirror = mainCameraRotationMirror;// * glm::scale(vec3(-1.0f, 1.0f, -1.0f));
|
||||
glm::quat mirrorCameraRotationWorld = worldFromMirror * mirrorCameraRotationMirror;
|
||||
glm::quat mainCameraRotationMirror = mirrorFromWorld * glm::mat4_cast(mainCameraRotationWorld);
|
||||
glm::quat mirrorCameraRotationMirror = glm::quat(mainCameraRotationMirror.w, -mainCameraRotationMirror.x, -mainCameraRotationMirror.y, mainCameraRotationMirror.z) *
|
||||
glm::angleAxis((float)M_PI, glm::vec3(0, 1, 0));
|
||||
glm::quat mirrorCameraRotationWorld = worldFromMirror * glm::mat4_cast(mirrorCameraRotationMirror);
|
||||
|
||||
viewFrustum.setPosition(mirrorCameraPositionWorld);
|
||||
viewFrustum.setOrientation(mirrorCameraRotationWorld);
|
||||
|
||||
// build frustum using mirror space translation of mirrored camera
|
||||
//float nearClip = mirrorCameraPositionMirror.z + mirrorPropertiesDimensions.z * 2.0f;
|
||||
//glm::vec3 upperRight = halfMirrorPropertiesDimensions - mirrorCameraPositionMirror;
|
||||
//glm::vec3 bottomLeft = -halfMirrorPropertiesDimensions - mirrorCameraPositionMirror;
|
||||
//glm::mat4 frustum = glm::frustum(bottomLeft.x, upperRight.x, bottomLeft.y, upperRight.y, nearClip, viewFrustum.getFarClip());
|
||||
//viewFrustum.setProjection(frustum);
|
||||
// modify the near clip plane to be the XY plane of the mirror
|
||||
// from: https://terathon.com/lengyel/Lengyel-Oblique.pdf
|
||||
glm::mat4 view = viewFrustum.getView();
|
||||
glm::mat4 projection = viewFrustum.getProjection();
|
||||
|
||||
//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) {
|
||||
|
@ -295,7 +297,7 @@ void EntityRenderer::render(RenderArgs* args) {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -263,8 +263,9 @@ void GizmoEntityRenderer::doRender(RenderArgs* args) {
|
|||
|
||||
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,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition(), true));
|
||||
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition(), true));
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
Pipeline pipelineType = getPipelineType(materials);
|
||||
|
|
|
@ -103,8 +103,9 @@ void GridEntityRenderer::doRender(RenderArgs* args) {
|
|||
} else {
|
||||
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,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
batch->setModelTransform(transform);
|
||||
|
||||
auto minCorner = glm::vec2(-0.5f, -0.5f);
|
||||
|
|
|
@ -147,8 +147,9 @@ void ImageEntityRenderer::doRender(RenderArgs* args) {
|
|||
|
||||
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,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
|
||||
float imageWidth = _texture->getWidth();
|
||||
float imageHeight = _texture->getHeight();
|
||||
|
|
|
@ -47,8 +47,9 @@ void LineEntityRenderer::doRender(RenderArgs* args) {
|
|||
const auto& modelTransform = getModelTransform();
|
||||
Transform transform = Transform();
|
||||
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,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
usePrimaryFrustum ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
batch.setModelTransform(transform);
|
||||
if (_linePoints.size() > 1) {
|
||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, false, false, false, true,
|
||||
|
|
|
@ -303,8 +303,9 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) {
|
|||
proceduralRender = true;
|
||||
}
|
||||
|
||||
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||
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);
|
||||
|
||||
if (!proceduralRender) {
|
||||
|
|
|
@ -325,8 +325,9 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
|
|||
buildPipelines();
|
||||
}
|
||||
|
||||
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||
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.setPipeline(_pipelines[{args->_renderMethod, isTransparent()}]);
|
||||
|
|
|
@ -1860,8 +1860,9 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) {
|
|||
PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
|
||||
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,
|
||||
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);
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
|
|
|
@ -118,8 +118,9 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
|||
|
||||
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,
|
||||
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));
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
|
|
|
@ -164,8 +164,9 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
|||
transform = _renderTransform;
|
||||
});
|
||||
|
||||
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||
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);
|
||||
|
||||
Pipeline pipelineType = getPipelineType(materials);
|
||||
|
@ -352,8 +353,9 @@ void entities::TextPayload::render(RenderArgs* args) {
|
|||
return;
|
||||
}
|
||||
|
||||
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||
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();
|
||||
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);
|
||||
|
||||
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||
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);
|
||||
|
||||
// Turn off jitter for these entities
|
||||
|
|
|
@ -71,14 +71,15 @@ void CauterizedMeshPartPayload::updateTransformForCauterizedMesh(const Transform
|
|||
_cauterizedTransform = renderTransform;
|
||||
}
|
||||
|
||||
void CauterizedMeshPartPayload::bindTransform(gpu::Batch& batch, const Transform& transform, RenderArgs::RenderMode renderMode) const {
|
||||
bool useCauterizedMesh = (renderMode != RenderArgs::RenderMode::SHADOW_RENDER_MODE && renderMode != RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) && _enableCauterization;
|
||||
void CauterizedMeshPartPayload::bindTransform(gpu::Batch& batch, const Transform& transform, RenderArgs::RenderMode renderMode, size_t mirrorDepth) const {
|
||||
bool useCauterizedMesh = _enableCauterization && (renderMode != RenderArgs::RenderMode::SHADOW_RENDER_MODE && renderMode != RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) &&
|
||||
mirrorDepth == 0;
|
||||
if (useCauterizedMesh) {
|
||||
if (_cauterizedClusterBuffer) {
|
||||
batch.setUniformBuffer(graphics::slot::buffer::Skinning, _cauterizedClusterBuffer);
|
||||
}
|
||||
batch.setModelTransform(_cauterizedTransform);
|
||||
} 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 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; }
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) {
|
|||
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) {
|
||||
batch.setUniformBuffer(graphics::slot::buffer::Skinning, _clusterBuffer);
|
||||
}
|
||||
|
@ -300,8 +300,9 @@ Item::Bound ModelMeshPartPayload::getBound(RenderArgs* args) const {
|
|||
auto worldBound = _adjustedLocalBound;
|
||||
auto parentTransform = _parentTransform;
|
||||
if (args) {
|
||||
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||
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);
|
||||
return worldBound;
|
||||
|
@ -314,18 +315,19 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
|||
void ModelMeshPartPayload::render(RenderArgs* args) {
|
||||
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;
|
||||
}
|
||||
|
||||
gpu::Batch& batch = *(args->_batch);
|
||||
|
||||
Transform transform = _parentTransform;
|
||||
bool usePrimaryFrustum = args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE || args->_mirrorDepth > 0;
|
||||
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);
|
||||
bindTransform(batch, modelTransform, args->_renderMode);
|
||||
bindTransform(batch, modelTransform, args->_renderMode, args->_mirrorDepth);
|
||||
|
||||
//Bind the index buffer and vertex buffer and Blend shapes if needed
|
||||
bindMesh(batch);
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
|
||||
// ModelMeshPartPayload functions to perform render
|
||||
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 updateKey(const render::ItemKey& key);
|
||||
|
|
|
@ -277,7 +277,7 @@ public:
|
|||
using Outputs = render::VaryingSet4<render::ItemBound, gpu::FramebufferPointer, RenderArgsPointer, glm::vec2>;
|
||||
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) {
|
||||
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()));
|
||||
}
|
||||
|
||||
render::ItemBound mirror = items[_mirrorIndex];
|
||||
|
||||
_cachedArgsPointer->_renderMode = args->_renderMode;
|
||||
_cachedArgsPointer->_blitFramebuffer = args->_blitFramebuffer;
|
||||
args->_renderMode = RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE;
|
||||
args->_blitFramebuffer = _mirrorFramebuffer;
|
||||
_cachedArgsPointer->_ignoreItem = args->_ignoreItem;
|
||||
_cachedArgsPointer->_mirrorDepth = args->_mirrorDepth;
|
||||
|
||||
args->_blitFramebuffer = _mirrorFramebuffer;
|
||||
args->_ignoreItem = mirror.id;
|
||||
args->_mirrorDepth = _depth;
|
||||
|
||||
render::ItemBound mirror = items[_mirrorIndex];
|
||||
ViewFrustum srcViewFrustum = args->getViewFrustum();
|
||||
args->_scene->getItem(mirror.id).computeMirrorView(srcViewFrustum);
|
||||
|
||||
|
@ -317,6 +322,7 @@ protected:
|
|||
gpu::FramebufferPointer _mirrorFramebuffer { nullptr };
|
||||
RenderArgsPointer _cachedArgsPointer { std::make_shared<RenderArgs>() };
|
||||
size_t _mirrorIndex;
|
||||
size_t _depth;
|
||||
|
||||
};
|
||||
|
||||
|
@ -377,6 +383,8 @@ public:
|
|||
// Restore the blit framebuffer after we've sampled from it
|
||||
if (cachedArgs) {
|
||||
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>();
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -244,7 +244,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
|
||||
// Lighting Buffer ready for tone mapping
|
||||
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
|
||||
{ // 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 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
|
||||
const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(toneMappedBuffer, lightingModel, hudOpaque, hudTransparent, hazeFrame).asVarying();
|
||||
task.addJob<RenderHUDLayerTask>("RenderHUDLayer", renderHUDLayerInputs);
|
||||
|
|
|
@ -16,8 +16,8 @@ void CompositeHUD::run(const RenderContextPointer& renderContext, const gpu::Fra
|
|||
assert(renderContext->args);
|
||||
assert(renderContext->args->_context);
|
||||
|
||||
// We do not want to render HUD elements in secondary camera
|
||||
if (nsightActive() || renderContext->args->_renderMode == RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) {
|
||||
// We do not want to render HUD elements in secondary camera or mirrors
|
||||
if (nsightActive() || renderContext->args->_renderMode == RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE || renderContext->args->_mirrorDepth > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,9 +25,10 @@ using namespace shader::render_utils::program;
|
|||
gpu::PipelinePointer ToneMapAndResample::_pipeline;
|
||||
gpu::PipelinePointer ToneMapAndResample::_mirrorPipeline;
|
||||
|
||||
ToneMapAndResample::ToneMapAndResample() {
|
||||
ToneMapAndResample::ToneMapAndResample(size_t depth) {
|
||||
Parameters parameters;
|
||||
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) ¶meters));
|
||||
_depth = depth;
|
||||
}
|
||||
|
||||
void ToneMapAndResample::init() {
|
||||
|
@ -95,7 +96,8 @@ void ToneMapAndResample::run(const RenderContextPointer& renderContext, const In
|
|||
batch.setViewportTransform(destViewport);
|
||||
batch.setProjectionTransform(glm::mat4());
|
||||
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.setUniformBuffer(render_utils::slot::buffer::ToneMappingParams, _parametersBuffer);
|
||||
|
|
|
@ -49,11 +49,9 @@ signals:
|
|||
|
||||
class ToneMapAndResample {
|
||||
public:
|
||||
ToneMapAndResample();
|
||||
ToneMapAndResample(size_t depth);
|
||||
virtual ~ToneMapAndResample() {}
|
||||
|
||||
void render(RenderArgs* args, const gpu::TexturePointer& lightingBuffer, gpu::FramebufferPointer& destinationBuffer);
|
||||
|
||||
void setExposure(float exposure);
|
||||
float getExposure() const { return _parametersBuffer.get<Parameters>()._exposure; }
|
||||
|
||||
|
@ -75,7 +73,8 @@ protected:
|
|||
|
||||
gpu::FramebufferPointer _destinationFrameBuffer;
|
||||
|
||||
float _factor{ 2.0f };
|
||||
float _factor { 2.0f };
|
||||
size_t _depth { 0 };
|
||||
|
||||
gpu::FramebufferPointer getResampledFrameBuffer(const gpu::FramebufferPointer& sourceFramebuffer);
|
||||
|
||||
|
|
|
@ -159,6 +159,9 @@ namespace render {
|
|||
bool _takingSnapshot { false };
|
||||
StencilMaskMode _stencilMaskMode { StencilMaskMode::NONE };
|
||||
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());
|
||||
for (auto& id : items) {
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
|||
PerformanceTimer perfTimer("insideFitItems");
|
||||
for (auto id : inSelection.insideItems) {
|
||||
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));
|
||||
outItems.emplace_back(itemBound);
|
||||
if (item.getKey().isMetaCullGroup()) {
|
||||
|
@ -205,7 +205,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
|||
PerformanceTimer perfTimer("insideSmallItems");
|
||||
for (auto id : inSelection.insideSubcellItems) {
|
||||
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));
|
||||
outItems.emplace_back(itemBound);
|
||||
if (item.getKey().isMetaCullGroup()) {
|
||||
|
@ -220,7 +220,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
|||
PerformanceTimer perfTimer("partialFitItems");
|
||||
for (auto id : inSelection.partialItems) {
|
||||
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));
|
||||
outItems.emplace_back(itemBound);
|
||||
if (item.getKey().isMetaCullGroup()) {
|
||||
|
@ -235,7 +235,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
|||
PerformanceTimer perfTimer("partialSmallItems");
|
||||
for (auto id : inSelection.partialSubcellItems) {
|
||||
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));
|
||||
outItems.emplace_back(itemBound);
|
||||
if (item.getKey().isMetaCullGroup()) {
|
||||
|
@ -252,7 +252,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
|||
PerformanceTimer perfTimer("insideFitItems");
|
||||
for (auto id : inSelection.insideItems) {
|
||||
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));
|
||||
outItems.emplace_back(itemBound);
|
||||
if (item.getKey().isMetaCullGroup()) {
|
||||
|
@ -267,7 +267,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
|||
PerformanceTimer perfTimer("insideSmallItems");
|
||||
for (auto id : inSelection.insideSubcellItems) {
|
||||
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));
|
||||
if (test.solidAngleTest(itemBound.bound)) {
|
||||
outItems.emplace_back(itemBound);
|
||||
|
@ -284,7 +284,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
|||
PerformanceTimer perfTimer("partialFitItems");
|
||||
for (auto id : inSelection.partialItems) {
|
||||
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));
|
||||
if (test.frustumTest(itemBound.bound)) {
|
||||
outItems.emplace_back(itemBound);
|
||||
|
@ -301,7 +301,7 @@ void CullSpatialSelection::run(const RenderContextPointer& renderContext,
|
|||
PerformanceTimer perfTimer("partialSmallItems");
|
||||
for (auto id : inSelection.partialSubcellItems) {
|
||||
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));
|
||||
if (test.frustumTest(itemBound.bound) && test.solidAngleTest(itemBound.bound)) {
|
||||
outItems.emplace_back(itemBound);
|
||||
|
|
|
@ -167,7 +167,8 @@ void UpsampleToBlitFramebuffer::run(const RenderContextPointer& renderContext, c
|
|||
batch.setViewportTransform(viewport);
|
||||
batch.setProjectionTransform(glm::mat4());
|
||||
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.setResourceTexture(0, sourceFramebuffer->getRenderBuffer(0));
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace render {
|
|||
using 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);
|
||||
|
||||
|
@ -81,6 +81,8 @@ namespace render {
|
|||
|
||||
static gpu::PipelinePointer _pipeline;
|
||||
static gpu::PipelinePointer _mirrorPipeline;
|
||||
|
||||
size_t _depth;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue