commit
0f3c3563b0
|
|
@ -0,0 +1,14 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
|
@ -312,7 +312,7 @@ jobs:
|
|||
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
|
||||
needs: build
|
||||
runs-on: windows
|
||||
runs-on: windows-large
|
||||
steps:
|
||||
- name: Sign and package Windows viewer
|
||||
if: env.AZURE_KEY_VAULT_URI && env.AZURE_CERT_NAME && env.AZURE_CLIENT_ID && env.AZURE_CLIENT_SECRET && env.AZURE_TENANT_ID
|
||||
|
|
@ -412,7 +412,7 @@ jobs:
|
|||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: "*-metadata"
|
||||
|
||||
|
||||
- name: Rename metadata
|
||||
run: |
|
||||
cp Windows-metadata/autobuild-package.xml Windows-autobuild-package.xml
|
||||
|
|
@ -441,7 +441,7 @@ jobs:
|
|||
append_body: true
|
||||
fail_on_unmatched_files: true
|
||||
files: |
|
||||
macOS-installer/*.dmg
|
||||
macOS-installer/*.dmg
|
||||
Windows-installer/*.exe
|
||||
*-autobuild-package.xml
|
||||
*-viewer_version.txt
|
||||
|
|
|
|||
|
|
@ -1760,6 +1760,18 @@
|
|||
</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, Copyright (C) 2022 Blender Authors</string>
|
||||
<key>description</key>
|
||||
<string>Mikktspace Tangent Generator</string>
|
||||
<key>license</key>
|
||||
<string>Apache 2.0</string>
|
||||
<key>license_file</key>
|
||||
<string>mikktspace.txt</string>
|
||||
<key>name</key>
|
||||
<string>mikktspace</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
|
|
@ -1767,52 +1779,46 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b48b7ac0792d3ea8f087d99d9e4a29d8</string>
|
||||
<string>65edf85c36a10001e32bdee582bec4732137208b</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/v2-e967e1b/mikktspace-1-darwin64-8756084692.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>windows</key>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>0a016b9c0c1e2c0b557e0124094da6c5</string>
|
||||
<string>fa9dcee4584df7e7271fdf69c08e6fd3122a47fc</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/v2-e967e1b/mikktspace-1-linux64-8756084692.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>02e9e5b6fe6788f4d2babb83ec544843</string>
|
||||
<string>130b33a70bdb3a8a188376c6a91840bdb61380a8</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/v2-e967e1b/mikktspace-1-windows64-8756084692.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</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>
|
||||
|
|
@ -3100,61 +3106,45 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>description</key>
|
||||
<string>zlib data compression library for the next generation systems</string>
|
||||
</map>
|
||||
<key>webrtc-shim</key>
|
||||
<key>tinyexr</key>
|
||||
<map>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<key>common</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>a23ffe29c49f8fabb8c5f2de9879bed9d7e0e0ca</string>
|
||||
<string>8278a2368136cb12319ca00e7aceb2829bf3ebd8</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/3p-webrtc-shim/releases/assets/155507516</string>
|
||||
<string>https://github.com/secondlife/3p-tinyexr/releases/download/v1.0.8-ba4bc64/tinyexr-v1.0.8-common-9373975608.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>b264c6ed008bd45c4687c5dc4d7532727c74624a</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/3p-webrtc-shim/releases/assets/155507520</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
<string>common</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>license</key>
|
||||
<string>MIT</string>
|
||||
<string>3-clause BSD</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/webrtc-license.txt</string>
|
||||
<string>LICENSES/tinyexr_license.txt</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2011, The WebRTC project authors. All rights reserved.</string>
|
||||
<string>Copyright (c) 2014 - 2021, Syoyo Fujita and many contributors.</string>
|
||||
<key>version</key>
|
||||
<string>m114.0.26.d4b8b92</string>
|
||||
<string>v1.0.8</string>
|
||||
<key>name</key>
|
||||
<string>webrtc-shim</string>
|
||||
<string>tinyexr</string>
|
||||
<key>vcs_branch</key>
|
||||
<string>main</string>
|
||||
<string>dependabot/github_actions/secondlife/action-autobuild-4</string>
|
||||
<key>vcs_revision</key>
|
||||
<string>d4b8b921825ae4344d87fdb0c9179c358c6e3698</string>
|
||||
<string>4dc4d1d90d82a22843e2adf5130f9ecb5ee5769e</string>
|
||||
<key>vcs_url</key>
|
||||
<string>https://github.com/secondlife/3p-webrtc-shim</string>
|
||||
<key>canonical_repo</key>
|
||||
<string>https://github.com/secondlife/3p-webrtc-shim</string>
|
||||
<string>https://github.com/secondlife/3p-tinyexr</string>
|
||||
<key>description</key>
|
||||
<string>tinyexr import library</string>
|
||||
<key>source_type</key>
|
||||
<string>git</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>package_description</key>
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ Ansariel Hiller
|
|||
SL-4126
|
||||
SL-20224
|
||||
SL-20524
|
||||
secondlife/viewer#1051
|
||||
Aralara Rajal
|
||||
Arare Chantilly
|
||||
CHUIBUG-191
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
The Setting RenderMaxTextureResolution controls the maximum resolution of non-boosted textures as displayed by the viewer.
|
||||
|
||||
Valid values are 512-2048 (clamped in C++).
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
Test Asset available on beta grid:
|
||||
Object: 'Damaged Helmet', AssetID 0623e759-11b5-746c-a75e-7ba1caa6eb0e
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
A resident may swap out their sky for an EXR format HDRI for the purposes of previewing how their object would render in Second Life in an environment that matches the supplied HDRI. This should aid in matching inworld lighting with external tools so artists can know if their content has imported properly.
|
||||
|
||||
To load an HDRI, click Develop->Render Tests->HDRI Preview:
|
||||
|
||||

|
||||
|
||||
Choose an EXR image. A library of publicly available HDRIs can be found here: https://polyhaven.com/hdris
|
||||
|
||||
The Personal Lighting floater will open, and the sky will be replaced with the HDRI you chose. Reflection Probes will reset, and the scene will be illuminated by the HDRI.
|
||||
|
||||
Three debug settings affect how the HDRI is displayed:
|
||||
|
||||
RenderHDRIExposure - Exposure adjustment of HDRI when previewing an HDRI. Units are EV. Sane values would be -10 to 10.
|
||||
RenderHDRIRotation - Rotation (in degrees) of environment when previewing an HDRI.
|
||||
RenderHDRISplitScreen - What percentage of screen to render using HDRI vs EEP sky.
|
||||
|
||||
Exposure and Rotation should behave similarly to the rotation and exposure controls in Substance Painter.
|
||||
|
||||
Split Screen can be used to display an EEP sky side-by-side with an HDRI sky to aid in authoring an EEP sky that matches an HDRI sky. It is currently expected that EEP sun disc, moon, clouds, and stars do not render when previewing an HDRI, but that may change in the future.
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
# Material Preview
|
||||
|
||||
## Overview
|
||||
|
||||
Material preview is a UI feature which displays a lit spherical preview of a PBR material. It can be found in the following UIs:
|
||||
|
||||
- The material picker swatch
|
||||
- In the build floater, in the Texture tab, when applying a PBR material
|
||||
- (If the feature is enabled) In the Region/Estate floater, in the Terrain tab, when applying PBR materials to terrain
|
||||
- In the floater to select a material from inventory, which can be opened by clicking the material picker swatch
|
||||
|
||||
## Known Issues
|
||||
|
||||
These are known issues that the current implementation of this feature does not address:
|
||||
|
||||
- The material preview in the build floater is a preview of the base material ID only, and ignores other properties on the prim face like material overrides (https://github.com/secondlife/viewer/issues/865)
|
||||
- Alpha mask previews as alpha blend (https://github.com/secondlife/viewer/issues/866)
|
||||
- Double-sided previews as single-sided (https://github.com/secondlife/viewer/issues/867)
|
||||
- Material preview inherits some of its lighting from the current environment, and reflections from the default reflection probe (https://github.com/secondlife/viewer/issues/868)
|
||||
|
||||
## General Regression Testing
|
||||
|
||||
- Check that the material preview swatch looks OK with different materials selected
|
||||
- Check that the material preview swatch runs reasonably well on different systems, especially when the select material from inventory floater is also open
|
||||
- In particular: AMD, MacOS, minimum spec machines
|
||||
- Watch out for regressions in rendering caused by opening a floater with a material preview swatch
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
### Disappearing Objects Fix Test
|
||||
|
||||
This test is recommended for verifying that https://github.com/secondlife/viewer-issues/issues/72 is fixed.
|
||||
|
||||
#### Symptoms
|
||||
|
||||
When the bug occurs, one or more of following types of objects could randomly disappear in the world, permanently until relog:
|
||||
|
||||
- Objects
|
||||
- Water level in current region
|
||||
- Adjacent region/void water
|
||||
|
||||
Note: Disappearing objects in reflections have a different root cause and are not covered by the fix.
|
||||
|
||||
#### Bug Reproduction Steps
|
||||
|
||||
Verify the disappearing objects bug does not reproduce, given the following steps:
|
||||
|
||||
- Runtime prerequisites: Material preview swatch may not be available in your viewer or region if this feature is still behind a feature flag. It is safe to enable this feature manually by setting, "UIPreviewMaterial" to True in the advanced settings. The setting will persist for the current session.
|
||||
- Region prerequisites: Unknown, but a region with lots of objects in it seems to increase repro rate. The following locations have been known to easily reproduce the bug, as of 2024-02-16:
|
||||
- http://maps.secondlife.com/secondlife/LindenWorld%20B/161/75/47
|
||||
- [secondlife://Aditi/secondlife/Rumpus%20Room%202048/128/128/24](secondlife://Aditi/secondlife/Rumpus%20Room%202048/128/128/24)
|
||||
- Right click an object and select, "Edit item"
|
||||
- Go to texture tab, select PBR Metallic Roughness from dropdown, and click the button to select material from inventory
|
||||
- Ensure "Apply now" is checked in the inventory selection floater
|
||||
- Alternate between different materials from the inventory selection floater
|
||||
- Look around the world and check for permanently disappeared objects.
|
||||
|
||||
### Dynamic Exposure Influence Fix Test
|
||||
|
||||
This test is recommended for verifying that https://github.com/secondlife/viewer-issues/issues/72 is fixed.
|
||||
|
||||
#### Symptoms
|
||||
|
||||
Dynamic exposure in the world could be influenced by the material preview being displayed. If a material preview was being generated in a given frame, then, depending on the current environment, the user would observe an unpleasant flashing effect in the environment:
|
||||
|
||||
- The world view could suddenly get darker and then fade back to normal exposure levels
|
||||
- The world view could suddenly get brighter and then fade back to normal exposure levels
|
||||
|
||||
#### Bug Reproduction Steps
|
||||
|
||||
Verify the dynamic exposure influence bug does not reproduce. Test using a few environment presets such as Default Midday, Sunset, and Midnight.
|
||||
|
||||
- Right click an object and select, "Edit item"
|
||||
- Go to texture tab, select PBR Metallic Roughness from dropdown, and click the button to select material from inventory
|
||||
- Alternate between different materials from the inventory selection floater
|
||||
|
||||
#### Regression Testing
|
||||
|
||||
Dynamic exposure in the world should continue to work correctly. In particular:
|
||||
|
||||
- Exposure should fade gradually from high exposure to low exposure and back as needed
|
||||
- Exposure should decrease in brighter environments
|
||||
- Exposure should increase in darker environments
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# PBR Terrain Appearance
|
||||
|
||||
## Tiling
|
||||
|
||||
The southwest corner of a region with PBR materials should exactly match up with the bottom left corner of the material texture(s).
|
||||
|
||||
If two adjacent regions have the same PBR terrain settings, then:
|
||||
|
||||
- There should not be seams between the two regions at their shared border
|
||||
- The ground should not suddenly slide beneath the avatar when moving between regions (except due to movement of the avatar, which is not covered by this test plan)
|
||||
|
||||
## Feature Gating
|
||||
|
||||
PBR terrain should have lower detail on lower graphics settings. PBR terrain will also not show emissive textures on some machines (like Macs) which do not support more than 16 textures.
|
||||
|
||||
### Triplanar Mapping
|
||||
|
||||
Triplanar mapping improves the texture repeats on the sides of terrain slopes.
|
||||
|
||||
Availability of Triplanar mapping:
|
||||
|
||||
- Medium-High and below: No triplanar mapping
|
||||
- High and above: Triplanar mapping
|
||||
|
||||
### PBR Textures
|
||||
|
||||
At the highest graphics support level, PBR terrain supports all PBR textures.
|
||||
|
||||
Availability of PBR textures varies by machine and graphics setting:
|
||||
|
||||
- Low: Base color only (looks similar to texture terrain)
|
||||
- Medium-Low, and machines that do not support greater than 16 textures such as Macs: All PBR textures enabled except emissive textures.
|
||||
- Medium: All PBR textures enabled
|
||||
|
||||
### PBR Alpha
|
||||
|
||||
PBR terrain does not support materials with alpha blend or double-sided. In addition, the viewer does not make any guarantees about what will render behind the terrain if alpha is used.
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
# PBR Terrain Composition
|
||||
|
||||
## Feature Availability
|
||||
|
||||
PBR Terrain is visible for all viewers with the PBR Terrain feature, regardless of if the feature flag is enabled.
|
||||
|
||||
There is only one set of four asset IDs applied to the terrain. In other words, unlike PBR materials on prims, there is no fallback texture set for viewers that do not support PBR terrain. Viewers without support will view terrain as blank (solid grey or white).
|
||||
|
||||
## Editing Terrain Composition
|
||||
|
||||
All tests in this section assume the PBR terrain feature flag is enabled, and that the user has appropriate permissions to modify the terrain textures.
|
||||
|
||||
### Feature Availability
|
||||
|
||||
On the client, the advanced setting `RenderTerrainPBREnabled` is the PBR terrain feature flag.
|
||||
|
||||
The PBR terrain feature flag should be set automatically when logging in/teleporting to a new region.
|
||||
|
||||
- The flag should be enabled on regions where the PBR terrain feature is enabled
|
||||
- Otherwise the flag should be disabled
|
||||
|
||||
When the PBR terrain feature flag is disabled:
|
||||
|
||||
- The "PBR Metallic Roughness" checkbox should not be visible
|
||||
- The user should not be able to apply PBR terrain to the region, only textures.
|
||||
|
||||
When the PBR terrain feature flag is enabled:
|
||||
|
||||
- The "PBR Metallic Roughness" checkbox should be visible
|
||||
- The user should be able to apply PBR terrain or textures to the region, depending on if the "PBR Metallic Roughness" checkbox is checked.
|
||||
|
||||
### Current Composition Type
|
||||
|
||||
When the Region/Estate floater is opened to the terrain Tab, the current terrain should be shown in the four swatches, and the "PBR Metallic Roughness" checkbox should be checked or unchecked accordingly.
|
||||
|
||||
- If it is texture terrain, the "PBR Metallic Roughness" checkbox should be unchecked, and the floater should display the four textures applied to the terrain.
|
||||
- If it is material terrain, the "PBR Metallic Roughness" checkbox should be checked, and the floater should display the four materials applied to the terrain.
|
||||
|
||||
In addition, where possible, textual labels and descriptions in the tab should make sense given the current value of the "PBR Metallic Roughness" checkbox. If the checkbox is unchecked, the labels should refer to textures. If the checkbox is checked, the labels should refer to materials.
|
||||
|
||||
### Toggling Composition Type
|
||||
|
||||
When toggling the "PBR Metallic Roughness" checkbox to the opposite value, which does not correspond to the current terrain type, one of the following sets of four terrain swatches will be displayed:
|
||||
|
||||
- The default textures/materials
|
||||
- For textures, this is the default terrain texture set
|
||||
- For materials, this is all blank materials, but this is subject to change
|
||||
- The previously applied texture/material set
|
||||
- History is available on a best-effort basis only. In particular, the history does not persist on viewer restart.
|
||||
|
||||
When toggling back the "PBR Metallic Roughness" checkbox to the original value, assuming nothing else has changed, then the current terrain should be shown in the four swatches again.
|
||||
|
||||
### Saving Composition
|
||||
|
||||
A user with appropriate permissions can change and save the textures or materials to the terrain. If the "PBR Metallic Roughness" checkbox is checked, the user applies materials, otherwise the user applies textures.
|
||||
|
||||
The user should not be allowed to set the texture or material swatches to null.
|
||||
|
||||
Saving may fail for the following reasons:
|
||||
|
||||
- A terrain or material texture is invalid
|
||||
- A terrain texture is greater than the max texture upload resolution
|
||||
|
||||
If saving the terrain fails for any reason, the terrain should not be updated.
|
||||
|
||||
Unlike a viewer without PBR terrain support, the new viewer will no longer treat textures with alpha channels as invalid.
|
||||
|
||||
## Graphics Features
|
||||
|
||||
Texture terrain with transparency is not permitted to be applied in the viewer.
|
||||
|
||||
See [PBR Terrain Appearance](./pbr_terrain_appearance.md) for supported PBR terrain features.
|
||||
|
||||
## Minimap
|
||||
|
||||
The minimap should display the terrain with appropriate textures and colors.
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# Terrain Loading
|
||||
|
||||
## Behavior overview
|
||||
|
||||
- Texture terrain should load if textures are applied to the region, and no PBR Metallic Roughness materials are applied.
|
||||
- PBR terrain should load if PBR materials are applied to the region, even if the RenderTerrainPBREnabled feature flag is disabled in debug settings. This setting only disables the display of PBR materials in the Region / Estate > Terrain UI.
|
||||
- Related subsystem: A change to the PBR terrain loading system may affect the texture terrain loading system and vice-versa
|
||||
- Related subsystem: Minimap should load if terrain loads
|
||||
- They may not finish loading at the same time
|
||||
|
||||
## Implementation details
|
||||
|
||||
This section is provided mainly for clarification of how the terrain loading system works.
|
||||
|
||||
The simulator sends 4 terrain composition UUIDs to the viewer for the region. The viewer does not know ahead-of-time if the terrain composition uses textures or materials. Therefore, to expedite terrain loading, the viewer makes up to 8 "top-level" asset requests simultaneously:
|
||||
|
||||
- Up to 4 texture asset requests, one for each UUID
|
||||
- Up to 4 material asset requests, one for each UUID
|
||||
|
||||
It is therefore expected that half of these asset lookups will fail.
|
||||
|
||||
The viewer inspects the load success of these top-level assets to make the binary decision of whether to render all 4 texture assets or all 4 material assets. This determines the choice of composition for terrain both in-world and on the minimap.
|
||||
|
||||
The minimap also attempts to wait for textures to partially load before it can render a tile for a given region:
|
||||
|
||||
- When rendering texture terrain, the minimap attempts to wait for top-level texture assets to partially load
|
||||
- When rendering PBR material terrain, the minimap attempts to wait for any base color/emissive textures in the materials to partially load, if they are present
|
||||
|
||||
We don't make guarantees that the minimap tile will render for the region if any aforementioned required textures/materials fail to sufficiently load. However, the minimap may make a best-effort attempt to render the region by ignoring or replacing data.
|
||||
|
|
@ -103,6 +103,11 @@ if (WINDOWS)
|
|||
string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||
endif()
|
||||
|
||||
# workaround for github runner image breakage:
|
||||
# https://github.com/actions/runner-images/issues/10004#issuecomment-2153445161
|
||||
# can be removed after the above issue is resolved and deployed across GHA
|
||||
add_compile_definitions(_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR)
|
||||
endif (WINDOWS)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ set(cmake_SOURCE_FILES
|
|||
PulseAudio.cmake
|
||||
Python.cmake
|
||||
TemplateCheck.cmake
|
||||
TinyEXR.cmake
|
||||
TinyGLTF.cmake
|
||||
Tut.cmake
|
||||
UI.cmake
|
||||
UnixInstall.cmake
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
use_prebuilt_binary(tinyexr)
|
||||
|
||||
set(TINYEXR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tinyexr)
|
||||
|
||||
|
|
@ -494,45 +494,70 @@ void LLAvatarAppearance::computeBodySize()
|
|||
mCurrBodySizeState["mAnkleLeft scale"] = mAnkleLeftp->getScale();
|
||||
mCurrBodySizeState["mFootLeft pos"] = mFootLeftp->getPosition();
|
||||
|
||||
F32 old_height = mBodySize.mV[VZ];
|
||||
LLVector3 pelvis_scale = mPelvisp->getScale();
|
||||
|
||||
// some of the joints have not been cached
|
||||
LLVector3 skull = mSkullp->getPosition();
|
||||
//LLVector3 skull_scale = mSkullp->getScale();
|
||||
|
||||
LLVector3 neck = mNeckp->getPosition();
|
||||
LLVector3 neck_scale = mNeckp->getScale();
|
||||
|
||||
LLVector3 chest = mChestp->getPosition();
|
||||
LLVector3 chest_scale = mChestp->getScale();
|
||||
|
||||
// the rest of the joints have been cached
|
||||
LLVector3 head = mHeadp->getPosition();
|
||||
LLVector3 head_scale = mHeadp->getScale();
|
||||
|
||||
LLVector3 torso = mTorsop->getPosition();
|
||||
LLVector3 torso_scale = mTorsop->getScale();
|
||||
|
||||
LLVector3 hip = mHipLeftp->getPosition();
|
||||
LLVector3 hip_scale = mHipLeftp->getScale();
|
||||
|
||||
LLVector3 knee = mKneeLeftp->getPosition();
|
||||
LLVector3 knee_scale = mKneeLeftp->getScale();
|
||||
|
||||
LLVector3 ankle = mAnkleLeftp->getPosition();
|
||||
LLVector3 ankle_scale = mAnkleLeftp->getScale();
|
||||
|
||||
LLVector3 foot = mFootLeftp->getPosition();
|
||||
|
||||
F32 old_offset = mAvatarOffset.mV[VZ];
|
||||
|
||||
// TODO: Measure the real depth and width
|
||||
mPelvisToFoot = computePelvisToFoot();
|
||||
F32 new_height = computeBodyHeight();
|
||||
mBodySize.set(DEFAULT_AGENT_DEPTH, DEFAULT_AGENT_WIDTH, new_height);
|
||||
F32 new_offset = getVisualParamWeight(AVATAR_HOVER);
|
||||
mAvatarOffset.set(0, 0, new_offset);
|
||||
mAvatarOffset.mV[VZ] = getVisualParamWeight(AVATAR_HOVER);
|
||||
|
||||
if (mBodySize.mV[VZ] != old_height || new_offset != old_offset)
|
||||
mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
|
||||
knee.mV[VZ] * hip_scale.mV[VZ] -
|
||||
ankle.mV[VZ] * knee_scale.mV[VZ] -
|
||||
foot.mV[VZ] * ankle_scale.mV[VZ];
|
||||
|
||||
LLVector3 new_body_size;
|
||||
new_body_size.mV[VZ] = mPelvisToFoot +
|
||||
// the sqrt(2) correction below is an approximate
|
||||
// correction to get to the top of the head
|
||||
F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) +
|
||||
head.mV[VZ] * neck_scale.mV[VZ] +
|
||||
neck.mV[VZ] * chest_scale.mV[VZ] +
|
||||
chest.mV[VZ] * torso_scale.mV[VZ] +
|
||||
torso.mV[VZ] * pelvis_scale.mV[VZ];
|
||||
|
||||
// TODO -- measure the real depth and width
|
||||
new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
|
||||
new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
|
||||
|
||||
mAvatarOffset.mV[VX] = 0.0f;
|
||||
mAvatarOffset.mV[VY] = 0.0f;
|
||||
|
||||
if (new_body_size != mBodySize || old_offset != mAvatarOffset.mV[VZ])
|
||||
{
|
||||
mBodySize = new_body_size;
|
||||
|
||||
compareJointStateMaps(mLastBodySizeState, mCurrBodySizeState);
|
||||
}
|
||||
}
|
||||
|
||||
F32 LLAvatarAppearance::computeBodyHeight()
|
||||
{
|
||||
F32 result = mPelvisToFoot +
|
||||
// all these relative positions usually are positive
|
||||
mPelvisp->getScale().mV[VZ] * mTorsop->getPosition().mV[VZ] +
|
||||
mTorsop->getScale().mV[VZ] * mChestp->getPosition().mV[VZ] +
|
||||
mChestp->getScale().mV[VZ] * mNeckp->getPosition().mV[VZ] +
|
||||
mNeckp->getScale().mV[VZ] * mHeadp->getPosition().mV[VZ] +
|
||||
mHeadp->getScale().mV[VZ] * mSkullp->getPosition().mV[VZ] * 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
F32 LLAvatarAppearance::computePelvisToFoot()
|
||||
{
|
||||
F32 result =
|
||||
// all these relative positions usually are negative
|
||||
mPelvisp->getScale().mV[VZ] * mHipLeftp->getPosition().mV[VZ] +
|
||||
mHipLeftp->getScale().mV[VZ] * mKneeLeftp->getPosition().mV[VZ] +
|
||||
mKneeLeftp->getScale().mV[VZ] * mAnkleLeftp->getPosition().mV[VZ] +
|
||||
mAnkleLeftp->getScale().mV[VZ] * mFootLeftp->getPosition().mV[VZ] / 2;
|
||||
return -result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// parseSkeletonFile()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -147,8 +147,6 @@ public:
|
|||
void compareJointStateMaps(joint_state_map_t& last_state,
|
||||
joint_state_map_t& curr_state);
|
||||
void computeBodySize();
|
||||
F32 computeBodyHeight();
|
||||
F32 computePelvisToFoot();
|
||||
|
||||
public:
|
||||
typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
|
||||
|
|
|
|||
|
|
@ -89,3 +89,4 @@ const LLUUID IMG_USE_BAKED_AUX1 ("9742065b-19b5-297c-858a-29711d539043");
|
|||
const LLUUID IMG_USE_BAKED_AUX2 ("03642e83-2bd1-4eb9-34b4-4c47ed586d2d");
|
||||
const LLUUID IMG_USE_BAKED_AUX3 ("edd51b77-fc10-ce7a-4b3d-011dfc349e4f");
|
||||
|
||||
const LLUUID BLANK_MATERIAL_ASSET_ID ("968cbad0-4dad-d64e-71b5-72bf13ad051a");
|
||||
|
|
|
|||
|
|
@ -236,6 +236,8 @@ 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;
|
||||
|
||||
LL_COMMON_API extern const LLUUID BLANK_MATERIAL_ASSET_ID;
|
||||
|
||||
// radius within which a chat message is fully audible
|
||||
const F32 CHAT_NORMAL_RADIUS = 20.f;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,25 +3,25 @@
|
|||
* @author Nat Goodspeed
|
||||
* @date 2009-06-03
|
||||
* @brief Implementation for llcoros.
|
||||
*
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ template <class Object> class LLStrider
|
|||
};
|
||||
U32 mSkip;
|
||||
public:
|
||||
|
||||
LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); }
|
||||
LLStrider(Object* first) { mObjectp = first; mSkip = sizeof(Object); }
|
||||
~LLStrider() { }
|
||||
|
||||
const LLStrider<Object>& operator = (Object *first) { mObjectp = first; return *this;}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "llmath.h"
|
||||
#include "v4coloru.h"
|
||||
#include "v3color.h"
|
||||
|
||||
#include "llimagebmp.h"
|
||||
#include "llimagetga.h"
|
||||
|
|
@ -984,6 +985,28 @@ void LLImageRaw::verticalFlip()
|
|||
}
|
||||
|
||||
|
||||
bool LLImageRaw::checkHasTransparentPixels()
|
||||
{
|
||||
if (getComponents() != 4)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
U8* data = getData();
|
||||
U32 pixels = getWidth() * getHeight();
|
||||
|
||||
// check alpha channel for all 255
|
||||
for (U32 i = 0; i < pixels; ++i)
|
||||
{
|
||||
if (data[i * 4 + 3] != 255)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLImageRaw::optimizeAwayAlpha()
|
||||
{
|
||||
if (getComponents() == 4)
|
||||
|
|
@ -1021,6 +1044,34 @@ bool LLImageRaw::optimizeAwayAlpha()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool LLImageRaw::makeAlpha()
|
||||
{
|
||||
if (getComponents() == 3)
|
||||
{
|
||||
U8* data = getData();
|
||||
U32 pixels = getWidth() * getHeight();
|
||||
|
||||
// alpha channel doesn't exist, make a new copy of data with alpha channel
|
||||
U8* new_data = (U8*) ll_aligned_malloc_16(getWidth() * getHeight() * 4);
|
||||
|
||||
for (U32 i = 0; i < pixels; ++i)
|
||||
{
|
||||
U32 di = i * 4;
|
||||
U32 si = i * 3;
|
||||
for (U32 j = 0; j < 3; ++j)
|
||||
{
|
||||
new_data[di+j] = data[si+j];
|
||||
}
|
||||
}
|
||||
|
||||
setDataAndSize(new_data, getWidth(), getHeight(), 3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image)
|
||||
{
|
||||
// Find new sizes
|
||||
|
|
@ -1105,7 +1156,7 @@ void LLImageRaw::composite( LLImageRaw* src )
|
|||
return;
|
||||
}
|
||||
|
||||
llassert(3 == src->getComponents());
|
||||
llassert((3 == src->getComponents()) || (4 == src->getComponents()));
|
||||
llassert(3 == dst->getComponents());
|
||||
|
||||
if( 3 == dst->getComponents() )
|
||||
|
|
@ -1263,6 +1314,30 @@ void LLImageRaw::fill( const LLColor4U& color )
|
|||
}
|
||||
}
|
||||
|
||||
void LLImageRaw::tint( const LLColor3& color )
|
||||
{
|
||||
llassert( (3 == getComponents()) || (4 == getComponents()) );
|
||||
if (isBufferInvalid())
|
||||
{
|
||||
LL_WARNS() << "Invalid image buffer" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
S32 pixels = getWidth() * getHeight();
|
||||
const S32 components = getComponents();
|
||||
U8* data = getData();
|
||||
for( S32 i = 0; i < pixels; i++ )
|
||||
{
|
||||
const float c0 = data[0] * color.mV[0];
|
||||
const float c1 = data[1] * color.mV[1];
|
||||
const float c2 = data[2] * color.mV[2];
|
||||
data[0] = llclamp((U8)c0, 0, 255);
|
||||
data[1] = llclamp((U8)c1, 0, 255);
|
||||
data[2] = llclamp((U8)c2, 0, 255);
|
||||
data += components;
|
||||
}
|
||||
}
|
||||
|
||||
LLPointer<LLImageRaw> LLImageRaw::duplicate()
|
||||
{
|
||||
if(getNumRefs() < 2)
|
||||
|
|
@ -1794,6 +1869,73 @@ void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S3
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void LLImageRaw::addEmissive(LLImageRaw* src)
|
||||
{
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
if (!validateSrcAndDst(__FUNCTION__, src, dst))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
llassert((3 == src->getComponents()) || (4 == src->getComponents()));
|
||||
llassert(3 == dst->getComponents());
|
||||
|
||||
if( 3 == dst->getComponents() )
|
||||
{
|
||||
if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
|
||||
{
|
||||
addEmissiveUnscaled(src);
|
||||
}
|
||||
else
|
||||
{
|
||||
addEmissiveScaled(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLImageRaw::addEmissiveUnscaled(LLImageRaw* src)
|
||||
{
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
llassert((3 == src->getComponents()) || (4 == src->getComponents()));
|
||||
llassert((3 == dst->getComponents()) || (4 == dst->getComponents()));
|
||||
llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
|
||||
|
||||
U8* const src_data = src->getData();
|
||||
U8* const dst_data = dst->getData();
|
||||
for(S32 y = 0; y < dst->getHeight(); ++y)
|
||||
{
|
||||
const S32 src_row_offset = src->getComponents() * src->getWidth() * y;
|
||||
const S32 dst_row_offset = dst->getComponents() * dst->getWidth() * y;
|
||||
for (S32 x = 0; x < dst->getWidth(); ++x)
|
||||
{
|
||||
const S32 src_offset = src_row_offset + (x * src->getComponents());
|
||||
const S32 dst_offset = dst_row_offset + (x * dst->getComponents());
|
||||
U8* const src_pixel = src_data + src_offset;
|
||||
U8* const dst_pixel = dst_data + dst_offset;
|
||||
dst_pixel[0] = llmin(255, dst_pixel[0] + src_pixel[0]);
|
||||
dst_pixel[1] = llmin(255, dst_pixel[1] + src_pixel[1]);
|
||||
dst_pixel[2] = llmin(255, dst_pixel[2] + src_pixel[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLImageRaw::addEmissiveScaled(LLImageRaw* src)
|
||||
{
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
|
||||
|
||||
LLImageRaw temp(dst->getWidth(), dst->getHeight(), dst->getComponents());
|
||||
llassert_always(temp.getDataSize() > 0);
|
||||
temp.copyScaled(src);
|
||||
|
||||
dst->addEmissiveUnscaled(&temp);
|
||||
}
|
||||
|
||||
|
||||
bool LLImageRaw::validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst)
|
||||
{
|
||||
if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid())
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
#include "lltrace.h"
|
||||
|
||||
const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
|
||||
const S32 MAX_IMAGE_MIP = 11; // 2048x2048
|
||||
const S32 MAX_IMAGE_MIP = 12; // 4096x4096
|
||||
|
||||
// *TODO : Use MAX_IMAGE_MIP as max discard level and modify j2c management so that the number
|
||||
// of levels is read from the header's file, not inferred from its size.
|
||||
|
|
@ -44,7 +44,7 @@ const S32 MAX_DISCARD_LEVEL = 5;
|
|||
// and declared right here. Some come from the JPEG2000 spec, some conventions specific to SL.
|
||||
const S32 MAX_DECOMPOSITION_LEVELS = 32; // Number of decomposition levels cannot exceed 32 according to jpeg2000 spec
|
||||
const S32 MIN_DECOMPOSITION_LEVELS = 5; // the SL viewer will *crash* trying to decode images with fewer than 5 decomposition levels (unless image is small that is)
|
||||
const S32 MAX_PRECINCT_SIZE = 2048; // No reason to be bigger than MAX_IMAGE_SIZE
|
||||
const S32 MAX_PRECINCT_SIZE = 4096; // No reason to be bigger than MAX_IMAGE_SIZE
|
||||
const S32 MIN_PRECINCT_SIZE = 4; // Can't be smaller than MIN_BLOCK_SIZE
|
||||
const S32 MAX_BLOCK_SIZE = 64; // Max total block size is 4096, hence 64x64 when using square blocks
|
||||
const S32 MIN_BLOCK_SIZE = 4; // Min block dim is 4 according to jpeg2000 spec
|
||||
|
|
@ -52,11 +52,11 @@ const S32 MIN_LAYER_SIZE = 2000; // Size of the first quality layer (
|
|||
const S32 MAX_NB_LAYERS = 64; // Max number of layers we'll entertain in SL (practical limit)
|
||||
|
||||
const S32 MIN_IMAGE_SIZE = (1<<MIN_IMAGE_MIP); // 4, only used for expand/contract power of 2
|
||||
const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 2048
|
||||
const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 4096
|
||||
const S32 MIN_IMAGE_AREA = MIN_IMAGE_SIZE * MIN_IMAGE_SIZE;
|
||||
const S32 MAX_IMAGE_AREA = MAX_IMAGE_SIZE * MAX_IMAGE_SIZE;
|
||||
const S32 MAX_IMAGE_COMPONENTS = 8;
|
||||
const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS; //2048 * 2048 * 8 = 16 MB
|
||||
const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS; //4096 * 4096 * 8 = 128 MB
|
||||
|
||||
// Note! These CANNOT be changed without modifying simulator code
|
||||
// *TODO: change both to 1024 when SIM texture fetching is deprecated
|
||||
|
|
@ -71,6 +71,7 @@ const S32 HTTP_PACKET_SIZE = 1496;
|
|||
class LLImageFormatted;
|
||||
class LLImageRaw;
|
||||
class LLColor4U;
|
||||
class LLColor3;
|
||||
|
||||
typedef enum e_image_codec
|
||||
{
|
||||
|
|
@ -208,9 +209,13 @@ public:
|
|||
|
||||
void verticalFlip();
|
||||
|
||||
// Returns true if the image is not fully opaque
|
||||
bool checkHasTransparentPixels();
|
||||
// if the alpha channel is all 100% opaque, delete it
|
||||
// returns true if alpha channel was deleted
|
||||
bool optimizeAwayAlpha();
|
||||
// Create an alpha channel if this image doesn't have one
|
||||
bool makeAlpha();
|
||||
|
||||
static S32 biasedDimToPowerOfTwo(S32 curr_dim, S32 max_dim = MAX_IMAGE_SIZE);
|
||||
static S32 expandDimToPowerOfTwo(S32 curr_dim, S32 max_dim = MAX_IMAGE_SIZE);
|
||||
|
|
@ -224,6 +229,9 @@ public:
|
|||
// Fill the buffer with a constant color
|
||||
void fill( const LLColor4U& color );
|
||||
|
||||
// Multiply this raw image by the given color
|
||||
void tint( const LLColor3& color );
|
||||
|
||||
// Copy operations
|
||||
|
||||
//duplicate this raw image if refCount > 1.
|
||||
|
|
@ -267,6 +275,12 @@ public:
|
|||
// Src and dst are same size. Src has 4 components. Dst has 3 components.
|
||||
void compositeUnscaled4onto3( LLImageRaw* src );
|
||||
|
||||
// Emissive operations used by minimap
|
||||
// Roughly emulates GLTF emissive texture, but is not GLTF-compliant
|
||||
// *TODO: Remove in favor of shader
|
||||
void addEmissive(LLImageRaw* src);
|
||||
void addEmissiveScaled(LLImageRaw* src);
|
||||
void addEmissiveUnscaled(LLImageRaw* src);
|
||||
protected:
|
||||
// Create an image from a local file (generally used in tools)
|
||||
//bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false);
|
||||
|
|
|
|||
|
|
@ -407,7 +407,6 @@ LLSettingsSky::LLSettingsSky(const LLSD &data) :
|
|||
mNextRainbowTextureId(),
|
||||
mNextHaloTextureId()
|
||||
{
|
||||
mCanAutoAdjust = !data.has(SETTING_REFLECTION_PROBE_AMBIANCE);
|
||||
}
|
||||
|
||||
LLSettingsSky::LLSettingsSky():
|
||||
|
|
@ -430,8 +429,6 @@ void LLSettingsSky::replaceSettings(LLSD settings)
|
|||
mNextBloomTextureId.setNull();
|
||||
mNextRainbowTextureId.setNull();
|
||||
mNextHaloTextureId.setNull();
|
||||
|
||||
mCanAutoAdjust = !settings.has(SETTING_REFLECTION_PROBE_AMBIANCE);
|
||||
}
|
||||
|
||||
void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother)
|
||||
|
|
@ -444,7 +441,6 @@ void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother)
|
|||
mNextBloomTextureId = pother->mNextBloomTextureId;
|
||||
mNextRainbowTextureId = pother->mNextRainbowTextureId;
|
||||
mNextHaloTextureId = pother->mNextHaloTextureId;
|
||||
mCanAutoAdjust = pother->mCanAutoAdjust;
|
||||
}
|
||||
|
||||
void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
|
||||
|
|
@ -1146,7 +1142,6 @@ void LLSettingsSky::setSkyIceLevel(F32 ice_level)
|
|||
|
||||
void LLSettingsSky::setReflectionProbeAmbiance(F32 ambiance)
|
||||
{
|
||||
mCanAutoAdjust = false; // we've now touched this sky in a "new" way, it can no longer auto adjust
|
||||
setValue(SETTING_REFLECTION_PROBE_AMBIANCE, ambiance);
|
||||
}
|
||||
|
||||
|
|
@ -1448,24 +1443,6 @@ F32 LLSettingsSky::getReflectionProbeAmbiance(bool auto_adjust) const
|
|||
return mSettings[SETTING_REFLECTION_PROBE_AMBIANCE].asReal();
|
||||
}
|
||||
|
||||
F32 LLSettingsSky::getTotalReflectionProbeAmbiance(F32 cloud_shadow_scale, bool auto_adjust) const
|
||||
{
|
||||
#if 0
|
||||
// feed cloud shadow back into reflection probe ambiance to mimic pre-reflection-probe behavior
|
||||
// without brightening dark/interior spaces
|
||||
F32 probe_ambiance = getReflectionProbeAmbiance(auto_adjust);
|
||||
|
||||
if (probe_ambiance > 0.f && probe_ambiance < 1.f)
|
||||
{
|
||||
probe_ambiance += (1.f - probe_ambiance) * getCloudShadow() * cloud_shadow_scale;
|
||||
}
|
||||
|
||||
return probe_ambiance;
|
||||
#else
|
||||
return getReflectionProbeAmbiance(auto_adjust);
|
||||
#endif
|
||||
}
|
||||
|
||||
F32 LLSettingsSky::getSkyBottomRadius() const
|
||||
{
|
||||
return mSettings[SETTING_SKY_BOTTOM_RADIUS].asReal();
|
||||
|
|
@ -1810,3 +1787,8 @@ LLUUID LLSettingsSky::getNextBloomTextureId() const
|
|||
return mNextBloomTextureId;
|
||||
}
|
||||
|
||||
// if true, this sky is a candidate for auto-adjustment
|
||||
bool LLSettingsSky::canAutoAdjust() const
|
||||
{
|
||||
return !mSettings.has(SETTING_REFLECTION_PROBE_AMBIANCE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ public:
|
|||
static const std::string SETTING_DOME_OFFSET;
|
||||
static const std::string SETTING_DOME_RADIUS;
|
||||
static const std::string SETTING_GAMMA;
|
||||
static const std::string SETTING_GLOW;
|
||||
static const std::string SETTING_GLOW;
|
||||
static const std::string SETTING_LIGHT_NORMAL;
|
||||
static const std::string SETTING_MAX_Y;
|
||||
static const std::string SETTING_MOON_ROTATION;
|
||||
|
|
@ -92,7 +92,7 @@ public:
|
|||
static const std::string SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR;
|
||||
static const std::string SETTING_DENSITY_PROFILE_LINEAR_TERM;
|
||||
static const std::string SETTING_DENSITY_PROFILE_CONSTANT_TERM;
|
||||
|
||||
|
||||
static const std::string SETTING_SKY_MOISTURE_LEVEL;
|
||||
static const std::string SETTING_SKY_DROPLET_RADIUS;
|
||||
static const std::string SETTING_SKY_ICE_LEVEL;
|
||||
|
|
@ -117,7 +117,7 @@ public:
|
|||
virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("sky"); }
|
||||
virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_SKY; }
|
||||
|
||||
// Settings status
|
||||
// Settings status
|
||||
virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE;
|
||||
|
||||
virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE;
|
||||
|
|
@ -129,7 +129,7 @@ public:
|
|||
F32 getSkyBottomRadius() const;
|
||||
F32 getSkyTopRadius() const;
|
||||
F32 getSunArcRadians() const;
|
||||
F32 getMieAnisotropy() const;
|
||||
F32 getMieAnisotropy() const;
|
||||
|
||||
F32 getSkyMoistureLevel() const;
|
||||
F32 getSkyDropletRadius() const;
|
||||
|
|
@ -139,10 +139,6 @@ public:
|
|||
// auto_adjust - if true and canAutoAdjust() is true, return 1.0
|
||||
F32 getReflectionProbeAmbiance(bool auto_adjust = false) const;
|
||||
|
||||
// get the probe ambiance setting to use for rendering (adjusted by cloud shadow, aka cloud coverage)
|
||||
// auto_adjust - if true and canAutoAdjust() is true, return 1.0
|
||||
F32 getTotalReflectionProbeAmbiance(F32 cloud_shadow_scale, bool auto_adjust = false) const;
|
||||
|
||||
// Return first (only) profile layer represented in LLSD
|
||||
LLSD getRayleighConfig() const;
|
||||
LLSD getMieConfig() const;
|
||||
|
|
@ -200,7 +196,7 @@ public:
|
|||
|
||||
F32 getCloudShadow() const;
|
||||
void setCloudShadow(F32 val);
|
||||
|
||||
|
||||
F32 getCloudVariance() const;
|
||||
void setCloudVariance(F32 val);
|
||||
|
||||
|
|
@ -299,7 +295,7 @@ public:
|
|||
|
||||
// color based on brightness
|
||||
LLColor3 getMoonlightColor() const;
|
||||
|
||||
|
||||
LLColor4 getMoonAmbient() const;
|
||||
LLColor3 getMoonDiffuse() const;
|
||||
LLColor4 getSunAmbient() const;
|
||||
|
|
@ -340,7 +336,7 @@ public:
|
|||
virtual void updateSettings() SETTINGS_OVERRIDE;
|
||||
|
||||
// if true, this sky is a candidate for auto-adjustment
|
||||
bool canAutoAdjust() const { return mCanAutoAdjust; }
|
||||
bool canAutoAdjust() const;
|
||||
|
||||
protected:
|
||||
static const std::string SETTING_LEGACY_EAST_ANGLE;
|
||||
|
|
@ -385,9 +381,6 @@ private:
|
|||
mutable LLColor4 mTotalAmbient;
|
||||
mutable LLColor4 mHazeColor;
|
||||
|
||||
// if true, this sky is a candidate for auto adjustment
|
||||
bool mCanAutoAdjust = true;
|
||||
|
||||
typedef std::map<std::string, S32> mapNameToUniformId_t;
|
||||
|
||||
static mapNameToUniformId_t sNameToUniformMapping;
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ class LLCamera
|
|||
: public LLCoordFrame
|
||||
{
|
||||
public:
|
||||
|
||||
LLCamera(const LLCamera& rhs)
|
||||
{
|
||||
*this = rhs;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,16 @@ public:
|
|||
return (F32*)&mMatrix;
|
||||
}
|
||||
|
||||
inline LLMatrix4& asMatrix4()
|
||||
{
|
||||
return *(LLMatrix4*)this;
|
||||
}
|
||||
|
||||
inline const LLMatrix4& asMatrix4() const
|
||||
{
|
||||
return *(LLMatrix4*)this;
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
mMatrix[0].clear();
|
||||
|
|
|
|||
|
|
@ -45,16 +45,15 @@
|
|||
#include "llmatrix3a.h"
|
||||
#include "lloctree.h"
|
||||
#include "llvolume.h"
|
||||
#include "llvolumeoctree.h"
|
||||
#include "llstl.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llvector4a.h"
|
||||
#include "llmatrix4a.h"
|
||||
#include "llmeshoptimizer.h"
|
||||
#include "lltimer.h"
|
||||
#include "llvolumeoctree.h"
|
||||
|
||||
#include "mikktspace/mikktspace.h"
|
||||
#include "mikktspace/mikktspace.c" // insert mikktspace implementation into llvolume object file
|
||||
#include "mikktspace/mikktspace.hh"
|
||||
|
||||
#include "meshoptimizer/meshoptimizer.h"
|
||||
|
||||
|
|
@ -377,77 +376,6 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons
|
|||
}
|
||||
}
|
||||
|
||||
class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle, LLVolumeTriangle*>
|
||||
{
|
||||
public:
|
||||
const LLVolumeFace* mFace;
|
||||
|
||||
LLVolumeOctreeRebound(const LLVolumeFace* face)
|
||||
{
|
||||
mFace = face;
|
||||
}
|
||||
|
||||
virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
|
||||
{ //this is a depth first traversal, so it's safe to assum all children have complete
|
||||
//bounding data
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
|
||||
|
||||
LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0);
|
||||
|
||||
LLVector4a& min = node->mExtents[0];
|
||||
LLVector4a& max = node->mExtents[1];
|
||||
|
||||
if (!branch->isEmpty())
|
||||
{ //node has data, find AABB that binds data set
|
||||
const LLVolumeTriangle* tri = *(branch->getDataBegin());
|
||||
|
||||
//initialize min/max to first available vertex
|
||||
min = *(tri->mV[0]);
|
||||
max = *(tri->mV[0]);
|
||||
|
||||
for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
|
||||
{ //for each triangle in node
|
||||
|
||||
//stretch by triangles in node
|
||||
tri = *iter;
|
||||
|
||||
min.setMin(min, *tri->mV[0]);
|
||||
min.setMin(min, *tri->mV[1]);
|
||||
min.setMin(min, *tri->mV[2]);
|
||||
|
||||
max.setMax(max, *tri->mV[0]);
|
||||
max.setMax(max, *tri->mV[1]);
|
||||
max.setMax(max, *tri->mV[2]);
|
||||
}
|
||||
}
|
||||
else if (branch->getChildCount() > 0)
|
||||
{ //no data, but child nodes exist
|
||||
LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0);
|
||||
|
||||
//initialize min/max to extents of first child
|
||||
min = child->mExtents[0];
|
||||
max = child->mExtents[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert(!branch->isLeaf()); // Empty leaf
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < branch->getChildCount(); ++i)
|
||||
{ //stretch by child extents
|
||||
LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0);
|
||||
min.setMin(min, child->mExtents[0]);
|
||||
max.setMax(max, child->mExtents[1]);
|
||||
}
|
||||
|
||||
node->mBounds[0].setAdd(min, max);
|
||||
node->mBounds[0].mul(0.5f);
|
||||
|
||||
node->mBounds[1].setSub(max,min);
|
||||
node->mBounds[1].mul(0.5f);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// statics
|
||||
//-------------------------------------------------------------------
|
||||
|
|
@ -5507,8 +5435,41 @@ struct MikktData
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t GetNumFaces()
|
||||
{
|
||||
return uint32_t(face->mNumIndices / 3);
|
||||
}
|
||||
|
||||
uint32_t GetNumVerticesOfFace(const uint32_t face_num)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
mikk::float3 GetPosition(const uint32_t face_num, const uint32_t vert_num)
|
||||
{
|
||||
F32* v = p[face_num * 3 + vert_num].mV;
|
||||
return mikk::float3(v);
|
||||
}
|
||||
|
||||
mikk::float3 GetTexCoord(const uint32_t face_num, const uint32_t vert_num)
|
||||
{
|
||||
F32* uv = tc[face_num * 3 + vert_num].mV;
|
||||
return mikk::float3(uv[0], uv[1], 1.0f);
|
||||
}
|
||||
|
||||
mikk::float3 GetNormal(const uint32_t face_num, const uint32_t vert_num)
|
||||
{
|
||||
F32* normal = n[face_num * 3 + vert_num].mV;
|
||||
return mikk::float3(normal);
|
||||
}
|
||||
|
||||
void SetTangentSpace(const uint32_t face_num, const uint32_t vert_num, mikk::float3 T, bool orientation)
|
||||
{
|
||||
S32 i = face_num * 3 + vert_num;
|
||||
t[i].set(T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
|
||||
}
|
||||
};
|
||||
|
||||
bool LLVolumeFace::cacheOptimize(bool gen_tangents)
|
||||
{ //optimize for vertex cache according to Forsyth method:
|
||||
|
|
@ -5520,62 +5481,9 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
|
|||
{ // generate mikkt space tangents before cache optimizing since the index buffer may change
|
||||
// a bit of a hack to do this here, but this function gets called exactly once for the lifetime of a mesh
|
||||
// and is executed on a background thread
|
||||
SMikkTSpaceInterface ms;
|
||||
|
||||
ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext)
|
||||
{
|
||||
MikktData* data = (MikktData*)pContext->m_pUserData;
|
||||
LLVolumeFace* face = data->face;
|
||||
return face->mNumIndices / 3;
|
||||
};
|
||||
|
||||
ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace)
|
||||
{
|
||||
return 3;
|
||||
};
|
||||
|
||||
ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert)
|
||||
{
|
||||
MikktData* data = (MikktData*)pContext->m_pUserData;
|
||||
F32* v = data->p[iFace * 3 + iVert].mV;
|
||||
fvPosOut[0] = v[0];
|
||||
fvPosOut[1] = v[1];
|
||||
fvPosOut[2] = v[2];
|
||||
};
|
||||
|
||||
ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert)
|
||||
{
|
||||
MikktData* data = (MikktData*)pContext->m_pUserData;
|
||||
F32* n = data->n[iFace * 3 + iVert].mV;
|
||||
fvNormOut[0] = n[0];
|
||||
fvNormOut[1] = n[1];
|
||||
fvNormOut[2] = n[2];
|
||||
};
|
||||
|
||||
ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert)
|
||||
{
|
||||
MikktData* data = (MikktData*)pContext->m_pUserData;
|
||||
F32* tc = data->tc[iFace * 3 + iVert].mV;
|
||||
fvTexcOut[0] = tc[0];
|
||||
fvTexcOut[1] = tc[1];
|
||||
};
|
||||
|
||||
ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert)
|
||||
{
|
||||
MikktData* data = (MikktData*)pContext->m_pUserData;
|
||||
S32 i = iFace * 3 + iVert;
|
||||
|
||||
data->t[i].set(fvTangent);
|
||||
data->t[i].mV[3] = fSign;
|
||||
};
|
||||
|
||||
ms.m_setTSpace = nullptr;
|
||||
|
||||
MikktData data(this);
|
||||
|
||||
SMikkTSpaceContext ctx = { &ms, &data };
|
||||
|
||||
genTangSpaceDefault(&ctx);
|
||||
mikk::Mikktspace ctx(data);
|
||||
ctx.genTangSpace();
|
||||
|
||||
//re-weld
|
||||
meshopt_Stream mos[] =
|
||||
|
|
@ -5596,9 +5504,6 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
|
|||
|
||||
if (vert_count < 65535 && vert_count != 0)
|
||||
{
|
||||
std::vector<U32> indices;
|
||||
indices.resize(mNumIndices);
|
||||
|
||||
//copy results back into volume
|
||||
resizeVertices(vert_count);
|
||||
|
||||
|
|
@ -5687,8 +5592,7 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
|
|||
|
||||
llassert(mNumIndices % 3 == 0);
|
||||
|
||||
mOctree = new LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(center, size, NULL);
|
||||
new LLVolumeOctreeListener(mOctree);
|
||||
mOctree = new LLVolumeOctree(center, size);
|
||||
const U32 num_triangles = mNumIndices / 3;
|
||||
// Initialize all the triangles we need
|
||||
mOctreeTriangles = new LLVolumeTriangle[num_triangles];
|
||||
|
|
@ -5743,7 +5647,7 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
|
|||
while (!mOctree->balance()) { }
|
||||
|
||||
//calculate AABB for each node
|
||||
LLVolumeOctreeRebound rebound(this);
|
||||
LLVolumeOctreeRebound rebound;
|
||||
rebound.traverse(mOctree);
|
||||
|
||||
if (gDebugGL)
|
||||
|
|
@ -5756,12 +5660,12 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
|
|||
void LLVolumeFace::destroyOctree()
|
||||
{
|
||||
delete mOctree;
|
||||
mOctree = NULL;
|
||||
mOctree = nullptr;
|
||||
delete[] mOctreeTriangles;
|
||||
mOctreeTriangles = NULL;
|
||||
mOctreeTriangles = nullptr;
|
||||
}
|
||||
|
||||
const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* LLVolumeFace::getOctree() const
|
||||
const LLVolumeOctree* LLVolumeFace::getOctree() const
|
||||
{
|
||||
return mOctree;
|
||||
}
|
||||
|
|
@ -6476,9 +6380,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
|
||||
const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent);
|
||||
|
||||
void LLVolumeFace::createTangents()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
|
||||
|
|
@ -6496,7 +6397,7 @@ void LLVolumeFace::createTangents()
|
|||
(*ptr++).clear();
|
||||
}
|
||||
|
||||
CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, mTangents);
|
||||
LLCalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, mTangents);
|
||||
|
||||
//normalize normals
|
||||
for (U32 i = 0; i < mNumVertices; i++)
|
||||
|
|
@ -7206,7 +7107,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
|
|||
}
|
||||
|
||||
//adapted from Lengyel, Eric. "Computing Tangent Space Basis Vectors for an Arbitrary Mesh". Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html
|
||||
void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
|
||||
void LLCalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
|
||||
const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ template <class T, typename T_PTR> class LLOctreeNode;
|
|||
class LLVolumeFace;
|
||||
class LLVolume;
|
||||
class LLVolumeTriangle;
|
||||
class LLVolumeOctree;
|
||||
|
||||
#include "lluuid.h"
|
||||
#include "v4color.h"
|
||||
|
|
@ -913,7 +914,7 @@ public:
|
|||
void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f));
|
||||
void destroyOctree();
|
||||
// Get a reference to the octree, which may be null
|
||||
const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* getOctree() const;
|
||||
const LLVolumeOctree* getOctree() const;
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -987,7 +988,7 @@ public:
|
|||
LLVector3 mNormalizedScale = LLVector3(1,1,1);
|
||||
|
||||
private:
|
||||
LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* mOctree;
|
||||
LLVolumeOctree* mOctree;
|
||||
LLVolumeTriangle* mOctreeTriangles;
|
||||
|
||||
BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
|
||||
|
|
@ -1142,6 +1143,8 @@ public:
|
|||
|
||||
std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
|
||||
|
||||
void LLCalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent);
|
||||
|
||||
BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size);
|
||||
BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size);
|
||||
BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size);
|
||||
|
|
|
|||
|
|
@ -92,15 +92,15 @@ void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTria
|
|||
}
|
||||
|
||||
LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
|
||||
const LLVolumeFace* face, F32* closest_t,
|
||||
LLVolumeFace* face, F32* closest_t,
|
||||
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
|
||||
: mFace(face),
|
||||
mStart(start),
|
||||
: mStart(start),
|
||||
mDir(dir),
|
||||
mIntersection(intersection),
|
||||
mTexCoord(tex_coord),
|
||||
mNormal(normal),
|
||||
mTangent(tangent),
|
||||
mFace(face),
|
||||
mClosestT(closest_t),
|
||||
mHitFace(false)
|
||||
{
|
||||
|
|
@ -139,7 +139,7 @@ void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle, LL
|
|||
{
|
||||
*mClosestT = t;
|
||||
mHitFace = true;
|
||||
|
||||
mHitTriangle = tri;
|
||||
if (mIntersection != NULL)
|
||||
{
|
||||
LLVector4a intersect = mDir;
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ public:
|
|||
LL_ALIGN_16(LLVector4a mPositionGroup);
|
||||
|
||||
const LLVector4a* mV[3];
|
||||
U16 mIndex[3];
|
||||
U32 mIndex[3];
|
||||
|
||||
F32 mRadius;
|
||||
mutable S32 mBinIndex;
|
||||
|
|
@ -112,7 +112,6 @@ public:
|
|||
class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*>
|
||||
{
|
||||
public:
|
||||
const LLVolumeFace* mFace;
|
||||
LLVector4a mStart;
|
||||
LLVector4a mDir;
|
||||
LLVector4a mEnd;
|
||||
|
|
@ -121,10 +120,13 @@ public:
|
|||
LLVector4a* mNormal;
|
||||
LLVector4a* mTangent;
|
||||
F32* mClosestT;
|
||||
LLVolumeFace* mFace;
|
||||
bool mHitFace;
|
||||
const LLVolumeTriangle* mHitTriangle = nullptr;
|
||||
|
||||
LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
|
||||
const LLVolumeFace* face, F32* closest_t,
|
||||
LLVolumeFace* face,
|
||||
F32* closest_t,
|
||||
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);
|
||||
|
||||
void traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);
|
||||
|
|
@ -137,4 +139,91 @@ class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle, LLVolum
|
|||
virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch);
|
||||
};
|
||||
|
||||
class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle, LLVolumeTriangle*>
|
||||
{
|
||||
public:
|
||||
LLVolumeOctreeRebound()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
|
||||
{ //this is a depth first traversal, so it's safe to assum all children have complete
|
||||
//bounding data
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
|
||||
|
||||
LLVolumeOctreeListener* node = (LLVolumeOctreeListener*)branch->getListener(0);
|
||||
|
||||
LLVector4a& min = node->mExtents[0];
|
||||
LLVector4a& max = node->mExtents[1];
|
||||
|
||||
if (!branch->isEmpty())
|
||||
{ //node has data, find AABB that binds data set
|
||||
const LLVolumeTriangle* tri = *(branch->getDataBegin());
|
||||
|
||||
//initialize min/max to first available vertex
|
||||
min = *(tri->mV[0]);
|
||||
max = *(tri->mV[0]);
|
||||
|
||||
for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
|
||||
{ //for each triangle in node
|
||||
|
||||
//stretch by triangles in node
|
||||
tri = *iter;
|
||||
|
||||
min.setMin(min, *tri->mV[0]);
|
||||
min.setMin(min, *tri->mV[1]);
|
||||
min.setMin(min, *tri->mV[2]);
|
||||
|
||||
max.setMax(max, *tri->mV[0]);
|
||||
max.setMax(max, *tri->mV[1]);
|
||||
max.setMax(max, *tri->mV[2]);
|
||||
}
|
||||
}
|
||||
else if (branch->getChildCount() > 0)
|
||||
{ //no data, but child nodes exist
|
||||
LLVolumeOctreeListener* child = (LLVolumeOctreeListener*)branch->getChild(0)->getListener(0);
|
||||
|
||||
//initialize min/max to extents of first child
|
||||
min = child->mExtents[0];
|
||||
max = child->mExtents[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert(!branch->isLeaf()); // Empty leaf
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < branch->getChildCount(); ++i)
|
||||
{ //stretch by child extents
|
||||
LLVolumeOctreeListener* child = (LLVolumeOctreeListener*)branch->getChild(i)->getListener(0);
|
||||
min.setMin(min, child->mExtents[0]);
|
||||
max.setMax(max, child->mExtents[1]);
|
||||
}
|
||||
|
||||
node->mBounds[0].setAdd(min, max);
|
||||
node->mBounds[0].mul(0.5f);
|
||||
|
||||
node->mBounds[1].setSub(max, min);
|
||||
node->mBounds[1].mul(0.5f);
|
||||
}
|
||||
};
|
||||
|
||||
class LLVolumeOctree : public LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>, public LLRefCount
|
||||
{
|
||||
public:
|
||||
LLVolumeOctree(const LLVector4a& center, const LLVector4a& size)
|
||||
:
|
||||
LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(center, size, nullptr),
|
||||
LLRefCount()
|
||||
{
|
||||
new LLVolumeOctreeListener(this);
|
||||
}
|
||||
|
||||
LLVolumeOctree()
|
||||
: LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(LLVector4a::getZero(), LLVector4a(1.f,1.f,1.f), nullptr),
|
||||
LLRefCount()
|
||||
{
|
||||
new LLVolumeOctreeListener(this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -582,7 +582,7 @@ void LLPluginProcessParent::idle(void)
|
|||
params.args.add("-e");
|
||||
params.args.add("tell application \"Terminal\"");
|
||||
params.args.add("-e");
|
||||
params.args.add(STRINGIZE("set win to do script \"gdb -pid "
|
||||
params.args.add(STRINGIZE("set win to do script \"lldb -pid "
|
||||
<< mProcess->getProcessID() << "\""));
|
||||
params.args.add("-e");
|
||||
params.args.add("do script \"continue\" in win");
|
||||
|
|
|
|||
|
|
@ -5,21 +5,21 @@
|
|||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, 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$
|
||||
*/
|
||||
|
|
@ -130,6 +130,16 @@ public:
|
|||
bool mOverrideDoubleSided = false;
|
||||
bool mOverrideAlphaMode = false;
|
||||
|
||||
// *TODO: If/when we implement additional GLTF extensions, they may not be
|
||||
// compatible with our GLTF terrain implementation. We may want to disallow
|
||||
// materials with some features from being set on terrain, if their
|
||||
// implementation on terrain is not compliant with the spec:
|
||||
// - KHR_materials_transmission: Probably OK?
|
||||
// - KHR_materials_ior: Probably OK?
|
||||
// - KHR_materials_volume: Likely incompatible, as our terrain
|
||||
// heightmaps cannot currently be described as finite enclosed
|
||||
// volumes.
|
||||
// See also LLPanelRegionTerrainInfo::validateMaterials
|
||||
// These fields are local to viewer and are a part of local bitmap support
|
||||
typedef std::map<LLUUID, LLUUID> local_tex_map_t;
|
||||
local_tex_map_t mTrackingIdToLocalTexture;
|
||||
|
|
@ -204,7 +214,7 @@ public:
|
|||
void writeToModel(tinygltf::Model& model, S32 mat_index) const;
|
||||
|
||||
virtual void applyOverride(const LLGLTFMaterial& override_mat);
|
||||
|
||||
|
||||
// apply the given LLSD override data
|
||||
void applyOverrideLLSD(const LLSD& data);
|
||||
|
||||
|
|
|
|||
|
|
@ -1934,6 +1934,19 @@ void LLReflectionProbeParams::setIsDynamic(bool is_dynamic)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void LLReflectionProbeParams::setIsMirror(bool is_mirror)
|
||||
{
|
||||
if (is_mirror)
|
||||
{
|
||||
mFlags |= FLAG_MIRROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
mFlags &= ~FLAG_MIRROR;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
LLFlexibleObjectData::LLFlexibleObjectData()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ public:
|
|||
{
|
||||
FLAG_BOX_VOLUME = 0x01, // use a box influence volume
|
||||
FLAG_DYNAMIC = 0x02, // render dynamic objects (avatars) into this Reflection Probe
|
||||
FLAG_MIRROR = 0x04, // This probe is used for reflections on realtime mirrors.
|
||||
};
|
||||
|
||||
protected:
|
||||
|
|
@ -209,11 +210,13 @@ public:
|
|||
void setClipDistance(F32 distance) { mClipDistance = llclamp(distance, REFLECTION_PROBE_MIN_CLIP_DISTANCE, REFLECTION_PROBE_MAX_CLIP_DISTANCE); }
|
||||
void setIsBox(bool is_box);
|
||||
void setIsDynamic(bool is_dynamic);
|
||||
void setIsMirror(bool is_mirror);
|
||||
|
||||
F32 getAmbiance() const { return mAmbiance; }
|
||||
F32 getClipDistance() const { return mClipDistance; }
|
||||
bool getIsBox() const { return (mFlags & FLAG_BOX_VOLUME) != 0; }
|
||||
bool getIsDynamic() const { return (mFlags & FLAG_DYNAMIC) != 0; }
|
||||
bool getIsMirror() const { return (mFlags & FLAG_MIRROR) != 0; }
|
||||
};
|
||||
|
||||
//-------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -685,6 +685,7 @@ S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams)
|
|||
mMaterialUpdatePending = true;
|
||||
}
|
||||
mMaterial = pMaterialParams;
|
||||
|
||||
return TEM_CHANGE_TEXTURE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
/**
|
||||
/**
|
||||
* @file llgltfmaterial_test.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* $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$
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
|
|
|||
|
|
@ -1190,6 +1190,8 @@ S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTex
|
|||
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
S32 index = mTexture[uniform];
|
||||
if (index != -1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -49,13 +49,14 @@ public:
|
|||
bool hasShadows = false;
|
||||
bool hasAmbientOcclusion = false;
|
||||
bool hasSrgb = false;
|
||||
bool encodesNormal = false; // include: shaders\class1\environment\encodeNormF.glsl
|
||||
bool isDeferred = false;
|
||||
bool hasScreenSpaceReflections = false;
|
||||
bool disableTextureIndex = false;
|
||||
bool hasAlphaMask = false;
|
||||
bool hasReflectionProbes = false;
|
||||
bool attachNothing = false;
|
||||
bool hasHeroProbes = false;
|
||||
bool isPBRTerrain = false;
|
||||
};
|
||||
|
||||
// ============= Structure for caching shader uniforms ===============
|
||||
|
|
|
|||
|
|
@ -49,6 +49,10 @@ LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps)
|
|||
mUseMipMaps = usemipmaps ;
|
||||
// Create an empty image of the specified size and width
|
||||
mGLTexturep = new LLImageGL(raw, usemipmaps) ;
|
||||
mFullWidth = mGLTexturep->getCurrentWidth();
|
||||
mFullHeight = mGLTexturep->getCurrentHeight();
|
||||
mComponents = mGLTexturep->getComponents();
|
||||
setTexelsPerImage();
|
||||
}
|
||||
|
||||
LLGLTexture::~LLGLTexture()
|
||||
|
|
@ -95,7 +99,8 @@ void LLGLTexture::setBoostLevel(S32 level)
|
|||
mBoostLevel = level ;
|
||||
if(mBoostLevel != LLGLTexture::BOOST_NONE
|
||||
&& mBoostLevel != LLGLTexture::BOOST_ICON
|
||||
&& mBoostLevel != LLGLTexture::BOOST_THUMBNAIL)
|
||||
&& mBoostLevel != LLGLTexture::BOOST_THUMBNAIL
|
||||
&& mBoostLevel != LLGLTexture::BOOST_TERRAIN)
|
||||
{
|
||||
setNoDelete() ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class LLGLTexture : public LLTexture
|
|||
public:
|
||||
enum
|
||||
{
|
||||
MAX_IMAGE_SIZE_DEFAULT = 1024,
|
||||
MAX_IMAGE_SIZE_DEFAULT = 2048,
|
||||
INVALID_DISCARD_LEVEL = 0x7fff
|
||||
};
|
||||
|
||||
|
|
@ -52,10 +52,11 @@ public:
|
|||
BOOST_AVATAR ,
|
||||
BOOST_AVATAR_BAKED ,
|
||||
BOOST_SCULPTED ,
|
||||
BOOST_TERRAIN , // Needed for minimap generation for now. Lower than BOOST_HIGH so the texture stats don't get forced, i.e. texture stats are manually managed by minimap/terrain instead.
|
||||
|
||||
BOOST_HIGH = 10,
|
||||
BOOST_BUMP ,
|
||||
BOOST_TERRAIN , // has to be high priority for minimap / low detail
|
||||
BOOST_UNUSED_1 , // Placeholder to avoid disrupting habits around texture debug
|
||||
BOOST_SELECTED ,
|
||||
BOOST_AVATAR_BAKED_SELF ,
|
||||
BOOST_AVATAR_SELF , // needed for baking avatar
|
||||
|
|
|
|||
|
|
@ -2068,10 +2068,6 @@ void LLRender::diffuseColor3f(F32 r, F32 g, F32 b)
|
|||
{
|
||||
shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
glColor3f(r,g,b);
|
||||
}
|
||||
}
|
||||
|
||||
void LLRender::diffuseColor3fv(const F32* c)
|
||||
|
|
@ -2083,10 +2079,6 @@ void LLRender::diffuseColor3fv(const F32* c)
|
|||
{
|
||||
shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0], c[1], c[2], 1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
glColor3fv(c);
|
||||
}
|
||||
}
|
||||
|
||||
void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a)
|
||||
|
|
@ -2098,10 +2090,6 @@ void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a)
|
|||
{
|
||||
shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,a);
|
||||
}
|
||||
else
|
||||
{
|
||||
glColor4f(r,g,b,a);
|
||||
}
|
||||
}
|
||||
|
||||
void LLRender::diffuseColor4fv(const F32* c)
|
||||
|
|
@ -2113,10 +2101,6 @@ void LLRender::diffuseColor4fv(const F32* c)
|
|||
{
|
||||
shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
glColor4fv(c);
|
||||
}
|
||||
}
|
||||
|
||||
void LLRender::diffuseColor4ubv(const U8* c)
|
||||
|
|
@ -2128,10 +2112,6 @@ void LLRender::diffuseColor4ubv(const U8* c)
|
|||
{
|
||||
shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0]/255.f, c[1]/255.f, c[2]/255.f, c[3]/255.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
glColor4ubv(c);
|
||||
}
|
||||
}
|
||||
|
||||
void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a)
|
||||
|
|
@ -2143,10 +2123,6 @@ void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a)
|
|||
{
|
||||
shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r/255.f, g/255.f, b/255.f, a/255.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
glColor4ub(r,g,b,a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
/**
|
||||
/**
|
||||
* @file llrendertarget.cpp
|
||||
* @brief LLRenderTarget implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
|
@ -44,7 +44,7 @@ void check_framebuffer_status()
|
|||
break;
|
||||
default:
|
||||
LL_WARNS() << "check_framebuffer_status failed -- " << std::hex << status << LL_ENDL;
|
||||
ll_fail("check_framebuffer_status failed");
|
||||
ll_fail("check_framebuffer_status failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -75,10 +75,10 @@ LLRenderTarget::~LLRenderTarget()
|
|||
}
|
||||
|
||||
void LLRenderTarget::resize(U32 resx, U32 resy)
|
||||
{
|
||||
{
|
||||
//for accounting, get the number of pixels added/subtracted
|
||||
S32 pix_diff = (resx*resy)-(mResX*mResY);
|
||||
|
||||
|
||||
mResX = resx;
|
||||
mResY = resy;
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ void LLRenderTarget::resize(U32 resx, U32 resy)
|
|||
}
|
||||
|
||||
if (mDepth)
|
||||
{
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
|
||||
U32 internal_type = LLTexUnit::getInternalType(mUsage);
|
||||
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
|
||||
|
|
@ -100,7 +100,7 @@ void LLRenderTarget::resize(U32 resx, U32 resy)
|
|||
sBytesAllocated += pix_diff*4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLTexUnit::eTextureType usage, LLTexUnit::eTextureMipGeneration generateMipMaps)
|
||||
{
|
||||
|
|
@ -112,7 +112,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLT
|
|||
resy = llmin(resy, (U32) gGLManager.mGLMaxTextureSize);
|
||||
|
||||
release();
|
||||
|
||||
|
||||
mResX = resx;
|
||||
mResY = resy;
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLT
|
|||
// Calculate the number of mip levels based upon resolution that we should have.
|
||||
mMipLevels = 1 + floor(log10((float)llmax(mResX, mResY))/log10(2.0));
|
||||
}
|
||||
|
||||
|
||||
if (depth)
|
||||
{
|
||||
if (!allocateDepth())
|
||||
|
|
@ -140,12 +140,12 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLT
|
|||
if (mDepth)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
|
||||
}
|
||||
|
||||
|
||||
return addColorAttachment(color_fmt);
|
||||
}
|
||||
|
||||
|
|
@ -190,7 +190,7 @@ void LLRenderTarget::releaseColorAttachment()
|
|||
llassert(!isBoundInStack());
|
||||
llassert(mTex.size() == 1); //cannot use releaseColorAttachment with LLRenderTarget managed color targets
|
||||
llassert(mFBO != 0); // mFBO must be valid
|
||||
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
|
||||
|
|
@ -238,12 +238,12 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sBytesAllocated += mResX*mResY*4;
|
||||
|
||||
stop_glerror();
|
||||
|
||||
|
||||
|
||||
if (offset == 0)
|
||||
{ //use bilinear filtering on single texture render targets that aren't multisampled
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
|
||||
|
|
@ -266,15 +266,15 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
|
|||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
|
||||
if (mFBO)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset,
|
||||
LLTexUnit::getInternalType(mUsage), tex, 0);
|
||||
|
||||
|
||||
check_framebuffer_status();
|
||||
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
|
||||
}
|
||||
|
||||
|
|
@ -286,8 +286,8 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
|
|||
bindTarget();
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -296,7 +296,7 @@ bool LLRenderTarget::allocateDepth()
|
|||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
|
||||
LLImageGL::generateTextures(1, &mDepth);
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
|
||||
|
||||
|
||||
U32 internal_type = LLTexUnit::getInternalType(mUsage);
|
||||
stop_glerror();
|
||||
clear_glerror();
|
||||
|
|
@ -336,7 +336,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
|
|||
if (mDepth)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, target.mFBO);
|
||||
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
|
||||
check_framebuffer_status();
|
||||
|
|
@ -355,7 +355,7 @@ void LLRenderTarget::release()
|
|||
if (mDepth)
|
||||
{
|
||||
LLImageGL::deleteTextures(1, &mDepth);
|
||||
|
||||
|
||||
mDepth = 0;
|
||||
|
||||
sBytesAllocated -= mResX*mResY*4;
|
||||
|
|
@ -408,7 +408,7 @@ void LLRenderTarget::release()
|
|||
|
||||
mTex.clear();
|
||||
mInternalFormat.clear();
|
||||
|
||||
|
||||
mResX = mResY = 0;
|
||||
}
|
||||
|
||||
|
|
@ -417,7 +417,7 @@ void LLRenderTarget::bindTarget()
|
|||
LL_PROFILE_GPU_ZONE("bindTarget");
|
||||
llassert(mFBO);
|
||||
llassert(!isBoundInStack());
|
||||
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
sCurFBO = mFBO;
|
||||
|
||||
|
|
@ -427,7 +427,7 @@ void LLRenderTarget::bindTarget()
|
|||
GL_COLOR_ATTACHMENT2,
|
||||
GL_COLOR_ATTACHMENT3};
|
||||
glDrawBuffers(mTex.size(), drawbuffers);
|
||||
|
||||
|
||||
if (mTex.empty())
|
||||
{ //no color buffer to draw to
|
||||
glDrawBuffer(GL_NONE);
|
||||
|
|
@ -452,7 +452,7 @@ void LLRenderTarget::clear(U32 mask_in)
|
|||
if (mUseDepth)
|
||||
{
|
||||
mask |= GL_DEPTH_BUFFER_BIT;
|
||||
|
||||
|
||||
}
|
||||
if (mFBO)
|
||||
{
|
||||
|
|
@ -560,11 +560,38 @@ bool LLRenderTarget::isBoundInStack() const
|
|||
{
|
||||
LLRenderTarget* cur = sBoundTarget;
|
||||
while (cur && cur != this)
|
||||
{
|
||||
{
|
||||
cur = cur->mPreviousRT;
|
||||
}
|
||||
|
||||
return cur == this;
|
||||
}
|
||||
|
||||
void LLRenderTarget::swapFBORefs(LLRenderTarget& other)
|
||||
{
|
||||
// Must be initialized
|
||||
llassert(mFBO);
|
||||
llassert(other.mFBO);
|
||||
|
||||
// Must be unbound
|
||||
// *NOTE: mPreviousRT can be non-null even if this target is unbound - presumably for debugging purposes?
|
||||
llassert(sCurFBO != mFBO);
|
||||
llassert(sCurFBO != other.mFBO);
|
||||
llassert(!isBoundInStack());
|
||||
llassert(!other.isBoundInStack());
|
||||
|
||||
// Must be same type
|
||||
llassert(sUseFBO == other.sUseFBO);
|
||||
llassert(mResX == other.mResX);
|
||||
llassert(mResY == other.mResY);
|
||||
llassert(mInternalFormat == other.mInternalFormat);
|
||||
llassert(mTex.size() == other.mTex.size());
|
||||
llassert(mDepth == other.mDepth);
|
||||
llassert(mUseDepth == other.mUseDepth);
|
||||
llassert(mGenerateMipMaps == other.mGenerateMipMaps);
|
||||
llassert(mMipLevels == other.mMipLevels);
|
||||
llassert(mUsage == other.mUsage);
|
||||
|
||||
std::swap(mFBO, other.mFBO);
|
||||
std::swap(mTex, other.mTex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,6 +169,9 @@ public:
|
|||
|
||||
static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
|
||||
|
||||
// *HACK
|
||||
void swapFBORefs(LLRenderTarget& other);
|
||||
|
||||
protected:
|
||||
U32 mResX;
|
||||
U32 mResY;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ using std::make_pair;
|
|||
using std::string;
|
||||
|
||||
LLShaderMgr * LLShaderMgr::sInstance = NULL;
|
||||
bool LLShaderMgr::sMirrorsEnabled = false;
|
||||
|
||||
LLShaderMgr::LLShaderMgr()
|
||||
{
|
||||
|
|
@ -183,7 +184,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
// Attach Fragment Shader Features Next
|
||||
///////////////////////////////////////
|
||||
|
||||
// NOTE order of shader object attaching is VERY IMPORTANT!!!
|
||||
// NOTE order of shader object attaching is VERY IMPORTANT!!!
|
||||
|
||||
if (!shader->attachFragmentObject("deferred/globalF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (features->hasSrgb || features->hasAtmospherics || features->calculatesAtmospherics || features->isDeferred)
|
||||
{
|
||||
if (!shader->attachFragmentObject("environment/srgbF.glsl"))
|
||||
|
|
@ -257,14 +264,6 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
}
|
||||
}
|
||||
|
||||
if (features->encodesNormal)
|
||||
{
|
||||
if (!shader->attachFragmentObject("environment/encodeNormF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (features->hasAtmospherics || features->isDeferred)
|
||||
{
|
||||
if (!shader->attachFragmentObject("windlight/atmosphericsFuncs.glsl")) {
|
||||
|
|
@ -277,6 +276,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
}
|
||||
}
|
||||
|
||||
if (features->isPBRTerrain)
|
||||
{
|
||||
if (!shader->attachFragmentObject("deferred/pbrterrainUtilF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE order of shader object attaching is VERY IMPORTANT!!!
|
||||
if (features->hasAtmospherics)
|
||||
{
|
||||
|
|
@ -321,7 +328,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
|
||||
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -572,21 +579,38 @@ 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");
|
||||
}
|
||||
|
||||
if (sMirrorsEnabled)
|
||||
{
|
||||
extra_code_text[extra_code_count++] = strdup("#define HERO_PROBES 1\n");
|
||||
}
|
||||
|
||||
// Use alpha float to store bit flags
|
||||
// See: C++: addDeferredAttachment(), shader: frag_data[2]
|
||||
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS 0.0 \n"); // atmo kill
|
||||
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_ATMOS 0.34\n"); // bit 0
|
||||
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_PBR 0.67\n"); // bit 1
|
||||
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_HDRI 1.0\n"); // bit 2
|
||||
extra_code_text[extra_code_count++] = strdup("#define GET_GBUFFER_FLAG(flag) (abs(norm.w-flag)< 0.1)\n");
|
||||
|
||||
if (defines)
|
||||
|
|
@ -1192,6 +1216,9 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("emissiveColor");
|
||||
mReservedUniforms.push_back("metallicFactor");
|
||||
mReservedUniforms.push_back("roughnessFactor");
|
||||
mReservedUniforms.push_back("mirror_flag");
|
||||
mReservedUniforms.push_back("clipPlane");
|
||||
mReservedUniforms.push_back("clipSign");
|
||||
|
||||
mReservedUniforms.push_back("diffuseMap");
|
||||
mReservedUniforms.push_back("altDiffuseMap");
|
||||
|
|
@ -1204,6 +1231,7 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("sceneDepth");
|
||||
mReservedUniforms.push_back("reflectionProbes");
|
||||
mReservedUniforms.push_back("irradianceProbes");
|
||||
mReservedUniforms.push_back("heroProbes");
|
||||
mReservedUniforms.push_back("cloud_noise_texture");
|
||||
mReservedUniforms.push_back("cloud_noise_texture_next");
|
||||
mReservedUniforms.push_back("fullbright");
|
||||
|
|
@ -1374,8 +1402,32 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("detail_1");
|
||||
mReservedUniforms.push_back("detail_2");
|
||||
mReservedUniforms.push_back("detail_3");
|
||||
|
||||
mReservedUniforms.push_back("alpha_ramp");
|
||||
|
||||
mReservedUniforms.push_back("detail_0_base_color");
|
||||
mReservedUniforms.push_back("detail_1_base_color");
|
||||
mReservedUniforms.push_back("detail_2_base_color");
|
||||
mReservedUniforms.push_back("detail_3_base_color");
|
||||
mReservedUniforms.push_back("detail_0_normal");
|
||||
mReservedUniforms.push_back("detail_1_normal");
|
||||
mReservedUniforms.push_back("detail_2_normal");
|
||||
mReservedUniforms.push_back("detail_3_normal");
|
||||
mReservedUniforms.push_back("detail_0_metallic_roughness");
|
||||
mReservedUniforms.push_back("detail_1_metallic_roughness");
|
||||
mReservedUniforms.push_back("detail_2_metallic_roughness");
|
||||
mReservedUniforms.push_back("detail_3_metallic_roughness");
|
||||
mReservedUniforms.push_back("detail_0_emissive");
|
||||
mReservedUniforms.push_back("detail_1_emissive");
|
||||
mReservedUniforms.push_back("detail_2_emissive");
|
||||
mReservedUniforms.push_back("detail_3_emissive");
|
||||
|
||||
mReservedUniforms.push_back("baseColorFactors");
|
||||
mReservedUniforms.push_back("metallicFactors");
|
||||
mReservedUniforms.push_back("roughnessFactors");
|
||||
mReservedUniforms.push_back("emissiveColors");
|
||||
mReservedUniforms.push_back("minimum_alphas");
|
||||
|
||||
mReservedUniforms.push_back("origin");
|
||||
mReservedUniforms.push_back("display_gamma");
|
||||
|
||||
|
|
@ -1397,6 +1449,7 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("cloud_variance");
|
||||
mReservedUniforms.push_back("reflection_probe_ambiance");
|
||||
mReservedUniforms.push_back("max_probe_lod");
|
||||
mReservedUniforms.push_back("probe_strength");
|
||||
|
||||
mReservedUniforms.push_back("sh_input_r");
|
||||
mReservedUniforms.push_back("sh_input_g");
|
||||
|
|
@ -1407,6 +1460,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;
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@ public:
|
|||
EMISSIVE_COLOR, // "emissiveColor"
|
||||
METALLIC_FACTOR, // "metallicFactor"
|
||||
ROUGHNESS_FACTOR, // "roughnessFactor"
|
||||
MIRROR_FLAG, // "mirror_flag"
|
||||
CLIP_PLANE, // "clipPlane"
|
||||
CLIP_SIGN, // "clipSign"
|
||||
DIFFUSE_MAP, // "diffuseMap"
|
||||
ALTERNATE_DIFFUSE_MAP, // "altDiffuseMap"
|
||||
SPECULAR_MAP, // "specularMap"
|
||||
|
|
@ -96,6 +99,7 @@ public:
|
|||
SCENE_DEPTH, // "sceneDepth"
|
||||
REFLECTION_PROBES, // "reflectionProbes"
|
||||
IRRADIANCE_PROBES, // "irradianceProbes"
|
||||
HERO_PROBE, // "heroProbes"
|
||||
CLOUD_NOISE_MAP, // "cloud_noise_texture"
|
||||
CLOUD_NOISE_MAP_NEXT, // "cloud_noise_texture_next"
|
||||
FULLBRIGHT, // "fullbright"
|
||||
|
|
@ -251,8 +255,32 @@ public:
|
|||
TERRAIN_DETAIL1, // "detail_1"
|
||||
TERRAIN_DETAIL2, // "detail_2"
|
||||
TERRAIN_DETAIL3, // "detail_3"
|
||||
|
||||
TERRAIN_ALPHARAMP, // "alpha_ramp"
|
||||
|
||||
TERRAIN_DETAIL0_BASE_COLOR, // "detail_0_base_color" (GLTF)
|
||||
TERRAIN_DETAIL1_BASE_COLOR, // "detail_1_base_color" (GLTF)
|
||||
TERRAIN_DETAIL2_BASE_COLOR, // "detail_2_base_color" (GLTF)
|
||||
TERRAIN_DETAIL3_BASE_COLOR, // "detail_3_base_color" (GLTF)
|
||||
TERRAIN_DETAIL0_NORMAL, // "detail_0_normal" (GLTF)
|
||||
TERRAIN_DETAIL1_NORMAL, // "detail_1_normal" (GLTF)
|
||||
TERRAIN_DETAIL2_NORMAL, // "detail_2_normal" (GLTF)
|
||||
TERRAIN_DETAIL3_NORMAL, // "detail_3_normal" (GLTF)
|
||||
TERRAIN_DETAIL0_METALLIC_ROUGHNESS, // "detail_0_metallic_roughness" (GLTF)
|
||||
TERRAIN_DETAIL1_METALLIC_ROUGHNESS, // "detail_1_metallic_roughness" (GLTF)
|
||||
TERRAIN_DETAIL2_METALLIC_ROUGHNESS, // "detail_2_metallic_roughness" (GLTF)
|
||||
TERRAIN_DETAIL3_METALLIC_ROUGHNESS, // "detail_3_metallic_roughness" (GLTF)
|
||||
TERRAIN_DETAIL0_EMISSIVE, // "detail_0_emissive" (GLTF)
|
||||
TERRAIN_DETAIL1_EMISSIVE, // "detail_1_emissive" (GLTF)
|
||||
TERRAIN_DETAIL2_EMISSIVE, // "detail_2_emissive" (GLTF)
|
||||
TERRAIN_DETAIL3_EMISSIVE, // "detail_3_emissive" (GLTF)
|
||||
|
||||
TERRAIN_BASE_COLOR_FACTORS, // "baseColorFactors" (GLTF)
|
||||
TERRAIN_METALLIC_FACTORS, // "metallicFactors" (GLTF)
|
||||
TERRAIN_ROUGHNESS_FACTORS, // "roughnessFactors" (GLTF)
|
||||
TERRAIN_EMISSIVE_COLORS, // "emissiveColors" (GLTF)
|
||||
TERRAIN_MINIMUM_ALPHAS, // "minimum_alphas" (GLTF)
|
||||
|
||||
SHINY_ORIGIN, // "origin"
|
||||
DISPLAY_GAMMA, // "display_gamma"
|
||||
|
||||
|
|
@ -279,6 +307,7 @@ public:
|
|||
|
||||
REFLECTION_PROBE_AMBIANCE, // "reflection_probe_ambiance"
|
||||
REFLECTION_PROBE_MAX_LOD, // "max_probe_lod"
|
||||
REFLECTION_PROBE_STRENGTH, // "probe_strength"
|
||||
SH_INPUT_L1R, // "sh_input_r"
|
||||
SH_INPUT_L1G, // "sh_input_g"
|
||||
SH_INPUT_L1B, // "sh_input_b"
|
||||
|
|
@ -287,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
|
||||
|
|
@ -336,6 +368,7 @@ public:
|
|||
bool mShaderCacheInitialized = false;
|
||||
bool mShaderCacheEnabled = false;
|
||||
std::string mShaderCacheDir;
|
||||
static bool sMirrorsEnabled;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
|||
|
|
@ -657,7 +657,7 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
|
|||
U16 idx = indicesp[i];
|
||||
gGL.vertex3fv(pos[idx].getF32ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
gGL.end();
|
||||
gGL.flush();
|
||||
}
|
||||
|
|
@ -741,8 +741,8 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
|
|||
llassert(mGLBuffer == sGLRenderBuffer);
|
||||
llassert(mGLIndices == sGLRenderIndices);
|
||||
gGL.syncMatrices();
|
||||
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
|
||||
(GLvoid*) (indices_offset * sizeof(U16)));
|
||||
glDrawRangeElements(sGLMode[mode], start, end, count, mIndicesType,
|
||||
(GLvoid*) (indices_offset * (size_t) mIndicesStride));
|
||||
}
|
||||
|
||||
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
|
||||
|
|
@ -1139,7 +1139,7 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count)
|
|||
}
|
||||
|
||||
// flush the given byte range
|
||||
// target -- "targret" parameter for glBufferSubData
|
||||
// target -- "target" parameter for glBufferSubData
|
||||
// start -- first byte to copy
|
||||
// end -- last byte to copy (NOT last byte + 1)
|
||||
// data -- mMappedData or mMappedIndexData
|
||||
|
|
@ -1301,6 +1301,8 @@ bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector4a>& strider, U32 index,
|
|||
}
|
||||
bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, U32 index, S32 count)
|
||||
{
|
||||
llassert(mIndicesStride == 2); // cannot access 32-bit indices with U16 strider
|
||||
llassert(mIndicesType == GL_UNSIGNED_SHORT);
|
||||
return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index, count);
|
||||
}
|
||||
bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, U32 index, S32 count)
|
||||
|
|
@ -1319,6 +1321,10 @@ bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, U32 index,
|
|||
{
|
||||
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count);
|
||||
}
|
||||
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector4a>& strider, U32 index, S32 count)
|
||||
{
|
||||
return VertexBufferStrider<LLVector4a, TYPE_NORMAL>::get(*this, strider, index, count);
|
||||
}
|
||||
bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, U32 index, S32 count)
|
||||
{
|
||||
return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count);
|
||||
|
|
@ -1503,4 +1509,39 @@ void LLVertexBuffer::setColorData(const LLColor4U* data)
|
|||
flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_COLOR], mOffsets[TYPE_COLOR] + sTypeSize[TYPE_COLOR] * getNumVerts() - 1, (U8*) data);
|
||||
}
|
||||
|
||||
void LLVertexBuffer::setNormalData(const LLVector4a* data)
|
||||
{
|
||||
llassert(sGLRenderBuffer == mGLBuffer);
|
||||
flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_NORMAL], mOffsets[TYPE_NORMAL] + sTypeSize[TYPE_NORMAL] * getNumVerts() - 1, (U8*) data);
|
||||
}
|
||||
|
||||
void LLVertexBuffer::setTangentData(const LLVector4a* data)
|
||||
{
|
||||
llassert(sGLRenderBuffer == mGLBuffer);
|
||||
flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TANGENT], mOffsets[TYPE_TANGENT] + sTypeSize[TYPE_TANGENT] * getNumVerts() - 1, (U8*) data);
|
||||
}
|
||||
|
||||
void LLVertexBuffer::setWeight4Data(const LLVector4a* data)
|
||||
{
|
||||
llassert(sGLRenderBuffer == mGLBuffer);
|
||||
flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_WEIGHT4], mOffsets[TYPE_WEIGHT4] + sTypeSize[TYPE_WEIGHT4] * getNumVerts() - 1, (U8*) data);
|
||||
}
|
||||
|
||||
void LLVertexBuffer::setIndexData(const U16* data)
|
||||
{
|
||||
llassert(sGLRenderIndices == mGLIndices);
|
||||
flush_vbo(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16) * getNumIndices() - 1, (U8*) data);
|
||||
}
|
||||
|
||||
void LLVertexBuffer::setIndexData(const U32* data)
|
||||
{
|
||||
llassert(sGLRenderIndices == mGLIndices);
|
||||
if (mIndicesType != GL_UNSIGNED_INT)
|
||||
{ // HACK -- vertex buffers are initialized as 16-bit indices, but can be switched to 32-bit indices
|
||||
mIndicesType = GL_UNSIGNED_INT;
|
||||
mIndicesStride = 4;
|
||||
mNumIndices /= 2;
|
||||
}
|
||||
flush_vbo(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U32) * getNumIndices() - 1, (U8*)data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ public:
|
|||
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
|
||||
bool getTexCoord2Strider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
|
||||
bool getNormalStrider(LLStrider<LLVector3>& strider, U32 index=0, S32 count = -1);
|
||||
bool getNormalStrider(LLStrider<LLVector4a>& strider, U32 index = 0, S32 count = -1);
|
||||
bool getTangentStrider(LLStrider<LLVector3>& strider, U32 index=0, S32 count = -1);
|
||||
bool getTangentStrider(LLStrider<LLVector4a>& strider, U32 index=0, S32 count = -1);
|
||||
bool getColorStrider(LLStrider<LLColor4U>& strider, U32 index=0, S32 count = -1);
|
||||
|
|
@ -187,15 +188,15 @@ public:
|
|||
bool getWeightStrider(LLStrider<F32>& strider, U32 index=0, S32 count = -1);
|
||||
bool getWeight4Strider(LLStrider<LLVector4>& strider, U32 index=0, S32 count = -1);
|
||||
bool getClothWeightStrider(LLStrider<LLVector4>& strider, U32 index=0, S32 count = -1);
|
||||
bool getBasecolorTexcoordStrider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
|
||||
bool getNormalTexcoordStrider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
|
||||
bool getMetallicRoughnessTexcoordStrider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
|
||||
bool getEmissiveTexcoordStrider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
|
||||
|
||||
void setPositionData(const LLVector4a* data);
|
||||
void setNormalData(const LLVector4a* data);
|
||||
void setTangentData(const LLVector4a* data);
|
||||
void setWeight4Data(const LLVector4a* data);
|
||||
void setTexCoordData(const LLVector2* data);
|
||||
void setColorData(const LLColor4U* data);
|
||||
|
||||
void setIndexData(const U16* data);
|
||||
void setIndexData(const U32* data);
|
||||
|
||||
U32 getNumVerts() const { return mNumVerts; }
|
||||
U32 getNumIndices() const { return mNumIndices; }
|
||||
|
|
@ -227,6 +228,8 @@ protected:
|
|||
U32 mGLIndices = 0; // GL IBO handle
|
||||
U32 mNumVerts = 0; // Number of vertices allocated
|
||||
U32 mNumIndices = 0; // Number of indices allocated
|
||||
U32 mIndicesType = GL_UNSIGNED_SHORT; // type of indices in index buffer
|
||||
U32 mIndicesStride = 2; // size of each index in bytes
|
||||
U32 mOffsets[TYPE_MAX]; // byte offsets into mMappedData of each attribute
|
||||
|
||||
U8* mMappedData = nullptr; // pointer to currently mapped data (NULL if unmapped)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ include(OpenGL)
|
|||
include(OpenSSL)
|
||||
include(PNG)
|
||||
include(TemplateCheck)
|
||||
include(TinyEXR)
|
||||
include(ThreeJS)
|
||||
include(Tracy)
|
||||
include(UI)
|
||||
|
|
@ -71,8 +72,12 @@ if (NOT HAVOK_TPV)
|
|||
endif()
|
||||
endif (NOT HAVOK_TPV)
|
||||
|
||||
|
||||
set(viewer_SOURCE_FILES
|
||||
gltfscenemanager.cpp
|
||||
gltf/asset.cpp
|
||||
gltf/accessor.cpp
|
||||
gltf/primitive.cpp
|
||||
gltf/animation.cpp
|
||||
groupchatlistener.cpp
|
||||
llaccountingcostmanager.cpp
|
||||
llaisapi.cpp
|
||||
|
|
@ -312,6 +317,7 @@ set(viewer_SOURCE_FILES
|
|||
llgiveinventory.cpp
|
||||
llglsandbox.cpp
|
||||
llgltfmateriallist.cpp
|
||||
llgltfmaterialpreviewmgr.cpp
|
||||
llgroupactions.cpp
|
||||
llgroupiconctrl.cpp
|
||||
llgrouplist.cpp
|
||||
|
|
@ -522,6 +528,7 @@ set(viewer_SOURCE_FILES
|
|||
llrecentpeople.cpp
|
||||
llreflectionmap.cpp
|
||||
llreflectionmapmanager.cpp
|
||||
llheroprobemanager.cpp
|
||||
llregioninfomodel.cpp
|
||||
llregionposition.cpp
|
||||
llremoteparcelrequest.cpp
|
||||
|
|
@ -726,7 +733,13 @@ set(VIEWER_BINARY_NAME "secondlife-bin" CACHE STRING
|
|||
set(viewer_HEADER_FILES
|
||||
CMakeLists.txt
|
||||
ViewerInstall.cmake
|
||||
gltfscenemanager.h
|
||||
groupchatlistener.h
|
||||
gltf/asset.h
|
||||
gltf/accessor.h
|
||||
gltf/buffer_util.h
|
||||
gltf/primitive.h
|
||||
gltf/animation.h
|
||||
llaccountingcost.h
|
||||
llaccountingcostmanager.h
|
||||
llaisapi.h
|
||||
|
|
@ -969,6 +982,7 @@ set(viewer_HEADER_FILES
|
|||
llgesturemgr.h
|
||||
llgiveinventory.h
|
||||
llgltfmateriallist.h
|
||||
llgltfmaterialpreviewmgr.h
|
||||
llgroupactions.h
|
||||
llgroupiconctrl.h
|
||||
llgrouplist.h
|
||||
|
|
@ -1165,6 +1179,7 @@ set(viewer_HEADER_FILES
|
|||
llrecentpeople.h
|
||||
llreflectionmap.h
|
||||
llreflectionmapmanager.h
|
||||
llheroprobemanager.h
|
||||
llregioninfomodel.h
|
||||
llregionposition.h
|
||||
llremoteparcelrequest.h
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
7.1.8
|
||||
7.1.9
|
||||
|
|
|
|||
|
|
@ -7042,7 +7042,7 @@
|
|||
<key>OctreeAlphaDistanceFactor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Multiplier on alpha object distance for determining octree node size </string>
|
||||
<string>Multiplier on alpha object distance for determining octree node size. First two parameters are currently unused. Third parameter is distance at which to perform detailed alpha sorting.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -7051,7 +7051,7 @@
|
|||
<array>
|
||||
<real>0.1</real>
|
||||
<real>0.0</real>
|
||||
<real>0.0</real>
|
||||
<real>64.0</real>
|
||||
</array>
|
||||
</map>
|
||||
|
||||
|
|
@ -7160,17 +7160,6 @@
|
|||
<key>Value</key>
|
||||
<real>32.0</real>
|
||||
</map>
|
||||
<key>RenderCloudShadowAmbianceFactor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Amount that cloud shadow (aka cloud coverage) contributes to reflection probe ambiance</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.1</real>
|
||||
</map>
|
||||
<key>RenderCPUBasis</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -7485,6 +7474,17 @@
|
|||
<real>0.00</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>RenderMirrors</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Renders realtime mirrors.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderScreenSpaceReflections</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -7595,6 +7595,17 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderDesaturateIrradiance</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Desaturate irradiance to remove blue tint</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderDebugAlphaMask</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -7661,6 +7672,50 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderHDRIExposure</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Exposure adjustment of HDRI when previewing an HDRI. Units are EV. Sane values would be -10 to 10.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.0</real>
|
||||
</map>
|
||||
<key>RenderHDRIRotation</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Rotation (in degrees) of environment when previewing an HDRI.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.0</real>
|
||||
</map>
|
||||
<key>RenderHDRISplitScreen</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>What percentage of screen to render using HDRI vs EEP sky.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>RenderHDRIIrradianceOnly</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Only use HDRI sky for irradiance map when RenderHDRISplitScreen is 0</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderMaxOpenGLVersion</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -7693,6 +7748,17 @@
|
|||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>16</integer>
|
||||
</map>
|
||||
<key>RenderMaxTextureResolution</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Maximum texture resolution to download for non-boosted textures.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>2048</integer>
|
||||
</map>
|
||||
<key>RenderDebugTextureBind</key>
|
||||
<map>
|
||||
|
|
@ -8689,6 +8755,50 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderHeroProbeResolution</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Resolution to render hero probes used for mirrors, water, etc.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>1024</integer>
|
||||
</map>
|
||||
<key>RenderHeroProbeDistance</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Distance in meters for hero probes to render out to.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>8</real>
|
||||
</map>
|
||||
<key>RenderHeroProbeUpdateRate</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>How many frames to wait for until it's time to render the probe. E.g., every other frame (1), every two frames (2), every three frames (3) etc.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>2</integer>
|
||||
</map>
|
||||
<key>RenderHeroProbeConservativeUpdateMultiplier</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>How many probe updates to wait until it's time to update faces that are not directly facing the camera. Acts as a multiplier. E.g., frames to the periphery of the camera updating once every 3 updates, vs ones directly facing the camera updating every update.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>16</integer>
|
||||
</map>
|
||||
<key>RenderReflectionProbeVolumes</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -8901,38 +9011,49 @@
|
|||
<integer>3</integer>
|
||||
</map>
|
||||
<key>RenderReflectionRes</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Reflection map resolution.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>64</integer>
|
||||
</map>
|
||||
<key>RenderResolutionDivisor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Divisor for rendering 3D scene at reduced resolution.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderShaderLightingMaxLevel</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Max lighting level to use in the shader (class 3 is default, 2 is less lights, 1 is sun/moon only. Works around shader compiler bugs on certain platforms.)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>3</integer>
|
||||
</map>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Reflection map resolution.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>64</integer>
|
||||
</map>
|
||||
<key>RenderReservedTextureIndices</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Count of texture indices to reserve for shadow and reflection maps when using indexed texture rendering. Probably only want to set from the login screen.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>14</integer>
|
||||
</map>
|
||||
<key>RenderResolutionDivisor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Divisor for rendering 3D scene at reduced resolution.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderShaderLightingMaxLevel</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Max lighting level to use in the shader (class 3 is default, 2 is less lights, 1 is sun/moon only. Works around shader compiler bugs on certain platforms.)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>3</integer>
|
||||
</map>
|
||||
<key>RenderSkyAutoAdjustLegacy</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -9054,6 +9175,17 @@
|
|||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.5</real>
|
||||
</map>
|
||||
<key>RenderDiffuseLuminanceScale</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Luminance adjustment for diffuse surfaces to aid auto-exposure behavior</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.5</real>
|
||||
</map>
|
||||
<key>RenderShaderLODThreshold</key>
|
||||
<map>
|
||||
|
|
@ -9113,7 +9245,7 @@
|
|||
<key>RenderTerrainScale</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Terrain detail texture scale</string>
|
||||
<string>Terrain detail texture scale (meters)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -9121,6 +9253,83 @@
|
|||
<key>Value</key>
|
||||
<real>12.0</real>
|
||||
</map>
|
||||
<key>RenderTerrainPBREnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>EXPERIMENTAL: Enable PBR Terrain features.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderTerrainPBRForce</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Force-load PBR terrain if enabled</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderTerrainPBRDetail</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Detail level for PBR terrain. 0 is full detail. Negative values drop rendering features, in accordance with the GLTF specification when possible, which reduces the number of texture binds.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderTerrainPBRScale</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>PBR terrain detail texture scale (meters)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>8.0</real>
|
||||
</map>
|
||||
<key>RenderTerrainPBRPlanarSampleCount</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>How many UV planes to sample PBR terrain textures from. 1 is "flat", 3 is triplanar mapping (aka box mapping)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<real>3</real>
|
||||
</map>
|
||||
<key>RenderTerrainPBRTriplanarBlendFactor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Higher values create sharper transitions, but are more likely to produce artifacts.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<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>
|
||||
|
|
@ -11778,6 +11987,17 @@
|
|||
<key>Value</key>
|
||||
<integer>2</integer>
|
||||
</map>
|
||||
<key>UIPreviewMaterial</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether or not PBR material swatch is enabled</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<real>0</real>
|
||||
</map>
|
||||
<key>UIResizeBarHeight</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -13593,7 +13813,7 @@
|
|||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>2048</integer>
|
||||
<integer>1024</integer>
|
||||
</map>
|
||||
<key>max_texture_dimension_Y</key>
|
||||
<map>
|
||||
|
|
@ -13604,7 +13824,7 @@
|
|||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>2048</integer>
|
||||
<integer>1024</integer>
|
||||
</map>
|
||||
<!-- End of back compatibility settings -->
|
||||
<key>teleport_offer_invitation_max_length</key>
|
||||
|
|
@ -14380,6 +14600,50 @@
|
|||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>LocalTerrainAsset1</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>00000000-0000-0000-0000-000000000000</string>
|
||||
</map>
|
||||
<key>LocalTerrainAsset2</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>00000000-0000-0000-0000-000000000000</string>
|
||||
</map>
|
||||
<key>LocalTerrainAsset3</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>00000000-0000-0000-0000-000000000000</string>
|
||||
</map>
|
||||
<key>LocalTerrainAsset4</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>00000000-0000-0000-0000-000000000000</string>
|
||||
</map>
|
||||
<key>PathfindingRetrieveNeighboringRegion</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
uniform mat3 normal_matrix;
|
||||
uniform mat4 texture_matrix0;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
uniform mat4 modelview_matrix;
|
||||
|
||||
in vec3 position;
|
||||
in vec3 normal;
|
||||
|
|
@ -35,10 +36,12 @@ in vec2 texcoord0;
|
|||
out vec3 vary_normal;
|
||||
out vec4 vertex_color;
|
||||
out vec2 vary_texcoord0;
|
||||
out vec3 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
out vec4 frag_data[3];
|
||||
out vec4 frag_data[4];
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
|
|
@ -33,11 +33,14 @@ uniform float minimum_alpha;
|
|||
|
||||
in vec3 vary_normal;
|
||||
in vec2 vary_texcoord0;
|
||||
in vec3 vary_position;
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
void mirrorClip(vec3 pos);
|
||||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
|
||||
vec4 diff = texture(diffuseMap, vary_texcoord0.xy);
|
||||
|
||||
if (diff.a < minimum_alpha)
|
||||
|
|
@ -48,6 +51,7 @@ void main()
|
|||
frag_data[0] = vec4(diff.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ in vec4 weight;
|
|||
|
||||
out vec3 vary_normal;
|
||||
out vec2 vary_texcoord0;
|
||||
out vec3 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
@ -57,6 +58,7 @@ void main()
|
|||
|
||||
vary_normal = norm;
|
||||
|
||||
vary_position = pos.xyz;
|
||||
gl_Position = projection_matrix * pos;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file blurLightF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, 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$
|
||||
*/
|
||||
|
|
@ -40,18 +40,18 @@ uniform float kern_scale;
|
|||
in vec2 vary_fragcoord;
|
||||
|
||||
vec4 getPosition(vec2 pos_screen);
|
||||
vec3 getNorm(vec2 pos_screen);
|
||||
vec4 getNorm(vec2 pos_screen);
|
||||
|
||||
void main()
|
||||
void main()
|
||||
{
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
vec3 norm = getNorm(tc);
|
||||
vec4 norm = getNorm(tc);
|
||||
vec3 pos = getPosition(tc).xyz;
|
||||
vec4 ccol = texture(lightMap, tc).rgba;
|
||||
|
||||
|
||||
vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
|
||||
dlt /= max(-pos.z*dist_factor, 1.0);
|
||||
|
||||
|
||||
vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
|
||||
vec4 col = defined_weight.xyxx * ccol;
|
||||
|
||||
|
|
@ -75,15 +75,15 @@ void main()
|
|||
k[1] = (k[0]+k[2])*0.5f;
|
||||
k[3] = (k[2]+k[4])*0.5f;
|
||||
k[5] = (k[4]+k[6])*0.5f;
|
||||
|
||||
|
||||
for (int i = 1; i < 7; i++)
|
||||
{
|
||||
vec2 samptc = tc + k[i].z*dlt*2.0;
|
||||
samptc /= screen_res;
|
||||
vec3 samppos = getPosition(samptc).xyz;
|
||||
vec3 samppos = getPosition(samptc).xyz;
|
||||
|
||||
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
|
||||
|
||||
|
||||
if (d*d <= pointplanedist_tolerance_pow2)
|
||||
{
|
||||
col += texture(lightMap, samptc)*k[i].xyxx;
|
||||
|
|
@ -95,10 +95,10 @@ void main()
|
|||
{
|
||||
vec2 samptc = tc - k[i].z*dlt*2.0;
|
||||
samptc /= screen_res;
|
||||
vec3 samppos = getPosition(samptc).xyz;
|
||||
vec3 samppos = getPosition(samptc).xyz;
|
||||
|
||||
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
|
||||
|
||||
|
||||
if (d*d <= pointplanedist_tolerance_pow2)
|
||||
{
|
||||
col += texture(lightMap, samptc)*k[i].xyxx;
|
||||
|
|
@ -108,7 +108,7 @@ void main()
|
|||
|
||||
col /= defined_weight.xyxx;
|
||||
//col.y *= col.y;
|
||||
|
||||
|
||||
frag_color = max(col, vec4(0));
|
||||
|
||||
#ifdef IS_AMD_CARD
|
||||
|
|
|
|||
|
|
@ -37,11 +37,13 @@ in vec3 vary_mat2;
|
|||
|
||||
in vec4 vertex_color;
|
||||
in vec2 vary_texcoord0;
|
||||
in vec3 vary_position;
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
|
||||
void mirrorClip(vec3 pos);
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
|
||||
vec4 col = texture(diffuseMap, vary_texcoord0.xy);
|
||||
|
||||
if(col.a < minimum_alpha)
|
||||
|
|
@ -60,6 +62,6 @@ void main()
|
|||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(tnorm);
|
||||
frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(0);
|
||||
frag_data[2] = vec4(nvn, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(vertex_color.a, 0, 0, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat3 normal_matrix;
|
||||
uniform mat4 texture_matrix0;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
|
@ -38,11 +39,11 @@ out vec3 vary_mat1;
|
|||
out vec3 vary_mat2;
|
||||
out vec4 vertex_color;
|
||||
out vec2 vary_texcoord0;
|
||||
out vec3 vary_position;
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
mat4 getObjectSkinnedTransform();
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat4 modelview_matrix;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
|
|
@ -52,11 +53,13 @@ void main()
|
|||
mat4 mat = getObjectSkinnedTransform();
|
||||
mat = modelview_matrix * mat;
|
||||
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
|
||||
vary_position = pos;
|
||||
gl_Position = projection_matrix*vec4(pos, 1.0);
|
||||
|
||||
vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
|
||||
vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz);
|
||||
#else
|
||||
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
vec3 n = normalize(normal_matrix * normal);
|
||||
vec3 t = normalize(normal_matrix * tangent.xyz);
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ SOFTWARE.
|
|||
|
||||
uniform sampler2D normalMap;
|
||||
uniform sampler2D depthMap;
|
||||
uniform sampler2D emissiveRect;
|
||||
uniform sampler2D projectionMap; // rgba
|
||||
uniform sampler2D brdfLut;
|
||||
|
||||
|
|
@ -140,40 +141,11 @@ vec2 getScreenCoordinate(vec2 screenpos)
|
|||
return sc - vec2(1.0, 1.0);
|
||||
}
|
||||
|
||||
// See: https://aras-p.info/texts/CompactNormalStorage.html
|
||||
// Method #4: Spheremap Transform, Lambert Azimuthal Equal-Area projection
|
||||
vec3 getNorm(vec2 screenpos)
|
||||
vec4 getNorm(vec2 screenpos)
|
||||
{
|
||||
vec2 enc = texture(normalMap, screenpos.xy).xy;
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec3 getNormalFromPacked(vec4 packedNormalEnvIntensityFlags)
|
||||
{
|
||||
vec2 enc = packedNormalEnvIntensityFlags.xy;
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return normalize(n); // TODO: Is this normalize redundant?
|
||||
}
|
||||
|
||||
// return packedNormalEnvIntensityFlags since GBUFFER_FLAG_HAS_PBR needs .w
|
||||
// See: C++: addDeferredAttachments(), GLSL: softenLightF
|
||||
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity)
|
||||
{
|
||||
vec4 packedNormalEnvIntensityFlags = texture(normalMap, screenpos.xy);
|
||||
n = getNormalFromPacked( packedNormalEnvIntensityFlags );
|
||||
envIntensity = packedNormalEnvIntensityFlags.z;
|
||||
return packedNormalEnvIntensityFlags;
|
||||
vec4 norm = texture(normalMap, screenpos.xy);
|
||||
norm.xyz = normalize(norm.xyz);
|
||||
return norm;
|
||||
}
|
||||
|
||||
// get linear depth value given a depth buffer sample d and znear and zfar values
|
||||
|
|
|
|||
|
|
@ -31,14 +31,18 @@ uniform float minimum_alpha;
|
|||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
in vec3 vary_position;
|
||||
|
||||
in vec3 vary_normal;
|
||||
in vec4 vertex_color;
|
||||
in vec2 vary_texcoord0;
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
void mirrorClip(vec3 pos);
|
||||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
|
||||
vec4 col = texture(diffuseMap, vary_texcoord0.xy) * vertex_color;
|
||||
|
||||
if (col.a < minimum_alpha)
|
||||
|
|
@ -49,7 +53,7 @@ void main()
|
|||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,16 +28,19 @@
|
|||
out vec4 frag_data[4];
|
||||
|
||||
in vec3 vary_normal;
|
||||
in vec3 vary_position;
|
||||
|
||||
uniform float minimum_alpha;
|
||||
|
||||
in vec4 vertex_color;
|
||||
in vec2 vary_texcoord0;
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
void mirrorClip(vec3 pos);
|
||||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
|
||||
vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color;
|
||||
|
||||
if (col.a < minimum_alpha)
|
||||
|
|
@ -48,6 +51,6 @@ void main()
|
|||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@ uniform sampler2D diffuseMap;
|
|||
in vec3 vary_normal;
|
||||
in vec2 vary_texcoord0;
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = texture(diffuseMap, vary_texcoord0.xy);
|
||||
|
|
@ -48,7 +46,7 @@ void main()
|
|||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,17 +32,19 @@ uniform sampler2D diffuseMap;
|
|||
in vec3 vary_normal;
|
||||
in vec4 vertex_color;
|
||||
in vec2 vary_texcoord0;
|
||||
in vec3 vary_position;
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
void mirrorClip(vec3 pos);
|
||||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
vec3 col = vertex_color.rgb * texture(diffuseMap, vary_texcoord0.xy).rgb;
|
||||
frag_data[0] = vec4(col, 0.0);
|
||||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(0);
|
||||
frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(vertex_color.a, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,12 +30,14 @@ out vec4 frag_data[4];
|
|||
in vec3 vary_normal;
|
||||
in vec4 vertex_color;
|
||||
in vec2 vary_texcoord0;
|
||||
in vec3 vary_position;
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
void mirrorClip(vec3 pos);
|
||||
vec3 linear_to_srgb(vec3 c);
|
||||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
|
||||
|
||||
vec3 spec;
|
||||
|
|
@ -44,6 +46,6 @@ void main()
|
|||
frag_data[0] = vec4(col, 0.0);
|
||||
frag_data[1] = vec4(spec, vertex_color.a); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(0);
|
||||
frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(vertex_color.a, 0, 0, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,13 +36,16 @@ out vec3 vary_normal;
|
|||
|
||||
out vec4 vertex_color;
|
||||
out vec2 vary_texcoord0;
|
||||
out vec3 vary_position;
|
||||
|
||||
void passTextureIndex();
|
||||
|
||||
uniform mat4 modelview_matrix;
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
mat4 getObjectSkinnedTransform();
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat4 modelview_matrix;
|
||||
|
||||
#endif
|
||||
|
||||
void main()
|
||||
|
|
@ -51,9 +54,11 @@ void main()
|
|||
mat4 mat = getObjectSkinnedTransform();
|
||||
mat = modelview_matrix * mat;
|
||||
vec4 pos = mat * vec4(position.xyz, 1.0);
|
||||
vary_position = pos.xyz;
|
||||
gl_Position = projection_matrix * pos;
|
||||
vary_normal = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
|
||||
#else
|
||||
vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
vary_normal = normalize(normal_matrix * normal);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,34 +1,36 @@
|
|||
/**
|
||||
/**
|
||||
* @file exposureF.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$
|
||||
*/
|
||||
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
uniform sampler2D emissiveRect;
|
||||
#ifdef USE_LAST_EXPOSURE
|
||||
uniform sampler2D exposureMap;
|
||||
#endif
|
||||
|
||||
uniform float dt;
|
||||
uniform vec2 noiseVec;
|
||||
|
|
@ -41,7 +43,7 @@ float lum(vec3 col)
|
|||
return dot(l, col);
|
||||
}
|
||||
|
||||
void main()
|
||||
void main()
|
||||
{
|
||||
vec2 tc = vec2(0.5,0.5);
|
||||
|
||||
|
|
@ -51,11 +53,13 @@ void main()
|
|||
L /= max_L;
|
||||
L = pow(L, 2.0);
|
||||
float s = mix(dynamic_exposure_params.z, dynamic_exposure_params.y, L);
|
||||
|
||||
|
||||
#ifdef USE_LAST_EXPOSURE
|
||||
float prev = texture(exposureMap, vec2(0.5,0.5)).r;
|
||||
|
||||
s = mix(prev, s, min(dt*2.0*abs(prev-s), 0.04));
|
||||
|
||||
#endif
|
||||
|
||||
frag_color = max(vec4(s, s, s, dt), vec4(0.0));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
/**
|
||||
/**
|
||||
* @file deferred/fullbrightF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, 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$
|
||||
*/
|
||||
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
out vec4 frag_color;
|
||||
|
|
@ -50,9 +50,11 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
|
|||
vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
void mirrorClip(vec3 pos);
|
||||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
#ifdef IS_ALPHA
|
||||
waterClip(vary_position.xyz);
|
||||
#endif
|
||||
|
|
@ -88,7 +90,7 @@ void main()
|
|||
calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten);
|
||||
|
||||
color.rgb = applySkyAndWaterFog(pos, additive, atten, color).rgb;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* @file class1/deferred/globalF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2024&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2024, 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$
|
||||
*/
|
||||
|
||||
|
||||
// Global helper functions included in every fragment shader
|
||||
// DO NOT declare sampler uniforms here as OS X doesn't compile
|
||||
// them out
|
||||
|
||||
uniform float mirror_flag;
|
||||
uniform vec4 clipPlane;
|
||||
uniform float clipSign;
|
||||
|
||||
void mirrorClip(vec3 pos)
|
||||
{
|
||||
if (mirror_flag > 0)
|
||||
{
|
||||
if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) < 0.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -37,7 +37,6 @@ uniform sampler2D specularMap;
|
|||
in vec2 vary_texcoord0;
|
||||
|
||||
vec3 linear_to_srgb(vec3 c);
|
||||
vec2 encode_normal (vec3 n);
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
@ -53,6 +52,6 @@ void main()
|
|||
|
||||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = spec;
|
||||
frag_data[2] = vec4(encode_normal(norm.xyz),0,GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[2] = vec4(norm.xyz, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,32 @@
|
|||
/**
|
||||
/**
|
||||
* @file luminanceF.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$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
// take a luminance sample of diffuseRect and emissiveRect
|
||||
// take a luminance sample of diffuseRect and emissiveRect
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
|
|
@ -34,6 +34,8 @@ in vec2 vary_fragcoord;
|
|||
|
||||
uniform sampler2D diffuseRect;
|
||||
uniform sampler2D emissiveRect;
|
||||
uniform sampler2D normalMap;
|
||||
uniform float diffuse_luminance_scale;
|
||||
|
||||
float lum(vec3 col)
|
||||
{
|
||||
|
|
@ -41,11 +43,25 @@ float lum(vec3 col)
|
|||
return dot(l, col);
|
||||
}
|
||||
|
||||
void main()
|
||||
void main()
|
||||
{
|
||||
vec2 tc = vary_fragcoord*0.6+0.2;
|
||||
tc.y -= 0.1; // HACK - nudge exposure sample down a little bit to favor ground over sky
|
||||
vec3 c = texture(diffuseRect, tc).rgb + texture(emissiveRect, tc).rgb;
|
||||
vec3 c = texture(diffuseRect, tc).rgb;
|
||||
|
||||
vec4 norm = texture(normalMap, tc);
|
||||
|
||||
if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_HDRI) &&
|
||||
!GET_GBUFFER_FLAG(GBUFFER_FLAG_SKIP_ATMOS))
|
||||
{
|
||||
// Apply the diffuse luminance scale to objects but not the sky
|
||||
// Prevents underexposing when looking at bright environments
|
||||
// while still allowing for realistically bright skies.
|
||||
c *= diffuse_luminance_scale;
|
||||
}
|
||||
|
||||
c += texture(emissiveRect, tc).rgb;
|
||||
|
||||
float L = lum(c);
|
||||
frag_color = vec4(max(L, 0.0));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,25 +28,18 @@
|
|||
#define DIFFUSE_ALPHA_MODE_MASK 2
|
||||
#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
mat4 getObjectSkinnedTransform();
|
||||
#else
|
||||
uniform mat3 normal_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
#endif
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
|
||||
#if !defined(HAS_SKIN)
|
||||
uniform mat4 modelview_matrix;
|
||||
#endif
|
||||
|
||||
out vec3 vary_position;
|
||||
|
||||
#endif
|
||||
|
||||
uniform mat4 texture_matrix0;
|
||||
|
||||
in vec3 position;
|
||||
|
|
@ -85,9 +78,7 @@ void main()
|
|||
|
||||
vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
vary_position = pos;
|
||||
#endif
|
||||
|
||||
gl_Position = projection_matrix*vec4(pos,1.0);
|
||||
|
||||
|
|
@ -133,10 +124,8 @@ void main()
|
|||
|
||||
vertex_color = diffuse_color;
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
#if !defined(HAS_SKIN)
|
||||
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
/**
|
||||
/**
|
||||
* @file class1\deferred\moonF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2005, 2020 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$
|
||||
*/
|
||||
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
out vec4 frag_data[4];
|
||||
|
|
@ -34,7 +34,7 @@ uniform sampler2D diffuseMap;
|
|||
|
||||
in vec2 vary_texcoord0;
|
||||
|
||||
void main()
|
||||
void main()
|
||||
{
|
||||
// Restore Pre-EEP alpha fade moon near horizon
|
||||
float fade = 1.0;
|
||||
|
|
@ -55,7 +55,7 @@ void main()
|
|||
|
||||
frag_data[0] = vec4(0);
|
||||
frag_data[1] = vec4(0.0);
|
||||
frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
|
||||
frag_data[3] = vec4(c.rgb, c.a);
|
||||
|
||||
// Added and commented out for a ground truth. Do not uncomment - Geenz
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file pbrShadowAlphaMaskF.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$
|
||||
*/
|
||||
|
|
@ -33,9 +33,9 @@ in vec4 vertex_color;
|
|||
in vec2 vary_texcoord0;
|
||||
uniform float minimum_alpha;
|
||||
|
||||
void main()
|
||||
void main()
|
||||
{
|
||||
float alpha = texture(diffuseMap,vary_texcoord0.xy).a;
|
||||
float alpha = texture(diffuseMap,vary_texcoord0.xy).a * vertex_color.a;
|
||||
|
||||
if (alpha < minimum_alpha)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file pbropaqueF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, 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$
|
||||
*/
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#ifndef IS_HUD
|
||||
|
||||
// deferred opaque implementation
|
||||
// deferred opaque implementation
|
||||
|
||||
uniform sampler2D diffuseMap; //always in sRGB space
|
||||
|
||||
|
|
@ -54,28 +54,38 @@ in vec2 emissive_texcoord;
|
|||
|
||||
uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
vec3 linear_to_srgb(vec3 c);
|
||||
vec3 srgb_to_linear(vec3 c);
|
||||
|
||||
uniform vec4 clipPlane;
|
||||
uniform float clipSign;
|
||||
|
||||
void mirrorClip(vec3 pos);
|
||||
|
||||
uniform mat3 normal_matrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
|
||||
vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba;
|
||||
basecolor.rgb = srgb_to_linear(basecolor.rgb);
|
||||
|
||||
basecolor *= vertex_color;
|
||||
|
||||
if (basecolor.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
vec3 col = vertex_color.rgb * srgb_to_linear(basecolor.rgb);
|
||||
vec3 col = basecolor.rgb;
|
||||
|
||||
// from mikktspace.com
|
||||
vec3 vNt = texture(bumpMap, normal_texcoord.xy).xyz*2.0-1.0;
|
||||
float sign = vary_sign;
|
||||
vec3 vN = vary_normal;
|
||||
vec3 vT = vary_tangent.xyz;
|
||||
|
||||
|
||||
vec3 vB = sign * cross(vN, vT);
|
||||
vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
|
||||
|
||||
|
|
@ -85,7 +95,7 @@ void main()
|
|||
// roughness 0.0
|
||||
// metal 0.0
|
||||
vec3 spec = texture(specularMap, metallic_roughness_texcoord.xy).rgb;
|
||||
|
||||
|
||||
spec.g *= roughnessFactor;
|
||||
spec.b *= metallicFactor;
|
||||
|
||||
|
|
@ -102,8 +112,8 @@ void main()
|
|||
//emissive = tnorm*0.5+0.5;
|
||||
// See: C++: addDeferredAttachments(), GLSL: softenLightF
|
||||
frag_data[0] = max(vec4(col, 0.0), vec4(0)); // Diffuse
|
||||
frag_data[1] = max(vec4(spec.rgb,vertex_color.a), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal.
|
||||
frag_data[2] = max(vec4(encode_normal(tnorm), vertex_color.a, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags
|
||||
frag_data[1] = max(vec4(spec.rgb,0.0), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal.
|
||||
frag_data[2] = vec4(tnorm, GBUFFER_FLAG_HAS_PBR); // normal, environment intensity, flags
|
||||
frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,9 @@
|
|||
|
||||
//deferred opaque implementation
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
uniform mat4 modelview_matrix;
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
uniform mat4 projection_matrix;
|
||||
mat4 getObjectSkinnedTransform();
|
||||
#else
|
||||
|
|
@ -59,6 +60,7 @@ out vec4 vertex_color;
|
|||
out vec3 vary_tangent;
|
||||
flat out float vary_sign;
|
||||
out vec3 vary_normal;
|
||||
out vec3 vary_position;
|
||||
|
||||
vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
|
||||
vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
|
||||
|
|
@ -71,10 +73,11 @@ void main()
|
|||
mat = modelview_matrix * mat;
|
||||
|
||||
vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
|
||||
|
||||
vary_position = pos;
|
||||
gl_Position = projection_matrix*vec4(pos,1.0);
|
||||
|
||||
#else
|
||||
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
|
||||
//transform vertex
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,347 @@
|
|||
/**
|
||||
* @file class1\deferred\terrainF.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$
|
||||
*/
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
#define TERRAIN_PBR_DETAIL_EMISSIVE 0
|
||||
#define TERRAIN_PBR_DETAIL_OCCLUSION -1
|
||||
#define TERRAIN_PBR_DETAIL_NORMAL -2
|
||||
#define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3
|
||||
|
||||
#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
|
||||
#define TerrainCoord vec4[2]
|
||||
#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1
|
||||
#define TerrainCoord vec2
|
||||
#endif
|
||||
|
||||
#define MIX_X 1 << 3
|
||||
#define MIX_Y 1 << 4
|
||||
#define MIX_Z 1 << 5
|
||||
#define MIX_W 1 << 6
|
||||
|
||||
struct TerrainMix
|
||||
{
|
||||
vec4 weight;
|
||||
int type;
|
||||
};
|
||||
|
||||
TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal);
|
||||
|
||||
struct PBRMix
|
||||
{
|
||||
vec4 col; // RGB color with alpha, linear space
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
vec3 orm; // Occlusion, roughness, metallic
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
vec2 rm; // Roughness, metallic
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
vec3 vNt; // Unpacked normal texture sample, vector
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
vec3 emissive; // RGB emissive color, linear space
|
||||
#endif
|
||||
};
|
||||
|
||||
PBRMix init_pbr_mix();
|
||||
|
||||
PBRMix terrain_sample_and_multiply_pbr(
|
||||
TerrainCoord terrain_coord
|
||||
, sampler2D tex_col
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, sampler2D tex_orm
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
, sampler2D tex_vNt
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, sampler2D tex_emissive
|
||||
#endif
|
||||
, vec4 factor_col
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
, vec3 factor_orm
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, vec2 factor_rm
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, vec3 factor_emissive
|
||||
#endif
|
||||
);
|
||||
|
||||
PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight);
|
||||
|
||||
out vec4 frag_data[4];
|
||||
|
||||
uniform sampler2D alpha_ramp;
|
||||
|
||||
// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures
|
||||
uniform sampler2D detail_0_base_color;
|
||||
uniform sampler2D detail_1_base_color;
|
||||
uniform sampler2D detail_2_base_color;
|
||||
uniform sampler2D detail_3_base_color;
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
uniform sampler2D detail_0_normal;
|
||||
uniform sampler2D detail_1_normal;
|
||||
uniform sampler2D detail_2_normal;
|
||||
uniform sampler2D detail_3_normal;
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
uniform sampler2D detail_0_metallic_roughness;
|
||||
uniform sampler2D detail_1_metallic_roughness;
|
||||
uniform sampler2D detail_2_metallic_roughness;
|
||||
uniform sampler2D detail_3_metallic_roughness;
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
uniform sampler2D detail_0_emissive;
|
||||
uniform sampler2D detail_1_emissive;
|
||||
uniform sampler2D detail_2_emissive;
|
||||
uniform sampler2D detail_3_emissive;
|
||||
#endif
|
||||
|
||||
uniform vec4[4] baseColorFactors; // See also vertex_color in pbropaqueV.glsl
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
uniform vec4 metallicFactors;
|
||||
uniform vec4 roughnessFactors;
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
uniform vec3[4] emissiveColors;
|
||||
#endif
|
||||
uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
|
||||
|
||||
#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
|
||||
in vec4[2] vary_coords;
|
||||
#endif
|
||||
in vec3 vary_position;
|
||||
in vec3 vary_normal;
|
||||
in vec3 vary_tangent;
|
||||
flat in float vary_sign;
|
||||
in vec4 vary_texcoord0;
|
||||
in vec4 vary_texcoord1;
|
||||
|
||||
void mirrorClip(vec3 position);
|
||||
|
||||
float terrain_mix(TerrainMix tm, vec4 tms4);
|
||||
|
||||
void main()
|
||||
{
|
||||
// Make sure we clip the terrain if we're in a mirror.
|
||||
mirrorClip(vary_position);
|
||||
|
||||
#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
|
||||
TerrainCoord terrain_texcoord = vary_coords;
|
||||
#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1
|
||||
TerrainCoord terrain_texcoord = vary_texcoord0.xy;
|
||||
#endif
|
||||
|
||||
float alpha1 = texture(alpha_ramp, vary_texcoord0.zw).a;
|
||||
float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a;
|
||||
float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a;
|
||||
|
||||
TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal);
|
||||
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
// RGB = Occlusion, Roughness, Metal
|
||||
// default values, see LLViewerTexture::sDefaultPBRORMImagep
|
||||
// occlusion 1.0
|
||||
// roughness 0.0
|
||||
// metal 0.0
|
||||
vec3[4] orm_factors;
|
||||
orm_factors[0] = vec3(1.0, roughnessFactors.x, metallicFactors.x);
|
||||
orm_factors[1] = vec3(1.0, roughnessFactors.y, metallicFactors.y);
|
||||
orm_factors[2] = vec3(1.0, roughnessFactors.z, metallicFactors.z);
|
||||
orm_factors[3] = vec3(1.0, roughnessFactors.w, metallicFactors.w);
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
vec2[4] rm_factors;
|
||||
rm_factors[0] = vec2(roughnessFactors.x, metallicFactors.x);
|
||||
rm_factors[1] = vec2(roughnessFactors.y, metallicFactors.y);
|
||||
rm_factors[2] = vec2(roughnessFactors.z, metallicFactors.z);
|
||||
rm_factors[3] = vec2(roughnessFactors.w, metallicFactors.w);
|
||||
#endif
|
||||
|
||||
PBRMix pbr_mix = init_pbr_mix();
|
||||
PBRMix mix2;
|
||||
switch (tm.type & MIX_X)
|
||||
{
|
||||
case MIX_X:
|
||||
mix2 = terrain_sample_and_multiply_pbr(
|
||||
terrain_texcoord
|
||||
, detail_0_base_color
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, detail_0_metallic_roughness
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
, detail_0_normal
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, detail_0_emissive
|
||||
#endif
|
||||
, baseColorFactors[0]
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
, orm_factors[0]
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, rm_factors[0]
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, emissiveColors[0]
|
||||
#endif
|
||||
);
|
||||
pbr_mix = mix_pbr(pbr_mix, mix2, tm.weight.x);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (tm.type & MIX_Y)
|
||||
{
|
||||
case MIX_Y:
|
||||
mix2 = terrain_sample_and_multiply_pbr(
|
||||
terrain_texcoord
|
||||
, detail_1_base_color
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, detail_1_metallic_roughness
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
, detail_1_normal
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, detail_1_emissive
|
||||
#endif
|
||||
, baseColorFactors[1]
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
, orm_factors[1]
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, rm_factors[1]
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, emissiveColors[1]
|
||||
#endif
|
||||
);
|
||||
pbr_mix = mix_pbr(pbr_mix, mix2, tm.weight.y);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (tm.type & MIX_Z)
|
||||
{
|
||||
case MIX_Z:
|
||||
mix2 = terrain_sample_and_multiply_pbr(
|
||||
terrain_texcoord
|
||||
, detail_2_base_color
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, detail_2_metallic_roughness
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
, detail_2_normal
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, detail_2_emissive
|
||||
#endif
|
||||
, baseColorFactors[2]
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
, orm_factors[2]
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, rm_factors[2]
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, emissiveColors[2]
|
||||
#endif
|
||||
);
|
||||
pbr_mix = mix_pbr(pbr_mix, mix2, tm.weight.z);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (tm.type & MIX_W)
|
||||
{
|
||||
case MIX_W:
|
||||
mix2 = terrain_sample_and_multiply_pbr(
|
||||
terrain_texcoord
|
||||
, detail_3_base_color
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, detail_3_metallic_roughness
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
, detail_3_normal
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, detail_3_emissive
|
||||
#endif
|
||||
, baseColorFactors[3]
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
, orm_factors[3]
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, rm_factors[3]
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, emissiveColors[3]
|
||||
#endif
|
||||
);
|
||||
pbr_mix = mix_pbr(pbr_mix, mix2, tm.weight.w);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
float minimum_alpha = terrain_mix(tm, minimum_alphas);
|
||||
if (pbr_mix.col.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
float base_color_factor_alpha = terrain_mix(tm, vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z));
|
||||
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
// from mikktspace.com
|
||||
vec3 vNt = pbr_mix.vNt;
|
||||
vec3 vN = vary_normal;
|
||||
vec3 vT = vary_tangent.xyz;
|
||||
|
||||
vec3 vB = vary_sign * cross(vN, vT);
|
||||
vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
|
||||
|
||||
tnorm *= gl_FrontFacing ? 1.0 : -1.0;
|
||||
#else
|
||||
vec3 tnorm = vary_normal;
|
||||
tnorm *= gl_FrontFacing ? 1.0 : -1.0;
|
||||
#endif
|
||||
|
||||
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
#define mix_emissive pbr_mix.emissive
|
||||
#else
|
||||
#define mix_emissive vec3(0)
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
#define mix_orm pbr_mix.orm
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
#define mix_orm vec3(1.0, pbr_mix.rm)
|
||||
#else
|
||||
// Matte plastic potato terrain
|
||||
#define mix_orm vec3(1.0, 1.0, 0.0)
|
||||
#endif
|
||||
frag_data[0] = max(vec4(pbr_mix.col.xyz, 0.0), vec4(0)); // Diffuse
|
||||
frag_data[1] = max(vec4(mix_orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal.
|
||||
frag_data[2] = vec4(tnorm, GBUFFER_FLAG_HAS_PBR); // normal, flags
|
||||
frag_data[3] = max(vec4(mix_emissive,0), vec4(0)); // PBR sRGB Emissive
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,473 @@
|
|||
/**
|
||||
* @file class1\deferred\pbrterrainUtilF.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$
|
||||
*/
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
/**
|
||||
* Triplanar mapping implementation adapted from Inigo Quilez' example shader,
|
||||
* MIT license.
|
||||
* https://www.shadertoy.com/view/MtsGWH
|
||||
* Copyright © 2015 Inigo Quilez
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions: The above copyright
|
||||
* notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS",
|
||||
* WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define TERRAIN_PBR_DETAIL_EMISSIVE 0
|
||||
#define TERRAIN_PBR_DETAIL_OCCLUSION -1
|
||||
#define TERRAIN_PBR_DETAIL_NORMAL -2
|
||||
#define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3
|
||||
|
||||
in vec3 vary_vertex_normal;
|
||||
|
||||
vec3 srgb_to_linear(vec3 c);
|
||||
|
||||
// A relatively agressive threshold for terrain material mixing sampling
|
||||
// cutoff. This ensures that only one or two materials are used in most places,
|
||||
// making PBR terrain blending more performant. Should be greater than 0 to work.
|
||||
#define TERRAIN_RAMP_MIX_THRESHOLD 0.1
|
||||
// A small threshold for triplanar mapping sampling cutoff. This and
|
||||
// TERRAIN_TRIPLANAR_BLEND_FACTOR together ensures that only one or two samples
|
||||
// per texture are used in most places, making triplanar mapping more
|
||||
// performant. Should be greater than 0 to work.
|
||||
// There's also an artistic design choice in the use of these factors, and the
|
||||
// use of triplanar generally. Don't take these triplanar constants for granted.
|
||||
#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01
|
||||
|
||||
#define SAMPLE_X 1 << 0
|
||||
#define SAMPLE_Y 1 << 1
|
||||
#define SAMPLE_Z 1 << 2
|
||||
#define MIX_X 1 << 3
|
||||
#define MIX_Y 1 << 4
|
||||
#define MIX_Z 1 << 5
|
||||
#define MIX_W 1 << 6
|
||||
|
||||
struct PBRMix
|
||||
{
|
||||
vec4 col; // RGB color with alpha, linear space
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
vec3 orm; // Occlusion, roughness, metallic
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
vec2 rm; // Roughness, metallic
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
vec3 vNt; // Unpacked normal texture sample, vector
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
vec3 emissive; // RGB emissive color, linear space
|
||||
#endif
|
||||
};
|
||||
|
||||
PBRMix init_pbr_mix()
|
||||
{
|
||||
PBRMix mix;
|
||||
mix.col = vec4(0);
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
mix.orm = vec3(0);
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
mix.rm = vec2(0);
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
mix.vNt = vec3(0);
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
mix.emissive = vec3(0);
|
||||
#endif
|
||||
return mix;
|
||||
}
|
||||
|
||||
// Usage example, for two weights:
|
||||
// vec2 weights = ... // Weights must add up to 1
|
||||
// PBRMix mix = init_pbr_mix();
|
||||
// PBRMix mix1 = ...
|
||||
// mix = mix_pbr(mix, mix1, weights.x);
|
||||
// PBRMix mix2 = ...
|
||||
// mix = mix_pbr(mix, mix2, weights.y);
|
||||
PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight)
|
||||
{
|
||||
PBRMix mix;
|
||||
mix.col = mix1.col + (mix2.col * mix2_weight);
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
mix.orm = mix1.orm + (mix2.orm * mix2_weight);
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
mix.rm = mix1.rm + (mix2.rm * mix2_weight);
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
mix.vNt = mix1.vNt + (mix2.vNt * mix2_weight);
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
mix.emissive = mix1.emissive + (mix2.emissive * mix2_weight);
|
||||
#endif
|
||||
return mix;
|
||||
}
|
||||
|
||||
PBRMix sample_pbr(
|
||||
vec2 uv
|
||||
, sampler2D tex_col
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, sampler2D tex_orm
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
, sampler2D tex_vNt
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, sampler2D tex_emissive
|
||||
#endif
|
||||
)
|
||||
{
|
||||
PBRMix mix;
|
||||
mix.col = texture(tex_col, uv);
|
||||
mix.col.rgb = srgb_to_linear(mix.col.rgb);
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
mix.orm = texture(tex_orm, uv).xyz;
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
mix.rm = texture(tex_orm, uv).yz;
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
mix.vNt = texture(tex_vNt, uv).xyz*2.0-1.0;
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
mix.emissive = srgb_to_linear(texture(tex_emissive, uv).xyz);
|
||||
#endif
|
||||
return mix;
|
||||
}
|
||||
|
||||
struct TerrainTriplanar
|
||||
{
|
||||
vec3 weight;
|
||||
int type;
|
||||
};
|
||||
|
||||
struct TerrainMix
|
||||
{
|
||||
vec4 weight;
|
||||
int type;
|
||||
};
|
||||
|
||||
#define TerrainMixSample vec4[4]
|
||||
#define TerrainMixSample3 vec3[4]
|
||||
|
||||
TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal)
|
||||
{
|
||||
TerrainMix tm;
|
||||
vec4 sample_x = vec4(1,0,0,0);
|
||||
vec4 sample_y = vec4(0,1,0,0);
|
||||
vec4 sample_z = vec4(0,0,1,0);
|
||||
vec4 sample_w = vec4(0,0,0,1);
|
||||
|
||||
tm.weight = mix( mix(sample_w, sample_z, alpha2), mix(sample_y, sample_x, alpha1), alphaFinal );
|
||||
tm.weight -= TERRAIN_RAMP_MIX_THRESHOLD;
|
||||
ivec4 usage = max(ivec4(0), ivec4(ceil(tm.weight)));
|
||||
// Prevent negative weights and keep weights balanced
|
||||
tm.weight = tm.weight*vec4(usage);
|
||||
tm.weight /= (tm.weight.x + tm.weight.y + tm.weight.z + tm.weight.w);
|
||||
|
||||
tm.type = (usage.x * MIX_X) |
|
||||
(usage.y * MIX_Y) |
|
||||
(usage.z * MIX_Z) |
|
||||
(usage.w * MIX_W);
|
||||
return tm;
|
||||
}
|
||||
|
||||
TerrainTriplanar _t_triplanar()
|
||||
{
|
||||
float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR;
|
||||
float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD;
|
||||
vec3 weight_signed = pow(abs(vary_vertex_normal), vec3(sharpness));
|
||||
weight_signed /= (weight_signed.x + weight_signed.y + weight_signed.z);
|
||||
weight_signed -= vec3(threshold);
|
||||
TerrainTriplanar tw;
|
||||
// *NOTE: Make sure the threshold doesn't affect the materials
|
||||
tw.weight = max(vec3(0), weight_signed);
|
||||
tw.weight /= (tw.weight.x + tw.weight.y + tw.weight.z);
|
||||
ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed))));
|
||||
tw.type = ((usage.x) * SAMPLE_X) |
|
||||
((usage.y) * SAMPLE_Y) |
|
||||
((usage.z) * SAMPLE_Z);
|
||||
return tw;
|
||||
}
|
||||
|
||||
// Assume weights add to 1
|
||||
float terrain_mix(TerrainMix tm, vec4 tms4)
|
||||
{
|
||||
return (tm.weight.x * tms4[0]) +
|
||||
(tm.weight.y * tms4[1]) +
|
||||
(tm.weight.z * tms4[2]) +
|
||||
(tm.weight.w * tms4[3]);
|
||||
}
|
||||
|
||||
#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
|
||||
// Triplanar mapping
|
||||
|
||||
// Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused)
|
||||
#define TerrainCoord vec4[2]
|
||||
|
||||
vec2 _t_uv(vec2 uv_unflipped, float sign_or_zero)
|
||||
{
|
||||
// Handle case where sign is 0
|
||||
float sign = (2.0*sign_or_zero) + 1.0;
|
||||
sign /= abs(sign);
|
||||
// If the vertex normal is negative, flip the texture back
|
||||
// right-side up.
|
||||
vec2 uv = uv_unflipped * vec2(sign, 1);
|
||||
return uv;
|
||||
}
|
||||
|
||||
vec3 _t_normal_post_1(vec3 vNt0, float sign_or_zero)
|
||||
{
|
||||
// Assume normal is unpacked
|
||||
vec3 vNt1 = vNt0;
|
||||
// Get sign
|
||||
float sign = sign_or_zero;
|
||||
// Handle case where sign is 0
|
||||
sign = (2.0*sign) + 1.0;
|
||||
sign /= abs(sign);
|
||||
// If the sign is negative, rotate normal by 180 degrees
|
||||
vNt1.xy = (min(0, sign) * vNt1.xy) + (min(0, -sign) * -vNt1.xy);
|
||||
return vNt1;
|
||||
}
|
||||
|
||||
// Triplanar-specific normal texture fixes
|
||||
vec3 _t_normal_post_x(vec3 vNt0)
|
||||
{
|
||||
vec3 vNt_x = _t_normal_post_1(vNt0, sign(vary_vertex_normal.x));
|
||||
// *HACK: Transform normals according to orientation of the UVs
|
||||
vNt_x.xy = vec2(-vNt_x.y, vNt_x.x);
|
||||
return vNt_x;
|
||||
}
|
||||
vec3 _t_normal_post_y(vec3 vNt0)
|
||||
{
|
||||
vec3 vNt_y = _t_normal_post_1(vNt0, sign(vary_vertex_normal.y));
|
||||
// *HACK: Transform normals according to orientation of the UVs
|
||||
vNt_y.xy = -vNt_y.xy;
|
||||
return vNt_y;
|
||||
}
|
||||
vec3 _t_normal_post_z(vec3 vNt0)
|
||||
{
|
||||
vec3 vNt_z = _t_normal_post_1(vNt0, sign(vary_vertex_normal.z));
|
||||
return vNt_z;
|
||||
}
|
||||
|
||||
PBRMix terrain_sample_pbr(
|
||||
TerrainCoord terrain_coord
|
||||
, TerrainTriplanar tw
|
||||
, sampler2D tex_col
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, sampler2D tex_orm
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
, sampler2D tex_vNt
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, sampler2D tex_emissive
|
||||
#endif
|
||||
)
|
||||
{
|
||||
PBRMix mix = init_pbr_mix();
|
||||
|
||||
#define get_uv_x() _t_uv(terrain_coord[0].zw, sign(vary_vertex_normal.x))
|
||||
#define get_uv_y() _t_uv(terrain_coord[1].xy, sign(vary_vertex_normal.y))
|
||||
#define get_uv_z() _t_uv(terrain_coord[0].xy, sign(vary_vertex_normal.z))
|
||||
switch (tw.type & SAMPLE_X)
|
||||
{
|
||||
case SAMPLE_X:
|
||||
PBRMix mix_x = sample_pbr(
|
||||
get_uv_x()
|
||||
, tex_col
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, tex_orm
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
, tex_vNt
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, tex_emissive
|
||||
#endif
|
||||
);
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
// Triplanar-specific normal texture fix
|
||||
mix_x.vNt = _t_normal_post_x(mix_x.vNt);
|
||||
#endif
|
||||
mix = mix_pbr(mix, mix_x, tw.weight.x);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (tw.type & SAMPLE_Y)
|
||||
{
|
||||
case SAMPLE_Y:
|
||||
PBRMix mix_y = sample_pbr(
|
||||
get_uv_y()
|
||||
, tex_col
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, tex_orm
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
, tex_vNt
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, tex_emissive
|
||||
#endif
|
||||
);
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
// Triplanar-specific normal texture fix
|
||||
mix_y.vNt = _t_normal_post_y(mix_y.vNt);
|
||||
#endif
|
||||
mix = mix_pbr(mix, mix_y, tw.weight.y);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (tw.type & SAMPLE_Z)
|
||||
{
|
||||
case SAMPLE_Z:
|
||||
PBRMix mix_z = sample_pbr(
|
||||
get_uv_z()
|
||||
, tex_col
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, tex_orm
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
, tex_vNt
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, tex_emissive
|
||||
#endif
|
||||
);
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
// Triplanar-specific normal texture fix
|
||||
// *NOTE: Bottom face has not been tested
|
||||
mix_z.vNt = _t_normal_post_z(mix_z.vNt);
|
||||
#endif
|
||||
mix = mix_pbr(mix, mix_z, tw.weight.z);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return mix;
|
||||
}
|
||||
|
||||
#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1
|
||||
|
||||
#define TerrainCoord vec2
|
||||
|
||||
#define terrain_sample_pbr sample_pbr
|
||||
|
||||
#endif
|
||||
|
||||
PBRMix multiply_factors_pbr(
|
||||
PBRMix mix_in
|
||||
, vec4 factor_col
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
, vec3 factor_orm
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, vec2 factor_rm
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, vec3 factor_emissive
|
||||
#endif
|
||||
)
|
||||
{
|
||||
PBRMix mix = mix_in;
|
||||
mix.col *= factor_col;
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
mix.orm *= factor_orm;
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
mix.rm *= factor_rm;
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
mix.emissive *= factor_emissive;
|
||||
#endif
|
||||
return mix;
|
||||
}
|
||||
|
||||
PBRMix terrain_sample_and_multiply_pbr(
|
||||
TerrainCoord terrain_coord
|
||||
, sampler2D tex_col
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, sampler2D tex_orm
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
, sampler2D tex_vNt
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, sampler2D tex_emissive
|
||||
#endif
|
||||
, vec4 factor_col
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
, vec3 factor_orm
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, vec2 factor_rm
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, vec3 factor_emissive
|
||||
#endif
|
||||
)
|
||||
{
|
||||
PBRMix mix = terrain_sample_pbr(
|
||||
terrain_coord
|
||||
#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
|
||||
, _t_triplanar()
|
||||
#endif
|
||||
, tex_col
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, tex_orm
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
|
||||
, tex_vNt
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, tex_emissive
|
||||
#endif
|
||||
);
|
||||
|
||||
mix = multiply_factors_pbr(mix
|
||||
, factor_col
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
|
||||
, factor_orm
|
||||
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
|
||||
, factor_rm
|
||||
#endif
|
||||
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
|
||||
, factor_emissive
|
||||
#endif
|
||||
);
|
||||
|
||||
return mix;
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* @file class1\environment\pbrterrainV.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$
|
||||
*/
|
||||
|
||||
uniform mat3 normal_matrix;
|
||||
uniform mat4 texture_matrix0;
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
in vec3 position;
|
||||
in vec3 normal;
|
||||
in vec4 tangent;
|
||||
in vec4 diffuse_color;
|
||||
in vec2 texcoord1;
|
||||
|
||||
#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
|
||||
out vec4[2] vary_coords;
|
||||
#endif
|
||||
out vec3 vary_vertex_normal; // Used by pbrterrainUtilF.glsl
|
||||
out vec3 vary_normal;
|
||||
out vec3 vary_tangent;
|
||||
flat out float vary_sign;
|
||||
out vec4 vary_texcoord0;
|
||||
out vec4 vary_texcoord1;
|
||||
out vec3 vary_position;
|
||||
|
||||
// *HACK: tangent_space_transform should use texture_normal_transform, or maybe
|
||||
// we shouldn't use tangent_space_transform at all. See the call to
|
||||
// tangent_space_transform below.
|
||||
uniform vec4[2] texture_base_color_transform;
|
||||
|
||||
vec2 terrain_texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform);
|
||||
vec3 terrain_tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform);
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
|
||||
|
||||
vec3 n = normal_matrix * normal;
|
||||
vary_vertex_normal = normal;
|
||||
vec3 t = normal_matrix * tangent.xyz;
|
||||
|
||||
vary_tangent = normalize(t);
|
||||
// *TODO: Decide if we want this. It may be better to just calculate the
|
||||
// tangents on-the-fly in the fragment shader, due to the subtleties of the
|
||||
// effect of triplanar mapping on UVs.
|
||||
// *HACK: Should be using texture_normal_transform here. The KHR texture
|
||||
// transform spec requires handling texture transforms separately for each
|
||||
// individual texture.
|
||||
vary_tangent = normalize(terrain_tangent_space_transform(vec4(t, tangent.w), n, texture_base_color_transform));
|
||||
vary_sign = tangent.w;
|
||||
vary_normal = normalize(n);
|
||||
|
||||
// Transform and pass tex coords
|
||||
// *HACK: texture_base_color_transform is used for all of these here, but
|
||||
// the KHR texture transform spec requires handling texture transforms
|
||||
// separately for each individual texture.
|
||||
#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
|
||||
// xy
|
||||
vary_coords[0].xy = terrain_texture_transform(position.xy, texture_base_color_transform);
|
||||
// yz
|
||||
vary_coords[0].zw = terrain_texture_transform(position.yz, texture_base_color_transform);
|
||||
// (-x)z
|
||||
vary_coords[1].xy = terrain_texture_transform(position.xz * vec2(-1, 1), texture_base_color_transform);
|
||||
#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1
|
||||
vary_texcoord0.xy = terrain_texture_transform(position.xy, texture_base_color_transform);
|
||||
#endif
|
||||
|
||||
vec4 tc = vec4(texcoord1,0,1);
|
||||
vary_texcoord0.zw = tc.xy;
|
||||
vary_texcoord1.xy = tc.xy-vec2(2.0, 0.0);
|
||||
vary_texcoord1.zw = tc.xy-vec2(1.0, 0.0);
|
||||
}
|
||||
|
|
@ -97,6 +97,7 @@ vec3 toneMapACES_Hill(vec3 color)
|
|||
|
||||
uniform float exposure;
|
||||
uniform float gamma;
|
||||
uniform float aces_mix;
|
||||
|
||||
vec3 toneMap(vec3 color)
|
||||
{
|
||||
|
|
@ -106,7 +107,7 @@ vec3 toneMap(vec3 color)
|
|||
color *= exposure * exp_scale;
|
||||
|
||||
// mix ACES and Linear here as a compromise to avoid over-darkening legacy content
|
||||
color = mix(toneMapACES_Hill(color), color, 0.3);
|
||||
color = mix(toneMapACES_Hill(color), color, aces_mix);
|
||||
#endif
|
||||
|
||||
return color;
|
||||
|
|
@ -152,6 +153,15 @@ float noise(vec2 x) {
|
|||
|
||||
//=============================
|
||||
|
||||
void debugExposure(inout vec3 color)
|
||||
{
|
||||
float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
|
||||
exp_scale *= 0.5;
|
||||
if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1)
|
||||
{
|
||||
color = vec3(1,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
vec3 legacyGamma(vec3 color)
|
||||
{
|
||||
|
|
@ -181,6 +191,7 @@ void main()
|
|||
vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb));
|
||||
diff.rgb += nz*0.003;
|
||||
|
||||
//debugExposure(diff.rgb);
|
||||
frag_color = max(diff, vec4(0));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file class1/deferred/skyF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2005, 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$
|
||||
*/
|
||||
|
|
@ -27,6 +27,15 @@
|
|||
in vec3 vary_HazeColor;
|
||||
in float vary_LightNormPosDot;
|
||||
|
||||
#ifdef HAS_HDRI
|
||||
in vec4 vary_position;
|
||||
in vec3 vary_rel_pos;
|
||||
uniform float sky_hdr_scale;
|
||||
uniform float hdri_split_screen;
|
||||
uniform mat3 env_mat;
|
||||
uniform sampler2D environmentMap;
|
||||
#endif
|
||||
|
||||
uniform sampler2D rainbow_map;
|
||||
uniform sampler2D halo_map;
|
||||
|
||||
|
|
@ -37,6 +46,9 @@ uniform float ice_level;
|
|||
out vec4 frag_data[4];
|
||||
|
||||
vec3 srgb_to_linear(vec3 c);
|
||||
vec3 linear_to_srgb(vec3 c);
|
||||
|
||||
#define PI 3.14159265
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// The fragment shader for the sky
|
||||
|
|
@ -71,24 +83,42 @@ vec3 halo22(float d)
|
|||
|
||||
void main()
|
||||
{
|
||||
// Potential Fill-rate optimization. Add cloud calculation
|
||||
// back in and output alpha of 0 (so that alpha culling kills
|
||||
// the fragment) if the sky wouldn't show up because the clouds
|
||||
// are fully opaque.
|
||||
vec3 color;
|
||||
#ifdef HAS_HDRI
|
||||
vec3 frag_coord = vary_position.xyz/vary_position.w;
|
||||
if (-frag_coord.x > ((1.0-hdri_split_screen)*2.0-1.0))
|
||||
{
|
||||
vec3 pos = normalize(vary_rel_pos);
|
||||
pos = env_mat * pos;
|
||||
vec2 texCoord = vec2(atan(pos.z, pos.x) + PI, acos(pos.y)) / vec2(2.0 * PI, PI);
|
||||
color = textureLod(environmentMap, texCoord.xy, 0).rgb * sky_hdr_scale;
|
||||
color = min(color, vec3(8192*8192*16)); // stupidly large value arrived at by binary search -- avoids framebuffer corruption from some HDRIs
|
||||
|
||||
vec3 color = vary_HazeColor;
|
||||
frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_HAS_HDRI);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Potential Fill-rate optimization. Add cloud calculation
|
||||
// back in and output alpha of 0 (so that alpha culling kills
|
||||
// the fragment) if the sky wouldn't show up because the clouds
|
||||
// are fully opaque.
|
||||
|
||||
float rel_pos_lightnorm = vary_LightNormPosDot;
|
||||
float optic_d = rel_pos_lightnorm;
|
||||
vec3 halo_22 = halo22(optic_d);
|
||||
color.rgb += rainbow(optic_d);
|
||||
color.rgb += halo_22;
|
||||
color.rgb *= 2.;
|
||||
color.rgb = clamp(color.rgb, vec3(0), vec3(5));
|
||||
color = vary_HazeColor;
|
||||
|
||||
float rel_pos_lightnorm = vary_LightNormPosDot;
|
||||
float optic_d = rel_pos_lightnorm;
|
||||
vec3 halo_22 = halo22(optic_d);
|
||||
color.rgb += rainbow(optic_d);
|
||||
color.rgb += halo_22;
|
||||
color.rgb *= 2.;
|
||||
color.rgb = clamp(color.rgb, vec3(0), vec3(5));
|
||||
|
||||
frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS);
|
||||
}
|
||||
|
||||
frag_data[0] = vec4(0);
|
||||
frag_data[1] = vec4(0);
|
||||
frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); //1.0 in norm.w masks off fog
|
||||
frag_data[3] = vec4(color.rgb, 1.0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ in vec3 position;
|
|||
out vec3 vary_HazeColor;
|
||||
out float vary_LightNormPosDot;
|
||||
|
||||
#ifdef HAS_HDRI
|
||||
out vec4 vary_position;
|
||||
out vec3 vary_rel_pos;
|
||||
#endif
|
||||
|
||||
// Inputs
|
||||
uniform vec3 camPosLocal;
|
||||
|
||||
|
|
@ -72,6 +77,11 @@ void main()
|
|||
// Get relative position
|
||||
vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
|
||||
|
||||
#ifdef HAS_HDRI
|
||||
vary_rel_pos = rel_pos;
|
||||
vary_position = pos;
|
||||
#endif
|
||||
|
||||
// Adj position vector to clamp altitude
|
||||
if (rel_pos.y > 0.)
|
||||
{
|
||||
|
|
@ -92,13 +102,13 @@ void main()
|
|||
|
||||
// Initialize temp variables
|
||||
vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color * 0.7; //magic 0.7 to match legacy color
|
||||
|
||||
|
||||
// Sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
// this is used later for sunlight modulation at various altitudes
|
||||
vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
|
||||
|
||||
// Calculate relative weights
|
||||
vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
|
||||
vec3 combined_haze = max(abs(blue_density) + vec3(abs(haze_density)), vec3(1e-6));
|
||||
vec3 blue_weight = blue_density / combined_haze;
|
||||
vec3 haze_weight = haze_density / combined_haze;
|
||||
|
||||
|
|
@ -142,7 +152,7 @@ void main()
|
|||
sunlight *= max(0.0, (1. - cloud_shadow));
|
||||
|
||||
// Haze color below cloud
|
||||
vec3 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient)
|
||||
vec3 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient)
|
||||
+ (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient));
|
||||
|
||||
// Attenuate cloud color by atmosphere
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
/**
|
||||
/**
|
||||
* @file class1\deferred\terrainF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, 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$
|
||||
*/
|
||||
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
out vec4 frag_data[4];
|
||||
|
|
@ -38,12 +38,13 @@ in vec3 vary_normal;
|
|||
in vec4 vary_texcoord0;
|
||||
in vec4 vary_texcoord1;
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
void mirrorClip(vec3 position);
|
||||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(pos);
|
||||
/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
|
||||
|
||||
|
||||
vec4 color0 = texture(detail_0, vary_texcoord0.xy);
|
||||
vec4 color1 = texture(detail_1, vary_texcoord0.xy);
|
||||
vec4 color2 = texture(detail_2, vary_texcoord0.xy);
|
||||
|
|
@ -53,13 +54,13 @@ void main()
|
|||
float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a;
|
||||
float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a;
|
||||
vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
|
||||
|
||||
outColor.a = 0.0; // yes, downstream atmospherics
|
||||
|
||||
|
||||
outColor.a = 0.0; // yes, downstream atmospherics
|
||||
|
||||
frag_data[0] = outColor;
|
||||
frag_data[1] = vec4(0.0,0.0,0.0,-1.0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,36 +1,36 @@
|
|||
/**
|
||||
/**
|
||||
* @file class1\environment\terrainV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, 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$
|
||||
*/
|
||||
|
||||
uniform mat3 normal_matrix;
|
||||
uniform mat4 texture_matrix0;
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
in vec3 position;
|
||||
in vec3 normal;
|
||||
in vec4 diffuse_color;
|
||||
in vec2 texcoord0;
|
||||
in vec2 texcoord1;
|
||||
|
||||
out vec3 pos;
|
||||
|
|
@ -41,18 +41,18 @@ out vec4 vary_texcoord1;
|
|||
uniform vec4 object_plane_s;
|
||||
uniform vec4 object_plane_t;
|
||||
|
||||
vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
|
||||
vec2 texgen_object(vec4 vpos, mat4 mat, vec4 tp0, vec4 tp1)
|
||||
{
|
||||
vec4 tcoord;
|
||||
|
||||
|
||||
tcoord.x = dot(vpos, tp0);
|
||||
tcoord.y = dot(vpos, tp1);
|
||||
tcoord.z = tc.z;
|
||||
tcoord.w = tc.w;
|
||||
tcoord.z = 0;
|
||||
tcoord.w = 1;
|
||||
|
||||
tcoord = mat * tcoord;
|
||||
|
||||
return tcoord;
|
||||
tcoord = mat * tcoord;
|
||||
|
||||
return tcoord.xy;
|
||||
}
|
||||
|
||||
void main()
|
||||
|
|
@ -62,15 +62,15 @@ void main()
|
|||
vec4 t_pos = modelview_projection_matrix * pre_pos;
|
||||
|
||||
gl_Position = t_pos;
|
||||
pos = t_pos.xyz;
|
||||
pos = (modelview_matrix*pre_pos).xyz;
|
||||
|
||||
vary_normal = normalize(normal_matrix * normal);
|
||||
|
||||
|
||||
// Transform and pass tex coords
|
||||
vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
|
||||
|
||||
vary_texcoord0.xy = texgen_object(vec4(position, 1.0), texture_matrix0, object_plane_s, object_plane_t);
|
||||
|
||||
vec4 t = vec4(texcoord1,0,1);
|
||||
|
||||
|
||||
vary_texcoord0.zw = t.xy;
|
||||
vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
|
||||
vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file class1/deferred/textureUtilV.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$
|
||||
*/
|
||||
|
|
@ -65,7 +65,7 @@ vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl
|
|||
// Apply texture animation first to avoid shearing and other artifacts
|
||||
texcoord = (sl_animation_transform * vec4(texcoord, 0, 1)).xy;
|
||||
// Convert to left-handed coordinate system. The offset of 1 is necessary
|
||||
// for rotations to be applied correctly.
|
||||
// for rotation and scale to be applied correctly.
|
||||
texcoord.y = 1.0 - texcoord.y;
|
||||
texcoord = khr_texture_transform(texcoord, khr_gltf_transform[0].xy, khr_gltf_transform[0].z, khr_gltf_transform[1].xy);
|
||||
// Convert back to right-handed coordinate system
|
||||
|
|
@ -77,6 +77,19 @@ vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl
|
|||
return texcoord;
|
||||
}
|
||||
|
||||
// Similar to texture_transform but no offset during coordinate system
|
||||
// conversion, and no texture animation support.
|
||||
vec2 terrain_texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform)
|
||||
{
|
||||
vec2 texcoord = vertex_texcoord;
|
||||
|
||||
texcoord.y = -texcoord.y;
|
||||
texcoord = khr_texture_transform(texcoord, khr_gltf_transform[0].xy, khr_gltf_transform[0].z, khr_gltf_transform[1].xy);
|
||||
texcoord.y = -texcoord.y;
|
||||
|
||||
return texcoord;
|
||||
}
|
||||
|
||||
// Take the rotation only from both transforms and apply to the tangent. This
|
||||
// accounts for the change of the topology of the normal texture when a texture
|
||||
// rotation is applied to it.
|
||||
|
|
@ -120,3 +133,25 @@ vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] kh
|
|||
|
||||
return (weights.x * vertex_binormal.xyz) + (weights.y * vertex_tangent.xyz);
|
||||
}
|
||||
|
||||
// Similar to tangent_space_transform but no no texture animation support.
|
||||
vec3 terrain_tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform)
|
||||
{
|
||||
// Immediately convert to left-handed coordinate system ((0,1) -> (0, -1))
|
||||
vec2 weights = vec2(0, -1);
|
||||
|
||||
// Apply KHR_texture_transform (rotation only)
|
||||
float khr_rotation = khr_gltf_transform[0].z;
|
||||
mat2 khr_rotation_mat = mat2(
|
||||
cos(khr_rotation),-sin(khr_rotation),
|
||||
sin(khr_rotation), cos(khr_rotation)
|
||||
);
|
||||
weights = khr_rotation_mat * weights;
|
||||
|
||||
// Convert back to right-handed coordinate system
|
||||
weights.y = -weights.y;
|
||||
|
||||
vec3 vertex_binormal = vertex_tangent.w * cross(vertex_normal, vertex_tangent.xyz);
|
||||
|
||||
return (weights.x * vertex_binormal.xyz) + (weights.y * vertex_tangent.xyz);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,13 +32,14 @@ uniform sampler2D diffuseMap;
|
|||
in vec4 vertex_color;
|
||||
in vec3 vary_normal;
|
||||
in vec2 vary_texcoord0;
|
||||
in vec3 vary_position;
|
||||
|
||||
uniform float minimum_alpha;
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
|
||||
void mirrorClip(vec3 pos);
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
vec4 col = texture(diffuseMap, vary_texcoord0.xy);
|
||||
if (col.a < minimum_alpha)
|
||||
{
|
||||
|
|
@ -48,6 +49,6 @@ void main()
|
|||
frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
|
||||
frag_data[3] = vec4(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
uniform mat4 texture_matrix0;
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
uniform mat3 normal_matrix;
|
||||
|
||||
|
|
@ -34,11 +35,14 @@ in vec2 texcoord0;
|
|||
out vec3 vary_normal;
|
||||
out vec4 vertex_color;
|
||||
out vec2 vary_texcoord0;
|
||||
out vec3 vary_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
|
||||
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
|
||||
vary_normal = normalize(normal_matrix * normal);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
/**
|
||||
* @file encodeNormF.glsl
|
||||
* @file normaldebugF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2018&license=viewerlgpl$
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2018, Linden Research, Inc.
|
||||
* 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
|
||||
|
|
@ -23,12 +23,11 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// Lambert Azimuthal Equal-Area projection
|
||||
// See: https://aras-p.info/texts/CompactNormalStorage.html
|
||||
// Also see: A_bit_more_deferred_-_CryEngine3.ppt
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
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[];
|
||||
#ifdef HAS_ATTRIBUTE_TANGENT
|
||||
in vec4 tangent_g[];
|
||||
#endif
|
||||
|
||||
layout(triangles) in;
|
||||
#ifdef HAS_ATTRIBUTE_TANGENT
|
||||
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();
|
||||
|
||||
#ifdef HAS_ATTRIBUTE_TANGENT
|
||||
// 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;
|
||||
#ifdef HAS_ATTRIBUTE_TANGENT
|
||||
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);
|
||||
#ifdef HAS_ATTRIBUTE_TANGENT
|
||||
tangent_g = get_screen_normal(position.xyz, world_pos, tangent.xyz, mat);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -38,6 +38,7 @@ in vec3 vary_dir;
|
|||
uniform float mipLevel;
|
||||
uniform int u_width;
|
||||
uniform float max_probe_lod;
|
||||
uniform float probe_strength;
|
||||
|
||||
|
||||
// =============================================================================================================
|
||||
|
|
@ -129,7 +130,7 @@ vec4 prefilterEnvMap(vec3 R)
|
|||
float totalWeight = 0.0;
|
||||
float envMapDim = float(textureSize(reflectionProbes, 0).s);
|
||||
float roughness = mipLevel/max_probe_lod;
|
||||
int numSamples = max(int(32*roughness), 1);
|
||||
int numSamples = max(int(PROBE_FILTER_SAMPLES*roughness), 1);
|
||||
|
||||
float numMips = max_probe_lod+1;
|
||||
|
||||
|
|
@ -163,5 +164,6 @@ void main()
|
|||
{
|
||||
vec3 N = normalize(vary_dir);
|
||||
frag_color = max(prefilterEnvMap(N), vec4(0));
|
||||
frag_color.a *= probe_strength;
|
||||
}
|
||||
// =============================================================================================================
|
||||
|
|
|
|||
|
|
@ -30,9 +30,13 @@ uniform sampler2D texture1;
|
|||
|
||||
in vec2 vary_texcoord0;
|
||||
in vec2 vary_texcoord1;
|
||||
in vec3 vary_position;
|
||||
|
||||
void mirrorClip(vec3 pos);
|
||||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
float tex0 = texture(texture0, vary_texcoord0.xy).a;
|
||||
float tex1 = texture(texture1, vary_texcoord1.xy).a;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 texture_matrix0;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
|
|
@ -32,11 +33,11 @@ in vec2 texcoord1;
|
|||
|
||||
out vec2 vary_texcoord0;
|
||||
out vec2 vary_texcoord1;
|
||||
out vec3 vary_position;
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
mat4 getObjectSkinnedTransform();
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat4 modelview_matrix;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
|
|
@ -46,8 +47,10 @@ void main()
|
|||
mat4 mat = getObjectSkinnedTransform();
|
||||
mat = modelview_matrix * mat;
|
||||
vec4 pos = mat * vec4(position.xyz, 1.0);
|
||||
vary_position = pos.xyz;
|
||||
gl_Position = projection_matrix * pos;
|
||||
#else
|
||||
vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;
|
||||
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
|
||||
#endif
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
|
|
|
|||
|
|
@ -57,16 +57,16 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
|
|||
|
||||
vec3 rel_pos_norm = normalize(rel_pos);
|
||||
float rel_pos_len = length(rel_pos);
|
||||
|
||||
|
||||
vec3 sunlight = (sun_up_factor == 1) ? sunlight_color: moonlight_color;
|
||||
|
||||
|
||||
// sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
// this is used later for sunlight modulation at various altitudes
|
||||
vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
|
||||
// I had thought blue_density and haze_density should have equal weighting,
|
||||
// but attenuation due to haze_density tends to seem too strong
|
||||
|
||||
vec3 combined_haze = blue_density + vec3(haze_density);
|
||||
vec3 combined_haze = max(blue_density + vec3(haze_density), vec3(1e-6));
|
||||
vec3 blue_weight = blue_density / combined_haze;
|
||||
vec3 haze_weight = vec3(haze_density) / combined_haze;
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
|
|||
haze_glow = max(haze_glow, .001); // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
|
||||
haze_glow *= glow.x;
|
||||
// higher glow.x gives dimmer glow (because next step is 1 / "angle")
|
||||
haze_glow = pow(haze_glow, glow.z);
|
||||
haze_glow = clamp(pow(haze_glow, glow.z), -100000, 100000);
|
||||
// glow.z should be negative, so we're doing a sort of (1 / "angle") function
|
||||
|
||||
// add "minimum anti-solar illumination"
|
||||
|
|
@ -119,7 +119,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
|
|||
additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb);
|
||||
|
||||
// brightness of surface both sunlight and ambient
|
||||
|
||||
|
||||
sunlit = sunlight.rgb;
|
||||
amblit = tmpAmbient;
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
|
|||
|
||||
vec3 srgb_to_linear(vec3 col);
|
||||
|
||||
// provide a touch of lighting in the opposite direction of the sun light
|
||||
// provide a touch of lighting in the opposite direction of the sun light
|
||||
// so areas in shadow don't lose all detail
|
||||
float ambientLighting(vec3 norm, vec3 light_dir)
|
||||
{
|
||||
|
|
@ -150,7 +150,7 @@ void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, ou
|
|||
// (allows for mixing of light sources other than sunlight e.g. reflection probes)
|
||||
sunlit *= sky_sunlight_scale;
|
||||
amblit *= sky_ambient_scale;
|
||||
|
||||
|
||||
amblit = srgb_to_linear(amblit);
|
||||
amblit *= ambientLighting(norm, light_dir);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ void waterClip(vec3 pos);
|
|||
vec3 srgb_to_linear(vec3 c);
|
||||
vec3 linear_to_srgb(vec3 c);
|
||||
|
||||
vec2 encode_normal (vec3 n);
|
||||
vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);
|
||||
void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
|
||||
|
||||
|
|
@ -78,6 +77,8 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
|
|||
|
||||
float getAmbientClamp();
|
||||
|
||||
void mirrorClip(vec3 pos);
|
||||
|
||||
void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear);
|
||||
|
||||
|
|
@ -167,6 +168,8 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec
|
|||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
|
||||
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
|
||||
|
||||
vec4 pos = vec4(vary_position, 1.0);
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file class1\deferred\pbralphaF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, 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$
|
||||
*/
|
||||
|
|
@ -87,9 +87,10 @@ vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);
|
|||
void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
|
||||
float calcLegacyDistanceAttenuation(float distance, float falloff);
|
||||
float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
|
||||
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
||||
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear);
|
||||
|
||||
void mirrorClip(vec3 pos);
|
||||
void waterClip(vec3 pos);
|
||||
|
||||
void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor);
|
||||
|
|
@ -110,15 +111,15 @@ vec3 pbrBaseLight(vec3 diffuseColor,
|
|||
vec3 additive,
|
||||
vec3 atten);
|
||||
|
||||
vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
|
||||
float perceptualRoughness,
|
||||
vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
|
||||
float perceptualRoughness,
|
||||
float metallic,
|
||||
vec3 n, // normal
|
||||
vec3 v, // surface point to camera
|
||||
vec3 l); //surface point to light
|
||||
|
||||
vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
|
||||
float perceptualRoughness,
|
||||
vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
|
||||
float perceptualRoughness,
|
||||
float metallic,
|
||||
vec3 n, // normal
|
||||
vec3 p, // pixel position
|
||||
|
|
@ -156,6 +157,8 @@ vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
|
|||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
|
||||
vec3 color = vec3(0,0,0);
|
||||
|
||||
vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
|
||||
|
|
@ -178,7 +181,7 @@ void main()
|
|||
float sign = vary_sign;
|
||||
vec3 vN = vary_normal;
|
||||
vec3 vT = vary_tangent.xyz;
|
||||
|
||||
|
||||
vec3 vB = sign * cross(vN, vT);
|
||||
vec3 norm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
|
||||
|
||||
|
|
@ -215,7 +218,7 @@ void main()
|
|||
vec3 irradiance = vec3(0);
|
||||
vec3 radiance = vec3(0);
|
||||
sampleReflectionProbes(irradiance, radiance, vary_position.xy*0.5+0.5, pos.xyz, norm.xyz, gloss, true, amblit);
|
||||
|
||||
|
||||
vec3 diffuseColor;
|
||||
vec3 specularColor;
|
||||
calcDiffuseSpecular(col.rgb, metallic, diffuseColor, specularColor);
|
||||
|
|
@ -242,7 +245,7 @@ void main()
|
|||
color.rgb = applySkyAndWaterFog(pos.xyz, additive, atten, vec4(color, 1.0)).rgb;
|
||||
|
||||
float a = basecolor.a*vertex_color.a;
|
||||
|
||||
|
||||
frag_color = max(vec4(color.rgb,a), vec4(0));
|
||||
}
|
||||
|
||||
|
|
@ -292,7 +295,7 @@ void main()
|
|||
// emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear
|
||||
colorEmissive *= srgb_to_linear(texture(emissiveMap, emissive_texcoord.xy).rgb);
|
||||
|
||||
|
||||
|
||||
float a = basecolor.a*vertex_color.a;
|
||||
color += colorEmissive;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file sunLightF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, 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$
|
||||
*/
|
||||
|
|
@ -35,23 +35,23 @@ in vec2 vary_fragcoord;
|
|||
uniform vec3 sun_dir;
|
||||
uniform float shadow_bias;
|
||||
|
||||
vec3 getNorm(vec2 pos_screen);
|
||||
vec4 getNorm(vec2 pos_screen);
|
||||
vec4 getPosition(vec2 pos_screen);
|
||||
|
||||
float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
|
||||
float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen);
|
||||
|
||||
void main()
|
||||
void main()
|
||||
{
|
||||
vec2 pos_screen = vary_fragcoord.xy;
|
||||
vec4 pos = getPosition(pos_screen);
|
||||
vec3 norm = getNorm(pos_screen);
|
||||
vec4 norm = getNorm(pos_screen);
|
||||
|
||||
vec4 col;
|
||||
col.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
|
||||
col.r = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
|
||||
col.g = 1.0f;
|
||||
col.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
|
||||
col.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
|
||||
col.b = sampleSpotShadow(pos.xyz, norm.xyz, 0, pos_screen);
|
||||
col.a = sampleSpotShadow(pos.xyz, norm.xyz, 1, pos_screen);
|
||||
|
||||
frag_color = clamp(col, vec4(0), vec4(1));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
/**
|
||||
/**
|
||||
* @file class2/deferred/sunLightSSAOF.glsl
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, 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$
|
||||
*/
|
||||
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
out vec4 frag_color;
|
||||
|
|
@ -32,23 +32,23 @@ out vec4 frag_color;
|
|||
in vec2 vary_fragcoord;
|
||||
|
||||
vec4 getPosition(vec2 pos_screen);
|
||||
vec3 getNorm(vec2 pos_screen);
|
||||
vec4 getNorm(vec2 pos_screen);
|
||||
|
||||
float sampleDirectionalShadow(vec3 shadow_pos, vec3 norm, vec2 pos_screen);
|
||||
float sampleSpotShadow(vec3 shadow_pos, vec3 norm, int index, vec2 pos_screen);
|
||||
float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
|
||||
|
||||
void main()
|
||||
void main()
|
||||
{
|
||||
vec2 pos_screen = vary_fragcoord.xy;
|
||||
vec4 pos = getPosition(pos_screen);
|
||||
vec3 norm = getNorm(pos_screen);
|
||||
vec4 norm = getNorm(pos_screen);
|
||||
|
||||
vec4 col;
|
||||
col.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
|
||||
col.g = calcAmbientOcclusion(pos, norm, pos_screen);
|
||||
col.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
|
||||
col.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
|
||||
col.r = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
|
||||
col.g = calcAmbientOcclusion(pos, norm.xyz, pos_screen);
|
||||
col.b = sampleSpotShadow(pos.xyz, norm.xyz, 0, pos_screen);
|
||||
col.a = sampleSpotShadow(pos.xyz, norm.xyz, 1, pos_screen);
|
||||
|
||||
frag_color = clamp(col, vec4(0), vec4(1));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,8 +53,11 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
|
|||
|
||||
void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
|
||||
|
||||
void mirrorClip(vec3 pos);
|
||||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
#ifdef HAS_DIFFUSE_LOOKUP
|
||||
vec4 color = diffuseLookup(vary_texcoord0.xy);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ uniform vec3 moon_dir;
|
|||
uniform int sun_up_factor;
|
||||
in vec2 vary_fragcoord;
|
||||
|
||||
vec3 getNorm(vec2 pos_screen);
|
||||
vec4 getNorm(vec2 pos_screen);
|
||||
vec4 getPositionWithDepth(vec2 pos_screen, float depth);
|
||||
void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
|
||||
|
||||
|
|
@ -53,8 +53,7 @@ void main()
|
|||
vec2 tc = vary_fragcoord.xy;
|
||||
float depth = getDepth(tc.xy);
|
||||
vec4 pos = getPositionWithDepth(tc, depth);
|
||||
vec4 norm = texture(normalMap, tc);
|
||||
norm.xyz = getNorm(tc);
|
||||
vec4 norm = getNorm(tc);
|
||||
vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
|
||||
|
||||
vec3 color = vec3(0);
|
||||
|
|
@ -68,16 +67,16 @@ void main()
|
|||
calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
|
||||
|
||||
vec3 sunlit_linear = srgb_to_linear(sunlit);
|
||||
|
||||
|
||||
// mask off atmospherics below water (when camera is under water)
|
||||
bool do_atmospherics = false;
|
||||
|
||||
|
||||
if (dot(vec3(0), waterPlane.xyz) + waterPlane.w > 0.0 ||
|
||||
dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0)
|
||||
{
|
||||
do_atmospherics = true;
|
||||
}
|
||||
|
||||
|
||||
vec3 irradiance = vec3(0);
|
||||
vec3 radiance = vec3(0);
|
||||
|
||||
|
|
@ -102,5 +101,5 @@ void main()
|
|||
}
|
||||
|
||||
frag_color = max(vec4(color.rgb, alpha), vec4(0)); //output linear since local lights will be added to this shader's results
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,13 @@ void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float
|
|||
vec3 srgb_to_linear(vec3 cs);
|
||||
vec3 linear_to_srgb(vec3 cs);
|
||||
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat3 normal_matrix;
|
||||
|
||||
in vec3 vary_position;
|
||||
|
||||
void mirrorClip(vec3 pos);
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
|
||||
out vec4 frag_color;
|
||||
|
|
@ -66,12 +73,12 @@ uniform vec4 morphFactor;
|
|||
uniform vec3 camPosLocal;
|
||||
uniform mat3 env_mat;
|
||||
|
||||
uniform float is_mirror;
|
||||
|
||||
uniform vec3 sun_dir;
|
||||
uniform vec3 moon_dir;
|
||||
in vec2 vary_fragcoord;
|
||||
|
||||
in vec3 vary_position;
|
||||
|
||||
uniform mat4 proj_mat;
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
|
@ -209,8 +216,6 @@ in vec3 vary_normal;
|
|||
in vec4 vertex_color;
|
||||
in vec2 vary_texcoord0;
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
|
||||
// get the transformed normal and apply glossiness component from normal map
|
||||
vec3 getNormal(inout float glossiness)
|
||||
{
|
||||
|
|
@ -285,12 +290,12 @@ float getShadow(vec3 pos, vec3 norm)
|
|||
|
||||
void main()
|
||||
{
|
||||
mirrorClip(vary_position);
|
||||
waterClip();
|
||||
|
||||
// diffcol == diffuse map combined with vertex color
|
||||
vec4 diffcol = texture(diffuseMap, vary_texcoord0.xy);
|
||||
diffcol.rgb *= vertex_color.rgb;
|
||||
|
||||
alphaMask(diffcol.a);
|
||||
|
||||
// spec == specular map combined with specular color
|
||||
|
|
@ -299,8 +304,6 @@ void main()
|
|||
float glossiness = specular_color.a;
|
||||
vec3 norm = getNormal(glossiness);
|
||||
|
||||
vec2 abnormal = encode_normal(norm.xyz);
|
||||
|
||||
float emissive = getEmissive(diffcol);
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
|
|
@ -407,10 +410,15 @@ void main()
|
|||
|
||||
#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
|
||||
// deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
|
||||
frag_data[0] = vec4(diffcol.rgb, emissive); // gbuffer is sRGB for legacy materials
|
||||
frag_data[1] = vec4(spec.rgb, glossiness); // XYZ = Specular color. W = Specular exponent.
|
||||
frag_data[2] = vec4(encode_normal(norm), env, GBUFFER_FLAG_HAS_ATMOS);; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
|
||||
frag_data[3] = vec4(0);
|
||||
|
||||
float flag = GBUFFER_FLAG_HAS_ATMOS;
|
||||
|
||||
frag_data[0] = max(vec4(diffcol.rgb, emissive), vec4(0)); // gbuffer is sRGB for legacy materials
|
||||
frag_data[1] = max(vec4(spec.rgb, glossiness), vec4(0)); // XYZ = Specular color. W = Specular exponent.
|
||||
frag_data[2] = vec4(norm, flag); // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
|
||||
frag_data[3] = vec4(env, 0, 0, 0);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ in vec4 vary_fragcoord;
|
|||
void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
|
||||
float calcLegacyDistanceAttenuation(float distance, float falloff);
|
||||
vec4 getPosition(vec2 pos_screen);
|
||||
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
|
||||
vec4 getNorm(vec2 screenpos);
|
||||
vec2 getScreenXY(vec4 clip);
|
||||
vec2 getScreenCoord(vec4 clip);
|
||||
vec3 srgb_to_linear(vec3 c);
|
||||
|
|
@ -56,8 +56,8 @@ vec3 srgb_to_linear(vec3 c);
|
|||
// Util
|
||||
vec3 hue_to_rgb(float hue);
|
||||
|
||||
vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
|
||||
float perceptualRoughness,
|
||||
vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
|
||||
float perceptualRoughness,
|
||||
float metallic,
|
||||
vec3 n, // normal
|
||||
vec3 v, // surface point to camera
|
||||
|
|
@ -74,9 +74,8 @@ void main()
|
|||
discard;
|
||||
}
|
||||
|
||||
float envIntensity; // not used for this shader
|
||||
vec3 n;
|
||||
vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
|
||||
vec4 norm = getNorm(tc); // need `norm.w` for GET_GBUFFER_FLAG()
|
||||
vec3 n = norm.xyz;
|
||||
|
||||
vec4 spec = texture(specularRect, tc);
|
||||
vec3 diffuse = texture(diffuseRect, tc).rgb;
|
||||
|
|
@ -92,7 +91,7 @@ void main()
|
|||
float metallic = orm.b;
|
||||
vec3 f0 = vec3(0.04);
|
||||
vec3 baseColor = diffuse.rgb;
|
||||
|
||||
|
||||
vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
|
||||
diffuseColor *= 1.0 - metallic;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
/**
|
||||
/**
|
||||
* @file class3\deferred\pointLightF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, 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$
|
||||
*/
|
||||
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
out vec4 frag_color;
|
||||
|
|
@ -52,15 +52,15 @@ uniform vec4 viewport;
|
|||
|
||||
void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
|
||||
float calcLegacyDistanceAttenuation(float distance, float falloff);
|
||||
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
|
||||
vec4 getNorm(vec2 screenpos);
|
||||
vec4 getPosition(vec2 pos_screen);
|
||||
vec2 getScreenXY(vec4 clip);
|
||||
vec2 getScreenCoord(vec4 clip);
|
||||
vec3 srgb_to_linear(vec3 c);
|
||||
float getDepth(vec2 tc);
|
||||
|
||||
vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
|
||||
float perceptualRoughness,
|
||||
vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
|
||||
float perceptualRoughness,
|
||||
float metallic,
|
||||
vec3 n, // normal
|
||||
vec3 v, // surface point to camera
|
||||
|
|
@ -72,9 +72,8 @@ void main()
|
|||
vec2 tc = getScreenCoord(vary_fragcoord);
|
||||
vec3 pos = getPosition(tc).xyz;
|
||||
|
||||
float envIntensity;
|
||||
vec3 n;
|
||||
vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
|
||||
vec4 norm = getNorm(tc); // need `norm.w` for GET_GBUFFER_FLAG()
|
||||
vec3 n = norm.xyz;
|
||||
|
||||
vec3 diffuse = texture(diffuseRect, tc).rgb;
|
||||
vec4 spec = texture(specularRect, tc);
|
||||
|
|
@ -94,13 +93,13 @@ void main()
|
|||
|
||||
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
|
||||
{
|
||||
vec3 colorEmissive = texture(emissiveRect, tc).rgb;
|
||||
vec3 colorEmissive = texture(emissiveRect, tc).rgb;
|
||||
vec3 orm = spec.rgb;
|
||||
float perceptualRoughness = orm.g;
|
||||
float metallic = orm.b;
|
||||
vec3 f0 = vec3(0.04);
|
||||
vec3 baseColor = diffuse.rgb;
|
||||
|
||||
|
||||
vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
|
||||
diffuseColor *= 1.0 - metallic;
|
||||
|
||||
|
|
@ -137,7 +136,7 @@ void main()
|
|||
final_color += lit*scol*color.rgb*spec.rgb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (dot(final_color, final_color) <= 0.0)
|
||||
{
|
||||
discard;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n,
|
|||
|
||||
uniform samplerCubeArray reflectionProbes;
|
||||
uniform samplerCubeArray irradianceProbes;
|
||||
|
||||
uniform sampler2D sceneMap;
|
||||
uniform int cube_snapshot;
|
||||
uniform float max_probe_lod;
|
||||
|
|
@ -47,14 +48,16 @@ layout (std140) uniform ReflectionProbes
|
|||
/// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation
|
||||
// box[3][0..2] - plane thickness
|
||||
mat4 refBox[MAX_REFMAP_COUNT];
|
||||
mat4 heroBox;
|
||||
// list of bounding spheres for reflection probes sorted by distance to camera (closest first)
|
||||
vec4 refSphere[MAX_REFMAP_COUNT];
|
||||
// extra parameters
|
||||
// extra parameters
|
||||
// x - irradiance scale
|
||||
// y - radiance scale
|
||||
// z - fade in
|
||||
// w - znear
|
||||
vec4 refParams[MAX_REFMAP_COUNT];
|
||||
vec4 heroSphere;
|
||||
// index of cube map in reflectionProbes for a corresponding reflection probe
|
||||
// e.g. cube map channel of refSphere[2] is stored in refIndex[2]
|
||||
// refIndex.x - cubemap channel in reflectionProbes
|
||||
|
|
@ -70,6 +73,10 @@ layout (std140) uniform ReflectionProbes
|
|||
|
||||
// number of reflection probes present in refSphere
|
||||
int refmapCount;
|
||||
|
||||
int heroShape;
|
||||
int heroMipCount;
|
||||
int heroProbeCount;
|
||||
};
|
||||
|
||||
// Inputs
|
||||
|
|
@ -95,7 +102,7 @@ bool shouldSampleProbe(int i, vec3 pos)
|
|||
if (refIndex[i].w < 0)
|
||||
{
|
||||
vec4 v = refBox[i] * vec4(pos, 1.0);
|
||||
if (abs(v.x) > 1 ||
|
||||
if (abs(v.x) > 1 ||
|
||||
abs(v.y) > 1 ||
|
||||
abs(v.z) > 1)
|
||||
{
|
||||
|
|
@ -222,7 +229,7 @@ void preProbeSample(vec3 pos)
|
|||
}
|
||||
}
|
||||
count++;
|
||||
|
||||
|
||||
++neighborIdx;
|
||||
}
|
||||
|
||||
|
|
@ -244,56 +251,56 @@ void preProbeSample(vec3 pos)
|
|||
|
||||
// original reference implementation:
|
||||
/*
|
||||
bool intersect(const Ray &ray) const
|
||||
{
|
||||
float t0, t1; // solutions for t if the ray intersects
|
||||
#if 0
|
||||
bool intersect(const Ray &ray) const
|
||||
{
|
||||
float t0, t1; // solutions for t if the ray intersects
|
||||
#if 0
|
||||
// geometric solution
|
||||
Vec3f L = center - orig;
|
||||
float tca = L.dotProduct(dir);
|
||||
Vec3f L = center - orig;
|
||||
float tca = L.dotProduct(dir);
|
||||
// if (tca < 0) return false;
|
||||
float d2 = L.dotProduct(L) - tca * tca;
|
||||
if (d2 > radius2) return false;
|
||||
float thc = sqrt(radius2 - d2);
|
||||
t0 = tca - thc;
|
||||
t1 = tca + thc;
|
||||
#else
|
||||
float d2 = L.dotProduct(L) - tca * tca;
|
||||
if (d2 > radius2) return false;
|
||||
float thc = sqrt(radius2 - d2);
|
||||
t0 = tca - thc;
|
||||
t1 = tca + thc;
|
||||
#else
|
||||
// analytic solution
|
||||
Vec3f L = orig - center;
|
||||
float a = dir.dotProduct(dir);
|
||||
float b = 2 * dir.dotProduct(L);
|
||||
float c = L.dotProduct(L) - radius2;
|
||||
if (!solveQuadratic(a, b, c, t0, t1)) return false;
|
||||
#endif
|
||||
if (t0 > t1) std::swap(t0, t1);
|
||||
|
||||
if (t0 < 0) {
|
||||
t0 = t1; // if t0 is negative, let's use t1 instead
|
||||
if (t0 < 0) return false; // both t0 and t1 are negative
|
||||
}
|
||||
|
||||
t = t0;
|
||||
|
||||
return true;
|
||||
Vec3f L = orig - center;
|
||||
float a = dir.dotProduct(dir);
|
||||
float b = 2 * dir.dotProduct(L);
|
||||
float c = L.dotProduct(L) - radius2;
|
||||
if (!solveQuadratic(a, b, c, t0, t1)) return false;
|
||||
#endif
|
||||
if (t0 > t1) std::swap(t0, t1);
|
||||
|
||||
if (t0 < 0) {
|
||||
t0 = t1; // if t0 is negative, let's use t1 instead
|
||||
if (t0 < 0) return false; // both t0 and t1 are negative
|
||||
}
|
||||
|
||||
t = t0;
|
||||
|
||||
return true;
|
||||
} */
|
||||
|
||||
// adapted -- assume that origin is inside sphere, return intersection of ray with edge of sphere
|
||||
vec3 sphereIntersect(vec3 origin, vec3 dir, vec3 center, float radius2)
|
||||
{
|
||||
float t0, t1; // solutions for t if the ray intersects
|
||||
{
|
||||
float t0, t1; // solutions for t if the ray intersects
|
||||
|
||||
vec3 L = center - origin;
|
||||
vec3 L = center - origin;
|
||||
float tca = dot(L,dir);
|
||||
|
||||
float d2 = dot(L,L) - tca * tca;
|
||||
|
||||
float thc = sqrt(radius2 - d2);
|
||||
t0 = tca - thc;
|
||||
t1 = tca + thc;
|
||||
float d2 = dot(L,L) - tca * tca;
|
||||
|
||||
float thc = sqrt(radius2 - d2);
|
||||
t0 = tca - thc;
|
||||
t1 = tca + thc;
|
||||
|
||||
vec3 v = origin + dir * t1;
|
||||
return v;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
void swap(inout float a, inout float b)
|
||||
{
|
||||
|
|
@ -305,17 +312,17 @@ void swap(inout float a, inout float b)
|
|||
// debug implementation, make no assumptions about origin
|
||||
void sphereIntersectDebug(vec3 origin, vec3 dir, vec3 center, float radius2, float depth, inout vec4 col)
|
||||
{
|
||||
float t[2]; // solutions for t if the ray intersects
|
||||
float t[2]; // solutions for t if the ray intersects
|
||||
|
||||
// geometric solution
|
||||
vec3 L = center - origin;
|
||||
vec3 L = center - origin;
|
||||
float tca = dot(L, dir);
|
||||
// if (tca < 0) return false;
|
||||
float d2 = dot(L, L) - tca * tca;
|
||||
if (d2 > radius2) return;
|
||||
float thc = sqrt(radius2 - d2);
|
||||
t[0] = tca - thc;
|
||||
t[1] = tca + thc;
|
||||
float d2 = dot(L, L) - tca * tca;
|
||||
if (d2 > radius2) return;
|
||||
float thc = sqrt(radius2 - d2);
|
||||
t[0] = tca - thc;
|
||||
t[1] = tca + thc;
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
|
|
@ -365,11 +372,11 @@ return texCUBE(envMap, ReflDirectionWS);
|
|||
// i - probe index in refBox/refSphere
|
||||
// d - distance to nearest wall in clip space
|
||||
// scale - scale of box, default 1.0
|
||||
vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale)
|
||||
vec3 boxIntersect(vec3 origin, vec3 dir, mat4 i, out float d, float scale)
|
||||
{
|
||||
// Intersection with OBB convert to unit box space
|
||||
// Transform in local unit parallax cube space (scaled and rotated)
|
||||
mat4 clipToLocal = refBox[i];
|
||||
mat4 clipToLocal = i;
|
||||
|
||||
vec3 RayLS = mat3(clipToLocal) * dir;
|
||||
vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz;
|
||||
|
|
@ -388,7 +395,7 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale)
|
|||
return IntersectPositionCS;
|
||||
}
|
||||
|
||||
vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d)
|
||||
vec3 boxIntersect(vec3 origin, vec3 dir, mat4 i, out float d)
|
||||
{
|
||||
return boxIntersect(origin, dir, i, d, 1.0);
|
||||
}
|
||||
|
|
@ -404,8 +411,8 @@ void debugBoxCol(vec3 ro, vec3 rd, float t, vec3 p, inout vec4 col)
|
|||
bool behind = dot(v,v) > dot(pos,pos);
|
||||
|
||||
float w = 0.25;
|
||||
|
||||
if (behind)
|
||||
|
||||
if (behind)
|
||||
{
|
||||
w *= 0.5;
|
||||
w /= (length(v)-length(pos))*0.5+1.0;
|
||||
|
|
@ -419,7 +426,7 @@ void debugBoxCol(vec3 ro, vec3 rd, float t, vec3 p, inout vec4 col)
|
|||
|
||||
// cribbed from https://iquilezles.org/articles/intersectors/
|
||||
// axis aligned box centered at the origin, with size boxSize
|
||||
void boxIntersectionDebug( in vec3 ro, in vec3 p, vec3 boxSize, inout vec4 col)
|
||||
void boxIntersectionDebug( in vec3 ro, in vec3 p, vec3 boxSize, inout vec4 col)
|
||||
{
|
||||
vec3 rd = normalize(p-ro);
|
||||
|
||||
|
|
@ -443,10 +450,10 @@ void boxIntersectionDebug( in vec3 ro, in vec3 p, vec3 boxSize, inout vec4 col)
|
|||
}
|
||||
|
||||
|
||||
void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col)
|
||||
void boxIntersectDebug(vec3 origin, vec3 pos, mat4 i, inout vec4 col)
|
||||
{
|
||||
mat4 clipToLocal = refBox[i];
|
||||
|
||||
mat4 clipToLocal = i;
|
||||
|
||||
// transform into unit cube space
|
||||
origin = (clipToLocal * vec4(origin, 1.0)).xyz;
|
||||
pos = (clipToLocal * vec4(pos, 1.0)).xyz;
|
||||
|
|
@ -462,16 +469,16 @@ void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col)
|
|||
// r - radius of probe influence volume
|
||||
// i - index of probe in refSphere
|
||||
// dw - distance weight
|
||||
float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw)
|
||||
float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, vec4 i, out float dw)
|
||||
{
|
||||
float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down)
|
||||
float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down)
|
||||
vec3 delta = pos.xyz - origin;
|
||||
float d2 = max(length(delta), 0.001);
|
||||
|
||||
float atten = 1.0 - max(d2 - r1, 0.0) / max((r - r1), 0.001);
|
||||
float w = 1.0 / d2;
|
||||
|
||||
w *= refParams[i].z;
|
||||
w *= i.z;
|
||||
|
||||
dw = w * atten * max(r, 1.0)*4;
|
||||
|
||||
|
|
@ -488,7 +495,7 @@ float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw
|
|||
// lod - which mip to sample (lower is higher res, sharper reflections)
|
||||
// c - center of probe
|
||||
// r2 - radius of probe squared
|
||||
// i - index of probe
|
||||
// i - index of probe
|
||||
vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c, int i)
|
||||
{
|
||||
// parallax adjustment
|
||||
|
|
@ -497,7 +504,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c,
|
|||
if (refIndex[i].w < 0)
|
||||
{ // box probe
|
||||
float d = 0;
|
||||
v = boxIntersect(pos, dir, i, d);
|
||||
v = boxIntersect(pos, dir, refBox[i], d);
|
||||
|
||||
w = max(d, 0.001);
|
||||
}
|
||||
|
|
@ -507,18 +514,18 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c,
|
|||
|
||||
float rr = r * r;
|
||||
|
||||
v = sphereIntersect(pos, dir, c,
|
||||
v = sphereIntersect(pos, dir, c,
|
||||
refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
|
||||
rr);
|
||||
|
||||
w = sphereWeight(pos, dir, refSphere[i].xyz, r, i, dw);
|
||||
w = sphereWeight(pos, dir, refSphere[i].xyz, r, refParams[i], dw);
|
||||
}
|
||||
|
||||
v -= c;
|
||||
vec3 d = normalize(v);
|
||||
|
||||
v = env_mat * v;
|
||||
|
||||
|
||||
vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod) * refParams[i].y;
|
||||
|
||||
return ret.rgb;
|
||||
|
|
@ -529,7 +536,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c,
|
|||
// dir - pixel normal
|
||||
// w - weight of sample (distance and angular attenuation)
|
||||
// dw - weight of sample (distance only)
|
||||
// i - index of probe
|
||||
// i - index of probe
|
||||
vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int i, vec3 amblit)
|
||||
{
|
||||
// parallax adjustment
|
||||
|
|
@ -537,7 +544,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int
|
|||
if (refIndex[i].w < 0)
|
||||
{
|
||||
float d = 0.0;
|
||||
v = boxIntersect(pos, dir, i, d, 3.0);
|
||||
v = boxIntersect(pos, dir, refBox[i], d, 3.0);
|
||||
w = max(d, 0.001);
|
||||
}
|
||||
else
|
||||
|
|
@ -547,16 +554,16 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int
|
|||
// pad sphere for manual probe extending into automatic probe space
|
||||
float rr = r * r;
|
||||
|
||||
v = sphereIntersect(pos, dir, c,
|
||||
v = sphereIntersect(pos, dir, c,
|
||||
refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
|
||||
rr);
|
||||
|
||||
w = sphereWeight(pos, dir, refSphere[i].xyz, r, i, dw);
|
||||
w = sphereWeight(pos, dir, refSphere[i].xyz, r, refParams[i], dw);
|
||||
}
|
||||
|
||||
v -= c;
|
||||
v = env_mat * v;
|
||||
|
||||
|
||||
vec3 col = textureLod(irradianceProbes, vec4(v.xyz, refIndex[i].x), 0).rgb * refParams[i].x;
|
||||
|
||||
col = mix(amblit, col, min(refParams[i].x, 1.0));
|
||||
|
|
@ -618,7 +625,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod)
|
|||
col[1] *= 1.0/wsum[1];
|
||||
col[0] = vec3(0);
|
||||
}
|
||||
|
||||
|
||||
return col[1]+col[0];
|
||||
}
|
||||
|
||||
|
|
@ -647,7 +654,7 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit)
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
float w = 0;
|
||||
float dw = 0;
|
||||
|
|
@ -677,10 +684,53 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit)
|
|||
col[1] *= 1.0/wsum[1];
|
||||
col[0] = vec3(0);
|
||||
}
|
||||
|
||||
|
||||
return col[1]+col[0];
|
||||
}
|
||||
|
||||
#if defined(HERO_PROBES)
|
||||
|
||||
uniform vec4 clipPlane;
|
||||
uniform samplerCubeArray heroProbes;
|
||||
|
||||
void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness)
|
||||
{
|
||||
float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w;
|
||||
float w = 0;
|
||||
float dw = 0;
|
||||
float falloffMult = 10;
|
||||
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
|
||||
if (heroShape < 1)
|
||||
{
|
||||
float d = 0;
|
||||
boxIntersect(pos, norm, heroBox, d, 1.0);
|
||||
|
||||
w = max(d, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
float r = heroSphere.w;
|
||||
|
||||
w = sphereWeight(pos, refnormpersp, heroSphere.xyz, r, vec4(1), dw);
|
||||
}
|
||||
|
||||
clipDist = clipDist * 0.95 + 0.05;
|
||||
clipDist = clamp(clipDist * falloffMult, 0, 1);
|
||||
w = clamp(w * falloffMult * clipDist, 0, 1);
|
||||
w = mix(0, w, clamp(glossiness - 0.75, 0, 1) * 4); // We only generate a quarter of the mips for the hero probes. Linearly interpolate between normal probes and hero probes based upon glossiness.
|
||||
glossenv = mix(glossenv, textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz, w);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit)
|
||||
{
|
||||
|
|
@ -712,6 +762,8 @@ void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,
|
|||
glossenv = mix(glossenv, ssr.rgb, ssr.a);
|
||||
}
|
||||
#endif
|
||||
|
||||
tapHeroProbe(glossenv, pos, norm, glossiness);
|
||||
}
|
||||
|
||||
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
||||
|
|
@ -747,7 +799,7 @@ void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)
|
|||
{
|
||||
if (refIndex[i].w < 0)
|
||||
{
|
||||
boxIntersectDebug(origin, pos, i, col);
|
||||
boxIntersectDebug(origin, pos, refBox[i], col);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -799,8 +851,9 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
|
|||
{
|
||||
float lod = (1.0-glossiness)*reflection_lods;
|
||||
glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (envIntensity > 0.0)
|
||||
{
|
||||
legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0);
|
||||
|
|
@ -826,6 +879,9 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
|
|||
}
|
||||
#endif
|
||||
|
||||
tapHeroProbe(glossenv, pos, norm, glossiness);
|
||||
tapHeroProbe(legacyenv, pos, norm, 1.0);
|
||||
|
||||
glossenv = clamp(glossenv, vec3(0), vec3(10));
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue