Merge pull request #7995 from samcake/blue

Fix the jittering reflection bug and more Normal improvments
This commit is contained in:
Brad Hefta-Gaub 2016-06-02 14:13:44 -07:00
commit 326aa639fc
19 changed files with 133 additions and 56 deletions

View file

@ -25,24 +25,43 @@ layout(location = 2) out vec4 _fragColor2;
// the alpha threshold
uniform float alphaThreshold;
uniform sampler2D normalFittingMap;
vec3 bestFitNormal(vec3 normal) {
vec3 absNorm = abs(normal);
float maxNAbs = max(absNorm.z, max(absNorm.x, absNorm.y));
vec2 signNotZero(vec2 v) {
return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);
}
vec2 texcoord = (absNorm.z < maxNAbs ?
(absNorm.y < maxNAbs ? absNorm.yz : absNorm.xz) :
absNorm.xy);
texcoord = (texcoord.x < texcoord.y ? texcoord.yx : texcoord.xy);
texcoord.y /= texcoord.x;
vec3 cN = normal / maxNAbs;
float fittingScale = texture(normalFittingMap, texcoord).a;
cN *= fittingScale;
return (cN * 0.5 + 0.5);
vec2 float32x3_to_oct(in vec3 v) {
vec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));
return ((v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p);
}
vec3 oct_to_float32x3(in vec2 e) {
vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
if (v.z < 0) {
v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);
}
return normalize(v);
}
vec3 snorm12x2_to_unorm8x3(vec2 f) {
vec2 u = vec2(round(clamp(f, -1.0, 1.0) * 2047.0 + 2047.0));
float t = floor(u.y / 256.0);
return floor(vec3(
u.x / 16.0,
fract(u.x / 16.0) * 256.0 + t,
u.y - t * 256.0
)) / 255.0;
}
vec2 unorm8x3_to_snorm12x2(vec3 u) {
u *= 255.0;
u.y *= (1.0 / 16.0);
vec2 s = vec2( u.x * 16.0 + floor(u.y),
fract(u.y) * (16.0 * 256.0) + u.z);
return clamp(s * (1.0 / 2047.0) - 1.0, vec2(-1.0), vec2(1.0));
}
float mod289(float x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
@ -322,7 +341,7 @@ void main(void) {
}
vec4 diffuse = vec4(_color.rgb, alpha);
vec4 normal = vec4(normalize(bestFitNormal(_normal)), 0.5);
vec4 normal = vec4(packNormal(normalize(_normal)), 0.5);
_fragColor0 = diffuse;
_fragColor1 = normal;
@ -355,7 +374,7 @@ void main(void) {
float emissiveAmount = getProceduralColors(diffuse, specular, shininess);
_fragColor0 = vec4(diffuse.rgb, 1.0);
_fragColor1 = vec4(bestFitNormal(normalize(_normal.xyz)), 1.0 - (emissiveAmount / 2.0));
_fragColor1 = vec4(packNormal(normalize(_normal.xyz)), 1.0 - (emissiveAmount / 2.0));
_fragColor2 = vec4(specular, shininess / 128.0);
}
)SCRIBE";

View file

@ -119,6 +119,15 @@ TransformObject getTransformObject() {
}
<@endfunc@>
<@func transformModelToWorldDir(cameraTransform, objectTransform, modelDir, worldDir)@>
{ // transformModelToEyeDir
vec3 mr0 = <$objectTransform$>._modelInverse[0].xyz;
vec3 mr1 = <$objectTransform$>._modelInverse[1].xyz;
vec3 mr2 = <$objectTransform$>._modelInverse[2].xyz;
<$worldDir$> = vec3(dot(mr0, <$modelDir$>), dot(mr1, <$modelDir$>), dot(mr2, <$modelDir$>));
}
<@endfunc@>
<@func transformModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@>
{ // transformModelToEyeDir

View file

@ -51,4 +51,70 @@ float packUnlit() {
return FRAG_PACK_UNLIT;
}
vec2 signNotZero(vec2 v) {
return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);
}
vec2 float32x3_to_oct(in vec3 v) {
vec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));
return ((v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p);
}
vec3 oct_to_float32x3(in vec2 e) {
vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
if (v.z < 0) {
v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);
}
return normalize(v);
}
vec3 snorm12x2_to_unorm8x3(vec2 f) {
vec2 u = vec2(round(clamp(f, -1.0, 1.0) * 2047.0 + 2047.0));
float t = floor(u.y / 256.0);
return floor(vec3(
u.x / 16.0,
fract(u.x / 16.0) * 256.0 + t,
u.y - t * 256.0
)) / 255.0;
}
vec2 unorm8x3_to_snorm12x2(vec3 u) {
u *= 255.0;
u.y *= (1.0 / 16.0);
vec2 s = vec2( u.x * 16.0 + floor(u.y),
fract(u.y) * (16.0 * 256.0) + u.z);
return clamp(s * (1.0 / 2047.0) - 1.0, vec2(-1.0), vec2(1.0));
}
uniform sampler2D normalFittingMap;
vec3 bestFitNormal(vec3 normal) {
vec3 absNorm = abs(normal);
float maxNAbs = max(absNorm.z, max(absNorm.x, absNorm.y));
vec2 texcoord = (absNorm.z < maxNAbs ?
(absNorm.y < maxNAbs ? absNorm.yz : absNorm.xz) :
absNorm.xy);
texcoord = (texcoord.x < texcoord.y ? texcoord.yx : texcoord.xy);
texcoord.y /= texcoord.x;
vec3 cN = normal / maxNAbs;
float fittingScale = texture(normalFittingMap, texcoord).a;
cN *= fittingScale;
return (cN * 0.5 + 0.5);
}
vec3 packNormal(in vec3 n) {
return snorm12x2_to_unorm8x3(float32x3_to_oct(n));
}
vec3 unpackNormal(in vec3 p) {
return oct_to_float32x3(unorm8x3_to_snorm12x2(p));
}
<@endif@>

View file

@ -100,7 +100,7 @@ DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) {
frag.obscurance = texture(obscuranceMap, texcoord).x;
// Unpack the normal from the map
frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0));
frag.normal = unpackNormal(frag.normalVal.xyz);
frag.roughness = frag.normalVal.a;
// Diffuse color and unpack the mode and the metallicness

View file

@ -17,24 +17,6 @@ layout(location = 0) out vec4 _fragColor0;
layout(location = 1) out vec4 _fragColor1;
layout(location = 2) out vec4 _fragColor2;
uniform sampler2D normalFittingMap;
vec3 bestFitNormal(vec3 normal) {
vec3 absNorm = abs(normal);
float maxNAbs = max(absNorm.z, max(absNorm.x, absNorm.y));
vec2 texcoord = (absNorm.z < maxNAbs ?
(absNorm.y < maxNAbs ? absNorm.yz : absNorm.xz) :
absNorm.xy);
texcoord = (texcoord.x < texcoord.y ? texcoord.yx : texcoord.xy);
texcoord.y /= texcoord.x;
vec3 cN = normal / maxNAbs;
float fittingScale = texture(normalFittingMap, texcoord).a;
cN *= fittingScale;
return (cN * 0.5 + 0.5);
}
// the alpha threshold
const float alphaThreshold = 0.5;
@ -55,7 +37,7 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness
discard;
}
_fragColor0 = vec4(albedo, packShadedMetallic(metallic));
_fragColor1 = vec4(bestFitNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor2 = vec4(emissive, occlusion);
}
@ -65,7 +47,7 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float r
discard;
}
_fragColor0 = vec4(albedo, packLightmappedMetallic(metallic));
_fragColor1 = vec4(bestFitNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor2 = vec4(emissive, 1.0);
}
@ -74,7 +56,7 @@ void packDeferredFragmentUnlit(vec3 normal, float alpha, vec3 color) {
discard;
}
_fragColor0 = vec4(color, packUnlit());
_fragColor1 = vec4(bestFitNormal(normal), 1.0);
_fragColor1 = vec4(packNormal(normal), 1.0);
//_fragColor2 = vec4(vec3(0.0), 1.0); // If unlit, do not worry about the emissive color target
}

View file

@ -66,7 +66,8 @@ vec3 evalGlobalSpecularIrradiance(Light light, vec3 fragEyeDir, vec3 fragNormal,
// prepareGlobalLight
// Transform directions to worldspace
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
// vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
vec3 fragNormal = vec3((normal));
vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0));
vec3 fragEyeDir = normalize(fragEyeVector);

View file

@ -59,8 +59,8 @@ void FramebufferCache::createPrimaryFramebuffer() {
_deferredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
_deferredFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create());
// auto colorFormat = gpu::Element::COLOR_RGBA_32;
auto colorFormat = gpu::Element::COLOR_SRGBA_32;
auto linearFormat = gpu::Element::COLOR_RGBA_32;
auto width = _frameBufferSize.width();
auto height = _frameBufferSize.height();
@ -70,7 +70,8 @@ void FramebufferCache::createPrimaryFramebuffer() {
_primaryFramebuffer->setRenderBuffer(0, _primaryColorTexture);
_deferredColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_deferredNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_deferredNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(linearFormat, width, height, defaultSampler));
_deferredSpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_deferredFramebuffer->setRenderBuffer(0, _deferredColorTexture);

View file

@ -36,5 +36,5 @@ void main(void) {
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
}

View file

@ -39,6 +39,6 @@ void main(void) {
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
}

View file

@ -39,6 +39,6 @@ void main(void) {
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
<$transformModelToEyeDir(cam, obj, inTangent.xyz, _tangent)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangent)$>
}

View file

@ -39,6 +39,6 @@ void main(void) {
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
<$transformModelToEyeDir(cam, obj, inTangent.xyz, _tangent)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangent)$>
}

View file

@ -32,5 +32,5 @@ void main(void) {
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
}

View file

@ -61,7 +61,7 @@ void main(void) {
vec3 fragLightDir = fragLightVec / fragLightDistance;
// Eval shading
vec3 fragNormal = vec3(invViewMat * vec4(frag.normal, 0.0));
vec3 fragNormal = vec3(frag.normal);
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
vec4 shading = evalFragShading(fragNormal, fragLightDir, fragEyeDir, frag.metallic, frag.specular, frag.roughness);

View file

@ -27,5 +27,5 @@ void main() {
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal.xyz)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal.xyz)$>
}

View file

@ -34,5 +34,5 @@ void main(void) {
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
}

View file

@ -45,6 +45,5 @@ void main(void) {
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToEyeAndClipPos(cam, obj, position, _position, gl_Position)$>
<$transformModelToEyeDir(cam, obj, interpolatedNormal.xyz, interpolatedNormal.xyz)$>
_normal = interpolatedNormal.xyz;
<$transformModelToWorldDir(cam, obj, interpolatedNormal.xyz, _normal.xyz)$>
}

View file

@ -50,8 +50,8 @@ void main(void) {
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToEyeAndClipPos(cam, obj, position, _position, gl_Position)$>
<$transformModelToEyeDir(cam, obj, interpolatedNormal.xyz, interpolatedNormal.xyz)$>
<$transformModelToEyeDir(cam, obj, interpolatedTangent.xyz, interpolatedTangent.xyz)$>
<$transformModelToWorldDir(cam, obj, interpolatedNormal.xyz, interpolatedNormal.xyz)$>
<$transformModelToWorldDir(cam, obj, interpolatedTangent.xyz, interpolatedTangent.xyz)$>
_normal = interpolatedNormal.xyz;
_tangent = interpolatedTangent.xyz;

View file

@ -68,7 +68,7 @@ void main(void) {
}
// Eval shading
vec3 fragNormal = vec3(invViewMat * vec4(frag.normal, 0.0));
vec3 fragNormal = vec3(frag.normal);
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
vec4 shading = evalFragShading(fragNormal, fragLightDir, fragEyeDir, frag.metallic, frag.specular, frag.roughness);

View file

@ -30,6 +30,6 @@ void main(void) {
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
<$transformModelToEyeDir(cam, obj, inNormal.xyz, varNormal)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, varNormal)$>
varPosition = inPosition.xyz;
}