forked from bartvdbraak/blender
Ambient Occlusion split up into:
Ambient occlusion: multiplied with direct lighting by default, add is also still available and more blending methods might be added if they are useful. This is fundamentally a non physical effect. Environment lighting: always added as you would expect (though you can subtract by specifying negative energy). This can be just white or take colors or textures from the world. Indirect lighting: only supported for AAO at the moment (and is still too approximate), and also is always added. A factor is available to specify how much is added, though value 1.0 is correct. Also: * Material ambient value now defaults to 1.0. * Added Environment, Indirect and Emit pass. * "Both" blending method is no longer available. * Attenuation, sampling parameters are still shared, some could be split up, though if they are different this would affect performance.
This commit is contained in:
parent
478dc000b3
commit
5445dda295
@ -137,11 +137,11 @@ class RENDER_PT_layers(RenderButtonsPanel):
|
|||||||
col.prop(rl, "pass_uv")
|
col.prop(rl, "pass_uv")
|
||||||
col.prop(rl, "pass_mist")
|
col.prop(rl, "pass_mist")
|
||||||
col.prop(rl, "pass_object_index")
|
col.prop(rl, "pass_object_index")
|
||||||
|
col.prop(rl, "pass_color")
|
||||||
|
|
||||||
if wide_ui:
|
if wide_ui:
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.label()
|
col.label()
|
||||||
col.prop(rl, "pass_color")
|
|
||||||
col.prop(rl, "pass_diffuse")
|
col.prop(rl, "pass_diffuse")
|
||||||
row = col.row()
|
row = col.row()
|
||||||
row.prop(rl, "pass_specular")
|
row.prop(rl, "pass_specular")
|
||||||
@ -150,16 +150,24 @@ class RENDER_PT_layers(RenderButtonsPanel):
|
|||||||
row.prop(rl, "pass_shadow")
|
row.prop(rl, "pass_shadow")
|
||||||
row.prop(rl, "pass_shadow_exclude", text="", icon='X')
|
row.prop(rl, "pass_shadow_exclude", text="", icon='X')
|
||||||
row = col.row()
|
row = col.row()
|
||||||
|
row.prop(rl, "pass_emit")
|
||||||
|
row.prop(rl, "pass_emit_exclude", text="", icon='X')
|
||||||
|
row = col.row()
|
||||||
row.prop(rl, "pass_ao")
|
row.prop(rl, "pass_ao")
|
||||||
row.prop(rl, "pass_ao_exclude", text="", icon='X')
|
row.prop(rl, "pass_ao_exclude", text="", icon='X')
|
||||||
row = col.row()
|
row = col.row()
|
||||||
|
row.prop(rl, "pass_environment")
|
||||||
|
row.prop(rl, "pass_environment_exclude", text="", icon='X')
|
||||||
|
row = col.row()
|
||||||
|
row.prop(rl, "pass_indirect")
|
||||||
|
row.prop(rl, "pass_indirect_exclude", text="", icon='X')
|
||||||
|
row = col.row()
|
||||||
row.prop(rl, "pass_reflection")
|
row.prop(rl, "pass_reflection")
|
||||||
row.prop(rl, "pass_reflection_exclude", text="", icon='X')
|
row.prop(rl, "pass_reflection_exclude", text="", icon='X')
|
||||||
row = col.row()
|
row = col.row()
|
||||||
row.prop(rl, "pass_refraction")
|
row.prop(rl, "pass_refraction")
|
||||||
row.prop(rl, "pass_refraction_exclude", text="", icon='X')
|
row.prop(rl, "pass_refraction_exclude", text="", icon='X')
|
||||||
|
|
||||||
|
|
||||||
class RENDER_PT_shading(RenderButtonsPanel):
|
class RENDER_PT_shading(RenderButtonsPanel):
|
||||||
bl_label = "Shading"
|
bl_label = "Shading"
|
||||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
@ -105,6 +105,7 @@ class WORLD_PT_world(WorldButtonsPanel):
|
|||||||
|
|
||||||
class WORLD_PT_mist(WorldButtonsPanel):
|
class WORLD_PT_mist(WorldButtonsPanel):
|
||||||
bl_label = "Mist"
|
bl_label = "Mist"
|
||||||
|
bl_default_closed = True
|
||||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
|
||||||
def draw_header(self, context):
|
def draw_header(self, context):
|
||||||
@ -135,6 +136,7 @@ class WORLD_PT_mist(WorldButtonsPanel):
|
|||||||
|
|
||||||
class WORLD_PT_stars(WorldButtonsPanel):
|
class WORLD_PT_stars(WorldButtonsPanel):
|
||||||
bl_label = "Stars"
|
bl_label = "Stars"
|
||||||
|
bl_default_closed = True
|
||||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
|
||||||
def draw_header(self, context):
|
def draw_header(self, context):
|
||||||
@ -166,77 +168,110 @@ class WORLD_PT_ambient_occlusion(WorldButtonsPanel):
|
|||||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
|
||||||
def draw_header(self, context):
|
def draw_header(self, context):
|
||||||
world = context.world
|
light = context.world.lighting
|
||||||
|
self.layout.prop(light, "use_ambient_occlusion", text="")
|
||||||
self.layout.prop(world.ambient_occlusion, "enabled", text="")
|
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
wide_ui = context.region.width > narrowui
|
light = context.world.lighting
|
||||||
ao = context.world.ambient_occlusion
|
|
||||||
|
|
||||||
layout.active = ao.enabled
|
layout.active = light.use_ambient_occlusion
|
||||||
|
|
||||||
layout.prop(ao, "gather_method", expand=True)
|
split = layout.split()
|
||||||
|
split.prop(light, "ao_factor", text="Factor")
|
||||||
|
split.prop(light, "ao_blend_mode", text="")
|
||||||
|
|
||||||
|
class WORLD_PT_environment_lighting(WorldButtonsPanel):
|
||||||
|
bl_label = "Environment Lighting"
|
||||||
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
|
||||||
|
def draw_header(self, context):
|
||||||
|
light = context.world.lighting
|
||||||
|
self.layout.prop(light, "use_environment_lighting", text="")
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
light = context.world.lighting
|
||||||
|
|
||||||
|
layout.active = light.use_environment_lighting
|
||||||
|
|
||||||
|
split = layout.split()
|
||||||
|
split.prop(light, "environment_energy", text="Energy")
|
||||||
|
split.prop(light, "environment_color", text="")
|
||||||
|
|
||||||
|
class WORLD_PT_indirect_lighting(WorldButtonsPanel):
|
||||||
|
bl_label = "Indirect Lighting"
|
||||||
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
|
||||||
|
def draw_header(self, context):
|
||||||
|
light = context.world.lighting
|
||||||
|
self.layout.prop(light, "use_indirect_lighting", text="")
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
light = context.world.lighting
|
||||||
|
|
||||||
|
layout.active = light.use_indirect_lighting
|
||||||
|
|
||||||
|
split = layout.split()
|
||||||
|
split.prop(light, "indirect_factor", text="Factor")
|
||||||
|
split.prop(light, "indirect_bounces", text="Bounces")
|
||||||
|
|
||||||
|
class WORLD_PT_gather(WorldButtonsPanel):
|
||||||
|
bl_label = "Gather"
|
||||||
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
light = context.world.lighting
|
||||||
|
|
||||||
|
layout.active = light.use_ambient_occlusion or light.use_environment_lighting or light.use_indirect_lighting
|
||||||
|
|
||||||
|
layout.prop(light, "gather_method", expand=True)
|
||||||
|
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.label(text="Attenuation:")
|
col.label(text="Attenuation:")
|
||||||
if ao.gather_method == 'RAYTRACE':
|
if light.gather_method == 'RAYTRACE':
|
||||||
col.prop(ao, "distance")
|
col.prop(light, "distance")
|
||||||
col.prop(ao, "falloff")
|
col.prop(light, "falloff")
|
||||||
sub = col.row()
|
sub = col.row()
|
||||||
sub.active = ao.falloff
|
sub.active = light.falloff
|
||||||
sub.prop(ao, "falloff_strength", text="Strength")
|
sub.prop(light, "falloff_strength", text="Strength")
|
||||||
|
|
||||||
if ao.gather_method == 'RAYTRACE':
|
if light.gather_method == 'RAYTRACE':
|
||||||
if wide_ui:
|
col = split.column()
|
||||||
col = split.column()
|
|
||||||
|
|
||||||
col.label(text="Sampling:")
|
col.label(text="Sampling:")
|
||||||
col.prop(ao, "sample_method", text="")
|
col.prop(light, "sample_method", text="")
|
||||||
|
|
||||||
sub = col.column()
|
sub = col.column()
|
||||||
sub.prop(ao, "samples")
|
sub.prop(light, "samples")
|
||||||
|
|
||||||
if ao.sample_method == 'ADAPTIVE_QMC':
|
if light.sample_method == 'ADAPTIVE_QMC':
|
||||||
sub.prop(ao, "threshold")
|
sub.prop(light, "threshold")
|
||||||
sub.prop(ao, "adapt_to_speed", slider=True)
|
sub.prop(light, "adapt_to_speed", slider=True)
|
||||||
elif ao.sample_method == 'CONSTANT_JITTERED':
|
elif light.sample_method == 'CONSTANT_JITTERED':
|
||||||
sub.prop(ao, "bias")
|
sub.prop(light, "bias")
|
||||||
|
|
||||||
if ao.gather_method == 'APPROXIMATE':
|
if light.gather_method == 'APPROXIMATE':
|
||||||
if wide_ui:
|
col = split.column()
|
||||||
col = split.column()
|
|
||||||
|
|
||||||
col.label(text="Sampling:")
|
col.label(text="Sampling:")
|
||||||
col.prop(ao, "passes")
|
col.prop(light, "passes")
|
||||||
col.prop(ao, "error_tolerance", text="Error")
|
col.prop(light, "error_tolerance", text="Error")
|
||||||
col.prop(ao, "pixel_cache")
|
col.prop(light, "pixel_cache")
|
||||||
col.prop(ao, "correction")
|
col.prop(light, "correction")
|
||||||
|
|
||||||
col = layout.column()
|
|
||||||
col.label(text="Influence:")
|
|
||||||
|
|
||||||
col.row().prop(ao, "blend_mode", expand=True)
|
|
||||||
|
|
||||||
split = layout.split()
|
|
||||||
|
|
||||||
col = split.column()
|
|
||||||
col.prop(ao, "energy")
|
|
||||||
col.prop(ao, "indirect_energy")
|
|
||||||
|
|
||||||
if wide_ui:
|
|
||||||
col = split.column()
|
|
||||||
col.prop(ao, "color")
|
|
||||||
col.prop(ao, "indirect_bounces")
|
|
||||||
|
|
||||||
bpy.types.register(WORLD_PT_context_world)
|
bpy.types.register(WORLD_PT_context_world)
|
||||||
bpy.types.register(WORLD_PT_preview)
|
bpy.types.register(WORLD_PT_preview)
|
||||||
bpy.types.register(WORLD_PT_world)
|
bpy.types.register(WORLD_PT_world)
|
||||||
bpy.types.register(WORLD_PT_ambient_occlusion)
|
bpy.types.register(WORLD_PT_ambient_occlusion)
|
||||||
|
bpy.types.register(WORLD_PT_environment_lighting)
|
||||||
|
bpy.types.register(WORLD_PT_indirect_lighting)
|
||||||
|
bpy.types.register(WORLD_PT_gather)
|
||||||
bpy.types.register(WORLD_PT_mist)
|
bpy.types.register(WORLD_PT_mist)
|
||||||
bpy.types.register(WORLD_PT_stars)
|
bpy.types.register(WORLD_PT_stars)
|
||||||
|
|
||||||
bpy.types.register(WORLD_PT_custom_props)
|
bpy.types.register(WORLD_PT_custom_props)
|
||||||
|
@ -43,7 +43,7 @@ struct bContext;
|
|||||||
struct ReportList;
|
struct ReportList;
|
||||||
|
|
||||||
#define BLENDER_VERSION 250
|
#define BLENDER_VERSION 250
|
||||||
#define BLENDER_SUBVERSION 14
|
#define BLENDER_SUBVERSION 15
|
||||||
|
|
||||||
#define BLENDER_MINVERSION 250
|
#define BLENDER_MINVERSION 250
|
||||||
#define BLENDER_MINSUBVERSION 0
|
#define BLENDER_MINSUBVERSION 0
|
||||||
|
@ -112,7 +112,7 @@ void init_material(Material *ma)
|
|||||||
ma->specr= ma->specg= ma->specb= 1.0;
|
ma->specr= ma->specg= ma->specb= 1.0;
|
||||||
ma->mirr= ma->mirg= ma->mirb= 1.0;
|
ma->mirr= ma->mirg= ma->mirb= 1.0;
|
||||||
ma->spectra= 1.0;
|
ma->spectra= 1.0;
|
||||||
ma->amb= 0.5;
|
ma->amb= 1.0;
|
||||||
ma->alpha= 1.0;
|
ma->alpha= 1.0;
|
||||||
ma->spec= ma->hasize= 0.5;
|
ma->spec= ma->hasize= 0.5;
|
||||||
ma->har= 50;
|
ma->har= 50;
|
||||||
|
@ -102,6 +102,9 @@ World *add_world(char *name)
|
|||||||
wrld->aodist= 10.0f;
|
wrld->aodist= 10.0f;
|
||||||
wrld->aosamp= 5;
|
wrld->aosamp= 5;
|
||||||
wrld->aoenergy= 1.0f;
|
wrld->aoenergy= 1.0f;
|
||||||
|
wrld->ao_env_energy= 1.0f;
|
||||||
|
wrld->ao_indirect_energy= 1.0f;
|
||||||
|
wrld->ao_indirect_bounces= 1;
|
||||||
wrld->aobias= 0.05f;
|
wrld->aobias= 0.05f;
|
||||||
wrld->ao_samp_method = WO_AOSAMP_HAMMERSLEY;
|
wrld->ao_samp_method = WO_AOSAMP_HAMMERSLEY;
|
||||||
wrld->ao_approx_error= 0.25f;
|
wrld->ao_approx_error= 0.25f;
|
||||||
|
@ -10604,6 +10604,36 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 15)) {
|
||||||
|
World *wo;
|
||||||
|
Material *ma;
|
||||||
|
|
||||||
|
/* ambient default from 0.5f to 1.0f */
|
||||||
|
for(ma= main->mat.first; ma; ma=ma->id.next)
|
||||||
|
ma->amb *= 2.0f;
|
||||||
|
|
||||||
|
for(wo= main->world.first; wo; wo=wo->id.next) {
|
||||||
|
/* ao splitting into ao/env/indirect */
|
||||||
|
wo->ao_env_energy= wo->aoenergy;
|
||||||
|
wo->aoenergy= 1.0f;
|
||||||
|
|
||||||
|
if(wo->ao_indirect_bounces == 0)
|
||||||
|
wo->ao_indirect_bounces= 1;
|
||||||
|
else
|
||||||
|
wo->mode |= WO_INDIRECT_LIGHT;
|
||||||
|
|
||||||
|
if(wo->aomix == WO_AOSUB)
|
||||||
|
wo->ao_env_energy= -wo->ao_env_energy;
|
||||||
|
else if(wo->aomix == WO_AOADDSUB)
|
||||||
|
wo->mode |= WO_AMB_OCC;
|
||||||
|
|
||||||
|
wo->aomix= WO_AOMUL;
|
||||||
|
|
||||||
|
/* ambient default from 0.5f to 1.0f */
|
||||||
|
mul_v3_fl(&wo->ambr, 0.5f);
|
||||||
|
wo->ao_env_energy *= 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* put 2.50 compatibility code here until next subversion bump */
|
/* put 2.50 compatibility code here until next subversion bump */
|
||||||
//{
|
//{
|
||||||
|
@ -170,23 +170,25 @@ typedef struct SceneRenderLayer {
|
|||||||
#define SCE_LAY_NEG_ZMASK 0x80000
|
#define SCE_LAY_NEG_ZMASK 0x80000
|
||||||
|
|
||||||
/* srl->passflag */
|
/* srl->passflag */
|
||||||
#define SCE_PASS_COMBINED 1
|
#define SCE_PASS_COMBINED 1
|
||||||
#define SCE_PASS_Z 2
|
#define SCE_PASS_Z 2
|
||||||
#define SCE_PASS_RGBA 4
|
#define SCE_PASS_RGBA 4
|
||||||
#define SCE_PASS_DIFFUSE 8
|
#define SCE_PASS_DIFFUSE 8
|
||||||
#define SCE_PASS_SPEC 16
|
#define SCE_PASS_SPEC 16
|
||||||
#define SCE_PASS_SHADOW 32
|
#define SCE_PASS_SHADOW 32
|
||||||
#define SCE_PASS_AO 64
|
#define SCE_PASS_AO 64
|
||||||
#define SCE_PASS_REFLECT 128
|
#define SCE_PASS_REFLECT 128
|
||||||
#define SCE_PASS_NORMAL 256
|
#define SCE_PASS_NORMAL 256
|
||||||
#define SCE_PASS_VECTOR 512
|
#define SCE_PASS_VECTOR 512
|
||||||
#define SCE_PASS_REFRACT 1024
|
#define SCE_PASS_REFRACT 1024
|
||||||
#define SCE_PASS_INDEXOB 2048
|
#define SCE_PASS_INDEXOB 2048
|
||||||
#define SCE_PASS_UV 4096
|
#define SCE_PASS_UV 4096
|
||||||
#define SCE_PASS_RADIO 8192 /* Radio removed, can use for new GI? */
|
#define SCE_PASS_RADIO 8192 /* Radio removed, can use for new GI? */
|
||||||
#define SCE_PASS_MIST 16384
|
#define SCE_PASS_MIST 16384
|
||||||
|
#define SCE_PASS_RAYHITS 32768
|
||||||
#define SCE_PASS_RAYHITS 32768
|
#define SCE_PASS_EMIT 65536
|
||||||
|
#define SCE_PASS_ENVIRONMENT 131072
|
||||||
|
#define SCE_PASS_INDIRECT 262144
|
||||||
|
|
||||||
/* note, srl->passflag is treestore element 'nr' in outliner, short still... */
|
/* note, srl->passflag is treestore element 'nr' in outliner, short still... */
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ typedef struct World {
|
|||||||
short aomode, aosamp, aomix, aocolor;
|
short aomode, aosamp, aomix, aocolor;
|
||||||
float ao_adapt_thresh, ao_adapt_speed_fac;
|
float ao_adapt_thresh, ao_adapt_speed_fac;
|
||||||
float ao_approx_error, ao_approx_correction;
|
float ao_approx_error, ao_approx_correction;
|
||||||
float ao_indirect_energy;
|
float ao_indirect_energy, ao_env_energy, ao_pad2;
|
||||||
short ao_indirect_bounces, ao_pad;
|
short ao_indirect_bounces, ao_pad;
|
||||||
short ao_samp_method, ao_gather_method, ao_approx_passes;
|
short ao_samp_method, ao_gather_method, ao_approx_passes;
|
||||||
|
|
||||||
@ -142,13 +142,16 @@ typedef struct World {
|
|||||||
#define WO_STARS 2
|
#define WO_STARS 2
|
||||||
#define WO_DOF 4
|
#define WO_DOF 4
|
||||||
#define WO_ACTIVITY_CULLING 8
|
#define WO_ACTIVITY_CULLING 8
|
||||||
#define WO_AMB_OCC 16
|
#define WO_ENV_LIGHT 16
|
||||||
#define WO_DBVT_CULLING 32
|
#define WO_DBVT_CULLING 32
|
||||||
|
#define WO_AMB_OCC 64
|
||||||
|
#define WO_INDIRECT_LIGHT 128
|
||||||
|
|
||||||
/* aomix */
|
/* aomix */
|
||||||
#define WO_AOADD 0
|
#define WO_AOADD 0
|
||||||
#define WO_AOSUB 1
|
#define WO_AOSUB 1 /* deprecated */
|
||||||
#define WO_AOADDSUB 2
|
#define WO_AOADDSUB 2 /* deprecated */
|
||||||
|
#define WO_AOMUL 3
|
||||||
|
|
||||||
/* ao_samp_method - methods for sampling the AO hemi */
|
/* ao_samp_method - methods for sampling the AO hemi */
|
||||||
#define WO_AOSAMP_CONSTANT 0
|
#define WO_AOSAMP_CONSTANT 0
|
||||||
|
@ -369,6 +369,8 @@ static void rna_def_render_pass(BlenderRNA *brna)
|
|||||||
{SCE_PASS_INDEXOB, "OBJECT_INDEX", 0, "Object Index", ""},
|
{SCE_PASS_INDEXOB, "OBJECT_INDEX", 0, "Object Index", ""},
|
||||||
{SCE_PASS_UV, "UV", 0, "UV", ""},
|
{SCE_PASS_UV, "UV", 0, "UV", ""},
|
||||||
{SCE_PASS_MIST, "MIST", 0, "Mist", ""},
|
{SCE_PASS_MIST, "MIST", 0, "Mist", ""},
|
||||||
|
{SCE_PASS_EMIT, "EMIT", 0, "Emit", ""},
|
||||||
|
{SCE_PASS_ENVIRONMENT, "ENVIRONMENT", 0, "Environment", ""},
|
||||||
{0, NULL, 0, NULL, NULL}};
|
{0, NULL, 0, NULL, NULL}};
|
||||||
|
|
||||||
srna= RNA_def_struct(brna, "RenderPass", NULL);
|
srna= RNA_def_struct(brna, "RenderPass", NULL);
|
||||||
|
@ -1142,6 +1142,24 @@ void rna_def_render_layer_common(StructRNA *srna, int scene)
|
|||||||
if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
|
if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
|
||||||
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "pass_emit", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_EMIT);
|
||||||
|
RNA_def_property_ui_text(prop, "Emit", "Deliver emission pass.");
|
||||||
|
if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
|
||||||
|
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "pass_environment", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_ENVIRONMENT);
|
||||||
|
RNA_def_property_ui_text(prop, "Environment", "Deliver environment lighting pass.");
|
||||||
|
if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
|
||||||
|
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "pass_indirect", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_INDIRECT);
|
||||||
|
RNA_def_property_ui_text(prop, "Indirect", "Deliver indirect lighting pass.");
|
||||||
|
if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
|
||||||
|
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "pass_specular_exclude", PROP_BOOLEAN, PROP_NONE);
|
prop= RNA_def_property(srna, "pass_specular_exclude", PROP_BOOLEAN, PROP_NONE);
|
||||||
RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_SPEC);
|
RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_SPEC);
|
||||||
RNA_def_property_ui_text(prop, "Specular Exclude", "Exclude specular pass from combined.");
|
RNA_def_property_ui_text(prop, "Specular Exclude", "Exclude specular pass from combined.");
|
||||||
@ -1171,6 +1189,24 @@ void rna_def_render_layer_common(StructRNA *srna, int scene)
|
|||||||
RNA_def_property_ui_text(prop, "Refraction Exclude", "Exclude raytraced refraction pass from combined.");
|
RNA_def_property_ui_text(prop, "Refraction Exclude", "Exclude raytraced refraction pass from combined.");
|
||||||
if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
|
if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
|
||||||
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "pass_emit_exclude", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_EMIT);
|
||||||
|
RNA_def_property_ui_text(prop, "Emit Exclude", "Exclude emission pass from combined.");
|
||||||
|
if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
|
||||||
|
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "pass_environment_exclude", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_ENVIRONMENT);
|
||||||
|
RNA_def_property_ui_text(prop, "Environment Exclude", "Exclude environment pass from combined.");
|
||||||
|
if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
|
||||||
|
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "pass_indirect_exclude", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "pass_xor", SCE_PASS_INDIRECT);
|
||||||
|
RNA_def_property_ui_text(prop, "Indirect Exclude", "Exclude indirect pass from combined.");
|
||||||
|
if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
|
||||||
|
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_def_scene_game_data(BlenderRNA *brna)
|
static void rna_def_scene_game_data(BlenderRNA *brna)
|
||||||
|
@ -45,9 +45,9 @@
|
|||||||
#include "WM_api.h"
|
#include "WM_api.h"
|
||||||
#include "WM_types.h"
|
#include "WM_types.h"
|
||||||
|
|
||||||
static PointerRNA rna_World_ambient_occlusion_get(PointerRNA *ptr)
|
static PointerRNA rna_World_lighting_get(PointerRNA *ptr)
|
||||||
{
|
{
|
||||||
return rna_pointer_inherit_refine(ptr, &RNA_WorldAmbientOcclusion, ptr->id.data);
|
return rna_pointer_inherit_refine(ptr, &RNA_WorldLighting, ptr->id.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PointerRNA rna_World_stars_get(PointerRNA *ptr)
|
static PointerRNA rna_World_stars_get(PointerRNA *ptr)
|
||||||
@ -182,15 +182,14 @@ static void rna_def_world_mtex(BlenderRNA *brna)
|
|||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_def_ambient_occlusion(BlenderRNA *brna)
|
static void rna_def_lighting(BlenderRNA *brna)
|
||||||
{
|
{
|
||||||
StructRNA *srna;
|
StructRNA *srna;
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
|
|
||||||
static EnumPropertyItem blend_mode_items[] = {
|
static EnumPropertyItem blend_mode_items[] = {
|
||||||
|
{WO_AOMUL, "MULTIPLY", 0, "Multiply", "Multiply direct lighting with ambient occlusion, darkening the result."},
|
||||||
{WO_AOADD, "ADD", 0, "Add", "Add light and shadow."},
|
{WO_AOADD, "ADD", 0, "Add", "Add light and shadow."},
|
||||||
{WO_AOSUB, "SUBTRACT", 0, "Subtract", "Subtract light and shadow (needs a normal light to make anything visible.)"},
|
|
||||||
{WO_AOADDSUB, "BOTH", 0, "Both", "Both lighten and darken."},
|
|
||||||
{0, NULL, 0, NULL, NULL}};
|
{0, NULL, 0, NULL, NULL}};
|
||||||
|
|
||||||
static EnumPropertyItem prop_color_items[] = {
|
static EnumPropertyItem prop_color_items[] = {
|
||||||
@ -210,14 +209,78 @@ static void rna_def_ambient_occlusion(BlenderRNA *brna)
|
|||||||
{WO_AOGATHER_APPROX, "APPROXIMATE", 0, "Approximate", "Inaccurate, but faster and without noise."},
|
{WO_AOGATHER_APPROX, "APPROXIMATE", 0, "Approximate", "Inaccurate, but faster and without noise."},
|
||||||
{0, NULL, 0, NULL, NULL}};
|
{0, NULL, 0, NULL, NULL}};
|
||||||
|
|
||||||
srna= RNA_def_struct(brna, "WorldAmbientOcclusion", NULL);
|
srna= RNA_def_struct(brna, "WorldLighting", NULL);
|
||||||
RNA_def_struct_sdna(srna, "World");
|
RNA_def_struct_sdna(srna, "World");
|
||||||
RNA_def_struct_nested(brna, srna, "World");
|
RNA_def_struct_nested(brna, srna, "World");
|
||||||
RNA_def_struct_ui_text(srna, "Ambient Occlusion", "Ambient occlusion settings for a World datablock.");
|
RNA_def_struct_ui_text(srna, "Lighting", "Lighting for a World datablock.");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
|
/* ambient occlusion */
|
||||||
|
prop= RNA_def_property(srna, "use_ambient_occlusion", PROP_BOOLEAN, PROP_NONE);
|
||||||
RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_AMB_OCC);
|
RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_AMB_OCC);
|
||||||
RNA_def_property_ui_text(prop, "Enabled", "Use Ambient Occlusion to add light based on distance between elements, creating the illusion of omnipresent light");
|
RNA_def_property_ui_text(prop, "Use Ambient Occlusion", "Use Ambient Occlusion to add shadowing based on distance between objects.");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "ao_factor", PROP_FLOAT, PROP_FACTOR);
|
||||||
|
RNA_def_property_float_sdna(prop, NULL, "aoenergy");
|
||||||
|
RNA_def_property_range(prop, 0, INT_MAX);
|
||||||
|
RNA_def_property_ui_range(prop, 0, 1, 0.1, 2);
|
||||||
|
RNA_def_property_ui_text(prop, "Factor", "Factor for ambient occlusion blending blending.");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "ao_blend_mode", PROP_ENUM, PROP_NONE);
|
||||||
|
RNA_def_property_enum_sdna(prop, NULL, "aomix");
|
||||||
|
RNA_def_property_enum_items(prop, blend_mode_items);
|
||||||
|
RNA_def_property_ui_text(prop, "Blend Mode", "Defines how AO mixes with material shading.");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
|
/* environment lighting */
|
||||||
|
prop= RNA_def_property(srna, "use_environment_lighting", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_ENV_LIGHT);
|
||||||
|
RNA_def_property_ui_text(prop, "Use Environment Lighting", "Add light coming from the environment.");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "environment_energy", PROP_FLOAT, PROP_NONE);
|
||||||
|
RNA_def_property_float_sdna(prop, NULL, "ao_env_energy");
|
||||||
|
RNA_def_property_ui_range(prop, 0, FLT_MAX, 0.1, 2);
|
||||||
|
RNA_def_property_ui_text(prop, "Environment Color", "Defines the strength of environment light.");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "environment_color", PROP_ENUM, PROP_NONE);
|
||||||
|
RNA_def_property_enum_sdna(prop, NULL, "aocolor");
|
||||||
|
RNA_def_property_enum_items(prop, prop_color_items);
|
||||||
|
RNA_def_property_ui_text(prop, "Environment Color", "Defines where the color of the environment light comes from.");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
|
/* indirect lighting */
|
||||||
|
prop= RNA_def_property(srna, "use_indirect_lighting", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_INDIRECT_LIGHT);
|
||||||
|
RNA_def_property_ui_text(prop, "Use Indirect Lighting", "Add indirect light bouncing of surrounding objects.");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "indirect_factor", PROP_FLOAT, PROP_FACTOR);
|
||||||
|
RNA_def_property_float_sdna(prop, NULL, "ao_indirect_energy");
|
||||||
|
RNA_def_property_range(prop, 0, INT_MAX);
|
||||||
|
RNA_def_property_ui_range(prop, 0, 1, 0.1, 2);
|
||||||
|
RNA_def_property_ui_text(prop, "Indirect Factor", "Factor for how much surrounding objects contribute to light.");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "indirect_bounces", PROP_INT, PROP_UNSIGNED);
|
||||||
|
RNA_def_property_int_sdna(prop, NULL, "ao_indirect_bounces");
|
||||||
|
RNA_def_property_range(prop, 1, INT_MAX);
|
||||||
|
RNA_def_property_ui_text(prop, "Bounces", "Number of indirect diffuse light bounces to use for approximate ambient occlusion.");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
|
/* gathering parameters */
|
||||||
|
prop= RNA_def_property(srna, "gather_method", PROP_ENUM, PROP_NONE);
|
||||||
|
RNA_def_property_enum_sdna(prop, NULL, "ao_gather_method");
|
||||||
|
RNA_def_property_enum_items(prop, prop_gather_method_items);
|
||||||
|
RNA_def_property_ui_text(prop, "Gather Method", "");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "passes", PROP_INT, PROP_NONE);
|
||||||
|
RNA_def_property_int_sdna(prop, NULL, "ao_approx_passes");
|
||||||
|
RNA_def_property_range(prop, 0, 10);
|
||||||
|
RNA_def_property_ui_text(prop, "Passes", "Number of preprocessing passes to reduce overocclusion (for Approximate).");
|
||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
|
prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
|
||||||
@ -230,12 +293,6 @@ static void rna_def_ambient_occlusion(BlenderRNA *brna)
|
|||||||
RNA_def_property_ui_text(prop, "Strength", "Distance attenuation factor, the higher, the 'shorter' the shadows.");
|
RNA_def_property_ui_text(prop, "Strength", "Distance attenuation factor, the higher, the 'shorter' the shadows.");
|
||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "energy", PROP_FLOAT, PROP_NONE);
|
|
||||||
RNA_def_property_float_sdna(prop, NULL, "aoenergy");
|
|
||||||
RNA_def_property_ui_range(prop, 0, 10, 0.1, 3);
|
|
||||||
RNA_def_property_ui_text(prop, "Energy", "Amount of enerygy generated by ambient occlusion.");
|
|
||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "bias", PROP_FLOAT, PROP_NONE);
|
prop= RNA_def_property(srna, "bias", PROP_FLOAT, PROP_NONE);
|
||||||
RNA_def_property_float_sdna(prop, NULL, "aobias");
|
RNA_def_property_float_sdna(prop, NULL, "aobias");
|
||||||
RNA_def_property_range(prop, 0, 0.5);
|
RNA_def_property_range(prop, 0, 0.5);
|
||||||
@ -283,46 +340,11 @@ static void rna_def_ambient_occlusion(BlenderRNA *brna)
|
|||||||
RNA_def_property_ui_text(prop, "Samples", "Amount of ray samples. Higher values give smoother results and longer rendering times");
|
RNA_def_property_ui_text(prop, "Samples", "Amount of ray samples. Higher values give smoother results and longer rendering times");
|
||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "blend_mode", PROP_ENUM, PROP_NONE);
|
|
||||||
RNA_def_property_enum_sdna(prop, NULL, "aomix");
|
|
||||||
RNA_def_property_enum_items(prop, blend_mode_items);
|
|
||||||
RNA_def_property_ui_text(prop, "Blend Mode", "Defines how AO mixes with material shading.");
|
|
||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "color", PROP_ENUM, PROP_NONE);
|
|
||||||
RNA_def_property_enum_sdna(prop, NULL, "aocolor");
|
|
||||||
RNA_def_property_enum_items(prop, prop_color_items);
|
|
||||||
RNA_def_property_ui_text(prop, "Color", "Defines the color of the AO light");
|
|
||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "sample_method", PROP_ENUM, PROP_NONE);
|
prop= RNA_def_property(srna, "sample_method", PROP_ENUM, PROP_NONE);
|
||||||
RNA_def_property_enum_sdna(prop, NULL, "ao_samp_method");
|
RNA_def_property_enum_sdna(prop, NULL, "ao_samp_method");
|
||||||
RNA_def_property_enum_items(prop, prop_sample_method_items);
|
RNA_def_property_enum_items(prop, prop_sample_method_items);
|
||||||
RNA_def_property_ui_text(prop, "Sample Method", "Method for generating shadow samples (for Raytrace).");
|
RNA_def_property_ui_text(prop, "Sample Method", "Method for generating shadow samples (for Raytrace).");
|
||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "gather_method", PROP_ENUM, PROP_NONE);
|
|
||||||
RNA_def_property_enum_sdna(prop, NULL, "ao_gather_method");
|
|
||||||
RNA_def_property_enum_items(prop, prop_gather_method_items);
|
|
||||||
RNA_def_property_ui_text(prop, "Gather Method", "");
|
|
||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "passes", PROP_INT, PROP_NONE);
|
|
||||||
RNA_def_property_int_sdna(prop, NULL, "ao_approx_passes");
|
|
||||||
RNA_def_property_range(prop, 0, 10);
|
|
||||||
RNA_def_property_ui_text(prop, "Passes", "Number of preprocessing passes to reduce overocclusion (for Approximate).");
|
|
||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "indirect_energy", PROP_FLOAT, PROP_UNSIGNED);
|
|
||||||
RNA_def_property_float_sdna(prop, NULL, "ao_indirect_energy");
|
|
||||||
RNA_def_property_ui_range(prop, 0, 10, 0.1, 3);
|
|
||||||
RNA_def_property_ui_text(prop, "Indirect", "Use approximate ambient occlusion for indirect diffuse lighting.");
|
|
||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "indirect_bounces", PROP_INT, PROP_UNSIGNED);
|
|
||||||
RNA_def_property_int_sdna(prop, NULL, "ao_indirect_bounces");
|
|
||||||
RNA_def_property_ui_text(prop, "Bounces", "Number of indirect diffuse light bounces to use for approximate ambient occlusion.");
|
|
||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_def_world_mist(BlenderRNA *brna)
|
static void rna_def_world_mist(BlenderRNA *brna)
|
||||||
@ -499,11 +521,11 @@ void RNA_def_world(BlenderRNA *brna)
|
|||||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||||
|
|
||||||
/* nested structs */
|
/* nested structs */
|
||||||
prop= RNA_def_property(srna, "ambient_occlusion", PROP_POINTER, PROP_NONE);
|
prop= RNA_def_property(srna, "lighting", PROP_POINTER, PROP_NONE);
|
||||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||||
RNA_def_property_struct_type(prop, "WorldAmbientOcclusion");
|
RNA_def_property_struct_type(prop, "WorldLighting");
|
||||||
RNA_def_property_pointer_funcs(prop, "rna_World_ambient_occlusion_get", NULL, NULL);
|
RNA_def_property_pointer_funcs(prop, "rna_World_lighting_get", NULL, NULL);
|
||||||
RNA_def_property_ui_text(prop, "Ambient Occlusion", "World ambient occlusion settings.");
|
RNA_def_property_ui_text(prop, "Lighting", "World lighting settings.");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "mist", PROP_POINTER, PROP_NONE);
|
prop= RNA_def_property(srna, "mist", PROP_POINTER, PROP_NONE);
|
||||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||||
@ -517,7 +539,7 @@ void RNA_def_world(BlenderRNA *brna)
|
|||||||
RNA_def_property_pointer_funcs(prop, "rna_World_stars_get", NULL, NULL);
|
RNA_def_property_pointer_funcs(prop, "rna_World_stars_get", NULL, NULL);
|
||||||
RNA_def_property_ui_text(prop, "Stars", "World stars settings.");
|
RNA_def_property_ui_text(prop, "Stars", "World stars settings.");
|
||||||
|
|
||||||
rna_def_ambient_occlusion(brna);
|
rna_def_lighting(brna);
|
||||||
rna_def_world_mist(brna);
|
rna_def_world_mist(brna);
|
||||||
rna_def_world_stars(brna);
|
rna_def_world_stars(brna);
|
||||||
rna_def_world_mtex(brna);
|
rna_def_world_mtex(brna);
|
||||||
|
@ -49,10 +49,13 @@ typedef struct ShadeResult
|
|||||||
float combined[4];
|
float combined[4];
|
||||||
float col[4];
|
float col[4];
|
||||||
float alpha, mist, z;
|
float alpha, mist, z;
|
||||||
|
float emit[3];
|
||||||
float diff[3]; /* no ramps, shadow, etc */
|
float diff[3]; /* no ramps, shadow, etc */
|
||||||
float spec[3];
|
float spec[3];
|
||||||
float shad[3];
|
float shad[3];
|
||||||
float ao[3];
|
float ao[3];
|
||||||
|
float env[3];
|
||||||
|
float indirect[3];
|
||||||
float refl[3];
|
float refl[3];
|
||||||
float refr[3];
|
float refr[3];
|
||||||
float nor[3];
|
float nor[3];
|
||||||
@ -153,7 +156,7 @@ typedef struct ShadeInput
|
|||||||
float dxstrand, dystrand;
|
float dxstrand, dystrand;
|
||||||
|
|
||||||
/* AO is a pre-process now */
|
/* AO is a pre-process now */
|
||||||
float ao[3], indirect[3];
|
float ao[3], indirect[3], env[3];
|
||||||
|
|
||||||
int xs, ys; /* pixel to be rendered */
|
int xs, ys; /* pixel to be rendered */
|
||||||
int mask; /* subsample mask */
|
int mask; /* subsample mask */
|
||||||
|
@ -399,6 +399,7 @@ typedef struct StrandSurface {
|
|||||||
float (*co)[3];
|
float (*co)[3];
|
||||||
/* for occlusion caching */
|
/* for occlusion caching */
|
||||||
float (*ao)[3];
|
float (*ao)[3];
|
||||||
|
float (*env)[3];
|
||||||
float (*indirect)[3];
|
float (*indirect)[3];
|
||||||
/* for speedvectors */
|
/* for speedvectors */
|
||||||
float (*prevco)[3], (*nextco)[3];
|
float (*prevco)[3], (*nextco)[3];
|
||||||
|
@ -99,7 +99,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi);
|
|||||||
|
|
||||||
extern void ray_shadow(ShadeInput *, LampRen *, float *);
|
extern void ray_shadow(ShadeInput *, LampRen *, float *);
|
||||||
extern void ray_trace(ShadeInput *, ShadeResult *);
|
extern void ray_trace(ShadeInput *, ShadeResult *);
|
||||||
extern void ray_ao(ShadeInput *, float *);
|
extern void ray_ao(ShadeInput *, float *, float *);
|
||||||
extern void init_jitter_plane(LampRen *lar);
|
extern void init_jitter_plane(LampRen *lar);
|
||||||
extern void init_ao_sphere(struct World *wrld);
|
extern void init_ao_sphere(struct World *wrld);
|
||||||
extern void init_render_qmcsampler(Render *re);
|
extern void init_render_qmcsampler(Render *re);
|
||||||
|
@ -1701,7 +1701,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
|||||||
|
|
||||||
if(re->r.mode & R_SPEED)
|
if(re->r.mode & R_SPEED)
|
||||||
dosurfacecache= 1;
|
dosurfacecache= 1;
|
||||||
else if((re->wrld.mode & WO_AMB_OCC) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX))
|
else if((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX))
|
||||||
if(ma->amb != 0.0f)
|
if(ma->amb != 0.0f)
|
||||||
dosurfacecache= 1;
|
dosurfacecache= 1;
|
||||||
|
|
||||||
@ -3811,7 +3811,7 @@ void init_render_world(Render *re)
|
|||||||
while(re->wrld.aosamp*re->wrld.aosamp < re->osa)
|
while(re->wrld.aosamp*re->wrld.aosamp < re->osa)
|
||||||
re->wrld.aosamp++;
|
re->wrld.aosamp++;
|
||||||
if(!(re->r.mode & R_RAYTRACE) && (re->wrld.ao_gather_method == WO_AOGATHER_RAYTRACE))
|
if(!(re->r.mode & R_RAYTRACE) && (re->wrld.ao_gather_method == WO_AOGATHER_RAYTRACE))
|
||||||
re->wrld.mode &= ~WO_AMB_OCC;
|
re->wrld.mode &= ~(WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memset(&re->wrld, 0, sizeof(World));
|
memset(&re->wrld, 0, sizeof(World));
|
||||||
@ -4849,7 +4849,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
|
|||||||
if(re->r.mode & R_RAYTRACE) {
|
if(re->r.mode & R_RAYTRACE) {
|
||||||
init_render_qmcsampler(re);
|
init_render_qmcsampler(re);
|
||||||
|
|
||||||
if(re->wrld.mode & WO_AMB_OCC)
|
if(re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT))
|
||||||
if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
|
if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
|
||||||
init_ao_sphere(&re->wrld);
|
init_ao_sphere(&re->wrld);
|
||||||
}
|
}
|
||||||
@ -4925,7 +4925,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
|
|||||||
project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0, 1);
|
project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0, 1);
|
||||||
|
|
||||||
/* Occlusion */
|
/* Occlusion */
|
||||||
if((re->wrld.mode & WO_AMB_OCC) && !re->test_break(re->tbh))
|
if((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && !re->test_break(re->tbh))
|
||||||
if(re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
|
if(re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
|
||||||
if(re->r.renderer==R_INTERN)
|
if(re->r.renderer==R_INTERN)
|
||||||
if(re->r.mode & R_SHADOW)
|
if(re->r.mode & R_SHADOW)
|
||||||
@ -5537,7 +5537,7 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob)
|
|||||||
if(re->r.mode & R_RAYTRACE) {
|
if(re->r.mode & R_RAYTRACE) {
|
||||||
init_render_qmcsampler(re);
|
init_render_qmcsampler(re);
|
||||||
|
|
||||||
if(re->wrld.mode & WO_AMB_OCC)
|
if(re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT))
|
||||||
if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
|
if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
|
||||||
init_ao_sphere(&re->wrld);
|
init_ao_sphere(&re->wrld);
|
||||||
}
|
}
|
||||||
@ -5569,7 +5569,7 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob)
|
|||||||
makeraytree(re);
|
makeraytree(re);
|
||||||
|
|
||||||
/* occlusion */
|
/* occlusion */
|
||||||
if((re->wrld.mode & WO_AMB_OCC) && !re->test_break(re->tbh))
|
if((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && !re->test_break(re->tbh))
|
||||||
if(re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
|
if(re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
|
||||||
if(re->r.mode & R_SHADOW)
|
if(re->r.mode & R_SHADOW)
|
||||||
make_occ_tree(re);
|
make_occ_tree(re);
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
#define CACHE_STEP 3
|
#define CACHE_STEP 3
|
||||||
|
|
||||||
typedef struct OcclusionCacheSample {
|
typedef struct OcclusionCacheSample {
|
||||||
float co[3], n[3], ao[3], indirect[3], intensity, dist2;
|
float co[3], n[3], ao[3], env[3], indirect[3], intensity, dist2;
|
||||||
int x, y, filled;
|
int x, y, filled;
|
||||||
} OcclusionCacheSample;
|
} OcclusionCacheSample;
|
||||||
|
|
||||||
@ -120,6 +120,7 @@ typedef struct OcclusionThread {
|
|||||||
Render *re;
|
Render *re;
|
||||||
StrandSurface *mesh;
|
StrandSurface *mesh;
|
||||||
float (*faceao)[3];
|
float (*faceao)[3];
|
||||||
|
float (*faceenv)[3];
|
||||||
float (*faceindirect)[3];
|
float (*faceindirect)[3];
|
||||||
int begin, end;
|
int begin, end;
|
||||||
int thread;
|
int thread;
|
||||||
@ -1375,19 +1376,19 @@ static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass)
|
|||||||
MEM_freeN(occ);
|
MEM_freeN(occ);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, float *co, float *n, int thread, int onlyshadow, float *ao, float *indirect)
|
static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, float *co, float *n, int thread, int onlyshadow, float *ao, float *env, float *indirect)
|
||||||
{
|
{
|
||||||
float nn[3], bn[3], fac, occ, occlusion, correction, rad[3];
|
float nn[3], bn[3], fac, occ, occlusion, correction, rad[3];
|
||||||
int aocolor;
|
int envcolor;
|
||||||
|
|
||||||
aocolor= re->wrld.aocolor;
|
envcolor= re->wrld.aocolor;
|
||||||
if(onlyshadow)
|
if(onlyshadow)
|
||||||
aocolor= WO_AOPLAIN;
|
envcolor= WO_AOPLAIN;
|
||||||
|
|
||||||
VECCOPY(nn, n);
|
VECCOPY(nn, n);
|
||||||
negate_v3(nn);
|
negate_v3(nn);
|
||||||
|
|
||||||
occ_lookup(tree, thread, exclude, co, nn, &occ, (tree->doindirect)? rad: NULL, (aocolor)? bn: NULL);
|
occ_lookup(tree, thread, exclude, co, nn, &occ, (tree->doindirect)? rad: NULL, (env && envcolor)? bn: NULL);
|
||||||
|
|
||||||
correction= re->wrld.ao_approx_correction;
|
correction= re->wrld.ao_approx_correction;
|
||||||
|
|
||||||
@ -1396,13 +1397,20 @@ static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, f
|
|||||||
if(correction != 0.0f)
|
if(correction != 0.0f)
|
||||||
occlusion += correction*exp(-occ);
|
occlusion += correction*exp(-occ);
|
||||||
|
|
||||||
if(aocolor) {
|
if(env) {
|
||||||
/* sky shading using bent normal */
|
/* sky shading using bent normal */
|
||||||
if(ELEM(aocolor, WO_AOSKYCOL, WO_AOSKYTEX)) {
|
if(ELEM(envcolor, WO_AOSKYCOL, WO_AOSKYTEX)) {
|
||||||
fac= 0.5*(1.0f+bn[0]*re->grvec[0]+ bn[1]*re->grvec[1]+ bn[2]*re->grvec[2]);
|
fac= 0.5*(1.0f+bn[0]*re->grvec[0]+ bn[1]*re->grvec[1]+ bn[2]*re->grvec[2]);
|
||||||
ao[0]= (1.0f-fac)*re->wrld.horr + fac*re->wrld.zenr;
|
env[0]= (1.0f-fac)*re->wrld.horr + fac*re->wrld.zenr;
|
||||||
ao[1]= (1.0f-fac)*re->wrld.horg + fac*re->wrld.zeng;
|
env[1]= (1.0f-fac)*re->wrld.horg + fac*re->wrld.zeng;
|
||||||
ao[2]= (1.0f-fac)*re->wrld.horb + fac*re->wrld.zenb;
|
env[2]= (1.0f-fac)*re->wrld.horb + fac*re->wrld.zenb;
|
||||||
|
|
||||||
|
mul_v3_fl(env, occlusion);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
env[0]= occlusion;
|
||||||
|
env[1]= occlusion;
|
||||||
|
env[2]= occlusion;
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
else { /* WO_AOSKYTEX */
|
else { /* WO_AOSKYTEX */
|
||||||
@ -1416,10 +1424,9 @@ static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, f
|
|||||||
shadeSkyView(ao, co, bn, dxyview);
|
shadeSkyView(ao, co, bn, dxyview);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mul_v3_fl(ao, occlusion);
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
if(ao) {
|
||||||
ao[0]= occlusion;
|
ao[0]= occlusion;
|
||||||
ao[1]= occlusion;
|
ao[1]= occlusion;
|
||||||
ao[2]= occlusion;
|
ao[2]= occlusion;
|
||||||
@ -1447,7 +1454,7 @@ static OcclusionCacheSample *find_occ_sample(OcclusionCache *cache, int x, int y
|
|||||||
return &cache->sample[y*cache->w + x];
|
return &cache->sample[y*cache->w + x];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int y, int thread, float *ao, float *indirect)
|
static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int y, int thread, float *ao, float *env, float *indirect)
|
||||||
{
|
{
|
||||||
OcclusionCache *cache;
|
OcclusionCache *cache;
|
||||||
OcclusionCacheSample *samples[4], *sample;
|
OcclusionCacheSample *samples[4], *sample;
|
||||||
@ -1468,6 +1475,7 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int
|
|||||||
dist2= INPR(d, d);
|
dist2= INPR(d, d);
|
||||||
if(dist2 < 0.5f*sample->dist2 && INPR(sample->n, n) > 0.98f) {
|
if(dist2 < 0.5f*sample->dist2 && INPR(sample->n, n) > 0.98f) {
|
||||||
VECCOPY(ao, sample->ao);
|
VECCOPY(ao, sample->ao);
|
||||||
|
VECCOPY(env, sample->env);
|
||||||
VECCOPY(indirect, sample->indirect);
|
VECCOPY(indirect, sample->indirect);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1495,6 +1503,7 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int
|
|||||||
|
|
||||||
/* compute weighted interpolation between samples */
|
/* compute weighted interpolation between samples */
|
||||||
zero_v3(ao);
|
zero_v3(ao);
|
||||||
|
zero_v3(env);
|
||||||
zero_v3(indirect);
|
zero_v3(indirect);
|
||||||
totw= 0.0f;
|
totw= 0.0f;
|
||||||
|
|
||||||
@ -1522,12 +1531,14 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int
|
|||||||
|
|
||||||
totw += w;
|
totw += w;
|
||||||
madd_v3_v3fl(ao, samples[i]->ao, w);
|
madd_v3_v3fl(ao, samples[i]->ao, w);
|
||||||
|
madd_v3_v3fl(env, samples[i]->env, w);
|
||||||
madd_v3_v3fl(indirect, samples[i]->indirect, w);
|
madd_v3_v3fl(indirect, samples[i]->indirect, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(totw >= 0.9f) {
|
if(totw >= 0.9f) {
|
||||||
totw= 1.0f/totw;
|
totw= 1.0f/totw;
|
||||||
mul_v3_fl(ao, totw);
|
mul_v3_fl(ao, totw);
|
||||||
|
mul_v3_fl(env, totw);
|
||||||
mul_v3_fl(indirect, totw);
|
mul_v3_fl(indirect, totw);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1553,16 +1564,21 @@ static void sample_occ_surface(ShadeInput *shi)
|
|||||||
interp_weights_face_v3(w, co1, co2, co3, co4, strand->vert->co);
|
interp_weights_face_v3(w, co1, co2, co3, co4, strand->vert->co);
|
||||||
|
|
||||||
zero_v3(shi->ao);
|
zero_v3(shi->ao);
|
||||||
|
zero_v3(shi->env);
|
||||||
zero_v3(shi->indirect);
|
zero_v3(shi->indirect);
|
||||||
|
|
||||||
madd_v3_v3fl(shi->ao, mesh->ao[face[0]], w[0]);
|
madd_v3_v3fl(shi->ao, mesh->ao[face[0]], w[0]);
|
||||||
|
madd_v3_v3fl(shi->env, mesh->env[face[0]], w[0]);
|
||||||
madd_v3_v3fl(shi->indirect, mesh->indirect[face[0]], w[0]);
|
madd_v3_v3fl(shi->indirect, mesh->indirect[face[0]], w[0]);
|
||||||
madd_v3_v3fl(shi->ao, mesh->ao[face[1]], w[1]);
|
madd_v3_v3fl(shi->ao, mesh->ao[face[1]], w[1]);
|
||||||
|
madd_v3_v3fl(shi->env, mesh->env[face[1]], w[1]);
|
||||||
madd_v3_v3fl(shi->indirect, mesh->indirect[face[1]], w[1]);
|
madd_v3_v3fl(shi->indirect, mesh->indirect[face[1]], w[1]);
|
||||||
madd_v3_v3fl(shi->ao, mesh->ao[face[2]], w[2]);
|
madd_v3_v3fl(shi->ao, mesh->ao[face[2]], w[2]);
|
||||||
|
madd_v3_v3fl(shi->env, mesh->env[face[2]], w[2]);
|
||||||
madd_v3_v3fl(shi->indirect, mesh->indirect[face[2]], w[2]);
|
madd_v3_v3fl(shi->indirect, mesh->indirect[face[2]], w[2]);
|
||||||
if(face[3]) {
|
if(face[3]) {
|
||||||
madd_v3_v3fl(shi->ao, mesh->ao[face[3]], w[3]);
|
madd_v3_v3fl(shi->ao, mesh->ao[face[3]], w[3]);
|
||||||
|
madd_v3_v3fl(shi->env, mesh->env[face[3]], w[3]);
|
||||||
madd_v3_v3fl(shi->indirect, mesh->indirect[face[3]], w[3]);
|
madd_v3_v3fl(shi->indirect, mesh->indirect[face[3]], w[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1570,6 +1586,7 @@ static void sample_occ_surface(ShadeInput *shi)
|
|||||||
shi->ao[0]= 1.0f;
|
shi->ao[0]= 1.0f;
|
||||||
shi->ao[1]= 1.0f;
|
shi->ao[1]= 1.0f;
|
||||||
shi->ao[2]= 1.0f;
|
shi->ao[2]= 1.0f;
|
||||||
|
zero_v3(shi->env);
|
||||||
zero_v3(shi->indirect);
|
zero_v3(shi->indirect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1581,7 +1598,7 @@ static void *exec_strandsurface_sample(void *data)
|
|||||||
OcclusionThread *othread= (OcclusionThread*)data;
|
OcclusionThread *othread= (OcclusionThread*)data;
|
||||||
Render *re= othread->re;
|
Render *re= othread->re;
|
||||||
StrandSurface *mesh= othread->mesh;
|
StrandSurface *mesh= othread->mesh;
|
||||||
float ao[3], indirect[3], co[3], n[3], *co1, *co2, *co3, *co4;
|
float ao[3], env[3], indirect[3], co[3], n[3], *co1, *co2, *co3, *co4;
|
||||||
int a, *face;
|
int a, *face;
|
||||||
|
|
||||||
for(a=othread->begin; a<othread->end; a++) {
|
for(a=othread->begin; a<othread->end; a++) {
|
||||||
@ -1602,8 +1619,9 @@ static void *exec_strandsurface_sample(void *data)
|
|||||||
}
|
}
|
||||||
negate_v3(n);
|
negate_v3(n);
|
||||||
|
|
||||||
sample_occ_tree(re, re->occlusiontree, NULL, co, n, othread->thread, 0, ao, indirect);
|
sample_occ_tree(re, re->occlusiontree, NULL, co, n, othread->thread, 0, ao, env, indirect);
|
||||||
VECCOPY(othread->faceao[a], ao);
|
VECCOPY(othread->faceao[a], ao);
|
||||||
|
VECCOPY(othread->faceenv[a], env);
|
||||||
VECCOPY(othread->faceindirect[a], indirect);
|
VECCOPY(othread->faceindirect[a], indirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1616,7 +1634,7 @@ void make_occ_tree(Render *re)
|
|||||||
OcclusionTree *tree;
|
OcclusionTree *tree;
|
||||||
StrandSurface *mesh;
|
StrandSurface *mesh;
|
||||||
ListBase threads;
|
ListBase threads;
|
||||||
float ao[3], indirect[3], (*faceao)[3], (*faceindirect)[3];
|
float ao[3], env[3], indirect[3], (*faceao)[3], (*faceenv)[3], (*faceindirect)[3];
|
||||||
int a, totface, totthread, *face, *count;
|
int a, totface, totthread, *face, *count;
|
||||||
|
|
||||||
/* ugly, needed for occ_face */
|
/* ugly, needed for occ_face */
|
||||||
@ -1630,7 +1648,7 @@ void make_occ_tree(Render *re)
|
|||||||
if(tree) {
|
if(tree) {
|
||||||
if(re->wrld.ao_approx_passes > 0)
|
if(re->wrld.ao_approx_passes > 0)
|
||||||
occ_compute_passes(re, tree, re->wrld.ao_approx_passes);
|
occ_compute_passes(re, tree, re->wrld.ao_approx_passes);
|
||||||
if(tree->doindirect && re->wrld.ao_indirect_bounces > 1)
|
if(tree->doindirect && (re->wrld.mode & WO_INDIRECT_LIGHT))
|
||||||
occ_compute_bounces(re, tree, re->wrld.ao_indirect_bounces);
|
occ_compute_bounces(re, tree, re->wrld.ao_indirect_bounces);
|
||||||
|
|
||||||
for(mesh=re->strandsurface.first; mesh; mesh=mesh->next) {
|
for(mesh=re->strandsurface.first; mesh; mesh=mesh->next) {
|
||||||
@ -1639,6 +1657,7 @@ void make_occ_tree(Render *re)
|
|||||||
|
|
||||||
count= MEM_callocN(sizeof(int)*mesh->totvert, "OcclusionCount");
|
count= MEM_callocN(sizeof(int)*mesh->totvert, "OcclusionCount");
|
||||||
faceao= MEM_callocN(sizeof(float)*3*mesh->totface, "StrandSurfFaceAO");
|
faceao= MEM_callocN(sizeof(float)*3*mesh->totface, "StrandSurfFaceAO");
|
||||||
|
faceenv= MEM_callocN(sizeof(float)*3*mesh->totface, "StrandSurfFaceEnv");
|
||||||
faceindirect= MEM_callocN(sizeof(float)*3*mesh->totface, "StrandSurfFaceIndirect");
|
faceindirect= MEM_callocN(sizeof(float)*3*mesh->totface, "StrandSurfFaceIndirect");
|
||||||
|
|
||||||
totthread= (mesh->totface > 10000)? re->r.threads: 1;
|
totthread= (mesh->totface > 10000)? re->r.threads: 1;
|
||||||
@ -1646,6 +1665,7 @@ void make_occ_tree(Render *re)
|
|||||||
for(a=0; a<totthread; a++) {
|
for(a=0; a<totthread; a++) {
|
||||||
othreads[a].re= re;
|
othreads[a].re= re;
|
||||||
othreads[a].faceao= faceao;
|
othreads[a].faceao= faceao;
|
||||||
|
othreads[a].faceenv= faceenv;
|
||||||
othreads[a].faceindirect= faceindirect;
|
othreads[a].faceindirect= faceindirect;
|
||||||
othreads[a].thread= a;
|
othreads[a].thread= a;
|
||||||
othreads[a].mesh= mesh;
|
othreads[a].mesh= mesh;
|
||||||
@ -1669,20 +1689,25 @@ void make_occ_tree(Render *re)
|
|||||||
face= mesh->face[a];
|
face= mesh->face[a];
|
||||||
|
|
||||||
VECCOPY(ao, faceao[a]);
|
VECCOPY(ao, faceao[a]);
|
||||||
|
VECCOPY(env, faceenv[a]);
|
||||||
VECCOPY(indirect, faceindirect[a]);
|
VECCOPY(indirect, faceindirect[a]);
|
||||||
|
|
||||||
VECADD(mesh->ao[face[0]], mesh->ao[face[0]], ao);
|
VECADD(mesh->ao[face[0]], mesh->ao[face[0]], ao);
|
||||||
|
VECADD(mesh->env[face[0]], mesh->env[face[0]], env);
|
||||||
VECADD(mesh->indirect[face[0]], mesh->indirect[face[0]], indirect);
|
VECADD(mesh->indirect[face[0]], mesh->indirect[face[0]], indirect);
|
||||||
count[face[0]]++;
|
count[face[0]]++;
|
||||||
VECADD(mesh->ao[face[1]], mesh->ao[face[1]], ao);
|
VECADD(mesh->ao[face[1]], mesh->ao[face[1]], ao);
|
||||||
|
VECADD(mesh->env[face[1]], mesh->env[face[1]], env);
|
||||||
VECADD(mesh->indirect[face[1]], mesh->indirect[face[1]], indirect);
|
VECADD(mesh->indirect[face[1]], mesh->indirect[face[1]], indirect);
|
||||||
count[face[1]]++;
|
count[face[1]]++;
|
||||||
VECADD(mesh->ao[face[2]], mesh->ao[face[2]], ao);
|
VECADD(mesh->ao[face[2]], mesh->ao[face[2]], ao);
|
||||||
|
VECADD(mesh->env[face[2]], mesh->env[face[2]], env);
|
||||||
VECADD(mesh->indirect[face[2]], mesh->indirect[face[2]], indirect);
|
VECADD(mesh->indirect[face[2]], mesh->indirect[face[2]], indirect);
|
||||||
count[face[2]]++;
|
count[face[2]]++;
|
||||||
|
|
||||||
if(face[3]) {
|
if(face[3]) {
|
||||||
VECADD(mesh->ao[face[3]], mesh->ao[face[3]], ao);
|
VECADD(mesh->ao[face[3]], mesh->ao[face[3]], ao);
|
||||||
|
VECADD(mesh->env[face[3]], mesh->env[face[3]], env);
|
||||||
VECADD(mesh->indirect[face[3]], mesh->indirect[face[3]], indirect);
|
VECADD(mesh->indirect[face[3]], mesh->indirect[face[3]], indirect);
|
||||||
count[face[3]]++;
|
count[face[3]]++;
|
||||||
}
|
}
|
||||||
@ -1691,12 +1716,14 @@ void make_occ_tree(Render *re)
|
|||||||
for(a=0; a<mesh->totvert; a++) {
|
for(a=0; a<mesh->totvert; a++) {
|
||||||
if(count[a]) {
|
if(count[a]) {
|
||||||
mul_v3_fl(mesh->ao[a], 1.0f/count[a]);
|
mul_v3_fl(mesh->ao[a], 1.0f/count[a]);
|
||||||
|
mul_v3_fl(mesh->env[a], 1.0f/count[a]);
|
||||||
mul_v3_fl(mesh->indirect[a], 1.0f/count[a]);
|
mul_v3_fl(mesh->indirect[a], 1.0f/count[a]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(count);
|
MEM_freeN(count);
|
||||||
MEM_freeN(faceao);
|
MEM_freeN(faceao);
|
||||||
|
MEM_freeN(faceenv);
|
||||||
MEM_freeN(faceindirect);
|
MEM_freeN(faceindirect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1723,12 +1750,12 @@ void sample_occ(Render *re, ShadeInput *shi)
|
|||||||
sample_occ_surface(shi);
|
sample_occ_surface(shi);
|
||||||
}
|
}
|
||||||
/* try to get result from the cache if possible */
|
/* try to get result from the cache if possible */
|
||||||
else if(shi->depth!=0 || !sample_occ_cache(tree, shi->co, shi->vno, shi->xs, shi->ys, shi->thread, shi->ao, shi->indirect)) {
|
else if(shi->depth!=0 || !sample_occ_cache(tree, shi->co, shi->vno, shi->xs, shi->ys, shi->thread, shi->ao, shi->env, shi->indirect)) {
|
||||||
/* no luck, let's sample the occlusion */
|
/* no luck, let's sample the occlusion */
|
||||||
exclude.obi= shi->obi - re->objectinstance;
|
exclude.obi= shi->obi - re->objectinstance;
|
||||||
exclude.facenr= shi->vlr->index;
|
exclude.facenr= shi->vlr->index;
|
||||||
onlyshadow= (shi->mat->mode & MA_ONLYSHADOW);
|
onlyshadow= (shi->mat->mode & MA_ONLYSHADOW);
|
||||||
sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao, shi->indirect);
|
sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao, shi->env, shi->indirect);
|
||||||
|
|
||||||
/* fill result into sample, each time */
|
/* fill result into sample, each time */
|
||||||
if(tree->cache) {
|
if(tree->cache) {
|
||||||
@ -1739,8 +1766,10 @@ void sample_occ(Render *re, ShadeInput *shi)
|
|||||||
VECCOPY(sample->co, shi->co);
|
VECCOPY(sample->co, shi->co);
|
||||||
VECCOPY(sample->n, shi->vno);
|
VECCOPY(sample->n, shi->vno);
|
||||||
VECCOPY(sample->ao, shi->ao);
|
VECCOPY(sample->ao, shi->ao);
|
||||||
|
VECCOPY(sample->env, shi->env);
|
||||||
VECCOPY(sample->indirect, shi->indirect);
|
VECCOPY(sample->indirect, shi->indirect);
|
||||||
sample->intensity= MAX3(sample->ao[0], sample->ao[1], sample->ao[2]);
|
sample->intensity= MAX3(sample->ao[0], sample->ao[1], sample->ao[2]);
|
||||||
|
sample->intensity= MAX2(sample->intensity, MAX3(sample->env[0], sample->env[1], sample->env[2]));
|
||||||
sample->intensity= MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
|
sample->intensity= MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
|
||||||
sample->dist2= INPR(shi->dxco, shi->dxco) + INPR(shi->dyco, shi->dyco);
|
sample->dist2= INPR(shi->dxco, shi->dxco) + INPR(shi->dyco, shi->dyco);
|
||||||
sample->filled= 1;
|
sample->filled= 1;
|
||||||
@ -1753,6 +1782,10 @@ void sample_occ(Render *re, ShadeInput *shi)
|
|||||||
shi->ao[1]= 1.0f;
|
shi->ao[1]= 1.0f;
|
||||||
shi->ao[2]= 1.0f;
|
shi->ao[2]= 1.0f;
|
||||||
|
|
||||||
|
shi->env[0]= 0.0f;
|
||||||
|
shi->env[1]= 0.0f;
|
||||||
|
shi->env[2]= 0.0f;
|
||||||
|
|
||||||
shi->indirect[0]= 0.0f;
|
shi->indirect[0]= 0.0f;
|
||||||
shi->indirect[1]= 0.0f;
|
shi->indirect[1]= 0.0f;
|
||||||
shi->indirect[2]= 0.0f;
|
shi->indirect[2]= 0.0f;
|
||||||
@ -1823,13 +1856,15 @@ void cache_occ_samples(Render *re, RenderPart *pa, ShadeSample *ssamp)
|
|||||||
onlyshadow= (shi->mat->mode & MA_ONLYSHADOW);
|
onlyshadow= (shi->mat->mode & MA_ONLYSHADOW);
|
||||||
exclude.obi= shi->obi - re->objectinstance;
|
exclude.obi= shi->obi - re->objectinstance;
|
||||||
exclude.facenr= shi->vlr->index;
|
exclude.facenr= shi->vlr->index;
|
||||||
sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao, shi->indirect);
|
sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao, shi->env, shi->indirect);
|
||||||
|
|
||||||
VECCOPY(sample->co, shi->co);
|
VECCOPY(sample->co, shi->co);
|
||||||
VECCOPY(sample->n, shi->vno);
|
VECCOPY(sample->n, shi->vno);
|
||||||
VECCOPY(sample->ao, shi->ao);
|
VECCOPY(sample->ao, shi->ao);
|
||||||
|
VECCOPY(sample->env, shi->env);
|
||||||
VECCOPY(sample->indirect, shi->indirect);
|
VECCOPY(sample->indirect, shi->indirect);
|
||||||
sample->intensity= MAX3(sample->ao[0], sample->ao[1], sample->ao[2]);
|
sample->intensity= MAX3(sample->ao[0], sample->ao[1], sample->ao[2]);
|
||||||
|
sample->intensity= MAX2(sample->intensity, MAX3(sample->env[0], sample->env[1], sample->env[2]));
|
||||||
sample->intensity= MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
|
sample->intensity= MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
|
||||||
sample->dist2= INPR(shi->dxco, shi->dxco) + INPR(shi->dyco, shi->dyco);
|
sample->dist2= INPR(shi->dxco, shi->dxco) + INPR(shi->dyco, shi->dyco);
|
||||||
sample->x= shi->xs;
|
sample->x= shi->xs;
|
||||||
|
@ -309,6 +309,12 @@ static char *get_pass_name(int passtype, int channel)
|
|||||||
if(channel==2) return "Color.B";
|
if(channel==2) return "Color.B";
|
||||||
return "Color.A";
|
return "Color.A";
|
||||||
}
|
}
|
||||||
|
if(passtype == SCE_PASS_EMIT) {
|
||||||
|
if(channel==-1) return "Emit";
|
||||||
|
if(channel==0) return "Emit.R";
|
||||||
|
if(channel==1) return "Emit.G";
|
||||||
|
return "Emit.B";
|
||||||
|
}
|
||||||
if(passtype == SCE_PASS_DIFFUSE) {
|
if(passtype == SCE_PASS_DIFFUSE) {
|
||||||
if(channel==-1) return "Diffuse";
|
if(channel==-1) return "Diffuse";
|
||||||
if(channel==0) return "Diffuse.R";
|
if(channel==0) return "Diffuse.R";
|
||||||
@ -333,6 +339,18 @@ static char *get_pass_name(int passtype, int channel)
|
|||||||
if(channel==1) return "AO.G";
|
if(channel==1) return "AO.G";
|
||||||
return "AO.B";
|
return "AO.B";
|
||||||
}
|
}
|
||||||
|
if(passtype == SCE_PASS_ENVIRONMENT) {
|
||||||
|
if(channel==-1) return "Environment";
|
||||||
|
if(channel==0) return "Environment.R";
|
||||||
|
if(channel==1) return "Environment.G";
|
||||||
|
return "Environment.B";
|
||||||
|
}
|
||||||
|
if(passtype == SCE_PASS_INDIRECT) {
|
||||||
|
if(channel==-1) return "Indirect";
|
||||||
|
if(channel==0) return "Indirect.R";
|
||||||
|
if(channel==1) return "Indirect.G";
|
||||||
|
return "Indirect.B";
|
||||||
|
}
|
||||||
if(passtype == SCE_PASS_REFLECT) {
|
if(passtype == SCE_PASS_REFLECT) {
|
||||||
if(channel==-1) return "Reflect";
|
if(channel==-1) return "Reflect";
|
||||||
if(channel==0) return "Reflect.R";
|
if(channel==0) return "Reflect.R";
|
||||||
@ -390,6 +408,9 @@ static int passtype_from_name(char *str)
|
|||||||
if(strcmp(str, "Color")==0)
|
if(strcmp(str, "Color")==0)
|
||||||
return SCE_PASS_RGBA;
|
return SCE_PASS_RGBA;
|
||||||
|
|
||||||
|
if(strcmp(str, "Emit")==0)
|
||||||
|
return SCE_PASS_EMIT;
|
||||||
|
|
||||||
if(strcmp(str, "Diffuse")==0)
|
if(strcmp(str, "Diffuse")==0)
|
||||||
return SCE_PASS_DIFFUSE;
|
return SCE_PASS_DIFFUSE;
|
||||||
|
|
||||||
@ -402,6 +423,12 @@ static int passtype_from_name(char *str)
|
|||||||
if(strcmp(str, "AO")==0)
|
if(strcmp(str, "AO")==0)
|
||||||
return SCE_PASS_AO;
|
return SCE_PASS_AO;
|
||||||
|
|
||||||
|
if(strcmp(str, "Environment")==0)
|
||||||
|
return SCE_PASS_ENVIRONMENT;
|
||||||
|
|
||||||
|
if(strcmp(str, "Indirect")==0)
|
||||||
|
return SCE_PASS_INDIRECT;
|
||||||
|
|
||||||
if(strcmp(str, "Reflect")==0)
|
if(strcmp(str, "Reflect")==0)
|
||||||
return SCE_PASS_REFLECT;
|
return SCE_PASS_REFLECT;
|
||||||
|
|
||||||
@ -572,12 +599,18 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int
|
|||||||
render_layer_add_pass(rr, rl, 3, SCE_PASS_UV);
|
render_layer_add_pass(rr, rl, 3, SCE_PASS_UV);
|
||||||
if(srl->passflag & SCE_PASS_RGBA)
|
if(srl->passflag & SCE_PASS_RGBA)
|
||||||
render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA);
|
render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA);
|
||||||
|
if(srl->passflag & SCE_PASS_EMIT)
|
||||||
|
render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT);
|
||||||
if(srl->passflag & SCE_PASS_DIFFUSE)
|
if(srl->passflag & SCE_PASS_DIFFUSE)
|
||||||
render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE);
|
render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE);
|
||||||
if(srl->passflag & SCE_PASS_SPEC)
|
if(srl->passflag & SCE_PASS_SPEC)
|
||||||
render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC);
|
render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC);
|
||||||
if(srl->passflag & SCE_PASS_AO)
|
if(srl->passflag & SCE_PASS_AO)
|
||||||
render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);
|
render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);
|
||||||
|
if(srl->passflag & SCE_PASS_ENVIRONMENT)
|
||||||
|
render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT);
|
||||||
|
if(srl->passflag & SCE_PASS_INDIRECT)
|
||||||
|
render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT);
|
||||||
if(srl->passflag & SCE_PASS_SHADOW)
|
if(srl->passflag & SCE_PASS_SHADOW)
|
||||||
render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW);
|
render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW);
|
||||||
if(srl->passflag & SCE_PASS_REFLECT)
|
if(srl->passflag & SCE_PASS_REFLECT)
|
||||||
|
@ -1829,7 +1829,7 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
|
static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env)
|
||||||
{
|
{
|
||||||
Isect isec;
|
Isect isec;
|
||||||
RayHint point_hint;
|
RayHint point_hint;
|
||||||
@ -1845,8 +1845,8 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
|
|||||||
int samples=0;
|
int samples=0;
|
||||||
int max_samples = R.wrld.aosamp*R.wrld.aosamp;
|
int max_samples = R.wrld.aosamp*R.wrld.aosamp;
|
||||||
|
|
||||||
float dxyview[3], skyadded=0, div;
|
float dxyview[3], skyadded=0;
|
||||||
int aocolor;
|
int envcolor;
|
||||||
|
|
||||||
RE_RC_INIT(isec, *shi);
|
RE_RC_INIT(isec, *shi);
|
||||||
isec.orig.ob = shi->obi;
|
isec.orig.ob = shi->obi;
|
||||||
@ -1866,15 +1866,15 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
|
|||||||
RE_rayobject_hint_bb( R.raytree, &point_hint, isec.start, isec.start );
|
RE_rayobject_hint_bb( R.raytree, &point_hint, isec.start, isec.start );
|
||||||
isec.hint = &point_hint;
|
isec.hint = &point_hint;
|
||||||
|
|
||||||
|
zero_v3(ao);
|
||||||
shadfac[0]= shadfac[1]= shadfac[2]= 0.0f;
|
zero_v3(env);
|
||||||
|
|
||||||
/* prevent sky colors to be added for only shadow (shadow becomes alpha) */
|
/* prevent sky colors to be added for only shadow (shadow becomes alpha) */
|
||||||
aocolor= R.wrld.aocolor;
|
envcolor= R.wrld.aocolor;
|
||||||
if(shi->mat->mode & MA_ONLYSHADOW)
|
if(shi->mat->mode & MA_ONLYSHADOW)
|
||||||
aocolor= WO_AOPLAIN;
|
envcolor= WO_AOPLAIN;
|
||||||
|
|
||||||
if(aocolor == WO_AOSKYTEX) {
|
if(envcolor == WO_AOSKYTEX) {
|
||||||
dxyview[0]= 1.0f/(float)R.wrld.aosamp;
|
dxyview[0]= 1.0f/(float)R.wrld.aosamp;
|
||||||
dxyview[1]= 1.0f/(float)R.wrld.aosamp;
|
dxyview[1]= 1.0f/(float)R.wrld.aosamp;
|
||||||
dxyview[2]= 0.0f;
|
dxyview[2]= 0.0f;
|
||||||
@ -1927,7 +1927,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
|
|||||||
if (R.wrld.aomode & WO_AODIST) fac+= exp(-isec.labda*R.wrld.aodistfac);
|
if (R.wrld.aomode & WO_AODIST) fac+= exp(-isec.labda*R.wrld.aodistfac);
|
||||||
else fac+= 1.0f;
|
else fac+= 1.0f;
|
||||||
}
|
}
|
||||||
else if(aocolor!=WO_AOPLAIN) {
|
else if(envcolor!=WO_AOPLAIN) {
|
||||||
float skycol[4];
|
float skycol[4];
|
||||||
float skyfac, view[3];
|
float skyfac, view[3];
|
||||||
|
|
||||||
@ -1936,18 +1936,18 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
|
|||||||
view[2]= -dir[2];
|
view[2]= -dir[2];
|
||||||
normalize_v3(view);
|
normalize_v3(view);
|
||||||
|
|
||||||
if(aocolor==WO_AOSKYCOL) {
|
if(envcolor==WO_AOSKYCOL) {
|
||||||
skyfac= 0.5*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);
|
skyfac= 0.5*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);
|
||||||
shadfac[0]+= (1.0f-skyfac)*R.wrld.horr + skyfac*R.wrld.zenr;
|
env[0]+= (1.0f-skyfac)*R.wrld.horr + skyfac*R.wrld.zenr;
|
||||||
shadfac[1]+= (1.0f-skyfac)*R.wrld.horg + skyfac*R.wrld.zeng;
|
env[1]+= (1.0f-skyfac)*R.wrld.horg + skyfac*R.wrld.zeng;
|
||||||
shadfac[2]+= (1.0f-skyfac)*R.wrld.horb + skyfac*R.wrld.zenb;
|
env[2]+= (1.0f-skyfac)*R.wrld.horb + skyfac*R.wrld.zenb;
|
||||||
}
|
}
|
||||||
else { /* WO_AOSKYTEX */
|
else { /* WO_AOSKYTEX */
|
||||||
shadeSkyView(skycol, isec.start, view, dxyview, shi->thread);
|
shadeSkyView(skycol, isec.start, view, dxyview, shi->thread);
|
||||||
shadeSunView(skycol, shi->view);
|
shadeSunView(skycol, shi->view);
|
||||||
shadfac[0]+= skycol[0];
|
env[0]+= skycol[0];
|
||||||
shadfac[1]+= skycol[1];
|
env[1]+= skycol[1];
|
||||||
shadfac[2]+= skycol[2];
|
env[2]+= skycol[2];
|
||||||
}
|
}
|
||||||
skyadded++;
|
skyadded++;
|
||||||
}
|
}
|
||||||
@ -1965,29 +1965,27 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(aocolor!=WO_AOPLAIN && skyadded) {
|
/* average color times distances/hits formula */
|
||||||
div= (1.0f - fac/(float)samples)/((float)skyadded);
|
ao[0]= ao[1]= ao[2]= 1.0f - fac/(float)samples;
|
||||||
|
|
||||||
shadfac[0]*= div; // average color times distances/hits formula
|
if(envcolor!=WO_AOPLAIN && skyadded)
|
||||||
shadfac[1]*= div; // average color times distances/hits formula
|
mul_v3_fl(env, (1.0f - fac/(float)samples)/((float)skyadded));
|
||||||
shadfac[2]*= div; // average color times distances/hits formula
|
else
|
||||||
} else {
|
copy_v3_v3(env, ao);
|
||||||
shadfac[0]= shadfac[1]= shadfac[2]= 1.0f - fac/(float)samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qsa)
|
if (qsa)
|
||||||
release_thread_qmcsampler(&R, shi->thread, qsa);
|
release_thread_qmcsampler(&R, shi->thread, qsa);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extern call from shade_lamp_loop, ambient occlusion calculus */
|
/* extern call from shade_lamp_loop, ambient occlusion calculus */
|
||||||
static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
|
static void ray_ao_spheresamp(ShadeInput *shi, float *ao, float *env)
|
||||||
{
|
{
|
||||||
Isect isec;
|
Isect isec;
|
||||||
RayHint point_hint;
|
RayHint point_hint;
|
||||||
float *vec, *nrm, div, bias, sh=0.0f;
|
float *vec, *nrm, bias, sh=0.0f;
|
||||||
float maxdist = R.wrld.aodist;
|
float maxdist = R.wrld.aodist;
|
||||||
float dxyview[3];
|
float dxyview[3];
|
||||||
int j= -1, tot, actual=0, skyadded=0, aocolor, resol= R.wrld.aosamp;
|
int j= -1, tot, actual=0, skyadded=0, envcolor, resol= R.wrld.aosamp;
|
||||||
|
|
||||||
RE_RC_INIT(isec, *shi);
|
RE_RC_INIT(isec, *shi);
|
||||||
isec.orig.ob = shi->obi;
|
isec.orig.ob = shi->obi;
|
||||||
@ -2007,7 +2005,8 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
|
|||||||
RE_rayobject_hint_bb( R.raytree, &point_hint, isec.start, isec.start );
|
RE_rayobject_hint_bb( R.raytree, &point_hint, isec.start, isec.start );
|
||||||
isec.hint = &point_hint;
|
isec.hint = &point_hint;
|
||||||
|
|
||||||
shadfac[0]= shadfac[1]= shadfac[2]= 0.0f;
|
zero_v3(ao);
|
||||||
|
zero_v3(env);
|
||||||
|
|
||||||
/* bias prevents smoothed faces to appear flat */
|
/* bias prevents smoothed faces to appear flat */
|
||||||
if(shi->vlr->flag & R_SMOOTH) {
|
if(shi->vlr->flag & R_SMOOTH) {
|
||||||
@ -2020,9 +2019,9 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* prevent sky colors to be added for only shadow (shadow becomes alpha) */
|
/* prevent sky colors to be added for only shadow (shadow becomes alpha) */
|
||||||
aocolor= R.wrld.aocolor;
|
envcolor= R.wrld.aocolor;
|
||||||
if(shi->mat->mode & MA_ONLYSHADOW)
|
if(shi->mat->mode & MA_ONLYSHADOW)
|
||||||
aocolor= WO_AOPLAIN;
|
envcolor= WO_AOPLAIN;
|
||||||
|
|
||||||
if(resol>32) resol= 32;
|
if(resol>32) resol= 32;
|
||||||
|
|
||||||
@ -2031,7 +2030,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
|
|||||||
// warning: since we use full sphere now, and dotproduct is below, we do twice as much
|
// warning: since we use full sphere now, and dotproduct is below, we do twice as much
|
||||||
tot= 2*resol*resol;
|
tot= 2*resol*resol;
|
||||||
|
|
||||||
if(aocolor == WO_AOSKYTEX) {
|
if(envcolor == WO_AOSKYTEX) {
|
||||||
dxyview[0]= 1.0f/(float)resol;
|
dxyview[0]= 1.0f/(float)resol;
|
||||||
dxyview[1]= 1.0f/(float)resol;
|
dxyview[1]= 1.0f/(float)resol;
|
||||||
dxyview[2]= 0.0f;
|
dxyview[2]= 0.0f;
|
||||||
@ -2063,7 +2062,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
|
|||||||
if (R.wrld.aomode & WO_AODIST) sh+= exp(-isec.labda*R.wrld.aodistfac);
|
if (R.wrld.aomode & WO_AODIST) sh+= exp(-isec.labda*R.wrld.aodistfac);
|
||||||
else sh+= 1.0f;
|
else sh+= 1.0f;
|
||||||
}
|
}
|
||||||
else if(aocolor!=WO_AOPLAIN) {
|
else if(envcolor!=WO_AOPLAIN) {
|
||||||
float skycol[4];
|
float skycol[4];
|
||||||
float fac, view[3];
|
float fac, view[3];
|
||||||
|
|
||||||
@ -2072,18 +2071,18 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
|
|||||||
view[2]= -vec[2];
|
view[2]= -vec[2];
|
||||||
normalize_v3(view);
|
normalize_v3(view);
|
||||||
|
|
||||||
if(aocolor==WO_AOSKYCOL) {
|
if(envcolor==WO_AOSKYCOL) {
|
||||||
fac= 0.5*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);
|
fac= 0.5*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);
|
||||||
shadfac[0]+= (1.0f-fac)*R.wrld.horr + fac*R.wrld.zenr;
|
env[0]+= (1.0f-fac)*R.wrld.horr + fac*R.wrld.zenr;
|
||||||
shadfac[1]+= (1.0f-fac)*R.wrld.horg + fac*R.wrld.zeng;
|
env[1]+= (1.0f-fac)*R.wrld.horg + fac*R.wrld.zeng;
|
||||||
shadfac[2]+= (1.0f-fac)*R.wrld.horb + fac*R.wrld.zenb;
|
env[2]+= (1.0f-fac)*R.wrld.horb + fac*R.wrld.zenb;
|
||||||
}
|
}
|
||||||
else { /* WO_AOSKYTEX */
|
else { /* WO_AOSKYTEX */
|
||||||
shadeSkyView(skycol, isec.start, view, dxyview, shi->thread);
|
shadeSkyView(skycol, isec.start, view, dxyview, shi->thread);
|
||||||
shadeSunView(skycol, shi->view);
|
shadeSunView(skycol, shi->view);
|
||||||
shadfac[0]+= skycol[0];
|
env[0]+= skycol[0];
|
||||||
shadfac[1]+= skycol[1];
|
env[1]+= skycol[1];
|
||||||
shadfac[2]+= skycol[2];
|
env[2]+= skycol[2];
|
||||||
}
|
}
|
||||||
skyadded++;
|
skyadded++;
|
||||||
}
|
}
|
||||||
@ -2095,28 +2094,25 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
|
|||||||
if(actual==0) sh= 1.0f;
|
if(actual==0) sh= 1.0f;
|
||||||
else sh = 1.0f - sh/((float)actual);
|
else sh = 1.0f - sh/((float)actual);
|
||||||
|
|
||||||
if(aocolor!=WO_AOPLAIN && skyadded) {
|
/* average color times distances/hits formula */
|
||||||
div= sh/((float)skyadded);
|
ao[0]= ao[1]= ao[2]= sh;
|
||||||
|
|
||||||
shadfac[0]*= div; // average color times distances/hits formula
|
if(envcolor!=WO_AOPLAIN && skyadded)
|
||||||
shadfac[1]*= div; // average color times distances/hits formula
|
mul_v3_fl(env, sh/((float)skyadded));
|
||||||
shadfac[2]*= div; // average color times distances/hits formula
|
else
|
||||||
}
|
copy_v3_v3(env, ao);
|
||||||
else {
|
|
||||||
shadfac[0]= shadfac[1]= shadfac[2]= sh;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ray_ao(ShadeInput *shi, float *shadfac)
|
void ray_ao(ShadeInput *shi, float *ao, float *env)
|
||||||
{
|
{
|
||||||
/* Unfortunately, the unusual way that the sphere sampler calculates roughly twice as many
|
/* Unfortunately, the unusual way that the sphere sampler calculates roughly twice as many
|
||||||
* samples as are actually traced, and skips them based on bias and OSA settings makes it very difficult
|
* samples as are actually traced, and skips them based on bias and OSA settings makes it very difficult
|
||||||
* to reuse code between these two functions. This is the easiest way I can think of to do it
|
* to reuse code between these two functions. This is the easiest way I can think of to do it
|
||||||
* --broken */
|
* --broken */
|
||||||
if (ELEM(R.wrld.ao_samp_method, WO_AOSAMP_HAMMERSLEY, WO_AOSAMP_HALTON))
|
if (ELEM(R.wrld.ao_samp_method, WO_AOSAMP_HAMMERSLEY, WO_AOSAMP_HALTON))
|
||||||
ray_ao_qmc(shi, shadfac);
|
ray_ao_qmc(shi, ao, env);
|
||||||
else if (R.wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
|
else if (R.wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
|
||||||
ray_ao_spheresamp(shi, shadfac);
|
ray_ao_spheresamp(shi, ao, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ray_shadow_jittered_coords(ShadeInput *shi, int max, float jitco[RE_MAX_OSA][3], int *totjitco)
|
static void ray_shadow_jittered_coords(ShadeInput *shi, int max, float jitco[RE_MAX_OSA][3], int *totjitco)
|
||||||
|
@ -459,6 +459,9 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset,
|
|||||||
col= shr->col;
|
col= shr->col;
|
||||||
pixsize= 4;
|
pixsize= 4;
|
||||||
break;
|
break;
|
||||||
|
case SCE_PASS_EMIT:
|
||||||
|
col= shr->emit;
|
||||||
|
break;
|
||||||
case SCE_PASS_DIFFUSE:
|
case SCE_PASS_DIFFUSE:
|
||||||
col= shr->diff;
|
col= shr->diff;
|
||||||
break;
|
break;
|
||||||
@ -471,6 +474,12 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset,
|
|||||||
case SCE_PASS_AO:
|
case SCE_PASS_AO:
|
||||||
col= shr->ao;
|
col= shr->ao;
|
||||||
break;
|
break;
|
||||||
|
case SCE_PASS_ENVIRONMENT:
|
||||||
|
col= shr->env;
|
||||||
|
break;
|
||||||
|
case SCE_PASS_INDIRECT:
|
||||||
|
col= shr->indirect;
|
||||||
|
break;
|
||||||
case SCE_PASS_REFLECT:
|
case SCE_PASS_REFLECT:
|
||||||
col= shr->refl;
|
col= shr->refl;
|
||||||
break;
|
break;
|
||||||
@ -557,6 +566,9 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult
|
|||||||
col= shr->col;
|
col= shr->col;
|
||||||
pixsize= 4;
|
pixsize= 4;
|
||||||
break;
|
break;
|
||||||
|
case SCE_PASS_EMIT:
|
||||||
|
col= shr->emit;
|
||||||
|
break;
|
||||||
case SCE_PASS_DIFFUSE:
|
case SCE_PASS_DIFFUSE:
|
||||||
col= shr->diff;
|
col= shr->diff;
|
||||||
break;
|
break;
|
||||||
@ -569,6 +581,12 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult
|
|||||||
case SCE_PASS_AO:
|
case SCE_PASS_AO:
|
||||||
col= shr->ao;
|
col= shr->ao;
|
||||||
break;
|
break;
|
||||||
|
case SCE_PASS_ENVIRONMENT:
|
||||||
|
col= shr->env;
|
||||||
|
break;
|
||||||
|
case SCE_PASS_INDIRECT:
|
||||||
|
col= shr->indirect;
|
||||||
|
break;
|
||||||
case SCE_PASS_REFLECT:
|
case SCE_PASS_REFLECT:
|
||||||
col= shr->refl;
|
col= shr->refl;
|
||||||
break;
|
break;
|
||||||
@ -2117,10 +2135,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int
|
|||||||
if(bs->type==RE_BAKE_AO) {
|
if(bs->type==RE_BAKE_AO) {
|
||||||
ambient_occlusion(shi);
|
ambient_occlusion(shi);
|
||||||
|
|
||||||
if(R.r.bake_flag & R_BAKE_NORMALIZE)
|
VECCOPY(shr.combined, shi->ao)
|
||||||
VECCOPY(shr.combined, shi->ao)
|
|
||||||
else
|
|
||||||
ambient_occlusion_to_diffuse(shi, shr.combined);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (bs->type==RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */
|
if (bs->type==RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */
|
||||||
|
@ -1319,11 +1319,11 @@ void shade_samples_do_AO(ShadeSample *ssamp)
|
|||||||
if(!(R.r.mode & R_RAYTRACE) && !(R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
|
if(!(R.r.mode & R_RAYTRACE) && !(R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(R.wrld.mode & WO_AMB_OCC) {
|
if(R.wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) {
|
||||||
shi= &ssamp->shi[0];
|
shi= &ssamp->shi[0];
|
||||||
|
|
||||||
if(((shi->passflag & SCE_PASS_COMBINED) && (shi->combinedflag & SCE_PASS_AO))
|
if(((shi->passflag & SCE_PASS_COMBINED) && (shi->combinedflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT)))
|
||||||
|| (shi->passflag & SCE_PASS_AO))
|
|| (shi->passflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT)))
|
||||||
for(sample=0, shi= ssamp->shi; sample<ssamp->tot; shi++, sample++)
|
for(sample=0, shi= ssamp->shi; sample<ssamp->tot; shi++, sample++)
|
||||||
if(!(shi->mode & MA_SHLESS))
|
if(!(shi->mode & MA_SHLESS))
|
||||||
ambient_occlusion(shi); /* stores in shi->ao[] */
|
ambient_occlusion(shi); /* stores in shi->ao[] */
|
||||||
|
@ -1013,41 +1013,69 @@ void ambient_occlusion(ShadeInput *shi)
|
|||||||
if((R.wrld.ao_gather_method == WO_AOGATHER_APPROX) && shi->mat->amb!=0.0f)
|
if((R.wrld.ao_gather_method == WO_AOGATHER_APPROX) && shi->mat->amb!=0.0f)
|
||||||
sample_occ(&R, shi);
|
sample_occ(&R, shi);
|
||||||
else if((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f)
|
else if((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f)
|
||||||
ray_ao(shi, shi->ao);
|
ray_ao(shi, shi->ao, shi->env);
|
||||||
else
|
else
|
||||||
shi->ao[0]= shi->ao[1]= shi->ao[2]= 1.0f;
|
shi->ao[0]= shi->ao[1]= shi->ao[2]= 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* wrld mode was checked for */
|
/* wrld mode was checked for */
|
||||||
void ambient_occlusion_to_diffuse(ShadeInput *shi, float *diff)
|
static void ambient_occlusion_apply(ShadeInput *shi, ShadeResult *shr)
|
||||||
{
|
{
|
||||||
if((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX) {
|
float f= R.wrld.aoenergy;
|
||||||
if(shi->amb!=0.0f) {
|
float tmp[3], tmpspec[3];
|
||||||
float f= R.wrld.aoenergy*shi->amb;
|
|
||||||
|
|
||||||
if (R.wrld.aomix==WO_AOADDSUB) {
|
if(!((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
|
||||||
diff[0] = 2.0f*shi->ao[0]-1.0f;
|
return;
|
||||||
diff[1] = 2.0f*shi->ao[1]-1.0f;
|
if(f == 0.0f)
|
||||||
diff[2] = 2.0f*shi->ao[2]-1.0f;
|
return;
|
||||||
}
|
|
||||||
else if (R.wrld.aomix==WO_AOSUB) {
|
if(R.wrld.aomix==WO_AOADD) {
|
||||||
diff[0] = shi->ao[0]-1.0f;
|
shr->combined[0] += shi->ao[0]*shi->r*shi->refl*f;
|
||||||
diff[1] = shi->ao[1]-1.0f;
|
shr->combined[1] += shi->ao[1]*shi->g*shi->refl*f;
|
||||||
diff[2] = shi->ao[2]-1.0f;
|
shr->combined[2] += shi->ao[2]*shi->b*shi->refl*f;
|
||||||
}
|
|
||||||
else {
|
|
||||||
VECCOPY(diff, shi->ao);
|
|
||||||
}
|
|
||||||
|
|
||||||
VECMUL(diff, f);
|
|
||||||
madd_v3_v3fl(diff, shi->indirect, R.wrld.ao_indirect_energy*shi->amb);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
diff[0]= diff[1]= diff[2]= 0.0f;
|
|
||||||
}
|
}
|
||||||
else
|
else if(R.wrld.aomix==WO_AOMUL) {
|
||||||
diff[0]= diff[1]= diff[2]= 0.0f;
|
mul_v3_v3v3(tmp, shr->combined, shi->ao);
|
||||||
|
mul_v3_v3v3(tmpspec, shr->spec, shi->ao);
|
||||||
|
|
||||||
|
if(f == 1.0f) {
|
||||||
|
copy_v3_v3(shr->combined, tmp);
|
||||||
|
copy_v3_v3(shr->spec, tmpspec);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
interp_v3_v3v3(shr->combined, shr->combined, tmp, f);
|
||||||
|
interp_v3_v3v3(shr->spec, shr->spec, tmpspec, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void environment_lighting_apply(ShadeInput *shi, ShadeResult *shr)
|
||||||
|
{
|
||||||
|
float f= R.wrld.ao_env_energy*shi->amb;
|
||||||
|
|
||||||
|
if(!((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
|
||||||
|
return;
|
||||||
|
if(f == 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
shr->combined[0] += shi->env[0]*shi->r*shi->refl*f;
|
||||||
|
shr->combined[1] += shi->env[1]*shi->g*shi->refl*f;
|
||||||
|
shr->combined[2] += shi->env[2]*shi->b*shi->refl*f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void indirect_lighting_apply(ShadeInput *shi, ShadeResult *shr)
|
||||||
|
{
|
||||||
|
float f= R.wrld.ao_indirect_energy;
|
||||||
|
|
||||||
|
if(!((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
|
||||||
|
return;
|
||||||
|
if(f == 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
shr->combined[0] += shi->indirect[0]*shi->r*shi->refl*f;
|
||||||
|
shr->combined[1] += shi->indirect[1]*shi->g*shi->refl*f;
|
||||||
|
shr->combined[2] += shi->indirect[2]*shi->b*shi->refl*f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* result written in shadfac */
|
/* result written in shadfac */
|
||||||
@ -1510,7 +1538,7 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* quite disputable this... also note it doesn't mirror-raytrace */
|
/* quite disputable this... also note it doesn't mirror-raytrace */
|
||||||
if((R.wrld.mode & WO_AMB_OCC) && shi->amb!=0.0f) {
|
if((R.wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && shi->amb!=0.0f) {
|
||||||
float f;
|
float f;
|
||||||
|
|
||||||
f= 1.0f - shi->ao[0];
|
f= 1.0f - shi->ao[0];
|
||||||
@ -1520,12 +1548,8 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
|
|||||||
shr->alpha += f;
|
shr->alpha += f;
|
||||||
shr->alpha *= f;
|
shr->alpha *= f;
|
||||||
}
|
}
|
||||||
else if(R.wrld.aomix==WO_AOSUB) {
|
else if(R.wrld.aomix==WO_AOMUL) {
|
||||||
shr->alpha += f;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
shr->alpha *= f;
|
shr->alpha *= f;
|
||||||
shr->alpha += f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1600,25 +1624,26 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( (ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL ) { // vertexcolor light
|
if( (ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL ) { // vertexcolor light
|
||||||
shr->diff[0]= shi->r*(shi->emit+shi->vcol[0]);
|
shr->emit[0]= shi->r*(shi->emit+shi->vcol[0]);
|
||||||
shr->diff[1]= shi->g*(shi->emit+shi->vcol[1]);
|
shr->emit[1]= shi->g*(shi->emit+shi->vcol[1]);
|
||||||
shr->diff[2]= shi->b*(shi->emit+shi->vcol[2]);
|
shr->emit[2]= shi->b*(shi->emit+shi->vcol[2]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
shr->diff[0]= shi->r*shi->emit;
|
shr->emit[0]= shi->r*shi->emit;
|
||||||
shr->diff[1]= shi->g*shi->emit;
|
shr->emit[1]= shi->g*shi->emit;
|
||||||
shr->diff[2]= shi->b*shi->emit;
|
shr->emit[2]= shi->b*shi->emit;
|
||||||
}
|
}
|
||||||
VECCOPY(shr->shad, shr->diff);
|
|
||||||
|
|
||||||
/* AO pass */
|
/* AO pass */
|
||||||
if(R.wrld.mode & WO_AMB_OCC) {
|
if(R.wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) {
|
||||||
if(((passflag & SCE_PASS_COMBINED) && (shi->combinedflag & SCE_PASS_AO))
|
if(((passflag & SCE_PASS_COMBINED) && (shi->combinedflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT)))
|
||||||
|| (passflag & SCE_PASS_AO)) {
|
|| (passflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT))) {
|
||||||
/* AO was calculated for scanline already */
|
/* AO was calculated for scanline already */
|
||||||
if(shi->depth)
|
if(shi->depth)
|
||||||
ambient_occlusion(shi);
|
ambient_occlusion(shi);
|
||||||
VECCOPY(shr->ao, shi->ao);
|
VECCOPY(shr->ao, shi->ao);
|
||||||
|
VECCOPY(shr->env, shi->env); // XXX multiply
|
||||||
|
VECCOPY(shr->indirect, shi->indirect); // XXX multiply
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1727,6 +1752,19 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
|
|||||||
|
|
||||||
/* from now stuff everything in shr->combined: ambient, AO, radio, ramps, exposure */
|
/* from now stuff everything in shr->combined: ambient, AO, radio, ramps, exposure */
|
||||||
if(!(ma->sss_flag & MA_DIFF_SSS) || !sss_pass_done(&R, ma)) {
|
if(!(ma->sss_flag & MA_DIFF_SSS) || !sss_pass_done(&R, ma)) {
|
||||||
|
/* add AO in combined? */
|
||||||
|
if(R.wrld.mode & WO_AMB_OCC)
|
||||||
|
if(shi->combinedflag & SCE_PASS_AO)
|
||||||
|
ambient_occlusion_apply(shi, shr);
|
||||||
|
|
||||||
|
if(R.wrld.mode & WO_ENV_LIGHT)
|
||||||
|
if(shi->combinedflag & SCE_PASS_ENVIRONMENT)
|
||||||
|
environment_lighting_apply(shi, shr);
|
||||||
|
|
||||||
|
if(R.wrld.mode & WO_INDIRECT_LIGHT)
|
||||||
|
if(shi->combinedflag & SCE_PASS_INDIRECT)
|
||||||
|
indirect_lighting_apply(shi, shr);
|
||||||
|
|
||||||
shr->combined[0]+= shi->ambr;
|
shr->combined[0]+= shi->ambr;
|
||||||
shr->combined[1]+= shi->ambg;
|
shr->combined[1]+= shi->ambg;
|
||||||
shr->combined[2]+= shi->ambb;
|
shr->combined[2]+= shi->ambb;
|
||||||
@ -1738,22 +1776,6 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
|
|||||||
shr->combined[2]+= shi->b*shi->amb*shi->rad[2];
|
shr->combined[2]+= shi->b*shi->amb*shi->rad[2];
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
/* add AO in combined? */
|
|
||||||
if(R.wrld.mode & WO_AMB_OCC) {
|
|
||||||
if(shi->combinedflag & SCE_PASS_AO) {
|
|
||||||
float aodiff[3];
|
|
||||||
ambient_occlusion_to_diffuse(shi, aodiff);
|
|
||||||
|
|
||||||
shr->combined[0] += shi->r*aodiff[0];
|
|
||||||
shr->combined[1] += shi->g*aodiff[1];
|
|
||||||
shr->combined[2] += shi->b*aodiff[2];
|
|
||||||
|
|
||||||
if (shr->combined[0] < 0.f) shr->combined[0]= 0.f;
|
|
||||||
if (shr->combined[1] < 0.f) shr->combined[1]= 0.f;
|
|
||||||
if (shr->combined[2] < 0.f) shr->combined[2]= 0.f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->combined, shi);
|
if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->combined, shi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1775,10 +1797,12 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* and add spec */
|
/* and add emit and spec */
|
||||||
|
if(shi->combinedflag & SCE_PASS_EMIT)
|
||||||
|
VECADD(shr->combined, shr->combined, shr->emit);
|
||||||
if(shi->combinedflag & SCE_PASS_SPEC)
|
if(shi->combinedflag & SCE_PASS_SPEC)
|
||||||
VECADD(shr->combined, shr->combined, shr->spec);
|
VECADD(shr->combined, shr->combined, shr->spec);
|
||||||
|
|
||||||
/* modulate by the object color */
|
/* modulate by the object color */
|
||||||
if((ma->shade_flag & MA_OBCOLOR) && shi->obr->ob) {
|
if((ma->shade_flag & MA_OBCOLOR) && shi->obr->ob) {
|
||||||
if(!(ma->sss_flag & MA_DIFF_SSS) || !sss_pass_done(&R, ma)) {
|
if(!(ma->sss_flag & MA_DIFF_SSS) || !sss_pass_done(&R, ma)) {
|
||||||
|
@ -222,6 +222,8 @@ void interpolate_shade_result(ShadeResult *shr1, ShadeResult *shr2, float t, Sha
|
|||||||
interpolate_vec3(shr1->nor, shr2->nor, t, negt, shr->nor);
|
interpolate_vec3(shr1->nor, shr2->nor, t, negt, shr->nor);
|
||||||
normalize_v3(shr->nor);
|
normalize_v3(shr->nor);
|
||||||
}
|
}
|
||||||
|
if(addpassflag & SCE_PASS_EMIT)
|
||||||
|
interpolate_vec3(shr1->emit, shr2->emit, t, negt, shr->emit);
|
||||||
if(addpassflag & SCE_PASS_DIFFUSE)
|
if(addpassflag & SCE_PASS_DIFFUSE)
|
||||||
interpolate_vec3(shr1->diff, shr2->diff, t, negt, shr->diff);
|
interpolate_vec3(shr1->diff, shr2->diff, t, negt, shr->diff);
|
||||||
if(addpassflag & SCE_PASS_SPEC)
|
if(addpassflag & SCE_PASS_SPEC)
|
||||||
@ -230,6 +232,10 @@ void interpolate_shade_result(ShadeResult *shr1, ShadeResult *shr2, float t, Sha
|
|||||||
interpolate_vec3(shr1->shad, shr2->shad, t, negt, shr->shad);
|
interpolate_vec3(shr1->shad, shr2->shad, t, negt, shr->shad);
|
||||||
if(addpassflag & SCE_PASS_AO)
|
if(addpassflag & SCE_PASS_AO)
|
||||||
interpolate_vec3(shr1->ao, shr2->ao, t, negt, shr->ao);
|
interpolate_vec3(shr1->ao, shr2->ao, t, negt, shr->ao);
|
||||||
|
if(addpassflag & SCE_PASS_ENVIRONMENT)
|
||||||
|
interpolate_vec3(shr1->env, shr2->env, t, negt, shr->env);
|
||||||
|
if(addpassflag & SCE_PASS_INDIRECT)
|
||||||
|
interpolate_vec3(shr1->indirect, shr2->indirect, t, negt, shr->indirect);
|
||||||
if(addpassflag & SCE_PASS_REFLECT)
|
if(addpassflag & SCE_PASS_REFLECT)
|
||||||
interpolate_vec3(shr1->refl, shr2->refl, t, negt, shr->refl);
|
interpolate_vec3(shr1->refl, shr2->refl, t, negt, shr->refl);
|
||||||
if(addpassflag & SCE_PASS_REFRACT)
|
if(addpassflag & SCE_PASS_REFRACT)
|
||||||
@ -963,6 +969,7 @@ StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm,
|
|||||||
mesh->totface= totface;
|
mesh->totface= totface;
|
||||||
mesh->face= MEM_callocN(sizeof(int)*4*mesh->totface, "StrandSurfFaces");
|
mesh->face= MEM_callocN(sizeof(int)*4*mesh->totface, "StrandSurfFaces");
|
||||||
mesh->ao= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfAO");
|
mesh->ao= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfAO");
|
||||||
|
mesh->env= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfEnv");
|
||||||
mesh->indirect= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfIndirect");
|
mesh->indirect= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfIndirect");
|
||||||
BLI_addtail(&re->strandsurface, mesh);
|
BLI_addtail(&re->strandsurface, mesh);
|
||||||
}
|
}
|
||||||
@ -1002,6 +1009,7 @@ void free_strand_surface(Render *re)
|
|||||||
if(mesh->prevco) MEM_freeN(mesh->prevco);
|
if(mesh->prevco) MEM_freeN(mesh->prevco);
|
||||||
if(mesh->nextco) MEM_freeN(mesh->nextco);
|
if(mesh->nextco) MEM_freeN(mesh->nextco);
|
||||||
if(mesh->ao) MEM_freeN(mesh->ao);
|
if(mesh->ao) MEM_freeN(mesh->ao);
|
||||||
|
if(mesh->env) MEM_freeN(mesh->env);
|
||||||
if(mesh->indirect) MEM_freeN(mesh->indirect);
|
if(mesh->indirect) MEM_freeN(mesh->indirect);
|
||||||
if(mesh->face) MEM_freeN(mesh->face);
|
if(mesh->face) MEM_freeN(mesh->face);
|
||||||
}
|
}
|
||||||
|
@ -3516,6 +3516,9 @@ void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
|
|||||||
col= shr->col;
|
col= shr->col;
|
||||||
pixsize= 4;
|
pixsize= 4;
|
||||||
break;
|
break;
|
||||||
|
case SCE_PASS_EMIT:
|
||||||
|
col= shr->emit;
|
||||||
|
break;
|
||||||
case SCE_PASS_DIFFUSE:
|
case SCE_PASS_DIFFUSE:
|
||||||
col= shr->diff;
|
col= shr->diff;
|
||||||
break;
|
break;
|
||||||
@ -3528,6 +3531,12 @@ void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
|
|||||||
case SCE_PASS_AO:
|
case SCE_PASS_AO:
|
||||||
col= shr->ao;
|
col= shr->ao;
|
||||||
break;
|
break;
|
||||||
|
case SCE_PASS_ENVIRONMENT:
|
||||||
|
col= shr->env;
|
||||||
|
break;
|
||||||
|
case SCE_PASS_INDIRECT:
|
||||||
|
col= shr->indirect;
|
||||||
|
break;
|
||||||
case SCE_PASS_REFLECT:
|
case SCE_PASS_REFLECT:
|
||||||
col= shr->refl;
|
col= shr->refl;
|
||||||
break;
|
break;
|
||||||
@ -3615,6 +3624,9 @@ void add_transp_passes(RenderLayer *rl, int offset, ShadeResult *shr, float alph
|
|||||||
fp= rpass->rect + 4*offset;
|
fp= rpass->rect + 4*offset;
|
||||||
addAlphaOverFloat(fp, shr->col);
|
addAlphaOverFloat(fp, shr->col);
|
||||||
break;
|
break;
|
||||||
|
case SCE_PASS_EMIT:
|
||||||
|
col= shr->emit;
|
||||||
|
break;
|
||||||
case SCE_PASS_DIFFUSE:
|
case SCE_PASS_DIFFUSE:
|
||||||
col= shr->diff;
|
col= shr->diff;
|
||||||
break;
|
break;
|
||||||
@ -3627,6 +3639,12 @@ void add_transp_passes(RenderLayer *rl, int offset, ShadeResult *shr, float alph
|
|||||||
case SCE_PASS_AO:
|
case SCE_PASS_AO:
|
||||||
col= shr->ao;
|
col= shr->ao;
|
||||||
break;
|
break;
|
||||||
|
case SCE_PASS_ENVIRONMENT:
|
||||||
|
col= shr->env;
|
||||||
|
break;
|
||||||
|
case SCE_PASS_INDIRECT:
|
||||||
|
col= shr->indirect;
|
||||||
|
break;
|
||||||
case SCE_PASS_REFLECT:
|
case SCE_PASS_REFLECT:
|
||||||
col= shr->refl;
|
col= shr->refl;
|
||||||
break;
|
break;
|
||||||
@ -3851,6 +3869,9 @@ static int addtosamp_shr(ShadeResult *samp_shr, ShadeSample *ssamp, int addpassf
|
|||||||
if(addpassflag & SCE_PASS_NORMAL)
|
if(addpassflag & SCE_PASS_NORMAL)
|
||||||
addvecmul(samp_shr->nor, shr->nor, fac);
|
addvecmul(samp_shr->nor, shr->nor, fac);
|
||||||
|
|
||||||
|
if(addpassflag & SCE_PASS_EMIT)
|
||||||
|
addvecmul(samp_shr->emit, shr->emit, fac);
|
||||||
|
|
||||||
if(addpassflag & SCE_PASS_DIFFUSE)
|
if(addpassflag & SCE_PASS_DIFFUSE)
|
||||||
addvecmul(samp_shr->diff, shr->diff, fac);
|
addvecmul(samp_shr->diff, shr->diff, fac);
|
||||||
|
|
||||||
@ -3863,6 +3884,12 @@ static int addtosamp_shr(ShadeResult *samp_shr, ShadeSample *ssamp, int addpassf
|
|||||||
if(addpassflag & SCE_PASS_AO)
|
if(addpassflag & SCE_PASS_AO)
|
||||||
addvecmul(samp_shr->ao, shr->ao, fac);
|
addvecmul(samp_shr->ao, shr->ao, fac);
|
||||||
|
|
||||||
|
if(addpassflag & SCE_PASS_ENVIRONMENT)
|
||||||
|
addvecmul(samp_shr->env, shr->env, fac);
|
||||||
|
|
||||||
|
if(addpassflag & SCE_PASS_INDIRECT)
|
||||||
|
addvecmul(samp_shr->indirect, shr->indirect, fac);
|
||||||
|
|
||||||
if(addpassflag & SCE_PASS_REFLECT)
|
if(addpassflag & SCE_PASS_REFLECT)
|
||||||
addvecmul(samp_shr->refl, shr->refl, fac);
|
addvecmul(samp_shr->refl, shr->refl, fac);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user