Skip to content

Commit 03ffe78

Browse files
committed
Fix rotating normal map bug (issue phaserjs#3870)
1 parent 4b162fb commit 03ffe78

3 files changed

Lines changed: 42 additions & 2 deletions

File tree

src/renderer/webgl/pipelines/ForwardDiffuseLightPipeline.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ var ForwardDiffuseLightPipeline = new Class({
4848
* @since 3.11.0
4949
*/
5050
this.defaultNormalMap;
51+
52+
/**
53+
* Inverse rotation matrix for normal map rotation fixing.
54+
*/
55+
this.inverseRotationMatrix = new Float32Array([
56+
1, 0, 0,
57+
0, 1, 0,
58+
0, 0, 1
59+
]);
5160
},
5261

5362
/**
@@ -244,6 +253,7 @@ var ForwardDiffuseLightPipeline = new Class({
244253
}
245254

246255
this.setTexture2D(normalTexture.glTexture, 1);
256+
this.setNormalMapRotation(rotation);
247257

248258
var camMatrix = this._tempMatrix1;
249259
var spriteMatrix = this._tempMatrix2;
@@ -412,6 +422,33 @@ var ForwardDiffuseLightPipeline = new Class({
412422
this.renderer.setPipeline(gameObject.defaultPipeline);
413423
},
414424

425+
/**
426+
* Rotates the normal map vectors inversely by the given angle.
427+
* Only works in 2D space.
428+
* @param {number} rotation rotation in angles
429+
*/
430+
setNormalMapRotation: function (rotation)
431+
{
432+
var inverseRotationMatrix = this.inverseRotationMatrix;
433+
if (rotation)
434+
{
435+
var rot = -rotation;
436+
var c = Math.cos(rot);
437+
var s = Math.sin(rot);
438+
439+
inverseRotationMatrix[1] = s;
440+
inverseRotationMatrix[3] = -s;
441+
inverseRotationMatrix[0] = inverseRotationMatrix[4] = c;
442+
}
443+
else
444+
{
445+
inverseRotationMatrix[0] = inverseRotationMatrix[4] = 1;
446+
inverseRotationMatrix[1] = inverseRotationMatrix[3] = 0;
447+
}
448+
449+
this.renderer.setMatrix3(this.program, 'uInverseRotationMatrix', false, inverseRotationMatrix);
450+
},
451+
415452
/**
416453
* Takes a Sprite Game Object, or any object that extends it, which has a normal texture and adds it to the batch.
417454
*
@@ -437,6 +474,7 @@ var ForwardDiffuseLightPipeline = new Class({
437474
this.renderer.setPipeline(this);
438475

439476
this.setTexture2D(normalTexture.glTexture, 1);
477+
this.setNormalMapRotation(sprite.rotation);
440478

441479
TextureTintPipeline.prototype.batchSprite.call(this, sprite, camera, parentTransformMatrix);
442480
}

src/renderer/webgl/shaders/ForwardDiffuse-frag.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module.exports = [
1919
'uniform sampler2D uNormSampler;',
2020
'uniform vec3 uAmbientLightColor;',
2121
'uniform Light uLights[kMaxLights];',
22+
'uniform mat3 uInverseRotationMatrix;',
2223
'',
2324
'varying vec2 outTexCoord;',
2425
'varying vec4 outTint;',
@@ -28,7 +29,7 @@ module.exports = [
2829
' vec3 finalColor = vec3(0.0, 0.0, 0.0);',
2930
' vec4 color = texture2D(uMainSampler, outTexCoord) * vec4(outTint.rgb * outTint.a, outTint.a);',
3031
' vec3 normalMap = texture2D(uNormSampler, outTexCoord).rgb;',
31-
' vec3 normal = normalize(vec3(normalMap * 2.0 - 1.0));',
32+
' vec3 normal = normalize(uInverseRotationMatrix * vec3(normalMap * 2.0 - 1.0));',
3233
' vec2 res = vec2(min(uResolution.x, uResolution.y)) * uCamera.w;',
3334
'',
3435
' for (int index = 0; index < kMaxLights; ++index)',

src/renderer/webgl/shaders/src/ForwardDiffuse.frag

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ uniform sampler2D uMainSampler;
1818
uniform sampler2D uNormSampler;
1919
uniform vec3 uAmbientLightColor;
2020
uniform Light uLights[kMaxLights];
21+
uniform mat3 uInverseRotationMatrix;
2122

2223
varying vec2 outTexCoord;
2324
varying vec4 outTint;
@@ -27,7 +28,7 @@ void main()
2728
vec3 finalColor = vec3(0.0, 0.0, 0.0);
2829
vec4 color = texture2D(uMainSampler, outTexCoord) * vec4(outTint.rgb * outTint.a, outTint.a);
2930
vec3 normalMap = texture2D(uNormSampler, outTexCoord).rgb;
30-
vec3 normal = normalize(vec3(normalMap * 2.0 - 1.0));
31+
vec3 normal = normalize(uInverseRotationMatrix * vec3(normalMap * 2.0 - 1.0));
3132
vec2 res = vec2(min(uResolution.x, uResolution.y)) * uCamera.w;
3233

3334
for (int index = 0; index < kMaxLights; ++index)

0 commit comments

Comments
 (0)