Blender Internal: Add "Lamp Data" shader node that allows shaders to acquire informat...
authorIRIE Shinsuke <irieshinsuke@yahoo.co.jp>
Mon, 25 Nov 2013 11:58:23 +0000 (20:58 +0900)
committerIRIE Shinsuke <irieshinsuke@yahoo.co.jp>
Mon, 25 Nov 2013 13:19:47 +0000 (22:19 +0900)
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!

18 files changed:
release/scripts/startup/nodeitems_builtins.py
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node.c
source/blender/editors/space_node/drawnode.c
source/blender/gpu/GPU_material.h
source/blender/gpu/intern/gpu_material.c
source/blender/gpu/shaders/gpu_shader_material.glsl
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_object.c
source/blender/nodes/CMakeLists.txt
source/blender/nodes/NOD_shader.h
source/blender/nodes/NOD_static_types.h
source/blender/nodes/shader/nodes/node_shader_lamp.c [new file with mode: 0644]
source/blender/render/extern/include/RE_shader_ext.h
source/blender/render/intern/source/shadeoutput.c
source/blenderplayer/bad_level_call_stubs/stubs.c

index fdda753372fe91f9b355e4ebcf51a0f784c3e462..675d0ab84894d2a07866a5a911917a07ab2011f4 100644 (file)
@@ -111,6 +111,7 @@ shader_node_categories = [
     ShaderOldNodeCategory("SH_INPUT", "Input", items=[
         NodeItem("ShaderNodeMaterial"),
         NodeItem("ShaderNodeCameraData"),
+        NodeItem("ShaderNodeLampData"),
         NodeItem("ShaderNodeValue"),
         NodeItem("ShaderNodeRGB"),
         NodeItem("ShaderNodeTexture"),
index b948f09d3d33ba4568dcca507d06953f70808d56..ced02099a4f9eb4396c4666ab5f824756fa6eb57 100644 (file)
@@ -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
index 869dbe032c951530fa773b4ee44cb3781f153ebb..698f2a4ef2d56011f81150670553ab9bba08d488 100644 (file)
@@ -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();
index b33c3d6c2285f6327891d097b21231a75611b050..61e7fd89866d1ac38e28d9adf6afc37078eb7a51 100644 (file)
@@ -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;
index 29da72a00fe60bb6649ff0d74278db7bc8234084..8c4c7d4755876404260e04461302f3863dcd00c4 100644 (file)
@@ -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
 }
index ed7a2f4ede0749768b14de5a339f47f2c384a508..8e7194bb4a1d90152a69827a280e29f00fa45868 100644 (file)
@@ -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)
index 1dd33080d9465bfb212884ab21a58a28831b0b20..3a4aa75aa0121589de14c8fdf093fef439f6c91f 100644 (file)
@@ -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)
 {
 
index 5fa41c14932a093f5a23de03dbcf61c38dc8d9ea..88b326914e17012cc056a63ac3de9884f36524e1 100644 (file)
@@ -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;
index 7950ed424eef657cb031102117a339b3ec003abc..807fad41373bcadc75f05dc01419a8c881e49d99 100644 (file)
@@ -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);
 
index 6b5bced75bd937c09673ea2d208809f88fd1562f..3d291f4d4c282383ead72f7918312c95a10faf39 100644 (file)
@@ -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;
index 3f366dfbcfa94e03dd4ce4248260c9897c5d37ea..eb0f30216f2f3d6ed644b5df26afe188e80b32b4 100644 (file)
@@ -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;
index 61c8cb5655df026edaf57b76b8db020545724660..64feb0068cb7663987e9e3de87cd8286c04f67b6 100644 (file)
@@ -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
index 853046a2a2318ccc3f8359d230f627c530582c63..71c0638829f8a28f9c8cdde0bb3b0d0a79b0a116 100644 (file)
@@ -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);
index db9f710b6cfe24dc7e65c1b7d5761be2ef6656ae..beeaa7787fb848fec67f18d2c46ee89d0c28ecf8 100644 (file)
@@ -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 (file)
index 0000000..adf53ba
--- /dev/null
@@ -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);
+}
index baec1a74721a034775ce297d57c7d01b72da8d59..dbde29ea7ac4721ed7ed7c197eebbe6b3a1fe115 100644 (file)
@@ -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);
index dbc9c47446f257e6196c0ee0d2815e392a7fdb43..40a5a5d9a0584a9e428a4d51f9a046f132272d97 100644 (file)
@@ -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;
+}
index d79da3f3d6f5a6c6e65be75368b3d30023150f66..7ff5f83c21c0c5779de97105cddcc42ba5046ae1 100644 (file)
@@ -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);}