forked from bartvdbraak/blender
Cycles: add light falloff node, with quadratic/linear/constant falloff and a
smoothing factor to reduce high values near the light. http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/More#Light_Falloff Note that this was already possible to do manually with the Ray Length, but this adds a convenient node for it. This commit also makes the mapping node min/max option work, fixing #31348.
This commit is contained in:
parent
f44e80e638
commit
e6a84eb1b5
@ -97,6 +97,13 @@ static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping b_map
|
||||
mapping->translation = get_float3(b_mapping.translation());
|
||||
mapping->rotation = get_float3(b_mapping.rotation());
|
||||
mapping->scale = get_float3(b_mapping.scale());
|
||||
|
||||
mapping->use_minmax = b_mapping.use_min() || b_mapping.use_max();
|
||||
|
||||
if(b_mapping.use_min())
|
||||
mapping->min = get_float3(b_mapping.min());
|
||||
if(b_mapping.use_max())
|
||||
mapping->max = get_float3(b_mapping.max());
|
||||
}
|
||||
|
||||
static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNode b_node)
|
||||
@ -323,6 +330,10 @@ static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Shader
|
||||
node = new LightPathNode();
|
||||
break;
|
||||
}
|
||||
case BL::ShaderNode::type_LIGHT_FALLOFF: {
|
||||
node = new LightFalloffNode();
|
||||
break;
|
||||
}
|
||||
case BL::ShaderNode::type_TEX_IMAGE: {
|
||||
BL::ShaderNodeTexImage b_image_node(b_node);
|
||||
BL::Image b_image(b_image_node.image());
|
||||
|
@ -326,6 +326,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
|
||||
case NODE_MAPPING:
|
||||
svm_node_mapping(kg, sd, stack, node.y, node.z, &offset);
|
||||
break;
|
||||
case NODE_MIN_MAX:
|
||||
svm_node_min_max(kg, sd, stack, node.y, node.z, &offset);
|
||||
break;
|
||||
case NODE_TEX_COORD:
|
||||
svm_node_tex_coord(kg, sd, stack, node.y, node.z);
|
||||
break;
|
||||
@ -344,6 +347,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
|
||||
case NODE_RGB_CURVES:
|
||||
svm_node_rgb_curves(kg, sd, stack, node, &offset);
|
||||
break;
|
||||
case NODE_LIGHT_FALLOFF:
|
||||
svm_node_light_falloff(sd, stack, node);
|
||||
break;
|
||||
case NODE_END:
|
||||
default:
|
||||
#ifndef __MULTI_CLOSURE__
|
||||
|
@ -39,5 +39,32 @@ __device void svm_node_light_path(ShaderData *sd, float *stack, uint type, uint
|
||||
stack_store_float(stack, out_offset, info);
|
||||
}
|
||||
|
||||
/* Light Falloff Node */
|
||||
|
||||
__device void svm_node_light_falloff(ShaderData *sd, float *stack, uint4 node)
|
||||
{
|
||||
uint strength_offset, out_offset, smooth_offset;
|
||||
|
||||
decode_node_uchar4(node.z, &strength_offset, &smooth_offset, &out_offset, NULL);
|
||||
|
||||
float strength = stack_load_float(stack, strength_offset);
|
||||
uint type = node.y;
|
||||
|
||||
switch(type) {
|
||||
case NODE_LIGHT_FALLOFF_QUADRATIC: break;
|
||||
case NODE_LIGHT_FALLOFF_LINEAR: strength *= sd->ray_length; break;
|
||||
case NODE_LIGHT_FALLOFF_CONSTANT: strength *= sd->ray_length*sd->ray_length; break;
|
||||
}
|
||||
|
||||
float smooth = stack_load_float(stack, smooth_offset);
|
||||
|
||||
if(smooth > 0.0f) {
|
||||
float squared = sd->ray_length*sd->ray_length;
|
||||
strength *= squared/(smooth + squared);
|
||||
}
|
||||
|
||||
stack_store_float(stack, out_offset, strength);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
|
@ -34,5 +34,16 @@ __device void svm_node_mapping(KernelGlobals *kg, ShaderData *sd, float *stack,
|
||||
stack_store_float3(stack, out_offset, r);
|
||||
}
|
||||
|
||||
__device void svm_node_min_max(KernelGlobals *kg, ShaderData *sd, float *stack, uint vec_offset, uint out_offset, int *offset)
|
||||
{
|
||||
float3 v = stack_load_float3(stack, vec_offset);
|
||||
|
||||
float3 mn = float4_to_float3(read_node_float(kg, offset));
|
||||
float3 mx = float4_to_float3(read_node_float(kg, offset));
|
||||
|
||||
float3 r = min(max(mn, v), mx);
|
||||
stack_store_float3(stack, out_offset, r);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
|
@ -90,7 +90,9 @@ typedef enum NodeType {
|
||||
NODE_TEX_CHECKER = 5700,
|
||||
NODE_BRIGHTCONTRAST = 5800,
|
||||
NODE_RGB_RAMP = 5900,
|
||||
NODE_RGB_CURVES = 6000
|
||||
NODE_RGB_CURVES = 6000,
|
||||
NODE_MIN_MAX = 6100,
|
||||
NODE_LIGHT_FALLOFF = 6200
|
||||
} NodeType;
|
||||
|
||||
typedef enum NodeAttributeType {
|
||||
@ -119,6 +121,12 @@ typedef enum NodeLightPath {
|
||||
NODE_LP_ray_length
|
||||
} NodeLightPath;
|
||||
|
||||
typedef enum NodeLightFalloff {
|
||||
NODE_LIGHT_FALLOFF_QUADRATIC,
|
||||
NODE_LIGHT_FALLOFF_LINEAR,
|
||||
NODE_LIGHT_FALLOFF_CONSTANT
|
||||
} NodeLightFalloff;
|
||||
|
||||
typedef enum NodeTexCoord {
|
||||
NODE_TEXCO_NORMAL,
|
||||
NODE_TEXCO_OBJECT,
|
||||
|
@ -33,6 +33,11 @@ TextureMapping::TextureMapping()
|
||||
rotation = make_float3(0.0f, 0.0f, 0.0f);
|
||||
scale = make_float3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
min = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
max = make_float3(FLT_MAX, FLT_MAX, FLT_MAX);
|
||||
|
||||
use_minmax = false;
|
||||
|
||||
x_mapping = X;
|
||||
y_mapping = Y;
|
||||
z_mapping = Z;
|
||||
@ -69,6 +74,8 @@ bool TextureMapping::skip()
|
||||
|
||||
if(x_mapping != X || y_mapping != Y || z_mapping != Z)
|
||||
return false;
|
||||
if(use_minmax)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -85,6 +92,12 @@ void TextureMapping::compile(SVMCompiler& compiler, int offset_in, int offset_ou
|
||||
compiler.add_node(tfm.y);
|
||||
compiler.add_node(tfm.z);
|
||||
compiler.add_node(tfm.w);
|
||||
|
||||
if(use_minmax) {
|
||||
compiler.add_node(NODE_MIN_MAX, offset_out, offset_out);
|
||||
compiler.add_node(float3_to_float4(min));
|
||||
compiler.add_node(float3_to_float4(max));
|
||||
}
|
||||
}
|
||||
|
||||
/* Image Texture */
|
||||
@ -1686,6 +1699,54 @@ void LightPathNode::compile(OSLCompiler& compiler)
|
||||
compiler.add(this, "node_light_path");
|
||||
}
|
||||
|
||||
/* Light Path */
|
||||
|
||||
LightFalloffNode::LightFalloffNode()
|
||||
: ShaderNode("light_path")
|
||||
{
|
||||
add_input("Strength", SHADER_SOCKET_FLOAT, 100.0f);
|
||||
add_input("Smooth", SHADER_SOCKET_FLOAT, 0.0f);
|
||||
add_output("Quadratic", SHADER_SOCKET_FLOAT);
|
||||
add_output("Linear", SHADER_SOCKET_FLOAT);
|
||||
add_output("Constant", SHADER_SOCKET_FLOAT);
|
||||
}
|
||||
|
||||
void LightFalloffNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
ShaderInput *strength_in = input("Strength");
|
||||
ShaderInput *smooth_in = input("Smooth");
|
||||
|
||||
compiler.stack_assign(strength_in);
|
||||
compiler.stack_assign(smooth_in);
|
||||
|
||||
ShaderOutput *out = output("Quadratic");
|
||||
if(!out->links.empty()) {
|
||||
compiler.stack_assign(out);
|
||||
compiler.add_node(NODE_LIGHT_FALLOFF, NODE_LIGHT_FALLOFF_QUADRATIC,
|
||||
compiler.encode_uchar4(strength_in->stack_offset, smooth_in->stack_offset, out->stack_offset));
|
||||
}
|
||||
|
||||
out = output("Linear");
|
||||
if(!out->links.empty()) {
|
||||
compiler.stack_assign(out);
|
||||
compiler.add_node(NODE_LIGHT_FALLOFF, NODE_LIGHT_FALLOFF_LINEAR,
|
||||
compiler.encode_uchar4(strength_in->stack_offset, smooth_in->stack_offset, out->stack_offset));
|
||||
compiler.add_node(NODE_LIGHT_FALLOFF, NODE_LIGHT_FALLOFF_LINEAR, out->stack_offset);
|
||||
}
|
||||
|
||||
out = output("Constant");
|
||||
if(!out->links.empty()) {
|
||||
compiler.stack_assign(out);
|
||||
compiler.add_node(NODE_LIGHT_FALLOFF, NODE_LIGHT_FALLOFF_CONSTANT,
|
||||
compiler.encode_uchar4(strength_in->stack_offset, smooth_in->stack_offset, out->stack_offset));
|
||||
}
|
||||
}
|
||||
|
||||
void LightFalloffNode::compile(OSLCompiler& compiler)
|
||||
{
|
||||
compiler.add(this, "node_light_falloff");
|
||||
}
|
||||
|
||||
/* Value */
|
||||
|
||||
ValueNode::ValueNode()
|
||||
|
@ -41,6 +41,9 @@ public:
|
||||
float3 rotation;
|
||||
float3 scale;
|
||||
|
||||
float3 min, max;
|
||||
bool use_minmax;
|
||||
|
||||
enum Mapping { NONE=0, X=1, Y=2, Z=3 };
|
||||
Mapping x_mapping, y_mapping, z_mapping;
|
||||
|
||||
@ -277,6 +280,11 @@ public:
|
||||
SHADER_NODE_CLASS(LightPathNode)
|
||||
};
|
||||
|
||||
class LightFalloffNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(LightFalloffNode)
|
||||
};
|
||||
|
||||
class ValueNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(ValueNode)
|
||||
|
@ -508,9 +508,10 @@ struct ShadeResult;
|
||||
#define SH_NODE_LAYER_WEIGHT 160
|
||||
#define SH_NODE_VOLUME_TRANSPARENT 161
|
||||
#define SH_NODE_VOLUME_ISOTROPIC 162
|
||||
#define SH_NODE_GAMMA 163
|
||||
#define SH_NODE_TEX_CHECKER 164
|
||||
#define SH_NODE_GAMMA 163
|
||||
#define SH_NODE_TEX_CHECKER 164
|
||||
#define SH_NODE_BRIGHTCONTRAST 165
|
||||
#define SH_NODE_LIGHT_FALLOFF 166
|
||||
|
||||
/* custom defines options for Material node */
|
||||
#define SH_NODE_MAT_DIFF 1
|
||||
|
@ -1969,6 +1969,7 @@ static void registerShaderNodes(bNodeTreeType *ttype)
|
||||
register_node_type_sh_attribute(ttype);
|
||||
register_node_type_sh_geometry(ttype);
|
||||
register_node_type_sh_light_path(ttype);
|
||||
register_node_type_sh_light_falloff(ttype);
|
||||
register_node_type_sh_fresnel(ttype);
|
||||
register_node_type_sh_layer_weight(ttype);
|
||||
register_node_type_sh_tex_coord(ttype);
|
||||
|
@ -2188,6 +2188,13 @@ void node_light_path(
|
||||
is_transmission_ray = 0.0;
|
||||
}
|
||||
|
||||
void node_light_falloff(float strength, float smooth, out float quadratic, out float linear, out float constant)
|
||||
{
|
||||
quadratic = strength;
|
||||
linear = strength;
|
||||
constant = strength;
|
||||
}
|
||||
|
||||
/* output */
|
||||
|
||||
void node_output_material(vec4 surface, vec4 volume, float displacement, out vec4 result)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -77,7 +77,8 @@ DefNode( ShaderNode, SH_NODE_VOLUME_TRANSPARENT, 0, "VO
|
||||
DefNode( ShaderNode, SH_NODE_VOLUME_ISOTROPIC, 0, "VOLUME_ISOTROPIC", VolumeIsotropic, "Isotropic Volume", "" )
|
||||
DefNode( ShaderNode, SH_NODE_EMISSION, 0, "EMISSION", Emission, "Emission", "" )
|
||||
DefNode( ShaderNode, SH_NODE_NEW_GEOMETRY, 0, "NEW_GEOMETRY", NewGeometry, "Geometry", "" )
|
||||
DefNode( ShaderNode, SH_NODE_LIGHT_PATH, 0, "LIGHT_PATH", Light_path, "Light Path", "" )
|
||||
DefNode( ShaderNode, SH_NODE_LIGHT_PATH, 0, "LIGHT_PATH", LightPath, "Light Path", "" )
|
||||
DefNode( ShaderNode, SH_NODE_LIGHT_FALLOFF, 0, "LIGHT_FALLOFF", LightFalloff, "Light Falloff", "" )
|
||||
DefNode( ShaderNode, SH_NODE_TEX_IMAGE, def_sh_tex_image, "TEX_IMAGE", TexImage, "Image Texture", "" )
|
||||
DefNode( ShaderNode, SH_NODE_TEX_ENVIRONMENT, def_sh_tex_environment, "TEX_ENVIRONMENT", TexEnvironment, "Environment Texture","" )
|
||||
DefNode( ShaderNode, SH_NODE_TEX_SKY, def_sh_tex_sky, "TEX_SKY", TexSky, "Sky Texture", "" )
|
||||
|
@ -149,6 +149,7 @@ set(SRC
|
||||
shader/nodes/node_shader_volume_transparent.c
|
||||
shader/nodes/node_shader_volume_isotropic.c
|
||||
shader/nodes/node_shader_light_path.c
|
||||
shader/nodes/node_shader_light_falloff.c
|
||||
shader/nodes/node_shader_mix_shader.c
|
||||
shader/nodes/node_shader_add_shader.c
|
||||
shader/nodes/node_shader_output_lamp.c
|
||||
|
@ -73,6 +73,7 @@ void register_node_type_sh_hue_sat(struct bNodeTreeType *ttype);
|
||||
void register_node_type_sh_attribute(struct bNodeTreeType *ttype);
|
||||
void register_node_type_sh_geometry(struct bNodeTreeType *ttype);
|
||||
void register_node_type_sh_light_path(struct bNodeTreeType *ttype);
|
||||
void register_node_type_sh_light_falloff(struct bNodeTreeType *ttype);
|
||||
void register_node_type_sh_fresnel(struct bNodeTreeType *ttype);
|
||||
void register_node_type_sh_layer_weight(struct bNodeTreeType *ttype);
|
||||
void register_node_type_sh_tex_coord(struct bNodeTreeType *ttype);
|
||||
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* ***** 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "../node_shader_util.h"
|
||||
|
||||
/* **************** INPUT ********************* */
|
||||
|
||||
static bNodeSocketTemplate sh_node_light_falloff_in[]= {
|
||||
{ SOCK_FLOAT, 0, "Strength", 100.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_FLOAT, 0, "Smooth", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
/* **************** OUTPUT ******************** */
|
||||
|
||||
static bNodeSocketTemplate sh_node_light_falloff_out[]= {
|
||||
{ SOCK_FLOAT, 0, "Quadratic", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_FLOAT, 0, "Linear", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_FLOAT, 0, "Constant", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static int node_shader_gpu_light_falloff(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out)
|
||||
{
|
||||
return GPU_stack_link(mat, "node_light_falloff", in, out);
|
||||
}
|
||||
|
||||
/* node type definition */
|
||||
void register_node_type_sh_light_falloff(bNodeTreeType *ttype)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(ttype, &ntype, SH_NODE_LIGHT_FALLOFF, "Light Falloff", NODE_CLASS_OP_COLOR, 0);
|
||||
node_type_compatibility(&ntype, NODE_NEW_SHADING);
|
||||
node_type_socket_templates(&ntype, sh_node_light_falloff_in, sh_node_light_falloff_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
node_type_storage(&ntype, "", NULL, NULL);
|
||||
node_type_exec(&ntype, NULL);
|
||||
node_type_gpu(&ntype, node_shader_gpu_light_falloff);
|
||||
|
||||
nodeRegisterType(ttype, &ntype);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user