Merge branch 'DRTVWR-559' of https://bitbucket.org/lindenlab/viewer
# Conflicts: # indra/llrender/llrender2dutils.cpp # indra/newview/llreflectionmapmanager.cpp # indra/newview/llviewershadermgr.cpp # indra/newview/llviewershadermgr.hmaster
commit
87501c03ae
|
|
@ -1576,7 +1576,14 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
|||
}
|
||||
else
|
||||
{ // platforms with working drivers...
|
||||
glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data);
|
||||
// We just want GL_ALPHA, but that isn't supported in OGL core profile 4.
|
||||
static const size_t TEMP_BYTES_PER_PIXEL = 4;
|
||||
U8* temp_data = (U8*)ll_aligned_malloc_32(mem_size * TEMP_BYTES_PER_PIXEL);
|
||||
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, temp_data);
|
||||
for (size_t pixel = 0; pixel < pixels; pixel++) {
|
||||
alpha_data[pixel] = temp_data[(pixel * TEMP_BYTES_PER_PIXEL) + 3];
|
||||
}
|
||||
ll_aligned_free_32(temp_data);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1067,13 +1067,6 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
|
|||
#endif
|
||||
|
||||
#if defined(TRACY_ENABLE) && LL_PROFILER_ENABLE_TRACY_OPENGL
|
||||
// Tracy uses the following:
|
||||
// glGenQueries
|
||||
// glGetQueryiv
|
||||
// glGetQueryObjectiv
|
||||
#define glGenQueries glGenQueriesARB
|
||||
#define glGetQueryiv glGetQueryivARB
|
||||
#define glGetQueryObjectiv glGetQueryObjectivARB
|
||||
#include <tracy/TracyOpenGL.hpp>
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -227,7 +227,6 @@ void LLGLSLShader::stopProfile(U32 count, U32 mode)
|
|||
|
||||
void LLGLSLShader::placeProfileQuery()
|
||||
{
|
||||
#if 1 || !LL_DARWIN
|
||||
if (mTimerQuery == 0)
|
||||
{
|
||||
glGenQueries(1, &mSamplesQuery);
|
||||
|
|
@ -269,12 +268,10 @@ void LLGLSLShader::placeProfileQuery()
|
|||
|
||||
glBeginQuery(GL_SAMPLES_PASSED, mSamplesQuery);
|
||||
glBeginQuery(GL_TIME_ELAPSED, mTimerQuery);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
|
||||
{
|
||||
#if !LL_DARWIN
|
||||
glEndQuery(GL_TIME_ELAPSED);
|
||||
glEndQuery(GL_SAMPLES_PASSED);
|
||||
|
||||
|
|
@ -307,7 +304,6 @@ void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
|
|||
|
||||
sTotalDrawCalls++;
|
||||
mDrawCalls++;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -679,7 +675,6 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
|
|||
|
||||
|
||||
glGetActiveUniform(mProgramObject, index, 1024, &length, &size, &type, (GLchar *)name);
|
||||
#if !LL_DARWIN
|
||||
if (size > 0)
|
||||
{
|
||||
switch(type)
|
||||
|
|
@ -721,7 +716,6 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
|
|||
}
|
||||
mTotalUniformSize += size;
|
||||
}
|
||||
#endif
|
||||
|
||||
S32 location = glGetUniformLocation(mProgramObject, name);
|
||||
if (location != -1)
|
||||
|
|
|
|||
|
|
@ -897,11 +897,11 @@ void LLRender::init(bool needs_vertex_buffer)
|
|||
}
|
||||
|
||||
// <FS:Ansariel> Don't ignore OpenGL max line width
|
||||
GLint range[2];
|
||||
glGetIntegerv(GL_ALIASED_LINE_WIDTH_RANGE, range);
|
||||
GLfloat range[2];
|
||||
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
|
||||
stop_glerror();
|
||||
mMaxLineWidthAliased = F32(range[1]);
|
||||
glGetIntegerv(GL_SMOOTH_LINE_WIDTH_RANGE, range);
|
||||
glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, range);
|
||||
stop_glerror();
|
||||
mMaxLineWidthSmooth = F32(range[1]);
|
||||
// </FS:Ansariel>
|
||||
|
|
|
|||
|
|
@ -1966,7 +1966,15 @@ void LLRender2D::setLineWidth(F32 width)
|
|||
{
|
||||
// <FS> Line width OGL core profile fix by Rye Mutt
|
||||
//gGL.flush();
|
||||
//glLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f));
|
||||
//// If outside the allowed range, glLineWidth fails with "invalid value".
|
||||
//// On Darwin, the range is [1, 1].
|
||||
//static GLfloat range[2]{0.0};
|
||||
//if (range[1] == 0)
|
||||
//{
|
||||
// glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, range);
|
||||
//}
|
||||
//width *= lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f);
|
||||
//glLineWidth(llclamp(width, range[0], range[1]));
|
||||
gGL.setLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -301,13 +301,11 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
|
|||
mTex.push_back(tex);
|
||||
mInternalFormat.push_back(color_fmt);
|
||||
|
||||
#if !LL_DARWIN
|
||||
if (gDebugGL)
|
||||
{ //bind and unbind to validate target
|
||||
bindTarget();
|
||||
flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return true;
|
||||
|
|
@ -471,6 +469,7 @@ void LLRenderTarget::release()
|
|||
|
||||
void LLRenderTarget::bindTarget()
|
||||
{
|
||||
LL_PROFILE_GPU_ZONE("bindTarget");
|
||||
llassert(mFBO);
|
||||
|
||||
if (mFBO)
|
||||
|
|
@ -577,6 +576,7 @@ void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilt
|
|||
|
||||
void LLRenderTarget::flush(bool fetch_depth)
|
||||
{
|
||||
LL_PROFILE_GPU_ZONE("rt flush");
|
||||
gGL.flush();
|
||||
llassert(mFBO);
|
||||
if (!mFBO)
|
||||
|
|
|
|||
|
|
@ -1330,6 +1330,7 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("diffuseRect");
|
||||
mReservedUniforms.push_back("specularRect");
|
||||
mReservedUniforms.push_back("emissiveRect");
|
||||
mReservedUniforms.push_back("brdfLut");
|
||||
mReservedUniforms.push_back("noiseMap");
|
||||
mReservedUniforms.push_back("lightFunc");
|
||||
mReservedUniforms.push_back("lightMap");
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ public:
|
|||
DEFERRED_DIFFUSE, // "diffuseRect"
|
||||
DEFERRED_SPECULAR, // "specularRect"
|
||||
DEFERRED_EMISSIVE, // "emissiveRect"
|
||||
DEFERRED_BRDF_LUT, // "brdfLut"
|
||||
DEFERRED_NOISE, // "noiseMap"
|
||||
DEFERRED_LIGHTFUNC, // "lightFunc"
|
||||
DEFERRED_LIGHT, // "lightMap"
|
||||
|
|
|
|||
|
|
@ -1342,7 +1342,6 @@ void LLVertexBuffer::setupVertexArray()
|
|||
|
||||
if (attrib_integer[i])
|
||||
{
|
||||
#if !LL_DARWIN
|
||||
//glVertexattribIPointer requires GLSL 1.30 or later
|
||||
if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
|
||||
{
|
||||
|
|
@ -1351,9 +1350,8 @@ void LLVertexBuffer::setupVertexArray()
|
|||
// Cast via intptr_t to make it painfully obvious to the
|
||||
// compiler that we're doing this intentionally.
|
||||
glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i],
|
||||
reinterpret_cast<const GLvoid*>(intptr_t(mOffsets[i])));
|
||||
reinterpret_cast<const GLvoid*>(intptr_t(mOffsets[i])));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2392,11 +2390,9 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
|
|||
if (data_mask & MAP_TEXTURE_INDEX &&
|
||||
(gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later
|
||||
{
|
||||
#if !LL_DARWIN
|
||||
S32 loc = TYPE_TEXTURE_INDEX;
|
||||
void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
|
||||
glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
|
||||
#endif
|
||||
}
|
||||
if (data_mask & MAP_VERTEX)
|
||||
{
|
||||
|
|
@ -2487,11 +2483,9 @@ void LLVertexBuffer::setupVertexBufferFast(U32 data_mask)
|
|||
}
|
||||
if (data_mask & MAP_TEXTURE_INDEX)
|
||||
{
|
||||
#if !LL_DARWIN
|
||||
S32 loc = TYPE_TEXTURE_INDEX;
|
||||
void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12);
|
||||
glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
|
||||
#endif
|
||||
}
|
||||
if (data_mask & MAP_VERTEX)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,9 +23,35 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
/* Parts of this file are taken from Sascha Willem's Vulkan GLTF refernce implementation
|
||||
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 sampler2DRect normalMap;
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2D projectionMap; // rgba
|
||||
uniform sampler2D brdfLut;
|
||||
|
||||
// projected lighted params
|
||||
uniform mat4 proj_mat; //screen space to light space projector
|
||||
|
|
@ -322,221 +348,150 @@ vec3 hue_to_rgb(float hue)
|
|||
|
||||
// PBR Utils
|
||||
|
||||
// ior Index of Refraction, normally 1.5
|
||||
// returns reflect0
|
||||
float calcF0(float ior)
|
||||
vec2 BRDF(float NoV, float roughness)
|
||||
{
|
||||
float f0 = (1.0 - ior) / (1.0 + ior);
|
||||
return f0 * f0;
|
||||
}
|
||||
|
||||
vec3 fresnel(float vh, vec3 f0, vec3 f90 )
|
||||
{
|
||||
float x = 1.0 - abs(vh);
|
||||
float x2 = x*x;
|
||||
float x5 = x2*x2*x;
|
||||
vec3 fr = f0 + (f90 - f0)*x5;
|
||||
return fr;
|
||||
}
|
||||
|
||||
vec3 fresnelSchlick( vec3 reflect0, vec3 reflect90, float vh)
|
||||
{
|
||||
return reflect0 + (reflect90 - reflect0) * pow(clamp(1.0 - vh, 0.0, 1.0), 5.0);
|
||||
}
|
||||
|
||||
// Approximate Environment BRDF
|
||||
vec2 getGGXApprox( vec2 uv )
|
||||
{
|
||||
// Reference: Physically Based Shading on Mobile
|
||||
// https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile
|
||||
// EnvBRDFApprox( vec3 SpecularColor, float Roughness, float NoV )
|
||||
float nv = uv.x;
|
||||
float roughness = uv.y;
|
||||
|
||||
const vec4 c0 = vec4( -1, -0.0275, -0.572, 0.022 );
|
||||
const vec4 c1 = vec4( 1, 0.0425, 1.04 , -0.04 );
|
||||
vec4 r = roughness * c0 + c1;
|
||||
float a004 = min( r.x * r.x, exp2( -9.28 * nv ) ) * r.x + r.y;
|
||||
vec2 ScaleBias = vec2( -1.04, 1.04 ) * a004 + r.zw;
|
||||
return ScaleBias;
|
||||
}
|
||||
|
||||
#define PBR_USE_GGX_APPROX 1
|
||||
vec2 getGGX( vec2 brdfPoint )
|
||||
{
|
||||
#if PBR_USE_GGX_APPROX
|
||||
return getGGXApprox( brdfPoint);
|
||||
#else
|
||||
return texture2D(GGXLUT, brdfPoint).rg; // TODO: use GGXLUT
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Reference: float getRangeAttenuation(float range, float distance)
|
||||
float getLightAttenuationPointSpot(float range, float distance)
|
||||
{
|
||||
#if 1
|
||||
return distance;
|
||||
#else
|
||||
float range2 = pow(range, 2.0);
|
||||
|
||||
// support negative range as unlimited
|
||||
if (range <= 0.0)
|
||||
{
|
||||
return 1.0 / range2;
|
||||
}
|
||||
|
||||
return max(min(1.0 - pow(distance / range, 4.0), 1.0), 0.0) / range2;
|
||||
#endif
|
||||
}
|
||||
|
||||
vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance)
|
||||
{
|
||||
float rangeAttenuation = getLightAttenuationPointSpot(lightRange, lightDistance);
|
||||
return rangeAttenuation * lightColor;
|
||||
}
|
||||
|
||||
float getLightAttenuationSpot(vec3 spotDirection)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v)
|
||||
{
|
||||
float spotAttenuation = getLightAttenuationSpot(-v);
|
||||
return spotAttenuation * getLightIntensityPoint( lightColor, lightRange, lightDistance );
|
||||
}
|
||||
|
||||
// NOTE: This is different from the GGX texture
|
||||
float D_GGX( float nh, float alphaRough )
|
||||
{
|
||||
float rough2 = alphaRough * alphaRough;
|
||||
float f = (nh * nh) * (rough2 - 1.0) + 1.0;
|
||||
return rough2 / (M_PI * f * f);
|
||||
}
|
||||
|
||||
// NOTE: This is different from the GGX texture
|
||||
// See:
|
||||
// Real Time Rendering, 4th Edition
|
||||
// Page 341
|
||||
// Equation 9.43
|
||||
// Also see:
|
||||
// https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/geometricshadowing(specularg)
|
||||
// 4.4.2 Geometric Shadowing (specular G)
|
||||
float V_GGX( float nl, float nv, float alphaRough )
|
||||
{
|
||||
#if 1
|
||||
// Note: When roughness is zero, has discontuinity in the bottom hemisphere
|
||||
float rough2 = alphaRough * alphaRough;
|
||||
float ggxv = nl * sqrt(nv * nv * (1.0 - rough2) + rough2);
|
||||
float ggxl = nv * sqrt(nl * nl * (1.0 - rough2) + rough2);
|
||||
|
||||
float ggx = ggxv + ggxl;
|
||||
if (ggx > 0.0)
|
||||
{
|
||||
return 0.5 / ggx;
|
||||
}
|
||||
return 0.0;
|
||||
#else
|
||||
// See: smithVisibility_GGXCorrelated, V_SmithCorrelated, etc.
|
||||
float rough2 = alphaRough * alphaRough;
|
||||
float ggxv = nl * sqrt(nv * (nv - rough2 * nv) + rough2);
|
||||
float ggxl = nv * sqrt(nl * (nl - rough2 * nl) + rough2);
|
||||
return 0.5 / (ggxv + ggxl);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// NOTE: Assumes a hard-coded IOR = 1.5
|
||||
void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight )
|
||||
{
|
||||
float metal = packedORM.b;
|
||||
c_diff = mix(diffuse, vec3(0), metal);
|
||||
float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics)
|
||||
reflect0 = vec3(0.04); // -> incidence reflectance 0.04
|
||||
// reflect0 = vec3(calcF0(IOR));
|
||||
reflect0 = mix(reflect0, diffuse, metal); // reflect at 0 degrees
|
||||
reflect90 = vec3(1); // reflect at 90 degrees
|
||||
specWeight = 1.0;
|
||||
|
||||
// When roughness is zero blender shows a tiny specular
|
||||
float perceptualRough = max(packedORM.g, 0.1);
|
||||
alphaRough = perceptualRough * perceptualRough;
|
||||
}
|
||||
|
||||
vec3 BRDFDiffuse(vec3 color)
|
||||
{
|
||||
return color * ONE_OVER_PI;
|
||||
}
|
||||
|
||||
vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh )
|
||||
{
|
||||
return (1.0 - fresnelSchlick( reflect0, reflect90, vh)) * BRDFDiffuse(c_diff);
|
||||
}
|
||||
|
||||
vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRough, float specWeight, float vh, float nl, float nv, float nh )
|
||||
{
|
||||
vec3 fresnel = fresnelSchlick( reflect0, reflect90, vh ); // Fresnel
|
||||
float vis = V_GGX( nl, nv, alphaRough ); // Visibility
|
||||
float d = D_GGX( nh, alphaRough ); // Distribution
|
||||
return fresnel * vis * d;
|
||||
return texture(brdfLut, vec2(NoV, roughness)).rg;
|
||||
}
|
||||
|
||||
// set colorDiffuse and colorSpec to the results of GLTF PBR style IBL
|
||||
void pbrIbl(out vec3 colorDiffuse, // diffuse color output
|
||||
out vec3 colorSpec, // specular color output,
|
||||
vec3 pbrIbl(vec3 diffuseColor,
|
||||
vec3 specularColor,
|
||||
vec3 radiance, // radiance map sample
|
||||
vec3 irradiance, // irradiance map sample
|
||||
float ao, // ambient occlusion factor
|
||||
float nv, // normal dot view vector
|
||||
float perceptualRough, // roughness factor
|
||||
float gloss, // 1.0 - roughness factor
|
||||
vec3 reflect0, // see also: initMaterial
|
||||
vec3 c_diff)
|
||||
float perceptualRough)
|
||||
{
|
||||
// Common to RadianceGGX and RadianceLambertian
|
||||
vec2 brdfPoint = clamp(vec2(nv, perceptualRough), vec2(0,0), vec2(1,1));
|
||||
vec2 vScaleBias = getGGX( brdfPoint); // Environment BRDF: scale and bias applied to reflect0
|
||||
vec3 fresnelR = max(vec3(gloss), reflect0) - reflect0; // roughness dependent fresnel
|
||||
vec3 kSpec = reflect0 + fresnelR*pow(1.0 - nv, 5.0);
|
||||
// retrieve a scale and bias to F0. See [1], Figure 3
|
||||
vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough);
|
||||
vec3 diffuseLight = irradiance;
|
||||
vec3 specularLight = radiance;
|
||||
|
||||
vec3 diffuse = diffuseLight * diffuseColor;
|
||||
vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
|
||||
|
||||
vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y;
|
||||
colorSpec = radiance * FssEssGGX;
|
||||
//specular *= 1.5;
|
||||
|
||||
// Reference: getIBLRadianceLambertian fs
|
||||
vec3 FssEssLambert = kSpec * vScaleBias.x + vScaleBias.y; // NOTE: Very similar to FssEssRadiance but with extra specWeight term
|
||||
float Ems = 1.0 - (vScaleBias.x + vScaleBias.y);
|
||||
vec3 avg = (reflect0 + (1.0 - reflect0) / 21.0);
|
||||
vec3 AvgEms = avg * Ems;
|
||||
vec3 FmsEms = AvgEms * FssEssLambert / (1.0 - AvgEms);
|
||||
vec3 kDiffuse = c_diff * (1.0 - FssEssLambert + FmsEms);
|
||||
colorDiffuse = (FmsEms + kDiffuse) * irradiance;
|
||||
|
||||
colorDiffuse *= ao;
|
||||
colorSpec *= ao;
|
||||
return (diffuse + specular) * ao;
|
||||
}
|
||||
|
||||
void pbrDirectionalLight(inout vec3 colorDiffuse,
|
||||
inout vec3 colorSpec,
|
||||
vec3 sunlit,
|
||||
float scol,
|
||||
vec3 reflect0,
|
||||
vec3 reflect90,
|
||||
vec3 c_diff,
|
||||
float alphaRough,
|
||||
float vh,
|
||||
float nl,
|
||||
float nv,
|
||||
float nh)
|
||||
// Encapsulate the various inputs used by the various functions in the shading equation
|
||||
// We store values in this struct to simplify the integration of alternative implementations
|
||||
// of the shading terms, outlined in the Readme.MD Appendix.
|
||||
struct PBRInfo
|
||||
{
|
||||
float scale = 16.0;
|
||||
vec3 sunColor = sunlit * scale;
|
||||
float NdotL; // cos angle between normal and light direction
|
||||
float NdotV; // cos angle between normal and view direction
|
||||
float NdotH; // cos angle between normal and half vector
|
||||
float LdotH; // cos angle between light direction and half vector
|
||||
float VdotH; // cos angle between view direction and half vector
|
||||
float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)
|
||||
float metalness; // metallic value at the surface
|
||||
vec3 reflectance0; // full reflectance color (normal incidence angle)
|
||||
vec3 reflectance90; // reflectance color at grazing angle
|
||||
float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])
|
||||
vec3 diffuseColor; // color contribution from diffuse lighting
|
||||
vec3 specularColor; // color contribution from specular lighting
|
||||
};
|
||||
|
||||
// scol = sun shadow
|
||||
vec3 intensity = sunColor * nl * scol;
|
||||
vec3 sunDiffuse = intensity * BRDFLambertian (reflect0, reflect90, c_diff , 1.0, vh);
|
||||
vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, 1.0, vh, nl, nv, nh);
|
||||
|
||||
colorDiffuse += sunDiffuse;
|
||||
colorSpec += sunSpec;
|
||||
// Basic Lambertian diffuse
|
||||
// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog
|
||||
// See also [1], Equation 1
|
||||
vec3 diffuse(PBRInfo pbrInputs)
|
||||
{
|
||||
return pbrInputs.diffuseColor / M_PI;
|
||||
}
|
||||
|
||||
// The following equation models the Fresnel reflectance term of the spec equation (aka F())
|
||||
// Implementation of fresnel from [4], Equation 15
|
||||
vec3 specularReflection(PBRInfo pbrInputs)
|
||||
{
|
||||
return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
|
||||
}
|
||||
|
||||
// This calculates the specular geometric attenuation (aka G()),
|
||||
// where rougher material will reflect less light back to the viewer.
|
||||
// This implementation is based on [1] Equation 4, and we adopt their modifications to
|
||||
// alphaRoughness as input as originally proposed in [2].
|
||||
float geometricOcclusion(PBRInfo pbrInputs)
|
||||
{
|
||||
float NdotL = pbrInputs.NdotL;
|
||||
float NdotV = pbrInputs.NdotV;
|
||||
float r = pbrInputs.alphaRoughness;
|
||||
|
||||
float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
|
||||
float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
|
||||
return attenuationL * attenuationV;
|
||||
}
|
||||
|
||||
// The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D())
|
||||
// Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz
|
||||
// Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3.
|
||||
float microfacetDistribution(PBRInfo pbrInputs)
|
||||
{
|
||||
float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;
|
||||
float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
|
||||
return roughnessSq / (M_PI * f * f);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
// make sure specular highlights from punctual lights don't fall off of polished surfaces
|
||||
perceptualRoughness = max(perceptualRoughness, 8.0/255.0);
|
||||
|
||||
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
||||
|
||||
// Compute reflectance.
|
||||
float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
||||
|
||||
// For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect.
|
||||
// For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%.
|
||||
float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
||||
vec3 specularEnvironmentR0 = specularColor.rgb;
|
||||
vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
|
||||
|
||||
vec3 h = normalize(l+v); // Half vector between both l and v
|
||||
vec3 reflection = -normalize(reflect(v, n));
|
||||
reflection.y *= -1.0f;
|
||||
|
||||
float NdotL = clamp(dot(n, l), 0.001, 1.0);
|
||||
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
||||
float NdotH = clamp(dot(n, h), 0.0, 1.0);
|
||||
float LdotH = clamp(dot(l, h), 0.0, 1.0);
|
||||
float VdotH = clamp(dot(v, h), 0.0, 1.0);
|
||||
|
||||
PBRInfo pbrInputs = PBRInfo(
|
||||
NdotL,
|
||||
NdotV,
|
||||
NdotH,
|
||||
LdotH,
|
||||
VdotH,
|
||||
perceptualRoughness,
|
||||
metallic,
|
||||
specularEnvironmentR0,
|
||||
specularEnvironmentR90,
|
||||
alphaRoughness,
|
||||
diffuseColor,
|
||||
specularColor
|
||||
);
|
||||
|
||||
// Calculate the shading terms for the microfacet specular shading model
|
||||
vec3 F = specularReflection(pbrInputs);
|
||||
float G = geometricOcclusion(pbrInputs);
|
||||
float D = microfacetDistribution(pbrInputs);
|
||||
|
||||
const vec3 u_LightColor = vec3(1.0);
|
||||
|
||||
// Calculation of analytical lighting contribution
|
||||
vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
|
||||
vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
|
||||
// Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
|
||||
vec3 color = NdotL * u_LightColor * (diffuseContrib + specContrib);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
/**
|
||||
* @file class1/deferred/genbrdflut.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$
|
||||
*/
|
||||
|
||||
/* Taken from Sascha Willem's Vulkan GLTF refernce implementation
|
||||
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.
|
||||
*/
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
VARYING vec2 vary_uv;
|
||||
|
||||
out vec4 outColor;
|
||||
|
||||
#define NUM_SAMPLES 1024
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Geometric Shadowing function
|
||||
float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness)
|
||||
{
|
||||
float k = (roughness * roughness) / 2.0;
|
||||
float GL = dotNL / (dotNL * (1.0 - k) + k);
|
||||
float GV = dotNV / (dotNV * (1.0 - k) + k);
|
||||
return GL * GV;
|
||||
}
|
||||
|
||||
vec2 BRDF(float NoV, float roughness)
|
||||
{
|
||||
// Normal always points along z-axis for the 2D lookup
|
||||
const vec3 N = vec3(0.0, 0.0, 1.0);
|
||||
vec3 V = vec3(sqrt(1.0 - NoV*NoV), 0.0, NoV);
|
||||
|
||||
vec2 LUT = vec2(0.0);
|
||||
for(uint i = 0u; i < NUM_SAMPLES; i++) {
|
||||
vec2 Xi = hammersley2d(i, NUM_SAMPLES);
|
||||
vec3 H = importanceSample_GGX(Xi, roughness, N);
|
||||
vec3 L = 2.0 * dot(V, H) * H - V;
|
||||
|
||||
float dotNL = max(dot(N, L), 0.0);
|
||||
float dotNV = max(dot(N, V), 0.0);
|
||||
float dotVH = max(dot(V, H), 0.0);
|
||||
float dotNH = max(dot(H, N), 0.0);
|
||||
|
||||
if (dotNL > 0.0) {
|
||||
float G = G_SchlicksmithGGX(dotNL, dotNV, roughness);
|
||||
float G_Vis = (G * dotVH) / (dotNH * dotNV);
|
||||
float Fc = pow(1.0 - dotVH, 5.0);
|
||||
LUT += vec2((1.0 - Fc) * G_Vis, Fc * G_Vis);
|
||||
}
|
||||
}
|
||||
return LUT / float(NUM_SAMPLES);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
outColor = vec4(BRDF(vary_uv.s, 1.0-vary_uv.t), 0.0, 1.0);
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* @file class3\deferred\genbrdflutV.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$
|
||||
*/
|
||||
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
|
||||
VARYING vec2 vary_uv;
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
vary_uv = position.xy*0.5+0.5;
|
||||
|
||||
gl_Position = vec4(position.xyz, 1.0);
|
||||
}
|
||||
|
|
@ -92,86 +92,68 @@ vec3 srgb_to_linear(vec3 c);
|
|||
vec3 linear_to_srgb(vec3 c);
|
||||
|
||||
// These are in deferredUtil.glsl but we can't set: mFeatures.isDeferred to include it
|
||||
vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
|
||||
vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
|
||||
void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
|
||||
vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
|
||||
vec3 scaleSoftClipFrag(vec3 l);
|
||||
|
||||
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);
|
||||
vec2 getGGX( vec2 brdfPoint );
|
||||
void initMaterial( vec3 diffuse, vec3 packedORM,
|
||||
out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
|
||||
float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
|
||||
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv,
|
||||
vec3 pos, vec3 norm, float glossiness, float envIntensity);
|
||||
|
||||
void pbrDirectionalLight(inout vec3 colorDiffuse,
|
||||
inout vec3 colorSpec,
|
||||
vec3 sunlit,
|
||||
float scol,
|
||||
vec3 reflect0,
|
||||
vec3 reflect90,
|
||||
vec3 c_diff,
|
||||
float alphaRough,
|
||||
float vh,
|
||||
float nl,
|
||||
float nv,
|
||||
float nh);
|
||||
|
||||
void pbrIbl(out vec3 colorDiffuse, // diffuse color output
|
||||
out vec3 colorSpec, // specular color output,
|
||||
// PBR interface
|
||||
vec3 pbrIbl(vec3 diffuseColor,
|
||||
vec3 specularColor,
|
||||
vec3 radiance, // radiance map sample
|
||||
vec3 irradiance, // irradiance map sample
|
||||
float ao, // ambient occlusion factor
|
||||
float nv,
|
||||
float perceptualRough, // roughness factor
|
||||
float gloss, // 1.0 - roughness factor
|
||||
vec3 reflect0,
|
||||
vec3 c_diff);
|
||||
float nv, // normal dot view vector
|
||||
float perceptualRoughness);
|
||||
|
||||
// lp = light position
|
||||
// la = linear attenuation, light radius
|
||||
// fa = falloff
|
||||
// See: LLRender::syncLightState()
|
||||
vec3 calcPointLightOrSpotLight(vec3 reflect0, vec3 reflect90, float alphaRough, vec3 c_diff,
|
||||
vec3 lightColor, vec3 diffuse, vec3 p, vec3 v, vec3 n, vec4 lp, vec3 ln,
|
||||
float lightSize, float lightFalloff, float is_pointlight, float ambiance)
|
||||
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,
|
||||
float metallic,
|
||||
vec3 n, // normal
|
||||
vec3 p, // pixel position
|
||||
vec3 v, // view vector (negative normalized pixel position)
|
||||
vec3 lp, // light position
|
||||
vec3 ld, // light direction (for spotlights)
|
||||
vec3 lightColor,
|
||||
float lightSize, float falloff, float is_pointlight, float ambiance)
|
||||
{
|
||||
vec3 intensity = vec3(0);
|
||||
vec3 color = vec3(0,0,0);
|
||||
|
||||
vec3 lv = lp.xyz - p;
|
||||
vec3 h, l;
|
||||
float nh, nl, nv, vh, lightDist;
|
||||
calcHalfVectors(lv,n,v,h,l,nh,nl,nv,vh,lightDist);
|
||||
|
||||
float dist = lightDist/lightSize;
|
||||
float lightDist = length(lv);
|
||||
|
||||
if (dist <= 1.0 && nl > 0.0)
|
||||
float dist = lightDist / lightSize;
|
||||
if (dist <= 1.0)
|
||||
{
|
||||
float dist_atten = calcLegacyDistanceAttenuation(dist,lightFalloff);
|
||||
lv /= lightDist;
|
||||
|
||||
float specWeight = 1.0;
|
||||
float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
|
||||
|
||||
lv = normalize(lv);
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
nl *= spot * spot;
|
||||
vec3 intensity = dist_atten * lightColor * 3.0;
|
||||
|
||||
if (nl > 0.0)
|
||||
{
|
||||
vec3 color = vec3(0);
|
||||
intensity = dist_atten * nl * lightColor;
|
||||
color += intensity * BRDFLambertian(reflect0, reflect90, c_diff, specWeight, vh);
|
||||
color += intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh);
|
||||
return color;
|
||||
}
|
||||
color = intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
|
||||
}
|
||||
return intensity;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 color = vec3(0,0,0);
|
||||
|
||||
vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
|
||||
vec3 pos = vary_position;
|
||||
|
||||
|
|
@ -184,10 +166,11 @@ void main()
|
|||
vec3 atten;
|
||||
calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true);
|
||||
|
||||
|
||||
// IF .mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
|
||||
// vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
|
||||
// else
|
||||
vec4 albedo = texture2D(diffuseMap, vary_texcoord0.xy).rgba;
|
||||
vec4 albedo = texture(diffuseMap, vary_texcoord0.xy).rgba;
|
||||
albedo.rgb = srgb_to_linear(albedo.rgb);
|
||||
#ifdef HAS_ALPHA_MASK
|
||||
if (albedo.a < minimum_alpha)
|
||||
|
|
@ -196,9 +179,9 @@ void main()
|
|||
}
|
||||
#endif
|
||||
|
||||
vec3 base = vertex_color.rgb * albedo.rgb;
|
||||
vec3 baseColor = vertex_color.rgb * albedo.rgb;
|
||||
|
||||
vec3 vNt = texture2D(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0;
|
||||
vec3 vNt = texture(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0;
|
||||
float sign = vary_sign;
|
||||
vec3 vN = vary_normal;
|
||||
vec3 vT = vary_tangent.xyz;
|
||||
|
|
@ -214,61 +197,43 @@ void main()
|
|||
scol = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
|
||||
#endif
|
||||
|
||||
// RGB = Occlusion, Roughness, Metal
|
||||
// default values, see LLViewerFetchedTexture::sWhiteImagep since roughnessFactor and metallicFactor are multiplied in
|
||||
// occlusion 1.0
|
||||
// roughness 0.0
|
||||
// metal 0.0
|
||||
vec3 packedORM = texture2D(specularMap, vary_texcoord2.xy).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: lldrawpoolapha.cpp
|
||||
vec3 orm = texture(specularMap, vary_texcoord2.xy).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
|
||||
|
||||
packedORM.g *= roughnessFactor;
|
||||
packedORM.b *= metallicFactor;
|
||||
float perceptualRoughness = orm.g * roughnessFactor;
|
||||
float metallic = orm.b * metallicFactor;
|
||||
float ao = orm.r;
|
||||
|
||||
// emissiveColor is the emissive color factor from GLTF and is already in linear space
|
||||
vec3 colorEmissive = emissiveColor;
|
||||
// emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear
|
||||
colorEmissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb);
|
||||
|
||||
vec3 colorDiffuse = vec3(0);
|
||||
vec3 colorSpec = vec3(0);
|
||||
|
||||
float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics)
|
||||
float ao = packedORM.r;
|
||||
float perceptualRough = packedORM.g;
|
||||
float metal = packedORM.b;
|
||||
|
||||
vec3 v = -normalize(vary_position.xyz);
|
||||
vec3 n = norm.xyz;
|
||||
|
||||
vec3 h, l;
|
||||
float nh, nl, nv, vh, lightDist;
|
||||
calcHalfVectors(light_dir, n, v, h, l, nh, nl, nv, vh, lightDist);
|
||||
|
||||
vec3 c_diff, reflect0, reflect90;
|
||||
float alphaRough, specWeight;
|
||||
initMaterial( base, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
|
||||
|
||||
float gloss = 1.0 - perceptualRough;
|
||||
// PBR IBL
|
||||
float gloss = 1.0 - perceptualRoughness;
|
||||
vec3 irradiance = vec3(0);
|
||||
vec3 radiance = vec3(0);
|
||||
vec3 legacyenv = vec3(0);
|
||||
vec3 legacyenv = vec3(0);
|
||||
sampleReflectionProbes(irradiance, radiance, legacyenv, pos.xyz, norm.xyz, gloss, 0.0);
|
||||
irradiance = max(amblit,irradiance) * ambocc;
|
||||
irradiance = max(srgb_to_linear(amblit),irradiance) * ambocc*4.0;
|
||||
|
||||
pbrIbl(colorDiffuse, colorSpec, radiance, irradiance, ao, nv, perceptualRough, gloss, reflect0, c_diff);
|
||||
vec3 f0 = vec3(0.04);
|
||||
|
||||
// Sun/Moon Lighting
|
||||
if (nl > 0.0 || nv > 0.0)
|
||||
{
|
||||
pbrDirectionalLight(colorDiffuse, colorSpec, srgb_to_linear(sunlit), scol, reflect0, reflect90, c_diff, alphaRough, vh, nl, nv, nh);
|
||||
}
|
||||
vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
|
||||
diffuseColor *= 1.0 - metallic;
|
||||
|
||||
vec3 col = colorDiffuse + colorEmissive + colorSpec;
|
||||
vec3 specularColor = mix(f0, baseColor.rgb, metallic);
|
||||
|
||||
vec3 v = -normalize(pos.xyz);
|
||||
float NdotV = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0);
|
||||
|
||||
color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness);
|
||||
color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, v, light_dir) * sunlit*8.0 * scol;
|
||||
color += colorEmissive;
|
||||
|
||||
vec3 light = vec3(0);
|
||||
|
||||
// Punctual lights
|
||||
#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight( reflect0, reflect90, alphaRough, c_diff, light_diffuse[i].rgb, base.rgb, pos.xyz, v, n, light_position[i], light_direction[i].xyz, light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w );
|
||||
#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, pos.xyz, v, light_position[i].xyz, light_direction[i].xyz, light_diffuse[i].rgb, light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
|
||||
|
||||
LIGHT_LOOP(1)
|
||||
LIGHT_LOOP(2)
|
||||
|
|
@ -278,12 +243,12 @@ void main()
|
|||
LIGHT_LOOP(6)
|
||||
LIGHT_LOOP(7)
|
||||
|
||||
col.rgb += light.rgb;
|
||||
color.rgb += light.rgb;
|
||||
|
||||
col.rgb = linear_to_srgb(col.rgb);
|
||||
col *= atten.r;
|
||||
col += 2.0*additive;
|
||||
col = scaleSoftClipFrag(col);
|
||||
color.rgb = linear_to_srgb(color.rgb);
|
||||
color *= atten.r;
|
||||
color += 2.0*additive;
|
||||
color = scaleSoftClipFrag(color);
|
||||
|
||||
frag_color = vec4(col,albedo.a * vertex_color.a);
|
||||
frag_color = vec4(color,albedo.a * vertex_color.a);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,63 +38,190 @@ uniform int sourceIdx;
|
|||
|
||||
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/irradiancecube.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.
|
||||
*/
|
||||
// =============================================================================================================
|
||||
// Code below is derived from the Khronos GLTF Sample viewer:
|
||||
// https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/master/source/shaders/ibl_filtering.frag
|
||||
|
||||
|
||||
#define MATH_PI 3.1415926535897932384626433832795
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
float u_roughness = 1.0;
|
||||
int u_sampleCount = 16;
|
||||
float u_lodBias = 2.0;
|
||||
int u_width = 64;
|
||||
|
||||
// Hammersley Points on the Hemisphere
|
||||
// CC BY 3.0 (Holger Dammertz)
|
||||
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
|
||||
// with adapted interface
|
||||
float radicalInverse_VdC(uint bits)
|
||||
{
|
||||
bits = (bits << 16u) | (bits >> 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);
|
||||
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
|
||||
}
|
||||
|
||||
// hammersley2d describes a sequence of points in the 2d unit square [0,1)^2
|
||||
// that can be used for quasi Monte Carlo integration
|
||||
vec2 hammersley2d(int i, int N) {
|
||||
return vec2(float(i)/float(N), radicalInverse_VdC(uint(i)));
|
||||
}
|
||||
|
||||
// Hemisphere Sample
|
||||
|
||||
// TBN generates a tangent bitangent normal coordinate frame from the normal
|
||||
// (the normal must be normalized)
|
||||
mat3 generateTBN(vec3 normal)
|
||||
{
|
||||
vec3 bitangent = vec3(0.0, 1.0, 0.0);
|
||||
|
||||
float NdotUp = dot(normal, vec3(0.0, 1.0, 0.0));
|
||||
float epsilon = 0.0000001;
|
||||
/*if (1.0 - abs(NdotUp) <= epsilon)
|
||||
{
|
||||
// Sampling +Y or -Y, so we need a more robust bitangent.
|
||||
if (NdotUp > 0.0)
|
||||
{
|
||||
bitangent = vec3(0.0, 0.0, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bitangent = vec3(0.0, 0.0, -1.0);
|
||||
}
|
||||
}*/
|
||||
|
||||
vec3 tangent = normalize(cross(bitangent, normal));
|
||||
bitangent = cross(normal, tangent);
|
||||
|
||||
return mat3(tangent, bitangent, normal);
|
||||
}
|
||||
|
||||
struct MicrofacetDistributionSample
|
||||
{
|
||||
float pdf;
|
||||
float cosTheta;
|
||||
float sinTheta;
|
||||
float phi;
|
||||
};
|
||||
|
||||
MicrofacetDistributionSample Lambertian(vec2 xi, float roughness)
|
||||
{
|
||||
MicrofacetDistributionSample lambertian;
|
||||
|
||||
// Cosine weighted hemisphere sampling
|
||||
// http://www.pbr-book.org/3ed-2018/Monte_Carlo_Integration/2D_Sampling_with_Multidimensional_Transformations.html#Cosine-WeightedHemisphereSampling
|
||||
lambertian.cosTheta = sqrt(1.0 - xi.y);
|
||||
lambertian.sinTheta = sqrt(xi.y); // equivalent to `sqrt(1.0 - cosTheta*cosTheta)`;
|
||||
lambertian.phi = 2.0 * MATH_PI * xi.x;
|
||||
|
||||
lambertian.pdf = lambertian.cosTheta / MATH_PI; // evaluation for solid angle, therefore drop the sinTheta
|
||||
|
||||
return lambertian;
|
||||
}
|
||||
|
||||
|
||||
// getImportanceSample returns an importance sample direction with pdf in the .w component
|
||||
vec4 getImportanceSample(int sampleIndex, vec3 N, float roughness)
|
||||
{
|
||||
// generate a quasi monte carlo point in the unit square [0.1)^2
|
||||
vec2 xi = hammersley2d(sampleIndex, u_sampleCount);
|
||||
|
||||
MicrofacetDistributionSample importanceSample;
|
||||
|
||||
// generate the points on the hemisphere with a fitting mapping for
|
||||
// the distribution (e.g. lambertian uses a cosine importance)
|
||||
importanceSample = Lambertian(xi, roughness);
|
||||
|
||||
// transform the hemisphere sample to the normal coordinate frame
|
||||
// i.e. rotate the hemisphere to the normal direction
|
||||
vec3 localSpaceDirection = normalize(vec3(
|
||||
importanceSample.sinTheta * cos(importanceSample.phi),
|
||||
importanceSample.sinTheta * sin(importanceSample.phi),
|
||||
importanceSample.cosTheta
|
||||
));
|
||||
mat3 TBN = generateTBN(N);
|
||||
vec3 direction = TBN * localSpaceDirection;
|
||||
|
||||
return vec4(direction, importanceSample.pdf);
|
||||
}
|
||||
|
||||
// Mipmap Filtered Samples (GPU Gems 3, 20.4)
|
||||
// https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling
|
||||
// https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf
|
||||
float computeLod(float pdf)
|
||||
{
|
||||
// // Solid angle of current sample -- bigger for less likely samples
|
||||
// float omegaS = 1.0 / (float(u_sampleCount) * pdf);
|
||||
// // Solid angle of texel
|
||||
// // note: the factor of 4.0 * MATH_PI
|
||||
// float omegaP = 4.0 * MATH_PI / (6.0 * float(u_width) * float(u_width));
|
||||
// // Mip level is determined by the ratio of our sample's solid angle to a texel's solid angle
|
||||
// // note that 0.5 * log2 is equivalent to log4
|
||||
// float lod = 0.5 * log2(omegaS / omegaP);
|
||||
|
||||
// babylon introduces a factor of K (=4) to the solid angle ratio
|
||||
// this helps to avoid undersampling the environment map
|
||||
// this does not appear in the original formulation by Jaroslav Krivanek and Mark Colbert
|
||||
// log4(4) == 1
|
||||
// lod += 1.0;
|
||||
|
||||
// We achieved good results by using the original formulation from Krivanek & Colbert adapted to cubemaps
|
||||
|
||||
// https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf
|
||||
float lod = 0.5 * log2( 6.0 * float(u_width) * float(u_width) / (float(u_sampleCount) * pdf));
|
||||
|
||||
|
||||
return lod;
|
||||
}
|
||||
|
||||
vec3 filterColor(vec3 N)
|
||||
{
|
||||
//return textureLod(uCubeMap, N, 3.0).rgb;
|
||||
vec3 color = vec3(0.f);
|
||||
float weight = 0.0f;
|
||||
|
||||
for(int i = 0; i < u_sampleCount; ++i)
|
||||
{
|
||||
vec4 importanceSample = getImportanceSample(i, N, 1.0);
|
||||
|
||||
vec3 H = vec3(importanceSample.xyz);
|
||||
float pdf = importanceSample.w;
|
||||
|
||||
// mipmap filtered samples (GPU Gems 3, 20.4)
|
||||
float lod = computeLod(pdf);
|
||||
|
||||
// apply the bias to the lod
|
||||
lod += u_lodBias;
|
||||
|
||||
lod = clamp(lod, 0, 7);
|
||||
// sample lambertian at a lower resolution to avoid fireflies
|
||||
vec3 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod).rgb;
|
||||
|
||||
color += lambertian;
|
||||
}
|
||||
|
||||
if(weight != 0.0f)
|
||||
{
|
||||
color /= weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
color /= float(u_sampleCount);
|
||||
}
|
||||
|
||||
return color.rgb ;
|
||||
}
|
||||
|
||||
// entry point
|
||||
void main()
|
||||
{
|
||||
float deltaPhi = (2.0 * PI) / 11.25;
|
||||
float deltaTheta = (0.5 * PI) / 4.0;
|
||||
float mipLevel = 2;
|
||||
vec3 color = vec3(0);
|
||||
|
||||
vec3 N = normalize(vary_dir);
|
||||
vec3 up = vec3(0.0, 1.0, 0.0);
|
||||
vec3 right = normalize(cross(up, N));
|
||||
up = normalize(cross(N, right));
|
||||
|
||||
const float TWO_PI = PI * 2.0;
|
||||
const float HALF_PI = PI * 0.5;
|
||||
|
||||
vec3 color = vec3(0.0);
|
||||
uint sampleCount = 0u;
|
||||
for (float phi = 0.0; phi < TWO_PI; phi += deltaPhi) {
|
||||
for (float theta = 0.0; theta < HALF_PI; theta += deltaTheta) {
|
||||
vec3 tempVec = cos(phi) * right + sin(phi) * up;
|
||||
vec3 sampleVector = cos(theta) * N + sin(theta) * tempVec;
|
||||
color += textureLod(reflectionProbes, vec4(sampleVector, sourceIdx), mipLevel).rgb * cos(theta) * sin(theta);
|
||||
sampleCount++;
|
||||
}
|
||||
}
|
||||
frag_color = vec4(PI * color / float(sampleCount), 1.0);
|
||||
color = filterColor(vary_dir);
|
||||
|
||||
frag_color = vec4(color,1.0);
|
||||
}
|
||||
// =============================================================================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ SOFTWARE.
|
|||
// =============================================================================================================
|
||||
|
||||
|
||||
uniform float roughness;
|
||||
//uniform float roughness;
|
||||
|
||||
uniform float mipLevel;
|
||||
|
||||
|
|
@ -123,14 +123,18 @@ float D_GGX(float dotNH, float roughness)
|
|||
return (alpha2)/(PI * denom*denom);
|
||||
}
|
||||
|
||||
vec3 prefilterEnvMap(vec3 R, float roughness)
|
||||
vec3 prefilterEnvMap(vec3 R)
|
||||
{
|
||||
vec3 N = R;
|
||||
vec3 V = R;
|
||||
vec3 color = vec3(0.0);
|
||||
float totalWeight = 0.0;
|
||||
float envMapDim = 256.0;
|
||||
int numSamples = 32/max(int(mipLevel), 1);
|
||||
int numSamples = 8;
|
||||
|
||||
float numMips = 7.0;
|
||||
|
||||
float roughness = (mipLevel+1)/numMips;
|
||||
|
||||
for(uint i = 0u; i < numSamples; i++) {
|
||||
vec2 Xi = hammersley2d(i, numSamples);
|
||||
|
|
@ -150,8 +154,9 @@ vec3 prefilterEnvMap(vec3 R, float roughness)
|
|||
// 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,sourceIdx), mipLevel).rgb * dotNL;
|
||||
//float mip = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f);
|
||||
float mip = clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, 7.f);
|
||||
color += textureLod(reflectionProbes, vec4(L,sourceIdx), mip).rgb * dotNL;
|
||||
totalWeight += dotNL;
|
||||
|
||||
}
|
||||
|
|
@ -162,7 +167,7 @@ vec3 prefilterEnvMap(vec3 R, float roughness)
|
|||
void main()
|
||||
{
|
||||
vec3 N = normalize(vary_dir);
|
||||
frag_color = vec4(prefilterEnvMap(N, roughness), 1.0);
|
||||
frag_color = vec4(prefilterEnvMap(N), 1.0);
|
||||
}
|
||||
// =============================================================================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ VARYING vec2 vary_texcoord0;
|
|||
|
||||
void main()
|
||||
{
|
||||
#if 0
|
||||
float w[9];
|
||||
|
||||
float c = 1.0/16.0; //corner weight
|
||||
|
|
@ -72,4 +73,7 @@ void main()
|
|||
//color /= wsum;
|
||||
|
||||
frag_color = vec4(color, 1.0);
|
||||
#else
|
||||
frag_color = vec4(texture2DRect(screenMap, vary_texcoord0.xy).rgb, 1.0);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,20 +52,24 @@ uniform mat4 inv_proj;
|
|||
|
||||
VARYING vec4 vary_fragcoord;
|
||||
|
||||
vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
|
||||
vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
|
||||
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);
|
||||
vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance);
|
||||
vec4 getPosition(vec2 pos_screen);
|
||||
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
|
||||
vec2 getScreenXY(vec4 clip);
|
||||
void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
|
||||
vec3 srgb_to_linear(vec3 c);
|
||||
|
||||
// Util
|
||||
vec3 hue_to_rgb(float hue);
|
||||
|
||||
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
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
#if defined(LOCAL_LIGHT_KILL)
|
||||
|
|
@ -87,38 +91,43 @@ void main()
|
|||
vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
|
||||
|
||||
vec3 h, l, v = -normalize(pos);
|
||||
float nh, nl, nv, vh, lightDist;
|
||||
float nh, nv, vh, lightDist;
|
||||
|
||||
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
|
||||
{
|
||||
vec3 colorDiffuse = vec3(0);
|
||||
vec3 colorSpec = vec3(0);
|
||||
vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl
|
||||
vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
|
||||
vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
|
||||
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;
|
||||
|
||||
vec3 c_diff, reflect0, reflect90;
|
||||
float alphaRough, specWeight;
|
||||
initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
|
||||
vec3 specularColor = mix(f0, baseColor.rgb, metallic);
|
||||
|
||||
for (int light_idx = 0; light_idx < LIGHT_COUNT; ++light_idx)
|
||||
{
|
||||
vec3 lightColor = light_col[ light_idx ].rgb; // Already in linear, see pipeline.cpp: volume->getLightLinearColor();
|
||||
float falloff = light_col[ light_idx ].a;
|
||||
float lightSize = light [ light_idx ].w;
|
||||
vec3 lv =(light [ light_idx ].xyz - pos);
|
||||
calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
|
||||
float lightSize = light[ light_idx ].w;
|
||||
vec3 lv = light[ light_idx ].xyz - pos;
|
||||
|
||||
lightDist = length(lv);
|
||||
|
||||
float dist = lightDist / lightSize;
|
||||
if (dist <= 1.0 && nl > 0.0)
|
||||
if (dist <= 1.0)
|
||||
{
|
||||
lv /= lightDist;
|
||||
|
||||
float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
|
||||
vec3 intensity = dist_atten * nl * lightColor;
|
||||
colorDiffuse += intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh);
|
||||
colorSpec += intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh);
|
||||
|
||||
vec3 intensity = dist_atten * lightColor * 3.0;
|
||||
|
||||
final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
|
||||
}
|
||||
}
|
||||
|
||||
final_color = colorDiffuse + colorSpec;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,40 +28,6 @@
|
|||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
#define DEBUG_ANY_LIGHT_TYPE 0 // Output blue light cone
|
||||
#define DEBUG_LEG_LIGHT_TYPE 0 // Show Legacy objects in blue
|
||||
#define DEBUG_PBR_LIGHT_TYPE 0 // Ouput gray if PBR multiSpot lights object
|
||||
#define DEBUG_PBR_SPOT 0
|
||||
#define DEBUG_PBR_SPOT_DIFFUSE 0 // PBR diffuse lit
|
||||
#define DEBUG_PBR_SPOT_SPECULAR 0 // PBR spec lit
|
||||
|
||||
#define DEBUG_LIGHT_FRUSTUM 0 // If projected light effects a surface
|
||||
#define DEBUG_AMBIANCE_COLOR 0 // calculated ambiance color
|
||||
#define DEBUG_AMBIANCE_AOE 0 // area of effect using inverse ambiance color
|
||||
#define DEBUG_AMBIANCE_FINAL 0 // light color * ambiance color
|
||||
#define DEBUG_NOISE 0 // monochrome noise
|
||||
#define DEBUG_SHADOW 0 // Show inverted shadow
|
||||
#define DEBUG_SPOT_DIFFUSE 0 // dot(n,l) * dist_atten
|
||||
#define DEBUG_SPOT_NL 0 // monochome area effected by light
|
||||
#define DEBUG_SPOT_SPEC_POS 0
|
||||
#define DEBUG_SPOT_REFLECTION 0 // color: pos reflected along n
|
||||
#define DEBUG_SPOT_ZERO 0 // Output zero for spotlight
|
||||
|
||||
#define DEBUG_PBR_LIGHT_H 0 // Half vector
|
||||
#define DEBUG_PBR_LIHGT_L 0 // Light vector
|
||||
#define DEBUG_PBR_LIGHT_NH 0 // colorized dot(n,h)
|
||||
#define DEBUG_PBR_LIGHT_NL 0 // colorized dot(n,l)
|
||||
#define DEBUG_PBR_LIGHT_NV 0 // colorized dot(n,v)
|
||||
#define DEBUG_PBR_LIGHT_VH 0 // colorized dot(v,h)
|
||||
#define DEBUG_PBR_LIGHT_DIFFUSE_COLOR 0 // non PBR spotlight
|
||||
#define DEBUG_PBR_LIGHT_SPECULAR_COLOR 0 // non PBR spotlight
|
||||
#define DEBUG_PBR_LIGHT_INTENSITY 0 // Light intensity
|
||||
#define DEBUG_PBR_LIGHT_INTENSITY_NL 0 // Light intensity * dot(n,l)
|
||||
#define DEBUG_PBR_LIGHT_BRDF_DIFFUSE 0 // like "fullbright" if no "nl" factor
|
||||
#define DEBUG_PBR_LIGHT_BRDF_SPECULAR 0
|
||||
#define DEBUG_PBR_LIGHT_BRDF_FINAL 0 // BRDF Diffuse + BRDF Specular
|
||||
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
|
|
@ -107,19 +73,15 @@ uniform vec2 screen_res;
|
|||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
|
||||
vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
|
||||
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);
|
||||
vec3 colorized_dot(float x);
|
||||
bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc );
|
||||
vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v);
|
||||
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
|
||||
vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv);
|
||||
vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );
|
||||
vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n);
|
||||
vec2 getScreenXY(vec4 clip);
|
||||
void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
|
||||
vec3 srgb_to_linear(vec3 cs);
|
||||
vec4 texture2DLodSpecular(vec2 tc, float lod);
|
||||
|
||||
|
|
@ -127,6 +89,13 @@ vec4 getPosition(vec2 pos_screen);
|
|||
|
||||
const float M_PI = 3.14159265;
|
||||
|
||||
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
|
||||
|
||||
void main()
|
||||
{
|
||||
#if defined(LOCAL_LIGHT_KILL)
|
||||
|
|
@ -178,11 +147,17 @@ void main()
|
|||
|
||||
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
|
||||
{
|
||||
vec3 colorDiffuse = vec3(0);
|
||||
vec3 colorSpec = vec3(0);
|
||||
vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl
|
||||
vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
|
||||
float metal = packedORM.b;
|
||||
vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
|
||||
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;
|
||||
|
||||
vec3 specularColor = mix(f0, baseColor.rgb, metallic);
|
||||
|
||||
// We need this additional test inside a light's frustum since a spotlight's ambiance can be applied
|
||||
if (proj_tc.x > 0.0 && proj_tc.x < 1.0
|
||||
|
|
@ -194,111 +169,16 @@ void main()
|
|||
if (nl > 0.0)
|
||||
{
|
||||
amb_da += (nl*0.5 + 0.5) * proj_ambiance;
|
||||
lit = nl * dist_atten;
|
||||
|
||||
vec3 c_diff, reflect0, reflect90;
|
||||
float alphaRough, specWeight;
|
||||
initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
|
||||
|
||||
|
||||
dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
|
||||
slit = getProjectedLightSpecularColor( pos, n );
|
||||
|
||||
float exposure = M_PI;
|
||||
dlit *= exposure;
|
||||
slit *= exposure;
|
||||
|
||||
colorDiffuse = shadow * lit * dlit * BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh );
|
||||
colorSpec = shadow * lit * slit * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
|
||||
colorSpec += shadow * lit * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
|
||||
|
||||
#if DEBUG_PBR_SPOT_DIFFUSE
|
||||
colorDiffuse = dlit.rgb; colorSpec = vec3(0);
|
||||
#endif
|
||||
#if DEBUG_PBR_SPOT_SPECULAR
|
||||
colorDiffuse = vec3(0); colorSpec = slit.rgb;
|
||||
#endif
|
||||
#if DEBUG_PBR_SPOT
|
||||
colorDiffuse = dlit; colorSpec = vec3(0);
|
||||
colorDiffuse *= nl;
|
||||
colorDiffuse *= shadow;
|
||||
#endif
|
||||
vec3 intensity = dist_atten * dlit * 3.0 * shadow; // Legacy attenuation
|
||||
final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
|
||||
}
|
||||
|
||||
amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
|
||||
colorDiffuse += diffuse.rgb * amb_rgb;
|
||||
|
||||
#if DEBUG_AMBIANCE_FINAL
|
||||
colorDiffuse = diffuse.rgb * amb_rgb; colorSpec = vec3(0);
|
||||
#endif
|
||||
#if DEBUG_LIGHT_FRUSTUM
|
||||
colorDiffuse = vec3(0,1,0); colorSpec = vec3(0);
|
||||
#endif
|
||||
#if DEBUG_NOISE
|
||||
float noise = texture2D(noiseMap, tc/128.0).b;
|
||||
colorDiffuse = vec3(noise); colorSpec = vec3(0);
|
||||
#endif
|
||||
final_color += diffuse.rgb * amb_rgb;
|
||||
}
|
||||
|
||||
#if DEBUG_PBR_LIGHT_TYPE
|
||||
colorDiffuse = vec3(0.5,0,0); colorSpec = vec3(0);
|
||||
#endif
|
||||
|
||||
#if DEBUG_PBR_LIGHT_H
|
||||
colorDiffuse = h*0.5 + 0.5; colorSpec = vec3(0);
|
||||
#endif
|
||||
#if DEBUG_PBR_LIHGT_L
|
||||
colorDiffuse = l*0.5 + 0.5; colorSpec = vec3(0);
|
||||
#endif
|
||||
#if DEBUG_PBR_LIGHT_NH
|
||||
colorDiffuse = colorized_dot(nh); colorSpec = vec3(0);
|
||||
#endif
|
||||
#if DEBUG_PBR_LIGHT_NL
|
||||
colorDiffuse = colorized_dot(nl); colorSpec = vec3(0);
|
||||
#endif
|
||||
#if DEBUG_PBR_LIGHT_NV
|
||||
colorDiffuse = colorized_dot(nv); colorSpec = vec3(0);
|
||||
#endif
|
||||
#if DEBUG_PBR_LIGHT_VH
|
||||
colorDiffuse = colorized_dot(vh); colorSpec = vec3(0);
|
||||
#endif
|
||||
#if DEBUG_PBR_LIGHT_DIFFUSE_COLOR
|
||||
colorDiffuse = dlit;
|
||||
#endif
|
||||
#if DEBUG_PBR_LIGHT_SPECULAR_COLOR
|
||||
colorDiffuse = slit;
|
||||
#endif
|
||||
#if DEBUG_PBR_LIGHT_INTENSITY
|
||||
colorDiffuse = getLightIntensitySpot( color, size, lightDist, v ); colorSpec = vec3(0);
|
||||
// colorDiffuse = nl * dist_atten;
|
||||
#endif
|
||||
#if DEBUG_PBR_LIGHT_INTENSITY_NL
|
||||
colorDiffuse = getLightIntensitySpot( color, size, lightDist, v ) * nl; colorSpec = vec3(0);
|
||||
#endif
|
||||
#if DEBUG_PBR_LIGHT_BRDF_DIFFUSE
|
||||
vec3 c_diff, reflect0, reflect90;
|
||||
float alphaRough, specWeight;
|
||||
initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
|
||||
|
||||
colorDiffuse = BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh );
|
||||
colorSpec = vec3(0);
|
||||
#endif
|
||||
#if DEBUG_PBR_LIGHT_BRDF_SPECULAR
|
||||
vec3 c_diff, reflect0, reflect90;
|
||||
float alphaRough, specWeight;
|
||||
initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
|
||||
|
||||
colorDiffuse = vec3(0);
|
||||
colorSpec = BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
|
||||
#endif
|
||||
#if DEBUG_PBR_LIGHT_BRDF_FINAL
|
||||
vec3 c_diff, reflect0, reflect90;
|
||||
float alphaRough, specWeight;
|
||||
initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
|
||||
colorDiffuse = nl * BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh );
|
||||
colorSpec = nl * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
|
||||
#endif
|
||||
|
||||
final_color = colorDiffuse + colorSpec;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -326,9 +206,6 @@ void main()
|
|||
|
||||
amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, noise, proj_tc.xy );
|
||||
final_color += diffuse.rgb * amb_rgb;
|
||||
#if DEBUG_LEG_LIGHT_TYPE
|
||||
final_color = vec3(0,0,0.5);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (spec.a > 0.0)
|
||||
|
|
@ -376,59 +253,9 @@ void main()
|
|||
}
|
||||
}
|
||||
}
|
||||
#if DEBUG_SPOT_REFLECTION
|
||||
final_color = ref;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DEBUG_LIGHT_FRUSTUM
|
||||
if (proj_tc.x > 0.0 && proj_tc.x < 1.0
|
||||
&& proj_tc.y > 0.0 && proj_tc.y < 1.0)
|
||||
{
|
||||
final_color = vec3(0,0,1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DEBUG_AMBIANCE_AOE
|
||||
if (proj_tc.x > 0.0 && proj_tc.x < 1.0
|
||||
&& proj_tc.y > 0.0 && proj_tc.y < 1.0)
|
||||
{
|
||||
final_color = 1.0 - amb_rgb;
|
||||
}
|
||||
#endif
|
||||
#if DEBUG_AMBIANCE_COLOR
|
||||
if (proj_tc.x > 0.0 && proj_tc.x < 1.0
|
||||
&& proj_tc.y > 0.0 && proj_tc.y < 1.0)
|
||||
{
|
||||
final_color = amb_rgb;
|
||||
}
|
||||
#endif
|
||||
#if DEBUG_SHADOW
|
||||
final_color = 1.0 - vec3(shadow);
|
||||
#endif
|
||||
#if DEBUG_SPOT_DIFFUSE
|
||||
final_color = vec3(nl * dist_atten);
|
||||
#endif
|
||||
#if DEBUG_SPOT_NL
|
||||
final_color =vec3(nl);
|
||||
#endif
|
||||
#if DEBUG_SPOT_SPEC_POS
|
||||
vec3 ref = reflect(normalize(pos), n);
|
||||
vec3 pdelta = proj_p-pos;
|
||||
float ds = dot(ref, proj_n);
|
||||
final_color = pos + ref * dot(pdelta, proj_n)/ds;
|
||||
#endif
|
||||
#if DEBUG_SPOT_REFLECTION
|
||||
final_color = reflect(normalize(pos), n);
|
||||
#endif
|
||||
#if DEBUG_SPOT_ZERO
|
||||
final_color = vec3(0,0,0);
|
||||
#endif
|
||||
#if DEBUG_ANY_LIGHT_TYPE
|
||||
final_color = vec3(0,0,0.3333);
|
||||
#endif
|
||||
|
||||
//not sure why, but this line prevents MATBUG-194
|
||||
final_color = max(final_color, vec3(0.0));
|
||||
|
||||
|
|
|
|||
|
|
@ -57,17 +57,20 @@ uniform vec2 screen_res;
|
|||
uniform mat4 inv_proj;
|
||||
uniform vec4 viewport;
|
||||
|
||||
vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
|
||||
vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
|
||||
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);
|
||||
vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance);
|
||||
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
|
||||
vec4 getPosition(vec2 pos_screen);
|
||||
vec2 getScreenXY(vec4 clip);
|
||||
void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
|
||||
vec3 srgb_to_linear(vec3 c);
|
||||
|
||||
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
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 final_color = vec3(0);
|
||||
|
|
@ -96,25 +99,20 @@ void main()
|
|||
|
||||
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
|
||||
{
|
||||
vec3 colorDiffuse = vec3(0);
|
||||
vec3 colorSpec = vec3(0);
|
||||
vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl
|
||||
vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
|
||||
float lightSize = size;
|
||||
vec3 lightColor = color; // Already in linear, see pipeline.cpp: volume->getLightLinearColor();
|
||||
vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
|
||||
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;
|
||||
|
||||
vec3 c_diff, reflect0, reflect90;
|
||||
float alphaRough, specWeight;
|
||||
initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
|
||||
vec3 specularColor = mix(f0, baseColor.rgb, metallic);
|
||||
|
||||
if (nl > 0.0)
|
||||
{
|
||||
vec3 intensity = dist_atten * nl * lightColor; // Legacy attenuation
|
||||
colorDiffuse += intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh);
|
||||
colorSpec += intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh);
|
||||
}
|
||||
|
||||
final_color = colorDiffuse + colorSpec;
|
||||
vec3 intensity = dist_atten * color * 3.0; // Legacy attenuation
|
||||
final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -524,14 +524,14 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 l
|
|||
vec3 pos, vec3 norm, float glossiness, float envIntensity)
|
||||
{
|
||||
// TODO - don't hard code lods
|
||||
float reflection_lods = 8;
|
||||
float reflection_lods = 7;
|
||||
preProbeSample(pos);
|
||||
|
||||
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
|
||||
|
||||
ambenv = sampleProbeAmbient(pos, norm);
|
||||
|
||||
if (glossiness > 0.0)
|
||||
//if (glossiness > 0.0)
|
||||
{
|
||||
float lod = (1.0-glossiness)*reflection_lods;
|
||||
glossenv = sampleProbes(pos, normalize(refnormpersp), lod, 1.f);
|
||||
|
|
|
|||
|
|
@ -89,34 +89,21 @@ vec4 applyWaterFogView(vec3 pos, vec4 color);
|
|||
#endif
|
||||
|
||||
// PBR interface
|
||||
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);
|
||||
void initMaterial( vec3 diffuse, vec3 packedORM,
|
||||
out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
|
||||
// perform PBR image based lighting according to GLTF spec
|
||||
// all parameters are in linear space
|
||||
void pbrIbl(out vec3 colorDiffuse, // diffuse color output
|
||||
out vec3 colorSpec, // specular color output,
|
||||
vec3 pbrIbl(vec3 diffuseColor,
|
||||
vec3 specularColor,
|
||||
vec3 radiance, // radiance map sample
|
||||
vec3 irradiance, // irradiance map sample
|
||||
float ao, // ambient occlusion factor
|
||||
float nv,
|
||||
float perceptualRough, // roughness factor
|
||||
float gloss, // 1.0 - roughness factor
|
||||
vec3 reflect0,
|
||||
vec3 c_diff);
|
||||
float nv, // normal dot view vector
|
||||
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
|
||||
|
||||
void pbrDirectionalLight(inout vec3 colorDiffuse,
|
||||
inout vec3 colorSpec,
|
||||
vec3 sunlit,
|
||||
float scol,
|
||||
vec3 reflect0,
|
||||
vec3 reflect90,
|
||||
vec3 c_diff,
|
||||
float alphaRough,
|
||||
float vh,
|
||||
float nl,
|
||||
float nv,
|
||||
float nh);
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
@ -124,9 +111,6 @@ void main()
|
|||
float depth = texture2DRect(depthMap, tc.xy).r;
|
||||
vec4 pos = getPositionWithDepth(tc, depth);
|
||||
vec4 norm = texture2DRect(normalMap, tc);
|
||||
float envIntensity = norm.z;
|
||||
norm.xyz = getNorm(tc);
|
||||
|
||||
vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
|
||||
float light_gamma = 1.0 / 1.3;
|
||||
|
||||
|
|
@ -160,51 +144,39 @@ void main()
|
|||
bool hasPBR = GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR);
|
||||
if (hasPBR)
|
||||
{
|
||||
// 5.22.2. material.pbrMetallicRoughness.baseColorTexture
|
||||
// The first three components (RGB) MUST be encoded with the sRGB transfer function.
|
||||
//
|
||||
// 5.19.7. material.emissiveTexture
|
||||
// This texture contains RGB components encoded with the sRGB transfer function.
|
||||
//
|
||||
// 5.22.5. material.pbrMetallicRoughness.metallicRoughnessTexture
|
||||
// These values MUST be encoded with a linear transfer function.
|
||||
norm.xyz = getNorm(tc);
|
||||
vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
|
||||
float perceptualRoughness = orm.g;
|
||||
float metallic = orm.b;
|
||||
float ao = orm.r * ambocc;
|
||||
|
||||
vec3 colorDiffuse = vec3(0);
|
||||
vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl
|
||||
vec3 colorSpec = vec3(0);
|
||||
vec3 colorEmissive = texture2DRect(specularRect, tc).rgb; //specularRect is sRGB sampler, result is in linear space
|
||||
|
||||
vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
|
||||
float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics)
|
||||
float ao = packedORM.r;
|
||||
float metal = packedORM.b;
|
||||
vec3 v = -normalize(pos.xyz);
|
||||
vec3 n = norm.xyz;
|
||||
|
||||
vec3 h, l;
|
||||
float nh, nl, nv, vh, lightDist;
|
||||
calcHalfVectors(light_dir, n, v, h, l, nh, nl, nv, vh, lightDist);
|
||||
|
||||
float perceptualRough = packedORM.g; // NOTE: do NOT clamp here to be consistent with Blender, Blender is wrong and Substance is right
|
||||
|
||||
vec3 c_diff, reflect0, reflect90;
|
||||
float alphaRough, specWeight;
|
||||
initMaterial( diffuse.rgb, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
|
||||
|
||||
float gloss = 1.0 - perceptualRough;
|
||||
// PBR IBL
|
||||
float gloss = 1.0 - perceptualRoughness;
|
||||
vec3 irradiance = vec3(0);
|
||||
vec3 radiance = vec3(0);
|
||||
sampleReflectionProbes(irradiance, radiance, legacyenv, pos.xyz, norm.xyz, gloss, 0.0);
|
||||
irradiance = max(amblit,irradiance) * ambocc;
|
||||
irradiance = max(srgb_to_linear(amblit),irradiance) * ambocc*4.0;
|
||||
|
||||
pbrIbl(colorDiffuse, colorSpec, radiance, irradiance, ao, nv, perceptualRough, gloss, reflect0, c_diff);
|
||||
vec3 f0 = vec3(0.04);
|
||||
vec3 baseColor = diffuse.rgb;
|
||||
|
||||
// Add in sun/moon punctual light
|
||||
if (nl > 0.0 || nv > 0.0)
|
||||
{
|
||||
pbrDirectionalLight(colorDiffuse, colorSpec, srgb_to_linear(sunlit), scol, reflect0, reflect90, c_diff, alphaRough, vh, nl, nv, nh);
|
||||
}
|
||||
//baseColor.rgb = vec3(0,0,0);
|
||||
//colorEmissive = srgb_to_linear(norm.xyz*0.5+0.5);
|
||||
|
||||
color.rgb = colorDiffuse + colorEmissive + colorSpec;
|
||||
|
||||
vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
|
||||
diffuseColor *= 1.0 - metallic;
|
||||
|
||||
vec3 specularColor = mix(f0, baseColor.rgb, metallic);
|
||||
|
||||
vec3 v = -normalize(pos.xyz);
|
||||
float NdotV = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0);
|
||||
|
||||
color.rgb += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness);
|
||||
color.rgb += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, v, normalize(light_dir)) * sunlit*8.0 * scol;
|
||||
color.rgb += colorEmissive;
|
||||
|
||||
color = linear_to_srgb(color);
|
||||
color *= atten.r;
|
||||
|
|
@ -212,10 +184,14 @@ void main()
|
|||
color = scaleSoftClipFrag(color);
|
||||
color = srgb_to_linear(color);
|
||||
|
||||
|
||||
frag_color.rgb = color.rgb; //output linear since local lights will be added to this shader's results
|
||||
}
|
||||
else
|
||||
{
|
||||
float envIntensity = norm.z;
|
||||
norm.xyz = getNorm(tc);
|
||||
|
||||
float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
|
||||
da = pow(da, light_gamma);
|
||||
|
||||
|
|
@ -278,5 +254,6 @@ void main()
|
|||
frag_color.rgb = srgb_to_linear(color.rgb);
|
||||
}
|
||||
|
||||
|
||||
frag_color.a = bloom;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,18 +82,14 @@ uniform vec2 screen_res;
|
|||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
|
||||
vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
|
||||
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);
|
||||
bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc );
|
||||
vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v);
|
||||
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
|
||||
vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv);
|
||||
vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );
|
||||
vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n);
|
||||
vec2 getScreenXY(vec4 clip_point);
|
||||
void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
|
||||
vec3 srgb_to_linear(vec3 c);
|
||||
vec4 texture2DLodSpecular(vec2 tc, float lod);
|
||||
|
||||
|
|
@ -101,6 +97,13 @@ vec4 getPosition(vec2 pos_screen);
|
|||
|
||||
const float M_PI = 3.14159265;
|
||||
|
||||
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
|
||||
|
||||
void main()
|
||||
{
|
||||
#if defined(LOCAL_LIGHT_KILL)
|
||||
|
|
@ -148,13 +151,20 @@ void main()
|
|||
vec3 dlit = vec3(0, 0, 0);
|
||||
vec3 slit = vec3(0, 0, 0);
|
||||
|
||||
vec3 amb_rgb = vec3(0);
|
||||
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
|
||||
{
|
||||
vec3 colorDiffuse = vec3(0);
|
||||
vec3 colorSpec = vec3(0);
|
||||
vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl
|
||||
vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
|
||||
float metal = packedORM.b;
|
||||
vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
|
||||
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;
|
||||
|
||||
vec3 specularColor = mix(f0, baseColor.rgb, metallic);
|
||||
|
||||
// We need this additional test inside a light's frustum since a spotlight's ambiance can be applied
|
||||
if (proj_tc.x > 0.0 && proj_tc.x < 1.0
|
||||
|
|
@ -166,46 +176,16 @@ void main()
|
|||
if (nl > 0.0)
|
||||
{
|
||||
amb_da += (nl*0.5 + 0.5) * proj_ambiance;
|
||||
lit = nl * dist_atten;
|
||||
|
||||
vec3 c_diff, reflect0, reflect90;
|
||||
float alphaRough, specWeight;
|
||||
initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
|
||||
|
||||
|
||||
dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
|
||||
slit = getProjectedLightSpecularColor( pos, n );
|
||||
|
||||
float exposure = M_PI;
|
||||
dlit *= exposure;
|
||||
slit *= exposure;
|
||||
|
||||
colorDiffuse = shadow * lit * dlit * BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh );
|
||||
colorSpec = shadow * lit * slit * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
|
||||
colorSpec += shadow * lit * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
|
||||
|
||||
#if DEBUG_PBR_SPOT_DIFFUSE
|
||||
colorDiffuse = dlit.rgb; colorSpec = vec3(0);
|
||||
#endif
|
||||
#if DEBUG_PBR_SPOT_SPECULAR
|
||||
colorDiffuse = vec3(0); colorSpec = slit.rgb;
|
||||
#endif
|
||||
#if DEBUG_PBR_SPOT
|
||||
colorDiffuse = dlit; colorSpec = vec3(0);
|
||||
colorDiffuse *= nl;
|
||||
colorDiffuse *= shadow;
|
||||
#endif
|
||||
vec3 intensity = dist_atten * dlit * 3.0 * shadow; // Legacy attenuation
|
||||
final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
|
||||
}
|
||||
|
||||
vec3 amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
|
||||
colorDiffuse += diffuse.rgb * amb_rgb;
|
||||
|
||||
amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
|
||||
final_color += diffuse.rgb * amb_rgb;
|
||||
}
|
||||
|
||||
#if DEBUG_PBR_LIGHT_TYPE
|
||||
colorDiffuse = vec3(0.5,0,0); colorSpec = vec3(0.0);
|
||||
#endif
|
||||
|
||||
final_color = colorDiffuse + colorSpec;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4908,7 +4908,11 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
|
|||
{
|
||||
// LL_WARNS("Inventory") << "Fatal inventory corruption: system folder type has excess copies under root, type " << ft << " count " << count_under_root << LL_ENDL; // <FS:Beq/> FIRE-31634 [OPENSIM] Better inventory validation logging
|
||||
validation_info->mDuplicateRequiredSystemFolders.insert(folder_type);
|
||||
if (!is_automatic && folder_type != LLFolderType::FT_SETTINGS)
|
||||
if (!is_automatic
|
||||
&& folder_type != LLFolderType::FT_SETTINGS
|
||||
// FT_MATERIAL might need to be automatic like the rest of upload folders
|
||||
&& folder_type != LLFolderType::FT_MATERIAL
|
||||
)
|
||||
{
|
||||
// <FS:Beq> FIRE-31634 [OPENSIM] Better inventory validation logging
|
||||
// LL_WARNS("Inventory") << "Fatal inventory corruption: system folder type has excess copies under root, type " << LLFolderType::lookup(folder_type) << "(" << ft << ") count " << count_under_root << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -204,14 +204,14 @@ void LLMaterialEditor::setAlbedoUploadId(const LLUUID& id)
|
|||
|
||||
LLColor4 LLMaterialEditor::getAlbedoColor()
|
||||
{
|
||||
LLColor4 ret = LLColor4(childGetValue("albedo color"));
|
||||
LLColor4 ret = linearColor4(LLColor4(childGetValue("albedo color")));
|
||||
ret.mV[3] = getTransparency();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setAlbedoColor(const LLColor4& color)
|
||||
{
|
||||
childSetValue("albedo color", color.getValue());
|
||||
childSetValue("albedo color", srgbColor4(color).getValue());
|
||||
setTransparency(color.mV[3]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2044,8 +2044,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
|
|||
S32 tc_bytes_size = ((size_vertices * sizeof(LLVector2)) + 0xF) & ~0xF;
|
||||
LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size);
|
||||
LLVector4a* combined_normals = combined_positions + size_vertices;
|
||||
LLVector4a* combined_tangents = combined_normals + size_vertices;
|
||||
LLVector2* combined_tex_coords = (LLVector2*)(combined_tangents + size_vertices);
|
||||
LLVector2* combined_tex_coords = (LLVector2*)(combined_normals + size_vertices);
|
||||
|
||||
// copy indices and vertices into new buffers
|
||||
S32 combined_positions_shift = 0;
|
||||
|
|
@ -2055,9 +2054,6 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
|
|||
{
|
||||
const LLVolumeFace &face = base_model->getVolumeFace(face_idx);
|
||||
|
||||
// ensure tangents have been generated or loaded
|
||||
llassert(face.mMikktSpaceTangents);
|
||||
|
||||
// Vertices
|
||||
S32 copy_bytes = face.mNumVertices * sizeof(LLVector4a);
|
||||
LLVector4a::memcpyNonAliased16((F32*)(combined_positions + combined_positions_shift), (F32*)face.mPositions, copy_bytes);
|
||||
|
|
@ -2065,9 +2061,6 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
|
|||
// Normals
|
||||
LLVector4a::memcpyNonAliased16((F32*)(combined_normals + combined_positions_shift), (F32*)face.mNormals, copy_bytes);
|
||||
|
||||
// Tangents
|
||||
LLVector4a::memcpyNonAliased16((F32*)(combined_tangents + combined_positions_shift), (F32*)face.mMikktSpaceTangents, copy_bytes);
|
||||
|
||||
// Tex coords
|
||||
copy_bytes = face.mNumVertices * sizeof(LLVector2);
|
||||
memcpy((void*)(combined_tex_coords + combined_positions_shift), (void*)face.mTexCoords, copy_bytes);
|
||||
|
|
@ -2193,8 +2186,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
|
|||
|
||||
LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size);
|
||||
LLVector4a* buffer_normals = buffer_positions + size_vertices;
|
||||
LLVector4a* buffer_tangents = buffer_normals + size_vertices;
|
||||
LLVector2* buffer_tex_coords = (LLVector2*)(buffer_tangents + size_vertices);
|
||||
LLVector2* buffer_tex_coords = (LLVector2*)(buffer_normals + size_vertices);
|
||||
S32 buffer_idx_size = (size_indices * sizeof(U16) + 0xF) & ~0xF;
|
||||
U16* buffer_indices = (U16*)ll_aligned_malloc_16(buffer_idx_size);
|
||||
S32* old_to_new_positions_map = new S32[size_vertices];
|
||||
|
|
@ -2287,7 +2279,6 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
|
|||
// Copy vertice, normals, tcs
|
||||
buffer_positions[buf_positions_copied] = combined_positions[idx];
|
||||
buffer_normals[buf_positions_copied] = combined_normals[idx];
|
||||
buffer_tangents[buf_positions_copied] = combined_tangents[idx];
|
||||
buffer_tex_coords[buf_positions_copied] = combined_tex_coords[idx];
|
||||
|
||||
old_to_new_positions_map[idx] = buf_positions_copied;
|
||||
|
|
@ -2332,7 +2323,6 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
|
|||
|
||||
LLVector4a::memcpyNonAliased16((F32*)new_face.mPositions, (F32*)buffer_positions, buf_positions_copied * sizeof(LLVector4a));
|
||||
LLVector4a::memcpyNonAliased16((F32*)new_face.mNormals, (F32*)buffer_normals, buf_positions_copied * sizeof(LLVector4a));
|
||||
LLVector4a::memcpyNonAliased16((F32*)new_face.mMikktSpaceTangents, (F32*)buffer_tangents, buf_positions_copied * sizeof(LLVector4a));
|
||||
|
||||
U32 tex_size = (buf_positions_copied * sizeof(LLVector2) + 0xF)&~0xF;
|
||||
LLVector4a::memcpyNonAliased16((F32*)new_face.mTexCoords, (F32*)buffer_tex_coords, tex_size);
|
||||
|
|
|
|||
|
|
@ -410,8 +410,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
|
||||
S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f;
|
||||
|
||||
//for (int i = 0; i < mMipChain.size(); ++i)
|
||||
for (int i = 0; i < 1; ++i)
|
||||
for (int i = 0; i < mMipChain.size(); ++i)
|
||||
{
|
||||
LL_PROFILE_GPU_ZONE("probe mip");
|
||||
mMipChain[i].bindTarget();
|
||||
|
|
@ -465,10 +464,14 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
|
||||
if (mip >= 0)
|
||||
{
|
||||
LL_PROFILE_GPU_ZONE("probe mip copy");
|
||||
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, targetIdx * 6 + face, 0, 0, res, res);
|
||||
glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
|
||||
if (i == 0)
|
||||
{
|
||||
glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
|
||||
}
|
||||
mTexture->unbind();
|
||||
}
|
||||
mMipChain[i].flush();
|
||||
|
|
@ -492,8 +495,12 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
|
||||
static LLStaticHashedString sMipLevel("mipLevel");
|
||||
|
||||
mMipChain[1].bindTarget();
|
||||
U32 res = mMipChain[1].getWidth();
|
||||
|
||||
for (int i = 1; i < mMipChain.size(); ++i)
|
||||
{
|
||||
LL_PROFILE_GPU_ZONE("probe radiance gen");
|
||||
for (int cf = 0; cf < 6; ++cf)
|
||||
{ // for each cube face
|
||||
LLCoordFrame frame;
|
||||
|
|
@ -503,15 +510,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
frame.getOpenGLRotation(mat);
|
||||
gGL.loadMatrix(mat);
|
||||
|
||||
mMipChain[i].bindTarget();
|
||||
static LLStaticHashedString sRoughness("roughness");
|
||||
|
||||
gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1));
|
||||
gRadianceGenProgram.uniform1f(sMipLevel, llmax((F32)(i - 1), 0.f));
|
||||
if (i > 0)
|
||||
{
|
||||
gRadianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
//gGL.begin(gGL.QUADS);
|
||||
//gGL.vertex3f(-1, -1, -1);
|
||||
|
|
@ -529,12 +532,17 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
gGL.end();
|
||||
// </FS:Ansariel>
|
||||
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();
|
||||
}
|
||||
|
||||
if (i != mMipChain.size() - 1)
|
||||
{
|
||||
res /= 2;
|
||||
glViewport(0, 0, res, res);
|
||||
}
|
||||
}
|
||||
|
||||
gRadianceGenProgram.unbind();
|
||||
|
||||
//generate irradiance map
|
||||
|
|
@ -542,7 +550,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
|
||||
mTexture->bind(channel);
|
||||
|
||||
gIrradianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex);
|
||||
gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx);
|
||||
|
||||
int start_mip = 0;
|
||||
// find the mip target to start with based on irradiance map resolution
|
||||
|
|
@ -554,8 +562,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = start_mip; i < mMipChain.size(); ++i)
|
||||
//for (int i = start_mip; i < mMipChain.size(); ++i)
|
||||
{
|
||||
int i = start_mip;
|
||||
LL_PROFILE_GPU_ZONE("probe irradiance gen");
|
||||
glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight());
|
||||
for (int cf = 0; cf < 6; ++cf)
|
||||
{ // for each cube face
|
||||
LLCoordFrame frame;
|
||||
|
|
@ -565,8 +576,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
frame.getOpenGLRotation(mat);
|
||||
gGL.loadMatrix(mat);
|
||||
|
||||
mMipChain[i].bindTarget();
|
||||
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
//gGL.begin(gGL.QUADS);
|
||||
//gGL.vertex3f(-1, -1, -1);
|
||||
|
|
@ -589,9 +598,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
mIrradianceMaps->bind(channel);
|
||||
glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
|
||||
mTexture->bind(channel);
|
||||
mMipChain[i].flush();
|
||||
}
|
||||
}
|
||||
|
||||
mMipChain[1].flush();
|
||||
|
||||
gIrradianceGenProgram.unbind();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2656,13 +2656,13 @@ LLTextureFetch::~LLTextureFetch()
|
|||
// ~LLQueuedThread() called here
|
||||
}
|
||||
|
||||
bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
|
||||
S32 LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
|
||||
S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (mDebugPause)
|
||||
{
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (f_type == FTT_SERVER_BAKE)
|
||||
|
|
@ -2678,7 +2678,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
|
|||
<< host << " != " << worker->mHost << LL_ENDL;
|
||||
removeRequest(worker, true);
|
||||
worker = NULL;
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2731,13 +2731,13 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
|
|||
{
|
||||
if (worker->wasAborted())
|
||||
{
|
||||
return false; // need to wait for previous aborted request to complete
|
||||
return -1; // need to wait for previous aborted request to complete
|
||||
}
|
||||
worker->lockWorkMutex(); // +Mw
|
||||
if (worker->mState == LLTextureFetchWorker::DONE && worker->mDesiredSize == llmax(desired_size, TEXTURE_CACHE_ENTRY_SIZE) && worker->mDesiredDiscard == desired_discard) {
|
||||
worker->unlockWorkMutex(); // -Mw
|
||||
|
||||
return false; // similar request has failed or is in a transitional state
|
||||
return -1; // similar request has failed or is in a transitional state
|
||||
}
|
||||
worker->mActiveCount++;
|
||||
worker->mNeedsAux = needs_aux;
|
||||
|
|
@ -2772,10 +2772,10 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
|
|||
worker->setCanUseHTTP(can_use_http) ;
|
||||
worker->unlockWorkMutex(); // -Mw
|
||||
}
|
||||
|
||||
|
||||
LL_DEBUGS(LOG_TXT) << "REQUESTED: " << id << " f_type " << fttype_to_string(f_type)
|
||||
<< " Discard: " << desired_discard << " size " << desired_size << LL_ENDL;
|
||||
return true;
|
||||
return desired_discard;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public:
|
|||
void shutDownImageDecodeThread();
|
||||
|
||||
// Threads: T* (but Tmain mostly)
|
||||
bool createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
|
||||
S32 createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
|
||||
S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http);
|
||||
|
||||
// Requests that a fetch operation be deleted from the queue.
|
||||
|
|
|
|||
|
|
@ -253,6 +253,7 @@ LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
|
|||
LLGLSLShader gDeferredSkinnedFullbrightProgram;
|
||||
LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram;
|
||||
LLGLSLShader gNormalMapGenProgram;
|
||||
LLGLSLShader gDeferredGenBrdfLutProgram;
|
||||
// [RLVa:KB] - @setsphere
|
||||
LLGLSLShader gRlvSphereProgram;
|
||||
// [/RLVa:KB]
|
||||
|
|
@ -1265,6 +1266,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
|
|||
gDeferredHighlightSpecularProgram.unload();
|
||||
|
||||
gNormalMapGenProgram.unload();
|
||||
gDeferredGenBrdfLutProgram.unload();
|
||||
|
||||
for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
|
||||
{
|
||||
gDeferredMaterialProgram[i].unload();
|
||||
|
|
@ -2877,6 +2880,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
|
|||
success = gNormalMapGenProgram.createShader(NULL, NULL);
|
||||
}
|
||||
|
||||
if (success && gGLManager.mHasCubeMapArray)
|
||||
{
|
||||
gDeferredGenBrdfLutProgram.mName = "Brdf Gen Shader";
|
||||
gDeferredGenBrdfLutProgram.mShaderFiles.clear();
|
||||
gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutV.glsl", GL_VERTEX_SHADER));
|
||||
gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutF.glsl", GL_FRAGMENT_SHADER));
|
||||
gDeferredGenBrdfLutProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
|
||||
success = gDeferredGenBrdfLutProgram.createShader(NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -306,6 +306,7 @@ extern LLGLSLShader gDeferredWLMoonProgram;
|
|||
extern LLGLSLShader gDeferredStarProgram;
|
||||
extern LLGLSLShader gDeferredFullbrightShinyProgram;
|
||||
extern LLGLSLShader gNormalMapGenProgram;
|
||||
extern LLGLSLShader gDeferredGenBrdfLutProgram;
|
||||
// [RLVa:KB] - @setsphere
|
||||
extern LLGLSLShader gRlvSphereProgram;
|
||||
// [/RLVa:KB]
|
||||
|
|
|
|||
|
|
@ -2302,16 +2302,18 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
}
|
||||
|
||||
// bypass texturefetch directly by pulling from LLTextureCache
|
||||
bool fetch_request_created = false;
|
||||
fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
|
||||
S32 fetch_request_discard = -1;
|
||||
fetch_request_discard = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
|
||||
w, h, c, desired_discard, needsAux(), mCanUseHTTP);
|
||||
|
||||
if (fetch_request_created)
|
||||
if (fetch_request_discard >= 0)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created");
|
||||
mHasFetcher = TRUE;
|
||||
mIsFetching = TRUE;
|
||||
mRequestedDiscardLevel = desired_discard;
|
||||
// in some cases createRequest can modify discard, as an example
|
||||
// bake textures are always at discard 0
|
||||
mRequestedDiscardLevel = llmin(desired_discard, fetch_request_discard);
|
||||
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
|
||||
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1332,6 +1332,8 @@ void LLPipeline::releaseLUTBuffers()
|
|||
LLImageGL::deleteTextures(1, &mLightFunc);
|
||||
mLightFunc = 0;
|
||||
}
|
||||
|
||||
mPbrBrdfLut.release();
|
||||
}
|
||||
|
||||
void LLPipeline::releaseShadowBuffers()
|
||||
|
|
@ -1516,6 +1518,21 @@ void LLPipeline::createLUTBuffers()
|
|||
|
||||
delete [] ls;
|
||||
}
|
||||
|
||||
mPbrBrdfLut.allocate(512, 512, GL_RG16F, false, false);
|
||||
mPbrBrdfLut.bindTarget();
|
||||
gDeferredGenBrdfLutProgram.bind();
|
||||
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
gGL.vertex2f(-1, -1);
|
||||
gGL.vertex2f(-1, 1);
|
||||
gGL.vertex2f(1, -1);
|
||||
gGL.vertex2f(1, 1);
|
||||
gGL.end();
|
||||
gGL.flush();
|
||||
|
||||
gDeferredGenBrdfLutProgram.unbind();
|
||||
mPbrBrdfLut.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8516,6 +8533,13 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
|
|||
deferred_target->bindTexture(3, channel, LLTexUnit::TFO_POINT); // frag_data[3]
|
||||
}
|
||||
|
||||
channel = shader.enableTexture(LLShaderMgr::DEFERRED_BRDF_LUT, LLTexUnit::TT_TEXTURE);
|
||||
if (channel > -1)
|
||||
{
|
||||
mPbrBrdfLut.bindTexture(0, channel);
|
||||
}
|
||||
|
||||
|
||||
channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
|
||||
if (channel > -1)
|
||||
{
|
||||
|
|
@ -8655,7 +8679,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
|
|||
}
|
||||
|
||||
bindReflectionProbes(shader);
|
||||
|
||||
|
||||
if (gAtmosphere)
|
||||
{
|
||||
// bind precomputed textures necessary for calculating sun and sky luminance
|
||||
|
|
@ -9567,6 +9591,7 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
|
|||
shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());
|
||||
shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
|
||||
shader.disableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage());
|
||||
shader.disableTexture(LLShaderMgr::DEFERRED_BRDF_LUT);
|
||||
shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
|
||||
shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage());
|
||||
shader.disableTexture(LLShaderMgr::DIFFUSE_MAP);
|
||||
|
|
|
|||
|
|
@ -703,6 +703,7 @@ public:
|
|||
|
||||
LLRenderTarget mHighlight;
|
||||
LLRenderTarget mPhysicsDisplay;
|
||||
LLRenderTarget mPbrBrdfLut;
|
||||
|
||||
LLCullResult mSky;
|
||||
LLCullResult mReflectedObjects;
|
||||
|
|
|
|||
Loading…
Reference in New Issue