mirror of
https://github.com/galacean/engine.git
synced 2026-06-06 21:52:36 +08:00
fix(shader-lab): resolve generic return type for texture/builtin functions (#2966)
* fix(shader-lab): resolve GVec4 generic return type for texture() builtin functions
This commit is contained in:
@@ -756,7 +756,7 @@ export namespace ASTNode {
|
||||
}
|
||||
}
|
||||
// #if _VERBOSE
|
||||
const builtinFn = BuiltinFunction.getFn(fnIdent, paramSig);
|
||||
const builtinFn = BuiltinFunction.resolveOverload(fnIdent, paramSig);
|
||||
if (builtinFn) {
|
||||
this.type = builtinFn.realReturnType;
|
||||
return;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { GalaceanDataType, TypeAny } from "../../common";
|
||||
import { Keyword } from "../../common/enums/Keyword";
|
||||
import { EShaderStage } from "../../common/enums/ShaderStage";
|
||||
|
||||
export enum EGenType {
|
||||
export enum GenericType {
|
||||
GenType = 200,
|
||||
GenIntType,
|
||||
GenUintType,
|
||||
@@ -20,12 +20,84 @@ export enum EGenType {
|
||||
}
|
||||
|
||||
export type NonGenericGalaceanType = Exclude<GalaceanDataType, string>;
|
||||
type BuiltinType = NonGenericGalaceanType | EGenType;
|
||||
type BuiltinType = NonGenericGalaceanType | GenericType;
|
||||
|
||||
function isGenericType(t: BuiltinType) {
|
||||
return t >= EGenType.GenType && t <= EGenType.GSampler2DArray;
|
||||
// Generic type system
|
||||
//
|
||||
// A generic family declares its concrete members and the dimension along which
|
||||
// members vary. Matching a generic position locks an index; projecting a return
|
||||
// family uses that index. Two families can only share an index if they vary
|
||||
// along the same dimension
|
||||
//
|
||||
// Example: `texture(GSampler2D, vec2) → GVec4` against `texture(sampler2D, uv)`
|
||||
// 1. Locate `sampler2D` in GSampler2D (ScalarType dimension) → index 0
|
||||
// 2. Project GVec4 (ScalarType dimension) at index 0 → vec4
|
||||
//
|
||||
// `ivec4 = texture(isampler2D, uv)` locks index 1, projects to `ivec4`
|
||||
// `min(vec3, vec3)` locks index 2 in GenType (Size dimension) and returns vec3
|
||||
// `min(vec3, vec2)` fails because the second arg would need index 1 but 2 is locked
|
||||
|
||||
const enum GenericDimension {
|
||||
// Varies along vector size: scalar / vec2 / vec3 / vec4 (or equivalents)
|
||||
Size,
|
||||
// Varies along the underlying scalar type: float / int / uint (sometimes with bool)
|
||||
ScalarType
|
||||
}
|
||||
|
||||
type FamilySpec = {
|
||||
readonly dimension: GenericDimension;
|
||||
readonly members: readonly NonGenericGalaceanType[];
|
||||
};
|
||||
|
||||
const FamilyMembers: Partial<Record<BuiltinType, FamilySpec>> = {
|
||||
// Size-varying families: index 0 → scalar, 1 → vec2, 2 → vec3, 3 → vec4
|
||||
// Per GLSL Spec §5.1, these appear in both parameter and return positions
|
||||
[GenericType.GenType]: {
|
||||
dimension: GenericDimension.Size,
|
||||
members: [Keyword.FLOAT, Keyword.VEC2, Keyword.VEC3, Keyword.VEC4]
|
||||
},
|
||||
[GenericType.GenIntType]: {
|
||||
dimension: GenericDimension.Size,
|
||||
members: [Keyword.INT, Keyword.IVEC2, Keyword.IVEC3, Keyword.IVEC4]
|
||||
},
|
||||
[GenericType.GenUintType]: {
|
||||
dimension: GenericDimension.Size,
|
||||
members: [Keyword.UINT, Keyword.UVEC2, Keyword.UVEC3, Keyword.UVEC4]
|
||||
},
|
||||
[GenericType.GenBoolType]: {
|
||||
dimension: GenericDimension.Size,
|
||||
members: [Keyword.BOOL, Keyword.BVEC2, Keyword.BVEC3, Keyword.BVEC4]
|
||||
},
|
||||
// Vec-only sub-families (no scalar): index 0 → vec2, 1 → vec3, 2 → vec4
|
||||
[GenericType.Vec]: { dimension: GenericDimension.Size, members: [Keyword.VEC2, Keyword.VEC3, Keyword.VEC4] },
|
||||
[GenericType.IntVec]: { dimension: GenericDimension.Size, members: [Keyword.IVEC2, Keyword.IVEC3, Keyword.IVEC4] },
|
||||
[GenericType.UintVec]: { dimension: GenericDimension.Size, members: [Keyword.UVEC2, Keyword.UVEC3, Keyword.UVEC4] },
|
||||
[GenericType.BoolVec]: { dimension: GenericDimension.Size, members: [Keyword.BVEC2, Keyword.BVEC3, Keyword.BVEC4] },
|
||||
[GenericType.Mat]: { dimension: GenericDimension.Size, members: [Keyword.MAT2, Keyword.MAT3, Keyword.MAT4] },
|
||||
|
||||
// ScalarType-varying families: index 0 → float base, 1 → int base, 2 → uint base
|
||||
// Per GLSL Spec §5.1:
|
||||
// GSampler* families are parameter-only (passed as texture samplers)
|
||||
// GVec4 is return-only (projected from a GSampler* parameter into the matching vec4 variant)
|
||||
[GenericType.GSampler2D]: {
|
||||
dimension: GenericDimension.ScalarType,
|
||||
members: [Keyword.SAMPLER2D, Keyword.I_SAMPLER2D, Keyword.U_SAMPLER2D]
|
||||
},
|
||||
[GenericType.GSampler3D]: {
|
||||
dimension: GenericDimension.ScalarType,
|
||||
members: [Keyword.SAMPLER3D, Keyword.I_SAMPLER3D, Keyword.U_SAMPLER3D]
|
||||
},
|
||||
[GenericType.GSamplerCube]: {
|
||||
dimension: GenericDimension.ScalarType,
|
||||
members: [Keyword.SAMPLER_CUBE, Keyword.I_SAMPLER_CUBE, Keyword.U_SAMPLER_CUBE]
|
||||
},
|
||||
[GenericType.GSampler2DArray]: {
|
||||
dimension: GenericDimension.ScalarType,
|
||||
members: [Keyword.SAMPLER2D_ARRAY, Keyword.I_SAMPLER2D_ARRAY, Keyword.U_SAMPLER2D_ARRAY]
|
||||
},
|
||||
[GenericType.GVec4]: { dimension: GenericDimension.ScalarType, members: [Keyword.VEC4, Keyword.IVEC4, Keyword.UVEC4] }
|
||||
};
|
||||
|
||||
const BuiltinFunctionTable: Map<string, BuiltinFunction[]> = new Map();
|
||||
|
||||
export class BuiltinFunction {
|
||||
@@ -47,11 +119,6 @@ export class BuiltinFunction {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
static getReturnType(fn: BuiltinFunction, genType?: NonGenericGalaceanType) {
|
||||
if (!isGenericType(fn._returnType)) return fn._returnType as NonGenericGalaceanType;
|
||||
return genType;
|
||||
}
|
||||
|
||||
static _create(ident: string, returnType: BuiltinType, ...args: BuiltinType[]) {
|
||||
const fn = new BuiltinFunction(ident, returnType, EShaderStage.ALL, ...args);
|
||||
const list = BuiltinFunctionTable.get(ident) ?? [];
|
||||
@@ -59,122 +126,175 @@ export class BuiltinFunction {
|
||||
BuiltinFunctionTable.set(ident, list);
|
||||
}
|
||||
|
||||
static _createWithScop(ident: string, returnType: BuiltinType, scope: EShaderStage, ...args: BuiltinType[]) {
|
||||
static _createWithScope(ident: string, returnType: BuiltinType, scope: EShaderStage, ...args: BuiltinType[]) {
|
||||
const fn = new BuiltinFunction(ident, returnType, scope, ...args);
|
||||
const list = BuiltinFunctionTable.get(ident) ?? [];
|
||||
list.push(fn);
|
||||
BuiltinFunctionTable.set(ident, list);
|
||||
}
|
||||
|
||||
// TODO: correct the type deduce, consider the following case:
|
||||
// It incorrectly inferred the type of the following expression as float, which should be vec3.
|
||||
// max(scatterAmt.xyz,0.0001)
|
||||
static getFn(ident: string, parameterTypes: NonGenericGalaceanType[]): BuiltinFunction | undefined {
|
||||
const list = BuiltinFunctionTable.get(ident);
|
||||
if (list) {
|
||||
for (let length = list.length, i = 0; i < length; i++) {
|
||||
const fn = list[i];
|
||||
const fnArgs = fn.args;
|
||||
const argLength = fnArgs.length;
|
||||
if (argLength !== parameterTypes.length) continue;
|
||||
// Try to match generic parameter type.
|
||||
let returnType = TypeAny;
|
||||
let found = true;
|
||||
for (let i = 0; i < argLength; i++) {
|
||||
const curFnArg = fnArgs[i];
|
||||
if (isGenericType(curFnArg)) {
|
||||
if (returnType === TypeAny) returnType = parameterTypes[i];
|
||||
// Overload resolution against the generic family system
|
||||
//
|
||||
// For each candidate signature: concrete positions require exact type match;
|
||||
// generic positions locate the actual arg's index within the declared family,
|
||||
// and lock an index per dimension (size / scalar-type) shared across positions.
|
||||
// The return type is resolved by projecting the appropriate lock through the
|
||||
// return family, or passed through verbatim if the return is concrete
|
||||
static resolveOverload(
|
||||
funcName: string,
|
||||
callArgTypes: NonGenericGalaceanType[] | undefined
|
||||
): BuiltinFunction | undefined {
|
||||
const overloads = BuiltinFunctionTable.get(funcName);
|
||||
if (!overloads) return undefined;
|
||||
const n = callArgTypes?.length ?? 0;
|
||||
|
||||
for (let i = 0, m = overloads.length; i < m; i++) {
|
||||
const candidate = overloads[i];
|
||||
const declaredArgs = candidate.args;
|
||||
if (declaredArgs.length !== n) continue;
|
||||
|
||||
let sizeLock = -1;
|
||||
let scalarTypeLock = -1;
|
||||
let matched = true;
|
||||
|
||||
for (let j = 0; j < n; j++) {
|
||||
const declaredType = declaredArgs[j];
|
||||
const actualType = callArgTypes![j];
|
||||
if (actualType === TypeAny) continue;
|
||||
|
||||
const paramFamily = FamilyMembers[declaredType];
|
||||
if (paramFamily) {
|
||||
// Families have at most 4 members; linear indexOf beats Map.get on this size
|
||||
const memberIdx = paramFamily.members.indexOf(actualType);
|
||||
if (memberIdx === -1) {
|
||||
matched = false;
|
||||
break;
|
||||
}
|
||||
if (paramFamily.dimension === GenericDimension.Size) {
|
||||
if (sizeLock === -1) sizeLock = memberIdx;
|
||||
else if (sizeLock !== memberIdx) {
|
||||
matched = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (curFnArg !== parameterTypes[i] && parameterTypes[i] !== TypeAny) {
|
||||
found = false;
|
||||
if (scalarTypeLock === -1) scalarTypeLock = memberIdx;
|
||||
else if (scalarTypeLock !== memberIdx) {
|
||||
matched = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
fn._realReturnType = returnType;
|
||||
return fn;
|
||||
} else if (declaredType !== actualType) {
|
||||
matched = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched) continue;
|
||||
|
||||
const returnFamily = FamilyMembers[candidate._returnType];
|
||||
if (!returnFamily) {
|
||||
candidate._realReturnType = candidate._returnType as NonGenericGalaceanType;
|
||||
return candidate;
|
||||
}
|
||||
const returnIdx = returnFamily.dimension === GenericDimension.Size ? sizeLock : scalarTypeLock;
|
||||
// No argument locked the dimension (all relevant args were TypeAny): fall
|
||||
// through as TypeAny so downstream overload resolution treats the result
|
||||
// as a wildcard rather than a specific guess
|
||||
candidate._realReturnType = returnIdx === -1 ? TypeAny : returnFamily.members[returnIdx];
|
||||
return candidate;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
static isExist(ident: string) {
|
||||
return !!BuiltinFunctionTable.get(ident);
|
||||
return BuiltinFunctionTable.has(ident);
|
||||
}
|
||||
}
|
||||
|
||||
BuiltinFunction._create("radians", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("degrees", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("sin", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("cos", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("tan", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("asin", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("acos", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("atan", EGenType.GenType, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("atan", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("sinh", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("cosh", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("tanh", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("asinh", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("acosh", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("atanh", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("radians", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("degrees", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("sin", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("cos", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("tan", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("asin", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("acos", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("atan", GenericType.GenType, GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("atan", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("sinh", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("cosh", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("tanh", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("asinh", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("acosh", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("atanh", GenericType.GenType, GenericType.GenType);
|
||||
|
||||
BuiltinFunction._create("pow", EGenType.GenType, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("exp", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("log", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("exp2", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("log2", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("sqrt", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("inversesqrt", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("pow", GenericType.GenType, GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("exp", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("log", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("exp2", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("log2", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("sqrt", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("inversesqrt", GenericType.GenType, GenericType.GenType);
|
||||
|
||||
BuiltinFunction._create("abs", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("abs", EGenType.GenIntType, EGenType.GenIntType);
|
||||
BuiltinFunction._create("sign", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("sign", EGenType.GenIntType, EGenType.GenIntType);
|
||||
BuiltinFunction._create("floor", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("trunc", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("round", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("roundEven", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("ceil", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("fract", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("mod", EGenType.GenType, EGenType.GenType, Keyword.FLOAT);
|
||||
BuiltinFunction._create("mod", EGenType.GenType, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("min", EGenType.GenType, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("min", EGenType.GenType, EGenType.GenType, Keyword.FLOAT);
|
||||
BuiltinFunction._create("min", EGenType.GenIntType, EGenType.GenIntType, EGenType.GenIntType);
|
||||
BuiltinFunction._create("min", EGenType.GenIntType, EGenType.GenIntType, Keyword.INT);
|
||||
BuiltinFunction._create("min", EGenType.GenUintType, EGenType.GenUintType, EGenType.GenUintType);
|
||||
BuiltinFunction._create("min", EGenType.GenUintType, EGenType.GenUintType, Keyword.UINT);
|
||||
BuiltinFunction._create("max", EGenType.GenType, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("max", EGenType.GenType, EGenType.GenType, Keyword.FLOAT);
|
||||
BuiltinFunction._create("max", EGenType.GenIntType, EGenType.GenIntType, EGenType.GenIntType);
|
||||
BuiltinFunction._create("max", EGenType.GenIntType, EGenType.GenIntType, Keyword.INT);
|
||||
BuiltinFunction._create("clamp", EGenType.GenType, EGenType.GenType, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("clamp", EGenType.GenType, EGenType.GenType, Keyword.FLOAT, Keyword.FLOAT);
|
||||
BuiltinFunction._create("clamp", EGenType.GenIntType, EGenType.GenIntType, EGenType.GenIntType, EGenType.GenIntType);
|
||||
BuiltinFunction._create("clamp", EGenType.GenIntType, EGenType.GenIntType, Keyword.INT, Keyword.INT);
|
||||
BuiltinFunction._create("abs", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("abs", GenericType.GenIntType, GenericType.GenIntType);
|
||||
BuiltinFunction._create("sign", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("sign", GenericType.GenIntType, GenericType.GenIntType);
|
||||
BuiltinFunction._create("floor", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("trunc", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("round", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("roundEven", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("ceil", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("fract", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("mod", GenericType.GenType, GenericType.GenType, Keyword.FLOAT);
|
||||
BuiltinFunction._create("mod", GenericType.GenType, GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("min", GenericType.GenType, GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("min", GenericType.GenType, GenericType.GenType, Keyword.FLOAT);
|
||||
BuiltinFunction._create("min", GenericType.GenIntType, GenericType.GenIntType, GenericType.GenIntType);
|
||||
BuiltinFunction._create("min", GenericType.GenIntType, GenericType.GenIntType, Keyword.INT);
|
||||
BuiltinFunction._create("min", GenericType.GenUintType, GenericType.GenUintType, GenericType.GenUintType);
|
||||
BuiltinFunction._create("min", GenericType.GenUintType, GenericType.GenUintType, Keyword.UINT);
|
||||
BuiltinFunction._create("max", GenericType.GenType, GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("max", GenericType.GenType, GenericType.GenType, Keyword.FLOAT);
|
||||
BuiltinFunction._create("max", GenericType.GenIntType, GenericType.GenIntType, GenericType.GenIntType);
|
||||
BuiltinFunction._create("max", GenericType.GenIntType, GenericType.GenIntType, Keyword.INT);
|
||||
BuiltinFunction._create("clamp", GenericType.GenType, GenericType.GenType, GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("clamp", GenericType.GenType, GenericType.GenType, Keyword.FLOAT, Keyword.FLOAT);
|
||||
BuiltinFunction._create(
|
||||
"clamp",
|
||||
EGenType.GenUintType,
|
||||
EGenType.GenUintType,
|
||||
EGenType.GenUintType,
|
||||
EGenType.GenUintType
|
||||
GenericType.GenIntType,
|
||||
GenericType.GenIntType,
|
||||
GenericType.GenIntType,
|
||||
GenericType.GenIntType
|
||||
);
|
||||
BuiltinFunction._create("clamp", EGenType.GenUintType, EGenType.GenUintType, Keyword.UINT, Keyword.UINT);
|
||||
BuiltinFunction._create("mix", EGenType.GenType, EGenType.GenType, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("mix", EGenType.GenType, EGenType.GenType, EGenType.GenType, Keyword.FLOAT);
|
||||
BuiltinFunction._create("mix", EGenType.GenType, EGenType.GenType, EGenType.GenType, EGenType.GenBoolType);
|
||||
BuiltinFunction._create("step", EGenType.GenType, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("step", EGenType.GenType, Keyword.FLOAT, EGenType.GenType);
|
||||
BuiltinFunction._create("smoothstep", EGenType.GenType, EGenType.GenType, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("smoothstep", EGenType.GenType, Keyword.FLOAT, Keyword.FLOAT, EGenType.GenType);
|
||||
BuiltinFunction._create("isnan", EGenType.GenBoolType, EGenType.GenType);
|
||||
BuiltinFunction._create("isinf", EGenType.GenBoolType, EGenType.GenType);
|
||||
BuiltinFunction._create("floatBitsToInt", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("floatBitsToUint", EGenType.GenUintType, EGenType.GenType);
|
||||
BuiltinFunction._create("intBitsToFloat", EGenType.GenType, EGenType.GenIntType);
|
||||
BuiltinFunction._create("uintBitsToFloat", EGenType.GenType, EGenType.GenUintType);
|
||||
BuiltinFunction._create("clamp", GenericType.GenIntType, GenericType.GenIntType, Keyword.INT, Keyword.INT);
|
||||
BuiltinFunction._create(
|
||||
"clamp",
|
||||
GenericType.GenUintType,
|
||||
GenericType.GenUintType,
|
||||
GenericType.GenUintType,
|
||||
GenericType.GenUintType
|
||||
);
|
||||
BuiltinFunction._create("clamp", GenericType.GenUintType, GenericType.GenUintType, Keyword.UINT, Keyword.UINT);
|
||||
BuiltinFunction._create("mix", GenericType.GenType, GenericType.GenType, GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("mix", GenericType.GenType, GenericType.GenType, GenericType.GenType, Keyword.FLOAT);
|
||||
BuiltinFunction._create("mix", GenericType.GenType, GenericType.GenType, GenericType.GenType, GenericType.GenBoolType);
|
||||
BuiltinFunction._create("step", GenericType.GenType, GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("step", GenericType.GenType, Keyword.FLOAT, GenericType.GenType);
|
||||
BuiltinFunction._create(
|
||||
"smoothstep",
|
||||
GenericType.GenType,
|
||||
GenericType.GenType,
|
||||
GenericType.GenType,
|
||||
GenericType.GenType
|
||||
);
|
||||
BuiltinFunction._create("smoothstep", GenericType.GenType, Keyword.FLOAT, Keyword.FLOAT, GenericType.GenType);
|
||||
BuiltinFunction._create("isnan", GenericType.GenBoolType, GenericType.GenType);
|
||||
BuiltinFunction._create("isinf", GenericType.GenBoolType, GenericType.GenType);
|
||||
BuiltinFunction._create("floatBitsToInt", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("floatBitsToUint", GenericType.GenUintType, GenericType.GenType);
|
||||
BuiltinFunction._create("intBitsToFloat", GenericType.GenType, GenericType.GenIntType);
|
||||
BuiltinFunction._create("uintBitsToFloat", GenericType.GenType, GenericType.GenUintType);
|
||||
|
||||
BuiltinFunction._create("packSnorm2x16", Keyword.UINT, Keyword.VEC2);
|
||||
BuiltinFunction._create("unpackSnorm2x16", Keyword.VEC2, Keyword.UINT);
|
||||
@@ -183,15 +303,21 @@ BuiltinFunction._create("unpackUnorm2x16", Keyword.VEC2, Keyword.UINT);
|
||||
BuiltinFunction._create("packHalf2x16", Keyword.UINT, Keyword.VEC2);
|
||||
BuiltinFunction._create("unpackHalf2x16", Keyword.VEC2, Keyword.UINT);
|
||||
|
||||
BuiltinFunction._create("length", Keyword.FLOAT, EGenType.GenType);
|
||||
BuiltinFunction._create("distance", Keyword.FLOAT, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("dot", Keyword.FLOAT, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("length", Keyword.FLOAT, GenericType.GenType);
|
||||
BuiltinFunction._create("distance", Keyword.FLOAT, GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("dot", Keyword.FLOAT, GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("cross", Keyword.VEC3, Keyword.VEC3, Keyword.VEC3);
|
||||
BuiltinFunction._create("normalize", EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("faceforward", EGenType.GenType, EGenType.GenType, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("reflect", EGenType.GenType, EGenType.GenType, EGenType.GenType);
|
||||
BuiltinFunction._create("refract", EGenType.GenType, EGenType.GenType, EGenType.GenType, Keyword.FLOAT);
|
||||
BuiltinFunction._create("matrixCompMult", EGenType.Mat, EGenType.Mat, EGenType.Mat);
|
||||
BuiltinFunction._create("normalize", GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create(
|
||||
"faceforward",
|
||||
GenericType.GenType,
|
||||
GenericType.GenType,
|
||||
GenericType.GenType,
|
||||
GenericType.GenType
|
||||
);
|
||||
BuiltinFunction._create("reflect", GenericType.GenType, GenericType.GenType, GenericType.GenType);
|
||||
BuiltinFunction._create("refract", GenericType.GenType, GenericType.GenType, GenericType.GenType, Keyword.FLOAT);
|
||||
BuiltinFunction._create("matrixCompMult", GenericType.Mat, GenericType.Mat, GenericType.Mat);
|
||||
BuiltinFunction._create("outerProduct", Keyword.MAT2, Keyword.VEC2, Keyword.VEC2);
|
||||
BuiltinFunction._create("outerProduct", Keyword.MAT3, Keyword.VEC3, Keyword.VEC3);
|
||||
BuiltinFunction._create("outerProduct", Keyword.MAT4, Keyword.VEC4, Keyword.VEC4);
|
||||
@@ -223,56 +349,56 @@ BuiltinFunction._create("inverse", Keyword.MAT2, Keyword.MAT2);
|
||||
BuiltinFunction._create("inverse", Keyword.MAT3, Keyword.MAT3);
|
||||
BuiltinFunction._create("inverse", Keyword.MAT4, Keyword.MAT4);
|
||||
|
||||
BuiltinFunction._create("lessThan", EGenType.BoolVec, EGenType.Vec, EGenType.Vec);
|
||||
BuiltinFunction._create("lessThan", EGenType.BoolVec, EGenType.IntVec, EGenType.IntVec);
|
||||
BuiltinFunction._create("lessThan", EGenType.BoolVec, EGenType.UintVec, EGenType.UintVec);
|
||||
BuiltinFunction._create("lessThan", GenericType.BoolVec, GenericType.Vec, GenericType.Vec);
|
||||
BuiltinFunction._create("lessThan", GenericType.BoolVec, GenericType.IntVec, GenericType.IntVec);
|
||||
BuiltinFunction._create("lessThan", GenericType.BoolVec, GenericType.UintVec, GenericType.UintVec);
|
||||
|
||||
BuiltinFunction._create("lessThanEqual", EGenType.BoolVec, EGenType.Vec, EGenType.Vec);
|
||||
BuiltinFunction._create("lessThanEqual", EGenType.BoolVec, EGenType.IntVec, EGenType.IntVec);
|
||||
BuiltinFunction._create("lessThanEqual", EGenType.BoolVec, EGenType.UintVec, EGenType.UintVec);
|
||||
BuiltinFunction._create("lessThanEqual", GenericType.BoolVec, GenericType.Vec, GenericType.Vec);
|
||||
BuiltinFunction._create("lessThanEqual", GenericType.BoolVec, GenericType.IntVec, GenericType.IntVec);
|
||||
BuiltinFunction._create("lessThanEqual", GenericType.BoolVec, GenericType.UintVec, GenericType.UintVec);
|
||||
|
||||
BuiltinFunction._create("greaterThan", EGenType.BoolVec, EGenType.Vec, EGenType.Vec);
|
||||
BuiltinFunction._create("greaterThan", EGenType.BoolVec, EGenType.IntVec, EGenType.IntVec);
|
||||
BuiltinFunction._create("greaterThan", EGenType.BoolVec, EGenType.UintVec, EGenType.UintVec);
|
||||
BuiltinFunction._create("greaterThan", GenericType.BoolVec, GenericType.Vec, GenericType.Vec);
|
||||
BuiltinFunction._create("greaterThan", GenericType.BoolVec, GenericType.IntVec, GenericType.IntVec);
|
||||
BuiltinFunction._create("greaterThan", GenericType.BoolVec, GenericType.UintVec, GenericType.UintVec);
|
||||
|
||||
BuiltinFunction._create("greaterThanEqual", EGenType.BoolVec, EGenType.Vec, EGenType.Vec);
|
||||
BuiltinFunction._create("greaterThanEqual", EGenType.BoolVec, EGenType.IntVec, EGenType.IntVec);
|
||||
BuiltinFunction._create("greaterThanEqual", EGenType.BoolVec, EGenType.UintVec, EGenType.UintVec);
|
||||
BuiltinFunction._create("greaterThanEqual", GenericType.BoolVec, GenericType.Vec, GenericType.Vec);
|
||||
BuiltinFunction._create("greaterThanEqual", GenericType.BoolVec, GenericType.IntVec, GenericType.IntVec);
|
||||
BuiltinFunction._create("greaterThanEqual", GenericType.BoolVec, GenericType.UintVec, GenericType.UintVec);
|
||||
|
||||
BuiltinFunction._create("equal", EGenType.BoolVec, EGenType.Vec, EGenType.Vec);
|
||||
BuiltinFunction._create("equal", EGenType.BoolVec, EGenType.IntVec, EGenType.IntVec);
|
||||
BuiltinFunction._create("equal", EGenType.BoolVec, EGenType.UintVec, EGenType.UintVec);
|
||||
BuiltinFunction._create("equal", EGenType.BoolVec, EGenType.BoolVec, EGenType.BoolVec);
|
||||
BuiltinFunction._create("equal", GenericType.BoolVec, GenericType.Vec, GenericType.Vec);
|
||||
BuiltinFunction._create("equal", GenericType.BoolVec, GenericType.IntVec, GenericType.IntVec);
|
||||
BuiltinFunction._create("equal", GenericType.BoolVec, GenericType.UintVec, GenericType.UintVec);
|
||||
BuiltinFunction._create("equal", GenericType.BoolVec, GenericType.BoolVec, GenericType.BoolVec);
|
||||
|
||||
BuiltinFunction._create("notEqual", EGenType.BoolVec, EGenType.Vec, EGenType.Vec);
|
||||
BuiltinFunction._create("notEqual", EGenType.BoolVec, EGenType.IntVec, EGenType.IntVec);
|
||||
BuiltinFunction._create("notEqual", EGenType.BoolVec, EGenType.UintVec, EGenType.UintVec);
|
||||
BuiltinFunction._create("notEqual", EGenType.BoolVec, EGenType.BoolVec, EGenType.BoolVec);
|
||||
BuiltinFunction._create("notEqual", GenericType.BoolVec, GenericType.Vec, GenericType.Vec);
|
||||
BuiltinFunction._create("notEqual", GenericType.BoolVec, GenericType.IntVec, GenericType.IntVec);
|
||||
BuiltinFunction._create("notEqual", GenericType.BoolVec, GenericType.UintVec, GenericType.UintVec);
|
||||
BuiltinFunction._create("notEqual", GenericType.BoolVec, GenericType.BoolVec, GenericType.BoolVec);
|
||||
|
||||
BuiltinFunction._create("any", Keyword.BOOL, EGenType.BoolVec);
|
||||
BuiltinFunction._create("all", Keyword.BOOL, EGenType.BoolVec);
|
||||
BuiltinFunction._create("not", EGenType.BoolVec, EGenType.BoolVec);
|
||||
BuiltinFunction._create("any", Keyword.BOOL, GenericType.BoolVec);
|
||||
BuiltinFunction._create("all", Keyword.BOOL, GenericType.BoolVec);
|
||||
BuiltinFunction._create("not", GenericType.BoolVec, GenericType.BoolVec);
|
||||
|
||||
BuiltinFunction._create("textureSize", Keyword.IVEC2, EGenType.GSampler2D, Keyword.INT);
|
||||
BuiltinFunction._create("textureSize", Keyword.IVEC3, EGenType.GSampler3D, Keyword.INT);
|
||||
BuiltinFunction._create("textureSize", Keyword.IVEC2, EGenType.GSamplerCube, Keyword.INT);
|
||||
BuiltinFunction._create("textureSize", Keyword.IVEC2, GenericType.GSampler2D, Keyword.INT);
|
||||
BuiltinFunction._create("textureSize", Keyword.IVEC3, GenericType.GSampler3D, Keyword.INT);
|
||||
BuiltinFunction._create("textureSize", Keyword.IVEC2, GenericType.GSamplerCube, Keyword.INT);
|
||||
|
||||
BuiltinFunction._create("textureSize", Keyword.IVEC2, Keyword.SAMPLER2D_SHADOW, Keyword.INT);
|
||||
BuiltinFunction._create("textureSize", Keyword.IVEC2, Keyword.SAMPLER_CUBE_SHADOW, Keyword.INT);
|
||||
|
||||
BuiltinFunction._create("textureSize", Keyword.IVEC3, EGenType.GSampler2DArray, Keyword.INT);
|
||||
BuiltinFunction._create("textureSize", Keyword.IVEC3, GenericType.GSampler2DArray, Keyword.INT);
|
||||
BuiltinFunction._create("textureSize", Keyword.IVEC3, Keyword.SAMPLER2D_ARRAY_SHADOW, Keyword.INT);
|
||||
|
||||
BuiltinFunction._create("texture2D", Keyword.VEC4, Keyword.SAMPLER2D, Keyword.VEC2);
|
||||
BuiltinFunction._create("texture2D", Keyword.VEC4, Keyword.SAMPLER2D, Keyword.VEC2, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture2D", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC2);
|
||||
BuiltinFunction._create("texture2D", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC2, Keyword.FLOAT);
|
||||
|
||||
BuiltinFunction._create("texture", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC2, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC2);
|
||||
BuiltinFunction._create("texture", EGenType.GVec4, EGenType.GSampler3D, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture", EGenType.GVec4, EGenType.GSampler3D, Keyword.VEC3);
|
||||
BuiltinFunction._create("texture", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC2, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC2);
|
||||
BuiltinFunction._create("texture", GenericType.GVec4, GenericType.GSampler3D, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture", GenericType.GVec4, GenericType.GSampler3D, Keyword.VEC3);
|
||||
|
||||
BuiltinFunction._create("texture", EGenType.GVec4, EGenType.GSamplerCube, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture", EGenType.GVec4, EGenType.GSamplerCube, Keyword.VEC3);
|
||||
BuiltinFunction._create("texture", GenericType.GVec4, GenericType.GSamplerCube, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture", GenericType.GVec4, GenericType.GSamplerCube, Keyword.VEC3);
|
||||
|
||||
BuiltinFunction._create("texture", Keyword.FLOAT, Keyword.SAMPLER2D_SHADOW, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture", Keyword.FLOAT, Keyword.SAMPLER2D_SHADOW, Keyword.VEC3);
|
||||
@@ -280,54 +406,54 @@ BuiltinFunction._create("texture", Keyword.FLOAT, Keyword.SAMPLER2D_SHADOW, Keyw
|
||||
BuiltinFunction._create("texture", Keyword.FLOAT, Keyword.SAMPLER_CUBE_SHADOW, Keyword.VEC4, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture", Keyword.FLOAT, Keyword.SAMPLER_CUBE_SHADOW, Keyword.VEC4);
|
||||
|
||||
BuiltinFunction._create("texture", EGenType.GVec4, Keyword.SAMPLER2D_ARRAY, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture", EGenType.GVec4, Keyword.SAMPLER2D_ARRAY, Keyword.VEC3);
|
||||
BuiltinFunction._create("texture", GenericType.GVec4, Keyword.SAMPLER2D_ARRAY, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture", GenericType.GVec4, Keyword.SAMPLER2D_ARRAY, Keyword.VEC3);
|
||||
|
||||
BuiltinFunction._create("texture", Keyword.FLOAT, Keyword.SAMPLER2D_ARRAY_SHADOW, Keyword.VEC4);
|
||||
|
||||
BuiltinFunction._create("textureProj", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProj", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC3);
|
||||
BuiltinFunction._create("textureProj", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC4, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProj", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC4);
|
||||
BuiltinFunction._create("textureProj", EGenType.GVec4, EGenType.GSampler3D, Keyword.VEC4, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProj", EGenType.GVec4, EGenType.GSampler3D, Keyword.VEC4);
|
||||
BuiltinFunction._create("textureProj", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProj", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC3);
|
||||
BuiltinFunction._create("textureProj", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC4, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProj", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC4);
|
||||
BuiltinFunction._create("textureProj", GenericType.GVec4, GenericType.GSampler3D, Keyword.VEC4, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProj", GenericType.GVec4, GenericType.GSampler3D, Keyword.VEC4);
|
||||
|
||||
BuiltinFunction._create("textureProj", Keyword.FLOAT, Keyword.SAMPLER2D_SHADOW, Keyword.VEC4, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProj", Keyword.FLOAT, Keyword.SAMPLER2D_SHADOW, Keyword.VEC4);
|
||||
|
||||
BuiltinFunction._create("textureLod", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC2, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureLod", EGenType.GVec4, EGenType.GSampler3D, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureLod", EGenType.GVec4, EGenType.GSamplerCube, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureLod", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC2, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureLod", GenericType.GVec4, GenericType.GSampler3D, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureLod", GenericType.GVec4, GenericType.GSamplerCube, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureLod", Keyword.FLOAT, Keyword.SAMPLER2D_SHADOW, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureLod", EGenType.GVec4, EGenType.GSampler2DArray, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture2DLodEXT", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC2, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture2DLodEXT", EGenType.GVec4, EGenType.GSampler3D, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureLod", GenericType.GVec4, GenericType.GSampler2DArray, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture2DLod", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC2, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture2DLodEXT", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC2, Keyword.FLOAT);
|
||||
BuiltinFunction._create("texture2DLodEXT", GenericType.GVec4, GenericType.GSampler3D, Keyword.VEC3, Keyword.FLOAT);
|
||||
|
||||
BuiltinFunction._create("textureCube", Keyword.SAMPLER_CUBE, Keyword.VEC3);
|
||||
BuiltinFunction._create("textureCube", Keyword.SAMPLER_CUBE, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureCube", EGenType.GVec4, EGenType.GSamplerCube, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureCubeLod", Keyword.SAMPLER_CUBE, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureCubeLodEXT", EGenType.GVec4, EGenType.GSamplerCube, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureCube", GenericType.GVec4, GenericType.GSamplerCube, Keyword.VEC3);
|
||||
BuiltinFunction._create("textureCube", GenericType.GVec4, GenericType.GSamplerCube, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureCubeLod", GenericType.GVec4, GenericType.GSamplerCube, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureCubeLodEXT", GenericType.GVec4, GenericType.GSamplerCube, Keyword.VEC3, Keyword.FLOAT);
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.VEC2,
|
||||
Keyword.IVEC2,
|
||||
Keyword.FLOAT
|
||||
);
|
||||
BuiltinFunction._create("textureOffset", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC2, Keyword.IVEC2);
|
||||
BuiltinFunction._create("textureOffset", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC2, Keyword.IVEC2);
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler3D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler3D,
|
||||
Keyword.VEC3,
|
||||
Keyword.IVEC3,
|
||||
Keyword.FLOAT
|
||||
);
|
||||
BuiltinFunction._create("textureOffset", EGenType.GVec4, EGenType.GSampler3D, Keyword.VEC3, Keyword.IVEC3);
|
||||
BuiltinFunction._create("textureOffset", GenericType.GVec4, GenericType.GSampler3D, Keyword.VEC3, Keyword.IVEC3);
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureOffset",
|
||||
@@ -340,38 +466,38 @@ BuiltinFunction._create(
|
||||
BuiltinFunction._create("textureOffset", Keyword.FLOAT, Keyword.SAMPLER2D_SHADOW, Keyword.VEC3, Keyword.IVEC2);
|
||||
BuiltinFunction._create(
|
||||
"textureOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2DArray,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2DArray,
|
||||
Keyword.VEC3,
|
||||
Keyword.IVEC2,
|
||||
Keyword.FLOAT
|
||||
);
|
||||
BuiltinFunction._create("textureOffset", EGenType.GVec4, EGenType.GSampler2DArray, Keyword.VEC3, Keyword.IVEC2);
|
||||
BuiltinFunction._create("textureOffset", GenericType.GVec4, GenericType.GSampler2DArray, Keyword.VEC3, Keyword.IVEC2);
|
||||
|
||||
BuiltinFunction._create("texelFetch", EGenType.GVec4, EGenType.GSampler2D, Keyword.IVEC2, Keyword.INT);
|
||||
BuiltinFunction._create("texelFetch", EGenType.GVec4, EGenType.GSampler3D, Keyword.IVEC3, Keyword.INT);
|
||||
BuiltinFunction._create("texelFetch", EGenType.GVec4, EGenType.GSampler2DArray, Keyword.IVEC3, Keyword.INT);
|
||||
BuiltinFunction._create("texelFetch", GenericType.GVec4, GenericType.GSampler2D, Keyword.IVEC2, Keyword.INT);
|
||||
BuiltinFunction._create("texelFetch", GenericType.GVec4, GenericType.GSampler3D, Keyword.IVEC3, Keyword.INT);
|
||||
BuiltinFunction._create("texelFetch", GenericType.GVec4, GenericType.GSampler2DArray, Keyword.IVEC3, Keyword.INT);
|
||||
|
||||
BuiltinFunction._create(
|
||||
"texelFetchOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.IVEC2,
|
||||
Keyword.INT,
|
||||
Keyword.IVEC2
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"texelFetchOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler3D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler3D,
|
||||
Keyword.IVEC3,
|
||||
Keyword.INT,
|
||||
Keyword.IVEC3
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"texelFetchOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2DArray,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2DArray,
|
||||
Keyword.IVEC3,
|
||||
Keyword.INT,
|
||||
Keyword.IVEC2
|
||||
@@ -379,33 +505,33 @@ BuiltinFunction._create(
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureProjOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.VEC3,
|
||||
Keyword.IVEC2,
|
||||
Keyword.FLOAT
|
||||
);
|
||||
BuiltinFunction._create("textureProjOffset", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC3, Keyword.IVEC2);
|
||||
BuiltinFunction._create("textureProjOffset", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC3, Keyword.IVEC2);
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureProjOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.VEC4,
|
||||
Keyword.IVEC2,
|
||||
Keyword.FLOAT
|
||||
);
|
||||
BuiltinFunction._create("textureProjOffset", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC4, Keyword.IVEC2);
|
||||
BuiltinFunction._create("textureProjOffset", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC4, Keyword.IVEC2);
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureProjOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler3D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler3D,
|
||||
Keyword.VEC4,
|
||||
Keyword.IVEC3,
|
||||
Keyword.FLOAT
|
||||
);
|
||||
BuiltinFunction._create("textureProjOffset", EGenType.GVec4, EGenType.GSampler3D, Keyword.VEC4, Keyword.IVEC3);
|
||||
BuiltinFunction._create("textureProjOffset", GenericType.GVec4, GenericType.GSampler3D, Keyword.VEC4, Keyword.IVEC3);
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureProjOffset",
|
||||
@@ -419,16 +545,16 @@ BuiltinFunction._create("textureProjOffset", Keyword.FLOAT, Keyword.SAMPLER2D_SH
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureLodOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.VEC2,
|
||||
Keyword.FLOAT,
|
||||
Keyword.IVEC2
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"textureLodOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler3D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler3D,
|
||||
Keyword.VEC3,
|
||||
Keyword.FLOAT,
|
||||
Keyword.IVEC3
|
||||
@@ -444,38 +570,38 @@ BuiltinFunction._create(
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"textureLodOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2DArray,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2DArray,
|
||||
Keyword.VEC3,
|
||||
Keyword.FLOAT,
|
||||
Keyword.IVEC2
|
||||
);
|
||||
|
||||
BuiltinFunction._create("textureProjLod", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProjLod", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC4, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProjLod", EGenType.GVec4, EGenType.GSampler3D, Keyword.VEC4, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProjLod", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC3, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProjLod", GenericType.GVec4, GenericType.GSampler2D, Keyword.VEC4, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProjLod", GenericType.GVec4, GenericType.GSampler3D, Keyword.VEC4, Keyword.FLOAT);
|
||||
BuiltinFunction._create("textureProjLod", Keyword.FLOAT, Keyword.SAMPLER2D_SHADOW, Keyword.VEC4, Keyword.FLOAT);
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureProjLodOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.VEC3,
|
||||
Keyword.FLOAT,
|
||||
Keyword.IVEC2
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"textureProjLodOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.VEC4,
|
||||
Keyword.FLOAT,
|
||||
Keyword.IVEC2
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"textureProjLodOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler3D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler3D,
|
||||
Keyword.VEC4,
|
||||
Keyword.FLOAT,
|
||||
Keyword.IVEC3
|
||||
@@ -489,9 +615,30 @@ BuiltinFunction._create(
|
||||
Keyword.IVEC2
|
||||
);
|
||||
|
||||
BuiltinFunction._create("textureGrad", EGenType.GVec4, EGenType.GSampler2D, Keyword.VEC2, Keyword.VEC2, Keyword.VEC2);
|
||||
BuiltinFunction._create("textureGrad", EGenType.GVec4, EGenType.GSampler3D, Keyword.VEC3, Keyword.VEC3, Keyword.VEC3);
|
||||
BuiltinFunction._create("textureGrad", EGenType.GVec4, EGenType.GSamplerCube, Keyword.VEC3, Keyword.VEC3, Keyword.VEC3);
|
||||
BuiltinFunction._create(
|
||||
"textureGrad",
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.VEC2,
|
||||
Keyword.VEC2,
|
||||
Keyword.VEC2
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"textureGrad",
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler3D,
|
||||
Keyword.VEC3,
|
||||
Keyword.VEC3,
|
||||
Keyword.VEC3
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"textureGrad",
|
||||
GenericType.GVec4,
|
||||
GenericType.GSamplerCube,
|
||||
Keyword.VEC3,
|
||||
Keyword.VEC3,
|
||||
Keyword.VEC3
|
||||
);
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureGrad",
|
||||
@@ -512,8 +659,8 @@ BuiltinFunction._create(
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureGrad",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2DArray,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2DArray,
|
||||
Keyword.VEC3,
|
||||
Keyword.VEC2,
|
||||
Keyword.VEC2
|
||||
@@ -529,8 +676,8 @@ BuiltinFunction._create(
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureGradOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.VEC2,
|
||||
Keyword.VEC2,
|
||||
Keyword.VEC2,
|
||||
@@ -538,8 +685,8 @@ BuiltinFunction._create(
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"textureGradOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler3D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler3D,
|
||||
Keyword.VEC3,
|
||||
Keyword.VEC3,
|
||||
Keyword.VEC3,
|
||||
@@ -556,8 +703,8 @@ BuiltinFunction._create(
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"textureGradOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2DArray,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2DArray,
|
||||
Keyword.VEC3,
|
||||
Keyword.VEC2,
|
||||
Keyword.VEC2,
|
||||
@@ -575,24 +722,24 @@ BuiltinFunction._create(
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureProjGrad",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.VEC3,
|
||||
Keyword.VEC2,
|
||||
Keyword.VEC2
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"textureProjGrad",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.VEC4,
|
||||
Keyword.VEC2,
|
||||
Keyword.VEC2
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"textureProjGrad",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler3D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler3D,
|
||||
Keyword.VEC4,
|
||||
Keyword.VEC3,
|
||||
Keyword.VEC3
|
||||
@@ -608,8 +755,8 @@ BuiltinFunction._create(
|
||||
|
||||
BuiltinFunction._create(
|
||||
"textureProjGradOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.VEC3,
|
||||
Keyword.VEC2,
|
||||
Keyword.VEC2,
|
||||
@@ -617,8 +764,8 @@ BuiltinFunction._create(
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"textureProjGradOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler2D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler2D,
|
||||
Keyword.VEC4,
|
||||
Keyword.VEC2,
|
||||
Keyword.VEC2,
|
||||
@@ -626,8 +773,8 @@ BuiltinFunction._create(
|
||||
);
|
||||
BuiltinFunction._create(
|
||||
"textureProjGradOffset",
|
||||
EGenType.GVec4,
|
||||
EGenType.GSampler3D,
|
||||
GenericType.GVec4,
|
||||
GenericType.GSampler3D,
|
||||
Keyword.VEC4,
|
||||
Keyword.VEC3,
|
||||
Keyword.VEC3,
|
||||
@@ -642,6 +789,6 @@ BuiltinFunction._create(
|
||||
Keyword.VEC2,
|
||||
Keyword.IVEC2
|
||||
);
|
||||
BuiltinFunction._createWithScop("dFdx", EGenType.GenType, EShaderStage.FRAGMENT, EGenType.GenType);
|
||||
BuiltinFunction._createWithScop("dFdy", EGenType.GenType, EShaderStage.FRAGMENT, EGenType.GenType);
|
||||
BuiltinFunction._createWithScop("fwidth", EGenType.GenType, EShaderStage.FRAGMENT, EGenType.GenType);
|
||||
BuiltinFunction._createWithScope("dFdx", GenericType.GenType, EShaderStage.FRAGMENT, GenericType.GenType);
|
||||
BuiltinFunction._createWithScope("dFdy", GenericType.GenType, EShaderStage.FRAGMENT, GenericType.GenType);
|
||||
BuiltinFunction._createWithScope("fwidth", GenericType.GenType, EShaderStage.FRAGMENT, GenericType.GenType);
|
||||
|
||||
@@ -247,6 +247,12 @@ describe("ShaderLab", async () => {
|
||||
glslValidate(engine, shaderSource, shaderLabRelease);
|
||||
});
|
||||
|
||||
it("macro-negate-number (!0, !1 in #if expressions)", async () => {
|
||||
const shaderSource = await readFile("./shaders/macro-negate-number.shader");
|
||||
glslValidate(engine, shaderSource, shaderLabVerbose);
|
||||
glslValidate(engine, shaderSource, shaderLabRelease);
|
||||
});
|
||||
|
||||
it("mrt-struct", async () => {
|
||||
const shaderSource = await readFile("./shaders/mrt-struct.shader");
|
||||
glslValidate(engine, shaderSource, shaderLabRelease);
|
||||
@@ -257,4 +263,16 @@ describe("ShaderLab", async () => {
|
||||
glslValidate(engine, shaderSource, shaderLabRelease);
|
||||
glslValidate(engine, shaderSource, shaderLabVerbose);
|
||||
});
|
||||
|
||||
it("texture-generic (GVec4 → vec4 resolve)", async () => {
|
||||
const shaderSource = await readFile("./shaders/texture-generic.shader");
|
||||
glslValidate(engine, shaderSource, shaderLabVerbose);
|
||||
glslValidate(engine, shaderSource, shaderLabRelease);
|
||||
});
|
||||
|
||||
it("generic-return-type (builtin generic return as arg to user function)", async () => {
|
||||
const shaderSource = await readFile("./shaders/generic-return-type.shader");
|
||||
glslValidate(engine, shaderSource, shaderLabVerbose);
|
||||
glslValidate(engine, shaderSource, shaderLabRelease);
|
||||
});
|
||||
});
|
||||
|
||||
52
tests/src/shader-lab/shaders/generic-return-type.shader
Normal file
52
tests/src/shader-lab/shaders/generic-return-type.shader
Normal file
@@ -0,0 +1,52 @@
|
||||
Shader "generic-return-type-test" {
|
||||
SubShader "Default" {
|
||||
Pass "Forward" {
|
||||
mat4 renderer_MVPMat;
|
||||
|
||||
struct Attributes { vec4 POSITION; };
|
||||
struct Varyings { vec2 uv; vec3 worldNormal; vec3 worldTangent; };
|
||||
|
||||
VertexShader = vert;
|
||||
FragmentShader = frag;
|
||||
|
||||
// Test: user-defined function with concrete parameter types
|
||||
vec3 CalculateNormalFromTangentSpace(vec3 normalFromTangentSpace, float normalStrength, vec3 normal, vec3 tangent, float mirrorNormal) {
|
||||
vec3 binormal = cross(normal, tangent) * mirrorNormal;
|
||||
return (normalFromTangentSpace.x * normalStrength) * normalize(tangent) +
|
||||
(normalFromTangentSpace.y * normalStrength) * normalize(binormal) +
|
||||
normalFromTangentSpace.z * normalize(normal);
|
||||
}
|
||||
|
||||
sampler2D u_normalMap;
|
||||
vec4 u_scaleAndStrength;
|
||||
|
||||
Varyings vert(Attributes attr) {
|
||||
Varyings o;
|
||||
gl_Position = renderer_MVPMat * attr.POSITION;
|
||||
o.uv = attr.POSITION.xy;
|
||||
o.worldNormal = attr.POSITION.xyz;
|
||||
o.worldTangent = attr.POSITION.xyz;
|
||||
return o;
|
||||
}
|
||||
|
||||
void frag(Varyings v) {
|
||||
vec3 normal = v.worldNormal;
|
||||
|
||||
// Test: builtin generic functions (normalize) on swizzled values,
|
||||
// passed as arguments to a user-defined function.
|
||||
// normalize(vec3) should not produce EGenType.GenType (200) as return type,
|
||||
// it should produce TypeAny so overload matching succeeds.
|
||||
vec3 nmmp = texture(u_normalMap, v.uv).xyz - vec3(0.5);
|
||||
normal = CalculateNormalFromTangentSpace(
|
||||
nmmp,
|
||||
u_scaleAndStrength.w,
|
||||
normalize(normal.xyz),
|
||||
normalize(v.worldTangent),
|
||||
1.0
|
||||
);
|
||||
|
||||
gl_FragColor = vec4(normalize(normal), 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
tests/src/shader-lab/shaders/macro-negate-number.shader
Normal file
41
tests/src/shader-lab/shaders/macro-negate-number.shader
Normal file
@@ -0,0 +1,41 @@
|
||||
Shader "macro-negate-number-test" {
|
||||
SubShader "default" {
|
||||
Pass "default" {
|
||||
struct a2v {
|
||||
vec4 POSITION;
|
||||
};
|
||||
|
||||
mat4 renderer_MVPMat;
|
||||
|
||||
#define SCENE_FOG_MODE 1
|
||||
|
||||
VertexShader = vert;
|
||||
FragmentShader = frag;
|
||||
|
||||
void vert(a2v v) {
|
||||
gl_Position = renderer_MVPMat * v.POSITION;
|
||||
}
|
||||
|
||||
void frag() {
|
||||
vec4 color = vec4(1.0);
|
||||
|
||||
// Test: !0 should evaluate to true (like C preprocessor)
|
||||
#if SCENE_FOG_MODE != 4 && (!0 || SCENE_FOG_MODE)
|
||||
color = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
// Test: !1 should evaluate to false
|
||||
#if !1
|
||||
color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
// Test: !0 alone
|
||||
#if !0
|
||||
color = vec4(0.0, 0.0, 1.0, 1.0);
|
||||
#endif
|
||||
|
||||
gl_FragColor = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
94
tests/src/shader-lab/shaders/texture-generic.shader
Normal file
94
tests/src/shader-lab/shaders/texture-generic.shader
Normal file
@@ -0,0 +1,94 @@
|
||||
Shader "texture-generic-test" {
|
||||
SubShader "Default" {
|
||||
Pass "Forward" {
|
||||
mat4 renderer_MVPMat;
|
||||
|
||||
struct Attributes { vec4 POSITION; };
|
||||
struct Varyings { vec2 uv; };
|
||||
|
||||
VertexShader = vert;
|
||||
FragmentShader = frag;
|
||||
|
||||
// Test: user-defined function taking vec4, called with texture() return value.
|
||||
// texture(sampler2D, vec2) returns GVec4 which must resolve to vec4.
|
||||
float decode32(vec4 rgba) {
|
||||
rgba = rgba * 255.0;
|
||||
float Sign = 1.0 - step(128.0, rgba[3] + 0.5) * 2.0;
|
||||
float Exponent = 2.0 * mod(float(int(rgba[3] + 0.5)), 128.0) + step(128.0, rgba[2] + 0.5) - 127.0;
|
||||
float Mantissa = mod(float(int(rgba[2] + 0.5)), 128.0) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;
|
||||
return Sign * exp2(Exponent - 23.0) * Mantissa;
|
||||
}
|
||||
|
||||
sampler2D u_texture;
|
||||
|
||||
// Test: texture() result passed to user function (GVec4 → vec4 resolve)
|
||||
mat4 getJointMatrix(float i) {
|
||||
float x = 4.0 * i;
|
||||
vec4 v1 = vec4(
|
||||
decode32(texture(u_texture, vec2((x + 0.5) / 1024.0, 0.5))),
|
||||
decode32(texture(u_texture, vec2((x + 1.5) / 1024.0, 0.5))),
|
||||
decode32(texture(u_texture, vec2((x + 2.5) / 1024.0, 0.5))),
|
||||
decode32(texture(u_texture, vec2((x + 3.5) / 1024.0, 0.5)))
|
||||
);
|
||||
return mat4(v1, v1, v1, vec4(0.0, 0.0, 0.0, 1.0));
|
||||
}
|
||||
|
||||
// Test: texture() result used directly in arithmetic (GVec4 → vec4)
|
||||
vec4 sampleAndScale(sampler2D tex, vec2 coord, float scale) {
|
||||
vec4 color = texture(tex, coord);
|
||||
return color * scale;
|
||||
}
|
||||
|
||||
// Test: textureLod also returns GVec4
|
||||
vec4 sampleLod(sampler2D tex, vec2 coord, float lod) {
|
||||
vec4 color = textureLod(tex, coord, lod);
|
||||
return color;
|
||||
}
|
||||
|
||||
// Test: texture2DLod (ES 1.0 function, concrete types)
|
||||
vec4 sampleLod2D(sampler2D tex, vec2 coord, float lod) {
|
||||
return texture2DLod(tex, coord, lod);
|
||||
}
|
||||
|
||||
// Test: texture2DLod result passed to user function
|
||||
float decodeLod2D(sampler2D tex, vec2 coord) {
|
||||
return decode32(texture2DLod(tex, coord, 0.0));
|
||||
}
|
||||
|
||||
// Test: texture() with samplerCube (GVec4 → vec4 resolve via GSamplerCube)
|
||||
samplerCube u_cubeMap;
|
||||
vec4 sampleCube(samplerCube tex, vec3 dir) {
|
||||
return texture(tex, dir);
|
||||
}
|
||||
|
||||
// Test: textureLod with samplerCube (GVec4 → vec4 resolve via GSamplerCube)
|
||||
vec4 sampleCubeLod(samplerCube tex, vec3 dir, float lod) {
|
||||
return textureLod(tex, dir, lod);
|
||||
}
|
||||
|
||||
// Test: texture(samplerCube) result passed to user function (vec4 param matching)
|
||||
float decodeCube(vec4 rgba) {
|
||||
return rgba.r + rgba.g;
|
||||
}
|
||||
float sampleAndDecode(samplerCube tex, vec3 dir) {
|
||||
return decodeCube(texture(tex, dir));
|
||||
}
|
||||
|
||||
Varyings vert(Attributes attr) {
|
||||
Varyings o;
|
||||
gl_Position = renderer_MVPMat * attr.POSITION;
|
||||
o.uv = attr.POSITION.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
void frag(Varyings v) {
|
||||
vec4 sampled = sampleAndScale(u_texture, v.uv, 1.0);
|
||||
vec4 lodSampled = sampleLod(u_texture, v.uv, 0.0);
|
||||
vec4 cubeSampled = sampleCube(u_cubeMap, vec3(v.uv, 1.0));
|
||||
vec4 cubeLodSampled = sampleCubeLod(u_cubeMap, vec3(v.uv, 1.0), 0.0);
|
||||
float decoded = sampleAndDecode(u_cubeMap, vec3(v.uv, 1.0));
|
||||
gl_FragColor = sampled + lodSampled + cubeSampled + cubeLodSampled + vec4(decoded);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user