[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44698] trunk/blender: Cycles: float texture support.

Brecht Van Lommel brechtvanlommel at pandora.be
Wed Mar 7 13:27:30 CET 2012


Revision: 44698
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44698
Author:   blendix
Date:     2012-03-07 12:27:18 +0000 (Wed, 07 Mar 2012)
Log Message:
-----------
Cycles: float texture support. Due to GPU limitations there are now 95 byte,
and 5 float image textures. For CPU render this limit will be lifted later
on with image cache support. Patch by Mike Farnsworth.

Also changed color space option in image/environment texture node, to show
options Color and Non-Color Data, instead of sRGB and Linear, this is more
descriptive, and it was not really correct to equate Non-Color Data with
Linear.

Modified Paths:
--------------
    trunk/blender/intern/cycles/kernel/kernel.cpp
    trunk/blender/intern/cycles/kernel/kernel_textures.h
    trunk/blender/intern/cycles/kernel/svm/svm_image.h
    trunk/blender/intern/cycles/render/image.cpp
    trunk/blender/intern/cycles/render/image.h
    trunk/blender/intern/cycles/render/nodes.cpp
    trunk/blender/intern/cycles/render/nodes.h
    trunk/blender/intern/cycles/render/scene.h
    trunk/blender/source/blender/makesdna/DNA_node_types.h
    trunk/blender/source/blender/makesrna/intern/rna_nodetree.c
    trunk/blender/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
    trunk/blender/source/blender/nodes/shader/nodes/node_shader_tex_image.c

Modified: trunk/blender/intern/cycles/kernel/kernel.cpp
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel.cpp	2012-03-07 07:32:15 UTC (rev 44697)
+++ trunk/blender/intern/cycles/kernel/kernel.cpp	2012-03-07 12:27:18 UTC (rev 44698)
@@ -84,6 +84,25 @@
 #define KERNEL_IMAGE_TEX(type, ttype, tname)
 #include "kernel_textures.h"
 
+	else if(strstr(name, "__tex_image_float")) {
+		texture_image_float4 *tex = NULL;
+		int id = atoi(name + strlen("__tex_image_float_"));
+
+		switch(id) {
+			case 95: tex = &kg->__tex_image_float_095; break;
+			case 96: tex = &kg->__tex_image_float_096; break;
+			case 97: tex = &kg->__tex_image_float_097; break;
+			case 98: tex = &kg->__tex_image_float_098; break;
+			case 99: tex = &kg->__tex_image_float_099; break;
+			default: break;
+		}
+
+		if(tex) {
+			tex->data = (float4*)mem;
+			tex->width = width;
+			tex->height = height;
+		}
+	}
 	else if(strstr(name, "__tex_image")) {
 		texture_image_uchar4 *tex = NULL;
 		int id = atoi(name + strlen("__tex_image_"));
@@ -184,11 +203,6 @@
 			case 92: tex = &kg->__tex_image_092; break;
 			case 93: tex = &kg->__tex_image_093; break;
 			case 94: tex = &kg->__tex_image_094; break;
-			case 95: tex = &kg->__tex_image_095; break;
-			case 96: tex = &kg->__tex_image_096; break;
-			case 97: tex = &kg->__tex_image_097; break;
-			case 98: tex = &kg->__tex_image_098; break;
-			case 99: tex = &kg->__tex_image_099; break;
 			default: break;
 		}
 

Modified: trunk/blender/intern/cycles/kernel/kernel_textures.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_textures.h	2012-03-07 07:32:15 UTC (rev 44697)
+++ trunk/blender/intern/cycles/kernel/kernel_textures.h	2012-03-07 12:27:18 UTC (rev 44698)
@@ -142,12 +142,14 @@
 KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_092)
 KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_093)
 KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_094)
-KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_095)
-KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_096)
-KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_097)
-KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_098)
-KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_099)
 
+/* full-float image */
+KERNEL_IMAGE_TEX(float4, texture_image_float4, __tex_image_float_095)
+KERNEL_IMAGE_TEX(float4, texture_image_float4, __tex_image_float_096)
+KERNEL_IMAGE_TEX(float4, texture_image_float4, __tex_image_float_097)
+KERNEL_IMAGE_TEX(float4, texture_image_float4, __tex_image_float_098)
+KERNEL_IMAGE_TEX(float4, texture_image_float4, __tex_image_float_099)
+
 #undef KERNEL_TEX
 #undef KERNEL_IMAGE_TEX
 

Modified: trunk/blender/intern/cycles/kernel/svm/svm_image.h
===================================================================
--- trunk/blender/intern/cycles/kernel/svm/svm_image.h	2012-03-07 07:32:15 UTC (rev 44697)
+++ trunk/blender/intern/cycles/kernel/svm/svm_image.h	2012-03-07 12:27:18 UTC (rev 44698)
@@ -130,11 +130,11 @@
 		case 92: r = kernel_tex_image_interp(__tex_image_092, x, y); break;
 		case 93: r = kernel_tex_image_interp(__tex_image_093, x, y); break;
 		case 94: r = kernel_tex_image_interp(__tex_image_094, x, y); break;
-		case 95: r = kernel_tex_image_interp(__tex_image_095, x, y); break;
-		case 96: r = kernel_tex_image_interp(__tex_image_096, x, y); break;
-		case 97: r = kernel_tex_image_interp(__tex_image_097, x, y); break;
-		case 98: r = kernel_tex_image_interp(__tex_image_098, x, y); break;
-		case 99: r = kernel_tex_image_interp(__tex_image_099, x, y); break;
+		case 95: r = kernel_tex_image_interp(__tex_image_float_095, x, y); break;
+		case 96: r = kernel_tex_image_interp(__tex_image_float_096, x, y); break;
+		case 97: r = kernel_tex_image_interp(__tex_image_float_097, x, y); break;
+		case 98: r = kernel_tex_image_interp(__tex_image_float_098, x, y); break;
+		case 99: r = kernel_tex_image_interp(__tex_image_float_099, x, y); break;
 		default: 
 			kernel_assert(0);
 			return make_float4(0.0f, 0.0f, 0.0f, 0.0f);

Modified: trunk/blender/intern/cycles/render/image.cpp
===================================================================
--- trunk/blender/intern/cycles/render/image.cpp	2012-03-07 07:32:15 UTC (rev 44697)
+++ trunk/blender/intern/cycles/render/image.cpp	2012-03-07 12:27:18 UTC (rev 44698)
@@ -39,9 +39,10 @@
 
 ImageManager::~ImageManager()
 {
-	for(size_t slot = 0; slot < images.size(); slot++) {
+	for(size_t slot = 0; slot < images.size(); slot++)
 		assert(!images[slot]);
-	}
+	for(size_t slot = 0; slot < float_images.size(); slot++)
+		assert(!float_images[slot]);
 }
 
 void ImageManager::set_osl_texture_system(void *texture_system)
@@ -49,39 +50,111 @@
 	osl_texture_system = texture_system;
 }
 
-int ImageManager::add_image(const string& filename)
+static bool is_float_image(const string& filename)
 {
+	ImageInput *in = ImageInput::create(filename);
+	bool is_float = false;
+
+	if(in) {
+		ImageSpec spec;
+
+		if(in->open(filename, spec)) {
+			/* check the main format, and channel formats;
+			   if any are non-integer, we'll need a float texture slot */
+			if(spec.format == TypeDesc::HALF ||
+			   spec.format == TypeDesc::FLOAT ||
+			   spec.format == TypeDesc::DOUBLE) {
+				is_float = true;
+			}
+
+			for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
+				if(spec.channelformats[channel] == TypeDesc::HALF ||
+				   spec.channelformats[channel] == TypeDesc::FLOAT ||
+				   spec.channelformats[channel] == TypeDesc::DOUBLE) {
+					is_float = true;
+				}
+			}
+
+			in->close();
+		}
+
+		delete in;
+	}
+
+	return is_float;
+}
+
+int ImageManager::add_image(const string& filename, bool& is_float)
+{
 	Image *img;
 	size_t slot;
 
-	/* find existing image */
-	for(slot = 0; slot < images.size(); slot++) {
-		if(images[slot] && images[slot]->filename == filename) {
-			images[slot]->users++;
-			return slot;
+	/* load image info and find out if we need a float texture */
+	is_float = is_float_image(filename);
+
+	if(is_float) {
+		/* find existing image */
+		for(slot = 0; slot < float_images.size(); slot++) {
+			if(float_images[slot] && float_images[slot]->filename == filename) {
+				float_images[slot]->users++;
+				return slot+TEX_IMAGE_FLOAT_START;
+			}
 		}
+
+		/* find free slot */
+		for(slot = 0; slot < float_images.size(); slot++) {
+			if(!float_images[slot])
+				break;
+		}
+
+		if(slot == float_images.size()) {
+			/* max images limit reached */
+			if(float_images.size() == TEX_NUM_FLOAT_IMAGES)
+				return -1;
+
+			float_images.resize(float_images.size() + 1);
+		}
+
+		/* add new image */
+		img = new Image();
+		img->filename = filename;
+		img->need_load = true;
+		img->users = 1;
+
+		float_images[slot] = img;
+		/* report slot out of total set of textures */
+		slot += TEX_IMAGE_FLOAT_START;
 	}
+	else {
+		for(slot = 0; slot < images.size(); slot++) {
+			if(images[slot] && images[slot]->filename == filename) {
+				images[slot]->users++;
+				return slot;
+			}
+		}
 
-	/* find free slot */
-	for(slot = 0; slot < images.size(); slot++)
-		if(!images[slot])
-			break;
-	
-	if(slot == images.size()) {
-		/* max images limit reached */
-		if(images.size() == TEX_IMAGE_MAX)
-			return -1;
+		/* find free slot */
+		for(slot = 0; slot < images.size(); slot++) {
+			if(!images[slot])
+				break;
+		}
 
-		images.resize(images.size() + 1);
+		if(slot == images.size()) {
+			/* max images limit reached */
+			if(images.size() == TEX_NUM_IMAGES)
+				return -1;
+
+			images.resize(images.size() + 1);
+		}
+
+		/* add new image */
+		img = new Image();
+		img->filename = filename;
+		img->need_load = true;
+		img->users = 1;
+
+		images[slot] = img;
 	}
-	
-	/* add new image */
-	img = new Image();
-	img->filename = filename;
-	img->need_load = true;
-	img->users = 1;
-
-	images[slot] = img;
 	need_update = true;
 
 	return slot;
@@ -91,24 +164,40 @@
 {
 	size_t slot;
 
-	for(slot = 0; slot < images.size(); slot++)
-		if(images[slot] && images[slot]->filename == filename)
+	for(slot = 0; slot < images.size(); slot++) {
+		if(images[slot] && images[slot]->filename == filename) {
+			/* decrement user count */
+			images[slot]->users--;
+			assert(images[slot]->users >= 0);
+
+			/* don't remove immediately, rather do it all together later on. one of
+			   the reasons for this is that on shader changes we add and remove nodes
+			   that use them, but we do not want to reload the image all the time. */
+			if(images[slot]->users == 0)
+				need_update = true;
+
 			break;
-	
-	if(slot == images.size())
-		return;
+		}
+	}
 
-	assert(images[slot]);
+	if(slot == images.size()) {
+		/* see if it's in a float texture slot */
+		for(slot = 0; slot < float_images.size(); slot++) {
+			if(float_images[slot] && float_images[slot]->filename == filename) {
+				/* decrement user count */
+				float_images[slot]->users--;
+				assert(float_images[slot]->users >= 0);
 
-	/* decrement user count */
-	images[slot]->users--;
-	assert(images[slot]->users >= 0);
-	
-	/* don't remove immediately, rather do it all together later on. one of
-	   the reasons for this is that on shader changes we add and remove nodes
-	   that use them, but we do not want to reload the image all the time. */
-	if(images[slot]->users == 0)
-		need_update = true;
+				/* don't remove immediately, rather do it all together later on. one of
+				   the reasons for this is that on shader changes we add and remove nodes
+				   that use them, but we do not want to reload the image all the time. */
+				if(float_images[slot]->users == 0)
+					need_update = true;
+
+				break;
+			}
+		}
+	}
 }
 
 bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
@@ -173,51 +262,168 @@
 	return true;
 }
 
+bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_img)
+{
+	if(img->filename == "")
+		return false;
+
+	/* load image from file through OIIO */
+	ImageInput *in = ImageInput::create(img->filename);
+
+	if(!in)
+		return false;
+
+	ImageSpec spec;
+
+	if(!in->open(img->filename, spec)) {
+		delete in;
+		return false;
+	}
+
+	/* we only handle certain number of components */
+	int width = spec.width;
+	int height = spec.height;
+	int components = spec.nchannels;
+
+	if(!(components == 1 || components == 3 || components == 4)) {
+		in->close();
+		delete in;
+		return false;
+	}
+
+	/* read RGBA pixels */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list