openfl / starling

Known as the "Cross-Platform Game Engine", Starling is a popular Stage3D framework for OpenFL and Haxe
Other
237 stars 68 forks source link

[Flash target works, HTML5 - not] Porting extensions. Issue with shaders #146

Closed CrazyFlasher closed 4 months ago

CrazyFlasher commented 4 years ago

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 :)

CrazyFlasher commented 4 years ago

BTW, works fine with Flash target.

CrazyFlasher commented 4 years ago

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 :)