私は論文「Single-Pass Wireframe Rendering」を実装しようとしていますが、これは非常に単純に見えますが、厚くて暗い値に関しては期待どおりの結果が得られます。
この論文には、高度を計算するための正確なコードが記載されていなかったので、適切だと思ったとおりに実行しました。コードは、3 つの頂点をビューポート空間に投影し、それらの「高度」を取得して、フラグメント シェーダーに送信する必要があります。
フラグメント シェーダーは、最も近いエッジの距離を決定し、edgeIntensity を生成します。この値で何をすべきかわかりませんが、[0,1] の間でスケーリングすることになっているため、出力色に対して逆数を掛けますが、非常に弱いだけです。
論文で取り上げられているかどうかわからないいくつかの質問がありました。まず、高度は 3D ではなく 2D で計算する必要がありますか? 2 つ目は、DirectX のビューポート空間の Z 範囲が異なる DirectX の機能をサイトに掲載したことです。それは問題ですか?透視投影を修正することを推奨しているため、ビューポート空間座標の w 値で発信高度距離を事前に乗算しています。
補正されていない画像には、遠方を向いている側の遠近法が補正されていないという明らかな問題があるようですが、遠近法が補正された画像の値は非常に弱いです。
私のコードの何が問題なのか、またはここからデバッグする方法を誰かが見ることができますか?
GLSL の頂点コード...
float altitude(in vec3 a, in vec3 b, in vec3 c) { // for an ABC triangle
vec3 ba = a - b;
vec3 bc = c - b;
vec3 ba_onto_bc = dot(ba,bc) * bc;
return(length(ba - ba_onto_bc));
}
in vec3 vertex; // incoming vertex
in vec3 v2; // first neighbor (CCW)
in vec3 v3; // second neighbor (CCW)
in vec4 color;
in vec3 normal;
varying vec3 worldPos;
varying vec3 worldNormal;
varying vec3 altitudes;
uniform mat4 objToWorld;
uniform mat4 cameraPV;
uniform mat4 normalToWorld;
void main() {
worldPos = (objToWorld * vec4(vertex,1.0)).xyz;
worldNormal = (normalToWorld * vec4(normal,1.0)).xyz;
//worldNormal = normal;
gl_Position = cameraPV * objToWorld * vec4(vertex,1.0);
// also put the neighboring polygons in viewport space
vec4 vv1 = gl_Position;
vec4 vv2 = cameraPV * objToWorld * vec4(v2,1.0);
vec4 vv3 = cameraPV * objToWorld * vec4(v3,1.0);
altitudes = vec3(vv1.w * altitude(vv1.xyz,vv2.xyz,vv3.xyz),
vv2.w * altitude(vv2.xyz,vv3.xyz,vv1.xyz),
vv3.w * altitude(vv3.xyz,vv1.xyz,vv2.xyz));
gl_FrontColor = color;
}
そして私のフラグメントコード...
varying vec3 worldPos;
varying vec3 worldNormal;
varying vec3 altitudes;
uniform vec3 cameraPos;
uniform vec3 lightDir;
uniform vec4 singleColor;
uniform float isSingleColor;
void main() {
// determine frag distance to closest edge
float d = min(min(altitudes.x, altitudes.y), altitudes.z);
float edgeIntensity = exp2(-2.0*d*d);
vec3 L = lightDir;
vec3 V = normalize(cameraPos - worldPos);
vec3 N = normalize(worldNormal);
vec3 H = normalize(L+V);
//vec4 color = singleColor;
vec4 color = isSingleColor*singleColor + (1.0-isSingleColor)*gl_Color;
//vec4 color = gl_Color;
float amb = 0.6;
vec4 ambient = color * amb;
vec4 diffuse = color * (1.0 - amb) * max(dot(L, N), 0.0);
vec4 specular = vec4(0.0);
gl_FragColor = (edgeIntensity * vec4(0.0)) + ((1.0-edgeIntensity) * vec4(ambient + diffuse + specular));
}
