summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/cmake/VulkanGltf.cmake5
-rw-r--r--indra/llrender/llcubemaparray.cpp44
-rw-r--r--indra/llrender/llcubemaparray.h9
-rw-r--r--indra/newview/CMakeLists.txt1
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl167
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl7
-rw-r--r--indra/newview/llreflectionmapmanager.cpp50
-rw-r--r--indra/newview/llreflectionmapmanager.h1
-rw-r--r--indra/newview/llviewershadermgr.cpp12
-rw-r--r--indra/newview/llviewershadermgr.h1
11 files changed, 328 insertions, 7 deletions
diff --git a/indra/cmake/VulkanGltf.cmake b/indra/cmake/VulkanGltf.cmake
new file mode 100644
index 0000000000..94541d5307
--- /dev/null
+++ b/indra/cmake/VulkanGltf.cmake
@@ -0,0 +1,5 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+use_prebuilt_binary(vulkan_gltf)
+
diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp
index e4081c1154..438d92cdba 100644
--- a/indra/llrender/llcubemaparray.cpp
+++ b/indra/llrender/llcubemaparray.cpp
@@ -53,6 +53,50 @@ GLenum LLCubeMapArray::sTargets[6] =
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
};
+LLVector3 LLCubeMapArray::sLookVecs[6] =
+{
+ LLVector3(1, 0, 0),
+ LLVector3(-1, 0, 0),
+ LLVector3(0, 1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, 1),
+ LLVector3(0, 0, -1)
+};
+
+LLVector3 LLCubeMapArray::sUpVecs[6] =
+{
+ LLVector3(0, -1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, 1),
+ LLVector3(0, 0, -1),
+ LLVector3(0, -1, 0),
+ LLVector3(0, -1, 0)
+};
+
+LLVector3 LLCubeMapArray::sClipToCubeLookVecs[6] =
+{
+ LLVector3(0, 0, -1), //GOOD
+ LLVector3(0, 0, 1), //GOOD
+
+ LLVector3(1, 0, 0), // GOOD
+ LLVector3(1, 0, 0), // GOOD
+
+ LLVector3(1, 0, 0),
+ LLVector3(-1, 0, 0),
+};
+
+LLVector3 LLCubeMapArray::sClipToCubeUpVecs[6] =
+{
+ LLVector3(-1, 0, 0), //GOOD
+ LLVector3(1, 0, 0), //GOOD
+
+ LLVector3(0, 1, 0), // GOOD
+ LLVector3(0, -1, 0), // GOOD
+
+ LLVector3(0, 0, -1),
+ LLVector3(0, 0, 1)
+};
+
LLCubeMapArray::LLCubeMapArray()
: mTextureStage(0)
{
diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h
index 52e21f1dda..cbc0692afb 100644
--- a/indra/llrender/llcubemaparray.h
+++ b/indra/llrender/llcubemaparray.h
@@ -32,13 +32,20 @@
class LLVector3;
-// Environment map hack!
class LLCubeMapArray : public LLRefCount
{
public:
LLCubeMapArray();
static GLenum sTargets[6];
+
+ // look and up vectors for each cube face (agent space)
+ static LLVector3 sLookVecs[6];
+ static LLVector3 sUpVecs[6];
+
+ // look and up vectors for each cube face (clip space)
+ static LLVector3 sClipToCubeLookVecs[6];
+ static LLVector3 sClipToCubeUpVecs[6];
// allocate a cube map array
// res - resolution of each cube face
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 0d2b99a8cd..5e0d3b52b4 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -56,6 +56,7 @@ include(UnixInstall)
include(ViewerMiscLibs)
include(ViewerManager)
include(VisualLeakDetector)
+include(VulkanGltf)
include(ZLIB)
include(URIPARSER)
diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
new file mode 100644
index 0000000000..27008b8a1c
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
@@ -0,0 +1,167 @@
+/**
+ * @file radianceGenF.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]*/
+
+#define REFMAP_COUNT 256
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform samplerCubeArray reflectionProbes;
+
+VARYING vec3 vary_dir;
+
+// =============================================================================================================
+// Parts of this file are (c) 2018 Sascha Willems
+// SNIPPED FROM https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/prefilterenvmap.frag
+/*
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+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.
+*/
+// =============================================================================================================
+
+
+uniform float roughness;
+
+uniform int numSamples;
+
+const float PI = 3.1415926536;
+
+// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
+float random(vec2 co)
+{
+ float a = 12.9898;
+ float b = 78.233;
+ float c = 43758.5453;
+ float dt= dot(co.xy ,vec2(a,b));
+ float sn= mod(dt,3.14);
+ return fract(sin(sn) * c);
+}
+
+vec2 hammersley2d(uint i, uint N)
+{
+ // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+ uint bits = (i << 16u) | (i >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ float rdi = float(bits) * 2.3283064365386963e-10;
+ return vec2(float(i) /float(N), rdi);
+}
+
+// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
+vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
+{
+ // Maps a 2D point to a hemisphere with spread based on roughness
+ float alpha = roughness * roughness;
+ float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
+ float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
+ float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
+ vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
+
+ // Tangent space
+ vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ vec3 tangentX = normalize(cross(up, normal));
+ vec3 tangentY = normalize(cross(normal, tangentX));
+
+ // Convert to world Space
+ return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
+}
+
+// Normal Distribution function
+float D_GGX(float dotNH, float roughness)
+{
+ float alpha = roughness * roughness;
+ float alpha2 = alpha * alpha;
+ float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0;
+ return (alpha2)/(PI * denom*denom);
+}
+
+vec3 prefilterEnvMap(vec3 R, float roughness)
+{
+ vec3 N = R;
+ vec3 V = R;
+ vec3 color = vec3(0.0);
+ float totalWeight = 0.0;
+ float envMapDim = 256.0;
+ for(uint i = 0u; i < numSamples; i++) {
+ vec2 Xi = hammersley2d(i, numSamples);
+ vec3 H = importanceSample_GGX(Xi, roughness, N);
+ vec3 L = 2.0 * dot(V, H) * H - V;
+ float dotNL = clamp(dot(N, L), 0.0, 1.0);
+ if(dotNL > 0.0) {
+ // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/
+
+ float dotNH = clamp(dot(N, H), 0.0, 1.0);
+ float dotVH = clamp(dot(V, H), 0.0, 1.0);
+
+ // Probability Distribution Function
+ float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001;
+ // Slid angle of current smple
+ float omegaS = 1.0 / (float(numSamples) * pdf);
+ // Solid angle of 1 pixel across all cube faces
+ float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);
+ // Biased (+1.0) mip level for better result
+ float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f);
+ color += textureLod(reflectionProbes, vec4(L,REFMAP_COUNT), mipLevel).rgb * dotNL;
+ totalWeight += dotNL;
+
+ }
+ }
+ return (color / totalWeight);
+}
+
+void main()
+{
+ vec3 N = normalize(vary_dir);
+ frag_color = vec4(prefilterEnvMap(N, roughness), 1.0);
+}
+// =============================================================================================================
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl
new file mode 100644
index 0000000000..5f5d9396ff
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl
@@ -0,0 +1,38 @@
+/**
+ * @file radianceGenV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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 mat4 modelview_matrix;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec3 vary_dir;
+
+void main()
+{
+ gl_Position = vec4(position, 1.0);
+
+ vary_dir = vec3(modelview_matrix * vec4(position, 1.0)).xyz;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 4a40f691be..40378b49ea 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -334,8 +334,9 @@ vec3 tapRefMap(vec3 pos, vec3 dir, float lod, vec3 c, float r2, int i)
v -= c;
v = env_mat * v;
{
- float min_lod = textureQueryLod(reflectionProbes,v).y; // lower is higher res
- return textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), max(min_lod, lod)).rgb;
+ //float min_lod = textureQueryLod(reflectionProbes,v).y; // lower is higher res
+ //return textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), max(min_lod, lod)).rgb;
+ return textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod).rgb;
//return texture(reflectionProbes, vec4(v.xyz, refIndex[i].x)).rgb;
}
}
@@ -450,7 +451,7 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 l
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
- ambenv = sampleProbeAmbient(pos, norm, reflection_lods-1);
+ ambenv = sampleProbeAmbient(pos, norm, reflection_lods-2);
if (glossiness > 0.0)
{
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 752427f0fa..025b8457c1 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -80,7 +80,8 @@ void LLReflectionMapManager::update()
if (mTexture.isNull())
{
mTexture = new LLCubeMapArray();
- mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT);
+ // store LL_REFLECTION_PROBE_COUNT+1 cube maps, final cube map is used for render target and radiance map generation source)
+ mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT+2);
}
if (!mRenderTarget.isComplete())
@@ -395,7 +396,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
gPipeline.mRT = &gPipeline.mMainRT;
mRenderTarget.flush();
- // generate mipmaps
+ // downsample to placeholder map
{
LLGLDepthTest depth(GL_FALSE, GL_FALSE);
LLGLDisable cull(GL_CULL_FACE);
@@ -451,7 +452,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
if (mip >= 0)
{
mTexture->bind(0);
- glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
+ //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, LL_REFLECTION_PROBE_COUNT * 6 + face, 0, 0, res, res);
mTexture->unbind();
}
mMipChain[i].flush();
@@ -463,6 +465,48 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
gReflectionMipProgram.unbind();
}
+
+ if (face == 5)
+ {
+ //generate radiance map
+ gRadianceGenProgram.bind();
+ S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ mTexture->bind(channel);
+
+ for (int cf = 0; cf < 6; ++cf)
+ { // for each cube face
+ LLCoordFrame frame;
+ frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
+
+ F32 mat[16];
+ frame.getOpenGLRotation(mat);
+ gGL.loadMatrix(mat);
+
+ for (int i = 0; i < mMipChain.size(); ++i)
+ {
+ mMipChain[i].bindTarget();
+ static LLStaticHashedString sRoughness("roughness");
+ static LLStaticHashedString sNumSamples("numSamples");
+
+ gRadianceGenProgram.uniform1i(sNumSamples, 32);
+ gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1));
+
+ gGL.begin(gGL.QUADS);
+ gGL.vertex3f(-1, -1, -1);
+ gGL.vertex3f(1, -1, -1);
+ gGL.vertex3f(1, 1, -1);
+ gGL.vertex3f(-1, 1, -1);
+ gGL.end();
+ gGL.flush();
+
+
+
+ S32 res = mMipChain[i].getWidth();
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
+ mMipChain[i].flush();
+ }
+ }
+ }
}
void LLReflectionMapManager::rebuild()
diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h
index 3b5cdc5520..551a461e63 100644
--- a/indra/newview/llreflectionmapmanager.h
+++ b/indra/newview/llreflectionmapmanager.h
@@ -29,6 +29,7 @@
#include "llreflectionmap.h"
#include "llrendertarget.h"
#include "llcubemaparray.h"
+#include "llcubemap.h"
class LLSpatialGroup;
class LLViewerObject;
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index d4ee754d5c..d5ca915da5 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -85,6 +85,7 @@ LLGLSLShader gCustomAlphaProgram;
LLGLSLShader gGlowCombineProgram;
LLGLSLShader gSplatTextureRectProgram;
LLGLSLShader gReflectionMipProgram;
+LLGLSLShader gRadianceGenProgram;
LLGLSLShader gGlowCombineFXAAProgram;
LLGLSLShader gTwoTextureAddProgram;
LLGLSLShader gTwoTextureCompareProgram;
@@ -762,6 +763,7 @@ void LLViewerShaderMgr::unloadShaders()
gGlowCombineProgram.unload();
gSplatTextureRectProgram.unload();
gReflectionMipProgram.unload();
+ gRadianceGenProgram.unload();
gGlowCombineFXAAProgram.unload();
gTwoTextureAddProgram.unload();
gTwoTextureCompareProgram.unload();
@@ -3821,6 +3823,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
}
}
+ if (success)
+ {
+ gRadianceGenProgram.mName = "Radiance Gen Shader";
+ gRadianceGenProgram.mShaderFiles.clear();
+ gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenV.glsl", GL_VERTEX_SHADER_ARB));
+ gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gRadianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gRadianceGenProgram.createShader(NULL, NULL);
+ }
+
if( !success )
{
mShaderLevel[SHADER_INTERFACE] = 0;
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index f0187db302..fa5b2121b9 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -162,6 +162,7 @@ extern LLGLSLShader gCustomAlphaProgram;
extern LLGLSLShader gGlowCombineProgram;
extern LLGLSLShader gSplatTextureRectProgram;
extern LLGLSLShader gReflectionMipProgram;
+extern LLGLSLShader gRadianceGenProgram;
extern LLGLSLShader gGlowCombineFXAAProgram;
extern LLGLSLShader gDebugProgram;
extern LLGLSLShader gClipProgram;