Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/shaders/node_math.osl
| Show All 11 Lines | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| * See the License for the specific language governing permissions and | * See the License for the specific language governing permissions and | ||||
| * limitations under the License. | * limitations under the License. | ||||
| */ | */ | ||||
| #include "stdosl.h" | #include "stdosl.h" | ||||
| float safe_divide(float a, float b) | float safe_divide(float a, float b) | ||||
| { | { | ||||
| float result; | return (b != 0.0) ? a / b : 0.0; | ||||
| if (b == 0.0) | |||||
| result = 0.0; | |||||
| else | |||||
| result = a / b; | |||||
| return result; | |||||
| } | } | ||||
| float safe_modulo(float a, float b) | float safe_modulo(float a, float b) | ||||
| { | { | ||||
| float result; | return (b != 0.0) ? fmod(a, b) : 0.0; | ||||
| if (b == 0.0) | |||||
| result = 0.0; | |||||
| else | |||||
| result = fmod(a, b); | |||||
| return result; | |||||
| } | } | ||||
| float safe_sqrt(float a) | float safe_sqrt(float a) | ||||
| { | { | ||||
| float result; | return (a > 0.0) ? sqrt(a) : 0.0; | ||||
| if (a > 0.0) | |||||
| result = sqrt(a); | |||||
| else | |||||
| result = 0.0; | |||||
| return result; | |||||
| } | } | ||||
| float safe_log(float a, float b) | float safe_log(float a, float b) | ||||
| { | { | ||||
| if (a < 0.0 || b < 0.0) | return (a > 0.0 && b > 0.0) ? log(a) / log(b) : 0.0; | ||||
| return 0.0; | |||||
| return log(a) / log(b); | |||||
| } | } | ||||
| /* OSL asin, acos, and pow functions are safe by default. */ | |||||
| shader node_math(string type = "add", | shader node_math(string type = "add", | ||||
| int use_clamp = 0, | float Value1 = 0.5, | ||||
| float Value1 = 0.0, | float Value2 = 0.5, | ||||
| float Value2 = 0.0, | |||||
| output float Value = 0.0) | output float Value = 0.0) | ||||
| { | { | ||||
| /* OSL asin, acos, pow check for values that could give rise to nan */ | |||||
| if (type == "add") | if (type == "add") | ||||
| Value = Value1 + Value2; | Value = Value1 + Value2; | ||||
| else if (type == "subtract") | else if (type == "subtract") | ||||
| Value = Value1 - Value2; | Value = Value1 - Value2; | ||||
| else if (type == "multiply") | else if (type == "multiply") | ||||
| Value = Value1 * Value2; | Value = Value1 * Value2; | ||||
| else if (type == "divide") | else if (type == "divide") | ||||
| Value = safe_divide(Value1, Value2); | Value = safe_divide(Value1, Value2); | ||||
| else if (type == "sine") | |||||
| Value = sin(Value1); | |||||
| else if (type == "cosine") | |||||
| Value = cos(Value1); | |||||
| else if (type == "tangent") | |||||
| Value = tan(Value1); | |||||
| else if (type == "arcsine") | |||||
| Value = asin(Value1); | |||||
| else if (type == "arccosine") | |||||
| Value = acos(Value1); | |||||
| else if (type == "arctangent") | |||||
| Value = atan(Value1); | |||||
| else if (type == "power") | else if (type == "power") | ||||
| Value = pow(Value1, Value2); | Value = pow(Value1, Value2); | ||||
| else if (type == "logarithm") | else if (type == "logarithm") | ||||
| Value = safe_log(Value1, Value2); | Value = safe_log(Value1, Value2); | ||||
| else if (type == "sqrt") | |||||
| Value = safe_sqrt(Value1); | |||||
| else if (type == "absolute") | |||||
| Value = fabs(Value1); | |||||
| else if (type == "minimum") | else if (type == "minimum") | ||||
| Value = min(Value1, Value2); | Value = min(Value1, Value2); | ||||
| else if (type == "maximum") | else if (type == "maximum") | ||||
| Value = max(Value1, Value2); | Value = max(Value1, Value2); | ||||
| else if (type == "round") | |||||
| Value = floor(Value1 + 0.5); | |||||
| else if (type == "less_than") | else if (type == "less_than") | ||||
| Value = Value1 < Value2; | Value = Value1 < Value2; | ||||
| else if (type == "greater_than") | else if (type == "greater_than") | ||||
| Value = Value1 > Value2; | Value = Value1 > Value2; | ||||
| else if (type == "modulo") | else if (type == "round") | ||||
| Value = safe_modulo(Value1, Value2); | Value = floor(Value1 + 0.5); | ||||
| else if (type == "absolute") | |||||
| Value = fabs(Value1); | |||||
| else if (type == "arctan2") | |||||
| Value = atan2(Value1, Value2); | |||||
| else if (type == "floor") | else if (type == "floor") | ||||
| Value = floor(Value1); | Value = floor(Value1); | ||||
| else if (type == "ceil") | else if (type == "ceil") | ||||
| Value = ceil(Value1); | Value = ceil(Value1); | ||||
| else if (type == "fract") | else if (type == "fraction") | ||||
| Value = Value1 - floor(Value1); | Value = Value1 - floor(Value1); | ||||
| else if (type == "sqrt") | else if (type == "modulo") | ||||
| Value = safe_sqrt(Value1); | Value = safe_modulo(Value1, Value2); | ||||
| else if (type == "sine") | |||||
| if (use_clamp) | Value = sin(Value1); | ||||
| Value = clamp(Value, 0.0, 1.0); | else if (type == "cosine") | ||||
| Value = cos(Value1); | |||||
| else if (type == "tangent") | |||||
| Value = tan(Value1); | |||||
| else if (type == "arcsine") | |||||
| Value = asin(Value1); | |||||
| else if (type == "arccosine") | |||||
| Value = acos(Value1); | |||||
| else if (type == "arctangent") | |||||
| Value = atan(Value1); | |||||
| else if (type == "arctan2") | |||||
| Value = atan2(Value1, Value2); | |||||
| else | |||||
| warning("%s", "Unknown math operator!"); | |||||
| } | } | ||||