1

現在、セル シェーディング シェーダーを作成していますが、エッジ検出に問題があります。現在、非線形深度バッファ値でラプラシアン エッジ検出を利用する次のコードを使用しています。

uniform sampler2d depth_tex;
void main(){
vec4 color_out;
float znear = 1.0;
float zfar = 50000.0;
float depthm = texture2D(depth_tex, gl_TexCoord[0].xy).r;
float lineAmp = mix( 0.001, 0.0, clamp( (500.0 / (zfar + znear - ( 2.0 * depthm - 1.0 ) * (zfar - znear) )/2.0), 0.0, 1.0 ) );// make the lines thicker at close range

float depthn = texture2D(depth_tex, gl_TexCoord[0].xy + vec2( (0.002 + lineAmp)*0.625 , 0.0) ).r;
depthn = depthn / depthm;

float depths = texture2D(depth_tex, gl_TexCoord[0].xy - vec2( (0.002 + lineAmp)*0.625 , 0.0) ).r;
depths = depths / depthm;

float depthw = texture2D(depth_tex, gl_TexCoord[0].xy + vec2(0.0 , 0.002 + lineAmp) ).r;
depthw = depthw / depthm;

float depthe = texture2D(depth_tex, gl_TexCoord[0].xy - vec2(0.0 , 0.002 + lineAmp) ).r;
depthe = depthe / depthm;

float Contour = -4.0 + depthn + depths + depthw + depthe;

float lineAmp2 = 100.0 * clamp( depthm - 0.99, 0.0, 1.0);
lineAmp2 = lineAmp2 * lineAmp2;
Contour = (512.0 + lineAmp2 * 204800.0 ) * Contour;

if(Contour > 0.15){
    Contour = (0.15 - Contour) / 1.5 + 0.5;
} else
    Contour = 1.0;

color_out.rgb = color_out.rgb * Contour;
    color_out.a = 1.0;
    gl_FragColor = color_out;
}

しかし、それはハックです[lineAmp2に注意してください]、遠距離での詳細は失われます. そこで、別のアルゴリズムを作成しました。

[ラプラシアン エッジ検出が使用されていることに注意してください]

1. 深度バッファから 5 つのサンプルを取得します: depthm、depthn、depths、depthw、depthe。ここで、depthm は処理されたフラグメントの正確な位置、depthn はわずかに上、depths はわずかに下などです。

2.カメラ空間での実際の座標を計算します[線形に変換するだけでなく]。

3. サイド サンプルを中間サンプルと減算して比較し、カメラ空間の 2 点間の距離の差で割ってそれぞれの差を正規化し、4 つの結果すべてを加算します。これは、理論的には、カメラから離れた場所で 2 つのフラグメントが画面上では非常に近いが、カメラ空間では非常に離れている状況に役立つはずです。これは線形深度テストでは致命的です。

どこ:

2.a [url=http://stackoverflow.com/questions/6652253/getting-the-true-z-value-from-the-depth-buffer]http:/ のアルゴリズムを使用して、非線形深度を線形に変換します。 /stackoverflow.com/questions/6652253/getting-the-true-z-value-from-the-depth-buffer[/url] 正確なコード:

uniform sampler2D depthBuffTex;
uniform float zNear;
uniform float zFar;
varying vec2 vTexCoord;
void main(void)
{
float z_b = texture2D(depthBuffTex, vTexCoord).x;
float z_n = 2.0 * z_b - 1.0;
float z_e = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));
}

2.b スクリーン座標を [tan a, tan b] に変換します。ここで、a は水平角度、bi 垂直です。いくつかの球座標を使ったもっと良い用語があるかもしれませんが、私はまだ知りません。

2.c 3d ベクトル (変換された画面座標、1.0) を作成し、線形深度でスケーリングします。これは、フラグメントの推定カメラ空間座標だと思います。みたいですね。

3.a それぞれの違いは次のとおりです: (depthm - sidedepth)/length( positionm - sideposition)

そして、私はいつでも何かを台無しにしたかもしれません。コードは問題ないように見えますが、アルゴリズムは自分で作成したため、そうではない可能性があります。

私のコード:

uniform sampler2d depth_tex;
void main(){
float znear = 1.0;
float zfar = 10000000000.0;

float depthm = texture2D(depth_tex, gl_TexCoord[0].xy + distort ).r;
depthm = 2.0 * zfar * znear / (zfar + znear - ( 2.0 * depthm - 1.0 ) * (zfar - znear) );    //convert to linear
vec2 scorm = (gl_TexCoord[0].xy + distort) -0.5;    //conversion to desired coordinates space. This line returns value from range (-0.5,0.5)
scorm = scorm * 2.0 * 0.5;     // normalize to (-1, 1) and multiply by tan FOV/2, and default fov is IIRC 60 degrees
scorm.x = scorm.x * 1.6;      //1.6 is aspect ratio 16/10
vec3 posm = vec3( scorm, 1.0 );
posm = posm * depthm;      //scale by linearized depth



float depthn = texture2D(depth_tex, gl_TexCoord[0].xy + distort + vec2( 0.002*0.625  , 0.0) ).r;          //0.625 is aspect ratio 10/16
depthn = 2.0 * zfar * znear / (zfar + znear - ( 2.0 * depthn - 1.0 ) * (zfar - znear) );
vec2 scorn = (gl_TexCoord[0].xy + distort + vec2( 0.002*0.625, 0.0) ) -0.5;
scorn = scorn * 2.0 * 0.5;
scorn.x = scorn.x * 1.6;
vec3 posn = vec3( scorn, 1.0 );
posn = posn * depthn;

float depths = texture2D(depth_tex, gl_TexCoord[0].xy + distort - vec2( 0.002*0.625 , 0.0) ).r;
depths = 2.0 * zfar * znear / (zfar + znear - ( 2.0 * depths - 1.0 ) * (zfar - znear) );
vec2 scors = (gl_TexCoord[0].xy + distort - vec2( 0.002*0.625, 0.0) ) -0.5;
scors = scors * 2.0 * 0.5;
scors.x = scors.x * 1.6;
vec3 poss = vec3( scors, 1.0 );
poss = poss * depths;

float depthw = texture2D(depth_tex, gl_TexCoord[0].xy + distort + vec2(0.0 , 0.002) ).r;
depthw = 2.0 * zfar * znear / (zfar + znear - ( 2.0 * depthw - 1.0 ) * (zfar - znear) );
vec2 scorw = ( gl_TexCoord[0].xy + distort + vec2( 0.0 , 0.002) ) -0.5;
scorw = scorw * 2.0 * 0.5;
scorw.x = scorw.x * 1.6;
vec3 posw = vec3( scorw, 1.0 );
posw = posw * depthw;

float depthe = texture2D(depth_tex, gl_TexCoord[0].xy + distort - vec2(0.0 , 0.002) ).r;
depthe = 2.0 * zfar * znear / (zfar + znear - ( 2.0 * depthe - 1.0 ) * (zfar - znear) );
vec2 score = ( gl_TexCoord[0].xy + distort - vec2( 0.0 , 0.002) ) -0.5;
score = score * 2.0 * 0.5;
score.x = score.x * 1.6;
vec3 pose = vec3( score, 1.0 );
pose = pose * depthe;

float Contour = ( depthn - depthm )/length(posm - posn) + ( depths - depthm )/length(posm - poss) + ( depthw - depthm )/length(posm - posw) + ( depthe - depthm )/length(posm - pose);
Contour = 0.25 * Contour;

color_out.rgb = vec3( Contour, Contour, Contour );
    color_out.a = 1.0;
    gl_FragColor = color_out;
}

2 番目のコードの正確な問題は、より長い距離でひどいアーティファクトが発生することです。

私の目標は、それらのいずれかが適切に機能するようにすることです。線形化された深度バッファと非線形化された深度バッファの両方で精度/品質を向上させるために使用できるトリックはありますか? 線形化された深度バッファーのアルゴリズムに何か問題がありますか?

4

0 に答える 0