paysages : Add clouds type with simplified settings (WIP).

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@471 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-12-05 15:35:25 +00:00 committed by ThunderK
parent 7e9a0e3faa
commit 1b011672a2
6 changed files with 168 additions and 126 deletions

View file

@ -23,6 +23,7 @@ Sky :
Clouds :
* Added clouds hardness to light.
* New cloud model with 2 noises : one for the global shape and one for edges.
* Added clouds types with automatic settings.
Rendering :
* Added full scene antialiasing (FSAA).

View file

@ -123,7 +123,7 @@ private:
static double _coverageFunc(CloudsLayerDefinition* layer, Vector3 position)
{
double coverage = curveGetValue(layer->coverage_by_altitude, position.y / layer->thickness + 0.5);
double coverage = curveGetValue(layer->_coverage_by_altitude, position.y / layer->thickness + 0.5);
position.y = 0.0;
double dist = v3Norm(position);
@ -170,13 +170,14 @@ FormClouds::FormClouds(QWidget *parent):
addPreview(_previewCoverage, tr("Layer coverage (no lighting)"));
addPreview(_previewColor, tr("Appearance"));
addInputEnum(tr("Clouds model"), (int*)&_layer->type, QStringList() << tr("Cirrus") << tr("Cumulus") << tr("Stratocumulus") << tr("Stratus"));
addInputDouble(tr("Lower altitude"), &_layer->lower_altitude, -10.0, 50.0, 0.5, 5.0);
addInputDouble(tr("Layer thickness"), &_layer->thickness, 0.0, 20.0, 0.1, 1.0);
addInputDouble(tr("Max coverage"), &_layer->base_coverage, 0.0, 1.0, 0.01, 0.1);
addInputCurve(tr("Coverage by altitude"), _layer->coverage_by_altitude, 0.0, 1.0, 0.0, 1.0, tr("Altitude in cloud layer"), tr("Coverage value"));
addInputNoise(tr("Shape noise"), _layer->shape_noise);
// addInputCurve(tr("Coverage by altitude"), _layer->_coverage_by_altitude, 0.0, 1.0, 0.0, 1.0, tr("Altitude in cloud layer"), tr("Coverage value"));
// addInputNoise(tr("Shape noise"), _layer->_shape_noise);
addInputDouble(tr("Shape scaling"), &_layer->shape_scaling, 3.0, 30.0, 0.3, 3.0);
addInputNoise(tr("Edge noise"), _layer->edge_noise);
// addInputNoise(tr("Edge noise"), _layer->_edge_noise);
addInputDouble(tr("Edge scaling"), &_layer->edge_scaling, 0.5, 5.0, 0.05, 0.5);
addInputDouble(tr("Edge length"), &_layer->edge_length, 0.0, 1.0, 0.01, 0.1);
addInputMaterial(tr("Material"), &_layer->material);
@ -200,6 +201,12 @@ void FormClouds::applyConfig()
scenerySetClouds(&_definition);
}
void FormClouds::configChangeEvent()
{
cloudsLayerValidateDefinition(_layer);
BaseForm::configChangeEvent();
}
void FormClouds::layerGetCopy(void* layer_definition)
{
cloudsLayerCopyDefinition((CloudsLayerDefinition*)layer_definition, _layer);

View file

@ -22,6 +22,9 @@ protected:
virtual void layerApply(void* layer_definition);
virtual void autoPresetSelected(int preset);
protected slots:
virtual void configChangeEvent();
private:
CloudsDefinition _definition;
CloudsLayerDefinition* _layer;

View file

@ -61,7 +61,7 @@ static double _standardCoverageFunc(CloudsLayerDefinition* layer, Vector3 positi
}
else
{
return layer->base_coverage * curveGetValue(layer->coverage_by_altitude, (position.y - layer->lower_altitude) / layer->thickness);
return layer->base_coverage * curveGetValue(layer->_coverage_by_altitude, (position.y - layer->lower_altitude) / layer->thickness);
}
}
@ -70,9 +70,9 @@ CloudsLayerDefinition* cloudsLayerCreateDefinition()
CloudsLayerDefinition* result;
result = malloc(sizeof(CloudsLayerDefinition));
result->coverage_by_altitude = curveCreate();
result->shape_noise = noiseCreateGenerator();
result->edge_noise = noiseCreateGenerator();
result->_coverage_by_altitude = curveCreate();
result->_shape_noise = noiseCreateGenerator();
result->_edge_noise = noiseCreateGenerator();
result->_custom_coverage = _standardCoverageFunc;
@ -83,111 +83,83 @@ CloudsLayerDefinition* cloudsLayerCreateDefinition()
void cloudsLayerDeleteDefinition(CloudsLayerDefinition* definition)
{
curveDelete(definition->coverage_by_altitude);
noiseDeleteGenerator(definition->shape_noise);
noiseDeleteGenerator(definition->edge_noise);
curveDelete(definition->_coverage_by_altitude);
noiseDeleteGenerator(definition->_shape_noise);
noiseDeleteGenerator(definition->_edge_noise);
free(definition);
}
void cloudsLayerAutoPreset(CloudsLayerDefinition* definition, CloudsPreset preset)
{
curveClear(definition->coverage_by_altitude);
noiseClearLevels(definition->shape_noise);
noiseClearLevels(definition->edge_noise);
definition->material.base.r = 0.7;
definition->material.base.g = 0.7;
definition->material.base.b = 0.7;
definition->material.base.a = 1.0;
if (preset == CLOUDS_PRESET_STRATOCUMULUS)
switch (preset)
{
definition->lower_altitude = 5.0;
definition->thickness = 6.0;
curveQuickAddPoint(definition->coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->coverage_by_altitude, 0.2, 1.0);
curveQuickAddPoint(definition->coverage_by_altitude, 0.5, 1.0);
curveQuickAddPoint(definition->coverage_by_altitude, 1.0, 0.0);
definition->material.reflection = 0.3;
definition->material.shininess = 0.8;
definition->hardness = 0.25;
definition->transparencydepth = 1.5;
definition->lighttraversal = 7.0;
definition->minimumlight = 0.4;
definition->shape_scaling = 10.0;
definition->edge_scaling = 0.8;
definition->edge_length = 0.3;
definition->base_coverage = 0.4;
noiseAddLevelsSimple(definition->shape_noise, 2, 1.0, 1.0);
noiseSetFunctionParams(definition->shape_noise, NOISE_FUNCTION_SIMPLEX, 0.3);
noiseAddLevelsSimple(definition->edge_noise, 8, 1.0, 1.0);
noiseSetFunctionParams(definition->edge_noise, NOISE_FUNCTION_SIMPLEX, 0.5);
}
else if (preset == CLOUDS_PRESET_CUMULUS)
{
definition->lower_altitude = 15.0;
definition->thickness = 15.0;
curveQuickAddPoint(definition->coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->coverage_by_altitude, 0.1, 1.0);
curveQuickAddPoint(definition->coverage_by_altitude, 0.4, 0.8);
curveQuickAddPoint(definition->coverage_by_altitude, 0.7, 1.0);
curveQuickAddPoint(definition->coverage_by_altitude, 1.0, 0.0);
definition->material.reflection = 0.5;
definition->material.shininess = 1.2;
definition->hardness = 0.25;
definition->transparencydepth = 1.5;
definition->lighttraversal = 8.0;
definition->minimumlight = 0.4;
definition->shape_scaling = 20.0;
definition->edge_scaling = 2.0;
definition->edge_length = 0.0;
definition->base_coverage = 0.7;
noiseAddLevelsSimple(definition->shape_noise, 7, 1.0, 1.0);
noiseSetFunctionParams(definition->shape_noise, NOISE_FUNCTION_SIMPLEX, 0.4);
}
else if (preset == CLOUDS_PRESET_CIRRUS)
{
definition->lower_altitude = 25.0;
definition->thickness = 2.0;
curveQuickAddPoint(definition->coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->coverage_by_altitude, 0.5, 1.0);
curveQuickAddPoint(definition->coverage_by_altitude, 1.0, 0.0);
definition->material.reflection = 0.4;
definition->material.shininess = 0.5;
definition->hardness = 0.0;
definition->transparencydepth = 3.0;
definition->lighttraversal = 10.0;
definition->minimumlight = 0.6;
definition->shape_scaling = 8.0;
definition->edge_scaling = 2.0;
definition->edge_length = 0.8;
definition->base_coverage = 0.6;
noiseAddLevelsSimple(definition->shape_noise, 3, 1.0, 1.0);
noiseSetFunctionParams(definition->shape_noise, NOISE_FUNCTION_SIMPLEX, 0.0);
noiseAddLevelsSimple(definition->edge_noise, 4, 1.0, 1.0);
noiseSetFunctionParams(definition->edge_noise, NOISE_FUNCTION_SIMPLEX, -0.2);
}
else if (preset == CLOUDS_PRESET_STRATUS)
{
definition->lower_altitude = 3.0;
definition->thickness = 4.0;
curveQuickAddPoint(definition->coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->coverage_by_altitude, 0.2, 1.0);
curveQuickAddPoint(definition->coverage_by_altitude, 0.8, 1.0);
curveQuickAddPoint(definition->coverage_by_altitude, 1.0, 0.0);
definition->material.reflection = 0.1;
definition->material.shininess = 0.8;
definition->hardness = 0.1;
definition->transparencydepth = 3.0;
definition->lighttraversal = 10.0;
definition->minimumlight = 0.6;
definition->shape_scaling = 8.0;
definition->edge_scaling = 2.0;
definition->edge_length = 1.0;
definition->base_coverage = 0.4;
noiseAddLevelsSimple(definition->shape_noise, 3, 1.0, 1.0);
noiseSetFunctionParams(definition->shape_noise, NOISE_FUNCTION_SIMPLEX, -0.3);
noiseAddLevelsSimple(definition->edge_noise, 4, 1.0, 1.0);
noiseSetFunctionParams(definition->edge_noise, NOISE_FUNCTION_SIMPLEX, -0.5);
case CLOUDS_PRESET_CIRRUS:
definition->type = CLOUDS_TYPE_CIRRUS;
definition->lower_altitude = 25.0;
definition->thickness = 2.0;
definition->material.reflection = 0.4;
definition->material.shininess = 0.5;
definition->hardness = 0.0;
definition->transparencydepth = 3.0;
definition->lighttraversal = 10.0;
definition->minimumlight = 0.6;
definition->shape_scaling = 8.0;
definition->edge_scaling = 2.0;
definition->edge_length = 0.8;
definition->base_coverage = 0.6;
break;
case CLOUDS_PRESET_CUMULUS:
definition->type = CLOUDS_TYPE_CUMULUS;
definition->lower_altitude = 15.0;
definition->thickness = 15.0;
definition->material.reflection = 0.5;
definition->material.shininess = 1.2;
definition->hardness = 0.25;
definition->transparencydepth = 1.5;
definition->lighttraversal = 8.0;
definition->minimumlight = 0.4;
definition->shape_scaling = 20.0;
definition->edge_scaling = 2.0;
definition->edge_length = 0.0;
definition->base_coverage = 0.7;
break;
case CLOUDS_PRESET_STRATOCUMULUS:
definition->type = CLOUDS_TYPE_STRATOCUMULUS;
definition->lower_altitude = 5.0;
definition->thickness = 6.0;
definition->material.reflection = 0.3;
definition->material.shininess = 0.8;
definition->hardness = 0.25;
definition->transparencydepth = 1.5;
definition->lighttraversal = 7.0;
definition->minimumlight = 0.4;
definition->shape_scaling = 10.0;
definition->edge_scaling = 0.8;
definition->edge_length = 0.3;
definition->base_coverage = 0.4;
break;
case CLOUDS_PRESET_STRATUS:
definition->type = CLOUDS_TYPE_STRATUS;
definition->lower_altitude = 3.0;
definition->thickness = 4.0;
definition->material.reflection = 0.1;
definition->material.shininess = 0.8;
definition->hardness = 0.1;
definition->transparencydepth = 3.0;
definition->lighttraversal = 10.0;
definition->minimumlight = 0.6;
definition->shape_scaling = 8.0;
definition->edge_scaling = 2.0;
definition->edge_length = 1.0;
definition->base_coverage = 0.4;
break;
default:
break;
}
cloudsLayerValidateDefinition(definition);
@ -200,14 +172,14 @@ void cloudsLayerCopyDefinition(CloudsLayerDefinition* source, CloudsLayerDefinit
temp = *destination;
*destination = *source;
destination->shape_noise = temp.shape_noise;
noiseCopy(source->shape_noise, destination->shape_noise);
destination->_shape_noise = temp._shape_noise;
noiseCopy(source->_shape_noise, destination->_shape_noise);
destination->edge_noise = temp.edge_noise;
noiseCopy(source->edge_noise, destination->edge_noise);
destination->_edge_noise = temp._edge_noise;
noiseCopy(source->_edge_noise, destination->_edge_noise);
destination->coverage_by_altitude = temp.coverage_by_altitude;
curveCopy(source->coverage_by_altitude, destination->coverage_by_altitude);
destination->_coverage_by_altitude = temp._coverage_by_altitude;
curveCopy(source->_coverage_by_altitude, destination->_coverage_by_altitude);
}
void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition)
@ -224,15 +196,66 @@ void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition)
{
definition->_custom_coverage = _standardCoverageFunc;
}
curveClear(definition->_coverage_by_altitude);
noiseClearLevels(definition->_shape_noise);
noiseClearLevels(definition->_edge_noise);
switch (definition->type)
{
case CLOUDS_TYPE_CIRRUS:
curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.5, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 3, 1.0, 1.0);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.0);
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, 1.0);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -0.2);
break;
case CLOUDS_TYPE_CUMULUS:
curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.1, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.4, 0.8);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.7, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 7, 1.0, 1.0);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.4);
break;
case CLOUDS_TYPE_STRATOCUMULUS:
curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.2, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.5, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 2, 1.0, 1.0);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.3);
noiseAddLevelsSimple(definition->_edge_noise, 8, 1.0, 1.0);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, 0.5);
break;
case CLOUDS_TYPE_STRATUS:
curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.2, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.8, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 3, 1.0, 1.0);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, -0.3);
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, 1.0);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -0.5);
break;
default:
break;
}
}
void _cloudsLayerSave(PackStream* stream, CloudsLayerDefinition* layer)
{
int clouds_type = (int)layer->type;
packWriteInt(stream, &clouds_type);
packWriteDouble(stream, &layer->lower_altitude);
packWriteDouble(stream, &layer->thickness);
curveSave(stream, layer->coverage_by_altitude);
noiseSaveGenerator(stream, layer->shape_noise);
noiseSaveGenerator(stream, layer->edge_noise);
curveSave(stream, layer->_coverage_by_altitude);
noiseSaveGenerator(stream, layer->_shape_noise);
noiseSaveGenerator(stream, layer->_edge_noise);
materialSave(stream, &layer->material);
packWriteDouble(stream, &layer->hardness);
packWriteDouble(stream, &layer->transparencydepth);
@ -246,11 +269,12 @@ void _cloudsLayerSave(PackStream* stream, CloudsLayerDefinition* layer)
void _cloudsLayerLoad(PackStream* stream, CloudsLayerDefinition* layer)
{
int clouds_type;
packReadInt(stream, &clouds_type);
layer->type = (CloudsType)clouds_type;
packReadDouble(stream, &layer->lower_altitude);
packReadDouble(stream, &layer->thickness);
curveLoad(stream, layer->coverage_by_altitude);
noiseLoadGenerator(stream, layer->shape_noise);
noiseLoadGenerator(stream, layer->edge_noise);
materialLoad(stream, &layer->material);
packReadDouble(stream, &layer->hardness);
packReadDouble(stream, &layer->transparencydepth);
@ -260,6 +284,8 @@ void _cloudsLayerLoad(PackStream* stream, CloudsLayerDefinition* layer)
packReadDouble(stream, &layer->edge_scaling);
packReadDouble(stream, &layer->edge_length);
packReadDouble(stream, &layer->base_coverage);
cloudsLayerValidateDefinition(layer);
}
LayerType cloudsGetLayerType()
@ -280,7 +306,7 @@ static inline double _getDistanceToBorder(CloudsLayerDefinition* layer, Vector3
{
double density, coverage, val;
val = noiseGet3DTotal(layer->shape_noise, position.x / layer->shape_scaling, position.y / layer->shape_scaling, position.z / layer->shape_scaling) / noiseGetMaxValue(layer->shape_noise);
val = noiseGet3DTotal(layer->_shape_noise, position.x / layer->shape_scaling, position.y / layer->shape_scaling, position.z / layer->shape_scaling) / noiseGetMaxValue(layer->_shape_noise);
coverage = layer->_custom_coverage(layer, position);
density = 0.5 * val - 0.5 + coverage;
@ -297,7 +323,7 @@ static inline double _getDistanceToBorder(CloudsLayerDefinition* layer, Vector3
{
density /= layer->edge_length;
val = 0.5 * noiseGet3DTotal(layer->edge_noise, position.x / layer->edge_scaling, position.y / layer->edge_scaling, position.z / layer->edge_scaling) / noiseGetMaxValue(layer->edge_noise);
val = 0.5 * noiseGet3DTotal(layer->_edge_noise, position.x / layer->edge_scaling, position.y / layer->edge_scaling, position.z / layer->edge_scaling) / noiseGetMaxValue(layer->_edge_noise);
val = val - 0.5 + density;
return val * (density * coverage * layer->shape_scaling + (1.0 - density) * layer->edge_scaling);

View file

@ -10,6 +10,14 @@
extern "C" {
#endif
typedef enum
{
CLOUDS_TYPE_CIRRUS,
CLOUDS_TYPE_CUMULUS,
CLOUDS_TYPE_STRATOCUMULUS,
CLOUDS_TYPE_STRATUS
} CloudsType;
typedef enum
{
CLOUDS_PRESET_CIRRUS,
@ -24,13 +32,11 @@ typedef double (*CloudCoverageFunc)(CloudsLayerDefinition* definition, Vector3 p
struct CloudsLayerDefinition
{
CloudsType type;
double lower_altitude;
double thickness;
double base_coverage;
Curve* coverage_by_altitude;
NoiseGenerator* shape_noise;
double shape_scaling;
NoiseGenerator* edge_noise;
double edge_scaling;
double edge_length;
SurfaceMaterial material;
@ -38,7 +44,11 @@ struct CloudsLayerDefinition
double transparencydepth;
double lighttraversal;
double minimumlight;
CloudCoverageFunc _custom_coverage;
Curve* _coverage_by_altitude;
NoiseGenerator* _shape_noise;
NoiseGenerator* _edge_noise;
};
typedef struct

View file

@ -180,14 +180,9 @@ void openclInit()
/* Get platform */
error = clGetPlatformIDs(1, &_platform, &platform_count);
if (error != CL_SUCCESS)
if (error != CL_SUCCESS || platform_count != 1)
{
printf("[OpenCL] Error getting platform id: %s\n", _getErrorMessage(error));
return;
}
else if (platform_count != 1)
{
printf("[OpenCL] No platform available\n");
printf("OpenCL support is unavailable\n");
return;
}
/* Get available devices */