Merge branch 'release/materials_featurette' of https://github.com/secondlife/viewer
# Conflicts: # indra/newview/app_settings/settings.xml # indra/newview/llspatialpartition.cpp # indra/newview/llviewermenu.cpp # indra/newview/pipeline.cpp # indra/newview/skins/default/xui/en/menu_viewer.xmlmeow-7.2.2
commit
c73b3b2a1b
|
|
@ -594,11 +594,22 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
|
|||
}
|
||||
else
|
||||
{
|
||||
//set version to 1.40
|
||||
shader_code_text[shader_code_count++] = strdup("#version 140\n");
|
||||
//some implementations of GLSL 1.30 require integer precision be explicitly declared
|
||||
extra_code_text[extra_code_count++] = strdup("precision mediump int;\n");
|
||||
extra_code_text[extra_code_count++] = strdup("precision highp float;\n");
|
||||
if (type == GL_GEOMETRY_SHADER)
|
||||
{
|
||||
//set version to 1.50
|
||||
shader_code_text[shader_code_count++] = strdup("#version 150\n");
|
||||
//some implementations of GLSL 1.30 require integer precision be explicitly declared
|
||||
extra_code_text[extra_code_count++] = strdup("precision mediump int;\n");
|
||||
extra_code_text[extra_code_count++] = strdup("precision highp float;\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//set version to 1.40
|
||||
shader_code_text[shader_code_count++] = strdup("#version 140\n");
|
||||
//some implementations of GLSL 1.30 require integer precision be explicitly declared
|
||||
extra_code_text[extra_code_count++] = strdup("precision mediump int;\n");
|
||||
extra_code_text[extra_code_count++] = strdup("precision highp float;\n");
|
||||
}
|
||||
}
|
||||
|
||||
extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n");
|
||||
|
|
@ -1471,6 +1482,8 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("sun_up_factor");
|
||||
mReservedUniforms.push_back("moonlight_color");
|
||||
|
||||
mReservedUniforms.push_back("debug_normal_draw_length");
|
||||
|
||||
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
|
||||
|
||||
std::set<std::string> dupe_check;
|
||||
|
|
|
|||
|
|
@ -329,6 +329,9 @@ public:
|
|||
WATER_EDGE_FACTOR, // "water_edge"
|
||||
SUN_UP_FACTOR, // "sun_up_factor"
|
||||
MOONLIGHT_COLOR, // "moonlight_color"
|
||||
|
||||
DEBUG_NORMAL_DRAW_LENGTH, // "debug_normal_draw_length"
|
||||
|
||||
END_RESERVED_UNIFORMS
|
||||
} eGLSLReservedUniforms;
|
||||
// clang-format on
|
||||
|
|
|
|||
|
|
@ -14005,6 +14005,17 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<real>8.0</real>
|
||||
</map>
|
||||
<key>RenderTerrainPBRNormalsEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>EXPERIMENTAL: Change normal gen for PBR Terrain.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderTrackerBeacon</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* @file normaldebugF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
in vec4 vertex_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
frag_color = max(vertex_color, vec4(0));
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* @file normaldebugG.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// *NOTE: Geometry shaders have a reputation for being slow. Consider using
|
||||
// compute shaders instead, which have a reputation for being fast. This
|
||||
// geometry shader in particular seems to run fine on my machine, but I won't
|
||||
// vouch for this in performance-critical areas.
|
||||
// -Cosmic,2023-09-28
|
||||
|
||||
out vec4 vertex_color;
|
||||
|
||||
in vec4 normal_g[];
|
||||
#if HAS_ATTRIBUTE_TANGENT == 1
|
||||
in vec4 tangent_g[];
|
||||
#endif
|
||||
|
||||
layout(TRIANGLES) in;
|
||||
#if HAS_ATTRIBUTE_TANGENT == 1
|
||||
layout(LINE_STRIP, max_vertices = 12) out;
|
||||
#else
|
||||
layout(LINE_STRIP, max_vertices = 6) out;
|
||||
#endif
|
||||
|
||||
void triangle_normal_debug(int i)
|
||||
{
|
||||
// Normal
|
||||
vec4 normal_color = vec4(1.0, 1.0, 0.0, 1.0);
|
||||
gl_Position = gl_in[i].gl_Position;
|
||||
vertex_color = normal_color;
|
||||
EmitVertex();
|
||||
gl_Position = normal_g[i];
|
||||
vertex_color = normal_color;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
|
||||
#if HAS_ATTRIBUTE_TANGENT == 1
|
||||
// Tangent
|
||||
vec4 tangent_color = vec4(0.0, 1.0, 1.0, 1.0);
|
||||
gl_Position = gl_in[i].gl_Position;
|
||||
vertex_color = tangent_color;
|
||||
EmitVertex();
|
||||
gl_Position = tangent_g[i];
|
||||
vertex_color = tangent_color;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
triangle_normal_debug(0);
|
||||
triangle_normal_debug(1);
|
||||
triangle_normal_debug(2);
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* @file normaldebugV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
in vec3 position;
|
||||
in vec3 normal;
|
||||
out vec4 normal_g;
|
||||
#if HAS_ATTRIBUTE_TANGENT == 1
|
||||
in vec4 tangent;
|
||||
out vec4 tangent_g;
|
||||
#endif
|
||||
|
||||
uniform float debug_normal_draw_length;
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
mat4 getObjectSkinnedTransform();
|
||||
#else
|
||||
uniform mat3 normal_matrix;
|
||||
#endif
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat4 modelview_matrix;
|
||||
|
||||
// *NOTE: Should use the modelview_projection_matrix here in the non-skinned
|
||||
// case for efficiency, but opting for the simplier implementation for now as
|
||||
// this is debug code. Also, the skinned version hasn't beeen tested yet.
|
||||
// world_pos = mat * vec4(position.xyz, 1.0)
|
||||
vec4 get_screen_normal(vec3 position, vec4 world_pos, vec3 normal, mat4 mat)
|
||||
{
|
||||
vec4 world_norm = mat * vec4((position + normal), 1.0);
|
||||
world_norm.xyz -= world_pos.xyz;
|
||||
world_norm.xyz = debug_normal_draw_length * normalize(world_norm.xyz);
|
||||
world_norm.xyz += world_pos.xyz;
|
||||
return projection_matrix * world_norm;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef HAS_SKIN
|
||||
mat4 mat = getObjectSkinnedTransform();
|
||||
mat = modelview_matrix * mat;
|
||||
#else
|
||||
#define mat modelview_matrix
|
||||
#endif
|
||||
|
||||
vec4 world_pos = mat * vec4(position.xyz,1.0);
|
||||
|
||||
gl_Position = projection_matrix * world_pos;
|
||||
normal_g = get_screen_normal(position.xyz, world_pos, normal.xyz, mat);
|
||||
#if HAS_ATTRIBUTE_TANGENT == 1
|
||||
tangent_g = get_screen_normal(position.xyz, world_pos, tangent.xyz, mat);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -40,6 +40,8 @@ public:
|
|||
virtual ~LLFetchedGLTFMaterial();
|
||||
|
||||
LLFetchedGLTFMaterial& operator=(const LLFetchedGLTFMaterial& rhs);
|
||||
// LLGLTFMaterial::operator== is defined, but LLFetchedGLTFMaterial::operator== is not.
|
||||
bool operator==(const LLGLTFMaterial& rhs) const = delete;
|
||||
|
||||
// If this material is loaded, fire the given function
|
||||
void onMaterialComplete(std::function<void()> material_complete);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "llenvironment.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "llviewercamera.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llviewertexturelist.h"
|
||||
|
|
@ -95,7 +96,7 @@ namespace
|
|||
{
|
||||
void fetch_texture_for_ui(LLPointer<LLViewerFetchedTexture>& img, const LLUUID& id)
|
||||
{
|
||||
if (id.notNull())
|
||||
if (!img && id.notNull())
|
||||
{
|
||||
if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
|
||||
{
|
||||
|
|
@ -129,6 +130,8 @@ namespace
|
|||
|
||||
LLGLTFPreviewTexture::MaterialLoadLevels get_material_load_levels(LLFetchedGLTFMaterial& material)
|
||||
{
|
||||
llassert(!material.isFetching());
|
||||
|
||||
using MaterialTextures = LLPointer<LLViewerFetchedTexture>*[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
|
||||
|
||||
MaterialTextures textures;
|
||||
|
|
@ -334,7 +337,7 @@ void set_preview_sphere_material(PreviewSphere& preview_sphere, LLPointer<LLFetc
|
|||
info->mGLTFMaterial = material;
|
||||
LLVertexBuffer* buf = info->mVertexBuffer.get();
|
||||
LLStrider<LLColor4U> colors;
|
||||
const S32 count = info->mEnd - info->mStart;
|
||||
const S32 count = info->mEnd - info->mStart + 1;
|
||||
buf->getColorStrider(colors, info->mStart, count);
|
||||
for (S32 i = 0; i < count; ++i)
|
||||
{
|
||||
|
|
@ -419,7 +422,8 @@ BOOL LLGLTFPreviewTexture::render()
|
|||
LLVector3 light_dir3(1.0f, 1.0f, 1.0f);
|
||||
light_dir3.normalize();
|
||||
const LLVector4 light_dir = LLVector4(light_dir3, 0);
|
||||
SetTemporarily<S32> sun_light_only(&LLPipeline::RenderLocalLightCount, 0);
|
||||
const S32 old_local_light_count = gSavedSettings.get<S32>("RenderLocalLightCount");
|
||||
gSavedSettings.set<S32>("RenderLocalLightCount", 0);
|
||||
|
||||
gPipeline.mReflectionMapManager.forceDefaultProbeAndUpdateUniforms();
|
||||
|
||||
|
|
@ -524,6 +528,7 @@ BOOL LLGLTFPreviewTexture::render()
|
|||
// Clean up
|
||||
gPipeline.setupHWLights();
|
||||
gPipeline.mReflectionMapManager.forceDefaultProbeAndUpdateUniforms(false);
|
||||
gSavedSettings.set<S32>("RenderLocalLightCount", old_local_light_count);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "pipeline.h"
|
||||
#include "llmeshrepository.h"
|
||||
#include "llrender.h"
|
||||
#include "lldrawpool.h"
|
||||
#include "lloctree.h"
|
||||
#include "llphysicsshapebuilderutil.h"
|
||||
#include "llvoavatar.h"
|
||||
|
|
@ -2024,7 +2025,11 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
|
|||
drawBoxOutline(pos,size);
|
||||
}
|
||||
}
|
||||
|
||||
// *TODO: LLDrawables which are not part of LLVOVolumes fall into a different
|
||||
// code path which uses a shader - it was tested to be faster than mapping a
|
||||
// vertex buffer in the terrain case. Consider using it for LLVOVolumes as well
|
||||
// to simplify and speed up this debug code. Alternatively, a compute shader is
|
||||
// likely faster. -Cosmic,2023-09-28
|
||||
void renderNormals(LLDrawable *drawablep)
|
||||
{
|
||||
if (!drawablep->isVisible())
|
||||
|
|
@ -2032,20 +2037,22 @@ void renderNormals(LLDrawable *drawablep)
|
|||
|
||||
LLVertexBuffer::unbind();
|
||||
|
||||
LLViewerObject* obj = drawablep->getVObj();
|
||||
LLVOVolume *vol = drawablep->getVOVolume();
|
||||
|
||||
if (vol)
|
||||
if (obj)
|
||||
{
|
||||
// <FS:Beq> FIX and improve renderNormals debug
|
||||
static LLCachedControl<bool> showSelectedOnly(gSavedSettings, "OnlyShowSelectedNormals");
|
||||
if(showSelectedOnly && !drawablep->getVObj()->isSelected())
|
||||
if (showSelectedOnly && !obj->isSelected())
|
||||
{
|
||||
drawablep->getVObj()->setDebugText("");
|
||||
obj->setDebugText("");
|
||||
return;
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
LLVolume *volume = vol->getVolume();
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
LLGLDepthTest gl_depth(GL_TRUE, GL_FALSE);
|
||||
|
||||
// Drawable's normals & tangents are stored in model space, i.e. before any scaling is applied.
|
||||
//
|
||||
|
|
@ -2054,68 +2061,136 @@ void renderNormals(LLDrawable *drawablep)
|
|||
// transform. We get that effect here by pre-applying the inverse scale (twice, because
|
||||
// one forward scale will be re-applied via the MVP in the vertex shader)
|
||||
|
||||
LLVector3 scale_v3 = vol->getScale();
|
||||
float scale_len = scale_v3.length();
|
||||
LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]);
|
||||
obj_scale.normalize3();
|
||||
LLVector4a inv_scale;
|
||||
float scale_len;
|
||||
if (vol)
|
||||
{
|
||||
LLVector3 scale_v3 = vol->getScale();
|
||||
LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]);
|
||||
obj_scale.normalize3();
|
||||
|
||||
// Create inverse-scale vector for normals
|
||||
inv_scale.set(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ], 0.0);
|
||||
inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice
|
||||
|
||||
inv_scale.normalize3fast();
|
||||
scale_len = scale_v3.length();
|
||||
}
|
||||
else
|
||||
{
|
||||
inv_scale.set(1.0, 1.0, 1.0, 0.0);
|
||||
scale_len = 1.0;
|
||||
}
|
||||
|
||||
gGL.pushMatrix();
|
||||
if (vol)
|
||||
{
|
||||
gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix);
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
// Normals &tangent line segments get scaled along with the object. Divide by scale length
|
||||
// to keep the as-viewed lengths (relatively) constant with the debug setting length
|
||||
float draw_length = gSavedSettings.getF32("RenderDebugNormalScale") / scale_len;
|
||||
|
||||
// Create inverse-scale vector for normals
|
||||
LLVector4a inv_scale(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ]);
|
||||
inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice
|
||||
inv_scale.normalize3fast();
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix);
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
|
||||
std::vector<LLVolumeFace>* faces = nullptr;
|
||||
std::vector<LLFace*>* drawable_faces = nullptr;
|
||||
if (vol)
|
||||
{
|
||||
const LLVolumeFace &face = volume->getVolumeFace(i);
|
||||
|
||||
gGL.flush();
|
||||
gGL.diffuseColor4f(1, 1, 0, 1);
|
||||
gGL.begin(LLRender::LINES);
|
||||
for (S32 j = 0; j < face.mNumVertices; ++j)
|
||||
{
|
||||
LLVector4a n, p;
|
||||
|
||||
n.setMul(face.mNormals[j], 1.0);
|
||||
n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP
|
||||
n.normalize3fast();
|
||||
n.mul(draw_length);
|
||||
p.setAdd(face.mPositions[j], n);
|
||||
|
||||
gGL.vertex3fv(face.mPositions[j].getF32ptr());
|
||||
gGL.vertex3fv(p.getF32ptr());
|
||||
}
|
||||
gGL.end();
|
||||
|
||||
// Tangents are simple vectors and do not require reorientation via pre-scaling
|
||||
if (face.mTangents)
|
||||
{
|
||||
gGL.flush();
|
||||
gGL.diffuseColor4f(0, 1, 1, 1);
|
||||
gGL.begin(LLRender::LINES);
|
||||
for (S32 j = 0; j < face.mNumVertices; ++j)
|
||||
{
|
||||
LLVector4a t, p;
|
||||
|
||||
t.setMul(face.mTangents[j], 1.0f);
|
||||
t.normalize3fast();
|
||||
t.mul(draw_length);
|
||||
p.setAdd(face.mPositions[j], t);
|
||||
|
||||
gGL.vertex3fv(face.mPositions[j].getF32ptr());
|
||||
gGL.vertex3fv(p.getF32ptr());
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
LLVolume* volume = vol->getVolume();
|
||||
faces = &volume->getVolumeFaces();
|
||||
}
|
||||
else
|
||||
{
|
||||
drawable_faces = &drawablep->getFaces();
|
||||
}
|
||||
|
||||
if (faces)
|
||||
{
|
||||
for (auto it = faces->begin(); it != faces->end(); ++it)
|
||||
{
|
||||
const LLVolumeFace& face = *it;
|
||||
|
||||
gGL.flush();
|
||||
gGL.diffuseColor4f(1, 1, 0, 1);
|
||||
gGL.begin(LLRender::LINES);
|
||||
for (S32 j = 0; j < face.mNumVertices; ++j)
|
||||
{
|
||||
LLVector4a n, p;
|
||||
|
||||
n.setMul(face.mNormals[j], 1.0);
|
||||
n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP
|
||||
n.normalize3fast();
|
||||
n.mul(draw_length);
|
||||
p.setAdd(face.mPositions[j], n);
|
||||
|
||||
gGL.vertex3fv(face.mPositions[j].getF32ptr());
|
||||
gGL.vertex3fv(p.getF32ptr());
|
||||
}
|
||||
gGL.end();
|
||||
|
||||
// Tangents are simple vectors and do not require reorientation via pre-scaling
|
||||
if (face.mTangents)
|
||||
{
|
||||
gGL.flush();
|
||||
gGL.diffuseColor4f(0, 1, 1, 1);
|
||||
gGL.begin(LLRender::LINES);
|
||||
for (S32 j = 0; j < face.mNumVertices; ++j)
|
||||
{
|
||||
LLVector4a t, p;
|
||||
|
||||
t.setMul(face.mTangents[j], 1.0f);
|
||||
t.normalize3fast();
|
||||
t.mul(draw_length);
|
||||
p.setAdd(face.mPositions[j], t);
|
||||
|
||||
gGL.vertex3fv(face.mPositions[j].getF32ptr());
|
||||
gGL.vertex3fv(p.getF32ptr());
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (drawable_faces)
|
||||
{
|
||||
// *HACK: Prepare to restore previous shader as other debug code depends on a simpler shader being present
|
||||
llassert(LLGLSLShader::sCurBoundShaderPtr == &gDebugProgram);
|
||||
LLGLSLShader* prev_shader = LLGLSLShader::sCurBoundShaderPtr;
|
||||
for (auto it = drawable_faces->begin(); it != drawable_faces->end(); ++it)
|
||||
{
|
||||
LLFace* facep = *it;
|
||||
LLFace& face = **it;
|
||||
LLVertexBuffer* buf = face.getVertexBuffer();
|
||||
if (!buf) { continue; }
|
||||
U32 mask_vn = LLVertexBuffer::TYPE_VERTEX | LLVertexBuffer::TYPE_NORMAL;
|
||||
if ((buf->getTypeMask() & mask_vn) != mask_vn) { continue; }
|
||||
|
||||
LLGLSLShader* shader;
|
||||
if ((buf->getTypeMask() & LLVertexBuffer::TYPE_TANGENT) != LLVertexBuffer::TYPE_TANGENT)
|
||||
{
|
||||
shader = &gNormalDebugProgram[NORMAL_DEBUG_SHADER_DEFAULT];
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = &gNormalDebugProgram[NORMAL_DEBUG_SHADER_WITH_TANGENTS];
|
||||
}
|
||||
shader->bind();
|
||||
|
||||
shader->uniform1f(LLShaderMgr::DEBUG_NORMAL_DRAW_LENGTH, draw_length);
|
||||
|
||||
LLRenderPass::applyModelMatrix(&facep->getDrawable()->getRegion()->mRenderMatrix);
|
||||
|
||||
buf->setBuffer();
|
||||
// *NOTE: The render type in the vertex shader is TRIANGLES, but gets converted to LINES in the geometry shader
|
||||
// *NOTE: For terrain normal debug, this seems to also include vertices for water, which is technically not part of the terrain. Should fix that at some point.
|
||||
buf->drawRange(LLRender::TRIANGLES, face.getGeomIndex(), face.getGeomIndex() + face.getGeomCount()-1, face.getIndicesCount(), face.getIndicesStart());
|
||||
}
|
||||
if (prev_shader)
|
||||
{
|
||||
prev_shader->bind();
|
||||
}
|
||||
}
|
||||
|
||||
gGL.popMatrix();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -827,17 +827,18 @@ void LLSurface::updatePatchVisibilities(LLAgent &agent)
|
|||
}
|
||||
}
|
||||
|
||||
BOOL LLSurface::idleUpdate(F32 max_update_time)
|
||||
template<bool PBR>
|
||||
bool LLSurface::idleUpdate(F32 max_update_time)
|
||||
{
|
||||
if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN))
|
||||
{
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Perform idle time update of non-critical stuff.
|
||||
// In this case, texture and normal updates.
|
||||
LLTimer update_timer;
|
||||
BOOL did_update = FALSE;
|
||||
bool did_update = false;
|
||||
|
||||
// If the Z height data has changed, we need to rebuild our
|
||||
// property line vertex arrays.
|
||||
|
|
@ -853,13 +854,13 @@ BOOL LLSurface::idleUpdate(F32 max_update_time)
|
|||
{
|
||||
std::set<LLSurfacePatch *>::iterator curiter = iter++;
|
||||
LLSurfacePatch *patchp = *curiter;
|
||||
patchp->updateNormals();
|
||||
patchp->updateNormals<PBR>();
|
||||
patchp->updateVerticalStats();
|
||||
if (max_update_time == 0.f || update_timer.getElapsedTimeF32() < max_update_time)
|
||||
{
|
||||
if (patchp->updateTexture())
|
||||
{
|
||||
did_update = TRUE;
|
||||
did_update = true;
|
||||
patchp->clearDirty();
|
||||
mDirtyPatchList.erase(curiter);
|
||||
}
|
||||
|
|
@ -875,6 +876,9 @@ BOOL LLSurface::idleUpdate(F32 max_update_time)
|
|||
return did_update;
|
||||
}
|
||||
|
||||
template bool LLSurface::idleUpdate</*PBR=*/false>(F32 max_update_time);
|
||||
template bool LLSurface::idleUpdate</*PBR=*/true>(F32 max_update_time);
|
||||
|
||||
void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch)
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,8 @@ public:
|
|||
LLSurfacePatch *resolvePatchGlobal(const LLVector3d &position_global) const;
|
||||
|
||||
// Update methods (called during idle, normally)
|
||||
BOOL idleUpdate(F32 max_update_time);
|
||||
template<bool PBR>
|
||||
bool idleUpdate(F32 max_update_time);
|
||||
|
||||
BOOL containsPosition(const LLVector3 &position);
|
||||
|
||||
|
|
@ -227,6 +228,9 @@ private:
|
|||
static S32 sTextureSize; // Size of the surface texture
|
||||
};
|
||||
|
||||
extern template bool LLSurface::idleUpdate</*PBR=*/false>(F32 max_update_time);
|
||||
extern template bool LLSurface::idleUpdate</*PBR=*/true>(F32 max_update_time);
|
||||
|
||||
|
||||
|
||||
// . __.
|
||||
|
|
|
|||
|
|
@ -268,7 +268,8 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3
|
|||
}
|
||||
|
||||
|
||||
void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
|
||||
template<>
|
||||
void LLSurfacePatch::calcNormal</*PBR=*/false>(const U32 x, const U32 y, const U32 stride)
|
||||
{
|
||||
U32 patch_width = mSurfacep->mPVArray.mPatchWidth;
|
||||
U32 surface_stride = mSurfacep->getGridsPerEdge();
|
||||
|
|
@ -420,6 +421,166 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
|
|||
*(mDataNorm + surface_stride * y + x) = normal;
|
||||
}
|
||||
|
||||
template<>
|
||||
void LLSurfacePatch::calcNormal</*PBR=*/true>(const U32 x, const U32 y, const U32 stride)
|
||||
{
|
||||
llassert(mDataNorm);
|
||||
constexpr U32 index = 0;
|
||||
|
||||
const U32 surface_stride = mSurfacep->getGridsPerEdge();
|
||||
LLVector3& normal_out = *(mDataNorm + surface_stride * y + x);
|
||||
calcNormalFlat(normal_out, x, y, index);
|
||||
}
|
||||
|
||||
// Calculate the flat normal of a triangle whose least coordinate is specified by the given x,y values.
|
||||
// If index = 0, calculate the normal of the first triangle, otherwise calculate the normal of the second.
|
||||
void LLSurfacePatch::calcNormalFlat(LLVector3& normal_out, const U32 x, const U32 y, const U32 index)
|
||||
{
|
||||
llassert(index == 0 || index == 1);
|
||||
|
||||
U32 patch_width = mSurfacep->mPVArray.mPatchWidth;
|
||||
U32 surface_stride = mSurfacep->getGridsPerEdge();
|
||||
|
||||
// Vertex stride is always 1 because we want the flat surface of the current triangle face
|
||||
constexpr U32 stride = 1;
|
||||
|
||||
const F32 mpg = mSurfacep->getMetersPerGrid() * stride;
|
||||
|
||||
S32 poffsets[2][2][2];
|
||||
poffsets[0][0][0] = x;
|
||||
poffsets[0][0][1] = y;
|
||||
|
||||
poffsets[0][1][0] = x;
|
||||
poffsets[0][1][1] = y + stride;
|
||||
|
||||
poffsets[1][0][0] = x + stride;
|
||||
poffsets[1][0][1] = y;
|
||||
|
||||
poffsets[1][1][0] = x + stride;
|
||||
poffsets[1][1][1] = y + stride;
|
||||
|
||||
const LLSurfacePatch *ppatches[2][2];
|
||||
|
||||
// LLVector3 p1, p2, p3, p4;
|
||||
|
||||
ppatches[0][0] = this;
|
||||
ppatches[0][1] = this;
|
||||
ppatches[1][0] = this;
|
||||
ppatches[1][1] = this;
|
||||
|
||||
U32 i, j;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
if (poffsets[i][j][0] < 0)
|
||||
{
|
||||
if (!ppatches[i][j]->getNeighborPatch(WEST))
|
||||
{
|
||||
poffsets[i][j][0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
poffsets[i][j][0] += patch_width;
|
||||
ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST);
|
||||
}
|
||||
}
|
||||
if (poffsets[i][j][1] < 0)
|
||||
{
|
||||
if (!ppatches[i][j]->getNeighborPatch(SOUTH))
|
||||
{
|
||||
poffsets[i][j][1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
poffsets[i][j][1] += patch_width;
|
||||
ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH);
|
||||
}
|
||||
}
|
||||
if (poffsets[i][j][0] >= (S32)patch_width)
|
||||
{
|
||||
if (!ppatches[i][j]->getNeighborPatch(EAST))
|
||||
{
|
||||
poffsets[i][j][0] = patch_width - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
poffsets[i][j][0] -= patch_width;
|
||||
ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST);
|
||||
}
|
||||
}
|
||||
if (poffsets[i][j][1] >= (S32)patch_width)
|
||||
{
|
||||
if (!ppatches[i][j]->getNeighborPatch(NORTH))
|
||||
{
|
||||
poffsets[i][j][1] = patch_width - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
poffsets[i][j][1] -= patch_width;
|
||||
ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLVector3 p00(-mpg,-mpg,
|
||||
*(ppatches[0][0]->mDataZ
|
||||
+ poffsets[0][0][0]
|
||||
+ poffsets[0][0][1]*surface_stride));
|
||||
LLVector3 p01(-mpg,+mpg,
|
||||
*(ppatches[0][1]->mDataZ
|
||||
+ poffsets[0][1][0]
|
||||
+ poffsets[0][1][1]*surface_stride));
|
||||
LLVector3 p10(+mpg,-mpg,
|
||||
*(ppatches[1][0]->mDataZ
|
||||
+ poffsets[1][0][0]
|
||||
+ poffsets[1][0][1]*surface_stride));
|
||||
LLVector3 p11(+mpg,+mpg,
|
||||
*(ppatches[1][1]->mDataZ
|
||||
+ poffsets[1][1][0]
|
||||
+ poffsets[1][1][1]*surface_stride));
|
||||
|
||||
// Triangle index / coordinate convention
|
||||
// for a single surface patch
|
||||
//
|
||||
// p01 p11
|
||||
//
|
||||
// ^ ._____.
|
||||
// | |\ |
|
||||
// | | \ 1 |
|
||||
// | | \ |
|
||||
// | 0 \ |
|
||||
// y |____\|
|
||||
//
|
||||
// p00 x ---> p10
|
||||
//
|
||||
// (z up / out of the screen due to right-handed coordinate system)
|
||||
|
||||
LLVector3 normal;
|
||||
if (index == 0)
|
||||
{
|
||||
LLVector3 c1 = p10 - p00;
|
||||
LLVector3 c2 = p01 - p00;
|
||||
|
||||
normal = c1;
|
||||
normal %= c2;
|
||||
normal.normVec();
|
||||
}
|
||||
else // index == 1
|
||||
{
|
||||
LLVector3 c1 = p11 - p01;
|
||||
LLVector3 c2 = p11 - p10;
|
||||
|
||||
normal = c1;
|
||||
normal %= c2;
|
||||
normal.normVec();
|
||||
}
|
||||
|
||||
llassert(&normal_out);
|
||||
normal_out = normal;
|
||||
}
|
||||
|
||||
const LLVector3 &LLSurfacePatch::getNormal(const U32 x, const U32 y) const
|
||||
{
|
||||
U32 surface_stride = mSurfacep->getGridsPerEdge();
|
||||
|
|
@ -517,6 +678,7 @@ void LLSurfacePatch::updateVerticalStats()
|
|||
}
|
||||
|
||||
|
||||
template<bool PBR>
|
||||
void LLSurfacePatch::updateNormals()
|
||||
{
|
||||
if (mSurfacep->mType == 'w')
|
||||
|
|
@ -534,9 +696,9 @@ void LLSurfacePatch::updateNormals()
|
|||
{
|
||||
for (j = 0; j <= grids_per_patch_edge; j++)
|
||||
{
|
||||
calcNormal(grids_per_patch_edge, j, 2);
|
||||
calcNormal(grids_per_patch_edge - 1, j, 2);
|
||||
calcNormal(grids_per_patch_edge - 2, j, 2);
|
||||
calcNormal<PBR>(grids_per_patch_edge, j, 2);
|
||||
calcNormal<PBR>(grids_per_patch_edge - 1, j, 2);
|
||||
calcNormal<PBR>(grids_per_patch_edge - 2, j, 2);
|
||||
}
|
||||
|
||||
dirty_patch = TRUE;
|
||||
|
|
@ -559,9 +721,9 @@ void LLSurfacePatch::updateNormals()
|
|||
|
||||
for (i = 0; i <= grids_per_patch_edge; i++)
|
||||
{
|
||||
calcNormal(i, grids_per_patch_edge, 2);
|
||||
calcNormal(i, grids_per_patch_edge - 1, 2);
|
||||
calcNormal(i, grids_per_patch_edge - 2, 2);
|
||||
calcNormal<PBR>(i, grids_per_patch_edge, 2);
|
||||
calcNormal<PBR>(i, grids_per_patch_edge - 1, 2);
|
||||
calcNormal<PBR>(i, grids_per_patch_edge - 2, 2);
|
||||
}
|
||||
|
||||
dirty_patch = TRUE;
|
||||
|
|
@ -582,8 +744,8 @@ void LLSurfacePatch::updateNormals()
|
|||
|
||||
for (j = 0; j < grids_per_patch_edge; j++)
|
||||
{
|
||||
calcNormal(0, j, 2);
|
||||
calcNormal(1, j, 2);
|
||||
calcNormal<PBR>(0, j, 2);
|
||||
calcNormal<PBR>(1, j, 2);
|
||||
}
|
||||
dirty_patch = TRUE;
|
||||
}
|
||||
|
|
@ -604,8 +766,8 @@ void LLSurfacePatch::updateNormals()
|
|||
|
||||
for (i = 0; i < grids_per_patch_edge; i++)
|
||||
{
|
||||
calcNormal(i, 0, 2);
|
||||
calcNormal(i, 1, 2);
|
||||
calcNormal<PBR>(i, 0, 2);
|
||||
calcNormal<PBR>(i, 1, 2);
|
||||
}
|
||||
dirty_patch = TRUE;
|
||||
}
|
||||
|
|
@ -704,10 +866,10 @@ void LLSurfacePatch::updateNormals()
|
|||
// We've got a northeast patch in the same surface.
|
||||
// The z and normals will be handled by that patch.
|
||||
}
|
||||
calcNormal(grids_per_patch_edge, grids_per_patch_edge, 2);
|
||||
calcNormal(grids_per_patch_edge, grids_per_patch_edge - 1, 2);
|
||||
calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge, 2);
|
||||
calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge - 1, 2);
|
||||
calcNormal<PBR>(grids_per_patch_edge, grids_per_patch_edge, 2);
|
||||
calcNormal<PBR>(grids_per_patch_edge, grids_per_patch_edge - 1, 2);
|
||||
calcNormal<PBR>(grids_per_patch_edge - 1, grids_per_patch_edge, 2);
|
||||
calcNormal<PBR>(grids_per_patch_edge - 1, grids_per_patch_edge - 1, 2);
|
||||
dirty_patch = TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -718,7 +880,7 @@ void LLSurfacePatch::updateNormals()
|
|||
{
|
||||
for (i=2; i < grids_per_patch_edge - 2; i++)
|
||||
{
|
||||
calcNormal(i, j, 2);
|
||||
calcNormal<PBR>(i, j, 2);
|
||||
}
|
||||
}
|
||||
dirty_patch = TRUE;
|
||||
|
|
@ -735,6 +897,9 @@ void LLSurfacePatch::updateNormals()
|
|||
}
|
||||
}
|
||||
|
||||
template void LLSurfacePatch::updateNormals</*PBR=*/false>();
|
||||
template void LLSurfacePatch::updateNormals</*PBR=*/true>();
|
||||
|
||||
void LLSurfacePatch::updateEastEdge()
|
||||
{
|
||||
U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ public:
|
|||
|
||||
void updateVerticalStats();
|
||||
void updateCompositionStats();
|
||||
template<bool PBR>
|
||||
void updateNormals();
|
||||
|
||||
void updateEastEdge();
|
||||
|
|
@ -102,9 +103,18 @@ public:
|
|||
LLVector3 getPointAgent(const U32 x, const U32 y) const; // get the point at the offset.
|
||||
LLVector2 getTexCoords(const U32 x, const U32 y) const;
|
||||
|
||||
// Per-vertex normals
|
||||
// *TODO: PBR=true is a test implementation solely for proof-of-concept.
|
||||
// Final implementation would likely be very different and may not even use
|
||||
// this function. If we decide to keep calcNormalFlat, remove index as it
|
||||
// is a debug parameter for testing.
|
||||
template<bool PBR>
|
||||
void calcNormal(const U32 x, const U32 y, const U32 stride);
|
||||
const LLVector3 &getNormal(const U32 x, const U32 y) const;
|
||||
|
||||
// Per-triangle normals for flat edges
|
||||
void calcNormalFlat(LLVector3& normal_out, const U32 x, const U32 y, const U32 index /* 0 or 1 */);
|
||||
|
||||
void eval(const U32 x, const U32 y, const U32 stride,
|
||||
LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1);
|
||||
|
||||
|
|
@ -181,5 +191,8 @@ protected:
|
|||
LLSurface *mSurfacep; // Pointer to "parent" surface
|
||||
};
|
||||
|
||||
extern template void LLSurfacePatch::updateNormals</*PBR=*/false>();
|
||||
extern template void LLSurfacePatch::updateNormals</*PBR=*/true>();
|
||||
|
||||
|
||||
#endif // LL_LLSURFACEPATCH_H
|
||||
|
|
|
|||
|
|
@ -732,7 +732,7 @@ void LLFloaterTexturePicker::draw()
|
|||
{
|
||||
mGLTFMaterial = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mImageAssetID);
|
||||
llassert(mGLTFMaterial == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(gGLTFMaterialList.getMaterial(mImageAssetID)) != nullptr);
|
||||
if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (*old_material.get() != *mGLTFMaterial.get())))
|
||||
if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (old_material.get() != mGLTFMaterial.get())))
|
||||
{
|
||||
// Only update the preview if needed, since gGLTFMaterialPreviewMgr does not cache the preview.
|
||||
if (mGLTFMaterial.isNull())
|
||||
|
|
@ -2395,7 +2395,7 @@ void LLTextureCtrl::draw()
|
|||
if (mInventoryPickType == PICK_MATERIAL)
|
||||
{
|
||||
mGLTFMaterial = gGLTFMaterialList.getMaterial(mImageAssetID);
|
||||
if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (*old_material.get() != *mGLTFMaterial.get())))
|
||||
if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (old_material.get() != mGLTFMaterial.get())))
|
||||
{
|
||||
// Only update the preview if needed, since gGLTFMaterialPreviewMgr does not cache the preview.
|
||||
if (mGLTFMaterial.isNull())
|
||||
|
|
|
|||
|
|
@ -846,8 +846,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 2")
|
||||
if (gResizeScreenTexture)
|
||||
{
|
||||
gResizeScreenTexture = FALSE;
|
||||
gPipeline.resizeScreenTexture();
|
||||
gResizeScreenTexture = FALSE;
|
||||
}
|
||||
|
||||
gGL.setColorMask(true, true);
|
||||
|
|
|
|||
|
|
@ -2441,6 +2441,20 @@ class LLAdvancedPurgeShaderCache : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
/////////////////////
|
||||
// REBUILD TERRAIN //
|
||||
/////////////////////
|
||||
|
||||
|
||||
class LLAdvancedRebuildTerrain : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
gPipeline.rebuildTerrain();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////
|
||||
// EVENT Recorder //
|
||||
///////////////////
|
||||
|
|
@ -12282,6 +12296,10 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");
|
||||
view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark");
|
||||
view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache");
|
||||
if (gSavedSettings.get<bool>("RenderTerrainPBREnabled"))
|
||||
{
|
||||
view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain");
|
||||
}
|
||||
//[FIX FIRE-1927 - enable DoubleClickTeleport shortcut : SJ]
|
||||
view_listener_t::addMenu(new FSAdvancedToggleDoubleClickAction, "Advanced.SetDoubleClickAction");
|
||||
view_listener_t::addMenu(new FSAdvancedCheckEnabledDoubleClickAction, "Advanced.CheckEnabledDoubleClickAction");
|
||||
|
|
|
|||
|
|
@ -1190,6 +1190,11 @@ void LLViewerRegion::dirtyHeights()
|
|||
}
|
||||
}
|
||||
|
||||
void LLViewerRegion::dirtyAllPatches()
|
||||
{
|
||||
getLand().dirtyAllPatches();
|
||||
}
|
||||
|
||||
//physically delete the cache entry
|
||||
void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry, bool for_rendering)
|
||||
{
|
||||
|
|
@ -1690,7 +1695,19 @@ void LLViewerRegion::idleUpdate(F32 max_update_time)
|
|||
|
||||
mLastUpdate = LLViewerOctreeEntryData::getCurrentFrame();
|
||||
|
||||
mImpl->mLandp->idleUpdate(max_update_time);
|
||||
static bool pbr_terrain_enabled = gSavedSettings.get<bool>("RenderTerrainPBREnabled");
|
||||
static LLCachedControl<bool> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", FALSE);
|
||||
bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR);
|
||||
bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals;
|
||||
|
||||
if (!pbr_land)
|
||||
{
|
||||
mImpl->mLandp->idleUpdate</*PBR=*/false>(max_update_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
mImpl->mLandp->idleUpdate</*PBR=*/true>(max_update_time);
|
||||
}
|
||||
|
||||
if (mParcelOverlay)
|
||||
{
|
||||
|
|
@ -1992,7 +2009,21 @@ LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* o
|
|||
// As above, but forcibly do the update.
|
||||
void LLViewerRegion::forceUpdate()
|
||||
{
|
||||
mImpl->mLandp->idleUpdate(0.f);
|
||||
constexpr F32 max_update_time = 0.f;
|
||||
|
||||
static bool pbr_terrain_enabled = gSavedSettings.get<BOOL>("RenderTerrainPBREnabled");
|
||||
static LLCachedControl<BOOL> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", FALSE);
|
||||
bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR);
|
||||
bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals;
|
||||
|
||||
if (!pbr_land)
|
||||
{
|
||||
mImpl->mLandp->idleUpdate</*PBR=*/false>(max_update_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
mImpl->mLandp->idleUpdate</*PBR=*/true>(max_update_time);
|
||||
}
|
||||
|
||||
if (mParcelOverlay)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -175,6 +175,9 @@ public:
|
|||
// Call this whenever you change the height data in the region.
|
||||
// (Automatically called by LLSurfacePatch's update routine)
|
||||
void dirtyHeights();
|
||||
// Call this whenever you want to force all terrain to rebuild.
|
||||
// (For example, if a global terrain config option has changed)
|
||||
void dirtyAllPatches();
|
||||
|
||||
LLViewerParcelOverlay *getParcelOverlay() const
|
||||
{ return mParcelOverlay; }
|
||||
|
|
|
|||
|
|
@ -91,6 +91,8 @@ LLGLSLShader gTwoTextureCompareProgram;
|
|||
LLGLSLShader gOneTextureFilterProgram;
|
||||
LLGLSLShader gDebugProgram;
|
||||
LLGLSLShader gSkinnedDebugProgram;
|
||||
LLGLSLShader gNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT];
|
||||
LLGLSLShader gSkinnedNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT];
|
||||
LLGLSLShader gClipProgram;
|
||||
LLGLSLShader gAlphaMaskProgram;
|
||||
LLGLSLShader gBenchmarkProgram;
|
||||
|
|
@ -2727,6 +2729,33 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
|
|||
success = success && gDebugProgram.createShader(NULL, NULL);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
for (S32 variant = 0; variant < NORMAL_DEBUG_SHADER_COUNT; ++variant)
|
||||
{
|
||||
LLGLSLShader& shader = gNormalDebugProgram[variant];
|
||||
LLGLSLShader& skinned_shader = gSkinnedNormalDebugProgram[variant];
|
||||
shader.mName = "Normal Debug Shader";
|
||||
shader.mShaderFiles.clear();
|
||||
shader.mShaderFiles.push_back(make_pair("interface/normaldebugV.glsl", GL_VERTEX_SHADER));
|
||||
// *NOTE: Geometry shaders have a reputation for being slow.
|
||||
// Consider using compute shaders instead, which have a reputation
|
||||
// for being fast. This geometry shader in particular seems to run
|
||||
// fine on my machine, but I won't vouch for this in
|
||||
// performance-critical areas. -Cosmic,2023-09-28
|
||||
shader.mShaderFiles.push_back(make_pair("interface/normaldebugG.glsl", GL_GEOMETRY_SHADER));
|
||||
shader.mShaderFiles.push_back(make_pair("interface/normaldebugF.glsl", GL_FRAGMENT_SHADER));
|
||||
shader.mRiggedVariant = &skinned_shader;
|
||||
shader.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
|
||||
if (variant == NORMAL_DEBUG_SHADER_WITH_TANGENTS)
|
||||
{
|
||||
shader.addPermutation("HAS_ATTRIBUTE_TANGENT", "1");
|
||||
}
|
||||
success = make_rigged_variant(shader, skinned_shader);
|
||||
success = success && shader.createShader(NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
gClipProgram.mName = "Clip Shader";
|
||||
|
|
|
|||
|
|
@ -156,6 +156,14 @@ extern LLGLSLShader gRadianceGenProgram;
|
|||
extern LLGLSLShader gIrradianceGenProgram;
|
||||
extern LLGLSLShader gGlowCombineFXAAProgram;
|
||||
extern LLGLSLShader gDebugProgram;
|
||||
enum NormalDebugShaderVariant : S32
|
||||
{
|
||||
NORMAL_DEBUG_SHADER_DEFAULT,
|
||||
NORMAL_DEBUG_SHADER_WITH_TANGENTS,
|
||||
NORMAL_DEBUG_SHADER_COUNT
|
||||
};
|
||||
extern LLGLSLShader gNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT];
|
||||
extern LLGLSLShader gSkinnedNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT];
|
||||
extern LLGLSLShader gClipProgram;
|
||||
extern LLGLSLShader gBenchmarkProgram;
|
||||
extern LLGLSLShader gReflectionProbeDisplayProgram;
|
||||
|
|
|
|||
|
|
@ -214,6 +214,7 @@ BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable)
|
|||
|
||||
void LLVOSurfacePatch::updateFaceSize(S32 idx)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (idx != 0)
|
||||
{
|
||||
LL_WARNS() << "Terrain partition requested invalid face!!!" << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -177,7 +177,6 @@ F32 LLPipeline::CameraFocusTransitionTime;
|
|||
F32 LLPipeline::CameraFNumber;
|
||||
F32 LLPipeline::CameraFocalLength;
|
||||
F32 LLPipeline::CameraFieldOfView;
|
||||
S32 LLPipeline::RenderLocalLightCount;
|
||||
F32 LLPipeline::RenderShadowNoise;
|
||||
F32 LLPipeline::RenderShadowBlurSize;
|
||||
F32 LLPipeline::RenderSSAOScale;
|
||||
|
|
@ -564,7 +563,6 @@ void LLPipeline::init()
|
|||
connectRefreshCachedSettingsSafe("CameraFNumber");
|
||||
connectRefreshCachedSettingsSafe("CameraFocalLength");
|
||||
connectRefreshCachedSettingsSafe("CameraFieldOfView");
|
||||
connectRefreshCachedSettingsSafe("RenderLocalLightCount");
|
||||
connectRefreshCachedSettingsSafe("RenderShadowNoise");
|
||||
connectRefreshCachedSettingsSafe("RenderShadowBlurSize");
|
||||
connectRefreshCachedSettingsSafe("RenderSSAOScale");
|
||||
|
|
@ -1125,7 +1123,6 @@ void LLPipeline::refreshCachedSettings()
|
|||
CameraFNumber = gSavedSettings.getF32("CameraFNumber");
|
||||
CameraFocalLength = gSavedSettings.getF32("CameraFocalLength");
|
||||
CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView");
|
||||
RenderLocalLightCount = gSavedSettings.getS32("RenderLocalLightCount");
|
||||
RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise");
|
||||
RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize");
|
||||
RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale");
|
||||
|
|
@ -5401,7 +5398,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
|
|||
return;
|
||||
}
|
||||
|
||||
const S32 local_light_count = LLPipeline::RenderLocalLightCount;
|
||||
static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
|
||||
|
||||
if (local_light_count >= 1)
|
||||
{
|
||||
|
|
@ -5670,7 +5667,7 @@ void LLPipeline::setupHWLights()
|
|||
|
||||
mLightMovingMask = 0;
|
||||
|
||||
const S32 local_light_count = LLPipeline::RenderLocalLightCount;
|
||||
static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
|
||||
|
||||
if (local_light_count >= 1)
|
||||
{
|
||||
|
|
@ -8177,7 +8174,7 @@ void LLPipeline::renderDeferredLighting()
|
|||
unbindDeferredShader(gDeferredSoftenProgram);
|
||||
}
|
||||
|
||||
const S32 local_light_count = LLPipeline::RenderLocalLightCount;
|
||||
static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
|
||||
|
||||
if (local_light_count > 0)
|
||||
{
|
||||
|
|
@ -8456,6 +8453,7 @@ void LLPipeline::renderDeferredLighting()
|
|||
LLPipeline::RENDER_TYPE_CONTROL_AV,
|
||||
LLPipeline::RENDER_TYPE_ALPHA_MASK,
|
||||
LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
|
||||
LLPipeline::RENDER_TYPE_TERRAIN,
|
||||
LLPipeline::RENDER_TYPE_WATER,
|
||||
END_RENDER_TYPES);
|
||||
|
||||
|
|
@ -11139,6 +11137,16 @@ void LLPipeline::rebuildDrawInfo()
|
|||
}
|
||||
}
|
||||
|
||||
void LLPipeline::rebuildTerrain()
|
||||
{
|
||||
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
|
||||
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
|
||||
{
|
||||
LLViewerRegion* region = *iter;
|
||||
region->dirtyAllPatches();
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Reset VB during TP
|
||||
void LLPipeline::initDeferredVB()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -134,6 +134,8 @@ public:
|
|||
|
||||
// rebuild all LLVOVolume render batches
|
||||
void rebuildDrawInfo();
|
||||
// Rebuild all terrain
|
||||
void rebuildTerrain();
|
||||
|
||||
// Clear LLFace mVertexBuffer pointers
|
||||
void resetVertexBuffers(LLDrawable* drawable);
|
||||
|
|
@ -1041,7 +1043,6 @@ public:
|
|||
static F32 CameraFNumber;
|
||||
static F32 CameraFocalLength;
|
||||
static F32 CameraFieldOfView;
|
||||
static S32 RenderLocalLightCount;
|
||||
static F32 RenderShadowNoise;
|
||||
static F32 RenderShadowBlurSize;
|
||||
static F32 RenderSSAOScale;
|
||||
|
|
|
|||
|
|
@ -528,6 +528,7 @@
|
|||
<menu_item_check label="Angehängte Partikel rendern" name="Render Attached Particles"/>
|
||||
<menu_item_check label="Shader-Cache aktivieren" name="Enable Shader Cache"/>
|
||||
<menu_item_call label="Shader-Cache bereinigen" name="Shader Cache Clear"/>
|
||||
<menu_item_call label="Terrain neu erstellen" name="Rebuild Terrain"/>
|
||||
</menu>
|
||||
<menu label="Netzwerk" name="Network">
|
||||
<menu_item_check label="Agent pausieren" name="AgentPause"/>
|
||||
|
|
|
|||
|
|
@ -4599,6 +4599,13 @@
|
|||
<menu_item_call.on_click
|
||||
function="Advanced.ClearShaderCache" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
enabled="true"
|
||||
label="Rebuild Terrain"
|
||||
name="Rebuild Terrain">
|
||||
<menu_item_call.on_click
|
||||
function="Advanced.RebuildTerrain" />
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
|
||||
<menu
|
||||
|
|
|
|||
Loading…
Reference in New Issue