游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3608|回复: 1

SSAO效果失败,求指点

[复制链接]

1

主题

4

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2013-9-8 11:39:22 | 显示全部楼层 |阅读模式
这是ps的主要部分

float4 main(PS_IN pIn):SV_TARGET
{
    //视空间坐标
    float3 posInView=GetViewPos(pIn.texCoor);
    //深度
    float deep=posInView.z;
    //采样球缩放
    float SphereR=GetSamRadius(deep);
    //视空间法线
    float3 n=gBuff_1.Sample(Sam_Point_Warp,pIn.texCoor).xyz;
    int sampleCount=32;
    float ssaoRate=0;
    for(int idx=0;idx<sampleCount;++idx)
    {
        //获得一个随机向量
        float3 ranVec3=randVec[idx];
        //用随机纹理反射
        ranVec3=normalize(RefByNoise(pIn.texCoor,ranVec3));
        //只要垂直于表面的上半球的矢量(用于消除边缘发亮)
        if(dot(n,ranVec3)<0)
        {
            ranVec3=-ranVec3;
        }
        //根据距离缩放球球
        ranVec3=ranVec3*SphereR;
        //找到需要采样的点
        float3 posForSample=posInView+ranVec3;
        //需要采样点的UV
        float2 uvForSample=viewPosToUV(posForSample);
        //这些被采样点对应UV取得场景的实际视空间坐标
        float3 viewPosInScene=GetViewPos(uvForSample);
        ssaoRate+=SSAO(posForSample,viewPosInScene,posInView,SphereR);
    }
    ssaoRate/=sampleCount;
    ssaoRate=1-ssaoRate;
    return float4(ssaoRate,ssaoRate,ssaoRate,1);
}

以下是相关的其它部分代码

G buffer的几个纹理声明,法线和坐标都在ViewSpace
Texture2D       gBuff_0 : register( t0 );//Texture
Texture2D       gBuff_1 : register( t1 );//Normal  
Texture2D       gBuff_2 : register( t2 );//Position  
Texture2D       zBuffer : register( t3 );//Depth

用于反射的随机法线的纹理
Texture2D   gRefNosize: register( t4 );
用于采样的随机矢量,最长不超过1
static float3 randVec[32]={float3(0.101.....................}
采样器
SamplerState   Sam_Point_Warp:   register(s0);

以下是几个关键函数
1.为了远景和近景都能比较好的ssao,所以对采样球进行缩放
float GetSamRadius(float distance)
{
    //tanH_FOV是摄影机水平张角一半的正切
    return tanH_FOV*distance*2.0*AOScanDis;
}

2.将视空间3d坐标转为屏幕2d坐标
//把这个视空间的点转换到屏幕的UV
float2 viewPosToUV(float3 p)
{
    //1。把投影看作是发生在z=1的地方
    p.xy=p.xy/p.z;
    //z等于1处的宽高的一半求出来
    float w=tanH_FOV;
    float h=BackBufferWH.y/BackBufferWH.x*w;
    //算出坐标占半宽高的比例
    p.x=p.x/w;
    p.y=p.y/h;
    //UV空间xy方向的转换
    float2 UV=(float2)0;
    UV.x=p.x*0.5+0.5;
    UV.y=-p.y*0.5+0.5;
     return float2(UV.x,UV.y);
}

3 测试ssao是否存在的函数
//第一个参数,采样球的端点
//第二个参数,真实采样出来的点
//第三个参数,中心点
//第四个参数,采样球半径
//

float SSAO(float3 pS,float3 pR,float3 pC,float sphereR)
{
    if(pS.z>pR.z)
    {
        float occDis=length(pR-pC);
        if(occDis<=AOBias)
        {
            return 0;
        }
        else
        {
            return max((1-pow((occDis-AOBias)/sphereR,AOIntensity)),0);
         }
    }
    else
    {
        return 0;
    }
}


本来渲染的是个山体,现在结果完全不正确,,求高手指点,哪里错了
ssaoFail.jpg


1

主题

4

帖子

13

积分

新手上路

Rank: 1

积分
13
 楼主| 发表于 2013-9-8 11:51:06 | 显示全部楼层
本帖最后由 LPVOID 于 2013-9-8 11:55 编辑

视空间法线我在 渲染到G的时候就没有把(-1,+1)规一到(0 ,1),因此这里直接采样出来就是法线
float3 n=gBuff_1.Sample(Sam_Point_Warp,pIn.texCoor).xyz;

另外加几个对比图
Diff
tex.jpg
Normal
SN.jpg
AO
texS.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-26 08:25

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表