0

我想编写一个小我的世界克隆。现在我尝试插入一些简单的照明,但我的结果非常糟糕。我阅读了很多关于它的内容,并尝试了不同的解决方案,但没有任何结果。

这就是我得到的。

初始化:

    GL11.glViewport(0, 0, Config.GAME_WIDTH, Config.GAME_HEIGHT);
    GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
    GL11.glLoadIdentity(); // Reset The Projection Matrix

    GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix
    GL11.glLoadIdentity(); // Reset The Modelview Matrix

    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glEnable(GL11.GL_CULL_FACE);
    GL11.glFrontFace(GL11.GL_CCW);

    GL11.glLightModeli(GL11.GL_LIGHT_MODEL_LOCAL_VIEWER, GL11.GL_TRUE);
    GL11.glEnable(GL11.GL_LIGHTING);
    GL11.glEnable(GL11.GL_LIGHT0);

    FloatBuffer qaAmbientLight  = floatBuffer(0.0f, 0.0f, 0.0f, 1.0f);
    FloatBuffer qaDiffuseLight  = floatBuffer(1.0f, 1.0f, 1.0f, 1.0f);
    FloatBuffer qaSpecularLight = floatBuffer(1.0f, 1.0f, 1.0f, 1.0f);

    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_AMBIENT, qaAmbientLight);
    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_DIFFUSE, qaDiffuseLight);
    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_SPECULAR, qaSpecularLight);

    FloatBuffer qaLightPosition = floatBuffer(lightPosition.x, lightPosition.y, lightPosition.z, 1.0f);
    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, qaLightPosition);

所以现在在每次渲染之前我都试过这个:

    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glClearColor(0.0f, 100.0f, 100.0f, 1.0f);
    GL11.glShadeModel(GL11.GL_FLAT);
    GL11.glLoadIdentity();
    FloatBuffer qaLightPosition = floatBuffer(lightPosition.x, lightPosition.y, lightPosition.z, 1.0f);
    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, qaLightPosition);

    FloatBuffer ambientMaterial = floatBuffer(0.2f, 0.2f, 0.2f, 1.0f);
    FloatBuffer diffuseMaterial = floatBuffer(0.8f, 0.8f, 0.8f, 1.0f);
    FloatBuffer specularMaterial = floatBuffer(0.0f, 0.0f, 0.0f, 1.0f);


    GL11.glMaterial(GL11.GL_FRONT, GL11.GL_AMBIENT, ambientMaterial);
    GL11.glMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE, diffuseMaterial);
    GL11.glMaterial(GL11.GL_FRONT, GL11.GL_SPECULAR, specularMaterial);
    GL11.glMaterialf(GL11.GL_FRONT, GL11.GL_SHININESS, 50.0f);

当然,这不是很多代码,但这都是关于照明的。我做错了吗?我读到 OpenGL 在光照和阴影方面不如 DirectX。

这就是它的样子:

http://img199.imageshack.us/img199/7014/testrender.png

有人可以给我一些建议让它看起来更好吗?

我发现了一篇带有很棒的街区景观的帖子。 http://i.imgur.com/zIocp.jpg 这就是它的样子:)

4

2 回答 2

4

有人可以给我一些建议让它看起来更好吗?

如果您使用可编程管道,OpenGL 和 DirectX 都与光照和阴影无关。法线只是另一个顶点属性,可用于光照计算。固定功能已过时且已弃用,因此如果您不被迫使用它,则不推荐使用它。

改用着色器其实并没有那么难,而且你不会再被固定的管线所限制;然后,您可以完全控制光照的计算方式,您可以轻松输出更多调试信息(例如根据其法线着色表面)。

这就是它的样子:)

您发布的屏幕也有可见的环境光遮蔽。在没有着色器的情况下实现这种效果将非常困难,而且根本不值得付出努力。

我碰巧自己也在做一个类似的项目;如果它不是开源和公开可用的,我不会提及它。这是示例结果:

Minicraft Screenie

您可以在此处找到光照着色器代码。

我将发布一段摘录以防止链接腐烂:

float CalcDirectionalLightFactor(vec3 lightDirection, vec3 normal) {
    float DiffuseFactor = dot(normalize(normal), -lightDirection);

    if (DiffuseFactor > 0) {
        return DiffuseFactor;
    }
    else {
        return 0.0;
    }
}

vec3 DiffuseColor = Light0.Color * Light0.DiffuseIntensity * CalcDirectionalLightFactor(Light0.Direction, normal);
于 2013-04-07T16:42:53.887 回答
1

Bartek 的回答很好。您将希望沿着编写自己的着色器的道路前进,了解 OpenGL 为阴影和照明提供了什么,而不是依赖于旧的、已弃用的照明模型。glEnable(LIGHTING_AND_SHADOWING) 要复杂得多。

但是,如果您只是想使用您的代码来查看颜色从二进制黑/白的变化,一个潜在的想法是关闭 qaSpecularLight(它会创建“有光泽的”全白高光,但不能帮助您获得“ matte" 外观)并调整 glShadeModel 设置以实现平滑着色。

这应该会有所帮助,但不会让您一路实现目标。按照 Bartek 的建议路径(或谷歌搜索类似的想法)。

于 2013-04-07T17:07:24.237 回答