From 7c78c20b6bf6f7dd00397c456fb9e2116febfca7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 19 May 2019 02:46:24 +0200 Subject: Cleanup: refactor image texture node code for coming changes --- .../kernel/shaders/node_environment_texture.osl | 12 +++-- .../cycles/kernel/shaders/node_image_texture.osl | 54 ++++++++++++++-------- intern/cycles/kernel/svm/svm_image.h | 33 ++++++------- intern/cycles/kernel/svm/svm_types.h | 5 ++ intern/cycles/render/nodes.cpp | 30 ++++++++---- 5 files changed, 84 insertions(+), 50 deletions(-) (limited to 'intern') diff --git a/intern/cycles/kernel/shaders/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl index eb32dad392f..43f607f7cb0 100644 --- a/intern/cycles/kernel/shaders/node_environment_texture.osl +++ b/intern/cycles/kernel/shaders/node_environment_texture.osl @@ -47,9 +47,10 @@ shader node_environment_texture( string filename = "", string projection = "equirectangular", string interpolation = "linear", - string color_space = "sRGB", + int compress_as_srgb = 0, + int ignore_alpha = 0, + int unassociate_alpha = 0, int is_float = 1, - int use_alpha = 1, output color Color = 0.0, output float Alpha = 1.0) { @@ -69,13 +70,16 @@ shader node_environment_texture( Color = (color)texture( filename, p[0], 1.0 - p[1], "wrap", "periodic", "interp", interpolation, "alpha", Alpha); - if (use_alpha) { + if (ignore_alpha) { + Alpha = 1.0; + } + else if (unassociate_alpha) { Color = color_unpremultiply(Color, Alpha); if (!is_float) Color = min(Color, 1.0); } - if (color_space == "sRGB") + if (compress_as_srgb) Color = color_srgb_to_scene_linear(Color); } diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl index df5eda39985..f78ca7ec0e8 100644 --- a/intern/cycles/kernel/shaders/node_image_texture.osl +++ b/intern/cycles/kernel/shaders/node_image_texture.osl @@ -56,11 +56,12 @@ point map_to_sphere(vector dir) } color image_texture_lookup(string filename, - string color_space, float u, float v, output float Alpha, - int use_alpha, + int compress_as_srgb, + int ignore_alpha, + int unassociate_alpha, int is_float, string interpolation, string extension) @@ -68,14 +69,17 @@ color image_texture_lookup(string filename, color rgb = (color)texture( filename, u, 1.0 - v, "wrap", extension, "interp", interpolation, "alpha", Alpha); - if (use_alpha) { + if (ignore_alpha) { + Alpha = 1.0; + } + else if (unassociate_alpha) { rgb = color_unpremultiply(rgb, Alpha); if (!is_float) rgb = min(rgb, 1.0); } - if (color_space == "sRGB") { + if (compress_as_srgb) { rgb = color_srgb_to_scene_linear(rgb); } @@ -86,13 +90,14 @@ shader node_image_texture(int use_mapping = 0, matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), point Vector = P, string filename = "", - string color_space = "sRGB", string projection = "flat", string interpolation = "smartcubic", string extension = "periodic", float projection_blend = 0.0, + int compress_as_srgb = 0, + int ignore_alpha = 0, + int unassociate_alpha = 0, int is_float = 1, - int use_alpha = 1, output color Color = 0.0, output float Alpha = 1.0) { @@ -102,8 +107,16 @@ shader node_image_texture(int use_mapping = 0, p = transform(mapping, p); if (projection == "flat") { - Color = image_texture_lookup( - filename, color_space, p[0], p[1], Alpha, use_alpha, is_float, interpolation, extension); + Color = image_texture_lookup(filename, + p[0], + p[1], + Alpha, + compress_as_srgb, + ignore_alpha, + unassociate_alpha, + is_float, + interpolation, + extension); } else if (projection == "box") { /* object space normal */ @@ -173,11 +186,12 @@ shader node_image_texture(int use_mapping = 0, if (weight[0] > 0.0) { Color += weight[0] * image_texture_lookup(filename, - color_space, p[1], p[2], tmp_alpha, - use_alpha, + compress_as_srgb, + ignore_alpha, + unassociate_alpha, is_float, interpolation, extension); @@ -185,11 +199,12 @@ shader node_image_texture(int use_mapping = 0, } if (weight[1] > 0.0) { Color += weight[1] * image_texture_lookup(filename, - color_space, p[0], p[2], tmp_alpha, - use_alpha, + compress_as_srgb, + ignore_alpha, + unassociate_alpha, is_float, interpolation, extension); @@ -197,11 +212,12 @@ shader node_image_texture(int use_mapping = 0, } if (weight[2] > 0.0) { Color += weight[2] * image_texture_lookup(filename, - color_space, p[1], p[0], tmp_alpha, - use_alpha, + compress_as_srgb, + ignore_alpha, + unassociate_alpha, is_float, interpolation, extension); @@ -211,11 +227,12 @@ shader node_image_texture(int use_mapping = 0, else if (projection == "sphere") { point projected = map_to_sphere(texco_remap_square(p)); Color = image_texture_lookup(filename, - color_space, projected[0], projected[1], Alpha, - use_alpha, + compress_as_srgb, + ignore_alpha, + unassociate_alpha, is_float, interpolation, extension); @@ -223,11 +240,12 @@ shader node_image_texture(int use_mapping = 0, else if (projection == "tube") { point projected = map_to_tube(texco_remap_square(p)); Color = image_texture_lookup(filename, - color_space, projected[0], projected[1], Alpha, - use_alpha, + compress_as_srgb, + ignore_alpha, + unassociate_alpha, is_float, interpolation, extension); diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index ee4b8b6e50c..2ef64662d0e 100644 --- a/intern/cycles/kernel/svm/svm_image.h +++ b/intern/cycles/kernel/svm/svm_image.h @@ -16,13 +16,12 @@ CCL_NAMESPACE_BEGIN -ccl_device float4 -svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb, uint use_alpha) +ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint flags) { float4 r = kernel_tex_image_interp(kg, id, x, y); const float alpha = r.w; - if (use_alpha && alpha != 1.0f && alpha != 0.0f) { + if ((flags & NODE_IMAGE_ALPHA_UNASSOCIATE) && alpha != 1.0f && alpha != 0.0f) { r /= alpha; const int texture_type = kernel_tex_type(id); if (texture_type == IMAGE_DATA_TYPE_BYTE4 || texture_type == IMAGE_DATA_TYPE_BYTE) { @@ -31,8 +30,7 @@ svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb, uint u r.w = alpha; } - if (srgb) { - /* TODO(lukas): Implement proper conversion for image textures. */ + if (flags & NODE_IMAGE_COMPRESS_AS_SRGB) { r = color_srgb_to_linear_v4(r); } @@ -48,13 +46,12 @@ ccl_device_inline float3 texco_remap_square(float3 co) ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { uint id = node.y; - uint co_offset, out_offset, alpha_offset, srgb; + uint co_offset, out_offset, alpha_offset, flags; - decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); + decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &flags); float3 co = stack_load_float3(stack, co_offset); float2 tex_co; - uint use_alpha = stack_valid(alpha_offset); if (node.w == NODE_IMAGE_PROJ_SPHERE) { co = texco_remap_square(co); tex_co = map_to_sphere(co); @@ -66,7 +63,7 @@ ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *sta else { tex_co = make_float2(co.x, co.y); } - float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, srgb, use_alpha); + float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, flags); if (stack_valid(out_offset)) stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); @@ -145,27 +142,26 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float } /* now fetch textures */ - uint co_offset, out_offset, alpha_offset, srgb; - decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); + uint co_offset, out_offset, alpha_offset, flags; + decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &flags); float3 co = stack_load_float3(stack, co_offset); uint id = node.y; float4 f = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - uint use_alpha = stack_valid(alpha_offset); /* Map so that no textures are flipped, rotation is somewhat arbitrary. */ if (weight.x > 0.0f) { float2 uv = make_float2((signed_N.x < 0.0f) ? 1.0f - co.y : co.y, co.z); - f += weight.x * svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); + f += weight.x * svm_image_texture(kg, id, uv.x, uv.y, flags); } if (weight.y > 0.0f) { float2 uv = make_float2((signed_N.y > 0.0f) ? 1.0f - co.x : co.x, co.z); - f += weight.y * svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); + f += weight.y * svm_image_texture(kg, id, uv.x, uv.y, flags); } if (weight.z > 0.0f) { float2 uv = make_float2((signed_N.z > 0.0f) ? 1.0f - co.y : co.y, co.x); - f += weight.z * svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); + f += weight.z * svm_image_texture(kg, id, uv.x, uv.y, flags); } if (stack_valid(out_offset)) @@ -180,10 +176,10 @@ ccl_device void svm_node_tex_environment(KernelGlobals *kg, uint4 node) { uint id = node.y; - uint co_offset, out_offset, alpha_offset, srgb; + uint co_offset, out_offset, alpha_offset, flags; uint projection = node.w; - decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); + decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &flags); float3 co = stack_load_float3(stack, co_offset); float2 uv; @@ -195,8 +191,7 @@ ccl_device void svm_node_tex_environment(KernelGlobals *kg, else uv = direction_to_mirrorball(co); - uint use_alpha = stack_valid(alpha_offset); - float4 f = svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); + float4 f = svm_image_texture(kg, id, uv.x, uv.y, flags); if (stack_valid(out_offset)) stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 2e4d0c81b95..ea92fd7ce59 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -380,6 +380,11 @@ typedef enum NodeImageProjection { NODE_IMAGE_PROJ_TUBE = 3, } NodeImageProjection; +typedef enum NodeImageFlags { + NODE_IMAGE_COMPRESS_AS_SRGB = 1, + NODE_IMAGE_ALPHA_UNASSOCIATE = 2, +} NodeImageFlags; + typedef enum NodeEnvironmentProjection { NODE_ENVIRONMENT_EQUIRECTANGULAR = 0, NODE_ENVIRONMENT_MIRROR_BALL = 1, diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index e4fa92fb1d7..27e6309ab2d 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -310,6 +310,14 @@ void ImageTextureNode::compile(SVMCompiler &compiler) if (slot != -1) { int vector_offset = tex_mapping.compile_begin(compiler, vector_in); + uint flags = 0; + + if (compress_as_srgb) { + flags |= NODE_IMAGE_COMPRESS_AS_SRGB; + } + if (!alpha_out->links.empty()) { + flags |= NODE_IMAGE_ALPHA_UNASSOCIATE; + } if (projection != NODE_IMAGE_PROJ_BOX) { compiler.add_node(NODE_TEX_IMAGE, @@ -317,7 +325,7 @@ void ImageTextureNode::compile(SVMCompiler &compiler) compiler.encode_uchar4(vector_offset, compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(alpha_out), - compress_as_srgb), + flags), projection); } else { @@ -326,7 +334,7 @@ void ImageTextureNode::compile(SVMCompiler &compiler) compiler.encode_uchar4(vector_offset, compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(alpha_out), - compress_as_srgb), + flags), __float_as_int(projection_blend)); } @@ -381,11 +389,12 @@ void ImageTextureNode::compile(OSLCompiler &compiler) compiler.parameter_texture("filename", slot); } - compiler.parameter("color_space", (compress_as_srgb) ? "sRGB" : "linear"); compiler.parameter(this, "projection"); compiler.parameter(this, "projection_blend"); + compiler.parameter("convert_from_srgb", compress_as_srgb); + compiler.parameter("ignore_alpha", !use_alpha); + compiler.parameter("unassociate_alpha", !alpha_out->links.empty()); compiler.parameter("is_float", is_float); - compiler.parameter("use_alpha", !alpha_out->links.empty()); compiler.parameter(this, "interpolation"); compiler.parameter(this, "extension"); @@ -491,13 +500,18 @@ void EnvironmentTextureNode::compile(SVMCompiler &compiler) if (slot != -1) { int vector_offset = tex_mapping.compile_begin(compiler, vector_in); + uint flags = 0; + + if (compress_as_srgb) { + flags |= NODE_IMAGE_COMPRESS_AS_SRGB; + } compiler.add_node(NODE_TEX_ENVIRONMENT, slot, compiler.encode_uchar4(vector_offset, compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(alpha_out), - compress_as_srgb), + flags), projection); tex_mapping.compile_end(compiler, vector_in, vector_offset); @@ -518,8 +532,6 @@ void EnvironmentTextureNode::compile(SVMCompiler &compiler) void EnvironmentTextureNode::compile(OSLCompiler &compiler) { - ShaderOutput *alpha_out = output("Alpha"); - tex_mapping.compile(compiler); /* See comments in ImageTextureNode::compile about support @@ -555,10 +567,10 @@ void EnvironmentTextureNode::compile(OSLCompiler &compiler) } compiler.parameter(this, "projection"); - compiler.parameter("color_space", (compress_as_srgb) ? "sRGB" : "linear"); compiler.parameter(this, "interpolation"); + compiler.parameter("convert_from_srgb", compress_as_srgb); + compiler.parameter("ignore_alpha", !use_alpha); compiler.parameter("is_float", is_float); - compiler.parameter("use_alpha", !alpha_out->links.empty()); compiler.add(this, "node_environment_texture"); } -- cgit v1.2.3