我試圖實現「單通線框渲染」這個文件,這看起來很簡單,但它給了我所期望的厚度,黑暗的值。OpenGL:調試「單通線框渲染」
該文件沒有給出確切的代碼來找出高度,所以我做了它,因爲我認爲合適。代碼應該將三個頂點投影到視口空間中,獲取它們的「高度」並將它們發送給片段着色器。
片段着色器確定最近邊緣的距離並生成edgeIntensity。我不確定我應該怎樣處理這個值,但是因爲它應該在[0,1]之間進行縮放,所以我將反轉與我的輸出顏色相乘,但它非常弱。
我有幾個問題,我不確定在論文中提到。首先,應該用2D而不是3D來計算海拔高度?其次,他們使用DirectX功能,DirectX具有不同的視口空間z範圍,是否正確?這很重要嗎?我將視出口高度距離乘以視口空間座標的w值,因爲他們建議對透視投影進行校正。
image trying to correct for perspective projection
no correction (not premultiplying by w-value)
非校正的圖像好像還沒有修正的更遠,面對的側面透視清晰的問題,但角度校正一個具有非常弱的值。
任何人都可以看到我的代碼有什麼問題,或者如何從這裏進行調試?
在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));
}
您可以使用'fwidth(min_dist)'作爲1像素的厚度,以距離邊緣的距離爲單位計算,並使用'step(fwidth(min_dist),min_dist)或更好的'smoothstep(fwidth(min_dist), 2 * fwidth(min_dist),min_dist)'。這消除了「魔術數字」'0.005'的需要。 –