スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

DXライブラリでSSAO3

こんにちは、ペチ子です
ペチってなんだろう


そういえばSSAOが中途半端になってたので今回もSSAO
いえ、毎回中途半端ですが

SSAOってなんだって人は詳細はwebで!

シンプルルーム
効果がわかりやすいようにシンプルな部屋を作ってみました
犯人はヤスだと思います

これにSSAO
SSAO強め
強めにしてます。英語で言うとyarisugiです
ランダムと法線を適当に計算してる手抜きなので色々おかしなとこもありますが
部屋の隅とか、接地してる部分とかちゃんと暗くなってます
それっぽければよいのです

これをぼかして上の元画像と合成すればできあがり
SSAO適用
うんこれは掛けない方がマシなレベル
シーンをちゃんとして、パラメーターを調整すれば見映えは良くなります

ということでHLSLです
事前に深度バッファを適当なスクリーンに出力しといてください
その辺はめんどくさい前にやった気がするので省略

SSAO_PS.pso
// 深度バッファ
sampler DepthMapTexture : register( s1 ) ;
// 法線
//sampler NormalMapTexture : register( s2 ) ;
// ランダム
//sampler NoiseTexture : register( s3 ) ;

//パラメーター
static const float strength = 0.125;//0.125
static const float falloff = 0.0000002;
static const float rad = 0.02;//0.006
static const float total_strength = 1.0;

#define samples 16
static const float invSamples = 1.0 / (float)samples;
static const float3 sample_sphere[samples] = {
float3( 0.5381, 0.1856,-0.4319), float3( 0.1379, 0.2486, 0.4430),
float3( 0.3371, 0.5679,-0.0057), float3(-0.6999,-0.0451,-0.0019),
float3( 0.0689,-0.1598,-0.8547), float3( 0.0560, 0.0069,-0.1843),
float3(-0.0146, 0.1402, 0.0762), float3( 0.0100,-0.1924,-0.0344),
float3(-0.3577,-0.5301,-0.4358), float3(-0.3169, 0.1063, 0.0158),
float3( 0.0103,-0.5869, 0.0046), float3(-0.0897,-0.4940, 0.3287),
float3( 0.7119,-0.0154,-0.0918), float3(-0.0533, 0.0596,-0.5411),
float3( 0.0352,-0.0631, 0.5460), float3(-0.4776, 0.2847,-0.0271)
};

float3 normal_from_depth(float depth, float2 UV) {

const float2 offset1 = float2(0.0,0.001);
const float2 offset2 = float2(0.001,0.0);

float depth1 = tex2D(DepthMapTexture, UV + offset1).r;
float depth2 = tex2D(DepthMapTexture, UV + offset2).r;

float3 p1 = float3(offset1, depth1 - depth);
float3 p2 = float3(offset2, depth2 - depth);

float3 normal = cross(p1, p2);
normal.z = -normal.z;

return normalize(normal);
}

float3 get_Rnd(float2 UV) {
float noiseX = (frac(sin(dot(UV, float2(12.9898,78.233) * 2.0)) * 43758.5453));
float noiseY = sqrt(1 - noiseX * noiseX);
float noiseZ = abs(noiseX + noiseX) * 0.5;
return float3(noiseX, noiseY, noiseZ);
}

float4 main(float2 Tex : TEXCOORD0) : COLOR0
{
float3 rnd = get_Rnd(Tex);
//float2 noiseScale = float2(1024.0 / 64.0, 768.0 / 64.0);
//float3 rnd = tex2D(NoiseTexture, Tex * noiseScale).xyz * 2.0 - 1.0;

float depth = tex2D(DepthMapTexture, Tex).r;
//float3 normal = (tex2D(NormalMapTexture, Tex).rgb - 0.5f) * 2.0f;
float3 normal = normal_from_depth(depth, Tex);

float bl = 0.0;
float radD = rad / depth;

float depthDiff;
float2 rpos;
float3 ray;
float4 occFrag;

for( int i = 0; i < samples; ++i )
{
ray = radD * reflect( sample_sphere[i], rnd );

rpos = Tex + sign(dot(ray, normal)) * ray.xy * float2(1.0f, -1.0f);
//occFrag.xyz = (tex2D(NormalMapTexture, rpos).xyz -0.5f ) * 2.0f;
occFrag.a = tex2D(DepthMapTexture, rpos).r;
occFrag.xyz = normal_from_depth(occFrag.a, rpos);

depthDiff = depth - occFrag.a;

bl += step( falloff, depthDiff ) * (1.0 - dot( normalize(occFrag.xyz), normal )) *
(1.0 - smoothstep( falloff, strength, depthDiff ));
}

float ao = 1.0 - total_strength * bl * invSamples;

return float4( ao, ao, ao, 1.0 );
}


コメントアウトしてるところは、ランダムテクスチャとか法線をテクスチャ出力した場合の処理
めんどうなので深度だけの手抜きなんちゃってSSAOです

パラメーターは上の方にまとまっているので色々弄ると良いでしょう

これとは関係ないですが、マルチレンダーターゲットで深度バッファを出力してるせいか、アンチエイリアスが効きませんでした
DirectXの仕様だそうですが、EdgeAAの時はマルチでAAできたような。ううむ


適当なテクスチャを貼って、パラメーターも調整してみましたの図

通常描画
通常描画

SSAOあり描画
SSAO

ああ、わかりました
エフェクトを使ったからって絵面が劇的に良くなるはずもなく
必要なのは画作りのセンスってことですね

センスをください

コメントの投稿

非公開コメント

プロフィール

ペチコートさん

Author:ペチコートさん
大航海時代オンライン
Zephyros、Eurosサーバーに潜伏中

偽ペチコ1号・2号
ペチコの手下達
Zephyrosサーバーに潜伏中

最新記事
月別アーカイブ
カテゴリ
リンク
最新コメント
検索フォーム
QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。