Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-03-07 16:27:18 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-03-07 16:27:18 +0400
commit9fba458a7fe535e60f5c6beee9757fe25ffe2d49 (patch)
treee625eb73d3da32a01c84385e1976f81d2f8b92bd /intern
parentbdf731f03d727d3862537c59fa11477b77eb60b0 (diff)
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.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/kernel.cpp24
-rw-r--r--intern/cycles/kernel/kernel_textures.h12
-rw-r--r--intern/cycles/kernel/svm/svm_image.h10
-rw-r--r--intern/cycles/render/image.cpp347
-rw-r--r--intern/cycles/render/image.h9
-rw-r--r--intern/cycles/render/nodes.cpp33
-rw-r--r--intern/cycles/render/nodes.h2
-rw-r--r--intern/cycles/render/scene.h3
8 files changed, 351 insertions, 89 deletions
diff --git a/intern/cycles/kernel/kernel.cpp b/intern/cycles/kernel/kernel.cpp
index a93f6172d28..667db1e5f03 100644
--- a/intern/cycles/kernel/kernel.cpp
+++ b/intern/cycles/kernel/kernel.cpp
@@ -84,6 +84,25 @@ void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t
#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 @@ void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t
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;
}
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index ca7ae432efa..8bab735d0d1 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -142,11 +142,13 @@ KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_091)
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
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index 073021bdd54..3d737b483cb 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -130,11 +130,11 @@ __device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y)
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);
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index de3ab8edf48..78b8f06c7b4 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -39,9 +39,10 @@ ImageManager::ImageManager()
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 @@ void ImageManager::set_osl_texture_system(void *texture_system)
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;
+ }
+
+ if(slot == images.size()) {
+ /* max images limit reached */
+ if(images.size() == TEX_NUM_IMAGES)
+ return -1;
+
+ images.resize(images.size() + 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 @@ void ImageManager::remove_image(const string& filename)
{
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]);
-
- /* 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;
+ 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);
+
+ /* 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 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
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 */
+ float *pixels = (float*)tex_img.resize(width, height);
+ int scanlinesize = width*components*sizeof(float);
+
+ in->read_image(TypeDesc::FLOAT,
+ (uchar*)pixels + (height-1)*scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride);
+
+ in->close();
+ delete in;
+
+ if(components == 3) {
+ for(int i = width*height-1; i >= 0; i--) {
+ pixels[i*4+3] = 1.0f;
+ pixels[i*4+2] = pixels[i*3+2];
+ pixels[i*4+1] = pixels[i*3+1];
+ pixels[i*4+0] = pixels[i*3+0];
+ }
+ }
+ else if(components == 1) {
+ for(int i = width*height-1; i >= 0; i--) {
+ pixels[i*4+3] = 1.0f;
+ pixels[i*4+2] = pixels[i];
+ pixels[i*4+1] = pixels[i];
+ pixels[i*4+0] = pixels[i];
+ }
+ }
+
+ return true;
+}
+
void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int slot)
{
if(osl_texture_system)
return;
- Image *img = images[slot];
- device_vector<uchar4>& tex_img = dscene->tex_image[slot];
+ Image *img;
+ bool is_float;
- if(tex_img.device_pointer)
- device->tex_free(tex_img);
+ if(slot < TEX_IMAGE_FLOAT_START) {
+ img = images[slot];
+ is_float = false;
+ }
+ else {
+ img = float_images[slot - TEX_IMAGE_FLOAT_START];
+ is_float = true;
+ }
- if(!file_load_image(img, tex_img)) {
- /* on failure to load, we set a 1x1 pixels black image */
- uchar *pixels = (uchar*)tex_img.resize(1, 1);
+ if(is_float) {
+ device_vector<float4>& tex_img = dscene->tex_float_image[slot - TEX_IMAGE_FLOAT_START];
+
+ if(tex_img.device_pointer)
+ device->tex_free(tex_img);
+
+ if(!file_load_float_image(img, tex_img)) {
+ /* on failure to load, we set a 1x1 pixels black image */
+ float *pixels = (float*)tex_img.resize(1, 1);
+
+ pixels[0] = 0.0f;
+ pixels[1] = 0.0f;
+ pixels[2] = 0.0f;
+ pixels[3] = 0.0f;
+ }
- pixels[0] = 0;
- pixels[1] = 0;
- pixels[2] = 0;
- pixels[3] = 0;
+ string name;
+
+ if(slot >= 10) name = string_printf("__tex_image_float_0%d", slot);
+ else name = string_printf("__tex_image_float_00%d", slot);
+
+ device->tex_alloc(name.c_str(), tex_img, true, true);
}
+ else {
+ device_vector<uchar4>& tex_img = dscene->tex_image[slot];
+
+ if(tex_img.device_pointer)
+ device->tex_free(tex_img);
+
+ if(!file_load_image(img, tex_img)) {
+ /* on failure to load, we set a 1x1 pixels black image */
+ uchar *pixels = (uchar*)tex_img.resize(1, 1);
- string name;
+ pixels[0] = 0;
+ pixels[1] = 0;
+ pixels[2] = 0;
+ pixels[3] = 0;
+ }
+
+ string name;
- if(slot >= 10) name = string_printf("__tex_image_0%d", slot);
- else name = string_printf("__tex_image_00%d", slot);
+ if(slot >= 10) name = string_printf("__tex_image_0%d", slot);
+ else name = string_printf("__tex_image_00%d", slot);
- device->tex_alloc(name.c_str(), tex_img, true, true);
+ device->tex_alloc(name.c_str(), tex_img, true, true);
+ }
}
void ImageManager::device_free_image(Device *device, DeviceScene *dscene, int slot)
{
- if(images[slot]) {
+ Image *img;
+ bool is_float;
+
+ if(slot < TEX_IMAGE_FLOAT_START) {
+ img = images[slot];
+ is_float = false;
+ }
+ else {
+ img = float_images[slot - TEX_IMAGE_FLOAT_START];
+ is_float = true;
+ }
+
+ if(img) {
if(osl_texture_system) {
#ifdef WITH_OSL
ustring filename(images[slot]->filename);
((OSL::TextureSystem*)osl_texture_system)->invalidate(filename);
#endif
}
+ else if(is_float) {
+ device->tex_free(dscene->tex_float_image[slot - TEX_IMAGE_FLOAT_START]);
+ dscene->tex_float_image[slot - TEX_IMAGE_FLOAT_START].clear();
+
+ delete float_images[slot - TEX_IMAGE_FLOAT_START];
+ float_images[slot - TEX_IMAGE_FLOAT_START] = NULL;
+ }
else {
device->tex_free(dscene->tex_image[slot]);
dscene->tex_image[slot].clear();
- }
- delete images[slot];
- images[slot] = NULL;
+ delete images[slot];
+ images[slot] = NULL;
+ }
}
}
@@ -242,6 +448,22 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress&
}
}
+ for(size_t slot = 0; slot < float_images.size(); slot++) {
+ if(float_images[slot]) {
+ if(float_images[slot]->users == 0) {
+ device_free_image(device, dscene, slot + TEX_IMAGE_FLOAT_START);
+ }
+ else if(float_images[slot]->need_load) {
+ string name = path_filename(float_images[slot]->filename);
+ progress.set_status("Updating Images", "Loading " + name);
+ device_load_image(device, dscene, slot + TEX_IMAGE_FLOAT_START);
+ float_images[slot]->need_load = false;
+ }
+
+ if(progress.get_cancel()) return;
+ }
+ }
+
need_update = false;
}
@@ -249,8 +471,11 @@ void ImageManager::device_free(Device *device, DeviceScene *dscene)
{
for(size_t slot = 0; slot < images.size(); slot++)
device_free_image(device, dscene, slot);
+ for(size_t slot = 0; slot < float_images.size(); slot++)
+ device_free_image(device, dscene, slot + TEX_IMAGE_FLOAT_START);
images.clear();
+ float_images.clear();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 0d49a1e6b67..d789e6885e3 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -26,7 +26,10 @@
CCL_NAMESPACE_BEGIN
-#define TEX_IMAGE_MAX 100
+#define TEX_NUM_FLOAT_IMAGES 5
+#define TEX_NUM_IMAGES 95
+#define TEX_IMAGE_MAX (TEX_NUM_IMAGES + TEX_NUM_FLOAT_IMAGES)
+#define TEX_IMAGE_FLOAT_START TEX_NUM_IMAGES
class Device;
class DeviceScene;
@@ -37,7 +40,7 @@ public:
ImageManager();
~ImageManager();
- int add_image(const string& filename);
+ int add_image(const string& filename, bool& is_float);
void remove_image(const string& filename);
void device_update(Device *device, DeviceScene *dscene, Progress& progress);
@@ -56,9 +59,11 @@ private:
};
vector<Image*> images;
+ vector<Image*> float_images;
void *osl_texture_system;
bool file_load_image(Image *img, device_vector<uchar4>& tex_img);
+ bool file_load_float_image(Image *img, device_vector<float4>& tex_img);
void device_load_image(Device *device, DeviceScene *dscene, int slot);
void device_free_image(Device *device, DeviceScene *dscene, int slot);
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 982521b31f2..86f0f3127e9 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -93,8 +93,8 @@ static ShaderEnum color_space_init()
{
ShaderEnum enm;
- enm.insert("Linear", 0);
- enm.insert("sRGB", 1);
+ enm.insert("None", 0);
+ enm.insert("Color", 1);
return enm;
}
@@ -106,8 +106,9 @@ ImageTextureNode::ImageTextureNode()
{
image_manager = NULL;
slot = -1;
+ is_float = false;
filename = "";
- color_space = ustring("sRGB");
+ color_space = ustring("Color");
add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_UV);
add_output("Color", SHADER_SOCKET_COLOR);
@@ -125,6 +126,7 @@ ShaderNode *ImageTextureNode::clone() const
ImageTextureNode *node = new ImageTextureNode(*this);
node->image_manager = NULL;
node->slot = -1;
+ node->is_float = false;
return node;
}
@@ -136,7 +138,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
if(slot == -1)
- slot = image_manager->add_image(filename);
+ slot = image_manager->add_image(filename, is_float);
if(!color_out->links.empty())
compiler.stack_assign(color_out);
@@ -144,6 +146,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
compiler.stack_assign(alpha_out);
if(slot != -1) {
+ int srgb = (is_float || color_space != "Color")? 0: 1;
compiler.stack_assign(vector_in);
if(!tex_mapping.skip())
@@ -155,7 +158,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
vector_in->stack_offset,
color_out->stack_offset,
alpha_out->stack_offset,
- color_space_enum[color_space]));
+ srgb));
}
else {
/* image not found */
@@ -171,7 +174,10 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
void ImageTextureNode::compile(OSLCompiler& compiler)
{
compiler.parameter("filename", filename.c_str());
- compiler.parameter("color_space", color_space.c_str());
+ if(is_float || color_space != "Color")
+ compiler.parameter("color_space", "Linear");
+ else
+ compiler.parameter("color_space", "sRGB");
compiler.add(this, "node_image_texture");
}
@@ -184,8 +190,9 @@ EnvironmentTextureNode::EnvironmentTextureNode()
{
image_manager = NULL;
slot = -1;
+ is_float = false;
filename = "";
- color_space = ustring("sRGB");
+ color_space = ustring("Color");
add_input("Vector", SHADER_SOCKET_VECTOR, ShaderInput::POSITION);
add_output("Color", SHADER_SOCKET_COLOR);
@@ -203,6 +210,7 @@ ShaderNode *EnvironmentTextureNode::clone() const
EnvironmentTextureNode *node = new EnvironmentTextureNode(*this);
node->image_manager = NULL;
node->slot = -1;
+ node->is_float = false;
return node;
}
@@ -214,7 +222,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
if(slot == -1)
- slot = image_manager->add_image(filename);
+ slot = image_manager->add_image(filename, is_float);
if(!color_out->links.empty())
compiler.stack_assign(color_out);
@@ -222,6 +230,8 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
compiler.stack_assign(alpha_out);
if(slot != -1) {
+ int srgb = (is_float || color_space != "Color")? 0: 1;
+
compiler.stack_assign(vector_in);
if(!tex_mapping.skip())
@@ -233,7 +243,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
vector_in->stack_offset,
color_out->stack_offset,
alpha_out->stack_offset,
- color_space_enum[color_space]));
+ srgb));
}
else {
/* image not found */
@@ -249,7 +259,10 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
void EnvironmentTextureNode::compile(OSLCompiler& compiler)
{
compiler.parameter("filename", filename.c_str());
- compiler.parameter("color_space", color_space.c_str());
+ if(is_float || color_space != "Color")
+ compiler.parameter("color_space", "Linear");
+ else
+ compiler.parameter("color_space", "sRGB");
compiler.add(this, "node_environment_texture");
}
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 338af4ef48a..6c9ed422b88 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -64,6 +64,7 @@ public:
ImageManager *image_manager;
int slot;
+ bool is_float;
string filename;
ustring color_space;
@@ -78,6 +79,7 @@ public:
ImageManager *image_manager;
int slot;
+ bool is_float;
string filename;
ustring color_space;
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index c251174b607..0a4f0ef5d95 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -92,7 +92,8 @@ public:
device_vector<uint> sobol_directions;
/* images */
- device_vector<uchar4> tex_image[TEX_IMAGE_MAX];
+ device_vector<uchar4> tex_image[TEX_NUM_IMAGES];
+ device_vector<float4> tex_float_image[TEX_NUM_FLOAT_IMAGES];
KernelData data;
};