py_sha_fresnel¶
Demonstrates how to implement a shader that computes a fresnel effect.
DETAILS
The shader evaluates the Fresnel response and shows how a ShaderData plugin reports its output and exception color.
To run this example, place the file in the Cinema 4D plugins folder and restart Cinema 4D.
Topics:
- Computing a Fresnel shader response
- Returning shader output and exception colors
Files¶
py_sha_fresnel.pyp¶
"""Demonstrates how to implement a shader that computes a fresnel effect.
The shader evaluates the Fresnel response and shows how a ShaderData plugin reports its output and exception color.
To run this example, place the file in the Cinema 4D plugins folder and restart Cinema 4D.
Topics:
- Computing a Fresnel shader response
- Returning shader output and exception colors
"""
__copyright__ = "Copyright 2026, MAXON Computer"
__author__ = "Maxime Adam"
__date__ = "25/08/2026"
__license__ = "Apache-2.0 license"
__version__ = "13.0.0"
import math
import c4d
# Be sure to use a unique ID obtained from developers.maxon.net
PLUGIN_ID = 1027089
class PyFresnel(c4d.plugins.ShaderData):
def __init__(self):
# If a Python exception occurs during the calculation of a pixel colorize
# this one in red for debugging purposes
self.SetExceptionColor(c4d.Vector(1, 0, 0))
def FaceForward(self, N, I):
return abs((-I) * N) * N
def Fresnel(self, I, N, etasqrt):
cos_theta = I * N
fuvA = etasqrt - (1.0 - (cos_theta * cos_theta))
fuvB = abs(fuvA)
fu2 = (fuvA + fuvB) / 2.0
fv2 = (-fuvA + fuvB) / 2.0
fv2sqrt = 0.0 if fv2 == 0.0 else math.sqrt(abs(fv2))
fu2sqrt = 0.0 if fu2 == 0.0 else math.sqrt(abs(fu2))
fperp_temp = ((cos_theta + fu2sqrt) * (cos_theta + fu2sqrt)) + fv2
if fperp_temp == 0.0:
return 1.0
fperp2 = (((cos_theta - fu2sqrt) * (cos_theta - fu2sqrt)) + fv2) / fperp_temp
fpara_temp = ((etasqrt * cos_theta + fu2sqrt) *
(etasqrt * cos_theta + fu2sqrt)) + fv2sqrt * fv2sqrt
if fpara_temp == 0.0:
return 1.0
fpara2 = (((etasqrt * cos_theta - fu2sqrt) * (etasqrt * cos_theta - fu2sqrt)) + -
fv2sqrt * -fv2sqrt) / fpara_temp
return 0.5 * (fperp2 + fpara2)
def Output(self, sh, cd):
"""Called by Cinema 4D for each point of the visible surface of a shaded object to return the color.
Important: No OS calls are allowed during this function. Doing so could cause a crash, since it can be called in a multi-processor context.
Args:
sh (c4d.BaseShader): The shader node connected with this instance.
cd (c4d.modules.render.ChannelData): Channel data to use and/or modify.
Returns:
c4d.Vector: The color of the shaded from 0 = black to 1 = white
"""
# If shader is computed in 3d space
if cd.vd:
# default IOR value
ior = 1.6
n = self.FaceForward(~cd.vd.bumpn, ~cd.vd.ray.v)
fresnel = self.Fresnel(-(~cd.vd.ray.v), ~n, ior * ior)
return c4d.Vector(fresnel)
# If shader is computed in 2d space, return black
else:
return c4d.Vector(0.0)
if __name__ == '__main__':
# String resource, see c4d_symbols.h, have to be redefined in python
IDS_PY_FRESNEL = 10000
c4d.plugins.RegisterShaderPlugin(
PLUGIN_ID, c4d.plugins.GeLoadString(IDS_PY_FRESNEL), 0, PyFresnel, "", 0)
res/c4d_symbols.h¶
enum
{
// End of symbol definition
IDS_PY_FRESNEL=10000,
_DUMMY_ELEMENT_
};
res/strings_us/c4d_strings.str¶
STRINGTABLE
{
IDS_PY_FRESNEL "Py SDK - Fresnel";
}