2013-11-25 3 views
1

내 게임 엔진에서 기본 스텐실 그림자가 작동합니다. 로,OpenGL : 광원의 스텐실 그림자를 변형합니다.

/* 
* @brief Applies translation, rotation and scale for the shadow of the specified 
* entity. In order to reuse the vertex arrays from the primary rendering 
* pass, the shadow origin must transformed into model-view space. 
*/ 
static void R_RotateForMeshShadow_default(const r_entity_t *e) { 
    vec3_t origin, delta; 

    if (!e) { 
     glPopMatrix(); 
     return; 
    } 

    R_TransformForEntity(e, e->lighting->shadow_origin, origin); 

    VectorSubtract(e->lighting->shadow_origin, e->origin, delta); 
    const vec_t scale = 1.0 + VectorLength(delta)/LIGHTING_MAX_SHADOW_DISTANCE; 

    /*const vec_t dot = DotProduct(e->lighting->shadow_normal, e->lighting->dir); 

    const vec_t sy = sin(Radians(e->angles[YAW])); 
    const vec_t cy = cos(Radians(e->angles[YAW]));*/ 

    glPushMatrix(); 

    glTranslatef(origin[0], origin[1], origin[2] + 1.0); 

    glRotatef(-e->angles[PITCH], 0.0, 1.0, 0.0); 

    glScalef(scale, scale, 0.0); 

} 내가 접지면 (shadow_normal) 및 조명 방향의 내적을 주석 한

: 나는 내가 가지고있는 조명 방향에 따라 그림자를 변형하기 위해 노력하고있어 모델의 요의 죄와 코사인이라고 생각합니다. 그림자의 크기를 늘릴 필요가 있다고 확신 할 수 있기 때문에 올바른 공식이 원근감있는 올바른 변형을 산출하는지 알지 못하기 때문에 . 투영을 더 잘 이해하는 사람에게는 이것이 아마 어린 아이의 놀이 일 것입니다. 나를 위해, 나는 어둠 속에서 찌름입니다.

답변

0

나는 결국 내 자신의 매트릭스를 관리하고 SGI의 OpenGL Cookbook에서 코드를 적용하여 원하는 효과를 얻을 수있었습니다. 이 코드는 DarkPlaces Quake 엔진의 LordHavoc 매트릭스 라이브러리를 사용합니다. 인라인 주석은 주요 단계를 호출합니다. 이것의 완전한 이행이 여기 살고

/* 
* @brief Projects the model view matrix for the given entity onto the shadow 
* plane. A perspective shear is then applied using the standard planar shadow 
* deformation from SGI's cookbook, adjusted for Quake's negative planes: 
* 
* ftp://ftp.sgi.com/opengl/contrib/blythe/advanced99/notes/node192.html 
*/ 
static void R_RotateForMeshShadow_default(const r_entity_t *e, r_shadow_t *s) { 
    vec4_t pos, normal; 
    matrix4x4_t proj, shear; 
    vec_t dot; 

    if (!e) { 
     glPopMatrix(); 
     return; 
    } 

    const cm_bsp_plane_t *p = &s->plane; 

    // project the entity onto the shadow plane 
    vec3_t vx, vy, vz, t; 
    Matrix4x4_ToVectors(&e->matrix, vx, vy, vz, t); 

    dot = DotProduct(vx, p->normal); 
    VectorMA(vx, -dot, p->normal, vx); 

    dot = DotProduct(vy, p->normal); 
    VectorMA(vy, -dot, p->normal, vy); 

    dot = DotProduct(vz, p->normal); 
    VectorMA(vz, -dot, p->normal, vz); 

    dot = DotProduct(t, p->normal) - p->dist; 
    VectorMA(t, -dot, p->normal, t); 

    Matrix4x4_FromVectors(&proj, vx, vy, vz, t); 

    glPushMatrix(); 

    glMultMatrixf((GLfloat *) proj.m); 

    // transform the light position and shadow plane into model space 
    Matrix4x4_Transform(&e->inverse_matrix, s->illumination->light.origin, pos); 
    pos[3] = 1.0; 

    const vec_t *n = p->normal; 
    Matrix4x4_TransformPositivePlane(&e->inverse_matrix, n[0], n[1], n[2], p->dist, normal); 

    // calculate shearing, accounting for Quake's negative plane equation 
    normal[3] = -normal[3]; 
    dot = DotProduct(pos, normal) + pos[3] * normal[3]; 

    shear.m[0][0] = dot - pos[0] * normal[0]; 
    shear.m[1][0] = 0.0 - pos[0] * normal[1]; 
    shear.m[2][0] = 0.0 - pos[0] * normal[2]; 
    shear.m[3][0] = 0.0 - pos[0] * normal[3]; 
    shear.m[0][1] = 0.0 - pos[1] * normal[0]; 
    shear.m[1][1] = dot - pos[1] * normal[1]; 
    shear.m[2][1] = 0.0 - pos[1] * normal[2]; 
    shear.m[3][1] = 0.0 - pos[1] * normal[3]; 
    shear.m[0][2] = 0.0 - pos[2] * normal[0]; 
    shear.m[1][2] = 0.0 - pos[2] * normal[1]; 
    shear.m[2][2] = dot - pos[2] * normal[2]; 
    shear.m[3][2] = 0.0 - pos[2] * normal[3]; 
    shear.m[0][3] = 0.0 - pos[3] * normal[0]; 
    shear.m[1][3] = 0.0 - pos[3] * normal[1]; 
    shear.m[2][3] = 0.0 - pos[3] * normal[2]; 
    shear.m[3][3] = dot - pos[3] * normal[3]; 

    glMultMatrixf((GLfloat *) shear.m); 

    Matrix4x4_Copy(&s->matrix, &proj); 
} 

: https://github.com/jdolan/quake2world/blob/master/src/client/renderer/r_mesh_shadow.c

여기에 전체 코드입니다
관련 문제