paysages : New texture model (WIP).
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@317 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
0242fc547a
commit
3bd7e91659
8 changed files with 224 additions and 127 deletions
|
@ -2,8 +2,9 @@
|
||||||
-------------------------------
|
-------------------------------
|
||||||
* Previews scaling is now logarithmic (slower when zoomed).
|
* Previews scaling is now logarithmic (slower when zoomed).
|
||||||
* Previews drawing now takes advantage of multiple CPUs.
|
* Previews drawing now takes advantage of multiple CPUs.
|
||||||
* New displacement mode for textures (perpendicular to local ground surface).
|
* New texture model (perpendicular displacement and thickness).
|
||||||
* Added clouds hardness to light.
|
* Added clouds hardness to light.
|
||||||
|
* Version management in saved files.
|
||||||
|
|
||||||
2012-04-20 Technology Preview 1
|
2012-04-20 Technology Preview 1
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
16
TODO
16
TODO
|
@ -1,6 +1,9 @@
|
||||||
Technology Preview 2 :
|
Technology Preview 2 :
|
||||||
|
- Interface for textures thickness and slope_range.
|
||||||
- Render tab previews should not rerender when changing render options.
|
- Render tab previews should not rerender when changing render options.
|
||||||
- Compute shadows only once for all textures at a same location (need an intermediary light status).
|
- Compute shadows only once for all textures at a same location.
|
||||||
|
=> Add an intermediary light status (two pass lighting).
|
||||||
|
- Don't change opacity when scrolling previews.
|
||||||
- Add layer sorting/naming.
|
- Add layer sorting/naming.
|
||||||
- Save GUI config (views, render params).
|
- Save GUI config (views, render params).
|
||||||
- Add an OSD ability on previews and use it for camera location and user landmarks.
|
- Add an OSD ability on previews and use it for camera location and user landmarks.
|
||||||
|
@ -9,21 +12,30 @@ Technology Preview 2 :
|
||||||
- Add a terrain modifier dialog with zones.
|
- Add a terrain modifier dialog with zones.
|
||||||
- Add a noise filler (and maybe noise intervals ?).
|
- Add a noise filler (and maybe noise intervals ?).
|
||||||
- Improve curve editor.
|
- Improve curve editor.
|
||||||
|
=> Add curve modes
|
||||||
|
=> Improve curve rendering
|
||||||
|
=> Add axis labels
|
||||||
- Water and terrain LOD moves with the camera, fix it like in the wanderer.
|
- Water and terrain LOD moves with the camera, fix it like in the wanderer.
|
||||||
- Pause previews drawing of main window when a dialog is opened.
|
- Pause previews drawing of main window when a dialog is opened.
|
||||||
- Interrupt preview chunk renderings that will be discarded at commit, or that are no more visible.
|
- Interrupt preview chunk renderings that will be discarded at commit, or that are no more visible.
|
||||||
- Can't overwrite picture files (ILError).
|
- Can't overwrite picture files (ILError).
|
||||||
- Fix "RGB parameters out of range" (and segfault) on preview while moving render params fast in render tab.
|
- Fix "RGB parameters out of range" (and segfault) on preview while moving render params fast in render tab.
|
||||||
|
=> May need to change the updateData system.
|
||||||
|
=> Previews need to be paused while updating data.
|
||||||
- When there are two previews in the same view, balance rendering between the two.
|
- When there are two previews in the same view, balance rendering between the two.
|
||||||
|
- Lock some previews together (eg: terrain height and colored preview).
|
||||||
|
- Find a new licence.
|
||||||
|
|
||||||
Technology Preview 3 :
|
Technology Preview 3 :
|
||||||
- Restore render progress.
|
- Restore render progress.
|
||||||
- Add antialiasing option (pay attention to memory usage).
|
- Add antialiasing option (pay attention to memory usage).
|
||||||
- Add basic vegetation system (not sure).
|
- Add basic vegetation system ?
|
||||||
|
- Texture shadowing and self-shadowing ?
|
||||||
- Improve sky rendering (colors and light halo).
|
- Improve sky rendering (colors and light halo).
|
||||||
- Add a progress indicator on previews.
|
- Add a progress indicator on previews.
|
||||||
- Multi threaded first pass.
|
- Multi threaded first pass.
|
||||||
- Fix potential holes in land rendering.
|
- Fix potential holes in land rendering.
|
||||||
|
- Progressive final render.
|
||||||
|
|
||||||
Release Candidate :
|
Release Candidate :
|
||||||
- Polish all features and UI.
|
- Polish all features and UI.
|
||||||
|
|
|
@ -76,7 +76,7 @@ private:
|
||||||
|
|
||||||
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
||||||
{
|
{
|
||||||
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location, precision);
|
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
|
static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
|
||||||
|
|
|
@ -120,7 +120,7 @@ private:
|
||||||
|
|
||||||
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
||||||
{
|
{
|
||||||
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location, precision);
|
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
|
static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
|
||||||
|
|
|
@ -96,8 +96,8 @@ void autoGenRealisticLandscape(int seed)
|
||||||
water.depth_color.b = 0.3;
|
water.depth_color.b = 0.3;
|
||||||
water.depth_color.a = 1.0;
|
water.depth_color.a = 1.0;
|
||||||
water.lighting_depth = 3.0;
|
water.lighting_depth = 3.0;
|
||||||
water.waves_noise_height = 0.015;
|
water.waves_noise_height = 0.005;
|
||||||
water.waves_noise_scale = 0.2;
|
water.waves_noise_scale = 0.07;
|
||||||
noiseGenerateBaseNoise(water.waves_noise, 262144);
|
noiseGenerateBaseNoise(water.waves_noise, 262144);
|
||||||
noiseAddLevelsSimple(water.waves_noise, 2, 1.0, 1.0);
|
noiseAddLevelsSimple(water.waves_noise, 2, 1.0, 1.0);
|
||||||
noiseAddLevelsSimple(water.waves_noise, 3, 0.15, 0.1);
|
noiseAddLevelsSimple(water.waves_noise, 3, 0.15, 0.1);
|
||||||
|
@ -139,7 +139,7 @@ void autoGenRealisticLandscape(int seed)
|
||||||
/* Terrain */
|
/* Terrain */
|
||||||
terrain = terrainCreateDefinition();
|
terrain = terrainCreateDefinition();
|
||||||
noiseGenerateBaseNoise(terrain.height_noise, 1048576);
|
noiseGenerateBaseNoise(terrain.height_noise, 1048576);
|
||||||
noiseAddLevelsSimple(terrain.height_noise, 10, 1.0, 1.0);
|
noiseAddLevelsSimple(terrain.height_noise, 12, 1.0, 1.0);
|
||||||
terrain.height_factor = 12.0 / noiseGetMaxValue(terrain.height_noise);
|
terrain.height_factor = 12.0 / noiseGetMaxValue(terrain.height_noise);
|
||||||
terrain.scaling = 10.0;
|
terrain.scaling = 10.0;
|
||||||
scenerySetTerrain(&terrain);
|
scenerySetTerrain(&terrain);
|
||||||
|
@ -152,35 +152,44 @@ void autoGenRealisticLandscape(int seed)
|
||||||
zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 5.0, 5.0);
|
zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 5.0, 5.0);
|
||||||
noiseGenerateBaseNoise(texture->bump_noise, 102400);
|
noiseGenerateBaseNoise(texture->bump_noise, 102400);
|
||||||
noiseAddLevelsSimple(texture->bump_noise, 8, 1.0, 1.0);
|
noiseAddLevelsSimple(texture->bump_noise, 8, 1.0, 1.0);
|
||||||
texture->bump_height = 0.1;
|
texture->bump_height = 0.01;
|
||||||
texture->bump_scaling = 0.15;
|
texture->bump_scaling = 0.015;
|
||||||
texture->material.base.r = 0.6;
|
texture->material.base.r = 0.6;
|
||||||
texture->material.base.g = 0.55;
|
texture->material.base.g = 0.55;
|
||||||
texture->material.base.b = 0.57;
|
texture->material.base.b = 0.57;
|
||||||
texture->material.reflection = 0.2;
|
texture->material.reflection = 0.2;
|
||||||
texture->material.shininess = 3.0;
|
texture->material.shininess = 3.0;
|
||||||
|
texture->thickness = 0.001;
|
||||||
|
texture->slope_range = 0.001;
|
||||||
texture = texturesGetLayer(&textures, texturesAddLayer(&textures));
|
texture = texturesGetLayer(&textures, texturesAddLayer(&textures));
|
||||||
zoneAddHeightRangeQuick(texture->zone, 1.0, -1.0, 0.0, 3.0, 15.0);
|
zoneAddHeightRangeQuick(texture->zone, 1.0, -1.0, 0.0, 3.0, 15.0);
|
||||||
zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.2, 0.3);
|
zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.1, 0.7);
|
||||||
noiseGenerateBaseNoise(texture->bump_noise, 102400);
|
noiseGenerateBaseNoise(texture->bump_noise, 102400);
|
||||||
noiseAddLevelsSimple(texture->bump_noise, 5, 1.0, 0.4);
|
noiseAddLevelsSimple(texture->bump_noise, 5, 1.0, 0.4);
|
||||||
noiseAddLevelsSimple(texture->bump_noise, 2, 0.03, 0.08);
|
noiseAddLevelsSimple(texture->bump_noise, 2, 0.03, 0.08);
|
||||||
texture->bump_height = 0.02;
|
texture->bump_height = 0.002;
|
||||||
texture->bump_scaling = 0.1;
|
texture->bump_scaling = 0.01;
|
||||||
texture->material.base.r = 0.12;
|
texture->material.base.r = 0.12;
|
||||||
texture->material.base.g = 0.19;
|
texture->material.base.g = 0.19;
|
||||||
texture->material.base.b = 0.035;
|
texture->material.base.b = 0.035;
|
||||||
texture->material.reflection = 0.1;
|
texture->material.reflection = 0.1;
|
||||||
texture->material.shininess = 2.0;
|
texture->material.shininess = 2.0;
|
||||||
/*texture = texturesGetLayer(&textures, texturesAddLayer(&textures));
|
texture->thickness = 0.02;
|
||||||
zoneAddHeightRange(texture->zone, 1.0, 3.0, 4.0, 100.0, 100.0);
|
texture->slope_range = 0.03;
|
||||||
|
texture = texturesGetLayer(&textures, texturesAddLayer(&textures));
|
||||||
|
zoneAddHeightRangeQuick(texture->zone, 1.0, 4.0, 5.0, 100.0, 100.0);
|
||||||
|
zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.2, 1.0);
|
||||||
noiseGenerateBaseNoise(texture->bump_noise, 102400);
|
noiseGenerateBaseNoise(texture->bump_noise, 102400);
|
||||||
noiseAddLevelsSimple(texture->bump_noise, 6, 0.04, 0.003);
|
noiseAddLevelsSimple(texture->bump_noise, 6, 1.0, 1.0);
|
||||||
texture->color.r = 1.0;
|
texture->bump_height = 0.002;
|
||||||
texture->color.g = 1.0;
|
texture->bump_scaling = 0.03;
|
||||||
texture->color.b = 1.0;
|
texture->material.base.r = 1.0;
|
||||||
texturesSetDefinition(layer, texture);
|
texture->material.base.g = 1.0;
|
||||||
texturesDeleteDefinition(texture);*/
|
texture->material.base.b = 1.0;
|
||||||
|
texture->material.reflection = 0.25;
|
||||||
|
texture->material.shininess = 0.6;
|
||||||
|
texture->thickness = 0.05;
|
||||||
|
texture->slope_range = 0.3;
|
||||||
scenerySetTextures(&textures);
|
scenerySetTextures(&textures);
|
||||||
texturesDeleteDefinition(&textures);
|
texturesDeleteDefinition(&textures);
|
||||||
|
|
||||||
|
|
|
@ -285,7 +285,7 @@ static HeightInfo _getWaterHeightInfo(Renderer* renderer)
|
||||||
|
|
||||||
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
||||||
{
|
{
|
||||||
return texturesGetColor(&_textures, renderer, location, precision);
|
return texturesGetColor(&_textures, renderer, location.x, location.z, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Color _applyAtmosphere(Renderer* renderer, Vector3 location, Color base)
|
static Color _applyAtmosphere(Renderer* renderer, Vector3 location, Color base)
|
||||||
|
|
|
@ -37,6 +37,8 @@ void texturesSave(PackStream* stream, TexturesDefinition* definition)
|
||||||
packWriteDouble(stream, &definition->textures[i].bump_height);
|
packWriteDouble(stream, &definition->textures[i].bump_height);
|
||||||
packWriteDouble(stream, &definition->textures[i].bump_scaling);
|
packWriteDouble(stream, &definition->textures[i].bump_scaling);
|
||||||
materialSave(stream, &definition->textures[i].material);
|
materialSave(stream, &definition->textures[i].material);
|
||||||
|
packWriteDouble(stream, &definition->textures[i].thickness);
|
||||||
|
packWriteDouble(stream, &definition->textures[i].slope_range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +62,8 @@ void texturesLoad(PackStream* stream, TexturesDefinition* definition)
|
||||||
packReadDouble(stream, &layer->bump_height);
|
packReadDouble(stream, &layer->bump_height);
|
||||||
packReadDouble(stream, &layer->bump_scaling);
|
packReadDouble(stream, &layer->bump_scaling);
|
||||||
materialLoad(stream, &layer->material);
|
materialLoad(stream, &layer->material);
|
||||||
|
packReadDouble(stream, &definition->textures[i].thickness);
|
||||||
|
packReadDouble(stream, &definition->textures[i].slope_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
texturesValidateDefinition(definition);
|
texturesValidateDefinition(definition);
|
||||||
|
@ -120,6 +124,8 @@ TextureLayerDefinition texturesLayerCreateDefinition()
|
||||||
result.material.base = COLOR_WHITE;
|
result.material.base = COLOR_WHITE;
|
||||||
result.material.reflection = 0.0;
|
result.material.reflection = 0.0;
|
||||||
result.material.shininess = 0.0;
|
result.material.shininess = 0.0;
|
||||||
|
result.thickness = 0.0;
|
||||||
|
result.slope_range = 0.001;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -135,6 +141,8 @@ void texturesLayerCopyDefinition(TextureLayerDefinition* source, TextureLayerDef
|
||||||
destination->material = source->material;
|
destination->material = source->material;
|
||||||
destination->bump_height = source->bump_height;
|
destination->bump_height = source->bump_height;
|
||||||
destination->bump_scaling = source->bump_scaling;
|
destination->bump_scaling = source->bump_scaling;
|
||||||
|
destination->thickness = source->thickness;
|
||||||
|
destination->slope_range = source->slope_range;
|
||||||
noiseCopy(source->bump_noise, destination->bump_noise);
|
noiseCopy(source->bump_noise, destination->bump_noise);
|
||||||
zoneCopy(source->zone, destination->zone);
|
zoneCopy(source->zone, destination->zone);
|
||||||
}
|
}
|
||||||
|
@ -145,6 +153,10 @@ void texturesLayerValidateDefinition(TextureLayerDefinition* definition)
|
||||||
{
|
{
|
||||||
definition->bump_scaling = 0.000001;
|
definition->bump_scaling = 0.000001;
|
||||||
}
|
}
|
||||||
|
if (definition->slope_range < 0.001)
|
||||||
|
{
|
||||||
|
definition->slope_range = 0.001;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int texturesGetLayerCount(TexturesDefinition* definition)
|
int texturesGetLayerCount(TexturesDefinition* definition)
|
||||||
|
@ -191,128 +203,181 @@ void texturesDeleteLayer(TexturesDefinition* definition, int layer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Vector3 _getPoint(TextureLayerDefinition* definition, Renderer* renderer, double x, double z, Vector3 prenormal, double scale)
|
|
||||||
{
|
|
||||||
Vector3 point;
|
|
||||||
|
|
||||||
point.x = x;
|
|
||||||
point.z = z;
|
|
||||||
point.y = renderer->getTerrainHeight(renderer, point.x, point.z);
|
|
||||||
|
|
||||||
return v3Add(point, v3Scale(prenormal, noiseGet2DTotal(definition->bump_noise, point.x / definition->bump_scaling, point.z / definition->bump_scaling) * definition->bump_height));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Vector3 _getPreNormal(TextureLayerDefinition* definition, Renderer* renderer, Vector3 point, double scale)
|
|
||||||
{
|
|
||||||
Vector3 dpoint, ref, normal;
|
|
||||||
|
|
||||||
/* TODO This method is better suited in terrain.c */
|
|
||||||
|
|
||||||
ref.y = 0.0;
|
|
||||||
point.y = renderer->getTerrainHeight(renderer, point.x, point.z);
|
|
||||||
|
|
||||||
dpoint.x = point.x + scale;
|
|
||||||
dpoint.z = point.z;
|
|
||||||
dpoint.y = renderer->getTerrainHeight(renderer, dpoint.x, dpoint.z);
|
|
||||||
ref.x = 0.0;
|
|
||||||
ref.z = 1.0;
|
|
||||||
normal = v3Normalize(v3Cross(ref, v3Sub(dpoint, point)));
|
|
||||||
|
|
||||||
dpoint.x = point.x;
|
|
||||||
dpoint.z = point.z + scale;
|
|
||||||
dpoint.y = renderer->getTerrainHeight(renderer, dpoint.x, dpoint.z);
|
|
||||||
ref.x = -1.0;
|
|
||||||
ref.z = 0.0;
|
|
||||||
normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
|
|
||||||
|
|
||||||
if (renderer->render_quality > 5)
|
|
||||||
{
|
|
||||||
dpoint.x = point.x;
|
|
||||||
dpoint.z = point.z - scale;
|
|
||||||
dpoint.y = renderer->getTerrainHeight(renderer, dpoint.x, dpoint.z);
|
|
||||||
ref.x = 1.0;
|
|
||||||
ref.z = 0.0;
|
|
||||||
normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
|
|
||||||
|
|
||||||
dpoint.x = point.x - scale;
|
|
||||||
dpoint.z = point.z;
|
|
||||||
dpoint.y = renderer->getTerrainHeight(renderer, dpoint.x, dpoint.z);
|
|
||||||
ref.x = 0.0;
|
|
||||||
ref.z = -1.0;
|
|
||||||
normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
|
|
||||||
}
|
|
||||||
|
|
||||||
return v3Normalize(normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Vector3 _getPostNormal(TextureLayerDefinition* definition, Renderer* renderer, Vector3 point, Vector3 prenormal, double scale)
|
|
||||||
{
|
|
||||||
Vector3 p0, d1, d2, d3, d4, normal;
|
|
||||||
|
|
||||||
p0 = _getPoint(definition, renderer, point.x, point.z, prenormal, scale);
|
|
||||||
|
|
||||||
d1 = v3Normalize(v3Sub(_getPoint(definition, renderer, point.x + scale, point.z, prenormal, scale), p0));
|
|
||||||
d3 = v3Normalize(v3Sub(_getPoint(definition, renderer, point.x, point.z + scale, prenormal, scale), p0));
|
|
||||||
if (renderer->render_quality > 5)
|
|
||||||
{
|
|
||||||
d2 = v3Normalize(v3Sub(_getPoint(definition, renderer, point.x - scale, point.z, prenormal, scale), p0));
|
|
||||||
d4 = v3Normalize(v3Sub(_getPoint(definition, renderer, point.x, point.z - scale, prenormal, scale), p0));
|
|
||||||
}
|
|
||||||
|
|
||||||
normal = v3Cross(d3, d1);
|
|
||||||
if (renderer->render_quality > 5)
|
|
||||||
{
|
|
||||||
normal = v3Add(normal, v3Cross(d1, d4));
|
|
||||||
normal = v3Add(normal, v3Cross(d4, d2));
|
|
||||||
normal = v3Add(normal, v3Cross(d2, d3));
|
|
||||||
}
|
|
||||||
|
|
||||||
return v3Normalize(normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
double texturesGetLayerCoverage(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail)
|
|
||||||
{
|
|
||||||
Vector3 normal;
|
|
||||||
|
|
||||||
normal = _getPreNormal(definition, renderer, location, detail * 0.1);
|
|
||||||
|
|
||||||
return zoneGetValue(definition->zone, location, normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail)
|
Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail)
|
||||||
{
|
{
|
||||||
Color result;
|
Color result;
|
||||||
Vector3 normal;
|
Vector3 normal;
|
||||||
double coverage;
|
double coverage, noise;
|
||||||
|
|
||||||
result = COLOR_TRANSPARENT;
|
result = COLOR_TRANSPARENT;
|
||||||
normal = _getPreNormal(definition, renderer, location, detail * 0.1);
|
/*normal = _getPreNormal(definition, renderer, location, detail * 0.1);
|
||||||
|
|
||||||
coverage = zoneGetValue(definition->zone, location, normal);
|
coverage = zoneGetValue(definition->zone, location, normal);
|
||||||
if (coverage > 0.0)
|
if (coverage > 0.0)
|
||||||
{
|
{
|
||||||
normal = _getPostNormal(definition, renderer, location, normal, detail * 0.1);
|
if (coverage < 1.0)
|
||||||
result = renderer->applyLightingToSurface(renderer, location, normal, definition->material);
|
{
|
||||||
result.a = coverage;
|
noise = noiseGet2DTotal(definition->border_noise, location.x * 1000.0, location.z * 1000.0);
|
||||||
}
|
coverage = -1.0 + 2.0 * coverage + noise * (1.0 - coverage);
|
||||||
|
}
|
||||||
|
if (coverage > 0.0)
|
||||||
|
{
|
||||||
|
normal = _getPostNormal(definition, renderer, location, normal, detail * 0.1);
|
||||||
|
result = renderer->applyLightingToSurface(renderer, location, normal, definition->material);
|
||||||
|
result.a = coverage < 0.1 ? coverage / 0.1 : 1.0;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, Vector3 location, double detail)
|
|
||||||
|
|
||||||
|
static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west)
|
||||||
{
|
{
|
||||||
Color result, tex_color;
|
Vector3 dnorth, deast, dsouth, dwest, normal;
|
||||||
|
|
||||||
|
dnorth = v3Sub(north, center);
|
||||||
|
deast = v3Sub(east, center);
|
||||||
|
dsouth = v3Sub(south, center);
|
||||||
|
dwest = v3Sub(west, center);
|
||||||
|
|
||||||
|
normal = v3Cross(deast, dnorth);
|
||||||
|
normal = v3Add(normal, v3Cross(dsouth, deast));
|
||||||
|
normal = v3Add(normal, v3Cross(dwest, dsouth));
|
||||||
|
normal = v3Add(normal, v3Cross(dnorth, dwest));
|
||||||
|
|
||||||
|
return v3Normalize(normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Vector3 _getNormal2(Vector3 center, Vector3 east, Vector3 south)
|
||||||
|
{
|
||||||
|
return v3Normalize(v3Cross(v3Sub(south, center), v3Sub(east, center)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline TextureResult _getTerrainResult(Renderer* renderer, double x, double z, double detail)
|
||||||
|
{
|
||||||
|
TextureResult result;
|
||||||
|
Vector3 center, north, east, south, west;
|
||||||
|
|
||||||
|
/* TODO This method is better suited in terrain.c */
|
||||||
|
|
||||||
|
center.x = x;
|
||||||
|
center.z = z;
|
||||||
|
center.y = renderer->getTerrainHeight(renderer, center.x, center.z);
|
||||||
|
|
||||||
|
east.x = x + detail;
|
||||||
|
east.z = z;
|
||||||
|
east.y = renderer->getTerrainHeight(renderer, east.x, east.z);
|
||||||
|
|
||||||
|
south.x = x;
|
||||||
|
south.z = z + detail;
|
||||||
|
south.y = renderer->getTerrainHeight(renderer, south.x, south.z);
|
||||||
|
|
||||||
|
if (renderer->render_quality > 5)
|
||||||
|
{
|
||||||
|
west.x = x - detail;
|
||||||
|
west.z = z;
|
||||||
|
west.y = renderer->getTerrainHeight(renderer, west.x, west.z);
|
||||||
|
|
||||||
|
north.x = x;
|
||||||
|
north.z = z - detail;
|
||||||
|
north.y = renderer->getTerrainHeight(renderer, north.x, north.z);
|
||||||
|
|
||||||
|
result.normal = _getNormal4(center, north, east, south, west);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.normal = _getNormal2(center, east, south);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.location = center;
|
||||||
|
result.color = COLOR_GREEN;
|
||||||
|
result.thickness = -100.0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _getLayerThickness(TextureLayerDefinition* definition, Renderer* renderer, double x, double z, TextureResult* result)
|
||||||
|
{
|
||||||
|
TextureResult base;
|
||||||
|
double coverage;
|
||||||
|
|
||||||
|
base = _getTerrainResult(renderer, x, z, definition->slope_range);
|
||||||
|
coverage = zoneGetValue(definition->zone, base.location, base.normal);
|
||||||
|
if (coverage > 0.0)
|
||||||
|
{
|
||||||
|
result->thickness = coverage * definition->thickness;
|
||||||
|
result->thickness += noiseGet2DTotal(definition->bump_noise, base.location.x / definition->bump_scaling, base.location.z / definition->bump_scaling) * definition->bump_height;
|
||||||
|
|
||||||
|
result->location = v3Add(base.location, v3Scale(base.normal, result->thickness));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result->thickness = -1000.0;
|
||||||
|
result->location = base.location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline TextureResult _getLayerResult(TextureLayerDefinition* definition, Renderer* renderer, double x, double z, double detail)
|
||||||
|
{
|
||||||
|
TextureResult result_center, result_north, result_east, result_south, result_west;
|
||||||
|
|
||||||
|
_getLayerThickness(definition, renderer, x, z, &result_center);
|
||||||
|
_getLayerThickness(definition, renderer, x + detail, z, &result_east);
|
||||||
|
_getLayerThickness(definition, renderer, x, z + detail, &result_south);
|
||||||
|
|
||||||
|
if (renderer->render_quality > 5)
|
||||||
|
{
|
||||||
|
_getLayerThickness(definition, renderer, x - detail, z, &result_west);
|
||||||
|
_getLayerThickness(definition, renderer, x, z - detail, &result_north);
|
||||||
|
|
||||||
|
result_center.normal = _getNormal4(result_center.location, result_north.location, result_east.location, result_south.location, result_west.location);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result_center.normal = _getNormal2(result_center.location, result_east.location, result_south.location);
|
||||||
|
}
|
||||||
|
|
||||||
|
result_center.color = renderer->applyLightingToSurface(renderer, result_center.location, result_center.normal, definition->material);
|
||||||
|
|
||||||
|
return result_center;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _cmpResults(const void* result1, const void* result2)
|
||||||
|
{
|
||||||
|
return ((TextureResult*)result1)->thickness > ((TextureResult*)result2)->thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
double texturesGetLayerCoverage(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail)
|
||||||
|
{
|
||||||
|
TextureResult base = _getTerrainResult(renderer, location.x, location.z, definition->slope_range);
|
||||||
|
return zoneGetValue(definition->zone, base.location, base.normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, double x, double z, double detail)
|
||||||
|
{
|
||||||
|
TextureResult results[TEXTURES_MAX_LAYERS + 1];
|
||||||
|
Color result;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
result = COLOR_GREEN;
|
/* TODO Do not compute layers fully covered */
|
||||||
|
/* TODO Optimize : each layer computes the same shadows */
|
||||||
|
|
||||||
|
detail *= 0.1;
|
||||||
|
|
||||||
|
results[0] = _getTerrainResult(renderer, x, z, detail);
|
||||||
|
|
||||||
for (i = 0; i < definition->nbtextures; i++)
|
for (i = 0; i < definition->nbtextures; i++)
|
||||||
{
|
{
|
||||||
/* TODO Do not compute layers fully covered */
|
results[i + 1] = _getLayerResult(definition->textures + i, renderer, x, z, detail);
|
||||||
/* TODO Optimize : each layer computes the same shadows */
|
}
|
||||||
tex_color = texturesGetLayerColor(definition->textures + i, renderer, location, detail);
|
|
||||||
if (tex_color.a > 0.0001)
|
qsort(results, definition->nbtextures + 1, sizeof(TextureResult), _cmpResults);
|
||||||
{
|
|
||||||
colorMask(&result, &tex_color);
|
result = results[0].color;
|
||||||
}
|
for (i = 0; i < definition->nbtextures; i++)
|
||||||
|
{
|
||||||
|
colorMask(&result, &results[i + 1].color);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -20,6 +20,8 @@ typedef struct
|
||||||
double bump_scaling;
|
double bump_scaling;
|
||||||
double bump_height;
|
double bump_height;
|
||||||
SurfaceMaterial material;
|
SurfaceMaterial material;
|
||||||
|
double thickness;
|
||||||
|
double slope_range;
|
||||||
} TextureLayerDefinition;
|
} TextureLayerDefinition;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -28,6 +30,14 @@ typedef struct
|
||||||
TextureLayerDefinition textures[TEXTURES_MAX_LAYERS];
|
TextureLayerDefinition textures[TEXTURES_MAX_LAYERS];
|
||||||
} TexturesDefinition;
|
} TexturesDefinition;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Vector3 location;
|
||||||
|
Vector3 normal;
|
||||||
|
double thickness;
|
||||||
|
Color color;
|
||||||
|
} TextureResult;
|
||||||
|
|
||||||
void texturesInit();
|
void texturesInit();
|
||||||
void texturesQuit();
|
void texturesQuit();
|
||||||
void texturesSave(PackStream* stream, TexturesDefinition* definition);
|
void texturesSave(PackStream* stream, TexturesDefinition* definition);
|
||||||
|
@ -50,7 +60,7 @@ void texturesDeleteLayer(TexturesDefinition* definition, int layer);
|
||||||
|
|
||||||
double texturesGetLayerCoverage(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail);
|
double texturesGetLayerCoverage(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail);
|
||||||
Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail);
|
Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail);
|
||||||
Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, Vector3 location, double detail);
|
Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, double x, double z, double detail);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue