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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
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 @@ 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]);
|
||||
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 @@ 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(!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);
|
||||
|
||||
pixels[0] = 0;
|
||||
pixels[1] = 0;
|
||||
pixels[2] = 0;
|
||||
pixels[3] = 0;
|
||||
if(slot < TEX_IMAGE_FLOAT_START) {
|
||||
img = images[slot];
|
||||
is_float = false;
|
||||
}
|
||||
else {
|
||||
img = float_images[slot - TEX_IMAGE_FLOAT_START];
|
||||
is_float = true;
|
||||
}
|
||||
|
||||
string name;
|
||||
if(is_float) {
|
||||
device_vector<float4>& tex_img = dscene->tex_float_image[slot - TEX_IMAGE_FLOAT_START];
|
||||
|
||||
if(slot >= 10) name = string_printf("__tex_image_0%d", slot);
|
||||
else name = string_printf("__tex_image_00%d", slot);
|
||||
if(tex_img.device_pointer)
|
||||
device->tex_free(tex_img);
|
||||
|
||||
device->tex_alloc(name.c_str(), tex_img, true, true);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
|
@@ -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);
|
||||
|
@@ -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");
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -582,8 +582,8 @@ typedef struct TexNodeOutput {
|
||||
#define SHD_WAVE_TRI 2
|
||||
|
||||
/* image/environment texture */
|
||||
#define SHD_COLORSPACE_LINEAR 0
|
||||
#define SHD_COLORSPACE_SRGB 1
|
||||
#define SHD_COLORSPACE_NONE 0
|
||||
#define SHD_COLORSPACE_COLOR 1
|
||||
|
||||
/* blur node */
|
||||
#define CMP_NODE_BLUR_ASPECT_NONE 0
|
||||
|
@@ -1264,8 +1264,8 @@ static void def_sh_tex_sky(StructRNA *srna)
|
||||
static void def_sh_tex_environment(StructRNA *srna)
|
||||
{
|
||||
static const EnumPropertyItem prop_color_space_items[] = {
|
||||
{SHD_COLORSPACE_SRGB, "SRGB", 0, "sRGB", "Image is in sRGB color space"},
|
||||
{SHD_COLORSPACE_LINEAR, "LINEAR", 0, "Linear", "Image is in scene linear color space"},
|
||||
{SHD_COLORSPACE_COLOR, "COLOR", 0, "Color", "Image contains color data, and will be converted to linear color for rendering"},
|
||||
{SHD_COLORSPACE_NONE, "NONE", 0, "Non-Color Data", "Image contains non-color data, for example a displacement or normal map, and will not be converted"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
PropertyRNA *prop;
|
||||
@@ -1289,8 +1289,8 @@ static void def_sh_tex_environment(StructRNA *srna)
|
||||
static void def_sh_tex_image(StructRNA *srna)
|
||||
{
|
||||
static const EnumPropertyItem prop_color_space_items[] = {
|
||||
{SHD_COLORSPACE_LINEAR, "LINEAR", 0, "Linear", "Image is in scene linear color space"},
|
||||
{SHD_COLORSPACE_SRGB, "SRGB", 0, "sRGB", "Image is in sRGB color space"},
|
||||
{SHD_COLORSPACE_COLOR, "COLOR", 0, "Color", "Image contains color data, and will be converted to linear color for rendering"},
|
||||
{SHD_COLORSPACE_NONE, "NONE", 0, "Non-Color Data", "Image contains non-color data, for example a displacement or normal map, and will not be converted"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
PropertyRNA *prop;
|
||||
|
@@ -44,7 +44,7 @@ static void node_shader_init_tex_environment(bNodeTree *UNUSED(ntree), bNode* no
|
||||
NodeTexEnvironment *tex = MEM_callocN(sizeof(NodeTexEnvironment), "NodeTexEnvironment");
|
||||
default_tex_mapping(&tex->base.tex_mapping);
|
||||
default_color_mapping(&tex->base.color_mapping);
|
||||
tex->color_space = SHD_COLORSPACE_SRGB;
|
||||
tex->color_space = SHD_COLORSPACE_COLOR;
|
||||
|
||||
node->storage = tex;
|
||||
}
|
||||
|
@@ -44,7 +44,7 @@ static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode* node, bN
|
||||
NodeTexImage *tex = MEM_callocN(sizeof(NodeTexImage), "NodeTexImage");
|
||||
default_tex_mapping(&tex->base.tex_mapping);
|
||||
default_color_mapping(&tex->base.color_mapping);
|
||||
tex->color_space = SHD_COLORSPACE_SRGB;
|
||||
tex->color_space = SHD_COLORSPACE_COLOR;
|
||||
|
||||
node->storage = tex;
|
||||
}
|
||||
|
Reference in New Issue
Block a user