Terrain fixes to match vanilla better - vertices need to be mapped directly to texels for colormap and blendmap (this also caused seams at cell borders), layer uv scale appears to be 8 not 10

actorid
scrawl 12 years ago
parent 2cfe6db389
commit 726c93c365

@ -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;
if ( splatX >= 0 && splatX < blendMapSize &&
splatY >= 0 && splatY < blendMapSize )
{
const int index = (splatY)*blendMapSize + splatX;
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 splatY = blendMapSize - relY - 1;
const int splatX = relX;
}
}
assert(splatX >= 0 && splatX < blendMapSize);
assert(splatY >= 0 && splatY < blendMapSize);
const int index = (splatY)*blendMapSize + splatX;
pBlend[index] = 1;
}
}

@ -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

Loading…
Cancel
Save