[Flash target works, HTML5 - not] Porting extensions. Issue with shaders
Hi. Recently I've started porting Starling Flash extensions to Starling OpenFL. Some of them are complete and work as expected: GodRayPlane, PixelMaskDisplayObject and TextureMaskStyle.
But with LightStyle I have low level issue. I guess something is wrong when AGAL shaders are being converted to GLSL. I get following error in browser console:
"Error: [openfl.display3D.Program3D] ERROR: Unable to initialize the shader program
Types of varying 'v5' differ between VERTEX and FRAGMENT shaders.
at Function.lime_utils_Log.error (http://127.0.0.1:3000/Main.js:30570:10)
at openfl_display3D_Program3D.__uploadFromGLSL (http://127.0.0.1:3000/Main.js:65294:19)
at openfl_display3D_Program3D.upload (http://127.0.0.1:3000/Main.js:64919:8)
at starling_rendering_Program.activate (http://127.0.0.1:3000/Main.js:86919:20)
at starling_extensions_lighting_LightEffect.beforeDraw (http://127.0.0.1:3000/Main.js:80387:22)
at starling_extensions_lighting_LightEffect.beforeDraw (http://127.0.0.1:3000/Main.js:80504:50)
at starling_extensions_lighting_LightEffect.beforeDraw (http://127.0.0.1:3000/Main.js:80575:56)
at starling_extensions_lighting_LightEffect.beforeDraw (http://127.0.0.1:3000/Main.js:83945:54)
at starling_extensions_lighting_LightEffect.render (http://127.0.0.1:3000/Main.js:80382:8)
at starling_display_MeshBatch.render (http://127.0.0.1:3000/Main.js:81889:18)"
These are AGAL vertex and fragment shaders that cause error:
mov vt0, va4
mul vt0.w, vt0.w, vc5.w
m44 op, va0, vc0
mov v0, va0
mov v1, va1
mul v2, va2, vc4
mov v3, va3
mov v4, vt0
crs vt1.xyz, va5.xyz, va6.xyz
mul vt1.xyz, vt1.xyz, va7.xxx
mov v5.xw, va5.xw
mov v6.xw, va5.yw
mov v7.xw, va5.zw
mov v5.y, va6.x
mov v6.y, va6.y
mov v7.y, va6.z
mov v5.z, vt1.x
mov v6.z, vt1.y
mov v7.z, vt1.z
tex ft0, v1, fs0 <2d, rgba>
mul ft0, ft0, v2
tex ft1, v3, fs1 <2d, rgba>
mul ft1.xy, ft1.xy, fc0.zz
sub ft1.xy, ft1.xy, fc0.yy
neg ft1.z, ft1.z
neg ft1.y, ft1.y
m33 ft1.xyz, ft1.xyz, v5
nrm ft1.xyz, ft1.xyz
mul ft2, ft0, fc11
mul ft2, ft2, v4.xxxx
mov ft6, ft2
sub ft2, fc12, v0
mul ft2.xyz, ft2.xyz, fc0.www
nrm ft2.xyz, ft2.xyz
dp3 ft3, ft2, ft1
sat ft3, ft3
mul ft4, ft3, fc0.z
mul ft4, ft4, ft1
sub ft4, ft4, ft2
sub ft5, fc3, v0
mul ft5.xyz, ft5.xyz, fc0.www
nrm ft5.xyz, ft5.xyz
dp3 ft2, ft4, ft5
sat ft2, ft2
mul ft3, ft3, fc13
mul ft3, ft3, v4.yyyy
pow ft4, ft2, v4.wwww
mul ft4, ft4, fc13
mul ft4, ft4, v4.zzzz
mul ft4, ft4, ft0.wwww
mul ft2, ft0, ft3
add ft2, ft2, ft4
add ft6, ft6, ft2
sub ft2, fc14, v0
mul ft2.xyz, ft2.xyz, fc0.www
nrm ft2.xyz, ft2.xyz
dp3 ft3, ft2, ft1
sat ft3, ft3
mul ft4, ft3, fc0.z
mul ft4, ft4, ft1
sub ft4, ft4, ft2
sub ft5, fc3, v0
mul ft5.xyz, ft5.xyz, fc0.www
nrm ft5.xyz, ft5.xyz
dp3 ft2, ft4, ft5
sat ft2, ft2
mul ft3, ft3, fc15
mul ft3, ft3, v4.yyyy
pow ft4, ft2, v4.wwww
mul ft4, ft4, fc15
mul ft4, ft4, v4.zzzz
mul ft4, ft4, ft0.wwww
mul ft2, ft0, ft3
add ft2, ft2, ft4
add ft6, ft6, ft2
mov ft6.w, ft0.w
mov oc, ft6
Shaders after converted to GLSL:
"// AGAL vertex shader
#version 100
precision highp float;
attribute vec4 va0;
attribute vec4 va1;
attribute vec4 va2;
attribute vec4 va3;
attribute vec4 va4;
attribute vec4 va5;
attribute vec4 va6;
attribute vec4 va7;
uniform mat4 vc0;
uniform vec4 vc4;
uniform vec4 vc5;
varying vec4 v0;
varying vec4 v1;
varying vec4 v2;
varying vec4 v3;
varying vec4 v4;
varying vec4 v5;
varying vec4 v6;
varying vec4 v7;
uniform vec4 vcPositionScale;
void main() {
vec4 vt0;
vec4 vt1;
vt0 = va4; // mov
vt0.w = vt0.w * vc5.w; // mul
gl_Position = va0 * vc0; // m44
v0 = va0; // mov
v1 = va1; // mov
v2 = va2 * vc4; // mul
v3 = va3; // mov
v4 = vt0; // mov
vt1.xyz = cross(vec3(va5.xyz), vec3(va6.xyz)); // crs
vt1.xyz = vt1.xyz * va7.xxx; // mul
v5.xw = va5.xw; // mov
v6.xw = va5.yw; // mov
v7.xw = va5.zw; // mov
v5.y = va6.x; // mov
v6.y = va6.y; // mov
v7.y = va6.z; // mov
v5.z = vt1.x; // mov
v6.z = vt1.y; // mov
v7.z = vt1.z; // mov
gl_Position *= vcPositionScale;
}
"
"// AGAL fragment shader
#version 100
precision highp float;
uniform vec4 fc0;
uniform vec4 fc3;
uniform vec4 fc11;
uniform vec4 fc12;
uniform vec4 fc13;
uniform vec4 fc14;
uniform vec4 fc15;
varying vec4 v0;
varying vec4 v1;
varying vec4 v2;
varying vec4 v3;
varying vec4 v4;
varying mat4 v5;
uniform sampler2D sampler0;
uniform sampler2D sampler1;
void main() {
vec4 ft0;
vec4 ft1;
vec4 ft2;
vec4 ft3;
vec4 ft4;
vec4 ft5;
vec4 ft6;
ft0 = texture2D(sampler0, v1.xy); // tex
ft0 = ft0 * v2; // mul
ft1 = texture2D(sampler1, v3.xy); // tex
ft1.xy = ft1.xy * fc0.zz; // mul
ft1.xy = ft1.xy - fc0.yy; // sub
ft1.z = -ft1.z; // neg
ft1.y = -ft1.y; // neg
ft1.xyz = ft1.xyz * mat3(v5); // m33
ft1.xyz = normalize(ft1.xyz); // normalize
ft2 = ft0 * fc11; // mul
ft2 = ft2 * v4.xxxx; // mul
ft6 = ft2; // mov
ft2 = fc12 - v0; // sub
ft2.xyz = ft2.xyz * fc0.www; // mul
ft2.xyz = normalize(ft2.xyz); // normalize
ft3 = vec4(dot(vec3(ft2.xyz), vec3(ft1.xyz))).xyzw; // dp3
ft3 = clamp(ft3, 0.0, 1.0); // saturate
ft4 = ft3 * fc0.zzzz; // mul
ft4 = ft4 * ft1; // mul
ft4 = ft4 - ft2; // sub
ft5 = fc3 - v0; // sub
ft5.xyz = ft5.xyz * fc0.www; // mul
ft5.xyz = normalize(ft5.xyz); // normalize
ft2 = vec4(dot(vec3(ft4.xyz), vec3(ft5.xyz))).xyzw; // dp3
ft2 = clamp(ft2, 0.0, 1.0); // saturate
ft3 = ft3 * fc13; // mul
ft3 = ft3 * v4.yyyy; // mul
ft4 = pow(ft2, v4.wwww); // pow
ft4 = ft4 * fc13; // mul
ft4 = ft4 * v4.zzzz; // mul
ft4 = ft4 * ft0.wwww; // mul
ft2 = ft0 * ft3; // mul
ft2 = ft2 + ft4; // add
ft6 = ft6 + ft2; // add
ft2 = fc14 - v0; // sub
ft2.xyz = ft2.xyz * fc0.www; // mul
ft2.xyz = normalize(ft2.xyz); // normalize
ft3 = vec4(dot(vec3(ft2.xyz), vec3(ft1.xyz))).xyzw; // dp3
ft3 = clamp(ft3, 0.0, 1.0); // saturate
ft4 = ft3 * fc0.zzzz; // mul
ft4 = ft4 * ft1; // mul
ft4 = ft4 - ft2; // sub
ft5 = fc3 - v0; // sub
ft5.xyz = ft5.xyz * fc0.www; // mul
ft5.xyz = normalize(ft5.xyz); // normalize
ft2 = vec4(dot(vec3(ft4.xyz), vec3(ft5.xyz))).xyzw; // dp3
ft2 = clamp(ft2, 0.0, 1.0); // saturate
ft3 = ft3 * fc15; // mul
ft3 = ft3 * v4.yyyy; // mul
ft4 = pow(ft2, v4.wwww); // pow
ft4 = ft4 * fc15; // mul
ft4 = ft4 * v4.zzzz; // mul
ft4 = ft4 * ft0.wwww; // mul
ft2 = ft0 * ft3; // mul
ft2 = ft2 + ft4; // add
ft6 = ft6 + ft2; // add
ft6.w = ft0.w; // mov
gl_FragColor = ft6; // mov
}
"
Link to sample:
https://github.com/CrazyFlasher/starling-extensions-hx/tree/master/samples/dynamicLight
Just run haxelib run openfl test html5 -debug
Thanks and please help :)
BTW, works fine with Flash target.
Commenting out those lines in AGAL fragment shader resolved the issue:
"m33 ft1.xyz, ft1.xyz, v5" // move N into local coords
"nrm ft1.xyz, ft1.xyz" // normalize N
Visually result works as expected, though I have no idea what these lines used to do :)