@carbonenginejs/runtime-resource 0.19.2 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -133,8 +133,33 @@ class DxbcGlslEmitter {
|
|
|
133
133
|
// into one array binding frees two texture units on shaders that
|
|
134
134
|
// sit exactly on WebGL2's 16-unit limit.
|
|
135
135
|
detailMapArrayRegisters: [],
|
|
136
|
+
// Which end of the source clip range is NEAR, and therefore which
|
|
137
|
+
// form the depth-range fixup takes.
|
|
138
|
+
//
|
|
139
|
+
// "reversed" (default) z_clip [w, 0] -> gl_Position.z = w - 2z
|
|
140
|
+
// "forward" z_clip [0, w] -> gl_Position.z = 2z - w
|
|
141
|
+
//
|
|
142
|
+
// The default is "reversed" because that is what the shaders this
|
|
143
|
+
// emitter translates were compiled against, and it is a property of
|
|
144
|
+
// the INPUT, not a preference of any one consumer. It is stated as
|
|
145
|
+
// an option rather than hard-coded for two reasons: the assumption
|
|
146
|
+
// is otherwise invisible in the output, and a future source may not
|
|
147
|
+
// share it. Deciding it here also means a consumer supplies a
|
|
148
|
+
// matching projection or gets inverted depth, which is a real
|
|
149
|
+
// coupling and better declared than implied.
|
|
150
|
+
//
|
|
151
|
+
// Switch to "forward" to A/B the convention against a forward-range
|
|
152
|
+
// projection. Expect an unbiased vertex to look identical either
|
|
153
|
+
// way - the fixup and the projection compose to the identity - and
|
|
154
|
+
// only shader-authored depth offsets to change sign. That is the
|
|
155
|
+
// whole observable difference, and it is what makes the wrong
|
|
156
|
+
// choice so hard to see.
|
|
157
|
+
depthRange: "reversed",
|
|
136
158
|
...options.profile
|
|
137
159
|
};
|
|
160
|
+
if (this.profile.depthRange !== "reversed" && this.profile.depthRange !== "forward") {
|
|
161
|
+
throw new TypeError(`DxbcGlslEmitter: depthRange must be "reversed" or "forward", got ${JSON.stringify(this.profile.depthRange)}`);
|
|
162
|
+
}
|
|
138
163
|
}
|
|
139
164
|
|
|
140
165
|
/**
|
|
@@ -3129,6 +3154,18 @@ DxbcGlslEmitter.prototype._gather4Channel = function _gather4Channel(operand) {
|
|
|
3129
3154
|
/**
|
|
3130
3155
|
* Assembles the final GLSL text.
|
|
3131
3156
|
*/
|
|
3157
|
+
/**
|
|
3158
|
+
* The depth-range fixup emitted at the end of a vertex stage, by source range.
|
|
3159
|
+
*
|
|
3160
|
+
* Both entries map their range onto GL NDC [-1, 1] and both compose to the
|
|
3161
|
+
* identity with a projection of the matching form, so an unbiased vertex is
|
|
3162
|
+
* unchanged either way. See `profile.depthRange`.
|
|
3163
|
+
* @type {Object.<string,string>}
|
|
3164
|
+
*/
|
|
3165
|
+
const DEPTH_RANGE_FIXUP = Object.freeze({
|
|
3166
|
+
reversed: "gl_Position.z = gl_Position.w - 2.0 * gl_Position.z;",
|
|
3167
|
+
forward: "gl_Position.z = 2.0 * gl_Position.z - gl_Position.w;"
|
|
3168
|
+
});
|
|
3132
3169
|
DxbcGlslEmitter.prototype._assemble = function _assemble(state) {
|
|
3133
3170
|
const lines = ["#version 300 es"];
|
|
3134
3171
|
if (state.isPixel || state.isCompute) {
|
|
@@ -3139,16 +3176,27 @@ DxbcGlslEmitter.prototype._assemble = function _assemble(state) {
|
|
|
3139
3176
|
if (helperSource) {
|
|
3140
3177
|
lines.push("", helperSource);
|
|
3141
3178
|
}
|
|
3142
|
-
// Vertex stages get the
|
|
3143
|
-
//
|
|
3144
|
-
//
|
|
3145
|
-
//
|
|
3146
|
-
//
|
|
3147
|
-
//
|
|
3148
|
-
//
|
|
3149
|
-
//
|
|
3150
|
-
//
|
|
3151
|
-
//
|
|
3179
|
+
// Vertex stages get the depth-range fixup that turns a compiled shader's
|
|
3180
|
+
// clip z into GL's. These shaders are compiled against a REVERSED depth
|
|
3181
|
+
// range: z_clip runs [w, 0], near at w and far at 0, and `w - 2z` maps that
|
|
3182
|
+
// onto GL NDC [-1, 1].
|
|
3183
|
+
//
|
|
3184
|
+
// The reversal is observable in the shipped bodies themselves. Surface
|
|
3185
|
+
// decals add a small positive constant to clip z to lift themselves off the
|
|
3186
|
+
// hull they sit on, and a lift is only toward the camera on a reversed
|
|
3187
|
+
// axis.
|
|
3188
|
+
//
|
|
3189
|
+
// The caller MUST supply a reversed-D3D projection. Composed with one, this
|
|
3190
|
+
// is exactly the identity for an unbiased vertex, so the depth buffer keeps
|
|
3191
|
+
// conventional GL values and legacy shaders sharing it are unaffected. What
|
|
3192
|
+
// changes is the direction of any offset the shader authors ITSELF: the
|
|
3193
|
+
// decal family adds `+1e-5` to lift itself off the hull, which is toward
|
|
3194
|
+
// the camera only on a reversed axis. Hand it a forward-D3D projection and
|
|
3195
|
+
// every such offset inverts - decals sink INTO the hull by `2e-5/w`, an
|
|
3196
|
+
// error that grows as the camera closes in.
|
|
3197
|
+
//
|
|
3198
|
+
// The body is wrapped in a helper so early `ret` (return) statements cannot
|
|
3199
|
+
// skip the fixup.
|
|
3152
3200
|
const writesPosition = [...state.outputNames.values()].includes("gl_Position");
|
|
3153
3201
|
if (!state.isPixel && !state.isCompute && writesPosition) {
|
|
3154
3202
|
lines.push("", "void dxbc_main() {");
|
|
@@ -3156,7 +3204,7 @@ DxbcGlslEmitter.prototype._assemble = function _assemble(state) {
|
|
|
3156
3204
|
lines.push(` ${early}`);
|
|
3157
3205
|
}
|
|
3158
3206
|
lines.push(...state.bodyLines, "}");
|
|
3159
|
-
lines.push("", "void main() {", " dxbc_main();",
|
|
3207
|
+
lines.push("", "void main() {", " dxbc_main();", ` ${DEPTH_RANGE_FIXUP[this.profile.depthRange]}`, "}");
|
|
3160
3208
|
return `${lines.join("\n")}\n`;
|
|
3161
3209
|
}
|
|
3162
3210
|
lines.push("", "void main() {");
|