From 27fe8d42ae38d039723c0f5e3325e49ad7b90b4e Mon Sep 17 00:00:00 2001 From: "glassmancody.info" Date: Thu, 19 Jan 2023 08:39:38 -0800 Subject: [PATCH] fix pass normals --- apps/openmw/mwrender/npcanimation.cpp | 12 ++++++++--- files/data/shaders/debug.omwfx | 2 +- files/shaders/groundcover_fragment.glsl | 12 +++++------ files/shaders/nv_default_fragment.glsl | 16 +++++++-------- files/shaders/objects_fragment.glsl | 25 +++++++++-------------- files/shaders/terrain_fragment.glsl | 27 +++++++++---------------- files/shaders/water_fragment.glsl | 2 +- 7 files changed, 42 insertions(+), 54 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index d019e65b5f..7447b9f280 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -313,8 +313,9 @@ namespace MWRender class DepthClearCallback : public osgUtil::RenderBin::DrawCallback { public: - DepthClearCallback() + DepthClearCallback(Resource::ResourceSystem* resourceSystem) { + mPassNormals = resourceSystem->getSceneManager()->getSupportsNormalsRT(); mDepth = new SceneUtil::AutoDepth; mDepth->setWriteMask(true); @@ -337,7 +338,11 @@ namespace MWRender if (postProcessor && postProcessor->getFbo(PostProcessor::FBO_FirstPerson, frameId)) { postProcessor->getFbo(PostProcessor::FBO_FirstPerson, frameId)->apply(*state); - + if (mPassNormals) + { + state->get()->glColorMaski(1, true, true, true, true); + state->haveAppliedAttribute(osg::StateAttribute::COLORMASK); + } glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // color accumulation pass bin->drawImplementation(renderInfo, previous); @@ -368,6 +373,7 @@ namespace MWRender state->checkGLErrors("after DepthClearCallback::drawImplementation"); } + bool mPassNormals; osg::ref_ptr mDepth; osg::ref_ptr mStateSet; }; @@ -416,7 +422,7 @@ namespace MWRender if (!prototypeAdded) { osg::ref_ptr depthClearBin(new osgUtil::RenderBin); - depthClearBin->setDrawCallback(new DepthClearCallback); + depthClearBin->setDrawCallback(new DepthClearCallback(mResourceSystem)); osgUtil::RenderBin::addRenderBinPrototype("DepthClear", depthClearBin); prototypeAdded = true; } diff --git a/files/data/shaders/debug.omwfx b/files/data/shaders/debug.omwfx index 4bfeea2499..360dfa26cd 100644 --- a/files/data/shaders/debug.omwfx +++ b/files/data/shaders/debug.omwfx @@ -31,7 +31,7 @@ fragment main { omw_FragColor = vec4(vec3(omw_GetLinearDepth(omw_TexCoord) / omw.far * uDepthFactor), 1.0); #if OMW_NORMALS if (uDisplayNormals && (!uDisplayDepth || omw_TexCoord.x < 0.5)) - omw_FragColor.rgb = omw_GetNormals(omw_TexCoord); + omw_FragColor.rgb = omw_GetNormals(omw_TexCoord) * 0.5 + 0.5; #endif } } diff --git a/files/shaders/groundcover_fragment.glsl b/files/shaders/groundcover_fragment.glsl index 0bdc3d915d..f8599ecaa8 100644 --- a/files/shaders/groundcover_fragment.glsl +++ b/files/shaders/groundcover_fragment.glsl @@ -45,19 +45,19 @@ varying vec3 passNormal; void main() { - vec3 worldNormal = normalize(passNormal); + vec3 normal = normalize(passNormal); #if @normalMap vec4 normalTex = texture2D(normalMap, normalMapUV); - vec3 normalizedNormal = worldNormal; + vec3 normalizedNormal = normal; vec3 normalizedTangent = normalize(passTangent.xyz); vec3 binormal = cross(normalizedTangent, normalizedNormal) * passTangent.w; mat3 tbnTranspose = mat3(normalizedTangent, binormal, normalizedNormal); - worldNormal = normalize(tbnTranspose * (normalTex.xyz * 2.0 - 1.0)); - vec3 viewNormal = gl_NormalMatrix * worldNormal; + normal = normalize(tbnTranspose * (normalTex.xyz * 2.0 - 1.0)); #endif + vec3 viewNormal = normalize(gl_NormalMatrix * normal); #if @diffuseMap gl_FragData[0] = texture2D(diffuseMap, diffuseMapUV); @@ -77,7 +77,7 @@ void main() lighting = passLighting + shadowDiffuseLighting * shadowing; #else vec3 diffuseLight, ambientLight; - doLighting(passViewPos, normalize(viewNormal), shadowing, diffuseLight, ambientLight); + doLighting(passViewPos, viewNormal, shadowing, diffuseLight, ambientLight); lighting = diffuseLight + ambientLight; #endif @@ -87,7 +87,7 @@ void main() gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth); #if !@disableNormals - gl_FragData[1].xyz = worldNormal * 0.5 + 0.5; + gl_FragData[1].xyz = viewNormal * 0.5 + 0.5; #endif applyShadowDebugOverlay(); diff --git a/files/shaders/nv_default_fragment.glsl b/files/shaders/nv_default_fragment.glsl index 57ef7b14df..565e76357d 100644 --- a/files/shaders/nv_default_fragment.glsl +++ b/files/shaders/nv_default_fragment.glsl @@ -46,7 +46,7 @@ uniform float specStrength; void main() { - vec3 worldNormal = normalize(passNormal); + vec3 normal = normalize(passNormal); #if @diffuseMap gl_FragData[0] = texture2D(diffuseMap, diffuseMapUV); @@ -62,20 +62,18 @@ void main() #if @normalMap vec4 normalTex = texture2D(normalMap, normalMapUV); - vec3 normalizedNormal = worldNormal; + vec3 normalizedNormal = normal; vec3 normalizedTangent = normalize(passTangent.xyz); vec3 binormal = cross(normalizedTangent, normalizedNormal) * passTangent.w; mat3 tbnTranspose = mat3(normalizedTangent, binormal, normalizedNormal); - worldNormal = normalize(tbnTranspose * (normalTex.xyz * 2.0 - 1.0)); - vec3 viewNormal = gl_NormalMatrix * worldNormal; -#else - vec3 viewNormal = gl_NormalMatrix * worldNormal; + normal = normalize(tbnTranspose * (normalTex.xyz * 2.0 - 1.0)); #endif + vec3 viewNormal = normalize(gl_NormalMatrix * normal); float shadowing = unshadowedLightRatio(linearDepth); vec3 diffuseLight, ambientLight; - doLighting(passViewPos, normalize(viewNormal), shadowing, diffuseLight, ambientLight); + doLighting(passViewPos, viewNormal, shadowing, diffuseLight, ambientLight); vec3 emission = getEmissionColor().xyz * emissiveMult; #if @emissiveMap emission *= texture2D(emissiveMap, emissiveMapUV).xyz; @@ -93,7 +91,7 @@ void main() #endif if (matSpec != vec3(0.0)) - gl_FragData[0].xyz += getSpecular(normalize(viewNormal), normalize(passViewPos.xyz), shininess, matSpec) * shadowing; + gl_FragData[0].xyz += getSpecular(viewNormal, normalize(passViewPos.xyz), shininess, matSpec) * shadowing; gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth); @@ -103,7 +101,7 @@ void main() #endif #if !defined(FORCE_OPAQUE) && !@disableNormals - gl_FragData[1].xyz = worldNormal * 0.5 + 0.5; + gl_FragData[1].xyz = viewNormal * 0.5 + 0.5; #endif applyShadowDebugOverlay(); diff --git a/files/shaders/objects_fragment.glsl b/files/shaders/objects_fragment.glsl index f05ff8eba8..c0a8fc9e26 100644 --- a/files/shaders/objects_fragment.glsl +++ b/files/shaders/objects_fragment.glsl @@ -120,23 +120,18 @@ void main() vec2 adjustedDiffuseUV = diffuseMapUV; #endif - vec3 worldNormal = normalize(passNormal); + vec3 normal = normalize(passNormal); vec3 viewVec = normalize(passViewPos.xyz); #if @normalMap vec4 normalTex = texture2D(normalMap, normalMapUV); - vec3 normalizedNormal = worldNormal; + vec3 normalizedNormal = normal; vec3 normalizedTangent = normalize(passTangent.xyz); vec3 binormal = cross(normalizedTangent, normalizedNormal) * passTangent.w; mat3 tbnTranspose = mat3(normalizedTangent, binormal, normalizedNormal); - worldNormal = normalize(tbnTranspose * (normalTex.xyz * 2.0 - 1.0)); - vec3 viewNormal = gl_NormalMatrix * worldNormal; -#endif - -#if (!@normalMap && (@parallax || @forcePPL || @softParticles)) - vec3 viewNormal = gl_NormalMatrix * worldNormal; + normal = normalize(tbnTranspose * (normalTex.xyz * 2.0 - 1.0)); #endif #if @parallax @@ -152,12 +147,13 @@ void main() // fetch a new normal using updated coordinates normalTex = texture2D(normalMap, adjustedDiffuseUV); - worldNormal = normalize(tbnTranspose * (normalTex.xyz * 2.0 - 1.0)); - viewNormal = gl_NormalMatrix * worldNormal; + normal = normalize(tbnTranspose * (normalTex.xyz * 2.0 - 1.0)); #endif #endif +vec3 viewNormal = normalize(gl_NormalMatrix * normal); + #if @diffuseMap gl_FragData[0] = texture2D(diffuseMap, adjustedDiffuseUV); gl_FragData[0].a *= coveragePreservingAlphaScale(diffuseMap, adjustedDiffuseUV); @@ -220,7 +216,7 @@ void main() lighting = passLighting + shadowDiffuseLighting * shadowing; #else vec3 diffuseLight, ambientLight; - doLighting(passViewPos, normalize(viewNormal), shadowing, diffuseLight, ambientLight); + doLighting(passViewPos, viewNormal, shadowing, diffuseLight, ambientLight); vec3 emission = getEmissionColor().xyz * emissiveMult; lighting = diffuseColor.xyz * diffuseLight + getAmbientColor().xyz * ambientLight + emission; #endif @@ -249,10 +245,7 @@ void main() matSpec *= specStrength; if (matSpec != vec3(0.0)) { -#if (!@normalMap && !@parallax && !@forcePPL) - vec3 viewNormal = gl_NormalMatrix * worldNormal; -#endif - gl_FragData[0].xyz += getSpecular(normalize(viewNormal), viewVec, shininess, matSpec) * shadowing; + gl_FragData[0].xyz += getSpecular(viewNormal, viewVec, shininess, matSpec) * shadowing; } gl_FragData[0] = applyFogAtPos(gl_FragData[0], passViewPos); @@ -267,7 +260,7 @@ void main() #endif #if !defined(FORCE_OPAQUE) && !@disableNormals - gl_FragData[1].xyz = worldNormal * 0.5 + 0.5; + gl_FragData[1].xyz = viewNormal * 0.5 + 0.5; #endif applyShadowDebugOverlay(); diff --git a/files/shaders/terrain_fragment.glsl b/files/shaders/terrain_fragment.glsl index 1e72cf5828..831e653878 100644 --- a/files/shaders/terrain_fragment.glsl +++ b/files/shaders/terrain_fragment.glsl @@ -44,24 +44,18 @@ void main() { vec2 adjustedUV = (gl_TextureMatrix[0] * vec4(uv, 0.0, 1.0)).xy; - vec3 worldNormal = normalize(passNormal); + vec3 normal = normalize(passNormal); #if @normalMap vec4 normalTex = texture2D(normalMap, adjustedUV); - vec3 normalizedNormal = worldNormal; + vec3 normalizedNormal = normal; vec3 tangent = vec3(1.0, 0.0, 0.0); vec3 binormal = normalize(cross(tangent, normalizedNormal)); tangent = normalize(cross(normalizedNormal, binormal)); // note, now we need to re-cross to derive tangent again because it wasn't orthonormal mat3 tbnTranspose = mat3(tangent, binormal, normalizedNormal); - worldNormal = tbnTranspose * (normalTex.xyz * 2.0 - 1.0); - vec3 viewNormal = normalize(gl_NormalMatrix * worldNormal); - normalize(worldNormal); -#endif - -#if (!@normalMap && (@parallax || @forcePPL)) - vec3 viewNormal = gl_NormalMatrix * worldNormal; + normal = tbnTranspose * (normalTex.xyz * 2.0 - 1.0); #endif #if @parallax @@ -73,11 +67,11 @@ void main() // update normal using new coordinates normalTex = texture2D(normalMap, adjustedUV); - worldNormal = tbnTranspose * (normalTex.xyz * 2.0 - 1.0); - viewNormal = normalize(gl_NormalMatrix * worldNormal); - normalize(worldNormal); + normal = tbnTranspose * (normalTex.xyz * 2.0 - 1.0); #endif + vec3 viewNormal = normalize(gl_NormalMatrix * normal); + vec4 diffuseTex = texture2D(diffuseMap, adjustedUV); gl_FragData[0] = vec4(diffuseTex.xyz, 1.0); @@ -95,7 +89,7 @@ void main() lighting = passLighting + shadowDiffuseLighting * shadowing; #else vec3 diffuseLight, ambientLight; - doLighting(passViewPos, normalize(viewNormal), shadowing, diffuseLight, ambientLight); + doLighting(passViewPos, viewNormal, shadowing, diffuseLight, ambientLight); lighting = diffuseColor.xyz * diffuseLight + getAmbientColor().xyz * ambientLight + getEmissionColor().xyz; #endif @@ -113,16 +107,13 @@ void main() if (matSpec != vec3(0.0)) { -#if (!@normalMap && !@parallax && !@forcePPL) - vec3 viewNormal = gl_NormalMatrix * worldNormal; -#endif - gl_FragData[0].xyz += getSpecular(normalize(viewNormal), normalize(passViewPos), shininess, matSpec) * shadowing; + gl_FragData[0].xyz += getSpecular(viewNormal, normalize(passViewPos), shininess, matSpec) * shadowing; } gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth); #if !@disableNormals && @writeNormals - gl_FragData[1].xyz = worldNormal.xyz * 0.5 + 0.5; + gl_FragData[1].xyz = viewNormal * 0.5 + 0.5; #endif applyShadowDebugOverlay(); diff --git a/files/shaders/water_fragment.glsl b/files/shaders/water_fragment.glsl index f60ec765b1..5849511316 100644 --- a/files/shaders/water_fragment.glsl +++ b/files/shaders/water_fragment.glsl @@ -360,7 +360,7 @@ void main(void) gl_FragData[0] = applyFogAtDist(gl_FragData[0], radialDepth, linearDepth); #if !@disableNormals - gl_FragData[1].rgb = normal * 0.5 + 0.5; + gl_FragData[1].rgb = normalize(gl_NormalMatrix * normal) * 0.5 + 0.5; #endif applyShadowDebugOverlay();