paysages : Textures refactoring and improving (WIP).
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@545 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
bf87e72a4a
commit
701c6b35c1
10 changed files with 192 additions and 32 deletions
1
TODO
1
TODO
|
@ -7,7 +7,6 @@ Technology Preview 2 :
|
||||||
=> Restore cloud lighting
|
=> Restore cloud lighting
|
||||||
=> Improve cloud rendering precision (and beware of precision discontinuity when rendering clouds in front of ground (shorter distance)).
|
=> Improve cloud rendering precision (and beware of precision discontinuity when rendering clouds in front of ground (shorter distance)).
|
||||||
- Improve textures (current model is greatly incorrect).
|
- Improve textures (current model is greatly incorrect).
|
||||||
=> Convert to new architecture model.
|
|
||||||
=> Use triplanar projection.
|
=> Use triplanar projection.
|
||||||
=> Separate models (basic texture and covering texture).
|
=> Separate models (basic texture and covering texture).
|
||||||
=> Covering texture height should inpact terrain height.
|
=> Covering texture height should inpact terrain height.
|
||||||
|
|
|
@ -75,11 +75,10 @@ private:
|
||||||
static AtmosphereResult _applyAerialPerspective(Renderer*, Vector3, Color base)
|
static AtmosphereResult _applyAerialPerspective(Renderer*, Vector3, Color base)
|
||||||
{
|
{
|
||||||
AtmosphereResult result;
|
AtmosphereResult result;
|
||||||
|
atmosphereInitResult(&result);
|
||||||
result.base = base;
|
result.base = base;
|
||||||
result.distance = 0.0;
|
|
||||||
result.inscattering = COLOR_BLACK;
|
|
||||||
result.attenuation = COLOR_BLACK;
|
|
||||||
result.final = base;
|
result.final = base;
|
||||||
|
atmosphereUpdateResult(&result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,6 +53,16 @@ static Vector3 _getCameraLocation(Renderer* renderer, Vector3)
|
||||||
return ((CameraDefinition*)renderer->customData[2])->location;
|
return ((CameraDefinition*)renderer->customData[2])->location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static AtmosphereResult _applyAerialPerspective(Renderer*, Vector3, Color base)
|
||||||
|
{
|
||||||
|
AtmosphereResult result;
|
||||||
|
atmosphereInitResult(&result);
|
||||||
|
result.base = base;
|
||||||
|
result.final = base;
|
||||||
|
atmosphereUpdateResult(&result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
||||||
QGLWidget(parent)
|
QGLWidget(parent)
|
||||||
{
|
{
|
||||||
|
@ -66,6 +76,7 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
||||||
_renderer->render_quality = 3;
|
_renderer->render_quality = 3;
|
||||||
_renderer->customData[2] = _base_camera;
|
_renderer->customData[2] = _base_camera;
|
||||||
_renderer->getCameraLocation = _getCameraLocation;
|
_renderer->getCameraLocation = _getCameraLocation;
|
||||||
|
_renderer->atmosphere->applyAerialPerspective = _applyAerialPerspective;
|
||||||
lightingManagerDisableSpecularity(_renderer->lighting);
|
lightingManagerDisableSpecularity(_renderer->lighting);
|
||||||
|
|
||||||
_inited = false;
|
_inited = false;
|
||||||
|
|
|
@ -116,17 +116,96 @@ static TerrainResult _fakeGetResult(Renderer* renderer, double x, double z, int
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west)
|
||||||
|
{
|
||||||
|
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 TerrainResult _realGetResult(Renderer* renderer, double x, double z, int with_painting, int with_textures)
|
static TerrainResult _realGetResult(Renderer* renderer, double x, double z, int with_painting, int with_textures)
|
||||||
{
|
{
|
||||||
TerrainResult result;
|
TerrainResult result;
|
||||||
|
double detail = 0.01;
|
||||||
|
|
||||||
result.location.x = x;
|
/* Normal */
|
||||||
result.location.y = renderer->terrain->getHeight(renderer, x, z, with_painting);
|
Vector3 center, north, east, south, west;
|
||||||
result.location.z = z;
|
|
||||||
|
|
||||||
|
center.x = x;
|
||||||
|
center.z = z;
|
||||||
|
center.y = renderer->terrain->getHeight(renderer, center.x, center.z, with_painting);
|
||||||
|
|
||||||
|
east.x = x + detail;
|
||||||
|
east.z = z;
|
||||||
|
east.y = renderer->terrain->getHeight(renderer, east.x, east.z, with_painting);
|
||||||
|
|
||||||
|
south.x = x;
|
||||||
|
south.z = z + detail;
|
||||||
|
south.y = renderer->terrain->getHeight(renderer, south.x, south.z, with_painting);
|
||||||
|
|
||||||
|
if (renderer->render_quality > 5)
|
||||||
|
{
|
||||||
|
west.x = x - detail;
|
||||||
|
west.z = z;
|
||||||
|
west.y = renderer->terrain->getHeight(renderer, west.x, west.z, with_painting);
|
||||||
|
|
||||||
|
north.x = x;
|
||||||
|
north.z = z - detail;
|
||||||
|
north.y = renderer->terrain->getHeight(renderer, north.x, north.z, with_painting);
|
||||||
|
|
||||||
|
result.normal = _getNormal4(center, north, east, south, west);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.normal = _getNormal2(center, east, south);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Location */
|
||||||
|
result.location = center;
|
||||||
|
|
||||||
|
/* Texture displacement */
|
||||||
if (with_textures)
|
if (with_textures)
|
||||||
{
|
{
|
||||||
result = renderer->textures->displaceTerrain(renderer, result);
|
center = result.location = renderer->textures->displaceTerrain(renderer, result);
|
||||||
|
|
||||||
|
/* TODO Recompute normal */
|
||||||
|
if (renderer->render_quality > 7)
|
||||||
|
{
|
||||||
|
/* Use 5 points on displaced terrain */
|
||||||
|
east = renderer->textures->displaceTerrain(renderer, _realGetResult(renderer, east.x, east.z, with_painting, 0));
|
||||||
|
south = renderer->textures->displaceTerrain(renderer, _realGetResult(renderer, south.x, south.z, with_painting, 0));
|
||||||
|
west = renderer->textures->displaceTerrain(renderer, _realGetResult(renderer, west.x, west.z, with_painting, 0));
|
||||||
|
north = renderer->textures->displaceTerrain(renderer, _realGetResult(renderer, north.x, north.z, with_painting, 0));
|
||||||
|
|
||||||
|
result.normal = _getNormal4(center, north, east, south, west);
|
||||||
|
}
|
||||||
|
else if (renderer->render_quality > 2)
|
||||||
|
{
|
||||||
|
/* Use 3 points on displaced terrain */
|
||||||
|
east = renderer->textures->displaceTerrain(renderer, _realGetResult(renderer, east.x, east.z, with_painting, 0));
|
||||||
|
south = renderer->textures->displaceTerrain(renderer, _realGetResult(renderer, south.x, south.z, with_painting, 0));
|
||||||
|
|
||||||
|
result.normal = _getNormal2(center, east, south);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Use texture noise directly, as if terrain was a plane */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -140,10 +219,10 @@ static Color _fakeGetFinalColor(Renderer* renderer, Vector3 location, double pre
|
||||||
return COLOR_GREEN;
|
return COLOR_GREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Color _realgetFinalColor(Renderer* renderer, Vector3 location, double precision)
|
static Color _realGetFinalColor(Renderer* renderer, Vector3 location, double precision)
|
||||||
{
|
{
|
||||||
TerrainResult terrain = renderer->terrain->getResult(renderer, location.x, location.z, 1, 1);
|
/* TODO Restore precision control */
|
||||||
TexturesResult textures = renderer->textures->applyToTerrain(renderer, terrain);
|
TexturesResult textures = renderer->textures->applyToTerrain(renderer, location.x, location.z);
|
||||||
return renderer->applyMediumTraversal(renderer, textures.final_location, textures.final_color);
|
return renderer->applyMediumTraversal(renderer, textures.final_location, textures.final_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +271,7 @@ static RayCastingResult _realCastRay(Renderer* renderer, Vector3 start, Vector3
|
||||||
}
|
}
|
||||||
result.hit = 1;
|
result.hit = 1;
|
||||||
result.hit_location = start;
|
result.hit_location = start;
|
||||||
result.hit_color = _realgetFinalColor(renderer, start, renderer->getPrecision(renderer, result.hit_location));
|
result.hit_color = _realGetFinalColor(renderer, start, renderer->getPrecision(renderer, result.hit_location));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +429,7 @@ static void _bindRenderer(Renderer* renderer, TerrainDefinition* definition)
|
||||||
renderer->terrain->castRay = _realCastRay;
|
renderer->terrain->castRay = _realCastRay;
|
||||||
renderer->terrain->getHeight = _realGetHeight;
|
renderer->terrain->getHeight = _realGetHeight;
|
||||||
renderer->terrain->getResult = _realGetResult;
|
renderer->terrain->getResult = _realGetResult;
|
||||||
renderer->terrain->getFinalColor = _realgetFinalColor;
|
renderer->terrain->getFinalColor = _realGetFinalColor;
|
||||||
|
|
||||||
lightingManagerRegisterFilter(renderer->lighting, (FuncLightingAlterLight)_alterLight, renderer);
|
lightingManagerRegisterFilter(renderer->lighting, (FuncLightingAlterLight)_alterLight, renderer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,8 @@ static TexturesLayerDefinition* _layerCreateDefinition()
|
||||||
|
|
||||||
result->_displacement_noise = noiseCreateGenerator();
|
result->_displacement_noise = noiseCreateGenerator();
|
||||||
|
|
||||||
|
_layerValidateDefinition(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,17 @@
|
||||||
|
|
||||||
void texturesAutoPreset(TexturesDefinition* definition, TexturesPreset preset)
|
void texturesAutoPreset(TexturesDefinition* definition, TexturesPreset preset)
|
||||||
{
|
{
|
||||||
|
int layer;
|
||||||
layersClear(definition->layers);
|
layersClear(definition->layers);
|
||||||
|
|
||||||
if (preset == TEXTURES_PRESET_IRELAND)
|
if (preset == TEXTURES_PRESET_IRELAND)
|
||||||
{
|
{
|
||||||
|
layer = layersAddLayer(definition->layers, NULL);
|
||||||
}
|
}
|
||||||
else if (preset == TEXTURES_PRESET_IRELAND)
|
else if (preset == TEXTURES_PRESET_ALPS)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else if (preset == TEXTURES_PRESET_IRELAND)
|
else if (preset == TEXTURES_PRESET_CANYON)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +35,7 @@ void texturesLayerAutoPreset(TexturesLayerDefinition* definition, TexturesLayerP
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cloudsLayerValidateDefinition(definition);
|
texturesGetLayerType().callback_validate(definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/*
|
/*
|
||||||
* Get the base presence factor of a layer, not accounting for other layers.
|
* Get the base presence factor of a layer, not accounting for other layers.
|
||||||
*/
|
*/
|
||||||
double texturesGetLayerBasePresence(Renderer* renderer, TexturesLayerDefinition* layer, TerrainResult result);
|
double texturesGetLayerBasePresence(TexturesLayerDefinition* layer, TerrainResult terrain);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get triplanar noise value, depending on the normal direction.
|
* Get triplanar noise value, depending on the normal direction.
|
||||||
|
@ -16,6 +16,6 @@ double texturesGetTriplanarNoise(NoiseGenerator* noise, Vector3 location, Vector
|
||||||
/*
|
/*
|
||||||
* Apply texture displacement on a terrain result.
|
* Apply texture displacement on a terrain result.
|
||||||
*/
|
*/
|
||||||
TerrainResult texturesApplyLayerDisplacement(Renderer* renderer, TexturesLayerDefinition* layer, TerrainResult initial, TerrainResult support, double presence, double cancel_factor);
|
/*TerrainResult texturesApplyLayerDisplacement(Renderer* renderer, TexturesLayerDefinition* layer, TerrainResult initial, TerrainResult support, double presence, double cancel_factor);*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -76,8 +76,8 @@ typedef struct
|
||||||
Color final_color;
|
Color final_color;
|
||||||
} TexturesResult;
|
} TexturesResult;
|
||||||
|
|
||||||
typedef TerrainResult (*FuncTexturesDisplaceTerrain)(Renderer* renderer, TerrainResult terrain);
|
typedef Vector3 (*FuncTexturesDisplaceTerrain)(Renderer* renderer, TerrainResult terrain);
|
||||||
typedef TexturesResult (*FuncTexturesApplyToTerrain)(Renderer* renderer, TerrainResult terrain);
|
typedef TexturesResult (*FuncTexturesApplyToTerrain)(Renderer* renderer, double x, double z);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,37 +5,72 @@
|
||||||
#include "../renderer.h"
|
#include "../renderer.h"
|
||||||
|
|
||||||
/******************** Fake ********************/
|
/******************** Fake ********************/
|
||||||
static TerrainResult _fakeDisplaceTerrain(Renderer* renderer, TerrainResult terrain)
|
static Vector3 _fakeDisplaceTerrain(Renderer* renderer, TerrainResult terrain)
|
||||||
{
|
{
|
||||||
UNUSED(renderer);
|
UNUSED(renderer);
|
||||||
|
|
||||||
return terrain;
|
return terrain.location;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TexturesResult _fakeApplyToTerrain(Renderer* renderer, TerrainResult terrain)
|
static TexturesResult _fakeApplyToTerrain(Renderer* renderer, double x, double z)
|
||||||
{
|
{
|
||||||
TexturesResult result;
|
TexturesResult result;
|
||||||
|
|
||||||
result.base_location = terrain.location;
|
result.base_location.x = x;
|
||||||
result.base_normal = terrain.normal;
|
result.base_location.y = 0.0;
|
||||||
|
result.base_location.z = z;
|
||||||
|
result.base_normal = VECTOR_UP;
|
||||||
result.layer_count = 0;
|
result.layer_count = 0;
|
||||||
result.final_location = terrain.location;
|
result.final_location = result.base_location;
|
||||||
result.final_color = COLOR_WHITE;
|
result.final_color = COLOR_WHITE;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************** Real ********************/
|
/******************** Real ********************/
|
||||||
static TerrainResult _realDisplaceTerrain(Renderer* renderer, TerrainResult terrain)
|
static Vector3 _realDisplaceTerrain(Renderer* renderer, TerrainResult terrain)
|
||||||
{
|
{
|
||||||
/* TODO */
|
TexturesDefinition* textures = renderer->textures->definition;
|
||||||
return _fakeDisplaceTerrain(renderer, terrain);
|
double offset = 0.0;
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
n = layersCount(textures->layers);
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
TexturesLayerDefinition* layer = layersGetLayer(textures->layers, i);
|
||||||
|
|
||||||
|
if (layer->displacement_height > 0.0)
|
||||||
|
{
|
||||||
|
double presence = texturesGetLayerBasePresence(layer, terrain);
|
||||||
|
offset += texturesGetTriplanarNoise(layer->_displacement_noise, terrain.location, terrain.normal) * presence * layer->displacement_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return v3Add(terrain.location, v3Scale(v3Normalize(terrain.normal), offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
static TexturesResult _realApplyToTerrain(Renderer* renderer, TerrainResult terrain)
|
static TexturesResult _realApplyToTerrain(Renderer* renderer, double x, double z)
|
||||||
{
|
{
|
||||||
/* TODO */
|
TexturesResult result;
|
||||||
return _fakeApplyToTerrain(renderer, terrain);
|
|
||||||
|
/* Displacement */
|
||||||
|
TerrainResult terrain = renderer->terrain->getResult(renderer, x, z, 1, 1);
|
||||||
|
|
||||||
|
/* TODO Detail */
|
||||||
|
|
||||||
|
/* TEMP */
|
||||||
|
SurfaceMaterial temp;
|
||||||
|
temp.base.r = 0.6;
|
||||||
|
temp.base.g = 0.55;
|
||||||
|
temp.base.b = 0.57;
|
||||||
|
temp.reflection = 0.02;
|
||||||
|
temp.shininess = 3.0;
|
||||||
|
|
||||||
|
result.base_location = terrain.location;
|
||||||
|
result.base_normal = terrain.normal;
|
||||||
|
result.final_location = terrain.location;
|
||||||
|
result.final_color = renderer->applyLightingToSurface(renderer, terrain.location, terrain.normal, &temp);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************** Renderer ********************/
|
/******************** Renderer ********************/
|
||||||
|
|
33
lib_paysages/textures/tools.c
Normal file
33
lib_paysages/textures/tools.c
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#include "private.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the base presence factor of a layer, not accounting for other layers.
|
||||||
|
*/
|
||||||
|
double texturesGetLayerBasePresence(TexturesLayerDefinition* layer, TerrainResult terrain)
|
||||||
|
{
|
||||||
|
return zoneGetValue(layer->terrain_zone, terrain.location, terrain.normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get triplanar noise value, depending on the normal direction.
|
||||||
|
*/
|
||||||
|
double texturesGetTriplanarNoise(NoiseGenerator* noise, Vector3 location, Vector3 normal)
|
||||||
|
{
|
||||||
|
/*assert(v3Norm(normal) == 1.0);*/
|
||||||
|
|
||||||
|
double noiseXY = noiseGet2DTotal(noise, location.x, location.y);
|
||||||
|
double noiseXZ = noiseGet2DTotal(noise, location.x, location.z);
|
||||||
|
double noiseYZ = noiseGet2DTotal(noise, location.y, location.z);
|
||||||
|
|
||||||
|
double mXY = fabs(normal.z);
|
||||||
|
double mXZ = fabs(normal.y);
|
||||||
|
double mYZ = fabs(normal.x);
|
||||||
|
double total = mXY + mXZ + mYZ;
|
||||||
|
mXY /= total;
|
||||||
|
mXZ /= total;
|
||||||
|
mYZ /= total;
|
||||||
|
|
||||||
|
return noiseXY * mXY + noiseXZ * mXZ + noiseYZ * mYZ;
|
||||||
|
}
|
Loading…
Reference in a new issue