xref: /aosp_15_r20/external/angle/doc/CompilingTranslatorWithEmscripten.md (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker# Introduction
2*8975f5c5SAndroid Build Coastguard Worker
3*8975f5c5SAndroid Build Coastguard WorkerThere are many situations in which it's useful for WebGL applications to
4*8975f5c5SAndroid Build Coastguard Workertransform shaders in various ways. ANGLE's shader translator can be used for
5*8975f5c5SAndroid Build Coastguard Workerthis purpose: compiling it with [Emscripten](http://emscripten.org/) allows it
6*8975f5c5SAndroid Build Coastguard Workerto be invoked from a web page. This wiki page provides some preliminary details
7*8975f5c5SAndroid Build Coastguard Workerabout how to do this.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker# Details
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard WorkerPull top of tree ANGLE.
12*8975f5c5SAndroid Build Coastguard Worker
13*8975f5c5SAndroid Build Coastguard WorkerInstall the Emscripten toolchain per the [instructions](http://emscripten.org/).
14*8975f5c5SAndroid Build Coastguard Worker
15*8975f5c5SAndroid Build Coastguard WorkerSymlink (preferred) or copy the ANGLE directory into ...emsdk/emscripten/master.
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard WorkerPut a shader to compile into a file (named with .vert or .frag suffix) in the
18*8975f5c5SAndroid Build Coastguard Workersame directory. For example, put the following shader from the [WebGL Aquarium]
19*8975f5c5SAndroid Build Coastguard Worker(http://webglsamples.org/aquarium/aquarium.html) into `aq-fish-nm.frag`:
20*8975f5c5SAndroid Build Coastguard Worker
21*8975f5c5SAndroid Build Coastguard Worker```
22*8975f5c5SAndroid Build Coastguard Workerprecision mediump float;
23*8975f5c5SAndroid Build Coastguard Workeruniform vec4 lightColor;
24*8975f5c5SAndroid Build Coastguard Workervarying vec4 v_position;
25*8975f5c5SAndroid Build Coastguard Workervarying vec2 v_texCoord;
26*8975f5c5SAndroid Build Coastguard Workervarying vec3 v_tangent;  // #normalMap
27*8975f5c5SAndroid Build Coastguard Workervarying vec3 v_binormal;  // #normalMap
28*8975f5c5SAndroid Build Coastguard Workervarying vec3 v_normal;
29*8975f5c5SAndroid Build Coastguard Workervarying vec3 v_surfaceToLight;
30*8975f5c5SAndroid Build Coastguard Workervarying vec3 v_surfaceToView;
31*8975f5c5SAndroid Build Coastguard Worker
32*8975f5c5SAndroid Build Coastguard Workeruniform vec4 ambient;
33*8975f5c5SAndroid Build Coastguard Workeruniform sampler2D diffuse;
34*8975f5c5SAndroid Build Coastguard Workeruniform vec4 specular;
35*8975f5c5SAndroid Build Coastguard Workeruniform sampler2D normalMap;  // #normalMap
36*8975f5c5SAndroid Build Coastguard Workeruniform float shininess;
37*8975f5c5SAndroid Build Coastguard Workeruniform float specularFactor;
38*8975f5c5SAndroid Build Coastguard Worker// #fogUniforms
39*8975f5c5SAndroid Build Coastguard Worker
40*8975f5c5SAndroid Build Coastguard Workervec4 lit(float l ,float h, float m) {
41*8975f5c5SAndroid Build Coastguard Worker  return vec4(1.0,
42*8975f5c5SAndroid Build Coastguard Worker              max(l, 0.0),
43*8975f5c5SAndroid Build Coastguard Worker              (l > 0.0) ? pow(max(0.0, h), m) : 0.0,
44*8975f5c5SAndroid Build Coastguard Worker              1.0);
45*8975f5c5SAndroid Build Coastguard Worker}
46*8975f5c5SAndroid Build Coastguard Workervoid main() {
47*8975f5c5SAndroid Build Coastguard Worker  vec4 diffuseColor = texture2D(diffuse, v_texCoord);
48*8975f5c5SAndroid Build Coastguard Worker  mat3 tangentToWorld = mat3(v_tangent,  // #normalMap
49*8975f5c5SAndroid Build Coastguard Worker                             v_binormal,  // #normalMap
50*8975f5c5SAndroid Build Coastguard Worker                             v_normal);  // #normalMap
51*8975f5c5SAndroid Build Coastguard Worker  vec4 normalSpec = texture2D(normalMap, v_texCoord.xy);  // #normalMap
52*8975f5c5SAndroid Build Coastguard Worker  vec3 tangentNormal = normalSpec.xyz - vec3(0.5, 0.5, 0.5);  // #normalMap
53*8975f5c5SAndroid Build Coastguard Worker  tangentNormal = normalize(tangentNormal + vec3(0, 0, 2));  // #normalMap
54*8975f5c5SAndroid Build Coastguard Worker  vec3 normal = (tangentToWorld * tangentNormal);  // #normalMap
55*8975f5c5SAndroid Build Coastguard Worker  normal = normalize(normal);  // #normalMap
56*8975f5c5SAndroid Build Coastguard Worker  vec3 surfaceToLight = normalize(v_surfaceToLight);
57*8975f5c5SAndroid Build Coastguard Worker  vec3 surfaceToView = normalize(v_surfaceToView);
58*8975f5c5SAndroid Build Coastguard Worker  vec3 halfVector = normalize(surfaceToLight + surfaceToView);
59*8975f5c5SAndroid Build Coastguard Worker  vec4 litR = lit(dot(normal, surfaceToLight),
60*8975f5c5SAndroid Build Coastguard Worker                    dot(normal, halfVector), shininess);
61*8975f5c5SAndroid Build Coastguard Worker  vec4 outColor = vec4(
62*8975f5c5SAndroid Build Coastguard Worker    (lightColor * (diffuseColor * litR.y + diffuseColor * ambient +
63*8975f5c5SAndroid Build Coastguard Worker                  specular * litR.z * specularFactor * normalSpec.a)).rgb,
64*8975f5c5SAndroid Build Coastguard Worker      diffuseColor.a);
65*8975f5c5SAndroid Build Coastguard Worker  // #fogCode
66*8975f5c5SAndroid Build Coastguard Worker  gl_FragColor = outColor;
67*8975f5c5SAndroid Build Coastguard Worker}
68*8975f5c5SAndroid Build Coastguard Worker```
69*8975f5c5SAndroid Build Coastguard Worker
70*8975f5c5SAndroid Build Coastguard WorkerCompile the shader translator, the translator sample, and the shader all
71*8975f5c5SAndroid Build Coastguard Workertogether:
72*8975f5c5SAndroid Build Coastguard Worker
73*8975f5c5SAndroid Build Coastguard Worker```
74*8975f5c5SAndroid Build Coastguard Worker./emcc -Iangle/include -Iangle/src angle/samples/translator/translator.cpp angle/src/compiler/preprocessor/*.cpp angle/src/compiler/translator/*.cpp angle/src/compiler/translator/timing/*.cpp angle/src/compiler/translator/depgraph/*.cpp angle/src/third_party/compiler/*.cpp angle/src/common/*.cpp -o translator.html --preload-file aq-fish-nm.frag -s NO_EXIT_RUNTIME=1
75*8975f5c5SAndroid Build Coastguard Worker```
76*8975f5c5SAndroid Build Coastguard Worker
77*8975f5c5SAndroid Build Coastguard WorkerServe up the resulting translator.html via `python -m SimpleHTTPServer`.
78*8975f5c5SAndroid Build Coastguard WorkerNavigate the browser to localhost:8000.
79*8975f5c5SAndroid Build Coastguard Worker
80*8975f5c5SAndroid Build Coastguard WorkerThe translator sample will run, displaying its output into the text area on the
81*8975f5c5SAndroid Build Coastguard Workerpage. Since it isn't receiving any input, it simply outputs a help message and
82*8975f5c5SAndroid Build Coastguard Workerexits.
83*8975f5c5SAndroid Build Coastguard Worker
84*8975f5c5SAndroid Build Coastguard WorkerTo invoke the translator again, processing the shader we included along with the
85*8975f5c5SAndroid Build Coastguard Workersource code, open the JavaScript console and type:
86*8975f5c5SAndroid Build Coastguard Worker
87*8975f5c5SAndroid Build Coastguard Worker```
88*8975f5c5SAndroid Build Coastguard WorkerModule['callMain'](['-s=w', '-u', 'aq-fish-nm.frag'])
89*8975f5c5SAndroid Build Coastguard Worker```
90*8975f5c5SAndroid Build Coastguard Worker
91*8975f5c5SAndroid Build Coastguard WorkerThe active uniforms and their types will be printed to the text area after the
92*8975f5c5SAndroid Build Coastguard Workertranslator sample processes the shader.
93*8975f5c5SAndroid Build Coastguard Worker
94*8975f5c5SAndroid Build Coastguard Worker# Issues and Next Steps
95*8975f5c5SAndroid Build Coastguard Worker
96*8975f5c5SAndroid Build Coastguard WorkerIt's clearly not useful to have to compile the shader in to the
97*8975f5c5SAndroid Build Coastguard WorkerEmscripten-translated executable. It would be helpful to define a simple wrapper
98*8975f5c5SAndroid Build Coastguard Workerfunction which can easily be called from JavaScript and which defines enough
99*8975f5c5SAndroid Build Coastguard Workerparameters to pass in a shader as a string, transform it somehow or compile it
100*8975f5c5SAndroid Build Coastguard Workerto another language target, and return the compiled result (or other
101*8975f5c5SAndroid Build Coastguard Workerinformation). A simple JavaScript library that wraps all of the interactions
102*8975f5c5SAndroid Build Coastguard Workerwith the Emscripten binary would be useful.
103*8975f5c5SAndroid Build Coastguard Worker
104*8975f5c5SAndroid Build Coastguard WorkerIt's not feasible to interact with the translator's data structures, nor
105*8975f5c5SAndroid Build Coastguard Workertraverse the AST from JavaScript. The code that operates upon the shader must be
106*8975f5c5SAndroid Build Coastguard Workerwritten in C++ and compiled in to the shader translator.
107*8975f5c5SAndroid Build Coastguard Worker
108*8975f5c5SAndroid Build Coastguard Workeremcc should be integrated better with ANGLE's build system.
109