diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index c27dce6cad..139b69c104 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -45,7 +45,7 @@ namespace MWRender // Setting this to 0 seems to cause glitches though. :/ mTerrainGlobals->setMaxPixelError(1); - mTerrainGlobals->setLayerBlendMapSize(32); + mTerrainGlobals->setLayerBlendMapSize(ESM::Land::LAND_TEXTURE_SIZE/2 + 1); //10 (default) didn't seem to be quite enough mTerrainGlobals->setSkirtSize(128); @@ -352,9 +352,9 @@ namespace MWRender } //covert the ltex data into a set of blend maps - for ( int texY = fromY - 1; texY < fromY + size + 1; texY++ ) + for ( int texY = fromY; texY < fromY + size + 1; texY++ ) { - for ( int texX = fromX - 1; texX < fromX + size + 1; texX++ ) + for ( int texX = fromX - 1; texX < fromX + size; texX++ ) // NB we wrap X from the other side because Y is reversed { const uint16_t ltexIndex = getLtexIndexAt(cellX, cellY, texX, texY); @@ -367,7 +367,7 @@ namespace MWRender //while texX is the splat index relative to the entire cell, //relX is relative to the current segment we are splatting - const int relX = texX - fromX; + const int relX = texX - fromX + 1; const int relY = texY - fromY; const int layerIndex = indexes.find(ltexIndex)->second; @@ -375,35 +375,15 @@ namespace MWRender float* const pBlend = terrain->getLayerBlendMap(layerIndex) ->getBlendPointer(); - for ( int y = -1; y < splatSize + 1; y++ ) - { - for ( int x = -1; x < splatSize + 1; x++ ) - { - //Note: Y is reversed - const int splatY = blendMapSize - 1 - relY * splatSize - y; - const int splatX = relX * splatSize + x; + const int splatY = blendMapSize - relY - 1; + const int splatX = relX; - if ( splatX >= 0 && splatX < blendMapSize && - splatY >= 0 && splatY < blendMapSize ) - { - const int index = (splatY)*blendMapSize + splatX; + assert(splatX >= 0 && splatX < blendMapSize); + assert(splatY >= 0 && splatY < blendMapSize); - if ( y >= 0 && y < splatSize && - x >= 0 && x < splatSize ) - { - pBlend[index] = 1; - } - else - { - //this provides a transition shading but also - //rounds off the corners slightly - pBlend[index] = std::min(1.0f, pBlend[index] + 0.5f); - } - } - - } - } + const int index = (splatY)*blendMapSize + splatX; + pBlend[index] = 1; } } diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index 58146118e9..1330229570 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -205,7 +205,6 @@ shUniform(float, waterLevel) @shSharedParameter(waterLevel) #endif - SH_START_PROGRAM { @@ -232,35 +231,46 @@ float previousAlpha = 1.f; #endif // Layer calculations +// rescale UV to directly map vertices to texel centers +// TODO: parameterize texel size +float2 blendUV = (UV - 0.5) * (8.0 / (8.0+1.0)) + 0.5; @shForeach(@shPropertyString(num_blendmaps)) - float4 blendValues@shIterator = shSample(blendMap@shIterator, UV); + float4 blendValues@shIterator = shSample(blendMap@shIterator, blendUV); @shEndForeach float3 albedo = float3(0,0,0); + + float2 layerUV = UV * 8; + @shForeach(@shPropertyString(num_layers)) #if IS_FIRST_PASS #if @shIterator == 0 // first layer of first pass is the base layer and doesn't need a blend map - albedo = shSample(diffuseMap0, UV * 10).rgb; + albedo = shSample(diffuseMap0, layerUV).rgb; #else - albedo = shLerp(albedo, shSample(diffuseMap@shIterator, UV * 10).rgb, blendValues@shPropertyString(blendmap_component_@shIterator)); + albedo = shLerp(albedo, shSample(diffuseMap@shIterator, layerUV).rgb, blendValues@shPropertyString(blendmap_component_@shIterator)); #endif #else #if @shIterator == 0 - albedo = shSample(diffuseMap@shIterator, UV * 10).rgb, blendValues@shPropertyString(blendmap_component_@shIterator); + albedo = shSample(diffuseMap@shIterator, layerUV).rgb, blendValues@shPropertyString(blendmap_component_@shIterator); #else - albedo = shLerp(albedo, shSample(diffuseMap@shIterator, UV * 10).rgb, blendValues@shPropertyString(blendmap_component_@shIterator)); + albedo = shLerp(albedo, shSample(diffuseMap@shIterator, layerUV).rgb, blendValues@shPropertyString(blendmap_component_@shIterator)); #endif previousAlpha *= 1.f-blendValues@shPropertyString(blendmap_component_@shIterator); #endif @shEndForeach shOutputColour(0) = float4(1,1,1,1); + #if COLOUR_MAP - shOutputColour(0).rgb *= shSample(colourMap, UV).rgb; + // Since we're emulating vertex colors here, + // rescale UV to directly map vertices to texel centers. TODO: parameterize texel size + const float colourmapSize = 33.f; + float2 colourUV = (UV - 0.5) * (colourmapSize / (colourmapSize+1.f)) + 0.5; + shOutputColour(0).rgb *= shSample(colourMap, colourUV).rgb; #endif shOutputColour(0).rgb *= albedo; @@ -347,6 +357,7 @@ float previousAlpha = 1.f; #else shOutputColour(0).a = 1.f-previousAlpha; #endif + } #endif