From ab9822eff8865846d3c7ef81ff30cc35cb48ae0c Mon Sep 17 00:00:00 2001 From: IRIE Shinsuke Date: Mon, 25 Nov 2013 20:58:23 +0900 Subject: [PATCH] Blender Internal: Add "Lamp Data" shader node that allows shaders to acquire information such as light vector from specified Lamp. For now this provides the following outputs: - Color - Light Vector - Distance - Shadow - Visibility Factor Note: Color output is multiplied by the lamp energy. Multiplication of color*max(dot(light_vector,normal_vector),0)*shadow*visibility_factor produces the exact same result as the Lambert shader. Many thanks to Brecht for code review and discussion! --- release/scripts/startup/nodeitems_builtins.py | 1 + source/blender/blenkernel/BKE_node.h | 1 + source/blender/blenkernel/intern/node.c | 1 + source/blender/editors/space_node/drawnode.c | 8 ++ source/blender/gpu/GPU_material.h | 2 + source/blender/gpu/intern/gpu_material.c | 47 ++++++++++ .../gpu/shaders/gpu_shader_material.glsl | 33 +++++++ source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/intern/rna_internal.h | 1 + source/blender/makesrna/intern/rna_nodetree.c | 13 +++ source/blender/makesrna/intern/rna_object.c | 5 + source/blender/nodes/CMakeLists.txt | 1 + source/blender/nodes/NOD_shader.h | 1 + source/blender/nodes/NOD_static_types.h | 1 + .../nodes/shader/nodes/node_shader_lamp.c | 86 ++++++++++++++++++ .../render/extern/include/RE_shader_ext.h | 3 +- .../render/intern/source/shadeoutput.c | 91 +++++++++++++++++++ .../bad_level_call_stubs/stubs.c | 1 + 18 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 source/blender/nodes/shader/nodes/node_shader_lamp.c diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index fdda753372f..675d0ab8489 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -111,6 +111,7 @@ shader_node_categories = [ ShaderOldNodeCategory("SH_INPUT", "Input", items=[ NodeItem("ShaderNodeMaterial"), NodeItem("ShaderNodeCameraData"), + NodeItem("ShaderNodeLampData"), NodeItem("ShaderNodeValue"), NodeItem("ShaderNodeRGB"), NodeItem("ShaderNodeTexture"), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index b948f09d3d3..ced02099a4f 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -740,6 +740,7 @@ struct ShadeResult; #define SH_NODE_SEPHSV 183 #define SH_NODE_COMBHSV 184 #define SH_NODE_BSDF_HAIR 185 +#define SH_NODE_LAMP 186 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 869dbe032c9..698f2a4ef2d 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3435,6 +3435,7 @@ static void registerShaderNodes(void) register_node_type_sh_output(); register_node_type_sh_material(); register_node_type_sh_camera(); + register_node_type_sh_lamp(); register_node_type_sh_gamma(); register_node_type_sh_brightcontrast(); register_node_type_sh_value(); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index b33c3d6c228..61e7fd89866 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -753,6 +753,11 @@ static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA } } +static void node_shader_buts_lamp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "lamp_object", 0, IFACE_("Lamp Object"), ICON_NONE); +} + static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "attribute_name", 0, IFACE_("Name"), ICON_NONE); @@ -1002,6 +1007,9 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_GEOMETRY: ntype->draw_buttons = node_shader_buts_geometry; break; + case SH_NODE_LAMP: + ntype->draw_buttons = node_shader_buts_lamp; + break; case SH_NODE_ATTRIBUTE: ntype->draw_buttons = node_shader_buts_attribute; break; diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 29da72a00fe..8c4c7d47558 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -133,6 +133,7 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float obcol[4], float autobumpscale); void GPU_material_unbind(GPUMaterial *material); int GPU_material_bound(GPUMaterial *material); +struct Scene *GPU_material_scene(GPUMaterial *material); void GPU_material_vertex_attributes(GPUMaterial *material, struct GPUVertexAttribs *attrib); @@ -244,6 +245,7 @@ void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float ener void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2); void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend); int GPU_lamp_shadow_layer(GPULamp *lamp); +GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **col, GPUNodeLink **lv, GPUNodeLink **dist, GPUNodeLink **shadow); #ifdef __cplusplus } diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index ed7a2f4ede0..8e7194bb4a1 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -355,6 +355,11 @@ int GPU_material_bound(GPUMaterial *material) return material->bound; } +Scene *GPU_material_scene(GPUMaterial *material) +{ + return material->scene; +} + void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs) { *attribs = material->attribs; @@ -1953,6 +1958,48 @@ int GPU_lamp_shadow_layer(GPULamp *lamp) return -1; } +GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **col, GPUNodeLink **lv, GPUNodeLink **dist, GPUNodeLink **shadow) +{ + GPUNodeLink *visifac; + + *col = GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob); + visifac = lamp_get_visibility(mat, lamp, lv, dist); + shade_light_textures(mat, lamp, col); + + if (GPU_lamp_has_shadow_buffer(lamp)) { + GPUNodeLink *vn, *inp; + + GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &vn); + GPU_link(mat, "shade_inp", vn, *lv, &inp); + mat->dynproperty |= DYN_LAMP_PERSMAT; + + if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { + GPU_link(mat, "shadows_only_vsm", + GPU_builtin(GPU_VIEW_POSITION), + GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), + GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), + GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), + GPU_uniform(lamp->shadow_color), inp, shadow); + } + else { + GPU_link(mat, "shadows_only", + GPU_builtin(GPU_VIEW_POSITION), + GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), + GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), + GPU_uniform(&lamp->bias), GPU_uniform(lamp->shadow_color), inp, shadow); + } + } + else { + GPU_link(mat, "set_rgb_one", shadow); + } + + /* ensure shadow buffer and lamp textures will be updated */ + add_user_list(&mat->lamps, lamp); + add_user_list(&lamp->materials, mat->ma); + + return visifac; +} + /* export the GLSL shader */ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 1dd33080d94..3a4aa75aa01 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -166,6 +166,15 @@ void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist) outview = normalize(co); } +void lamp(vec4 col, vec3 lv, float dist, vec3 shadow, float visifac, out vec4 outcol, out vec3 outlv, out float outdist, out vec4 outshadow, out float outvisifac) +{ + outcol = col; + outlv = lv; + outdist = dist; + outshadow = vec4(shadow, 1.0); + outvisifac = visifac; +} + void math_add(float val1, float val2, out float outval) { outval = val1 + val2; @@ -1973,6 +1982,30 @@ void test_shadowbuf_vsm(vec3 rco, sampler2D shadowmap, mat4 shadowpersmat, float } } +void shadows_only(vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float shadowbias, vec3 shadowcolor, float inp, out vec3 result) +{ + result = vec3(1.0); + + if(inp > 0.0) { + float shadfac; + + test_shadowbuf(rco, shadowmap, shadowpersmat, shadowbias, inp, shadfac); + result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor); + } +} + +void shadows_only_vsm(vec3 rco, sampler2D shadowmap, mat4 shadowpersmat, float shadowbias, float bleedbias, vec3 shadowcolor, float inp, out vec3 result) +{ + result = vec3(1.0); + + if(inp > 0.0) { + float shadfac; + + test_shadowbuf_vsm(rco, shadowmap, shadowpersmat, shadowbias, bleedbias, inp, shadfac); + result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor); + } +} + void shade_light_texture(vec3 rco, sampler2D cookie, mat4 shadowpersmat, out vec4 result) { diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 5fa41c14932..88b326914e1 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -493,6 +493,7 @@ extern StructRNA RNA_ShaderNodeExtendedMaterial; extern StructRNA RNA_ShaderNodeGeometry; extern StructRNA RNA_ShaderNodeHueSaturation; extern StructRNA RNA_ShaderNodeInvert; +extern StructRNA RNA_ShaderNodeLampData; extern StructRNA RNA_ShaderNodeMapping; extern StructRNA RNA_ShaderNodeMaterial; extern StructRNA RNA_ShaderNodeMath; diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 7950ed424ee..807fad41373 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -239,6 +239,7 @@ void rna_TextureSlot_brush_update(struct Main *bmain, struct Scene *scene, struc int rna_Armature_object_poll(struct PointerRNA *ptr, struct PointerRNA value); int rna_Camera_object_poll(struct PointerRNA *ptr, struct PointerRNA value); int rna_Curve_object_poll(struct PointerRNA *ptr, struct PointerRNA value); +int rna_Lamp_object_poll(struct PointerRNA *ptr, struct PointerRNA value); int rna_Lattice_object_poll(struct PointerRNA *ptr, struct PointerRNA value); int rna_Mesh_object_poll(struct PointerRNA *ptr, struct PointerRNA value); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 6b5bced75bd..3d291f4d4c2 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3258,6 +3258,19 @@ static void def_sh_geometry(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } +static void def_sh_lamp(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "lamp_object", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Lamp_object_poll"); + RNA_def_property_ui_text(prop, "Lamp Object", ""); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); +} + static void def_sh_attribute(StructRNA *srna) { PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 3f366dfbcfa..eb0f30216f2 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1446,6 +1446,11 @@ int rna_Camera_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value) return ((Object *)value.id.data)->type == OB_CAMERA; } +int rna_Lamp_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value) +{ + return ((Object *)value.id.data)->type == OB_LAMP; +} + int rna_DupliObject_index_get(PointerRNA *ptr) { DupliObject *dob = (DupliObject *)ptr->data; diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 61c8cb5655d..64feb0068cb 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -133,6 +133,7 @@ set(SRC shader/nodes/node_shader_geom.c shader/nodes/node_shader_hueSatVal.c shader/nodes/node_shader_invert.c + shader/nodes/node_shader_lamp.c shader/nodes/node_shader_mapping.c shader/nodes/node_shader_material.c shader/nodes/node_shader_math.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index 853046a2a23..71c0638829f 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -47,6 +47,7 @@ void register_node_type_sh_group(void); void register_node_type_sh_output(void); void register_node_type_sh_material(void); void register_node_type_sh_camera(void); +void register_node_type_sh_lamp(void); void register_node_type_sh_value(void); void register_node_type_sh_rgb(void); void register_node_type_sh_mix_rgb(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index db9f710b6cf..beeaa7787fb 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -56,6 +56,7 @@ DefNode( ShaderNode, SH_NODE_MAPPING, def_sh_mapping, "MAPPI DefNode( ShaderNode, SH_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", VectorCurve, "Vector Curves", "" ) DefNode( ShaderNode, SH_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", RGBCurve, "RGB Curves", "" ) DefNode( ShaderNode, SH_NODE_CAMERA, 0, "CAMERA", CameraData, "Camera Data", "" ) +DefNode( ShaderNode, SH_NODE_LAMP, def_sh_lamp, "LAMP", LampData, "Lamp Data", "" ) DefNode( ShaderNode, SH_NODE_MATH, def_math, "MATH", Math, "Math", "" ) DefNode( ShaderNode, SH_NODE_VECT_MATH, def_vector_math, "VECT_MATH", VectorMath, "Vector Math", "" ) DefNode( ShaderNode, SH_NODE_SQUEEZE, 0, "SQUEEZE", Squeeze, "Squeeze Value", "" ) diff --git a/source/blender/nodes/shader/nodes/node_shader_lamp.c b/source/blender/nodes/shader/nodes/node_shader_lamp.c new file mode 100644 index 00000000000..adf53ba9b52 --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_lamp.c @@ -0,0 +1,86 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2013 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/shader/nodes/node_shader_lamp.c + * \ingroup shdnodes + */ + + +#include "node_shader_util.h" + +/* **************** LAMP INFO ******************** */ +static bNodeSocketTemplate sh_node_lamp_out[] = { + { SOCK_RGBA, 0, N_("Color")}, + { SOCK_VECTOR, 0, N_("Light Vector")}, + { SOCK_FLOAT, 0, N_("Distance")}, + { SOCK_RGBA, 0, N_("Shadow")}, + { SOCK_FLOAT, 0, N_("Visibility Factor")}, + { -1, 0, "" } +}; + + +static void node_shader_exec_lamp(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **out) +{ + if (data) { + Object *ob = (Object *)node->id; + + if (ob) { + ShadeInput *shi = ((ShaderCallData *)data)->shi; + + shi->nodes = 1; /* temp hack to prevent trashadow recursion */ + out[4]->vec[0] = RE_lamp_get_data(shi, ob, out[0]->vec, out[1]->vec, out[2]->vec, out[3]->vec); + shi->nodes = 0; + } + } +} + +static int gpu_shader_lamp(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + if (node->id) { + GPULamp *lamp = GPU_lamp_from_blender(GPU_material_scene(mat), (Object *)node->id, NULL); + GPUNodeLink *col, *lv, *dist, *visifac, *shadow; + + visifac = GPU_lamp_get_data(mat, lamp, &col, &lv, &dist, &shadow); + + return GPU_stack_link(mat, "lamp", in, out, col, lv, dist, shadow, visifac); + } + + return 0; +} + +void register_node_type_sh_lamp(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_LAMP, "Lamp Data", NODE_CLASS_INPUT, 0); + node_type_compatibility(&ntype, NODE_OLD_SHADING); + node_type_socket_templates(&ntype, NULL, sh_node_lamp_out); + node_type_exec(&ntype, NULL, NULL, node_shader_exec_lamp); + node_type_gpu(&ntype, gpu_shader_lamp); + + nodeRegisterType(&ntype); +} diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index baec1a74721..dbde29ea7ac 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -194,6 +194,7 @@ struct Tex; struct MTex; struct ImBuf; struct ImagePool; +struct Object; /* this one uses nodes */ int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage); @@ -203,11 +204,11 @@ int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex, struct ImagePool *pool); +float RE_lamp_get_data(struct ShadeInput *shi, struct Object *lamp_obj, float col[4], float lv[3], float *dist, float shadow[4]); /* shaded view and bake */ struct Render; struct Image; -struct Object; int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob, short *do_update, float *progress); struct Image *RE_bake_shade_get_image(void); diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index dbc9c47446f..40a5a5d9a05 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -1982,3 +1982,94 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) shr->combined[3]= shr->alpha; } +/* used for "Lamp Data" shader node */ +static float lamp_get_data_internal(ShadeInput *shi, GroupObject *go, float col[4], float lv[3], float *dist, float shadow[4]) +{ + LampRen *lar = go->lampren; + float visifac, inp; + + if (!lar || lar->type == LA_YF_PHOTON + || ((lar->mode & LA_LAYER) && (lar->lay & shi->obi->lay) == 0) + || (lar->lay & shi->lay) == 0) + return 0.0f; + + if (lar->mode & LA_TEXTURE) + do_lamp_tex(lar, lv, shi, col, LA_TEXTURE); + + visifac = lamp_get_visibility(lar, shi->co, lv, dist); + + if (visifac == 0.0f + || lar->type == LA_HEMI + || (lar->type != LA_SPOT && !(lar->mode & LA_SHAD_RAY)) + || (R.r.scemode & R_BUTS_PREVIEW)) + return visifac; + + inp = dot_v3v3(shi->vn, lv); + + if (inp > 0.0f) { + float shadfac[4]; + + shadow[0] = lar->shdwr; + shadow[1] = lar->shdwg; + shadow[2] = lar->shdwb; + + if (lar->mode & LA_SHAD_TEX) + do_lamp_tex(lar, lv, shi, shadow, LA_SHAD_TEX); + + lamp_get_shadow(lar, shi, inp, shadfac, shi->depth); + + shadow[0] = 1.0f - ((1.0f - shadfac[0] * shadfac[3]) * (1.0f - shadow[0])); + shadow[1] = 1.0f - ((1.0f - shadfac[1] * shadfac[3]) * (1.0f - shadow[1])); + shadow[2] = 1.0f - ((1.0f - shadfac[2] * shadfac[3]) * (1.0f - shadow[2])); + } + + return visifac; +} + +float RE_lamp_get_data(ShadeInput *shi, Object *lamp_obj, float col[4], float lv[3], float *dist, float shadow[4]) +{ + col[0] = col[1] = col[2] = 0.0f; + col[3] = 1.0f; + copy_v3_v3(lv, shi->vn); + *dist = 1.0f; + shadow[0] = shadow[1] = shadow[2] = shadow[3] = 1.0f; + + if (lamp_obj->type == OB_LAMP) { + GroupObject *go; + Lamp *lamp = (Lamp *)lamp_obj->data; + + col[0] = lamp->r * lamp->energy; + col[1] = lamp->g * lamp->energy; + col[2] = lamp->b * lamp->energy; + + if (R.r.scemode & R_BUTS_PREVIEW) { + for (go = R.lights.first; go; go = go->next) { + /* "Lamp.002" is main key light of material preview */ + if (strcmp(go->ob->id.name + 2, "Lamp.002") == 0) + return lamp_get_data_internal(shi, go, col, lv, dist, shadow); + } + return 0.0f; + } + + if (shi->light_override) { + for (go = shi->light_override->gobject.first; go; go = go->next) { + if (go->ob == lamp_obj) + return lamp_get_data_internal(shi, go, col, lv, dist, shadow); + } + } + + if (shi->mat && shi->mat->group) { + for (go = shi->mat->group->gobject.first; go; go = go->next) { + if (go->ob == lamp_obj) + return lamp_get_data_internal(shi, go, col, lv, dist, shadow); + } + } + + for (go = R.lights.first; go; go = go->next) { + if (go->ob == lamp_obj) + return lamp_get_data_internal(shi, go, col, lv, dist, shadow); + } + } + + return 0.0f; +} diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index d79da3f3d6f..7ff5f83c21c 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -173,6 +173,7 @@ void modifier_skin_customdata_ensure(struct Object *ob) {STUB_ASSERT(0);} /* nodes */ struct RenderResult *RE_GetResult(struct Render *re) {STUB_ASSERT(0); return (struct RenderResult *) NULL;} struct Render *RE_GetRender(const char *name) {STUB_ASSERT(0); return (struct Render *) NULL;} +float RE_lamp_get_data(struct ShadeInput *shi, struct Object *lamp_obj, float col[3], float lv[3], float *dist) {STUB_ASSERT(0); return 0.0f;} /* blenkernel */ void RE_FreeRenderResult(struct RenderResult *res) {STUB_ASSERT(0);}