您当前的位置: 首页 >  缓存

Jave.Lin

暂无认证

  • 3浏览

    0关注

    704博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

深度缓存

Jave.Lin 发布时间:2016-04-14 01:26:18 ,浏览量:3

想写个:软光栅器 其实上周就已经开始写了一小部分了,但写着写着发现对很多现有的渲染引擎的架构设计不足,很多概念(术语)都不知道其内部真正的实现原理,根本不知道怎么写下去,所以只能对API的使用理解下,或是直接有原理说明后,才能动手去写。

看到了这篇文章的简单描述深度缓存: http://blog.csdn.net/aa20274270/article/details/48735229

为了加深理解,写了以下的伪代码: 很多渲染引擎的低层架构,我一点都不了解,都是靠猜的方式, 后面,如果能找到什么更好的学习方法,再拿出来分享; 欢迎大家指点

// @authro Jave.Lin
// @date 2016-04-14 01:17

// 对深度缓存的一些理解,写的一些伪代码
// 可能理解还不是最好的,希望大家可以指点

// 性能上先不考虑,先考虑可读性

// 已绘制的深度缓存数据
// 可以理解:深度缓存是有很多层缓存数据的
public class ZBuffer
{
    // 索引>=0,越小越靠近屏幕
    // 当然,这个大小,与远近的关系,都是与坐标系相关
    // 如果是:左手坐标那就是,那就是越小越远
    // 反之,右手坐标,越大越远
    public var vec:ZLayerBuffer[];

    public function ZBuffer()
    {
        vec = new ZLayerBuffer[];
    }

    // color = AARRGGBB
    public function write(x:int, y:int, z:Number, color:uint):void
    {
        // 根据z深度来,定应该放到哪个深度缓存中,
        // binary search (二分法)方式来先查,放到哪个index适合
        var idx:int = searchInsert(vec, z);
        var lBuffer:ZLayerBuffer = vec[idx];
        if (lBuffer == null || lBuffer.z != z)
        {
            lBuffer = new ZLayerBuffer();
            lBuffer.z = z;
            vec[idx] = lBuffer;
        }
        lBuffer.write(x, y, color);
    }

    // 我估计那些遮挡效果中,作一些特效处理的效果就需要用到read
    public function read(x:int, y:int, z:Number):uint
    {
        var idx:int = search(vec, z);
        var lBuffer:ZLayerBuffer = vec[idx];
        if (lBuffer == null)
        {
            return 0;
        }
        return lBuffer.read(x, y);
    }

    public function readFinal(x:int, y:int):uint
    {
        var a:int;
        var result:uint;
        var tC:uint;
        for (var i:int = 0; i < vec.length; ++i)
        {
            var lBuff:ZLayerBuffer = vec[i];
            tc = lBuffer.read(x, y);
            result = Utils.mergeC_argb(result, tc);
            a += (result & 0xff000000) >> 24;
            if (a >= 255)
            {
                break;
            }
        }
        return result;
    }

    // 每次在draw之前,估计所有深度缓存的数据都得重置一下
    public function clear():void
    {

    }

    private function searchInsert(vec:ZLayerBuffer[], z:Number):int
    {

    }

    private function search(vec:ZLayerBuffer[], z:Number):int
    {

    }
}

// 单个深度层中的map颜色数据
public class ZLayerBuffer
{
    public var z:Number;
    // colorMap的key就是x,y,value就是一个:color
    // x,y就是screen上的一个pixel坐标
    public var colorMap:HashMap;

    public function ZLayerBuffer()
    {
        colorMap = new HashMap();
    }

    // color = AARRGGBB
    public function write(x:int, y:int, color:uint):void
    {
        var rows:HashMap = colorMap[x];
        if (rows == null)
        {
            colorMap[x] = rows = new HashMap();
        }
        rows[y] = color;
    }

    public function read(x:int, y:int):uint
    {
        var rows:HashMap = colorMap[x];
        if (rows == null)
        {
            return 0;
        }
        return rows[y];
    }
}

public class Utils
{
    public function mergeC_argb(a:uint, b:uint):uint
    {

    }
}

深夜了,睡了,还有深度测试等有空继续;

新版优化:
// @authro Jave.Lin
// @date 2016-04-14 01:17

// 对深度缓存的一些理解,写的一些伪代码
// 可能理解还不是最好的,希望大家可以指点

// 性能上先不考虑,先考虑可读性

// 已绘制的深度缓存数据
// 可以理解:深度缓存是有很多层缓存数据的
public class ZBuffer
{
    // 越小越靠近屏幕
    // 当然,这个大小,与远近的关系,都是与坐标系相关
    // 如果是:左手坐标那就是,那就是越大越远,越小越近
    // 反之,右手坐标,越小越远,越大越近
    // 以下的远近判断,默认都以左手坐标
    public var vec:Fragment[];

    public var enabledTest:Boolean = true;

    public function ZBuffer()
    {
        vec = new Fragment[];
    }

    // color = AARRGGBB
    public function write(x:int, y:int, z:Number, color:uint):void
    {
        var frag:Fragment = vec[x][y];
        if (frag == null)
        {
            vec[x][y] = frag = new Fragment();
        }
        // 新z更近
        var a:int;
        // 启用深度测试
        if (enabledTest)
        {
            if (frag.z > z) // 这里头其实要根据坐标系的判断用:>还是> 24;
                if (a < 255)
                {
                    frag.color = Util.mergeC_argb(color, frag.color);
                }
                else
                {
                    frag.color = color; // 直接覆盖之前的颜色
                }
            }
            else // 新z更远
            {
                a = (frag.color & 0xff000000) >> 24;
                if (a < 255)
                {
                    frag.color = Util.mergeC_argb(frag.color, color);
                }
                else
                {
                    // nothing to do...
                }
            }
        }
        else
        {
            a = (color & 0xff000000) >> 24;
            if (a < 255)
            {
                frag.color = Util.mergeC_argb(color, frag.color);
            }
            else
            {
                frag.color = color; // 直接覆盖之前的颜色
            }
        }
    }

    // 我估计那些遮挡效果中,作一些特效处理的效果就需要用到read
    public function read(x:int, y:int):uint
    {
        var frag:Fragment = vec[x][y];
        return frag ? frag.color : 0;
    }

    // 每次在draw之前,估计所有深度缓存的数据都得重置一下
    public function clear():void
    {
        for (var rows:Fragment[] in vec)
        {
            for (var cols:Fragment in rows)
            {
                cols.z = 0;
                cols.color = 0;
            }
        }
    }
}

// 单个深度层中的map颜色数据
public class Fragment
{
    public var z:Number = 0;
    public var color:uint = 0;
}

public class Utils
{
    // 默认混合方式使用类似:blendMode.normal的混合因子
    public function mergeC_argb(a:uint, b:uint):uint
    {
        var aa:int = (a & 0xff000000) >> 24;
        var ba:int = (b & 0xff000000) >> 24;
        var aaF:Number = aa / 255;
        var baF:Number = ba / 255;

        var ar:int = ((a & 0x00ff0000) >> 18) * aaF;
        var ag:int = ((a & 0x0000ff00) >> 8) * aaF;
        var ab:int = (a & 0x000000ff) * aaF;

        var br:int = ((b & 0x00ff0000) >> 18) * baF;
        var bg:int = ((b & 0x0000ff00) >> 8) * baF;
        var bb:int = (b & 0x000000ff) * baF;

        return
        (((aa + ba) & 0xff)             
关注
打赏
1664331872
查看更多评论
0.0406s