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
diff options
context:
space:
mode:
-rw-r--r--release/scripts/ui/buttons_material.py63
-rw-r--r--release/scripts/ui/buttons_texture.py6
-rw-r--r--source/blender/blenkernel/intern/material.c6
-rw-r--r--source/blender/blenkernel/intern/texture.c1
-rw-r--r--source/blender/blenloader/intern/readfile.c19
-rw-r--r--source/blender/editors/render/render_preview.c15
-rw-r--r--source/blender/makesdna/DNA_material_types.h44
-rw-r--r--source/blender/makesdna/DNA_texture_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_material.c107
-rw-r--r--source/blender/makesrna/intern/rna_texture.c24
-rw-r--r--source/blender/render/intern/include/volume_precache.h2
-rw-r--r--source/blender/render/intern/include/volumetric.h3
-rw-r--r--source/blender/render/intern/source/convertblender.c24
-rw-r--r--source/blender/render/intern/source/rayshade.c3
-rw-r--r--source/blender/render/intern/source/texture.c17
-rw-r--r--source/blender/render/intern/source/volume_precache.c53
-rw-r--r--source/blender/render/intern/source/volumetric.c282
-rw-r--r--source/blender/render/intern/source/voxeldata.c6
18 files changed, 395 insertions, 283 deletions
diff --git a/release/scripts/ui/buttons_material.py b/release/scripts/ui/buttons_material.py
index 448cb36e130..ee7193da301 100644
--- a/release/scripts/ui/buttons_material.py
+++ b/release/scripts/ui/buttons_material.py
@@ -609,6 +609,23 @@ class VolumeButtonsPanel(bpy.types.Panel):
mat = context.material
engine = context.scene.render_data.engine
return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES)
+
+class MATERIAL_PT_volume_density(VolumeButtonsPanel):
+ __label__ = "Density"
+ __default_closed__ = False
+ COMPAT_ENGINES = set(['BLENDER_RENDER'])
+
+ def draw(self, context):
+ layout = self.layout
+
+ mat = context.material
+ vol = context.material.volume
+
+ split = layout.split()
+ row = split.row()
+ row.itemR(vol, "density")
+ row.itemR(vol, "density_scale")
+
class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
__label__ = "Shading"
@@ -620,22 +637,23 @@ class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
vol = context.material.volume
- row = layout.row()
- row.itemR(vol, "density")
- row.itemR(vol, "scattering")
-
split = layout.split()
col = split.column()
- col.itemR(vol, "absorption")
- col.itemR(vol, "absorption_color", text="")
-
+ col.itemR(vol, "scattering")
+ col.itemR(vol, "asymmetry")
+ col.itemR(vol, "transmission_color")
+
col = split.column()
- col.itemR(vol, "emission")
- col.itemR(vol, "emission_color", text="")
+ sub = col.column(align=True)
+ sub.itemR(vol, "emission")
+ sub.itemR(vol, "emission_color", text="")
+ sub = col.column(align=True)
+ sub.itemR(vol, "reflection")
+ sub.itemR(vol, "reflection_color", text="")
-class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
- __label__ = "Scattering"
+class MATERIAL_PT_volume_lighting(VolumeButtonsPanel):
+ __label__ = "Lighting"
__default_closed__ = False
COMPAT_ENGINES = set(['BLENDER_RENDER'])
@@ -648,24 +666,26 @@ class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
col = split.column()
col.itemR(vol, "scattering_mode", text="")
+
+ col = split.column()
+
if vol.scattering_mode == 'SINGLE_SCATTERING':
col.itemR(vol, "light_cache")
sub = col.column()
sub.active = vol.light_cache
sub.itemR(vol, "cache_resolution")
elif vol.scattering_mode in ('MULTIPLE_SCATTERING', 'SINGLE_PLUS_MULTIPLE_SCATTERING'):
+ sub = col.column()
+ sub.enabled = True
+ sub.active = False
+ sub.itemR(vol, "light_cache")
col.itemR(vol, "cache_resolution")
sub = col.column(align=True)
sub.itemR(vol, "ms_diffusion")
sub.itemR(vol, "ms_spread")
sub.itemR(vol, "ms_intensity")
-
- col = split.column()
- # col.itemL(text="Anisotropic Scattering:")
- col.itemR(vol, "phase_function", text="")
- if vol.phase_function in ('SCHLICK', 'HENYEY-GREENSTEIN'):
- col.itemR(vol, "asymmetry")
+
class MATERIAL_PT_volume_transp(VolumeButtonsPanel):
__label__= "Transparency"
@@ -693,16 +713,15 @@ class MATERIAL_PT_volume_integration(VolumeButtonsPanel):
col = split.column()
col.itemL(text="Step Calculation:")
col.itemR(vol, "step_calculation", text="")
- sub = col.column(align=True)
- sub.itemR(vol, "step_size")
- sub.itemR(vol, "shading_step_size")
+ col = col.column(align=True)
+ col.itemR(vol, "step_size")
col = split.column()
col.itemL()
col.itemR(vol, "depth_cutoff")
- col.itemR(vol, "density_scale")
+bpy.types.register(MATERIAL_PT_volume_density)
bpy.types.register(MATERIAL_PT_volume_shading)
-bpy.types.register(MATERIAL_PT_volume_scattering)
+bpy.types.register(MATERIAL_PT_volume_lighting)
bpy.types.register(MATERIAL_PT_volume_transp)
bpy.types.register(MATERIAL_PT_volume_integration)
diff --git a/release/scripts/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py
index c95fa266aaa..9765aa93ca4 100644
--- a/release/scripts/ui/buttons_texture.py
+++ b/release/scripts/ui/buttons_texture.py
@@ -246,13 +246,14 @@ class TEXTURE_PT_influence(TextureSlotPanel):
col = split.column()
factor_but(col, tex.map_density, "map_density", "density_factor", "Density")
factor_but(col, tex.map_emission, "map_emission", "emission_factor", "Emission")
- factor_but(col, tex.map_absorption, "map_absorption", "absorption_factor", "Absorption")
factor_but(col, tex.map_scattering, "map_scattering", "scattering_factor", "Scattering")
+ factor_but(col, tex.map_reflection, "map_reflection", "reflection_factor", "Reflection")
col = split.column()
col.itemL(text=" ")
factor_but(col, tex.map_alpha, "map_coloremission", "coloremission_factor", "Emission Color")
- factor_but(col, tex.map_colorabsorption, "map_colorabsorption", "colorabsorption_factor", "Absorption Color")
+ factor_but(col, tex.map_colortransmission, "map_colortransmission", "colortransmission_factor", "Transmission Color")
+ factor_but(col, tex.map_colorreflection, "map_colorreflection", "colorreflection_factor", "Reflection Color")
elif la:
row = layout.row()
@@ -642,6 +643,7 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel):
row.itemR(vd, "still_frame_number")
layout.itemR(vd, "interpolation")
+ layout.itemR(vd, "extension")
layout.itemR(vd, "intensity")
class TEXTURE_PT_pointdensity(TextureButtonsPanel):
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 1667bd97102..cbd306f6d87 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -172,15 +172,15 @@ void init_material(Material *ma)
ma->vol.density = 1.0f;
ma->vol.emission = 0.0f;
- ma->vol.absorption = 1.0f;
ma->vol.scattering = 1.0f;
+ ma->vol.reflection = 1.0f;
+ ma->vol.transmission_col[0] = ma->vol.transmission_col[1] = ma->vol.transmission_col[2] = 1.0f;
+ ma->vol.reflection_col[0] = ma->vol.reflection_col[1] = ma->vol.reflection_col[2] = 1.0f;
ma->vol.emission_col[0] = ma->vol.emission_col[1] = ma->vol.emission_col[2] = 1.0f;
- ma->vol.absorption_col[0] = ma->vol.absorption_col[1] = ma->vol.absorption_col[2] = 0.0f;
ma->vol.density_scale = 1.0f;
ma->vol.depth_cutoff = 0.01f;
ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED;
ma->vol.stepsize = 0.2f;
- ma->vol.shade_stepsize = 0.2f;
ma->vol.shade_type = MA_VOL_SHADE_SINGLE;
ma->vol.shadeflag |= MA_VOL_PRECACHESHADING;
ma->vol.precache_resolution = 50;
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index d7616ec8a9a..287396a85c8 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -984,6 +984,7 @@ struct VoxelData *BKE_add_voxeldata(void)
vd->interp_type= TEX_VD_LINEAR;
vd->file_format= TEX_VD_SMOKE;
vd->int_multiplier = 1.0;
+ vd->extend = TEX_CLIP;
vd->object = NULL;
return vd;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 114ec9095b1..94478b0d235 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -9573,15 +9573,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (ma->vol.stepsize < 0.0001f) {
ma->vol.density = 1.0f;
ma->vol.emission = 0.0f;
- ma->vol.absorption = 1.0f;
ma->vol.scattering = 1.0f;
ma->vol.emission_col[0] = ma->vol.emission_col[1] = ma->vol.emission_col[2] = 1.0f;
- ma->vol.absorption_col[0] = ma->vol.absorption_col[1] = ma->vol.absorption_col[2] = 0.0f;
ma->vol.density_scale = 1.0f;
ma->vol.depth_cutoff = 0.01f;
ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED;
ma->vol.stepsize = 0.2f;
- ma->vol.shade_stepsize = 0.2f;
ma->vol.shade_type = MA_VOL_SHADE_SINGLE;
ma->vol.shadeflag |= MA_VOL_PRECACHESHADING;
ma->vol.precache_resolution = 50;
@@ -9703,6 +9700,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
{
Scene *sce;
Object *ob;
+ Material *ma;
+ Tex *tex;
for(sce = main->scene.first; sce; sce = sce->id.next)
if(sce->unit.scale_length == 0.0f)
@@ -9716,7 +9715,21 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
/* rotation modes were added, but old objects would now default to being 'quaternion based' */
ob->rotmode= ROT_MODE_EUL;
}
+
+ for (ma = main->mat.first; ma; ma=ma->id.next) {
+ if (ma->vol.reflection == 0.f) {
+ ma->vol.reflection = 1.f;
+ ma->vol.transmission_col[0] = ma->vol.transmission_col[1] = ma->vol.transmission_col[2] = 1.0f;
+ ma->vol.reflection_col[0] = ma->vol.reflection_col[1] = ma->vol.reflection_col[2] = 1.0f;
+ }
+ }
+ for (tex = main->tex.first; tex; tex=tex->id.next) {
+ if (tex->vd) {
+ if (tex->vd->extend == 0) tex->vd->extend = TEX_CLIP;
+ }
+ }
+
for(sce= main->scene.first; sce; sce= sce->id.next)
{
if(sce->audio.main == 0.0)
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 81f6badc24b..7dc04a47c51 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -334,6 +334,19 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
}
}
}
+
+ /* turn off bounce lights for volume,
+ * doesn't make much visual difference and slows it down too */
+ if(mat->material_type == MA_TYPE_VOLUME) {
+ for(base= sce->base.first; base; base= base->next) {
+ if(base->object->type == OB_LAMP) {
+ /* if doesn't match 'Lamp.002' --> main key light */
+ if( strcmp(base->object->id.name+2, "Lamp.002") != 0 ) {
+ base->object->restrictflag |= OB_RESTRICT_RENDER;
+ }
+ }
+ }
+ }
if(sp->pr_method==PR_ICON_RENDER) {
@@ -363,6 +376,8 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
if(matar && actcol < base->object->totcol)
(*matar)[actcol]= mat;
+ } else if (base->object->type == OB_LAMP) {
+ base->object->restrictflag &= ~OB_RESTRICT_RENDER;
}
}
}
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 55e3c9107e4..b3a7e74e91d 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -50,26 +50,23 @@ struct Ipo;
typedef struct VolumeSettings {
float density;
float emission;
- float absorption;
float scattering;
+ float reflection;
float emission_col[3];
- float absorption_col[3];
+ float transmission_col[3];
+ float reflection_col[3];
+
float density_scale;
float depth_cutoff;
-
- short phasefunc_type;
- short vpad[3];
- float phasefunc_g;
-
- float stepsize;
- float shade_stepsize;
+ float asymmetry;
short stepsize_type;
short shadeflag;
short shade_type;
short precache_resolution;
-
+
+ float stepsize;
float ms_diff;
float ms_intensity;
int ms_steps;
@@ -160,9 +157,8 @@ typedef struct Material {
float sss_front, sss_back;
short sss_flag, sss_preset;
- /* yafray: absorption color, dispersion parameters and material preset menu */
- float YF_ar, YF_ag, YF_ab, YF_dscale, YF_dpwr;
- int YF_dsmp, YF_preset, YF_djit;
+ int mapto_textured; /* render-time cache to optimise texture lookups */
+ int pad4;
ListBase gpumaterial; /* runtime */
} Material;
@@ -320,12 +316,14 @@ typedef struct Material {
#define MAP_LAYER 16384
/* volume mapto - reuse definitions for now - a bit naughty! */
-#define MAP_DENSITY 128
-#define MAP_EMISSION 64
-#define MAP_EMISSION_COL 1
-#define MAP_ABSORPTION 512
-#define MAP_ABSORPTION_COL 8
-#define MAP_SCATTERING 16
+#define MAP_DENSITY 128
+#define MAP_EMISSION 64
+#define MAP_EMISSION_COL 1
+#define MAP_SCATTERING 16
+#define MAP_TRANSMISSION_COL 8
+#define MAP_REFLECTION_COL 4
+#define MAP_REFLECTION 32
+
/* mapto for halo */
//#define MAP_HA_COL 1
@@ -386,13 +384,5 @@ typedef struct Material {
#define MA_VOL_SHADE_MULTIPLE 2
#define MA_VOL_SHADE_SINGLEPLUSMULTIPLE 3
-/* vol_phasefunc_type */
-#define MA_VOL_PH_ISOTROPIC 0
-#define MA_VOL_PH_MIEHAZY 1
-#define MA_VOL_PH_MIEMURKY 2
-#define MA_VOL_PH_RAYLEIGH 3
-#define MA_VOL_PH_HG 4
-#define MA_VOL_PH_SCHLICK 5
-
#endif
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index c13c0522004..c8f35b4306f 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -167,7 +167,8 @@ typedef struct VoxelData {
int interp_type;
short file_format;
short flag;
- int pad;
+ short extend;
+ short pad;
struct Object *object; /* for rendering smoke sims */
float int_multiplier;
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 9f7b97dfa05..593fc2e5935 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -537,14 +537,19 @@ static void rna_def_material_mtex(BlenderRNA *brna)
/* volume material */
prop= RNA_def_property(srna, "map_coloremission", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_EMISSION_COL);
- RNA_def_property_ui_text(prop, "Emission Color", "Causes the texture to affect the colour of emission");
+ RNA_def_property_ui_text(prop, "Emission Color", "Causes the texture to affect the color of emission");
RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "map_colorabsorption", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_ABSORPTION_COL);
- RNA_def_property_ui_text(prop, "Absorption Color", "Causes the texture to affect the result colour after absorption");
+ prop= RNA_def_property(srna, "map_colorreflection", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_REFLECTION_COL);
+ RNA_def_property_ui_text(prop, "Reflection Color", "Causes the texture to affect the color of scattered light");
RNA_def_property_update(prop, 0, "rna_Material_update");
+ prop= RNA_def_property(srna, "map_colortransmission", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_TRANSMISSION_COL);
+ RNA_def_property_ui_text(prop, "Transmission Color", "Causes the texture to affect the result color after other light has been scattered/absorbed");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
+
prop= RNA_def_property(srna, "map_density", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_DENSITY);
RNA_def_property_ui_text(prop, "Density", "Causes the texture to affect the volume's density");
@@ -555,28 +560,34 @@ static void rna_def_material_mtex(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Emission", "Causes the texture to affect the volume's emission");
RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "map_absorption", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_ABSORPTION);
- RNA_def_property_ui_text(prop, "Absorption", "Causes the texture to affect the volume's absorption");
- RNA_def_property_update(prop, 0, "rna_Material_update");
-
prop= RNA_def_property(srna, "map_scattering", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_SCATTERING);
RNA_def_property_ui_text(prop, "Scattering", "Causes the texture to affect the volume's scattering");
RNA_def_property_update(prop, 0, "rna_Material_update");
+ prop= RNA_def_property(srna, "map_reflection", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_REFLECTION);
+ RNA_def_property_ui_text(prop, "Reflection", "Causes the texture to affect the reflected light's brightness");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
+
prop= RNA_def_property(srna, "coloremission_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "colfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Emission Color Factor", "Amount texture affects emission color.");
RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "colorabsorption_factor", PROP_FLOAT, PROP_NONE);
+ prop= RNA_def_property(srna, "colorreflection_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "colfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
- RNA_def_property_ui_text(prop, "Absorpion Color Factor", "Amount texture affects diffuse color.");
+ RNA_def_property_ui_text(prop, "Reflection Color Factor", "Amount texture affects color of out-scattered light");
RNA_def_property_update(prop, 0, "rna_Material_update");
+ prop= RNA_def_property(srna, "colortransmission_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "colfac");
+ RNA_def_property_ui_range(prop, 0, 1, 10, 3);
+ RNA_def_property_ui_text(prop, "Transmission Color Factor", "Amount texture affects result color after light has been scattered/absorbed.");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
+
prop= RNA_def_property(srna, "density_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "varfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
@@ -589,16 +600,16 @@ static void rna_def_material_mtex(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Emission Factor", "Amount texture affects emission.");
RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "absorption_factor", PROP_FLOAT, PROP_NONE);
+ prop= RNA_def_property(srna, "scattering_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "varfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
- RNA_def_property_ui_text(prop, "Absorption Factor", "Amount texture affects absorption.");
+ RNA_def_property_ui_text(prop, "Scattering Factor", "Amount texture affects scattering.");
RNA_def_property_update(prop, 0, "rna_Material_update");
-
- prop= RNA_def_property(srna, "scattering_factor", PROP_FLOAT, PROP_NONE);
+
+ prop= RNA_def_property(srna, "reflection_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "varfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
- RNA_def_property_ui_text(prop, "Scattering Factor", "Amount texture affects scattering.");
+ RNA_def_property_ui_text(prop, "Reflection Factor", "Amount texture affects brightness of out-scattered light.");
RNA_def_property_update(prop, 0, "rna_Material_update");
/* end volume material */
@@ -955,15 +966,6 @@ static void rna_def_material_volume(BlenderRNA *brna)
//{MA_VOL_STEP_ADAPTIVE, "ADAPTIVE", 0, "Adaptive", ""},
{0, NULL, 0, NULL, NULL}};
- static EnumPropertyItem prop_phasefunction_items[] = {
- {MA_VOL_PH_ISOTROPIC, "ISOTROPIC", 0, "Isotropic", ""},
- {MA_VOL_PH_MIEHAZY, "MIE_HAZY", 0, "Mie Hazy", ""},
- {MA_VOL_PH_MIEMURKY, "MIE_MURKY", 0, "Mie Murky", ""},
- {MA_VOL_PH_RAYLEIGH, "RAYLEIGH", 0, "Rayleigh", ""},
- {MA_VOL_PH_HG, "HENYEY-GREENSTEIN", 0, "Henyey-Greenstein", ""},
- {MA_VOL_PH_SCHLICK, "SCHLICK", 0, "Schlick", ""},
- {0, NULL, 0, NULL, NULL}};
-
srna= RNA_def_struct(brna, "MaterialVolume", NULL);
RNA_def_struct_sdna(srna, "VolumeSettings");
RNA_def_struct_nested(brna, srna, "Material");
@@ -982,13 +984,6 @@ static void rna_def_material_volume(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Step Size", "Distance between subsequent volume depth samples.");
RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "shading_step_size", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "shade_stepsize");
- RNA_def_property_range(prop, 0.0f, FLT_MAX);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Shading Step Size", "Distance between subsequent volume shading samples.");
- RNA_def_property_update(prop, 0, "rna_Material_update");
-
prop= RNA_def_property(srna, "scattering_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shade_type");
RNA_def_property_enum_items(prop, prop_scattering_items);
@@ -1043,31 +1038,30 @@ static void rna_def_material_volume(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Density Scale", "Multiplier for the material's density");
RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "absorption", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "absorption");
+ prop= RNA_def_property(srna, "scattering", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "scattering");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
- RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Absorption", "Amount of light that gets absorbed by the volume - higher values mean light travels less distance");
+ RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1 ,3);
+ RNA_def_property_ui_text(prop, "Scattering", "Amount of light that gets scattered out by the volume - the more out-scattering, the shallower the light will penetrate ");
RNA_def_property_update(prop, 0, "rna_Material_update");
- prop= RNA_def_property(srna, "absorption_color", PROP_FLOAT, PROP_COLOR);
- RNA_def_property_float_sdna(prop, NULL, "absorption_col");
+ prop= RNA_def_property(srna, "transmission_color", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_float_sdna(prop, NULL, "transmission_col");
RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Absorption Color", "");
+ RNA_def_property_ui_text(prop, "Transmission Color", "Result color of the volume, after other light has been scattered/absorbed");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
- prop= RNA_def_property(srna, "scattering", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "scattering");
- RNA_def_property_range(prop, 0.0f, FLT_MAX);
- RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1 ,3);
- RNA_def_property_ui_text(prop, "Scattering", "Amount of light that gets scattered by the volume - values > 1.0 are non-physical");
- RNA_def_property_update(prop, 0, "rna_Material_update");
+ prop= RNA_def_property(srna, "reflection_color", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_float_sdna(prop, NULL, "reflection_col");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Reflection Color", "Colour of light scattered out of the volume (does not affect transmission)");
+ RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
- prop= RNA_def_property(srna, "emission", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "emission");
+ prop= RNA_def_property(srna, "reflection", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "reflection");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
- RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Emission", "Amount of light that gets emitted by the volume");
+ RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1 ,3);
+ RNA_def_property_ui_text(prop, "Reflection", "Multiplier to make out-scattered light brighter or darker (non-physically correct)");
RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "emission_color", PROP_FLOAT, PROP_COLOR);
@@ -1076,16 +1070,17 @@ static void rna_def_material_volume(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Emission Color", "");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
- prop= RNA_def_property(srna, "phase_function", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "phasefunc_type");
- RNA_def_property_enum_items(prop, prop_phasefunction_items);
- RNA_def_property_ui_text(prop, "Phase Function", "Isotropic/Anisotropic scattering");
+ prop= RNA_def_property(srna, "emission", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "emission");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
+ RNA_def_property_ui_text(prop, "Emission", "Amount of light that gets emitted by the volume");
RNA_def_property_update(prop, 0, "rna_Material_update");
-
+
prop= RNA_def_property(srna, "asymmetry", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "phasefunc_g");
+ RNA_def_property_float_sdna(prop, NULL, "asymmetry");
RNA_def_property_range(prop, -1.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Asymmetry", "Continuum between forward scattering and back scattering");
+ RNA_def_property_ui_text(prop, "Asymmetry", "Back scattering (-1.0) to Forward scattering (1.0) and the range in between.");
RNA_def_property_update(prop, 0, "rna_Material_update");
}
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index d63f5823b2e..7bc8570ce13 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -955,11 +955,11 @@ static void rna_def_texture_image(BlenderRNA *brna)
PropertyRNA *prop;
static EnumPropertyItem prop_image_extension[] = {
- {1, "EXTEND", 0, "Extend", "Extends by repeating edge pixels of the image"},
- {2, "CLIP", 0, "Clip", "Clips to image size and sets exterior pixels as transparent"},
- {4, "CLIP_CUBE", 0, "Clip Cube", "Clips to cubic-shaped area around the image and sets exterior pixels as transparent"},
- {3, "REPEAT", 0, "Repeat", "Causes the image to repeat horizontally and vertically"},
- {5, "CHECKER", 0, "Checker", "Causes the image to repeat in checker board pattern"},
+ {TEX_EXTEND, "EXTEND", 0, "Extend", "Extends by repeating edge pixels of the image"},
+ {TEX_CLIP, "CLIP", 0, "Clip", "Clips to image size and sets exterior pixels as transparent"},
+ {TEX_CLIPCUBE, "CLIP_CUBE", 0, "Clip Cube", "Clips to cubic-shaped area around the image and sets exterior pixels as transparent"},
+ {TEX_REPEAT, "REPEAT", 0, "Repeat", "Causes the image to repeat horizontally and vertically"},
+ {TEX_CHECKER, "CHECKER", 0, "Checker", "Causes the image to repeat in checker board pattern"},
{0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "ImageTexture", "Texture");
@@ -1016,7 +1016,7 @@ static void rna_def_texture_image(BlenderRNA *brna)
prop= RNA_def_property(srna, "extension", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "extend");
RNA_def_property_enum_items(prop, prop_image_extension);
- RNA_def_property_ui_text(prop, "Extension", "Sets how the image is stretched in the texture");
+ RNA_def_property_ui_text(prop, "Extension", "Sets how the image is extrapolated past its original bounds");
RNA_def_property_update(prop, 0, "rna_Texture_update");
prop= RNA_def_property(srna, "repeat_x", PROP_INT, PROP_NONE);
@@ -1562,6 +1562,12 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna)
{TEX_VD_IMAGE_SEQUENCE, "IMAGE_SEQUENCE", 0, "Image Sequence", "Generate voxels from a sequence of image slices"},
{TEX_VD_SMOKE, "SMOKE", 0, "Smoke", "Render voxels from a Blender smoke simulation"},
{0, NULL, 0, NULL, NULL}};
+
+ static EnumPropertyItem voxeldata_extension[] = {
+ {TEX_EXTEND, "EXTEND", 0, "Extend", "Extends by repeating edge pixels of the image"},
+ {TEX_CLIP, "CLIP", 0, "Clip", "Clips to image size and sets exterior pixels as transparent"},
+ {TEX_REPEAT, "REPEAT", 0, "Repeat", "Causes the image to repeat horizontally and vertically"},
+ {0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "VoxelData", NULL);
RNA_def_struct_sdna(srna, "VoxelData");
@@ -1573,6 +1579,12 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Interpolation", "Method to interpolate/smooth values between voxel cells");
RNA_def_property_update(prop, 0, "rna_Texture_update");
+ prop= RNA_def_property(srna, "extension", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "extend");
+ RNA_def_property_enum_items(prop, voxeldata_extension);
+ RNA_def_property_ui_text(prop, "Extension", "Sets how the texture is extrapolated past its original bounds");
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+
prop= RNA_def_property(srna, "intensity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "int_multiplier");
RNA_def_property_range(prop, 0.01, FLT_MAX);
diff --git a/source/blender/render/intern/include/volume_precache.h b/source/blender/render/intern/include/volume_precache.h
index 9d87a219c82..368d60ee7f0 100644
--- a/source/blender/render/intern/include/volume_precache.h
+++ b/source/blender/render/intern/include/volume_precache.h
@@ -30,4 +30,4 @@ void volume_precache(Render *re);
void free_volume_precache(Render *re);
int point_inside_volume_objectinstance(ObjectInstanceRen *obi, float *co);
-#define VOL_MS_TIMESTEP 0.1f \ No newline at end of file
+#define VOL_MS_TIMESTEP 0.1f
diff --git a/source/blender/render/intern/include/volumetric.h b/source/blender/render/intern/include/volumetric.h
index 026b4840ea3..97e7e022fa0 100644
--- a/source/blender/render/intern/include/volumetric.h
+++ b/source/blender/render/intern/include/volumetric.h
@@ -26,9 +26,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
-float vol_get_stepsize(struct ShadeInput *shi, int context);
float vol_get_density(struct ShadeInput *shi, float *co);
-void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co, float stepsize, float density);
+void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co_);
void shade_volume_outside(ShadeInput *shi, ShadeResult *shr);
void shade_volume_inside(ShadeInput *shi, ShadeResult *shr);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 48a7c003c9f..b3784f26048 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -889,6 +889,28 @@ static void free_mesh_orco_hash(Render *re)
}
}
+static void check_material_mapto(Material *ma)
+{
+ int a;
+ ma->mapto_textured = 0;
+
+ /* cache which inputs are actually textured.
+ * this can avoid a bit of time spent iterating through all the texture slots, map inputs and map tos
+ * every time a property which may or may not be textured is accessed */
+
+ for(a=0; a<MAX_MTEX; a++) {
+ if(ma->mtex[a] && ma->mtex[a]->tex) {
+ /* currently used only in volume render, so we'll check for those flags */
+ if(ma->mtex[a]->mapto & MAP_DENSITY) ma->mapto_textured |= MAP_DENSITY;
+ if(ma->mtex[a]->mapto & MAP_EMISSION) ma->mapto_textured |= MAP_EMISSION;
+ if(ma->mtex[a]->mapto & MAP_EMISSION_COL) ma->mapto_textured |= MAP_EMISSION_COL;
+ if(ma->mtex[a]->mapto & MAP_SCATTERING) ma->mapto_textured |= MAP_SCATTERING;
+ if(ma->mtex[a]->mapto & MAP_TRANSMISSION_COL) ma->mapto_textured |= MAP_TRANSMISSION_COL;
+ if(ma->mtex[a]->mapto & MAP_REFLECTION) ma->mapto_textured |= MAP_REFLECTION;
+ if(ma->mtex[a]->mapto & MAP_REFLECTION_COL) ma->mapto_textured |= MAP_REFLECTION_COL;
+ }
+ }
+}
static void flag_render_node_material(Render *re, bNodeTree *ntree)
{
bNode *node;
@@ -930,6 +952,8 @@ static Material *give_render_material(Render *re, Object *ob, int nr)
if(ma->nodetree && ma->use_nodes)
flag_render_node_material(re, ma->nodetree);
+ check_material_mapto(ma);
+
return ma;
}
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index c1d0c943ca9..cce99d64b39 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -1343,7 +1343,8 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int
/* mix colors based on shadfac (rgb + amount of light factor) */
addAlphaLight(is->col, shr.diff, shr.alpha, d*shi.mat->filter);
} else if (shi.mat->material_type == MA_TYPE_VOLUME) {
- addAlphaLight(is->col, shr.combined, shr.alpha, 1.0f);
+ QUATCOPY(is->col, shr.combined);
+ is->col[3] = 1.f;
}
if(depth>0 && is->col[3]>0.0f) {
diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c
index 4830dab7d37..02b7f6aad86 100644
--- a/source/blender/render/intern/source/texture.c
+++ b/source/blender/render/intern/source/texture.c
@@ -2385,7 +2385,7 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa
}
- if((mapto_flag & (MAP_EMISSION_COL+MAP_ABSORPTION_COL)) && (mtex->mapto & (MAP_EMISSION_COL+MAP_ABSORPTION_COL))) {
+ if((mapto_flag & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL)) && (mtex->mapto & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL))) {
float tcol[3], colfac;
/* stencil maps on the texture control slider, not texture intensity value */
@@ -2413,8 +2413,11 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa
texture_rgb_blend(col, tcol, col, texres.tin, colfac, mtex->blendtype);
}
- /* MAP_COLMIR is abused for absorption colour at the moment */
- if((mapto_flag & MAP_ABSORPTION_COL) && (mtex->mapto & MAP_ABSORPTION_COL)) {
+ if((mapto_flag & MAP_REFLECTION_COL) && (mtex->mapto & MAP_REFLECTION_COL)) {
+ texture_rgb_blend(col, tcol, col, texres.tin, colfac, mtex->blendtype);
+ }
+
+ if((mapto_flag & MAP_TRANSMISSION_COL) && (mtex->mapto & MAP_TRANSMISSION_COL)) {
texture_rgb_blend(col, tcol, col, texres.tin, colfac, mtex->blendtype);
}
}
@@ -2443,14 +2446,14 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa
*val = texture_value_blend(mtex->def_var, *val, texres.tin, varfac, mtex->blendtype, flip);
CLAMP(*val, 0.0, 1.0);
}
- if((mapto_flag & MAP_ABSORPTION) && (mtex->mapto & MAP_ABSORPTION)) {
- int flip= mtex->maptoneg & MAP_ABSORPTION;
+ if((mapto_flag & MAP_SCATTERING) && (mtex->mapto & MAP_SCATTERING)) {
+ int flip= mtex->maptoneg & MAP_SCATTERING;
*val = texture_value_blend(mtex->def_var, *val, texres.tin, varfac, mtex->blendtype, flip);
CLAMP(*val, 0.0, 1.0);
}
- if((mapto_flag & MAP_SCATTERING) && (mtex->mapto & MAP_SCATTERING)) {
- int flip= mtex->maptoneg & MAP_SCATTERING;
+ if((mapto_flag & MAP_REFLECTION) && (mtex->mapto & MAP_REFLECTION)) {
+ int flip= mtex->maptoneg & MAP_REFLECTION;
*val = texture_value_blend(mtex->def_var, *val, texres.tin, varfac, mtex->blendtype, flip);
CLAMP(*val, 0.0, 1.0);
diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c
index 15d8643fea4..7ecaf83ae27 100644
--- a/source/blender/render/intern/source/volume_precache.c
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -185,9 +185,9 @@ static float get_avg_surrounds(float *cache, int *res, int xx, int yy, int zz)
}
}
- tot /= added;
+ if (added > 0) tot /= added;
- return ((added>0)?tot:0.0f);
+ return tot;
}
/* function to filter the edges of the light cache, where there was no volume originally.
@@ -202,17 +202,54 @@ static void lightcache_filter(VolumePrecache *vp)
for (y=0; y < vp->res[1]; y++) {
for (x=0; x < vp->res[0]; x++) {
/* trigger for outside mesh */
- if (vp->data_r[ V_I(x, y, z, vp->res) ] < -0.5f)
+ if (vp->data_r[ V_I(x, y, z, vp->res) ] < -0.f)
vp->data_r[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
- if (vp->data_g[ V_I(x, y, z, vp->res) ] < -0.5f)
+ if (vp->data_g[ V_I(x, y, z, vp->res) ] < -0.f)
vp->data_g[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
- if (vp->data_b[ V_I(x, y, z, vp->res) ] < -0.5f)
+ if (vp->data_b[ V_I(x, y, z, vp->res) ] < -0.f)
vp->data_b[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
}
}
}
}
+static void lightcache_filter2(VolumePrecache *vp)
+{
+ int x, y, z;
+ float *new_r, *new_g, *new_b;
+ int field_size = vp->res[0]*vp->res[1]*vp->res[2]*sizeof(float);
+
+ new_r = MEM_mallocN(field_size, "temp buffer for light cache filter r channel");
+ new_g = MEM_mallocN(field_size, "temp buffer for light cache filter g channel");
+ new_b = MEM_mallocN(field_size, "temp buffer for light cache filter b channel");
+
+ memcpy(new_r, vp->data_r, field_size);
+ memcpy(new_g, vp->data_g, field_size);
+ memcpy(new_b, vp->data_b, field_size);
+
+ for (z=0; z < vp->res[2]; z++) {
+ for (y=0; y < vp->res[1]; y++) {
+ for (x=0; x < vp->res[0]; x++) {
+ /* trigger for outside mesh */
+ if (vp->data_r[ V_I(x, y, z, vp->res) ] < -0.f)
+ new_r[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
+ if (vp->data_g[ V_I(x, y, z, vp->res) ] < -0.f)
+ new_g[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
+ if (vp->data_b[ V_I(x, y, z, vp->res) ] < -0.f)
+ new_b[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
+ }
+ }
+ }
+
+ SWAP(float *, vp->data_r, new_r);
+ SWAP(float *, vp->data_g, new_g);
+ SWAP(float *, vp->data_b, new_b);
+
+ if (new_r) { MEM_freeN(new_r); new_r=NULL; }
+ if (new_g) { MEM_freeN(new_g); new_g=NULL; }
+ if (new_b) { MEM_freeN(new_b); new_b=NULL; }
+}
+
static inline int ms_I(int x, int y, int z, int *n) //has a pad of 1 voxel surrounding the core for boundary simulation
{
return z*(n[1]+2)*(n[0]+2) + y*(n[0]+2) + x;
@@ -423,11 +460,10 @@ static void *vol_precache_part(void *data)
ObjectInstanceRen *obi = pa->obi;
RayTree *tree = pa->tree;
ShadeInput *shi = pa->shi;
- float density, scatter_col[3] = {0.f, 0.f, 0.f};
+ float scatter_col[3] = {0.f, 0.f, 0.f};
float co[3];
int x, y, z;
const int res[3]= {pa->res[0], pa->res[1], pa->res[2]};
- const float stepsize = vol_get_stepsize(shi, STEPSIZE_VIEW);
for (z= pa->minz; z < pa->maxz; z++) {
co[2] = pa->bbmin[2] + (pa->voxel[2] * (z + 0.5f));
@@ -448,8 +484,7 @@ static void *vol_precache_part(void *data)
VecCopyf(shi->view, co);
Normalize(shi->view);
- density = vol_get_density(shi, co);
- vol_get_scattering(shi, scatter_col, co, stepsize, density);
+ vol_get_scattering(shi, scatter_col, co);
obi->volume_precache->data_r[ V_I(x, y, z, res) ] = scatter_col[0];
obi->volume_precache->data_g[ V_I(x, y, z, res) ] = scatter_col[1];
diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c
index b2692c25b99..381a32de027 100644
--- a/source/blender/render/intern/source/volumetric.c
+++ b/source/blender/render/intern/source/volumetric.c
@@ -170,29 +170,6 @@ static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, float *co, float *co
}
}
-/* input shader data */
-
-float vol_get_stepsize(struct ShadeInput *shi, int context)
-{
- if (shi->mat->vol.stepsize_type == MA_VOL_STEP_RANDOMIZED) {
- /* range between 0.75 and 1.25 */
- const float rnd = 0.5f * BLI_thread_frand(shi->thread) + 0.75f;
-
- if (context == STEPSIZE_VIEW)
- return shi->mat->vol.stepsize * rnd;
- else if (context == STEPSIZE_SHADE)
- return shi->mat->vol.shade_stepsize * rnd;
- }
- else { // MA_VOL_STEP_CONSTANT
-
- if (context == STEPSIZE_VIEW)
- return shi->mat->vol.stepsize;
- else if (context == STEPSIZE_SHADE)
- return shi->mat->vol.shade_stepsize;
- }
-
- return shi->mat->vol.stepsize;
-}
/* trilinear interpolation */
static void vol_get_precached_scattering(ShadeInput *shi, float *scatter_col, float *co)
@@ -212,9 +189,9 @@ static void vol_get_precached_scattering(ShadeInput *shi, float *scatter_col, fl
sample_co[1] = ((co[1] - bbmin[1]) / dim[1]);
sample_co[2] = ((co[2] - bbmin[2]) / dim[2]);
- scatter_col[0] = voxel_sample_trilinear(vp->data_r, vp->res, sample_co);
- scatter_col[1] = voxel_sample_trilinear(vp->data_g, vp->res, sample_co);
- scatter_col[2] = voxel_sample_trilinear(vp->data_b, vp->res, sample_co);
+ scatter_col[0] = voxel_sample_triquadratic(vp->data_r, vp->res, sample_co);
+ scatter_col[1] = voxel_sample_triquadratic(vp->data_g, vp->res, sample_co);
+ scatter_col[2] = voxel_sample_triquadratic(vp->data_b, vp->res, sample_co);
}
/* Meta object density, brute force for now
@@ -270,7 +247,8 @@ float vol_get_density(struct ShadeInput *shi, float *co)
float density = shi->mat->vol.density;
float density_scale = shi->mat->vol.density_scale;
- do_volume_tex(shi, co, MAP_DENSITY, NULL, &density);
+ if (shi->mat->mapto_textured & MAP_DENSITY)
+ do_volume_tex(shi, co, MAP_DENSITY, NULL, &density);
// if meta-object, modulate by metadensity without increasing it
if (shi->obi->obr->ob->type == OB_MBALL) {
@@ -281,79 +259,110 @@ float vol_get_density(struct ShadeInput *shi, float *co)
return density * density_scale;
}
-/* scattering multiplier, values above 1.0 are non-physical,
- * but can be useful to tweak lighting */
-float vol_get_scattering_fac(ShadeInput *shi, float *co)
+
+/* Color of light that gets scattered out by the volume */
+/* Uses same physically based scattering parameter as in transmission calculations,
+ * along with artificial reflection scale/reflection color tint */
+void vol_get_reflection_color(ShadeInput *shi, float *ref_col, float *co)
{
float scatter = shi->mat->vol.scattering;
- float col[3] = {0.0, 0.0, 0.0};
+ float reflection= shi->mat->vol.reflection;
+ VECCOPY(ref_col, shi->mat->vol.reflection_col);
+
+ if (shi->mat->mapto_textured & (MAP_SCATTERING+MAP_REFLECTION_COL))
+ do_volume_tex(shi, co, MAP_SCATTERING+MAP_REFLECTION_COL, ref_col, &scatter);
- do_volume_tex(shi, co, MAP_SCATTERING, col, &scatter);
+ /* only one single float parameter at a time... :s */
+ if (shi->mat->mapto_textured & (MAP_REFLECTION))
+ do_volume_tex(shi, co, MAP_REFLECTION, NULL, &reflection);
- return scatter;
+ ref_col[0] = reflection * ref_col[0] * scatter;
+ ref_col[1] = reflection * ref_col[1] * scatter;
+ ref_col[2] = reflection * ref_col[2] * scatter;
}
/* compute emission component, amount of radiance to add per segment
* can be textured with 'emit' */
-void vol_get_emission(ShadeInput *shi, float *emission_col, float *co, float density)
+void vol_get_emission(ShadeInput *shi, float *emission_col, float *co)
{
float emission = shi->mat->vol.emission;
VECCOPY(emission_col, shi->mat->vol.emission_col);
- do_volume_tex(shi, co, MAP_EMISSION+MAP_EMISSION_COL, emission_col, &emission);
+ if (shi->mat->mapto_textured & (MAP_EMISSION+MAP_EMISSION_COL))
+ do_volume_tex(shi, co, MAP_EMISSION+MAP_EMISSION_COL, emission_col, &emission);
- emission_col[0] = emission_col[0] * emission * density;
- emission_col[1] = emission_col[1] * emission * density;
- emission_col[2] = emission_col[2] * emission * density;
+ emission_col[0] = emission_col[0] * emission;
+ emission_col[1] = emission_col[1] * emission;
+ emission_col[2] = emission_col[2] * emission;
}
-void vol_get_absorption(ShadeInput *shi, float *absorb_col, float *co)
+
+/* A combination of scattering and absorption -> known as sigma T.
+ * This can possibly use a specific scattering colour,
+ * and absorption multiplier factor too, but these parameters are left out for simplicity.
+ * It's easy enough to get a good wide range of results with just these two parameters. */
+void vol_get_sigma_t(ShadeInput *shi, float *sigma_t, float *co)
{
- float absorption = shi->mat->vol.absorption;
- VECCOPY(absorb_col, shi->mat->vol.absorption_col);
+ /* technically absorption, but named transmission color
+ * since it describes the effect of the coloring *after* absorption */
+ float transmission_col[3] = {shi->mat->vol.transmission_col[0], shi->mat->vol.transmission_col[1], shi->mat->vol.transmission_col[2]};
+ float scattering = shi->mat->vol.scattering;
- do_volume_tex(shi, co, MAP_ABSORPTION+MAP_ABSORPTION_COL, absorb_col, &absorption);
+ if (shi->mat->mapto_textured & (MAP_SCATTERING+MAP_TRANSMISSION_COL))
+ do_volume_tex(shi, co, MAP_SCATTERING+MAP_TRANSMISSION_COL, transmission_col, &scattering);
- absorb_col[0] = (1.0f - absorb_col[0]) * absorption;
- absorb_col[1] = (1.0f - absorb_col[1]) * absorption;
- absorb_col[2] = (1.0f - absorb_col[2]) * absorption;
+ sigma_t[0] = (1.0f - transmission_col[0]) + scattering;
+ sigma_t[1] = (1.0f - transmission_col[1]) + scattering;
+ sigma_t[2] = (1.0f - transmission_col[2]) + scattering;
}
/* phase function - determines in which directions the light
* is scattered in the volume relative to incoming direction
* and view direction */
-float vol_get_phasefunc(ShadeInput *shi, short phasefunc_type, float g, float *w, float *wp)
+float vol_get_phasefunc(ShadeInput *shi, float g, float *w, float *wp)
{
- const float costheta = Inpf(w, wp);
- const float scale = M_PI;
-
- /*
- * Scale constant is required, since Blender's shading system doesn't normalise for
- * energy conservation - eg. scaling by 1/pi for a lambert shader.
- * This makes volumes darker than other solid objects, for the same lighting intensity.
- * To correct this, scale up the phase function values
+ const float normalize = 0.25f; // = 1.f/4.f = M_PI/(4.f*M_PI)
+
+ /* normalization constant is 1/4 rather than 1/4pi, since
+ * Blender's shading system doesn't normalise for
+ * energy conservation - eg. multiplying by pdf ( 1/pi for a lambert brdf ).
+ * This means that lambert surfaces in Blender are pi times brighter than they 'should be'
+ * and therefore, with correct energy conservation, volumes will darker than other solid objects,
+ * for the same lighting intensity.
+ * To correct this, scale up the phase function values by pi
* until Blender's shading system supports this better. --matt
*/
+ if (g == 0.f) { /* isotropic */
+ return normalize * 1.f;
+ } else { /* schlick */
+ const float k = 1.55f * g - .55f * g * g * g;
+ const float kcostheta = k * Inpf(w, wp);
+ return normalize * (1.f - k*k) / ((1.f - kcostheta) * (1.f - kcostheta));
+ }
+
+ /*
+ * not used, but here for reference:
switch (phasefunc_type) {
case MA_VOL_PH_MIEHAZY:
- return scale * (0.5f + 4.5f * powf(0.5 * (1.f + costheta), 8.f)) / (4.f*M_PI);
+ return normalize * (0.5f + 4.5f * powf(0.5 * (1.f + costheta), 8.f));
case MA_VOL_PH_MIEMURKY:
- return scale * (0.5f + 16.5f * powf(0.5 * (1.f + costheta), 32.f)) / (4.f*M_PI);
+ return normalize * (0.5f + 16.5f * powf(0.5 * (1.f + costheta), 32.f));
case MA_VOL_PH_RAYLEIGH:
- return scale * 3.f/(16.f*M_PI) * (1 + costheta * costheta);
+ return normalize * 3.f/4.f * (1 + costheta * costheta);
case MA_VOL_PH_HG:
- return scale * (1.f / (4.f * M_PI) * (1.f - g*g) / powf(1.f + g*g - 2.f * g * costheta, 1.5f));
+ return normalize * (1.f - g*g) / powf(1.f + g*g - 2.f * g * costheta, 1.5f));
case MA_VOL_PH_SCHLICK:
{
const float k = 1.55f * g - .55f * g * g * g;
const float kcostheta = k * costheta;
- return scale * (1.f / (4.f * M_PI) * (1.f - k*k) / ((1.f - kcostheta) * (1.f - kcostheta)));
+ return normalize * (1.f - k*k) / ((1.f - kcostheta) * (1.f - kcostheta));
}
case MA_VOL_PH_ISOTROPIC:
default:
- return scale * (1.f / (4.f * M_PI));
+ return normalize * 1.f;
}
+ */
}
/* Compute transmittance = e^(-attenuation) */
@@ -361,15 +370,15 @@ void vol_get_transmittance_seg(ShadeInput *shi, float *tr, float stepsize, float
{
/* input density = density at co */
float tau[3] = {0.f, 0.f, 0.f};
- float absorb[3];
- const float scatter_dens = vol_get_scattering_fac(shi, co) * density * stepsize;
-
- vol_get_absorption(shi, absorb, co);
+ const float stepd = density * stepsize;
+ float sigma_t[3];
+
+ vol_get_sigma_t(shi, sigma_t, co);
/* homogenous volume within the sampled distance */
- tau[0] += scatter_dens * absorb[0];
- tau[1] += scatter_dens * absorb[1];
- tau[2] += scatter_dens * absorb[2];
+ tau[0] += stepd * sigma_t[0];
+ tau[1] += stepd * sigma_t[1];
+ tau[2] += stepd * sigma_t[2];
tr[0] *= exp(-tau[0]);
tr[1] *= exp(-tau[1]);
@@ -381,31 +390,29 @@ static void vol_get_transmittance(ShadeInput *shi, float *tr, float *co, float *
{
float p[3] = {co[0], co[1], co[2]};
float step_vec[3] = {endco[0] - co[0], endco[1] - co[1], endco[2] - co[2]};
- //const float ambtau = -logf(shi->mat->vol.depth_cutoff); // never zero
float tau[3] = {0.f, 0.f, 0.f};
float t0 = 0.f;
float t1 = Normalize(step_vec);
float pt0 = t0;
- t0 += shi->mat->vol.shade_stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread));
+ t0 += shi->mat->vol.stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread));
p[0] += t0 * step_vec[0];
p[1] += t0 * step_vec[1];
p[2] += t0 * step_vec[2];
- VecMulf(step_vec, shi->mat->vol.shade_stepsize);
+ VecMulf(step_vec, shi->mat->vol.stepsize);
- for (; t0 < t1; pt0 = t0, t0 += shi->mat->vol.shade_stepsize) {
- float absorb[3];
+ for (; t0 < t1; pt0 = t0, t0 += shi->mat->vol.stepsize) {
const float d = vol_get_density(shi, p);
const float stepd = (t0 - pt0) * d;
- const float scatter_dens = vol_get_scattering_fac(shi, p) * stepd;
- vol_get_absorption(shi, absorb, p);
+ float sigma_t[3];
+
+ vol_get_sigma_t(shi, sigma_t, co);
- tau[0] += scatter_dens * absorb[0];
- tau[1] += scatter_dens * absorb[1];
- tau[2] += scatter_dens * absorb[2];
+ tau[0] += stepd * sigma_t[0];
+ tau[1] += stepd * sigma_t[1];
+ tau[2] += stepd * sigma_t[2];
- //if (luminance(tau) >= ambtau) break;
VecAddf(p, p, step_vec);
}
@@ -420,8 +427,7 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *
float visifac, lv[3], lampdist;
float tr[3]={1.0,1.0,1.0};
float hitco[3], *atten_co;
- float p;
- float scatter_fac;
+ float p, ref_col[3];
if (lar->mode & LA_LAYER) if((lar->lay & shi->obi->lay)==0) return;
if ((lar->lay & shi->lay)==0) return;
@@ -475,15 +481,20 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *
}
}
- p = vol_get_phasefunc(shi, shi->mat->vol.phasefunc_type, shi->mat->vol.phasefunc_g, shi->view, lv);
- VecMulf(lacol, p);
+ if (luminance(lacol) < 0.001f) return;
+
+ p = vol_get_phasefunc(shi, shi->mat->vol.asymmetry, shi->view, lv);
+
+ /* physically based scattering with non-physically based RGB gain */
+ vol_get_reflection_color(shi, ref_col, co);
- scatter_fac = vol_get_scattering_fac(shi, co);
- VecMulf(lacol, scatter_fac);
+ lacol[0] *= p * ref_col[0];
+ lacol[1] *= p * ref_col[1];
+ lacol[2] *= p * ref_col[2];
}
/* single scattering only for now */
-void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co, float stepsize, float density)
+void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co)
{
ListBase *lights;
GroupObject *go;
@@ -515,71 +526,69 @@ outgoing radiance from behind surface * beam transmittance/attenuation
--> radiance for each segment =
(radiance added by scattering + radiance added by emission) * beam transmittance/attenuation
*/
+
+/* For ease of use, I've also introduced a 'reflection' and 'reflection color' parameter, which isn't
+ * physically correct. This works as an RGB tint/gain on out-scattered light, but doesn't affect the light
+ * that is transmitted through the volume. While having wavelength dependent absorption/scattering is more correct,
+ * it also makes it harder to control the overall look of the volume since colouring the outscattered light results
+ * in the inverse colour being transmitted through the rest of the volume.
+ */
static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float *endco)
{
- float tr[3] = {1.0f, 1.0f, 1.0f};
- float radiance[3] = {0.f, 0.f, 0.f}, d_radiance[3] = {0.f, 0.f, 0.f};
- float stepsize = vol_get_stepsize(shi, STEPSIZE_VIEW);
- int nsteps, s;
- float emit_col[3], scatter_col[3] = {0.0, 0.0, 0.0};
- float stepvec[3], step_sta[3], step_end[3], step_mid[3];
- float density;
- const float depth_cutoff = shi->mat->vol.depth_cutoff;
-
- /* ray marching */
- nsteps = (int)((VecLenf(co, endco) / stepsize) + 0.5);
-
- VecSubf(stepvec, endco, co);
- VecMulf(stepvec, 1.0f / nsteps);
- VecCopyf(step_sta, co);
- VecAddf(step_end, step_sta, stepvec);
-
- /* get radiance from all points along the ray due to participating media */
- for (s = 0; s < nsteps; s++) {
-
- density = vol_get_density(shi, step_sta);
+ float radiance[3] = {0.f, 0.f, 0.f};
+ float tr[3] = {1.f, 1.f, 1.f};
+ float p[3] = {co[0], co[1], co[2]};
+ float step_vec[3] = {endco[0] - co[0], endco[1] - co[1], endco[2] - co[2]};
+ const float stepsize = shi->mat->vol.stepsize;
+
+ float t0 = 0.f;
+ float pt0 = t0;
+ float t1 = Normalize(step_vec); /* returns vector length */
+
+ t0 += stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread));
+ p[0] += t0 * step_vec[0];
+ p[1] += t0 * step_vec[1];
+ p[2] += t0 * step_vec[2];
+ VecMulf(step_vec, stepsize);
+
+ for (; t0 < t1; pt0 = t0, t0 += stepsize) {
+ const float density = vol_get_density(shi, p);
- /* there's only any use in shading here if there's actually some density to shade! */
if (density > 0.01f) {
-
+ float scatter_col[3], emit_col[3];
+ const float stepd = (t0 - pt0) * density;
+
/* transmittance component (alpha) */
vol_get_transmittance_seg(shi, tr, stepsize, co, density);
-
- step_mid[0] = step_sta[0] + (stepvec[0] * 0.5);
- step_mid[1] = step_sta[1] + (stepvec[1] * 0.5);
- step_mid[2] = step_sta[2] + (stepvec[2] * 0.5);
-
- /* incoming light via emission or scattering (additive) */
- vol_get_emission(shi, emit_col, step_mid, density);
- if (shi->obi->volume_precache)
- vol_get_precached_scattering(shi, scatter_col, step_mid);
- else
- vol_get_scattering(shi, scatter_col, step_mid, stepsize, density);
+ if (luminance(tr) < shi->mat->vol.depth_cutoff) break;
- VecMulf(scatter_col, density);
- VecAddf(d_radiance, emit_col, scatter_col);
+ vol_get_emission(shi, emit_col, p);
- /* Lv += Tr * (Lve() + Ld) */
- VecMulVecf(d_radiance, tr, d_radiance);
- VecMulf(d_radiance, stepsize);
+ if (shi->obi->volume_precache) {
+ float p2[3];
+
+ p2[0] = p[0] + (step_vec[0] * 0.5);
+ p2[1] = p[1] + (step_vec[1] * 0.5);
+ p2[2] = p[2] + (step_vec[2] * 0.5);
+
+ vol_get_precached_scattering(shi, scatter_col, p2);
+ } else
+ vol_get_scattering(shi, scatter_col, p);
- VecAddf(radiance, radiance, d_radiance);
+ radiance[0] += stepd * tr[0] * (emit_col[0] + scatter_col[0]);
+ radiance[1] += stepd * tr[1] * (emit_col[1] + scatter_col[1]);
+ radiance[2] += stepd * tr[2] * (emit_col[2] + scatter_col[2]);
}
-
- VecCopyf(step_sta, step_end);
- VecAddf(step_end, step_end, stepvec);
-
- /* luminance rec. 709 */
- if ((0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]) < depth_cutoff) break;
+ VecAddf(p, p, step_vec);
}
- /* multiply original color (behind volume) with beam transmittance over entire distance */
- VecMulVecf(col, tr, col);
+ /* multiply original color (from behind volume) with transmittance over entire distance */
+ VecMulVecf(col, tr, col);
VecAddf(col, col, radiance);
/* alpha <-- transmission luminance */
- col[3] = 1.0f -(0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]);
+ col[3] = 1.0f - luminance(tr);
}
/* the main entry point for volume shading */
@@ -606,7 +615,7 @@ static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int in
/* don't render the backfaces of ztransp volume materials.
* volume shading renders the internal volume from between the
- * near view intersection of the solid volume to the
+ * ' view intersection of the solid volume to the
* intersection on the other side, as part of the shading of
* the front face.
@@ -709,8 +718,7 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct
vol_get_transmittance(shi, tr, startco, endco);
VecCopyf(shr->combined, tr);
- shr->combined[3] = 1.0f -(0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]);
- shr->alpha = shr->combined[3];
+ shr->combined[3] = 1.0f - luminance(tr);
}
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index 9318d37620c..479f33c9ff2 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -226,9 +226,6 @@ void make_voxeldata(struct Render *re)
{
Tex *tex;
- if(re->scene->r.scemode & R_PREVIEWBUTS)
- return;
-
re->i.infostr= "Loading voxel datasets";
re->stats_draw(re->sdh, &re->i);
@@ -259,9 +256,6 @@ void free_voxeldata(Render *re)
{
Tex *tex;
- if(re->scene->r.scemode & R_PREVIEWBUTS)
- return;
-
for (tex= G.main->tex.first; tex; tex= tex->id.next) {
if(tex->id.us && tex->type==TEX_VOXELDATA) {
free_voxeldata_one(re, tex);