[Bf-blender-cvs] [76425feed86] blender2.8: Object Info node support for GLSL mode and the internal render

Alexander Romanov noreply at git.blender.org
Tue Apr 18 15:37:28 CEST 2017


Commit: 76425feed8644a8fe1c0e52ef3f77b95012ba44e
Author: Alexander Romanov
Date:   Fri Apr 14 18:13:44 2017 +0300
Branches: blender2.8
https://developer.blender.org/rB76425feed8644a8fe1c0e52ef3f77b95012ba44e

Object Info node support for GLSL mode and the internal render

Object Info node can be useful to give some variation to a single material assigned to multiple instances. This patch adds support for Viewport and BI.

{F499530}

Example: {F499528}

Reviewers: merwin, brecht, dfelinto

Reviewed By: brecht

Subscribers: duarteframos, fclem, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov

Differential Revision: https://developer.blender.org/D2425

===================================================================

M	intern/cycles/blender/blender_object.cpp
M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenkernel/intern/object_dupli.c
A	source/blender/blenlib/BLI_hash.h
M	source/blender/gpu/GPU_material.h
M	source/blender/gpu/intern/gpu_codegen.c
M	source/blender/gpu/intern/gpu_draw.c
M	source/blender/gpu/intern/gpu_material.c
M	source/blender/gpu/intern/gpu_shader.c
M	source/blender/gpu/shaders/gpu_shader_material.glsl
M	source/blender/makesdna/DNA_object_types.h
M	source/blender/makesrna/intern/rna_object.c
M	source/blender/nodes/shader/nodes/node_shader_object_info.c
M	source/blender/render/extern/include/RE_pipeline.h
M	source/blender/render/extern/include/RE_shader_ext.h
M	source/blender/render/intern/include/render_types.h
M	source/blender/render/intern/source/renderdatabase.c
M	source/blender/render/intern/source/shadeoutput.c
M	source/blenderplayer/bad_level_call_stubs/stubs.c
M	source/gameengine/Ketsji/BL_BlenderShader.cpp

===================================================================

diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index d05699236cc..2810ad15b9a 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -379,27 +379,16 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
 			}
 		}
 
-		/* random number */
-		object->random_id = hash_string(object->name.c_str());
-
-		if(persistent_id) {
-			for(int i = 0; i < OBJECT_PERSISTENT_ID_SIZE; i++)
-				object->random_id = hash_int_2d(object->random_id, persistent_id[i]);
-		}
-		else
-			object->random_id = hash_int_2d(object->random_id, 0);
-
-		if(b_parent.ptr.data != b_ob.ptr.data)
-			object->random_id ^= hash_int(hash_string(b_parent.name().c_str()));
-
-		/* dupli texture coordinates */
+		/* dupli texture coordinates and random_id */
 		if(b_dupli_ob) {
 			object->dupli_generated = 0.5f*get_float3(b_dupli_ob.orco()) - make_float3(0.5f, 0.5f, 0.5f);
 			object->dupli_uv = get_float2(b_dupli_ob.uv());
+			object->random_id = b_dupli_ob.random_id();
 		}
 		else {
 			object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
 			object->dupli_uv = make_float2(0.0f, 0.0f);
+			object->random_id =  hash_int_2d(hash_string(object->name.c_str()), 0);
 		}
 
 		object->tag_update(scene);
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index afc6e5455c4..517a0738b44 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -157,6 +157,7 @@ shader_node_categories = [
         NodeItem("ShaderNodeGeometry"),
         NodeItem("ShaderNodeExtendedMaterial"),
         NodeItem("ShaderNodeParticleInfo"),
+        NodeItem("ShaderNodeObjectInfo"),
         NodeItem("NodeGroupInput", poll=group_input_output_item_poll),
         ]),
     ShaderOldNodeCategory("SH_OUTPUT", "Output", items=[
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 668c94bec8a..9a70c42418f 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -64,6 +64,7 @@
 #include "DEG_depsgraph.h"
 
 #include "BLI_strict_flags.h"
+#include "BLI_hash.h"
 
 /* Dupli-Geometry */
 
@@ -180,6 +181,22 @@ static DupliObject *make_dupli(const DupliContext *ctx,
 	if (ob->type == OB_MBALL)
 		dob->no_draw = true;
 
+	/* random number */
+	/* the logic here is designed to match Cycles */
+	dob->random_id = BLI_hash_string(dob->ob->id.name + 2);
+
+	if (dob->persistent_id[0] != INT_MAX) {
+		for(i = 0; i < MAX_DUPLI_RECUR*2; i++)
+			dob->random_id = BLI_hash_int_2d(dob->random_id, (unsigned int)dob->persistent_id[i]);
+	}
+	else {
+		dob->random_id = BLI_hash_int_2d(dob->random_id, 0);
+	}
+
+	if (ctx->object != ob) {
+		dob->random_id ^= BLI_hash_int(BLI_hash_string(ctx->object->id.name + 2));
+	}
+
 	return dob;
 }
 
diff --git a/source/blender/blenlib/BLI_hash.h b/source/blender/blenlib/BLI_hash.h
new file mode 100644
index 00000000000..551143f5d72
--- /dev/null
+++ b/source/blender/blenlib/BLI_hash.h
@@ -0,0 +1,66 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_HASH_H__
+#define __BLI_HASH_H__
+
+/** \file BLI_hash.h
+ *  \ingroup bli
+ */
+
+static inline unsigned int BLI_hash_int_2d(unsigned int kx, unsigned int ky)
+{
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+	unsigned int a, b, c;
+
+	a = b = c = 0xdeadbeef + (2 << 2) + 13;
+	a += kx;
+	b += ky;
+
+	c ^= b; c -= rot(b,14);
+	a ^= c; a -= rot(c,11);
+	b ^= a; b -= rot(a,25);
+	c ^= b; c -= rot(b,16);
+	a ^= c; a -= rot(c,4);
+	b ^= a; b -= rot(a,14);
+	c ^= b; c -= rot(b,24);
+
+	return c;
+
+#undef rot
+}
+
+static inline unsigned int BLI_hash_string(const char *str)
+{
+	unsigned int i = 0, c;
+
+	while((c = *str++))
+		i = i * 37 + c;
+
+	return i;
+}
+
+static inline  unsigned int BLI_hash_int(unsigned int k)
+{
+	return BLI_hash_int_2d(k, 0);
+}
+
+#endif // __BLI_HASH_H__
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index cbcd6383a72..7d08e72bb7b 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -97,6 +97,7 @@ typedef enum GPUBuiltin {
 	GPU_PARTICLE_ANG_VELOCITY = (1 << 12),
 	GPU_LOC_TO_VIEW_MATRIX =    (1 << 13),
 	GPU_INVERSE_LOC_TO_VIEW_MATRIX = (1 << 14),
+	GPU_OBJECT_INFO =           (1 << 15)
 } GPUBuiltin;
 
 typedef enum GPUOpenGLBuiltin {
@@ -212,6 +213,7 @@ bool GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNod
 
 void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link);
 void GPU_material_enable_alpha(GPUMaterial *material);
+GPUBuiltin GPU_get_material_builtins(GPUMaterial *material);
 GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]);
 
 /* High level functions to create and use GPU materials */
@@ -228,7 +230,7 @@ void GPU_material_bind(
         float viewmat[4][4], float viewinv[4][4], float cameraborder[4], bool scenelock);
 void GPU_material_bind_uniforms(
         GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4],
-        float autobumpscale, GPUParticleInfo *pi);
+        float autobumpscale, GPUParticleInfo *pi, float object_info[3]);
 void GPU_material_unbind(GPUMaterial *material);
 bool GPU_material_bound(GPUMaterial *material);
 struct Scene *GPU_material_scene(GPUMaterial *material);
@@ -325,6 +327,7 @@ struct GPUParticleInfo
 	float location[3];
 	float velocity[3];
 	float angular_velocity[3];
+	int random_id;
 };
 
 #ifdef WITH_OPENSUBDIV
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index faf1b907570..de2b94482f4 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -410,6 +410,8 @@ const char *GPU_builtin_name(GPUBuiltin builtin)
 		return "unfparticlevel";
 	else if (builtin == GPU_PARTICLE_ANG_VELOCITY)
 		return "unfparticleangvel";
+	else if (builtin == GPU_OBJECT_INFO)
+		return "unfobjectinfo";
 	else
 		return "";
 }
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index ef23713c271..f0987fb485d 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -43,6 +43,7 @@
 #include "BLI_math.h"
 #include "BLI_threads.h"
 #include "BLI_utildefines.h"
+#include "BLI_hash.h"
 
 #include "DNA_lamp_types.h"
 #include "DNA_material_types.h"
@@ -1880,6 +1881,21 @@ static int gpu_get_particle_info(GPUParticleInfo *pi)
 		return 0;
 }
 
+static void GPU_get_object_info(float oi[3], Material *mat)
+{
+	Object *ob = GMS.gob;
+	oi[0] = ob->index;
+	oi[1] = mat->index;
+	unsigned int random;
+	if (GMS.dob) {
+		random = GMS.dob->random_id;
+	}
+	else {
+		random = BLI_hash_int_2d(BLI_hash_string(GMS.gob->id.name + 2), 0);
+	}
+	oi[2] = random * (1.0f/(float)0xFFFFFFFF);
+}
+
 int GPU_object_material_bind(int nr, void *attribs)
 {
 	GPUVertexAttribs *gattribs = attribs;
@@ -1939,21 +1955,27 @@ int GPU_object_material_bind(int nr, void *attribs)
 			/* bind glsl material and get attributes */
 			Material *mat = GMS.gmatbuf[nr];
 			GPUParticleInfo partile_info;
+			float object_info[3] = {0};
 
 			float auto_bump_scale;
 
 			GPUMaterial *gpumat = GPU_material_from_blender(GMS.gscene, mat, GMS.is_opensubdiv);
 			GPU_material_vertex_attributes(gpumat, gattribs);
 
-			if (GMS.dob)
+			if (GMS.dob) {
 				gpu_get_particle_info(&partile_info);
+			}
+			
+			if (GPU_get_material_builtins(gpumat) & GPU_OBJECT_INFO) {
+				GPU_get_object_info(object_info, mat);
+			}
 
 			GPU_material_bind(
 			        gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT),
 			        GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac, GMS.gscenelock);
 
 			auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f;
-			GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gob->col, auto_bump_scale, &partile_info);
+			GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gob->col, auto_bump_scale, &partile_info, object_info);
 			GMS.gboundmat = mat;
 
 			/* for glsl use alpha blend mode, unless it's set to solid and
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index db5c3cf2f47..aa7a104ff86 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -124,6 +124,8 @@ struct GPUMaterial {
 	int partvel;
 	int partangvel;
 
+	int objectinfoloc;
+
 	ListBase lamps;
 	bool bound;
 
@@ -226,6 +228,8 @@ static int gpu_material_construct_end(GPUMaterial *material, const char *passnam
 			material->partvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_VELOCITY));
 		if (material->builtins & GPU_PARTICLE_ANG_VELOCITY)
 			material->partangvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_ANG_VELOCITY));
+		if (material->builtins & GPU_OBJECT_INFO)
+			material->objectinfoloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_INFO));
 		return 1;
 	}
 	else {
@@ -346,9 +350,14 @@ void GPU_material_bind(
 	}
 }
 
+GPUBuiltin GPU_get_material_builtins(GPUMaterial *material)
+{
+	return material->builtins;
+}
+
 void GPU_material_bind_uniforms(
         GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4],
-        float autobumpscale, GPUParticl

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list