Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorMiika Hamalainen <blender@miikah.org>2011-08-05 13:31:35 +0400
committerMiika Hamalainen <blender@miikah.org>2011-08-05 13:31:35 +0400
commit5467df14cac09a05081db0aa2166306e0f35cbe4 (patch)
tree1363d5ccd0615ad02edf217a8c7c3805d7240548 /source
parentf4c93eb580ede4863ab200b557fba7a8e1308b82 (diff)
Dynamic Paint:
* Added a new "color spread" slider for "spread" effect to adjust how much colors get mixed. * Improved smudge behavior on "wet" paint. * Displace can now be set "incremental". This way it's added on top of previous displace. * Added "displace clamp" setting. You can use it to limit maximum amount of displace. * Fix: velocity data wasn't always initialized, this could lead to no effect at all or crash. * Fix: Vertex color rendering near zero alpha values was still incorrect.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c263
-rw-r--r--source/blender/makesdna/DNA_dynamicpaint_types.h6
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c22
-rw-r--r--source/blender/render/intern/source/shadeinput.c12
4 files changed, 183 insertions, 120 deletions
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 290e6320c96..0b15744bb60 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -305,11 +305,13 @@ void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface) {
surface->output_name[0]='\0';
surface->output_name2[0]='\0';
surface->flags |= MOD_DPAINT_ANTIALIAS;
+ surface->disp_clamp = 1.0f;
}
else {
sprintf(surface->output_name, "dp_");
strcpy(surface->output_name2,surface->output_name);
surface->flags &= ~MOD_DPAINT_ANTIALIAS;
+ surface->disp_clamp = 0.0f;
}
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
@@ -894,7 +896,7 @@ static DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSett
surface->diss_speed = 300;
surface->dry_speed = 300;
- surface->disp_depth = 1.0f;
+ surface->disp_clamp = 0.0f;
surface->disp_type = MOD_DPAINT_DISP_DISPLACE;
surface->image_fileformat = MOD_DPAINT_IMGFORMAT_PNG;
@@ -911,6 +913,7 @@ static DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSett
}
surface->spread_speed = 1.0f;
+ surface->color_spread_speed = 1.0f;
surface->shrink_speed = 1.0f;
surface->wave_damping = 0.05f;
@@ -1263,87 +1266,40 @@ static void dynamicPaint_checkSurfaceData(DynamicPaintSurface *surface)
/***************************** Modifier processing ******************************/
-/* update cache frame range */
-void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface) {
- if (surface->pointcache) {
- surface->pointcache->startframe = surface->start_frame;
- surface->pointcache->endframe = surface->end_frame;
- }
-}
-
-/*
-* Updates derived mesh copy and processes dynamic paint step / caches.
-*/
-static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
+/* apply displacing vertex surface to the derived mesh */
+static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, DerivedMesh *result, int update_normals)
{
- if(pmd->canvas) {
- DynamicPaintCanvasSettings *canvas = pmd->canvas;
- DynamicPaintSurface *surface = canvas->surfaces.first;
-
- /* update derived mesh copy */
- if (canvas->dm) canvas->dm->release(canvas->dm);
- canvas->dm = CDDM_copy(dm);
-
- /* in case image sequence baking, stop here */
- if (canvas->flags & MOD_DPAINT_BAKING) return;
-
- /* loop through surfaces */
- for (; surface; surface=surface->next) {
- int current_frame = (int)scene->r.cfra;
-
- /* image sequences are handled by bake operator */
- if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) continue;
- if (!(surface->flags & MOD_DPAINT_ACTIVE)) continue;
-
- /* make sure surface is valid */
- dynamicPaint_checkSurfaceData(surface);
-
- /* limit frame range */
- CLAMP(current_frame, surface->start_frame, surface->end_frame);
-
- if (current_frame != surface->current_frame || (int)scene->r.cfra == surface->start_frame) {
- PointCache *cache = surface->pointcache;
- PTCacheID pid;
- surface->current_frame = current_frame;
+ PaintSurfaceData *sData = surface->data;
- /* read point cache */
- BKE_ptcache_id_from_dynamicpaint(&pid, ob, surface);
- pid.cache->startframe = surface->start_frame;
- pid.cache->endframe = surface->end_frame;
- BKE_ptcache_id_time(&pid, scene, scene->r.cfra, NULL, NULL, NULL);
+ if (!sData || surface->format != MOD_DPAINT_SURFACE_F_VERTEX) return;
- /* reset non-baked cache at first frame */
- if((int)scene->r.cfra == surface->start_frame && !(cache->flag & PTCACHE_BAKED))
- {
- cache->flag |= PTCACHE_REDO_NEEDED;
- BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
- cache->flag &= ~PTCACHE_REDO_NEEDED;
- }
+ /* displace paint */
+ if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
+ MVert *mvert = result->getVertArray(result);
+ int i;
+ float* value = (float*)sData->type_data;
- /* try to read from cache */
- if(BKE_ptcache_read(&pid, (float)scene->r.cfra)) {
- BKE_ptcache_validate(cache, (int)scene->r.cfra);
- }
- /* if read failed and we're on surface range do recalculate */
- else if ((int)scene->r.cfra == current_frame
- && !(cache->flag & PTCACHE_BAKED)) {
- /* calculate surface frame */
- canvas->flags |= MOD_DPAINT_BAKING;
- dynamicPaint_calculateFrame(surface, scene, ob, current_frame);
- canvas->flags &= ~MOD_DPAINT_BAKING;
+ #pragma omp parallel for schedule(static)
+ for (i=0; i<sData->total_points; i++) {
+ float normal[3];
+ normal_short_to_float_v3(normal, mvert[i].no);
+ normalize_v3(normal);
- BKE_ptcache_validate(cache, surface->current_frame);
- BKE_ptcache_write(&pid, surface->current_frame);
- }
- }
+ mvert[i].co[0] -= normal[0]*value[i];
+ mvert[i].co[1] -= normal[1]*value[i];
+ mvert[i].co[2] -= normal[2]*value[i];
}
}
+ else return;
+
+ if (update_normals)
+ CDDM_calc_normals(result);
}
/*
* Apply canvas data to the object derived mesh
*/
-struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
+static struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
{
DerivedMesh *result = CDDM_copy(dm);
@@ -1471,26 +1427,6 @@ struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, S
}
}
}
- /* displace paint */
- else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
- MVert *mvert = result->getVertArray(result);
- int i;
- float* value = (float*)sData->type_data;
-
- #pragma omp parallel for schedule(static)
- for (i=0; i<sData->total_points; i++) {
- float normal[3];
- normal_short_to_float_v3(normal, mvert[i].no);
- normalize_v3(normal);
-
- mvert[i].co[0] -= normal[0]*value[i];
- mvert[i].co[1] -= normal[1]*value[i];
- mvert[i].co[2] -= normal[2]*value[i];
- }
-
- CDDM_calc_normals(result);
- }
-
/* vertex group paint */
else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
int defgrp_index = defgroup_name_index(ob, surface->output_name);
@@ -1584,9 +1520,10 @@ struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, S
mvert[i].co[1] += normal[1]*wPoint[i].height;
mvert[i].co[2] += normal[2]*wPoint[i].height;
}
-
- CDDM_calc_normals(result);
}
+
+ /* displace */
+ dynamicPaint_applySurfaceDisplace(surface, result, 1);
}
}
}
@@ -1600,6 +1537,94 @@ struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, S
return result;
}
+/* update cache frame range */
+void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface)
+{
+ if (surface->pointcache) {
+ surface->pointcache->startframe = surface->start_frame;
+ surface->pointcache->endframe = surface->end_frame;
+ }
+}
+
+void canvas_copyDerivedMesh(DynamicPaintCanvasSettings *canvas, DerivedMesh *dm)
+{
+ if (canvas->dm) canvas->dm->release(canvas->dm);
+ canvas->dm = CDDM_copy(dm);
+}
+
+/*
+* Updates derived mesh copy and processes dynamic paint step / caches.
+*/
+static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
+{
+ if(pmd->canvas) {
+ DynamicPaintCanvasSettings *canvas = pmd->canvas;
+ DynamicPaintSurface *surface = canvas->surfaces.first;
+
+ /* update derived mesh copy */
+ canvas_copyDerivedMesh(canvas, dm);
+
+ /* in case image sequence baking, stop here */
+ if (canvas->flags & MOD_DPAINT_BAKING) return;
+
+ /* loop through surfaces */
+ for (; surface; surface=surface->next) {
+ int current_frame = (int)scene->r.cfra;
+
+ /* image sequences are handled by bake operator */
+ if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) continue;
+ if (!(surface->flags & MOD_DPAINT_ACTIVE)) continue;
+
+ /* make sure surface is valid */
+ dynamicPaint_checkSurfaceData(surface);
+
+ /* limit frame range */
+ CLAMP(current_frame, surface->start_frame, surface->end_frame);
+
+ if (current_frame != surface->current_frame || (int)scene->r.cfra == surface->start_frame) {
+ PointCache *cache = surface->pointcache;
+ PTCacheID pid;
+ surface->current_frame = current_frame;
+
+ /* read point cache */
+ BKE_ptcache_id_from_dynamicpaint(&pid, ob, surface);
+ pid.cache->startframe = surface->start_frame;
+ pid.cache->endframe = surface->end_frame;
+ BKE_ptcache_id_time(&pid, scene, scene->r.cfra, NULL, NULL, NULL);
+
+ /* reset non-baked cache at first frame */
+ if((int)scene->r.cfra == surface->start_frame && !(cache->flag & PTCACHE_BAKED))
+ {
+ cache->flag |= PTCACHE_REDO_NEEDED;
+ BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+ cache->flag &= ~PTCACHE_REDO_NEEDED;
+ }
+
+ /* try to read from cache */
+ if(BKE_ptcache_read(&pid, (float)scene->r.cfra)) {
+ BKE_ptcache_validate(cache, (int)scene->r.cfra);
+ }
+ /* if read failed and we're on surface range do recalculate */
+ else if ((int)scene->r.cfra == current_frame
+ && !(cache->flag & PTCACHE_BAKED)) {
+ /* calculate surface frame */
+ canvas->flags |= MOD_DPAINT_BAKING;
+ dynamicPaint_calculateFrame(surface, scene, ob, current_frame);
+ canvas->flags &= ~MOD_DPAINT_BAKING;
+
+ /* restore canvas derivedmesh if required */
+ if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE &&
+ surface->flags & MOD_DPAINT_DISP_INCREMENTAL && surface->next)
+ canvas_copyDerivedMesh(canvas, dm);
+
+ BKE_ptcache_validate(cache, surface->current_frame);
+ BKE_ptcache_write(&pid, surface->current_frame);
+ }
+ }
+ }
+ }
+}
+
/* Modifier call. Processes dynamic paint modifier step. */
struct DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
{
@@ -2339,9 +2364,10 @@ void dynamicPaint_outputImage(DynamicPaintSurface *surface, char* filename, shor
float depth = ((float*)sData->type_data)[index];
if (surface->disp_type == MOD_DPAINT_DISP_DISPLACE) {
+ if (surface->disp_clamp)
+ depth /= surface->disp_clamp*2.0f;
depth = (0.5f - depth);
- if (depth < 0.0f) depth = 0.0f;
- if (depth > 1.0f) depth = 1.0f;
+ CLAMP(depth, 0.0f, 1.0f);
}
mhImgB->rect_float[pos]=depth;
@@ -3016,6 +3042,7 @@ static void dynamicPaint_mixPaintColors(DynamicPaintSurface *surface, int index,
/* only increase wetness if it's below paint level */
wetness = (*paintWetness) * pPoint->e_alpha;
if (pPoint->wetness < wetness) pPoint->wetness = wetness;
+ pPoint->state = 2;
}
/* Erase paint */
else {
@@ -3115,6 +3142,12 @@ static void dynamicPaint_updatePointData(DynamicPaintSurface *surface, unsigned
else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
float *value = (float*)sData->type_data;
+ if (surface->flags & MOD_DPAINT_DISP_INCREMENTAL)
+ depth = value[index] + depth;
+
+ if (surface->disp_clamp && depth > surface->disp_clamp)
+ depth = surface->disp_clamp;
+
if (brush->flags & MOD_DPAINT_ERASE) {
value[index] *= (1.0f - strength);
if (value[index] < 0.0f) value[index] = 0.0f;
@@ -3138,7 +3171,7 @@ static void dynamicPaint_updatePointData(DynamicPaintSurface *surface, unsigned
/* wave surface */
else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
dynamicPaint_mixWaveHeight(&((PaintWavePoint*)sData->type_data)[index],
- brush, 0.0f-depth);
+ brush, 0.0f-depth);
}
/* doing velocity based painting */
@@ -3339,10 +3372,6 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, DynamicPaintBrus
float paintColor[3] = {0.0f};
int numOfHits = 0;
- //PaintPoint *pPoint = &((PaintPoint*)sData->type_data)[index];
- //pPoint->color[3] = id / grid->s_num[c_index];
- //pPoint->alpha = 1.0f;
-
/* for image sequence anti-aliasing, use gaussian factors */
if (samples > 1 && surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ)
total_sample = gaussianTotal;
@@ -3511,7 +3540,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, DynamicPaintBrus
if (!hit_found) continue;
/* velocity brush, only do on main sample */
- if (brush->flags & MOD_DPAINT_USES_VELOCITY && ss==0 && bData->velocity && brushVelocity) {
+ if (brush->flags & MOD_DPAINT_USES_VELOCITY && ss==0 && brushVelocity) {
int v1,v2,v3;
float weights[4];
float brushPointVelocity[3];
@@ -3540,7 +3569,12 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, DynamicPaintBrus
brushVelocity[v3].v, weights);
/* substract canvas point velocity */
- VECSUB(velocity, brushPointVelocity, bData->velocity[index].v);
+ if (bData->velocity) {
+ VECSUB(velocity, brushPointVelocity, bData->velocity[index].v);
+ }
+ else {
+ VECCOPY(velocity, brushPointVelocity);
+ }
velocity_val = len_v3(velocity);
/* */
@@ -3841,7 +3875,9 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, ParticleSys
mul_v3_v3fl(velocity, pa->state.vel, particle_timestep);
/* substract canvas point velocity */
- VECSUB(velocity, velocity, bData->velocity[index].v);
+ if (bData->velocity) {
+ VECSUB(velocity, velocity, bData->velocity[index].v);
+ }
velocity_val = len_v3(velocity);
if (brush->flags & MOD_DPAINT_DO_SMUDGE && bData->brush_velocity) {
@@ -3937,7 +3973,12 @@ static int dynamicPaint_paintSinglePoint(DynamicPaintSurface *surface, float *po
float velocity[3];
/* substract canvas point velocity */
- VECSUB(velocity, brushVel.v, bData->velocity[index].v);
+ if (bData->velocity) {
+ VECSUB(velocity, brushVel.v, bData->velocity[index].v);
+ }
+ else {
+ VECCOPY(velocity, brushVel.v);
+ }
velocity_val = len_v3(velocity);
if (brush->flags & MOD_DPAINT_DO_SMUDGE && bData->brush_velocity) {
@@ -4136,6 +4177,12 @@ static void dynamicPaint_doSmudge(DynamicPaintSurface *surface, DynamicPaintBrus
mix = dir_factor*pPoint->alpha;
if (mix) mixColors(ePoint->color, ePoint->alpha, pPoint->color, mix);
ePoint->alpha = ePoint->alpha*(1.0f-dir_factor) + pPoint->alpha*dir_factor;
+
+ /* smudge "wet layer" depending on user defined factor */
+ mix = dir_factor*pPoint->e_alpha;
+ if (mix) mixColors(ePoint->e_color, ePoint->e_alpha, pPoint->e_color, mix);
+ ePoint->e_alpha = ePoint->e_alpha*(1.0f-dir_factor) + pPoint->e_alpha*dir_factor;
+ pPoint->wetness *= (1.0f-dir_factor);
}
}
}
@@ -4280,7 +4327,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
float w_factor, alphaAdd = 0.0f;
PaintPoint *ePoint = &prevPoint[sData->adj_data->n_target[n_index]];
float speed_scale = (bNeighs[n_index].dist<eff_scale) ? 1.0f : eff_scale/bNeighs[n_index].dist;
- float color_mix = (MIN2(ePoint->wetness, pPoint->wetness))*0.25f;
+ float color_mix = (MIN2(ePoint->wetness, pPoint->wetness))*0.25f*surface->color_spread_speed;
totalAlpha += ePoint->e_alpha;
@@ -4599,7 +4646,7 @@ static void dynamicPaint_surfacePreStep(DynamicPaintSurface *surface, float time
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
PaintPoint *pPoint = &((PaintPoint*)sData->type_data)[index];
/* drying */
- if (pPoint->wetness > 0.0f) {
+ if (pPoint->wetness > 0.0f || pPoint->state > 0) {
/* for every drying step blend wet paint to the background */
if (pPoint->e_alpha) mixColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha);
pPoint->state = 1;
@@ -4670,7 +4717,7 @@ static int dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *ob
}
}
- return 0;
+ return ret;
}
static int surface_needsVelocityData(DynamicPaintSurface *surface, Scene *scene, Object *ob)
@@ -5075,6 +5122,10 @@ static int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Scene *scen
{
float timescale = 1.0f;
+ /* apply previous displace on derivedmesh if incremental surface */
+ if (surface->flags & MOD_DPAINT_DISP_INCREMENTAL)
+ dynamicPaint_applySurfaceDisplace(surface, surface->canvas->dm, 0);
+
/* update bake data */
dynamicPaint_generateBakeData(surface, scene, cObject);
diff --git a/source/blender/makesdna/DNA_dynamicpaint_types.h b/source/blender/makesdna/DNA_dynamicpaint_types.h
index 7793a0b34d8..4454d447909 100644
--- a/source/blender/makesdna/DNA_dynamicpaint_types.h
+++ b/source/blender/makesdna/DNA_dynamicpaint_types.h
@@ -39,6 +39,7 @@ struct PaintSurfaceData;
#define MOD_DPAINT_PREVIEW (1<<6) /* preview this surface on viewport*/
#define MOD_DPAINT_WAVE_OPEN_BORDERS (1<<7) /* passes waves through mesh edges */
+#define MOD_DPAINT_DISP_INCREMENTAL (1<<8) /* builds displace on top of earlier values */
#define MOD_DPAINT_OUT1 (1<<10) /* output primary surface */
#define MOD_DPAINT_OUT2 (1<<11) /* output secondary surface */
@@ -82,14 +83,13 @@ typedef struct DynamicPaintSurface {
int start_frame, end_frame;
int dry_speed, diss_speed;
- float disp_depth;
+ float disp_clamp;
- float spread_speed, shrink_speed;
+ float spread_speed, color_spread_speed, shrink_speed;
float drip_vel, drip_acc;
/* wave settings */
float wave_damping, wave_speed, wave_timescale, wave_spring;
- float pad_f;
char uvlayer_name[32];
char image_output_path[240];
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index 12aed3c8aac..d0f8264b656 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -460,6 +460,12 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_range(prop, 0.001, 10.0);
RNA_def_property_ui_range(prop, 0.01, 5.0, 1, 2);
RNA_def_property_ui_text(prop, "Spread Speed", "How fast spread effect moves on the canvas surface.");
+
+ prop= RNA_def_property(srna, "color_spread_speed", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "color_spread_speed");
+ RNA_def_property_range(prop, 0.0, 2.0);
+ RNA_def_property_ui_range(prop, 0.0, 2.0, 1, 2);
+ RNA_def_property_ui_text(prop, "Color Spread", "How fast colors get mixed within wet paint.");
prop= RNA_def_property(srna, "use_drip", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -537,12 +543,12 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
parm= RNA_def_boolean(func, "exists", 0, "", "");
RNA_def_function_return(func, parm);
- prop= RNA_def_property(srna, "displacement", PROP_FLOAT, PROP_NONE);
+ prop= RNA_def_property(srna, "disp_clamp", PROP_FLOAT, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_float_sdna(prop, NULL, "disp_depth");
- RNA_def_property_range(prop, 0.01, 5.0);
- RNA_def_property_ui_range(prop, 0.01, 5.0, 1, 2);
- RNA_def_property_ui_text(prop, "Displace Strength", "Maximum level of intersection to store in the texture. Use same value as the displace method strength.");
+ RNA_def_property_float_sdna(prop, NULL, "disp_clamp");
+ RNA_def_property_range(prop, 0.00, 50.0);
+ RNA_def_property_ui_range(prop, 0.00, 5.0, 1, 2);
+ RNA_def_property_ui_text(prop, "Clamp Displace", "Maximum level of displace intersection. Use 0.0 to disable.");
prop= RNA_def_property(srna, "image_fileformat", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -556,6 +562,12 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_dynamicpaint_disp_type);
RNA_def_property_ui_text(prop, "Data Type", "");
+ prop= RNA_def_property(srna, "incremental_disp", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_DISP_INCREMENTAL);
+ RNA_def_property_ui_text(prop, "Incremental", "New displace is added cumulatively on top of existing.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_DynamicPaintSurface_reset");
+
/* wave simulator settings */
prop= RNA_def_property(srna, "wave_damping", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "wave_damping");
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 301d5ba5568..2b3ad1027e5 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -1117,14 +1117,14 @@ void shade_input_set_shade_texco(ShadeInput *shi)
scol->col[3]= (l*((float)cp3[0]) - u*((float)cp1[0]) - v*((float)cp2[0]))/255.0f;
/* try to prevent invalid color sampling of zero alpha points */
- if (!cp1[3]) cp1 = cp2;
- if (!cp1[3]) cp1 = cp3;
+ if (!cp1[0]) cp1 = cp2;
+ if (!cp1[0]) cp1 = cp3;
- if (!cp2[3]) cp2 = cp1;
- if (!cp2[3]) cp1 = cp3;
+ if (!cp2[0]) cp2 = cp1;
+ if (!cp2[0]) cp2 = cp3;
- if (!cp3[3]) cp3 = cp1;
- if (!cp3[3]) cp3 = cp2;
+ if (!cp3[0]) cp3 = cp1;
+ if (!cp3[0]) cp3 = cp2;
/* sample color value */
scol->col[0]= (l*((float)cp3[3]) - u*((float)cp1[3]) - v*((float)cp2[3]))/255.0f;