diff -U2 -r /var/lib/copr-rpmbuild/results/openmw-git/upstream-unpacked/Source0/openmw-master/apps/openmw/mwrender/postprocessor.cpp /var/lib/copr-rpmbuild/results/openmw-git/srpm-unpacked/openmw-master.tar.bz2-extract/openmw-master/apps/openmw/mwrender/postprocessor.cpp --- /var/lib/copr-rpmbuild/results/openmw-git/upstream-unpacked/Source0/openmw-master/apps/openmw/mwrender/postprocessor.cpp 2026-08-21 00:18:33.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/openmw-git/srpm-unpacked/openmw-master.tar.bz2-extract/openmw-master/apps/openmw/mwrender/postprocessor.cpp 2026-08-20 21:04:05.000000000 +0000 @@ -462,9 +462,6 @@ } - // f16 normals: u8 isn't quite accurate enough even for opaque objects, but now we also - // need to blend terrain normals, and it's additive, so now u8 rounding losses would pile up. textures[Tex_Normal]->setSourceFormat(GL_RGB); - textures[Tex_Normal]->setSourceType(GL_HALF_FLOAT); - textures[Tex_Normal]->setInternalFormat(GL_RGB16F); + textures[Tex_Normal]->setInternalFormat(GL_RGB); textures[Tex_Distortion]->setSourceFormat(GL_RGB); diff -U2 -r /var/lib/copr-rpmbuild/results/openmw-git/upstream-unpacked/Source0/openmw-master/components/terrain/material.cpp /var/lib/copr-rpmbuild/results/openmw-git/srpm-unpacked/openmw-master.tar.bz2-extract/openmw-master/components/terrain/material.cpp --- /var/lib/copr-rpmbuild/results/openmw-git/upstream-unpacked/Source0/openmw-master/components/terrain/material.cpp 2026-08-21 00:18:33.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/openmw-git/srpm-unpacked/openmw-master.tar.bz2-extract/openmw-master/components/terrain/material.cpp 2026-08-20 21:04:05.000000000 +0000 @@ -198,6 +198,6 @@ { stateset->setMode(GL_BLEND, osg::StateAttribute::ON); - // This pass needs normals-buffer blending. - stateset->setAttribute(new osg::Enablei(GL_BLEND, 1)); + if (sceneManager->getSupportsNormalsRT()) + stateset->setAttribute(new osg::Disablei(GL_BLEND, 1)); stateset->setRenderBinDetails(firstLayer ? 0 : 1, "RenderBin"); if (!firstLayer) @@ -264,4 +264,5 @@ defineMap["specularMap"] = it->mSpecular ? "1" : "0"; defineMap["parallax"] = parallax ? "1" : "0"; + defineMap["writeNormals"] = (it == layers.end() - 1) ? "1" : "0"; defineMap["reconstructNormalZ"] = reconstructNormalZ ? "1" : "0"; Stereo::shaderStereoDefines(defineMap); diff -U2 -r /var/lib/copr-rpmbuild/results/openmw-git/upstream-unpacked/Source0/openmw-master/files/shaders/compatibility/terrain.frag /var/lib/copr-rpmbuild/results/openmw-git/srpm-unpacked/openmw-master.tar.bz2-extract/openmw-master/files/shaders/compatibility/terrain.frag --- /var/lib/copr-rpmbuild/results/openmw-git/upstream-unpacked/Source0/openmw-master/files/shaders/compatibility/terrain.frag 2026-08-21 00:18:33.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/openmw-git/srpm-unpacked/openmw-master.tar.bz2-extract/openmw-master/files/shaders/compatibility/terrain.frag 2026-08-20 21:04:05.000000000 +0000 @@ -103,7 +103,6 @@ gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth, near, far); -#if !@disableNormals - // Terrain normals are now additively blended the same way as terrain color is, thus using color's alpha. - gl_FragData[1] = vec4(viewNormal * 0.5 + 0.5, gl_FragData[0].a); +#if !@disableNormals && @writeNormals + gl_FragData[1].xyz = viewNormal * 0.5 + 0.5; #endif