BGE: Allow access to light shadow settings with python
This patch adds a new API which allow us to access light shadow settings from python. The new API can be used to write custom GLSL materials with shadows. Reviewers: brecht, kupoman, agoose77, panzergame, campbellbarton, moguri, hg1 Reviewed By: agoose77, panzergame, campbellbarton, moguri, hg1 Projects: #game_engine Differential Revision: https://developer.blender.org/D1690
This commit is contained in:
parent
a5c419f4cc
commit
c4c2bd1350
|
@ -48,6 +48,78 @@ base class --- :class:`KX_GameObject`
|
|||
|
||||
:type: float
|
||||
|
||||
.. attribute:: shadowClipStart
|
||||
|
||||
The shadowmap clip start, below which objects will not generate shadows.
|
||||
|
||||
:type: float (read only)
|
||||
|
||||
.. attribute:: shadowClipEnd
|
||||
|
||||
The shadowmap clip end, beyond which objects will not generate shadows.
|
||||
|
||||
:type: float (read only)
|
||||
|
||||
..attribute:: shadowFrustumSize
|
||||
|
||||
Size of the frustum used for creating the shadowmap.
|
||||
|
||||
:type: float (read only)
|
||||
|
||||
..attribute:: shadowBindId
|
||||
|
||||
The OpenGL shadow texture bind number/id.
|
||||
|
||||
:type: int (read only)
|
||||
|
||||
..attribute:: shadowMapType
|
||||
|
||||
The shadow shadow map type (0 -> Simple; 1 -> Variance)
|
||||
|
||||
:type: int (read only)
|
||||
|
||||
..attribute:: shadowBias
|
||||
|
||||
The shadow buffer sampling bias.
|
||||
|
||||
:type: float (read only)
|
||||
|
||||
..attribute:: shadowBleedBias
|
||||
|
||||
The bias for reducing light-bleed on variance shadow maps.
|
||||
|
||||
:type: float (read only)
|
||||
|
||||
..attribute:: useShadow
|
||||
|
||||
Returns True if the light has Shadow option activated, else returns False.
|
||||
|
||||
:type: boolean (read only)
|
||||
|
||||
.. attribute:: shadowColor
|
||||
|
||||
The color of this light shadows. Black = (0.0, 0.0, 0.0), White = (1.0, 1.0, 1.0).
|
||||
|
||||
:type: :class:`mathutils.Color` (read only)
|
||||
|
||||
.. attribute:: shadowMatrix
|
||||
|
||||
Matrix that converts a vector in camera space to shadow buffer depth space.
|
||||
|
||||
Computed as:
|
||||
mat4_perspective_to_depth * mat4_lamp_to_perspective * mat4_world_to_lamp * mat4_cam_to_world.
|
||||
|
||||
mat4_perspective_to_depth is a fixed matrix defined as follow:
|
||||
|
||||
0.5 0.0 0.0 0.5
|
||||
0.0 0.5 0.0 0.5
|
||||
0.0 0.0 0.5 0.5
|
||||
0.0 0.0 0.0 1.0
|
||||
Note:
|
||||
There is one matrix of that type per lamp casting shadow in the scene.
|
||||
|
||||
:type: Matrix4x4 (read only)
|
||||
|
||||
.. attribute:: distance
|
||||
|
||||
The maximum distance this light can illuminate. (SPOT and NORMAL lights only).
|
||||
|
|
|
@ -306,6 +306,8 @@ void GPU_lamp_update_buffer_mats(GPULamp *lamp);
|
|||
void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]);
|
||||
void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
|
||||
int GPU_lamp_shadow_buffer_type(GPULamp *lamp);
|
||||
int GPU_lamp_shadow_bind_code(GPULamp *lamp);
|
||||
float *GPU_lamp_dynpersmat(GPULamp *lamp);
|
||||
|
||||
void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]);
|
||||
void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy);
|
||||
|
|
|
@ -2275,6 +2275,16 @@ int GPU_lamp_shadow_buffer_type(GPULamp *lamp)
|
|||
return lamp->la->shadowmap_type;
|
||||
}
|
||||
|
||||
int GPU_lamp_shadow_bind_code(GPULamp *lamp)
|
||||
{
|
||||
return lamp->tex ? GPU_texture_opengl_bindcode(lamp->tex) : -1;
|
||||
}
|
||||
|
||||
float *GPU_lamp_dynpersmat(GPULamp *lamp)
|
||||
{
|
||||
return lamp->dynpersmat ? (float *)lamp->dynpersmat : NULL;
|
||||
}
|
||||
|
||||
int GPU_lamp_shadow_layer(GPULamp *lamp)
|
||||
{
|
||||
if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER | LA_LAYER_SHADOW)))
|
||||
|
|
|
@ -1432,6 +1432,15 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l
|
|||
lightobj->m_color[2] = la->b;
|
||||
lightobj->m_distance = la->dist;
|
||||
lightobj->m_energy = la->energy;
|
||||
lightobj->m_shadowclipstart = la->clipsta;
|
||||
lightobj->m_shadowclipend = la->clipend;
|
||||
lightobj->m_shadowbias = la->bias;
|
||||
lightobj->m_shadowbleedbias = la->bleedbias;
|
||||
lightobj->m_shadowmaptype = la->shadowmap_type;
|
||||
lightobj->m_shadowfrustumsize = la->shadow_frustum_size;
|
||||
lightobj->m_shadowcolor[0] = la->shdwr;
|
||||
lightobj->m_shadowcolor[1] = la->shdwg;
|
||||
lightobj->m_shadowcolor[2] = la->shdwb;
|
||||
lightobj->m_layer = layerflag;
|
||||
lightobj->m_spotblend = la->spotblend;
|
||||
lightobj->m_spotsize = la->spotsize;
|
||||
|
|
|
@ -158,6 +158,16 @@ PyAttributeDef KX_LightObject::Attributes[] = {
|
|||
KX_PYATTRIBUTE_RW_FUNCTION("quad_attenuation", KX_LightObject, pyattr_get_quad_attenuation, pyattr_set_quad_attenuation),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("spotsize", KX_LightObject, pyattr_get_spotsize, pyattr_set_spotsize),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("spotblend", KX_LightObject, pyattr_get_spotblend, pyattr_set_spotblend),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("shadowClipStart", KX_LightObject, pyattr_get_shadow_clip_start),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("shadowClipEnd", KX_LightObject, pyattr_get_shadow_clip_end),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("shadowFrustumSize", KX_LightObject, pyattr_get_shadow_frustum_size),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("shadowBias", KX_LightObject, pyattr_get_shadow_bias),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("shadowBleedBias", KX_LightObject, pyattr_get_shadow_bleed_bias),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("shadowBindId", KX_LightObject, pyattr_get_shadow_bind_code),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("shadowMapType", KX_LightObject, pyattr_get_shadow_map_type),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("shadowColor", KX_LightObject, pyattr_get_shadow_color),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("useShadow", KX_LightObject, pyattr_get_shadow_active),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("shadowMatrix", KX_LightObject, pyattr_get_shadow_matrix),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("SPOT", KX_LightObject, pyattr_get_typeconst),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("SUN", KX_LightObject, pyattr_get_typeconst),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("NORMAL", KX_LightObject, pyattr_get_typeconst),
|
||||
|
@ -219,6 +229,66 @@ int KX_LightObject::pyattr_set_energy(void *self_v, const KX_PYATTRIBUTE_DEF *at
|
|||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
|
||||
PyObject *KX_LightObject::pyattr_get_shadow_clip_start(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_LightObject *self = static_cast<KX_LightObject *>(self_v);
|
||||
return PyFloat_FromDouble(self->m_lightobj->m_shadowclipstart);
|
||||
}
|
||||
|
||||
PyObject *KX_LightObject::pyattr_get_shadow_clip_end(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_LightObject *self = static_cast<KX_LightObject *>(self_v);
|
||||
return PyFloat_FromDouble(self->m_lightobj->m_shadowclipend);
|
||||
}
|
||||
|
||||
PyObject *KX_LightObject::pyattr_get_shadow_frustum_size(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_LightObject *self = static_cast<KX_LightObject *>(self_v);
|
||||
return PyFloat_FromDouble(self->m_lightobj->m_shadowfrustumsize);
|
||||
}
|
||||
|
||||
PyObject *KX_LightObject::pyattr_get_shadow_bind_code(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_LightObject *self = static_cast<KX_LightObject *>(self_v);
|
||||
return PyLong_FromLong(self->m_lightobj->GetShadowBindCode());
|
||||
}
|
||||
|
||||
PyObject *KX_LightObject::pyattr_get_shadow_bias(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_LightObject *self = static_cast<KX_LightObject *>(self_v);
|
||||
return PyFloat_FromDouble(self->m_lightobj->m_shadowbias);
|
||||
}
|
||||
|
||||
PyObject *KX_LightObject::pyattr_get_shadow_bleed_bias(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_LightObject *self = static_cast<KX_LightObject *>(self_v);
|
||||
return PyFloat_FromDouble(self->m_lightobj->m_shadowbleedbias);
|
||||
}
|
||||
|
||||
PyObject *KX_LightObject::pyattr_get_shadow_map_type(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_LightObject *self = static_cast<KX_LightObject *>(self_v);
|
||||
return PyLong_FromLong(self->m_lightobj->m_shadowmaptype);
|
||||
}
|
||||
|
||||
PyObject *KX_LightObject::pyattr_get_shadow_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_LightObject *self = static_cast<KX_LightObject *>(self_v);
|
||||
return PyObjectFrom(self->m_lightobj->GetShadowMatrix());
|
||||
}
|
||||
|
||||
PyObject *KX_LightObject::pyattr_get_shadow_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_LightObject *self = static_cast<KX_LightObject *>(self_v);
|
||||
return PyColorFromVector(MT_Vector3(self->m_lightobj->m_shadowcolor));
|
||||
}
|
||||
|
||||
PyObject *KX_LightObject::pyattr_get_shadow_active(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_LightObject *self = static_cast<KX_LightObject *>(self_v);
|
||||
return PyBool_FromLong(self->m_lightobj->HasShadowBuffer());
|
||||
}
|
||||
|
||||
PyObject *KX_LightObject::pyattr_get_distance(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
|
||||
|
|
|
@ -70,6 +70,16 @@ public:
|
|||
static int pyattr_set_layer(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static PyObject* pyattr_get_energy(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int pyattr_set_energy(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static PyObject *pyattr_get_shadow_clip_start(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *pyattr_get_shadow_clip_end(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *pyattr_get_shadow_frustum_size(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *pyattr_get_shadow_bind_code(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *pyattr_get_shadow_bias(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *pyattr_get_shadow_bleed_bias(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *pyattr_get_shadow_map_type(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *pyattr_get_shadow_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *pyattr_get_shadow_active(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *pyattr_get_shadow_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_distance(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int pyattr_set_distance(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static PyObject* pyattr_get_color(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
|
|
|
@ -38,6 +38,7 @@ class KX_Camera;
|
|||
class KX_Scene;
|
||||
|
||||
class MT_Transform;
|
||||
class MT_Matrix4x4;
|
||||
|
||||
struct Image;
|
||||
|
||||
|
@ -56,6 +57,13 @@ public:
|
|||
|
||||
float m_energy;
|
||||
float m_distance;
|
||||
float m_shadowclipstart;
|
||||
float m_shadowfrustumsize;
|
||||
float m_shadowclipend;
|
||||
float m_shadowbias;
|
||||
float m_shadowbleedbias;
|
||||
short m_shadowmaptype;
|
||||
float m_shadowcolor[3];
|
||||
|
||||
float m_color[3];
|
||||
|
||||
|
@ -74,6 +82,8 @@ public:
|
|||
virtual RAS_ILightObject* Clone() = 0;
|
||||
|
||||
virtual bool HasShadowBuffer() = 0;
|
||||
virtual int GetShadowBindCode() = 0;
|
||||
virtual MT_Matrix4x4 GetShadowMatrix() = 0;
|
||||
virtual int GetShadowLayer() = 0;
|
||||
virtual void BindShadowBuffer(RAS_ICanvas *canvas, KX_Camera *cam, MT_Transform& camtrans) = 0;
|
||||
virtual void UnbindShadowBuffer() = 0;
|
||||
|
|
|
@ -177,6 +177,26 @@ bool RAS_OpenGLLight::HasShadowBuffer()
|
|||
return false;
|
||||
}
|
||||
|
||||
int RAS_OpenGLLight::GetShadowBindCode()
|
||||
{
|
||||
GPULamp *lamp;
|
||||
|
||||
if ((lamp = GetGPULamp()))
|
||||
return GPU_lamp_shadow_bind_code(lamp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
MT_Matrix4x4 RAS_OpenGLLight::GetShadowMatrix()
|
||||
{
|
||||
GPULamp *lamp;
|
||||
|
||||
if ((lamp = GetGPULamp()))
|
||||
return MT_Matrix4x4(GPU_lamp_dynpersmat(lamp));
|
||||
MT_Matrix4x4 mat;
|
||||
mat.setIdentity();
|
||||
return mat;
|
||||
}
|
||||
|
||||
int RAS_OpenGLLight::GetShadowLayer()
|
||||
{
|
||||
GPULamp *lamp;
|
||||
|
|
|
@ -46,6 +46,8 @@ public:
|
|||
RAS_OpenGLLight* Clone() { return new RAS_OpenGLLight(*this); }
|
||||
|
||||
bool HasShadowBuffer();
|
||||
int GetShadowBindCode();
|
||||
MT_Matrix4x4 GetShadowMatrix();
|
||||
int GetShadowLayer();
|
||||
void BindShadowBuffer(RAS_ICanvas *canvas, KX_Camera *cam, MT_Transform& camtrans);
|
||||
void UnbindShadowBuffer();
|
||||
|
|
Loading…
Reference in New Issue