【问题标题】:OpenGL: Deform (scale) stencil shadow from light sourceOpenGL:从光源变形(缩放)模板阴影
【发布时间】:2013-11-25 04:27:30
【问题描述】:

我的游戏引擎中有一个基本的模板阴影功能。我正在尝试根据我拥有的照明方向使阴影变形:

/*
 * @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) 和光照方向的点积,以及模型偏航的 sin 和 cos,因为虽然我很确定它们是我需要增强的阴影的比例,我不知道产生透视正确变形的正确公式是什么。对于更了解预测的人来说,这可能是儿戏……对我来说,我是在黑暗中刺伤。

【问题讨论】:

    标签: opengl transform shadow


    【解决方案1】:

    我最终能够通过管理我自己的矩阵和改编 SGI 的 OpenGL Cookbook 中的代码来达到预期的效果。该代码使用来自他的 DarkPlaces Quake 引擎的 LordHavoc 矩阵库。内联 cmets 列出了主要步骤。完整代码如下:

    /*
     * @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

    【讨论】:

      猜你喜欢
      • 2012-11-26
      • 2019-03-08
      • 2015-08-31
      • 2012-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多