Cerco di implementare la normale mappatura utilizzando LibGDX. Quindi ho ottenuto dei risultati positivi quando ho calcolato il colore diffuso e speculare nel vertex shader (almeno lo penso).Mappatura normale GLSL con LibGDX
Vertex Shader:
attribute vec4 a_position;
attribute vec2 a_texCoord0;
attribute vec3 a_normal;
varying vec2 v_texCoord;
varying float v_diffuse;
varying vec3 v_specular;
varying vec3 v_lightVec;
uniform mat4 u_worldTrans;
uniform mat4 u_projTrans;
uniform mat4 u_matViewInverseTranspose;
uniform mat4 u_matModelView;
const vec3 lightVector = vec3(0.0,0.0,-1.0);
void main()
{
// Output the unmodified vertex position.
gl_Position = u_projTrans * u_worldTrans * a_position;
mat3 normalMatrix = mat3(u_matViewInverseTranspose);
// compute the transformed normal
vec3 n = normalize(normalMatrix * a_normal);
// compute the light vector pointing toward the sun, in model coordinates
// x,y compose the longitude and z the (seasonal) lattitude of the nadir point.
//vec3 lightVec = normalize(vec3(u_matViewInverseTranspose * vec4(u_lightVec, 1.0)));
vec3 lightVec = normalize(normalMatrix * lightVector);
// Calculate a diffuse light intensity
//v_diffuse = dot(lightVec, n);
v_diffuse = clamp(dot(n, lightVec), 0.0, 1.0);
vec4 ecPosition = u_matModelView * a_position;
// compute the reflection vector
vec3 reflectVec = reflect(-lightVec, n);
// compute a unit vector in direction of viewing position
vec3 viewVec = normalize(vec3(-ecPosition));
// Calculate specular light intensity, scale down and apply a tint.
float specIntensity = pow(max(dot(reflectVec, viewVec), 0.0), 8.0);
v_specular = specIntensity *
//gloss color
vec3(1.,.7,.3) *
//gloss intensity
.7;
v_texCoord.y = 1.-a_texCoord0.y;
v_texCoord.x = a_texCoord0.x;
vec3 lightDir = normalize(lightVector - u_matModelView * a_position);
vec3 tangent=a_tangent;
vec3 t = normalize(normalMatrix * tangent);
vec3 b = cross (n, t);
vec3 v;
v.x = dot (lightDir, t);
v.y = dot (lightDir, b);
v.z = dot (lightDir, n);
v_lightVec = normalize (v);
}
Fragment Shader:
precision mediump float;
varying vec2 v_texCoord;
varying float v_diffuse;
varying vec3 v_specular;
varying vec3 v_lightVec;
uniform sampler2D u_texture;
uniform sampler2D u_normalMap;
void main()
{
vec3 ground = texture2D(u_texture, v_texCoord).rgb;
vec3 normal = normalize(2.0 * texture2D (u_normalMap, v_texCoord).rgb - 1.0);
float lamberFactor = max (dot (normal, v_lightVec), 0.0);
vec3 color = (ground.rgb * v_diffuse * lamberFactor + v_specular);
gl_FragColor = vec4 (color, 1.0);
}
Risultato:
Come si può vedere il risultato è reso corre ctly. Lo spot speculare si comporta come da molti esempi. Ma ho bisogno di implementare il colore speculare nello shader dei frammenti per ottenere un'immagine più impressionante. Quindi ho trovato un esempio da here e ora sto cercando di farlo funzionare.
Vertex Shader:
attribute vec4 a_position;
attribute vec2 a_texCoord0;
attribute vec3 a_normal;
attribute vec3 a_tangent;
varying vec2 v_texCoord;
varying vec3 v_lightVec;
varying vec3 v_eyeVec; //Added
uniform mat4 u_worldTrans;
uniform mat4 u_projTrans;
uniform mat4 u_matViewInverseTranspose;
uniform mat4 u_matModelView;
const vec3 lightVector = vec3(0.0,0.0,-1.0);
void main()
{
// Output the unmodified vertex position.
gl_Position = u_projTrans * u_worldTrans * a_position;
mat3 normalMatrix = mat3(u_matViewInverseTranspose);
// compute the transformed normal
vec3 n = normalize(normalMatrix * a_normal);
v_texCoord.y = 1.-a_texCoord0.y;
v_texCoord.x = a_texCoord0.x;
vec3 lightDir = normalize(lightVector - u_matModelView * a_position);
vec3 tangent=a_tangent;
vec3 t = normalize(normalMatrix * tangent);
vec3 b = cross (n, t);
vec3 v;
v.x = dot (lightDir, t);
v.y = dot (lightDir, b);
v.z = dot (lightDir, n);
v_lightVec = normalize (v);
//Added
vec3 ecPosition = u_matModelView * a_position;
vec3 tmp = vec3(-ecPosition);
v_eyeVec.x = dot(tmp, t);
v_eyeVec.y = dot(tmp, b);
v_eyeVec.z = dot(tmp, n);
v_eyeVec = normalize (v_eyeVec);
}
Fragment Shader:
precision mediump float;
varying vec2 v_texCoord;
varying vec3 v_lightVec;
varying vec3 v_eyeVec;
uniform sampler2D u_texture;
uniform sampler2D u_normalMap;
void main()
{
vec3 ground = texture2D(u_texture, v_texCoord).rgb;
vec3 normal = normalize(2.0 * texture2D (u_normalMap, v_texCoord).rgb - 1.0);
//Added
float distSqr = dot(v_lightVec, v_lightVec);
float att = clamp(1.0 - .25 * sqrt(distSqr), 0.0, 1.0);
vec3 lVec = v_lightVec * inversesqrt(distSqr);
vec3 vVec = normalize(v_eyeVec);
vec3 bump = normalize(texture2D(u_normalMap, v_texCoord).xyz * 2.0 - 1.0);
float diffuse = max(dot(lVec, bump), 0.0);
vec3 specular = pow(clamp(dot(reflect(-lVec, bump), v_eyeVec), 0.0, 1.0), 8.0) *
//gloss color
vec3(1.,.7,.3) *
//gloss intensity
.7;
vec3 color = (ground.rgb * diffuse + specular) * att;
gl_FragColor = vec4 (color, 1.0);
}
Risultato:
Il punto speculare è sbagliato. Ho pensato che succedesse a causa di un calcolo errato della matrice. Se è vero perché i primi due shader funzionano correttamente? Come ottengo la matrice model-view
, la matrice normal
e altre in LibGDX?
viewInvTraMatrix.set(camera.view);
viewInvTraMatrix.mul(renderable.worldTransform);
//model-view matrix
program.setUniformMatrix("u_matModelView", viewInvTraMatrix);
viewInvTraMatrix.inv(); //inverse
viewInvTraMatrix.tra(); //transpose
//normal matrix
program.setUniformMatrix("u_matViewInverseTranspose", viewInvTraMatrix);
//other matrix
program.setUniformMatrix("u_worldTrans", renderable.worldTransform);
program.setUniformMatrix("u_projTrans", camera.combined);
Quindi, la mia domanda è cosa c'è di sbagliato nell'ultima coppia di shader?
Perché non dare un'occhiata [qui] (http://www.microbasic.net/2015/01/tutorial-shadow-mapping-with-libgdx-3d-shadow-mapping-lighting/). È un po 'lungo, ma potrebbe aiutare – Fish
Hai indicato la mappatura delle ombre, ma ti sto chiedendo una mappatura normale! Sii attento! – Nolesh
Bump e normale stanno calcolando lo stesso valore, e ho usato qualcosa come specpower 3 invece di 8, ma per il resto pixelhader sembra corretto. Non sono sicuro del "matViewInverseTranspose", poiché si suppone che mantenga la trasposizione inversa della matrice del modello. Dal momento che lo hai usato anche come "matModelView", sembra che mantenga anche la trasformazione della vista. Ma la matrice materiale dovrebbe essere calcolata solo sulla matrice del modello. – StarShine