cs地图吧 关注:9,316贴子:340,253

【HZ大讲堂】讲解一下引擎中对各种渲染模式(rendermode)的处理

只看楼主收藏回复

渲染模式就是这个值:

给实体设置后由引擎读取,它的键叫rendermode,可取值从0~5,一共6个值
enum
{
kRenderNormal,// src
kRenderTransColor,// c*a+dest*(1-a)
kRenderTransTexture,// src*a+dest*(1-a)
kRenderGlow,// src*a+dest -- No Z buffer checks
kRenderTransAlpha,// src*srca+dest*(1-srca)
kRenderTransAdd,// src*a+dest
};
从HLSDK\common\const.h中也可以看到就是这六个
V社给出的注释很清楚的说明了它的颜色混合方式
至于什么是混合?就是当红色玻璃和蓝色玻璃重合在一起的时候重合部分的像素应该是什么颜色的?是紫色(Alpha)还是粉色(add),或者红色/蓝色(完全透明和完全不透明)?
rendermode = 0,也就是rendermode=kRenderNormal的情况:
靠近自己的像素完全覆盖后面的像素
比如一个rendermode=0的箱子挡住了背景的一部分,你看到的就是完全不透明的箱子
对于固体和固体实体,他在引擎里渲染时是用
qglColor4f(1, 1, 1, 1);
来设置颜色,也就是说,你设置的rendercolor完全无效,不管怎样他都是完全不透明+保持贴图本来的颜色
对于spr等点实体,渲染kRenderNormal的实体时使用
qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
qglColor4ub(color.r, color.g, color.b, 255);
qglDisable(GL_BLEND);
其中color.r(g/b) = rendercolor.r(g/b) * 255 / 256
也就是说这个spr是完全不透明的一张纸板,用spr查看工具看到的是黑色背景,游戏里出来的就是黑色背景


IP属地:江苏1楼2015-01-08 17:28回复


    IP属地:贵州2楼2015-01-08 17:49
    回复
      技术贴支持,还有最爱看到这些代码了


      IP属地:广东来自Android客户端3楼2015-01-08 17:51
      回复
        kRenderTransColor(rendermode=1)
        对固体实体来说,引擎使用:
        qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ALPHA);
        qglEnable(GL_BLEND);

        glDisable(GL_TEXTURE_2D);
        DrawGLSolidPoly(fa->polys);
        glEnable(GL_TEXTURE_2D);
        来处理渲染,其中GL_ALPHA代表不使用贴图里的颜色分量(只使用glColor指定的颜色)
        并且glDisable(GL_TEXTURE_2D);还把贴图给禁用了,这个时候实体的颜色完全由rendercolor决定,并且没有明暗


        IP属地:江苏4楼2015-01-08 18:14
        回复
          kRenderColor对sprite,使用:
          qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
          qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ALPHA);
          qglColor4ub(color.r, color.g, color.b, r_blend * 255);
          qglEnable(GL_BLEND);
          其中color.r(g/b) = rendercolor.r(g/b) * 255 / 256
          此时基本上效果跟kRenderNormal一样


          并且无视rendercolor设置的颜色


          IP属地:江苏6楼2015-01-08 18:19
          回复
            kRenderTransTexture
            对固体实体来说
            使用
            qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
            qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            qglColor4f(1, 1, 1, r_blend);
            qglDepthMask(0);
            qglEnable(GL_BLEND);
            其中r_blend = renderamt / 255.0
            此时无视rendercolor的设定,只使用renderamt作为alpha。并且关闭了深度缓冲的读写,这样这个固体实体就不会阻挡它后面的东西被绘制了。深度缓冲就是绘制时判定深度缓冲区中正在绘制的坐标的深度,绘制深度大(通俗的讲就是比较靠近屏幕的)的像素时会将原来小的深度值覆盖,也就是说如果靠近屏幕的像素已经有绘制东西了,在同一个屏幕坐标上远离屏幕的东西就会遮挡。
            举个栗子,不关闭深度缓冲区的后果:

            注意粉色的spr的坐标是靠近屏幕的,蓝色的圆环是远离屏幕的
            于是粉色的spr就把蓝色的spr给遮挡了


            IP属地:江苏7楼2015-01-08 18:31
            收起回复
              sprite使用kRenderTexture的渲染设置:
              glTexEnvf(GL_SRC_ALPHA, GL_TEXTURE_ENV_MODE, GL_MODULATE);
              glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
              glColor4ub(color.r, color.g, color.b, r_blend * 255);
              glEnable(GL_BLEND);
              由于没关闭深度缓冲区的写入,得到的结果就跟7L图中的一样,会出现诡异的明明是透明却把后面的东西遮挡了的情况。
              这就是spr使用kRenderTexture的效果,透明度完全取决于renderamt的设定,所以你可以看到后面还有略微透明的黑色背景
              glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);的算法就是像素的最终颜色=新的颜色*alpha + 源颜色 * (1-alpha),alpha取值0~1
              可以脑补一下,黑色的背景,rgb就是0,0,0,下图的alpha是200,源颜色就是他背后的东西的颜色
              按新的颜色*alpha + 源颜色 * (1-alpha)的算法可以发现,最终颜色是比较接近sprite本身的颜色的


              IP属地:江苏8楼2015-01-08 18:39
              回复
                固体实体使用kRenderTransAlpha:
                glEnable(GL_ALPHA_TEST);
                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
                glColor4f(1, 1, 1, 1);
                glDisable(GL_BLEND);
                glAlphaFunc(GL_GREATER, gl_alphamin.value);
                效果:无视rendercolor,renderamt,不开启混合,基本上和kRenderNormal一样,只是alpha大于25%的(gl_alphamin默认值0.25)部分才会被绘制,一般wad纹理的这个alpha值可以由{开头的纹理决定(让0 0 255颜色的部分的alpha变为0)
                sprite使用kRenderTransAlpha:
                qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
                qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                qglColor4ub(color.r, color.g, color.b, r_blend * 255);
                qglDepthMask(0);
                qglEnable(GL_BLEND);
                首先要求你的sprite有alpha通道,否则必然是跟kRenderNormal效果一样。
                alpha通道可以由spr的透明模式决定(IndexAlpha或AlphaTest)


                于是sprite的alpha通道可以由两种方式决定(indexalpha和alphatest)。
                indexalpha:spr中某个像素的调色板索引即为他的alpha值,颜色则直接取第255号调色板的值(所以你会发现
                indexalpha一般都是黑白的
                而alpatest则是当某个像素的调色板索引为255时该像素的alpha为0,否则alpha为255
                kRenderTransAlpha的spr效果基本是这样的:(前提你的spr能够正确产生alpha通道,如indexalpha / alphatest,下图用的是tga图片,本身就自带alpha通道)



                IP属地:江苏10楼2015-01-08 19:05
                回复
                  顶一个,我自己也做了一个固体,实体,spr,mdl各种渲染模式的比较,但太懒没有分享出来,而且也没楼主了解这么深入,表示上图对我我这种小白来说会好一些


                  IP属地:江苏13楼2015-01-08 19:25
                  回复
                    ===本期大讲堂到此结束===
                    如果有闲的蛋疼的同学可以把固体实体各种渲染的对比图发上来,我这里就不一个个发了(其实是懒得做地图)


                    IP属地:江苏15楼2015-01-08 19:34
                    回复
                      所以我再次丢下这两张图



                      IP属地:北京16楼2015-01-08 21:00
                      回复


                        来自Android客户端18楼2015-01-08 23:01
                        回复
                          以为是坟,结果是婶…


                          IP属地:江西来自iPhone客户端19楼2015-01-09 10:35
                          回复
                            必须顶啊


                            IP属地:广东来自Android客户端20楼2015-01-09 11:31
                            回复