diff options
32 files changed, 788 insertions, 295 deletions
| diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 849c10d62e..dee1ca24ab 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -33,6 +33,9 @@ jobs:        AUTOBUILD_GITHUB_TOKEN: ${{ secrets.SHARED_AUTOBUILD_GITHUB_TOKEN }}        AUTOBUILD_INSTALLABLE_CACHE: ${{ github.workspace }}/.autobuild-installables        AUTOBUILD_VARIABLES_FILE: ${{ github.workspace }}/.build-variables/variables +      # Direct autobuild to store vcs_url, vcs_branch and vcs_revision in +      # autobuild-package.xml. +      AUTOBUILD_VCS_INFO: "true"        AUTOBUILD_VSVER: "170"        DEVELOPER_DIR: ${{ matrix.developer_dir }}        # Ensure that Linden viewer builds engage Bugsplat. @@ -96,10 +99,17 @@ jobs:          if: runner.os == 'Windows'          run: choco install nsis-unicode +      - name: Determine source branch +        id: which-branch +        uses: secondlife/viewer-build-util/which-branch@v1 +        with: +          token: ${{ github.token }} +        - name: Build          id: build          shell: bash          env: +          AUTOBUILD_VCS_BRANCH: ${{ steps.which-branch.outputs.branch }}            RUNNER_OS: ${{ runner.os }}          run: |            # set up things the viewer's build.sh script expects @@ -150,7 +160,7 @@ jobs:            }            repo_branch()            { -            git -C "$1" branch | grep '^* ' | cut -c 3- +            echo "$AUTOBUILD_VCS_BRANCH"            }            record_dependencies_graph()            { diff --git a/autobuild.xml b/autobuild.xml index 8d73bf1fb4..531b3586d6 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1582,18 +1582,6 @@              <key>name</key>              <string>linux64</string>            </map> -          <key>windows</key> -          <map> -            <key>archive</key> -            <map> -              <key>hash</key> -              <string>2e5f1f7046a49d8b0bc295aa878116bc</string> -              <key>url</key> -              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/60043/564063/llphysicsextensions_stub-1.0.542456-windows-542456.tar.bz2</string> -            </map> -            <key>name</key> -            <string>windows</string> -          </map>          </map>          <key>license</key>          <string>internal</string> @@ -1734,18 +1722,6 @@        </map>        <key>mikktspace</key>        <map> -        <key>canonical_repo</key> -        <string>https://bitbucket.org/lindenlab/3p-mikktspace</string> -        <key>copyright</key> -        <string>Copyright (C) 2011 by Morten S. Mikkelsen</string> -        <key>description</key> -        <string>Mikktspace Tangent Generator</string> -        <key>license</key> -        <string>Copyright (C) 2011 by Morten S. Mikkelsen</string> -        <key>license_file</key> -        <string>mikktspace.txt</string> -        <key>name</key> -        <string>mikktspace</string>          <key>platforms</key>          <map>            <key>darwin64</key> @@ -1753,40 +1729,58 @@              <key>archive</key>              <map>                <key>hash</key> -              <string>b48b7ac0792d3ea8f087d99d9e4a29d8</string> +              <string>6cc1585dba85b0226a2e7033a7e2a2ceaae7c983</string> +              <key>hash_algorithm</key> +              <string>sha1</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104415/914944/mikktspace-1-darwin64-574859.tar.bz2</string> +              <string>https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-darwin64-5cee1f4.tar.zst</string>              </map>              <key>name</key>              <string>darwin64</string>            </map> -          <key>windows</key> +          <key>windows64</key>            <map>              <key>archive</key>              <map>                <key>hash</key> -              <string>0a016b9c0c1e2c0b557e0124094da6c5</string> +              <string>6b7d01ad54e4a88a001f66840c32329cedb28202</string> +              <key>hash_algorithm</key> +              <string>sha1</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104407/914918/mikktspace-1-windows-574859.tar.bz2</string> +              <string>https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-windows64-5cee1f4.tar.zst</string>              </map>              <key>name</key> -            <string>windows</string> +            <string>windows64</string>            </map> -          <key>windows64</key> +          <key>linux64</key>            <map>              <key>archive</key>              <map>                <key>hash</key> -              <string>02e9e5b6fe6788f4d2babb83ec544843</string> +              <string>edc9782bf209e17ad1845498b42f16d733582082</string> +              <key>hash_algorithm</key> +              <string>sha1</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104406/914909/mikktspace-1-windows64-574859.tar.bz2</string> +              <string>https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-linux64-5cee1f4.tar.zst</string>              </map>              <key>name</key> -            <string>windows64</string> +            <string>linux64</string>            </map>          </map> +        <key>license</key> +        <string>Copyright (C) 2011 by Morten S. Mikkelsen</string> +        <key>license_file</key> +        <string>mikktspace.txt</string> +        <key>copyright</key> +        <string>Copyright (C) 2011 by Morten S. Mikkelsen</string>          <key>version</key>          <string>1</string> +        <key>name</key> +        <string>mikktspace</string> +        <key>canonical_repo</key> +        <string>https://bitbucket.org/lindenlab/3p-mikktspace</string> +        <key>description</key> +        <string>Mikktspace Tangent Generator</string>        </map>        <key>minizip-ng</key>        <map> @@ -2376,18 +2370,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>        </map>        <key>tinygltf</key>        <map> -        <key>canonical_repo</key> -        <string>https://bitbucket.org/lindenlab/3p-tinygltf</string> -        <key>copyright</key> -        <string>// Copyright (c) 2015 - Present Syoyo Fujita, Aurélien Chatelain and many contributors.</string> -        <key>description</key> -        <string>tinygltf import library</string> -        <key>license</key> -        <string>MIT</string> -        <key>license_file</key> -        <string>LICENSES/tinygltf_license.txt</string> -        <key>name</key> -        <string>tinygltf</string>          <key>platforms</key>          <map>            <key>common</key> @@ -2395,20 +2377,34 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>              <key>archive</key>              <map>                <key>hash</key> -              <string>4dad1c0948141e1667c01a3ee755e4dc</string> +              <string>2c47ae2d0c38c86b8c2db8d9317f0ab15edfc74f</string> +              <key>hash_algorithm</key> +              <string>sha1</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105849/926137/tinygltf-v2.5.0-common-575729.tar.bz2</string> +              <string>https://github.com/secondlife/3p-tinygltf/releases/download/v2.5.0-1ae57fd/tinygltf-v2.5.0-common-1ae57fd.tar.zst</string>              </map>              <key>name</key>              <string>common</string>            </map>          </map> +        <key>license</key> +        <string>MIT</string> +        <key>license_file</key> +        <string>LICENSES/tinygltf_license.txt</string> +        <key>copyright</key> +        <string>// Copyright (c) 2015 - Present Syoyo Fujita, Aurélien Chatelain and many contributors.</string> +        <key>version</key> +        <string>v2.5.0</string> +        <key>name</key> +        <string>tinygltf</string> +        <key>canonical_repo</key> +        <string>https://bitbucket.org/lindenlab/3p-tinygltf</string> +        <key>description</key> +        <string>tinygltf import library</string>          <key>source</key>          <string>https://bitbucket.org/lindenlab/3p-tinygltf</string>          <key>source_type</key>          <string>git</string> -        <key>version</key> -        <string>v2.5.0</string>        </map>        <key>tracy</key>        <map> @@ -2419,9 +2415,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>              <key>archive</key>              <map>                <key>hash</key> -              <string>9b6e1a1f4b0969d38a1ca8ee00aeb548</string> +              <string>49650353442698c3e05102676fe427d0ebe02f0b</string> +              <key>hash_algorithm</key> +              <string>sha1</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110584/960613/tracy-v0.8.1.578241-darwin64-578241.tar.bz2</string> +              <string>https://github.com/secondlife/3p-tracy/releases/download/v0.8.1-eecbf72/tracy-v0.8.1-eecbf72-darwin64-eecbf72.tar.zst</string>              </map>              <key>name</key>              <string>darwin64</string> @@ -2431,11 +2429,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>              <key>archive</key>              <map>                <key>hash</key> -              <string>05b72ae5d733aed7d3bf142287601cc6</string> +              <string>2b80e7407e4f3e82eff3879add0e9ad63e7fcace</string>                <key>hash_algorithm</key> -              <string>md5</string> +              <string>sha1</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110586/960637/tracy-v0.8.1.578241-windows64-578241.tar.bz2</string> +              <string>https://github.com/secondlife/3p-tracy/releases/download/v0.8.1-eecbf72/tracy-v0.8.1-eecbf72-windows64-eecbf72.tar.zst</string>              </map>              <key>name</key>              <string>windows64</string> @@ -2448,7 +2446,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>          <key>copyright</key>          <string>Copyright (c) 2017-2022, Bartosz Taudul (wolf@nereid.pl)</string>          <key>version</key> -        <string>v0.8.1.235e98f</string> +        <string>v0.8.1-eecbf72</string>          <key>name</key>          <string>tracy</string>          <key>canonical_repo</key> @@ -2459,8 +2457,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>          <string>https://bitbucket.org/lindenlab/3p-tracy</string>          <key>source_type</key>          <string>git</string> -        <key>version</key> -        <string>v0.8.1.578241</string>        </map>        <key>tut</key>        <map> @@ -2724,59 +2720,37 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>        </map>        <key>vulkan_gltf</key>        <map> -        <key>canonical_repo</key> -        <string>https://bitbucket.org/lindenlab/3p-vulkan-gltf-pbr</string> -        <key>copyright</key> -        <string>Copyright (c) 2018 Sascha Willems</string> -        <key>description</key> -        <string>Vulkan GLTF Sample Implementation</string> -        <key>license</key> -        <string>Copyright (c) 2018 Sascha Willems</string> -        <key>license_file</key> -        <string>LICENSES/vulkan_gltf.txt</string> -        <key>name</key> -        <string>vulkan_gltf</string>          <key>platforms</key>          <map> -          <key>darwin64</key> -          <map> -            <key>archive</key> -            <map> -              <key>hash</key> -              <string>8cff2060843db3db788511ee34a8e8cc</string> -              <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101316/891509/vulkan_gltf-1-darwin64-572743.tar.bz2</string> -            </map> -            <key>name</key> -            <string>darwin64</string> -          </map> -          <key>windows</key> -          <map> -            <key>archive</key> -            <map> -              <key>hash</key> -              <string>58eea384be49ba756ce9c5e66669540b</string> -              <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101318/891520/vulkan_gltf-1-windows-572743.tar.bz2</string> -            </map> -            <key>name</key> -            <string>windows</string> -          </map> -          <key>windows64</key> +          <key>common</key>            <map>              <key>archive</key>              <map>                <key>hash</key> -              <string>79b6a11622c2f83cfc2b7cd1fafb867b</string> +              <string>8e365eff8dcace48d91e2530f8b13e420849aefc</string> +              <key>hash_algorithm</key> +              <string>sha1</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101319/891521/vulkan_gltf-1-windows64-572743.tar.bz2</string> +              <string>https://github.com/secondlife/3p-vulkan-gltf-pbr/releases/download/v1.0.0-d7c372f/vulkan_gltf-1.0.0-common-d7c372f.tar.zst</string>              </map>              <key>name</key> -            <string>windows64</string> +            <string>common</string>            </map>          </map> +        <key>license</key> +        <string>Copyright (c) 2018 Sascha Willems</string> +        <key>license_file</key> +        <string>vulkan_gltf.txt</string> +        <key>copyright</key> +        <string>Copyright (c) 2018 Sascha Willems</string>          <key>version</key> -        <string>1</string> +        <string>1.0.0</string> +        <key>name</key> +        <string>vulkan_gltf</string> +        <key>canonical_repo</key> +        <string>https://bitbucket.org/lindenlab/3p-vulkan-gltf-pbr</string> +        <key>description</key> +        <string>Vulkan GLTF Sample Implementation</string>        </map>        <key>xxhash</key>        <map> @@ -2787,54 +2761,14 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>              <key>archive</key>              <map>                <key>hash</key> -              <string>e4f77ba0a9b8ec3cc3fabc51c4da81d2</string> -              <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110070/956941/xxhash-0.8.1.578006-windows-578006.tar.bz2</string> -            </map> -            <key>name</key> -            <string>common</string> -          </map> -          <key>darwin64</key> -          <map> -            <key>archive</key> -            <map> -              <key>hash</key> -              <string>fdcc803a76a3359bb426db7dac161406676d51e7</string> +              <string>1a73c476b371b62066d1c3eced249660e9467e53</string>                <key>hash_algorithm</key>                <string>sha1</string>                <key>url</key> -              <string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-darwin64-7501c90.tar.zst</string> +              <string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1-69ff69a/xxhash-0.8.1-69ff69a-common-69ff69a.tar.zst</string>              </map>              <key>name</key> -            <string>darwin64</string> -          </map> -          <key>linux64</key> -          <map> -            <key>archive</key> -            <map> -              <key>hash</key> -              <string>7acb3f94a549fbb9bd7bc16604e34f33c5365a9b</string> -              <key>hash_algorithm</key> -              <string>sha1</string> -              <key>url</key> -              <string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-linux64-7501c90.tar.zst</string> -            </map> -            <key>name</key> -            <string>linux64</string> -          </map> -          <key>windows64</key> -          <map> -            <key>archive</key> -            <map> -              <key>hash</key> -              <string>4522d075ea4703ef4b527c3039864ef735ea7953</string> -              <key>hash_algorithm</key> -              <string>sha1</string> -              <key>url</key> -              <string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-windows64-7501c90.tar.zst</string> -            </map> -            <key>name</key> -            <string>windows64</string> +            <string>common</string>            </map>          </map>          <key>license</key> @@ -2844,7 +2778,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>          <key>copyright</key>          <string>Copyright (c) 2012-2021 Yann Collet</string>          <key>version</key> -        <string>0.8.1.7501c90</string> +        <string>0.8.1-69ff69a</string>          <key>name</key>          <string>xxhash</string>          <key>description</key> diff --git a/doc/testplans/optimize_away_alpha.md b/doc/testplans/optimize_away_alpha.md new file mode 100644 index 0000000000..f0c8d1e8d6 --- /dev/null +++ b/doc/testplans/optimize_away_alpha.md @@ -0,0 +1,5 @@ +Textures imported via Build->Upload->Material that have an all opaque (255) alpha channel should have their alpha channel removed before upload. + +1. Make 4 images that have different colors but all 255 alpha channels +2. Upload them all using Build->Upload->Material, with one in each of the material texture slots +3. Verify that using the textures as a blinn-phong diffuse map does not make the corresponding face render in the alpha pass (face should stay visible after disabling alpha pass by unchecking Advanced->Render Types->Alpha). diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp index 1b48e4daf3..473b3ebdc9 100644 --- a/indra/llcommon/indra_constants.cpp +++ b/indra/llcommon/indra_constants.cpp @@ -50,6 +50,7 @@ const LLUUID IMG_FIRE			("aca40aa8-44cf-44ca-a0fa-93e1a2986f82"); // dataserver  const LLUUID IMG_FACE_SELECT    ("a85ac674-cb75-4af6-9499-df7c5aaf7a28"); // face selector  const LLUUID IMG_DEFAULT_AVATAR ("c228d1cf-4b5d-4ba8-84f4-899a0796aa97"); // dataserver  const LLUUID IMG_INVISIBLE		("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver +const LLUUID IMG_WHITE          ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver  const LLUUID IMG_EXPLOSION				("68edcf47-ccd7-45b8-9f90-1649d7f12806"); // On dataserver  const LLUUID IMG_EXPLOSION_2			("21ce046c-83fe-430a-b629-c7660ac78d7c"); // On dataserver @@ -71,6 +72,11 @@ const LLUUID TERRAIN_ROCK_DETAIL		("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // V  const LLUUID DEFAULT_WATER_NORMAL		("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER +const LLUUID DEFAULT_OBJECT_TEXTURE     ("89556747-24cb-43ed-920b-47caed15465f"); // On dataserver +const LLUUID DEFAULT_OBJECT_SPECULAR    ("87e0e8f7-8729-1ea8-cfc9-8915773009db"); // On dataserver +const LLUUID DEFAULT_OBJECT_NORMAL      ("85f28839-7a1c-b4e3-d71d-967792970a7b"); // On dataserver +const LLUUID BLANK_OBJECT_NORMAL        ("5b53359e-59dd-d8a2-04c3-9e65134da47a"); // VIEWER (has a verion on dataserver, but with compression artifacts) +  const LLUUID IMG_USE_BAKED_HEAD  ("5a9f4a74-30f2-821c-b88d-70499d3e7183");  const LLUUID IMG_USE_BAKED_UPPER ("ae2de45c-d252-50b8-5c6e-19f39ce79317");  const LLUUID IMG_USE_BAKED_LOWER ("24daea5f-0539-cfcf-047f-fbc40b2786ba"); diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 679f79039b..a16cfac2b9 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -197,6 +197,7 @@ LL_COMMON_API extern const LLUUID IMG_FIRE;  LL_COMMON_API extern const LLUUID IMG_FACE_SELECT;  LL_COMMON_API extern const LLUUID IMG_DEFAULT_AVATAR;  LL_COMMON_API extern const LLUUID IMG_INVISIBLE; +LL_COMMON_API extern const LLUUID IMG_WHITE;  LL_COMMON_API extern const LLUUID IMG_EXPLOSION;  LL_COMMON_API extern const LLUUID IMG_EXPLOSION_2; @@ -230,6 +231,10 @@ LL_COMMON_API extern const LLUUID IMG_USE_BAKED_AUX3;  LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL; +LL_COMMON_API extern const LLUUID DEFAULT_OBJECT_TEXTURE; +LL_COMMON_API extern const LLUUID DEFAULT_OBJECT_SPECULAR; +LL_COMMON_API extern const LLUUID DEFAULT_OBJECT_NORMAL; +LL_COMMON_API extern const LLUUID BLANK_OBJECT_NORMAL;  // radius within which a chat message is fully audible  const F32 CHAT_NORMAL_RADIUS = 20.f; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index e974fb636d..d510e061a2 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -595,11 +595,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"); @@ -1465,6 +1476,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; diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 2c66965344..eb13418cd7 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -316,6 +316,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 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ef51c7f0dc..589d079acd 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3244,17 +3244,6 @@        <key>Value</key>        <integer>0</integer>      </map> -  <key>DefaultBlankNormalTexture</key> -  <map> -    <key>Comment</key> -    <string>Texture used as 'Blank' in texture picker for normal maps. (UUID texture reference)</string> -    <key>Persist</key> -    <integer>1</integer> -    <key>Type</key> -    <string>String</string> -    <key>Value</key> -    <string>5b53359e-59dd-d8a2-04c3-9e65134da47a</string> -  </map>  	<key>DefaultFemaleAvatar</key>  	<map>  	  <key>Comment</key> @@ -3288,39 +3277,6 @@  	  <key>Value</key>  	  <string>Male Shape & Outfit</string>  	</map> -  <key>DefaultObjectNormalTexture</key> -  <map> -    <key>Comment</key> -    <string>Texture used as 'Default' in texture picker for normal map. (UUID texture reference)</string> -    <key>Persist</key> -    <integer>1</integer> -    <key>Type</key> -    <string>String</string> -    <key>Value</key> -    <string>85f28839-7a1c-b4e3-d71d-967792970a7b</string> -  </map> -  <key>DefaultObjectSpecularTexture</key> -  <map> -    <key>Comment</key> -    <string>Texture used as 'Default' in texture picker for specular map. (UUID texture reference)</string> -    <key>Persist</key> -    <integer>1</integer> -    <key>Type</key> -    <string>String</string> -    <key>Value</key> -    <string>87e0e8f7-8729-1ea8-cfc9-8915773009db</string> -  </map> -  <key>DefaultObjectTexture</key> -    <map> -      <key>Comment</key> -      <string>Texture used as 'Default' in texture picker. (UUID texture reference)</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>String</string> -      <key>Value</key> -      <string>89556747-24cb-43ed-920b-47caed15465f</string> -    </map>      <key>DefaultUploadCost</key>      <map>        <key>Comment</key> @@ -10921,6 +10877,17 @@        <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> @@ -13708,17 +13675,6 @@        <key>Value</key>        <string>F3E07BC8-A973-476D-8C7F-F3B7293975D1</string>      </map> -    <key>UIImgWhiteUUID</key> -    <map> -      <key>Comment</key> -      <string /> -      <key>Persist</key> -      <integer>0</integer> -      <key>Type</key> -      <string>String</string> -      <key>Value</key> -      <string>5748decc-f629-461c-9a36-a35a221fe21f</string> -    </map>      <key>UILineEditorCursorThickness</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl new file mode 100644 index 0000000000..388042e7e0 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl @@ -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)); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl new file mode 100644 index 0000000000..ea04ce1cae --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl @@ -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); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl new file mode 100644 index 0000000000..d1596b9d2a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl @@ -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 +} + diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp index c64ee5a69c..c98afefa65 100644 --- a/indra/newview/llfloaterenvironmentadjust.cpp +++ b/indra/newview/llfloaterenvironmentadjust.cpp @@ -116,7 +116,7 @@ BOOL LLFloaterEnvironmentAdjust::postBuild()      getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setAllowNoTexture(TRUE);      getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setDefaultImageAssetID(LLSettingsWater::GetDefaultWaterNormalAssetId()); -    getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setBlankImageAssetID(LLUUID(gSavedSettings.getString("DefaultBlankNormalTexture"))); +    getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setBlankImageAssetID(BLANK_OBJECT_NORMAL);      getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onWaterMapChanged(); });      getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setCommitCallback([this](LLUICtrl*, const LLSD&) { onReflectionProbeAmbianceChanged(); }); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 45bb350e1f..f939418893 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -449,9 +449,7 @@ BOOL LLMaterialEditor::postBuild()      mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY));      mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); -    // should match normal textures from mBumpyTextureCtrl -    mNormalTextureCtrl->setDefaultImageAssetID(LLUUID(gSavedSettings.getString("DefaultObjectNormalTexture"))); -    mNormalTextureCtrl->setBlankImageAssetID(LLUUID(gSavedSettings.getString("DefaultBlankNormalTexture"))); +    mNormalTextureCtrl->setBlankImageAssetID(BLANK_OBJECT_NORMAL);      if (mIsOverride)      { diff --git a/indra/newview/llpaneleditwater.cpp b/indra/newview/llpaneleditwater.cpp index a09964e17d..cf536dd87e 100644 --- a/indra/newview/llpaneleditwater.cpp +++ b/indra/newview/llpaneleditwater.cpp @@ -89,7 +89,7 @@ BOOL LLPanelSettingsWaterMainTab::postBuild()      getChild<LLUICtrl>(FIELD_WATER_UNDERWATER_MOD)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFogUnderWaterChanged(); });      mTxtNormalMap->setDefaultImageAssetID(LLSettingsWater::GetDefaultWaterNormalAssetId()); -    mTxtNormalMap->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" ))); +    mTxtNormalMap->setBlankImageAssetID(BLANK_OBJECT_NORMAL);      mTxtNormalMap->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNormalMapChanged(); });      getChild<LLUICtrl>(FIELD_WATER_WAVE2_XY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSmallWaveChanged(); }); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index a9ff21a2dd..753601d98e 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -336,7 +336,7 @@ BOOL	LLPanelFace::postBuild()  	mTextureCtrl = getChild<LLTextureCtrl>("texture control");  	if(mTextureCtrl)  	{ -		mTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectTexture" ))); +		mTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_TEXTURE);  		mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) );  		mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );  		mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) ); @@ -353,7 +353,7 @@ BOOL	LLPanelFace::postBuild()  	mShinyTextureCtrl = getChild<LLTextureCtrl>("shinytexture control");  	if(mShinyTextureCtrl)  	{ -		mShinyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectSpecularTexture" ))); +		mShinyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_SPECULAR);  		mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) );  		mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) );  		mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) ); @@ -370,8 +370,8 @@ BOOL	LLPanelFace::postBuild()  	mBumpyTextureCtrl = getChild<LLTextureCtrl>("bumpytexture control");  	if(mBumpyTextureCtrl)  	{ -		mBumpyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectNormalTexture" ))); -		mBumpyTextureCtrl->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" ))); +		mBumpyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_NORMAL); +		mBumpyTextureCtrl->setBlankImageAssetID(BLANK_OBJECT_NORMAL);  		mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) );  		mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) );  		mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) ); @@ -4414,7 +4414,7 @@ void LLPanelFace::onCopyTexture()                          LLUUID id = mat_data["NormMap"].asUUID();                          if (id.notNull() && !get_can_copy_texture(id))                          { -                            mat_data["NormMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); +                            mat_data["NormMap"] = DEFAULT_OBJECT_TEXTURE;                              mat_data["NormMapNoCopy"] = true;                          } @@ -4424,7 +4424,7 @@ void LLPanelFace::onCopyTexture()                          LLUUID id = mat_data["SpecMap"].asUUID();                          if (id.notNull() && !get_can_copy_texture(id))                          { -                            mat_data["SpecMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); +                            mat_data["SpecMap"] = DEFAULT_OBJECT_TEXTURE;                              mat_data["SpecMapNoCopy"] = true;                          } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 931880a475..40e8e526d1 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -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" @@ -2000,7 +2001,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()) @@ -2008,11 +2013,13 @@ void renderNormals(LLDrawable *drawablep)      LLVertexBuffer::unbind(); +	LLViewerObject* obj = drawablep->getVObj();      LLVOVolume *vol = drawablep->getVOVolume(); -    if (vol) +	if (obj)      { -        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.          // @@ -2021,68 +2028,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(); -        // 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 +            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 -        // 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(); +            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(); -        gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix); +        if (vol) +        { +            gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix); +        }          gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -        for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) +        // 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; + +        std::vector<LLVolumeFace>* faces = nullptr; +		std::vector<LLFace*>* drawable_faces = nullptr; +        if (vol) +        { +            LLVolume* volume = vol->getVolume(); +            faces = &volume->getVolumeFaces(); +        } +        else          { -            const LLVolumeFace &face = volume->getVolumeFace(i); +			drawable_faces = &drawablep->getFaces(); +        } -            gGL.flush(); -            gGL.diffuseColor4f(1, 1, 0, 1); -            gGL.begin(LLRender::LINES); -            for (S32 j = 0; j < face.mNumVertices; ++j) -            { -                LLVector4a n, p; +		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); +					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(); +					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; -            // Tangents are simple vectors and do not require reorientation via pre-scaling -            if (face.mTangents) +						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)              { -                gGL.flush(); -                gGL.diffuseColor4f(0, 1, 1, 1); -                gGL.begin(LLRender::LINES); -                for (S32 j = 0; j < face.mNumVertices; ++j) +                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)                  { -                    LLVector4a t, p; +                    shader = &gNormalDebugProgram[NORMAL_DEBUG_SHADER_DEFAULT]; +                } +                else +                { +                    shader = &gNormalDebugProgram[NORMAL_DEBUG_SHADER_WITH_TANGENTS]; +                } +                shader->bind(); -                    t.setMul(face.mTangents[j], 1.0f); -                    t.normalize3fast(); -                    t.mul(draw_length); -                    p.setAdd(face.mPositions[j], t); +                shader->uniform1f(LLShaderMgr::DEBUG_NORMAL_DRAW_LENGTH, draw_length); -                    gGL.vertex3fv(face.mPositions[j].getF32ptr()); -                    gGL.vertex3fv(p.getF32ptr()); -                } -                gGL.end(); +                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();      } diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 1418499f8b..804afe6266 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -643,17 +643,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. @@ -669,13 +670,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);  			} @@ -691,6 +692,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)   { diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 33a64ae7d5..b7b47d2a1c 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -112,7 +112,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); @@ -224,6 +225,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); +  //        .   __. diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index a6370e9ec2..92b1273041 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -243,7 +243,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(); @@ -356,6 +357,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(); @@ -453,6 +614,7 @@ void LLSurfacePatch::updateVerticalStats()  } +template<bool PBR>  void LLSurfacePatch::updateNormals()   {  	if (mSurfacep->mType == 'w') @@ -470,9 +632,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; @@ -483,9 +645,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; @@ -496,8 +658,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;  	} @@ -507,8 +669,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;  	} @@ -584,10 +746,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;  	} @@ -598,7 +760,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; @@ -615,6 +777,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(); diff --git a/indra/newview/llsurfacepatch.h b/indra/newview/llsurfacepatch.h index 8c8f501dce..ec3864ce44 100644 --- a/indra/newview/llsurfacepatch.h +++ b/indra/newview/llsurfacepatch.h @@ -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 diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index febda177e2..0439b0b115 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -83,9 +83,11 @@  //static  bool get_is_predefined_texture(LLUUID asset_id)  { -    if (asset_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture")) -        || asset_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID")) -        || asset_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")) +    if (asset_id == DEFAULT_OBJECT_TEXTURE +        || asset_id == DEFAULT_OBJECT_SPECULAR +        || asset_id == DEFAULT_OBJECT_NORMAL +        || asset_id == BLANK_OBJECT_NORMAL +        || asset_id == IMG_WHITE          || asset_id == LLUUID(SCULPT_DEFAULT_TEXTURE))      {          return true; @@ -1663,8 +1665,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)  	// Default of defaults is white image for diff tex  	// -	LLUUID whiteImage( gSavedSettings.getString( "UIImgWhiteUUID" ) ); -	setBlankImageAssetID( whiteImage ); +	setBlankImageAssetID(IMG_WHITE);  	setAllowNoTexture(p.allow_no_texture);  	setCanApplyImmediately(p.can_apply_immediately); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 1d168de80d..e6d9aed1a3 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -738,8 +738,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); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 9db9d97ddc..da7b1131a3 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2122,6 +2122,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 //  /////////////////// @@ -9492,6 +9506,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"); +    }  	#ifdef TOGGLE_HACKED_GODLIKE_VIEWER  	view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode"); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index dae476d9d7..d541bb6647 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1105,6 +1105,11 @@ void LLViewerRegion::dirtyHeights()  	}  } +void LLViewerRegion::dirtyAllPatches() +{ +    getLand().dirtyAllPatches(); +} +  //physically delete the cache entry  void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry, bool for_rendering)  {	 @@ -1605,7 +1610,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)  	{ @@ -1906,7 +1923,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)  	{ diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 622490c881..1c2ff9bc97 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -163,6 +163,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; } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 91983f6603..e3c2c429da 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -92,6 +92,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; @@ -2738,6 +2740,33 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  	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";  		gClipProgram.mShaderFiles.clear();  		gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER)); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 9b4583cacf..3530602776 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -161,6 +161,14 @@ extern LLGLSLShader         gHeroRadianceGenProgram;  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; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 9a6d40ab0a..ebf03ae988 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -121,8 +121,17 @@ void LLViewerTextureList::doPreloadImages()  	LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();  	LLUIImageList* image_list = LLUIImageList::getInstance(); -	// Set the default flat normal map -	LLViewerFetchedTexture::sFlatNormalImagep = LLViewerTextureManager::getFetchedTextureFromFile("flatnormal.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_BUMP); +    // Set the default flat normal map +    // BLANK_OBJECT_NORMAL has a version on dataserver, but it has compression artifacts +    LLViewerFetchedTexture::sFlatNormalImagep = +        LLViewerTextureManager::getFetchedTextureFromFile("flatnormal.tga", +                                                          FTT_LOCAL_FILE, +                                                          MIPMAP_NO, +                                                          LLViewerFetchedTexture::BOOST_BUMP, +                                                          LLViewerTexture::FETCHED_TEXTURE, +                                                          0, +                                                          0, +                                                          BLANK_OBJECT_NORMAL);  	// PBR: irradiance  	LLViewerFetchedTexture::sDefaultIrradiancePBRp = LLViewerTextureManager::getFetchedTextureFromFile("default_irradiance.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 9544450a69..69b9476d38 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -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; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 3bd7acb06a..9fb9ade943 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8246,6 +8246,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); @@ -10874,3 +10875,12 @@ 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(); +    } +} diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index bbe34933f7..e8c6da1473 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -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); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 660f4b62c7..9b238693e0 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3297,6 +3297,13 @@ function="World.EnvPreset"              <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_item_separator />            <menu_item_call              enabled="true" | 
