OpenGL2: Add r_glossIsRoughness.
This commit is contained in:
parent
92d4b20129
commit
b52ede0445
6 changed files with 76 additions and 26 deletions
|
@ -150,11 +150,11 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float r)
|
vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float roughness)
|
||||||
{
|
{
|
||||||
#if defined(USE_BURLEY)
|
#if defined(USE_BURLEY)
|
||||||
// modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf
|
// modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf
|
||||||
float fd90 = -0.5 + EH * EH * r;
|
float fd90 = -0.5 + EH * EH * roughness;
|
||||||
float burley = 1.0 + fd90 * 0.04 / NH;
|
float burley = 1.0 + fd90 * 0.04 / NH;
|
||||||
burley *= burley;
|
burley *= burley;
|
||||||
return diffuseAlbedo * burley;
|
return diffuseAlbedo * burley;
|
||||||
|
@ -163,21 +163,21 @@ vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float r)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 EnvironmentBRDF(float r, float NE, vec3 specular)
|
vec3 EnvironmentBRDF(float roughness, float NE, vec3 specular)
|
||||||
{
|
{
|
||||||
// from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
|
// from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
|
||||||
float v = 1.0 - max(r, NE);
|
float v = 1.0 - max(roughness, NE);
|
||||||
v *= v * v;
|
v *= v * v;
|
||||||
return vec3(v) + specular;
|
return vec3(v) + specular;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float r)
|
vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float roughness)
|
||||||
{
|
{
|
||||||
// from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
|
// from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
|
||||||
float rr = r*r;
|
float rr = roughness*roughness;
|
||||||
float rrrr = rr*rr;
|
float rrrr = rr*rr;
|
||||||
float d = (NH * NH) * (rrrr - 1.0) + 1.0;
|
float d = (NH * NH) * (rrrr - 1.0) + 1.0;
|
||||||
float v = (EH * EH) * (r + 0.5);
|
float v = (EH * EH) * (roughness + 0.5);
|
||||||
return specular * (rrrr / (4.0 * d * d * v));
|
return specular * (rrrr / (4.0 * d * d * v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,6 +276,11 @@ void main()
|
||||||
attenuation = 1.0;
|
attenuation = 1.0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(r_lightGamma)
|
||||||
|
lightColor = pow(lightColor, vec3(r_lightGamma));
|
||||||
|
ambientColor = pow(ambientColor, vec3(r_lightGamma));
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(USE_NORMALMAP)
|
#if defined(USE_NORMALMAP)
|
||||||
#if defined(SWIZZLE_NORMALMAP)
|
#if defined(SWIZZLE_NORMALMAP)
|
||||||
N.xy = texture2D(u_NormalMap, texCoords).ag - vec2(0.5);
|
N.xy = texture2D(u_NormalMap, texCoords).ag - vec2(0.5);
|
||||||
|
@ -304,11 +309,6 @@ void main()
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(r_lightGamma)
|
|
||||||
lightColor = pow(lightColor, vec3(r_lightGamma));
|
|
||||||
ambientColor = pow(ambientColor, vec3(r_lightGamma));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)
|
#if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)
|
||||||
ambientColor = lightColor;
|
ambientColor = lightColor;
|
||||||
float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0);
|
float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0);
|
||||||
|
@ -343,7 +343,11 @@ void main()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
float gloss = specular.a;
|
float gloss = specular.a;
|
||||||
float r = exp2(-3.0 * gloss);
|
#if defined(GLOSS_IS_ROUGHNESS)
|
||||||
|
float roughness = gloss;
|
||||||
|
#else
|
||||||
|
float roughness = exp2(-3.0 * gloss);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(SPECULAR_IS_METALLIC)
|
#if defined(SPECULAR_IS_METALLIC)
|
||||||
// diffuse is actually base color, and green of specular is metallicness
|
// diffuse is actually base color, and green of specular is metallicness
|
||||||
|
@ -356,20 +360,20 @@ void main()
|
||||||
diffuse.rgb *= vec3(1.0) - specular.rgb;
|
diffuse.rgb *= vec3(1.0) - specular.rgb;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
reflectance = CalcDiffuse(diffuse.rgb, EH, NH, r);
|
reflectance = CalcDiffuse(diffuse.rgb, EH, NH, roughness);
|
||||||
#if defined(USE_SHADOWMAP) && defined(SHADOWMAP_MODULATE)
|
#if defined(USE_SHADOWMAP) && defined(SHADOWMAP_MODULATE)
|
||||||
// bit of a hack, with modulated shadowmaps, add specular to sunlight
|
// bit of a hack, with modulated shadowmaps, add specular to sunlight
|
||||||
H = normalize(var_PrimaryLightDir.xyz + E);
|
H = normalize(var_PrimaryLightDir.xyz + E);
|
||||||
EH = clamp(dot(E, H), 0.0, 1.0);
|
EH = clamp(dot(E, H), 0.0, 1.0);
|
||||||
NH = clamp(dot(N, H), 0.0, 1.0);
|
NH = clamp(dot(N, H), 0.0, 1.0);
|
||||||
reflectance += shadowValue * CalcSpecular(specular.rgb, NH, NL, NE, EH, r);
|
reflectance += shadowValue * CalcSpecular(specular.rgb, NH, NL, NE, EH, roughness);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL);
|
gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL);
|
||||||
gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb);
|
gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb);
|
||||||
|
|
||||||
#if defined(USE_CUBEMAP)
|
#if defined(USE_CUBEMAP)
|
||||||
reflectance = EnvironmentBRDF(r, NE, specular.rgb);
|
reflectance = EnvironmentBRDF(roughness, NE, specular.rgb);
|
||||||
|
|
||||||
vec3 R = reflect(E, N);
|
vec3 R = reflect(E, N);
|
||||||
|
|
||||||
|
@ -377,7 +381,11 @@ void main()
|
||||||
// from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
|
// from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
|
||||||
vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir;
|
vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir;
|
||||||
|
|
||||||
|
#if defined(GLOSS_IS_ROUGHNESS)
|
||||||
|
vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, roughness).rgb * u_EnableTextures.w;
|
||||||
|
#else
|
||||||
vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w;
|
vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w;
|
||||||
|
#endif
|
||||||
|
|
||||||
// normalize cubemap based on lowest mip (~diffuse)
|
// normalize cubemap based on lowest mip (~diffuse)
|
||||||
// multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation
|
// multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation
|
||||||
|
@ -411,8 +419,8 @@ void main()
|
||||||
EH2 = clamp(dot(E, H2), 0.0, 1.0);
|
EH2 = clamp(dot(E, H2), 0.0, 1.0);
|
||||||
NH2 = clamp(dot(N, H2), 0.0, 1.0);
|
NH2 = clamp(dot(N, H2), 0.0, 1.0);
|
||||||
|
|
||||||
reflectance = CalcDiffuse(diffuse.rgb, EH2, NH2, r);
|
reflectance = CalcDiffuse(diffuse.rgb, EH2, NH2, roughness);
|
||||||
reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, r);
|
reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, roughness);
|
||||||
|
|
||||||
lightColor = u_PrimaryLightColor * var_Color.rgb;
|
lightColor = u_PrimaryLightColor * var_Color.rgb;
|
||||||
|
|
||||||
|
|
|
@ -1025,6 +1025,9 @@ void GLSL_InitGPUShaders(void)
|
||||||
if (r_specularIsMetallic->value)
|
if (r_specularIsMetallic->value)
|
||||||
Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n");
|
Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n");
|
||||||
|
|
||||||
|
if (r_glossIsRoughness->value)
|
||||||
|
Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n");
|
||||||
|
|
||||||
if (r_dlightMode->integer >= 2)
|
if (r_dlightMode->integer >= 2)
|
||||||
Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");
|
Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,7 @@ cvar_t *r_deluxeMapping;
|
||||||
cvar_t *r_parallaxMapping;
|
cvar_t *r_parallaxMapping;
|
||||||
cvar_t *r_cubeMapping;
|
cvar_t *r_cubeMapping;
|
||||||
cvar_t *r_specularIsMetallic;
|
cvar_t *r_specularIsMetallic;
|
||||||
|
cvar_t *r_glossIsRoughness;
|
||||||
cvar_t *r_baseNormalX;
|
cvar_t *r_baseNormalX;
|
||||||
cvar_t *r_baseNormalY;
|
cvar_t *r_baseNormalY;
|
||||||
cvar_t *r_baseParallax;
|
cvar_t *r_baseParallax;
|
||||||
|
@ -1213,6 +1214,7 @@ void R_Register( void )
|
||||||
r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||||
r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||||
r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||||
|
r_glossIsRoughness = ri.Cvar_Get("r_glossIsRoughness", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||||
r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
|
r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||||
r_baseNormalY = ri.Cvar_Get( "r_baseNormalY", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
|
r_baseNormalY = ri.Cvar_Get( "r_baseNormalY", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||||
r_baseParallax = ri.Cvar_Get( "r_baseParallax", "0.05", CVAR_ARCHIVE | CVAR_LATCH );
|
r_baseParallax = ri.Cvar_Get( "r_baseParallax", "0.05", CVAR_ARCHIVE | CVAR_LATCH );
|
||||||
|
|
|
@ -1786,6 +1786,7 @@ extern cvar_t *r_deluxeMapping;
|
||||||
extern cvar_t *r_parallaxMapping;
|
extern cvar_t *r_parallaxMapping;
|
||||||
extern cvar_t *r_cubeMapping;
|
extern cvar_t *r_cubeMapping;
|
||||||
extern cvar_t *r_specularIsMetallic;
|
extern cvar_t *r_specularIsMetallic;
|
||||||
|
extern cvar_t *r_glossIsRoughness;
|
||||||
extern cvar_t *r_baseNormalX;
|
extern cvar_t *r_baseNormalX;
|
||||||
extern cvar_t *r_baseNormalY;
|
extern cvar_t *r_baseNormalY;
|
||||||
extern cvar_t *r_baseParallax;
|
extern cvar_t *r_baseParallax;
|
||||||
|
|
|
@ -449,11 +449,10 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
||||||
|| ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_SRC_COLOR)
|
|| ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_SRC_COLOR)
|
||||||
|| ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR);
|
|| ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR);
|
||||||
|
|
||||||
qboolean isWorldDraw = !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL);
|
|
||||||
|
|
||||||
#if defined(USE_OVERBRIGHT)
|
#if defined(USE_OVERBRIGHT)
|
||||||
float exactLight = 1.0f;
|
float exactLight = 1.0f;
|
||||||
#else
|
#else
|
||||||
|
qboolean isWorldDraw = !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL);
|
||||||
float exactLight = (isBlend || !isWorldDraw) ? 1.0f : (float)(1 << r_mapOverBrightBits->integer);
|
float exactLight = (isBlend || !isWorldDraw) ? 1.0f : (float)(1 << r_mapOverBrightBits->integer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -954,17 +954,23 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
||||||
|
|
||||||
exponent = atof( token );
|
exponent = atof( token );
|
||||||
|
|
||||||
// Change shininess to gloss
|
if (r_glossIsRoughness->integer)
|
||||||
// FIXME: assumes max exponent of 8192 and min of 1, must change here if altered in lightall_fp.glsl
|
stage->specularScale[3] = powf(2.0f / (exponent + 2.0), 0.25);
|
||||||
exponent = CLAMP(exponent, 1.0, 8192.0);
|
else
|
||||||
|
{
|
||||||
stage->specularScale[3] = log(exponent) / log(8192.0);
|
// Change shininess to gloss
|
||||||
|
// Assumes max exponent of 8190 and min of 0, must change here if altered in lightall_fp.glsl
|
||||||
|
exponent = CLAMP(exponent, 0.0f, 8190.0f);
|
||||||
|
stage->specularScale[3] = (log2f(exponent + 2.0f) - 1.0f) / 12.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// gloss <value>
|
// gloss <value>
|
||||||
//
|
//
|
||||||
else if (!Q_stricmp(token, "gloss"))
|
else if (!Q_stricmp(token, "gloss"))
|
||||||
{
|
{
|
||||||
|
float gloss;
|
||||||
|
|
||||||
token = COM_ParseExt(text, qfalse);
|
token = COM_ParseExt(text, qfalse);
|
||||||
if ( token[0] == 0 )
|
if ( token[0] == 0 )
|
||||||
{
|
{
|
||||||
|
@ -972,7 +978,38 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
stage->specularScale[3] = atof( token );
|
gloss = atof(token);
|
||||||
|
|
||||||
|
if (r_glossIsRoughness->integer)
|
||||||
|
stage->specularScale[3] = exp2f(-3.0f * gloss);
|
||||||
|
else
|
||||||
|
stage->specularScale[3] = gloss;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// roughness <value>
|
||||||
|
//
|
||||||
|
else if (!Q_stricmp(token, "roughness"))
|
||||||
|
{
|
||||||
|
float roughness;
|
||||||
|
|
||||||
|
token = COM_ParseExt(text, qfalse);
|
||||||
|
if (token[0] == 0)
|
||||||
|
{
|
||||||
|
ri.Printf(PRINT_WARNING, "WARNING: missing parameter for roughness in shader '%s'\n", shader.name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
roughness = atof(token);
|
||||||
|
|
||||||
|
if (r_glossIsRoughness->integer)
|
||||||
|
stage->specularScale[3] = roughness;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (roughness >= 0.125)
|
||||||
|
stage->specularScale[3] = log2f(1.0f / roughness) / 3.0f;
|
||||||
|
else
|
||||||
|
stage->specularScale[3] = 1.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// parallaxDepth <value>
|
// parallaxDepth <value>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue