mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-16 00:54:54 +00:00
shift pbrconfig to ORM
This commit is contained in:
parent
22b0785c73
commit
0c7811bd1a
54 changed files with 879 additions and 680 deletions
|
|
@ -30,22 +30,15 @@
|
|||
// Charles de Rousiers - Electronic Arts Frostbite
|
||||
// SIGGRAPH 2014
|
||||
|
||||
float pow5(float x) {
|
||||
float x2 = x * x;
|
||||
return x2 * x2 * x;
|
||||
}
|
||||
// BRDF from Frostbite presentation:
|
||||
// Moving Frostbite to Physically Based Rendering
|
||||
// S´ebastien Lagarde - Electronic Arts Frostbite
|
||||
// Charles de Rousiers - Electronic Arts Frostbite
|
||||
// SIGGRAPH 2014
|
||||
|
||||
float3 F_Schlick(in float3 f0, in float f90, in float u)
|
||||
float3 F_Schlick(float3 f0, float f90, float u)
|
||||
{
|
||||
return f0 + (f90 - f0) * pow5(1.f - u);
|
||||
}
|
||||
|
||||
float3 F_Fresnel(float3 SpecularColor, float VoH)
|
||||
{
|
||||
float3 SpecularColorSqrt = sqrt(min(SpecularColor, float3(0.99, 0.99, 0.99)));
|
||||
float3 n = (1 + SpecularColorSqrt) / (1 - SpecularColorSqrt);
|
||||
float3 g = sqrt(n*n + VoH*VoH - 1);
|
||||
return 0.5 * sqr((g - VoH) / (g + VoH)) * (1 + sqr(((g + VoH)*VoH - 1) / ((g - VoH)*VoH + 1)));
|
||||
return f0 + (f90 - f0) * pow(1.f - u, 5.f);
|
||||
}
|
||||
|
||||
float3 FresnelSchlickRoughness(float cosTheta, float3 F0, float roughness)
|
||||
|
|
@ -61,57 +54,23 @@ float3 FresnelSchlickRoughness(float cosTheta, float3 F0, float roughness)
|
|||
return ret;
|
||||
}
|
||||
|
||||
float Fr_DisneyDiffuse(float NdotV, float NdotL, float LdotH, float linearRoughness)
|
||||
float V_SmithGGXCorrelated(float NdotL, float NdotV, float alphaRoughnessSq)
|
||||
{
|
||||
float energyBias = lerp(0, 0.5, linearRoughness);
|
||||
float energyFactor = lerp(1.0, 1.0 / 1.51, linearRoughness);
|
||||
float fd90 = energyBias + 2.0 * LdotH*LdotH * linearRoughness;
|
||||
float3 f0 = float3(1.0f, 1.0f, 1.0f);
|
||||
float lightScatter = F_Schlick(f0, fd90, NdotL).r;
|
||||
float viewScatter = F_Schlick(f0, fd90, NdotV).r;
|
||||
float GGXV = NdotL * sqrt(NdotV * NdotV * (1.0 - alphaRoughnessSq) + alphaRoughnessSq);
|
||||
float GGXL = NdotV * sqrt(NdotL * NdotL * (1.0 - alphaRoughnessSq) + alphaRoughnessSq);
|
||||
|
||||
return lightScatter * viewScatter * energyFactor;
|
||||
float GGX = GGXV + GGXL;
|
||||
if (GGX > 0.0f)
|
||||
{
|
||||
return 0.5f / GGX;
|
||||
}
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
float V_SmithGGXCorrelated(float NdotL, float NdotV, float roughness)
|
||||
float D_GGX(float NdotH, float alphaRoughnessSq)
|
||||
{
|
||||
// Original formulation of G_SmithGGX Correlated
|
||||
// lambda_v = (-1 + sqrt(alphaG2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f;
|
||||
// lambda_l = (-1 + sqrt(alphaG2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f;
|
||||
// G_SmithGGXCorrelated = 1 / (1 + lambda_v + lambda_l);
|
||||
// V_SmithGGXCorrelated = G_SmithGGXCorrelated / (4.0f * NdotL * NdotV);
|
||||
|
||||
|
||||
// This is the optimized version
|
||||
//float alphaG2 = alphaG * alphaG;
|
||||
|
||||
// Caution: the "NdotL *" and "NdotV *" are explicitely inversed , this is not a mistake.
|
||||
//float Lambda_GGXV = NdotL * sqrt((-NdotV * alphaG2 + NdotV) * NdotV + alphaG2);
|
||||
//float Lambda_GGXL = NdotV * sqrt((-NdotL * alphaG2 + NdotL) * NdotL + alphaG2);
|
||||
|
||||
//return 0.5f / (Lambda_GGXV + Lambda_GGXL);
|
||||
|
||||
float a2 = roughness * roughness;
|
||||
|
||||
float lambdaV = NdotL * sqrt((NdotV - a2 * NdotV) * NdotV + a2);
|
||||
float lambdaL = NdotV * sqrt((NdotL - a2 * NdotL) * NdotL + a2);
|
||||
float v = 0.5 / (lambdaV + lambdaL);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
float D_GGX(float NdotH, float roughness)
|
||||
{
|
||||
// Divide by PI is apply later
|
||||
//float m2 = m * m;
|
||||
//float f = (NdotH * m2 - NdotH) * NdotH + 1;
|
||||
//return m2 / (f * f);
|
||||
|
||||
float oneMinusNdotHSquared = 1.0 - NdotH * NdotH;
|
||||
float a = NdotH * roughness;
|
||||
float k = roughness / (oneMinusNdotHSquared + a * a);
|
||||
float d = k * k * M_1OVER_PI_F;
|
||||
return d;
|
||||
float f = (NdotH * alphaRoughnessSq - NdotH) * NdotH + 1;
|
||||
return alphaRoughnessSq / (M_PI_F * f * f);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,22 +30,9 @@
|
|||
// Charles de Rousiers - Electronic Arts Frostbite
|
||||
// SIGGRAPH 2014
|
||||
|
||||
float pow5(float x) {
|
||||
float x2 = x * x;
|
||||
return x2 * x2 * x;
|
||||
}
|
||||
|
||||
vec3 F_Schlick(in vec3 f0, in float f90, in float u)
|
||||
vec3 F_Schlick(vec3 f0, float f90, float u)
|
||||
{
|
||||
return f0 + (f90 - f0) * pow5(1.f - u);
|
||||
}
|
||||
|
||||
vec3 F_Fresnel(vec3 SpecularColor, float VoH)
|
||||
{
|
||||
vec3 SpecularColorSqrt = sqrt(min(SpecularColor, vec3(0.99, 0.99, 0.99)));
|
||||
vec3 n = (1 + SpecularColorSqrt) / (1 - SpecularColorSqrt);
|
||||
vec3 g = sqrt(n*n + VoH*VoH - 1);
|
||||
return 0.5 * sqr((g - VoH) / (g + VoH)) * (1 + sqr(((g + VoH)*VoH - 1) / ((g - VoH)*VoH + 1)));
|
||||
return f0 + (f90 - f0) * pow(1.f - u, 5.f);
|
||||
}
|
||||
|
||||
vec3 FresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
|
||||
|
|
@ -61,48 +48,23 @@ vec3 FresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
|
|||
return ret;
|
||||
}
|
||||
|
||||
float Fr_DisneyDiffuse(float NdotV, float NdotL, float LdotH, float linearRoughness)
|
||||
float V_SmithGGXCorrelated(float NdotL, float NdotV, float alphaRoughnessSq)
|
||||
{
|
||||
float energyBias = lerp(0.0f, 0.5f, linearRoughness);
|
||||
float energyFactor = lerp(1.0f, 1.0f / 1.51f, linearRoughness);
|
||||
float fd90 = energyBias + 2.0 * LdotH*LdotH * linearRoughness;
|
||||
vec3 f0 = vec3(1.0f, 1.0f, 1.0f);
|
||||
float lightScatter = F_Schlick(f0, fd90, NdotL).r;
|
||||
float viewScatter = F_Schlick(f0, fd90, NdotV).r;
|
||||
float GGXV = NdotL * sqrt(NdotV * NdotV * (1.0 - alphaRoughnessSq) + alphaRoughnessSq);
|
||||
float GGXL = NdotV * sqrt(NdotL * NdotL * (1.0 - alphaRoughnessSq) + alphaRoughnessSq);
|
||||
|
||||
return lightScatter * viewScatter * energyFactor;
|
||||
float GGX = GGXV + GGXL;
|
||||
if (GGX > 0.0f)
|
||||
{
|
||||
return 0.5f / GGX;
|
||||
}
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
float V_SmithGGXCorrelated(float NdotL, float NdotV, float roughness)
|
||||
float D_GGX(float NdotH, float alphaRoughnessSq)
|
||||
{
|
||||
// Original formulation of G_SmithGGX Correlated
|
||||
// lambda_v = (-1 + sqrt(alphaG2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f;
|
||||
// lambda_l = (-1 + sqrt(alphaG2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f;
|
||||
// G_SmithGGXCorrelated = 1 / (1 + lambda_v + lambda_l);
|
||||
// V_SmithGGXCorrelated = G_SmithGGXCorrelated / (4.0f * NdotL * NdotV);
|
||||
|
||||
|
||||
// This is the optimized version
|
||||
//float alphaG2 = alphaG * alphaG;
|
||||
|
||||
float a2 = roughness * roughness;
|
||||
|
||||
float lambdaV = NdotL * sqrt((NdotV - a2 * NdotV) * NdotV + a2);
|
||||
float lambdaL = NdotV * sqrt((NdotL - a2 * NdotL) * NdotL + a2);
|
||||
float v = 0.5f / (lambdaV + lambdaL);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
float D_GGX(float NdotH, float roughness)
|
||||
{
|
||||
// Divide by PI is apply later
|
||||
|
||||
float oneMinusNdotHSquared = 1.0 - NdotH * NdotH;
|
||||
float a = NdotH * roughness;
|
||||
float k = roughness / (oneMinusNdotHSquared + a * a);
|
||||
float d = k * k * M_1OVER_PI_F;
|
||||
return d;
|
||||
float f = (NdotH * alphaRoughnessSq - NdotH) * NdotH + 1;
|
||||
return alphaRoughnessSq / (M_PI_F * f * f);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,23 +22,24 @@
|
|||
|
||||
#include "./torque.glsl"
|
||||
#include "./brdf.glsl"
|
||||
#include "./shaderModelAutoGen.glsl"
|
||||
|
||||
#ifndef TORQUE_SHADERGEN
|
||||
#line 26
|
||||
// These are the uniforms used by most lighting shaders.
|
||||
|
||||
uniform vec4 inLightPos[3];
|
||||
uniform vec4 inLightInvRadiusSq;
|
||||
uniform vec4 inLightPos[4];
|
||||
uniform vec4 inLightConfigData[4];
|
||||
uniform vec4 inLightColor[4];
|
||||
|
||||
#ifndef TORQUE_BL_NOSPOTLIGHT
|
||||
uniform vec4 inLightSpotDir[3];
|
||||
uniform vec4 inLightSpotDir[4];
|
||||
uniform vec4 inLightSpotAngle;
|
||||
uniform vec4 inLightSpotFalloff;
|
||||
#endif
|
||||
|
||||
uniform vec4 ambient;
|
||||
#define ambientCameraFactor 0.3
|
||||
uniform float smoothness;
|
||||
uniform float roughness;
|
||||
uniform float metalness;
|
||||
uniform vec4 albedo;
|
||||
|
||||
|
|
@ -73,48 +74,53 @@ struct Surface
|
|||
vec3 V; // world space view vector
|
||||
vec4 baseColor; // base color [0 -> 1] (rgba)
|
||||
float metalness; // metalness [0:dielectric -> 1:metal]
|
||||
float roughness; // roughness: [0:smooth -> 1:rough] (linear)
|
||||
float roughness_brdf; // roughness remapped from linear to BRDF
|
||||
float roughness; // material roughness: [0:smooth -> 1:rough]
|
||||
float linearRoughness; // linear roughness (roughness^2)
|
||||
float linearRoughnessSq; // (linearRoughness^2)
|
||||
float depth; // depth: [0:near -> 1:far] (linear)
|
||||
float ao; // ambient occlusion [0 -> 1]
|
||||
float matFlag; // material flag - use getFlag to retreive
|
||||
|
||||
float NdotV; // cos(angle between normal and view vector)
|
||||
vec3 f0; // fresnel value (rgb)
|
||||
float f90;
|
||||
vec3 albedo; // diffuse light absorbtion value (rgb)
|
||||
vec3 R; // reflection vector
|
||||
vec3 F; // fresnel term computed from f0, N and V
|
||||
float f90;
|
||||
|
||||
};
|
||||
|
||||
void updateSurface(inout Surface surface)
|
||||
{
|
||||
surface.NdotV = abs(dot(surface.N, surface.V)) + 1e-5f; // avoid artifact
|
||||
|
||||
surface.albedo = surface.baseColor.rgb * (1.0 - surface.metalness);
|
||||
surface.f0 = lerp(vec3(0.04f), surface.baseColor.rgb, surface.metalness);
|
||||
surface.linearRoughness = surface.roughness * surface.roughness;
|
||||
surface.linearRoughnessSq = surface.linearRoughness * surface.linearRoughness;
|
||||
|
||||
surface.albedo = surface.baseColor.rgb * (1.0f - surface.metalness);
|
||||
surface.f0 = mix(0.04f, surface.baseColor.rgb, surface.metalness);
|
||||
|
||||
surface.R = -reflect(surface.V, surface.N);
|
||||
surface.f90 = saturate(50.0 * dot(surface.f0, vec3(0.33,0.33,0.33)));
|
||||
surface.F = F_Schlick(surface.f0, surface.f90, surface.NdotV);
|
||||
}
|
||||
|
||||
Surface createSurface(vec4 normDepth, sampler2D colorBuffer, sampler2D matInfoBuffer, in vec2 uv, in vec3 wsEyePos, in vec3 wsEyeRay, in mat4 invView)
|
||||
Surface createSurface(vec4 gbuffer0, sampler2D gbufferTex1, sampler2D gbufferTex2, in vec2 uv, in vec3 wsEyePos, in vec3 wsEyeRay, in mat4 invView)
|
||||
{
|
||||
Surface surface;// = Surface();
|
||||
|
||||
vec4 gbuffer1 = texture(colorBuffer, uv);
|
||||
vec4 gbuffer2 = texture(matInfoBuffer, uv);
|
||||
surface.depth = normDepth.a;
|
||||
vec4 gbuffer1 = texture(gbufferTex1, uv);
|
||||
vec4 gbuffer2 = texture(gbufferTex2, uv);
|
||||
surface.depth = gbuffer0.a;
|
||||
surface.P = wsEyePos + wsEyeRay * surface.depth;
|
||||
surface.N = tMul(invView, vec4(normDepth.xyz,0)).xyz;
|
||||
surface.N = tMul(invView, vec4(gbuffer0.xyz,0)).xyz;
|
||||
surface.V = normalize(wsEyePos - surface.P);
|
||||
surface.baseColor = gbuffer1;
|
||||
const float minRoughness=1e-4;
|
||||
surface.roughness = 1.0 - (gbuffer2.b*0.8+0.1999); //t3d uses smoothness, so we convert to roughness.
|
||||
surface.roughness_brdf = surface.roughness * surface.roughness;
|
||||
surface.roughness = clamp(gbuffer2.b, 0.01f, 1.0f);
|
||||
surface.metalness = gbuffer2.a;
|
||||
surface.ao = gbuffer2.g;
|
||||
surface.matFlag = gbuffer2.r;
|
||||
|
||||
updateSurface(surface);
|
||||
return surface;
|
||||
}
|
||||
|
|
@ -128,9 +134,7 @@ Surface createForwardSurface(vec4 baseColor, vec3 normal, vec4 pbrProperties, in
|
|||
surface.N = normal;
|
||||
surface.V = normalize(wsEyePos - surface.P);
|
||||
surface.baseColor = baseColor;
|
||||
const float minRoughness=1e-4;
|
||||
surface.roughness = 1.0 - (pbrProperties.b*0.8+0.1999); //t3d uses smoothness, so we convert to roughness.
|
||||
surface.roughness_brdf = surface.roughness * surface.roughness;
|
||||
surface.roughness = clamp(pbrProperties.b, 0.01f, 1.0f);
|
||||
surface.metalness = pbrProperties.a;
|
||||
surface.ao = pbrProperties.g;
|
||||
surface.matFlag = pbrProperties.r;
|
||||
|
|
@ -166,16 +170,15 @@ vec3 BRDF_GetDebugSpecular(in Surface surface, in SurfaceToLight surfaceToLight)
|
|||
{
|
||||
//GGX specular
|
||||
vec3 F = F_Schlick(surface.f0, surface.f90, surfaceToLight.HdotV);
|
||||
float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.roughness);
|
||||
float D = D_GGX(surfaceToLight.NdotH, surface.roughness);
|
||||
vec3 Fr = D * F * Vis;
|
||||
return Fr*M_1OVER_PI_F;
|
||||
float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.linearRoughnessSq);
|
||||
float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughnessSq);
|
||||
vec3 Fr = D * F * Vis * M_1OVER_PI_F;
|
||||
return Fr;
|
||||
}
|
||||
|
||||
vec3 BRDF_GetDebugDiffuse(in Surface surface, in SurfaceToLight surfaceToLight)
|
||||
{
|
||||
vec3 Fd = surface.albedo.rgb;
|
||||
return Fd*M_1OVER_PI_F;
|
||||
return surface.albedo.rgb * M_1OVER_PI_F;
|
||||
}
|
||||
|
||||
//attenuations functions from "moving frostbite to pbr paper"
|
||||
|
|
@ -206,15 +209,15 @@ float getDistanceAtt( vec3 unormalizedLightVector , float invSqrAttRadius )
|
|||
vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
|
||||
{
|
||||
//lambert diffuse
|
||||
vec3 Fd = surface.albedo.rgb;
|
||||
vec3 Fd = surface.albedo.rgb * M_1OVER_PI_F;
|
||||
|
||||
//GGX specular
|
||||
vec3 F = F_Schlick(surface.f0, surface.f90, surfaceToLight.HdotV);
|
||||
float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.roughness);
|
||||
float D = D_GGX(surfaceToLight.NdotH, surface.roughness);
|
||||
float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.linearRoughnessSq);
|
||||
float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughnessSq);
|
||||
vec3 Fr = D * F * Vis;
|
||||
|
||||
return (Fd + Fr) * M_1OVER_PI_F;
|
||||
return Fd + Fr;
|
||||
}
|
||||
|
||||
vec3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float shadow)
|
||||
|
|
@ -235,6 +238,11 @@ float computeSpecOcclusion( float NdotV , float AO , float roughness )
|
|||
return saturate (pow( abs(NdotV + AO) , exp2 ( -16.0f * roughness - 1.0f )) - 1.0f + AO );
|
||||
}
|
||||
|
||||
float roughnessToMipLevel(float roughness, float numMips)
|
||||
{
|
||||
return roughness * numMips;
|
||||
}
|
||||
|
||||
vec4 compute4Lights( Surface surface,
|
||||
vec4 shadowMask,
|
||||
vec4 inLightPos[4],
|
||||
|
|
@ -340,7 +348,7 @@ vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 refBox
|
|||
}
|
||||
|
||||
vec4 computeForwardProbes(Surface surface,
|
||||
float cubeMips, float numProbes, mat4x4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES],
|
||||
float cubeMips, int numProbes, mat4x4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES],
|
||||
vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refBoxMinArray[MAX_FORWARD_PROBES], vec4 refBoxMaxArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
|
||||
float skylightCubemapIdx, sampler2D BRDFTexture,
|
||||
samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR)
|
||||
|
|
@ -401,11 +409,43 @@ vec4 computeForwardProbes(Surface surface,
|
|||
}
|
||||
}
|
||||
|
||||
#if DEBUGVIZ_ATTENUATION == 1
|
||||
float contribAlpha = 1;
|
||||
for (i = 0; i < numProbes; ++i)
|
||||
{
|
||||
contribAlpha -= contribution[i];
|
||||
}
|
||||
|
||||
return vec4(1 - contribAlpha, 1 - contribAlpha, 1 - contribAlpha, 1);
|
||||
#endif
|
||||
|
||||
#if DEBUGVIZ_CONTRIB == 1
|
||||
vec3 probeContribColors[4];
|
||||
probeContribColors[0] = vec3(1,0,0);
|
||||
probeContribColors[1] = vec3(0,1,0);
|
||||
probeContribColors[2] = vec3(0,0,1);
|
||||
probeContribColors[3] = vec3(1,1,0);
|
||||
|
||||
vec3 finalContribColor = vec3(0, 0, 0);
|
||||
float contribAlpha = 1;
|
||||
for (i = 0; i < numProbes; ++i)
|
||||
{
|
||||
finalContribColor += contribution[i] *probeContribColors[i].rgb;
|
||||
contribAlpha -= contribution[i];
|
||||
}
|
||||
|
||||
//Skylight coloration for anything not covered by probes above
|
||||
if(skylightCubemapIdx != -1)
|
||||
finalContribColor += vec3(0.3, 0.3, 0.3) * contribAlpha;
|
||||
|
||||
return vec4(finalContribColor, 1);
|
||||
#endif
|
||||
|
||||
vec3 irradiance = vec3(0, 0, 0);
|
||||
vec3 specular = vec3(0, 0, 0);
|
||||
|
||||
// Radiance (Specular)
|
||||
float lod = surface.roughness*cubeMips;
|
||||
float lod = roughnessToMipLevel(surface.roughness, cubeMips);
|
||||
|
||||
for (i = 0; i < numProbes; ++i)
|
||||
{
|
||||
|
|
@ -428,17 +468,182 @@ vec4 computeForwardProbes(Surface surface,
|
|||
}
|
||||
|
||||
//energy conservation
|
||||
vec3 kD = 1.0f - surface.F;
|
||||
vec3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness);
|
||||
vec3 kD = 1.0f - F;
|
||||
kD *= 1.0f - surface.metalness;
|
||||
|
||||
float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex)
|
||||
vec2 envBRDF = textureLod(BRDFTexture, vec2(dfgNdotV, surface.roughness),0).rg;
|
||||
specular *= surface.F * envBRDF.x + surface.f90 * envBRDF.y;
|
||||
vec2 envBRDF = texture(BRDFTexture, vec4(dfgNdotV, surface.roughness,0,0)).rg;
|
||||
specular *= F * envBRDF.x + surface.f90 * envBRDF.y;
|
||||
irradiance *= kD * surface.baseColor.rgb;
|
||||
|
||||
//AO
|
||||
irradiance *= surface.ao;
|
||||
specular *= computeSpecOcclusion(surface.NdotV, surface.ao, surface.roughness);
|
||||
|
||||
return vec4(irradiance + specular, 0);//alpha writes disabled
|
||||
//http://marmosetco.tumblr.com/post/81245981087
|
||||
float horizonOcclusion = 1.3;
|
||||
float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N));
|
||||
horizon *= horizon;
|
||||
|
||||
return vec4((irradiance + specular) * horizon, 0);//alpha writes disabled
|
||||
}
|
||||
|
||||
vec4 debugVizForwardProbes(Surface surface,
|
||||
float cubeMips, int numProbes, mat4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES],
|
||||
vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refBoxMinArray[MAX_FORWARD_PROBES], vec4 refBoxMaxArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
|
||||
float skylightCubemapIdx, sampler2D(BRDFTexture),
|
||||
samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR, int showAtten, int showContrib, int showSpec, int showDiff)
|
||||
{
|
||||
int i = 0;
|
||||
float alpha = 1;
|
||||
float blendFactor[MAX_FORWARD_PROBES];
|
||||
float blendSum = 0;
|
||||
float blendFacSum = 0;
|
||||
float invBlendSum = 0;
|
||||
float probehits = 0;
|
||||
//Set up our struct data
|
||||
float contribution[MAX_FORWARD_PROBES];
|
||||
for (i = 0; i < numProbes; ++i)
|
||||
{
|
||||
contribution[i] = 0;
|
||||
|
||||
if (probeConfigData[i].r == 0) //box
|
||||
{
|
||||
contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b);
|
||||
if (contribution[i] > 0.0)
|
||||
probehits++;
|
||||
}
|
||||
else if (probeConfigData[i].r == 1) //sphere
|
||||
{
|
||||
contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g);
|
||||
if (contribution[i] > 0.0)
|
||||
probehits++;
|
||||
}
|
||||
|
||||
contribution[i] = max(contribution[i], 0);
|
||||
|
||||
blendSum += contribution[i];
|
||||
invBlendSum += (1.0f - contribution[i]);
|
||||
}
|
||||
|
||||
if (probehits > 1.0)
|
||||
{
|
||||
for (i = 0; i < numProbes; i++)
|
||||
{
|
||||
blendFactor[i] = ((contribution[i] / blendSum)) / probehits;
|
||||
blendFactor[i] *= ((contribution[i]) / invBlendSum);
|
||||
blendFactor[i] = saturate(blendFactor[i]);
|
||||
blendFacSum += blendFactor[i];
|
||||
}
|
||||
|
||||
// Normalize blendVal
|
||||
if (blendFacSum == 0.0f) // Possible with custom weight
|
||||
{
|
||||
blendFacSum = 1.0f;
|
||||
}
|
||||
|
||||
float invBlendSumWeighted = 1.0f / blendFacSum;
|
||||
for (i = 0; i < numProbes; ++i)
|
||||
{
|
||||
blendFactor[i] *= invBlendSumWeighted;
|
||||
contribution[i] *= blendFactor[i];
|
||||
}
|
||||
}
|
||||
|
||||
if(showAtten == 1)
|
||||
{
|
||||
float contribAlpha = 1;
|
||||
for (i = 0; i < numProbes; ++i)
|
||||
{
|
||||
contribAlpha -= contribution[i];
|
||||
}
|
||||
|
||||
return vec4(1 - contribAlpha, 1 - contribAlpha, 1 - contribAlpha, 1);
|
||||
}
|
||||
|
||||
if(showContrib == 1)
|
||||
{
|
||||
vec3 probeContribColors[4];
|
||||
probeContribColors[0] = vec3(1,0,0);
|
||||
probeContribColors[1] = vec3(0,1,0);
|
||||
probeContribColors[2] = vec3(0,0,1);
|
||||
probeContribColors[3] = vec3(1,1,0);
|
||||
|
||||
vec3 finalContribColor = vec3(0, 0, 0);
|
||||
float contribAlpha = 1;
|
||||
for (i = 0; i < numProbes; ++i)
|
||||
{
|
||||
finalContribColor += contribution[i] *probeContribColors[i].rgb;
|
||||
contribAlpha -= contribution[i];
|
||||
}
|
||||
|
||||
//Skylight coloration for anything not covered by probes above
|
||||
if(skylightCubemapIdx != -1)
|
||||
finalContribColor += vec3(0.3, 0.3, 0.3) * contribAlpha;
|
||||
|
||||
return vec4(finalContribColor, 1);
|
||||
}
|
||||
|
||||
vec3 irradiance = vec3(0, 0, 0);
|
||||
vec3 specular = vec3(0, 0, 0);
|
||||
|
||||
// Radiance (Specular)
|
||||
float lod = roughnessToMipLevel(surface.roughness, cubeMips);
|
||||
|
||||
if(showSpec == 1)
|
||||
{
|
||||
lod = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < numProbes; ++i)
|
||||
{
|
||||
float contrib = contribution[i];
|
||||
if (contrib > 0.0f)
|
||||
{
|
||||
int cubemapIdx = probeConfigData[i].a;
|
||||
vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refBoxMinArray[i].xyz, refBoxMaxArray[i].xyz, inRefPosArray[i].xyz);
|
||||
|
||||
irradiance += textureLod(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
|
||||
specular += textureLod(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;
|
||||
alpha -= contrib;
|
||||
}
|
||||
}
|
||||
|
||||
if(skylightCubemapIdx != -1 && alpha >= 0.001)
|
||||
{
|
||||
irradiance = mix(irradiance,textureLod(irradianceCubemapAR, surface.R, skylightCubemapIdx, 0).xyz,alpha);
|
||||
specular = mix(specular,textureLod(specularCubemapAR, surface.R, skylightCubemapIdx, lod).xyz,alpha);
|
||||
}
|
||||
|
||||
if(showSpec == 1)
|
||||
{
|
||||
return vec4(specular, 0);
|
||||
}
|
||||
|
||||
if(showDiff == 1)
|
||||
{
|
||||
return vec4(irradiance, 0);
|
||||
}
|
||||
|
||||
//energy conservation
|
||||
vec3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness);
|
||||
vec3 kD = 1.0f - F;
|
||||
kD *= 1.0f - surface.metalness;
|
||||
|
||||
float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex)
|
||||
vec2 envBRDF = textureLod(BRDFTexture, vec2(dfgNdotV, surface.roughness),0).rg;
|
||||
specular *= F * envBRDF.x + surface.f90 * envBRDF.y;
|
||||
irradiance *= kD * surface.baseColor.rgb;
|
||||
|
||||
//AO
|
||||
irradiance *= surface.ao;
|
||||
specular *= computeSpecOcclusion(surface.NdotV, surface.ao, surface.roughness);
|
||||
|
||||
//http://marmosetco.tumblr.com/post/81245981087
|
||||
float horizonOcclusion = 1.3;
|
||||
float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N));
|
||||
horizon *= horizon;
|
||||
|
||||
return vec4((irradiance + specular) * horizon, 0);//alpha writes disabled
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@ uniform float4 inLightColor[4];
|
|||
#endif
|
||||
|
||||
uniform float4 ambient;
|
||||
uniform float smoothness;
|
||||
uniform float roughness;
|
||||
uniform float metalness;
|
||||
uniform float4 albedo;
|
||||
|
||||
|
|
@ -74,8 +74,9 @@ struct Surface
|
|||
float3 V; // world space view vector
|
||||
float4 baseColor; // base color [0 -> 1] (rgba)
|
||||
float metalness; // metalness [0:dielectric -> 1:metal]
|
||||
float roughness; // roughness: [0:smooth -> 1:rough] (linear)
|
||||
float roughness_brdf; // roughness remapped from linear to BRDF
|
||||
float roughness; // material roughness: [0:smooth -> 1:rough]
|
||||
float linearRoughness; // linear roughness (roughness^2)
|
||||
float linearRoughnessSq; // (linearRoughness^2)
|
||||
float depth; // depth: [0:near -> 1:far] (linear)
|
||||
float ao; // ambient occlusion [0 -> 1]
|
||||
float matFlag; // material flag - use getFlag to retreive
|
||||
|
|
@ -90,18 +91,19 @@ struct Surface
|
|||
inline void Update()
|
||||
{
|
||||
NdotV = abs(dot(N, V)) + 1e-5f; // avoid artifact
|
||||
|
||||
linearRoughness = roughness * roughness;
|
||||
linearRoughnessSq = linearRoughness * linearRoughness;
|
||||
|
||||
albedo = baseColor.rgb * (1.0 - metalness);
|
||||
f0 = lerp(0.04.xxx, baseColor.rgb, metalness);
|
||||
albedo = baseColor.rgb * (1.0f - metalness);
|
||||
f0 = lerp(0.04f, baseColor.rgb, metalness);
|
||||
|
||||
R = -reflect(V, N);
|
||||
f90 = saturate(50.0 * dot(f0, 0.33));
|
||||
f90 = saturate(50.0f * dot(f0, 0.33f));
|
||||
F = F_Schlick(f0, f90, NdotV);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline Surface createSurface(float4 gbuffer0, TORQUE_SAMPLER2D(gbufferTex1), TORQUE_SAMPLER2D(gbufferTex2), in float2 uv, in float3 wsEyePos, in float3 wsEyeRay, in float4x4 invView)
|
||||
{
|
||||
Surface surface = (Surface)0;
|
||||
|
|
@ -114,8 +116,7 @@ inline Surface createSurface(float4 gbuffer0, TORQUE_SAMPLER2D(gbufferTex1), TOR
|
|||
surface.N = mul(invView, float4(gbuffer0.xyz,0)).xyz;
|
||||
surface.V = normalize(wsEyePos - surface.P);
|
||||
surface.baseColor = gbuffer1;
|
||||
surface.roughness = 1.0 - (gbuffer2.b*0.8+0.1999); //t3d uses smoothness, so we convert to roughness.
|
||||
surface.roughness_brdf = surface.roughness * surface.roughness;
|
||||
surface.roughness = clamp(gbuffer2.b, 0.01f, 1.0f);
|
||||
surface.metalness = gbuffer2.a;
|
||||
surface.ao = gbuffer2.g;
|
||||
surface.matFlag = gbuffer2.r;
|
||||
|
|
@ -133,8 +134,7 @@ inline Surface createForwardSurface(float4 baseColor, float3 normal, float4 pbrP
|
|||
surface.N = normal;
|
||||
surface.V = normalize(wsEyePos - surface.P);
|
||||
surface.baseColor = baseColor;
|
||||
surface.roughness = 1.0 - (pbrProperties.b*0.8+0.1999); //t3d uses smoothness, so we convert to roughness.
|
||||
surface.roughness_brdf = surface.roughness * surface.roughness;
|
||||
surface.roughness = clamp(pbrProperties.b, 0.01f, 1.0f);
|
||||
surface.metalness = pbrProperties.a;
|
||||
surface.ao = pbrProperties.g;
|
||||
surface.matFlag = pbrProperties.r;
|
||||
|
|
@ -146,7 +146,7 @@ inline Surface createForwardSurface(float4 baseColor, float3 normal, float4 pbrP
|
|||
struct SurfaceToLight
|
||||
{
|
||||
float3 L; // surface to light vector
|
||||
float3 Lu; // un-normalized surface to light vector
|
||||
float3 Lu; // un-normalized surface to light vector
|
||||
float3 H; // half-vector between view vector and light vector
|
||||
float NdotL; // cos(angle between N and L)
|
||||
float HdotV; // cos(angle between H and V) = HdotL = cos(angle between H and L)
|
||||
|
|
@ -170,16 +170,15 @@ float3 BRDF_GetDebugSpecular(in Surface surface, in SurfaceToLight surfaceToLigh
|
|||
{
|
||||
//GGX specular
|
||||
float3 F = F_Schlick(surface.f0, surface.f90, surfaceToLight.HdotV);
|
||||
float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.roughness);
|
||||
float D = D_GGX(surfaceToLight.NdotH, surface.roughness);
|
||||
float3 Fr = D * F * Vis;
|
||||
return Fr*M_1OVER_PI_F;
|
||||
float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.linearRoughnessSq);
|
||||
float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughnessSq);
|
||||
float3 Fr = D * F * Vis * M_1OVER_PI_F;
|
||||
return Fr;
|
||||
}
|
||||
|
||||
float3 BRDF_GetDebugDiffuse(in Surface surface, in SurfaceToLight surfaceToLight)
|
||||
{
|
||||
float3 Fd = surface.albedo.rgb;
|
||||
return Fd*M_1OVER_PI_F;
|
||||
return surface.albedo.rgb * M_1OVER_PI_F;
|
||||
}
|
||||
|
||||
//attenuations functions from "moving frostbite to pbr paper"
|
||||
|
|
@ -210,15 +209,15 @@ float getDistanceAtt( float3 unormalizedLightVector , float invSqrAttRadius )
|
|||
float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
|
||||
{
|
||||
//lambert diffuse
|
||||
float3 Fd = surface.albedo.rgb;
|
||||
float3 Fd = surface.albedo.rgb * M_1OVER_PI_F;
|
||||
|
||||
//GGX specular
|
||||
float3 F = F_Schlick(surface.f0, surface.f90, surfaceToLight.HdotV);
|
||||
float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.roughness);
|
||||
float D = D_GGX(surfaceToLight.NdotH, surface.roughness);
|
||||
float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.linearRoughnessSq);
|
||||
float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughnessSq);
|
||||
float3 Fr = D * F * Vis;
|
||||
|
||||
return (Fd + Fr) * M_1OVER_PI_F;
|
||||
return Fd + Fr;
|
||||
}
|
||||
|
||||
float3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow)
|
||||
|
|
@ -234,12 +233,16 @@ float3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, float3 l
|
|||
return evaluateStandardBRDF(surface,surfaceToLight) * factor;
|
||||
}
|
||||
|
||||
|
||||
float computeSpecOcclusion( float NdotV , float AO , float roughness )
|
||||
{
|
||||
return saturate (pow( abs(NdotV + AO) , exp2 ( -16.0f * roughness - 1.0f )) - 1.0f + AO );
|
||||
}
|
||||
|
||||
float roughnessToMipLevel(float roughness, float numMips)
|
||||
{
|
||||
return roughness * numMips;
|
||||
}
|
||||
|
||||
float4 compute4Lights( Surface surface,
|
||||
float4 shadowMask,
|
||||
float4 inLightPos[4],
|
||||
|
|
@ -445,7 +448,7 @@ float4 computeForwardProbes(Surface surface,
|
|||
float3 specular = float3(0, 0, 0);
|
||||
|
||||
// Radiance (Specular)
|
||||
float lod = surface.roughness*cubeMips;
|
||||
float lod = roughnessToMipLevel(surface.roughness, cubeMips);
|
||||
|
||||
for (i = 0; i < numProbes; ++i)
|
||||
{
|
||||
|
|
@ -468,19 +471,25 @@ float4 computeForwardProbes(Surface surface,
|
|||
}
|
||||
|
||||
//energy conservation
|
||||
float3 kD = 1.0f - surface.F;
|
||||
float3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness);
|
||||
float3 kD = 1.0f - F;
|
||||
kD *= 1.0f - surface.metalness;
|
||||
|
||||
float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex)
|
||||
float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(dfgNdotV, surface.roughness,0,0)).rg;
|
||||
specular *= surface.F * envBRDF.x + surface.f90 * envBRDF.y;
|
||||
specular *= F * envBRDF.x + surface.f90 * envBRDF.y;
|
||||
irradiance *= kD * surface.baseColor.rgb;
|
||||
|
||||
//AO
|
||||
irradiance *= surface.ao;
|
||||
specular *= computeSpecOcclusion(surface.NdotV, surface.ao, surface.roughness);
|
||||
|
||||
return float4(irradiance + specular, 0);//alpha writes disabled
|
||||
//http://marmosetco.tumblr.com/post/81245981087
|
||||
float horizonOcclusion = 1.3;
|
||||
float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N));
|
||||
horizon *= horizon;
|
||||
|
||||
return float4((irradiance + specular) * horizon, 0);//alpha writes disabled
|
||||
}
|
||||
|
||||
float4 debugVizForwardProbes(Surface surface,
|
||||
|
|
@ -583,7 +592,7 @@ float4 debugVizForwardProbes(Surface surface,
|
|||
float3 specular = float3(0, 0, 0);
|
||||
|
||||
// Radiance (Specular)
|
||||
float lod = surface.roughness*cubeMips;
|
||||
float lod = roughnessToMipLevel(surface.roughness, cubeMips);
|
||||
|
||||
if(showSpec == 1)
|
||||
{
|
||||
|
|
@ -621,17 +630,23 @@ float4 debugVizForwardProbes(Surface surface,
|
|||
}
|
||||
|
||||
//energy conservation
|
||||
float3 kD = 1.0f - surface.F;
|
||||
float3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness);
|
||||
float3 kD = 1.0f - F;
|
||||
kD *= 1.0f - surface.metalness;
|
||||
|
||||
float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex)
|
||||
float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(dfgNdotV, surface.roughness,0,0)).rg;
|
||||
specular *= surface.F * envBRDF.x + surface.f90 * envBRDF.y;
|
||||
specular *= F * envBRDF.x + surface.f90 * envBRDF.y;
|
||||
irradiance *= kD * surface.baseColor.rgb;
|
||||
|
||||
//AO
|
||||
irradiance *= surface.ao;
|
||||
specular *= computeSpecOcclusion(surface.NdotV, surface.ao, surface.roughness);
|
||||
|
||||
return float4(irradiance + specular, 0);//alpha writes disabled
|
||||
//http://marmosetco.tumblr.com/post/81245981087
|
||||
float horizonOcclusion = 1.3;
|
||||
float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N));
|
||||
horizon *= horizon;
|
||||
|
||||
return float4((irradiance + specular) * horizon, 0);//alpha writes disabled
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include "../../../gl/torque.glsl"
|
||||
#include "shadergen:/autogenConditioners.h"
|
||||
#include "../../../gl/lighting.glsl"
|
||||
#include "../../../gl/brdf.glsl"
|
||||
|
||||
#line 7
|
||||
|
||||
|
|
@ -55,11 +56,11 @@ void main()
|
|||
//early out if emissive
|
||||
if (getFlag(surface.matFlag, 0))
|
||||
{
|
||||
discard;
|
||||
return texture(colorBuffer, IN_uv0.xy);
|
||||
}
|
||||
|
||||
#ifdef USE_SSAO_MASK
|
||||
float ssao = 1.0 - texture( ssaoMask, viewportCoordToRenderTarget( uv0.xy, rtParams6 ) ).r;
|
||||
float ssao = 1.0 - texture( ssaoMask, viewportCoordToRenderTarget( IN_uv0.xy, rtParams6 ) ).r;
|
||||
surface.ao = min(surface.ao, ssao);
|
||||
#endif
|
||||
|
||||
|
|
@ -166,7 +167,7 @@ void main()
|
|||
|
||||
// Radiance (Specular)
|
||||
#if DEBUGVIZ_SPECCUBEMAP == 0
|
||||
float lod = surface.roughness*cubeMips;
|
||||
float lod = roughnessToMipLevel(surface.roughness, cubeMips);
|
||||
#elif DEBUGVIZ_SPECCUBEMAP == 1
|
||||
float lod = 0;
|
||||
#endif
|
||||
|
|
@ -177,7 +178,7 @@ void main()
|
|||
float contrib = contribution[i];
|
||||
if (contrib > 0.0f)
|
||||
{
|
||||
float cubemapIdx = probeConfigData[i].a;
|
||||
int cubemapIdx = probeConfigData[i].a;
|
||||
vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refBoxMinArray[i].xyz, refBoxMaxArray[i].xyz, inRefPosArray[i].xyz);
|
||||
|
||||
irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib;
|
||||
|
|
@ -189,8 +190,8 @@ void main()
|
|||
|
||||
if (skylightCubemapIdx != -1 && alpha > 0.001)
|
||||
{
|
||||
irradiance += textureLod(irradianceCubemapAR, vec4(surface.R, skylightCubemapIdx), 0).xyz * alpha;
|
||||
specular += textureLod(specularCubemapAR, vec4(surface.R, skylightCubemapIdx), lod).xyz * alpha;
|
||||
irradiance = lerp(irradiance,textureLod(irradianceCubemapAR, surface.R, skylightCubemapIdx, 0).xyz,alpha);
|
||||
specular = lerp(specular,textureLod(specularCubemapAR, surface.R, skylightCubemapIdx, lod).xyz,alpha);
|
||||
}
|
||||
|
||||
#if DEBUGVIZ_SPECCUBEMAP == 1 && DEBUGVIZ_DIFFCUBEMAP == 0
|
||||
|
|
@ -203,17 +204,23 @@ void main()
|
|||
|
||||
|
||||
//energy conservation
|
||||
vec3 kD = 1.0f - surface.F;
|
||||
vec3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness);
|
||||
vec3 kD = 1.0f - F;
|
||||
kD *= 1.0f - surface.metalness;
|
||||
|
||||
float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex)
|
||||
vec2 envBRDF = textureLod(BRDFTexture, vec2(dfgNdotV, surface.roughness),0).rg;
|
||||
specular *= surface.F * envBRDF.x + surface.f90 * envBRDF.y;
|
||||
specular *= F * envBRDF.x + surface.f90 * envBRDF.y;
|
||||
irradiance *= kD * surface.baseColor.rgb;
|
||||
|
||||
//AO
|
||||
irradiance *= surface.ao;
|
||||
specular *= computeSpecOcclusion(surface.NdotV, surface.ao, surface.roughness);
|
||||
|
||||
//http://marmosetco.tumblr.com/post/81245981087
|
||||
float horizonOcclusion = 1.3;
|
||||
float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N));
|
||||
horizon *= horizon;
|
||||
|
||||
OUT_col = vec4(irradiance + specular, 0);//alpha writes disabled
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "../../shaderModel.hlsl"
|
||||
#include "../../shaderModelAutoGen.hlsl"
|
||||
#include "../../lighting.hlsl"
|
||||
#include "../../brdf.hlsl"
|
||||
|
||||
TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0);
|
||||
TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 1);
|
||||
|
|
@ -159,7 +160,7 @@ float4 main(PFXVertToPix IN) : SV_TARGET
|
|||
|
||||
// Radiance (Specular)
|
||||
#if DEBUGVIZ_SPECCUBEMAP == 0
|
||||
float lod = surface.roughness*cubeMips;
|
||||
float lod = roughnessToMipLevel(surface.roughness, cubeMips);
|
||||
#elif DEBUGVIZ_SPECCUBEMAP == 1
|
||||
float lod = 0;
|
||||
#endif
|
||||
|
|
@ -193,17 +194,23 @@ float4 main(PFXVertToPix IN) : SV_TARGET
|
|||
#endif
|
||||
|
||||
//energy conservation
|
||||
float3 kD = 1.0f - surface.F;
|
||||
float3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness);
|
||||
float3 kD = 1.0f - F;
|
||||
kD *= 1.0f - surface.metalness;
|
||||
|
||||
float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex)
|
||||
float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(dfgNdotV, surface.roughness,0,0)).rg;
|
||||
specular *= surface.F * envBRDF.x + surface.f90 * envBRDF.y;
|
||||
specular *= F * envBRDF.x + surface.f90 * envBRDF.y;
|
||||
irradiance *= kD * surface.baseColor.rgb;
|
||||
|
||||
//AO
|
||||
irradiance *= surface.ao;
|
||||
specular *= computeSpecOcclusion(surface.NdotV, surface.ao, surface.roughness);
|
||||
|
||||
return float4(irradiance + specular, 0);//alpha writes disabled
|
||||
//http://marmosetco.tumblr.com/post/81245981087
|
||||
float horizonOcclusion = 1.3;
|
||||
float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N));
|
||||
horizon *= horizon;
|
||||
|
||||
return float4((irradiance + specular) * horizon, 0);//alpha writes disabled
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue