init method
void
init()
Implementation
void init() {
final defines = parameters.defines;
vertexShader = parameters.vertexShader;
fragmentShader = parameters.fragmentShader;
final shadowMapTypeDefine = generateShadowMapTypeDefine(parameters);
final envMapTypeDefine = generateEnvMapTypeDefine(parameters);
final envMapModeDefine = generateEnvMapModeDefine(parameters);
final envMapBlendingDefine = generateEnvMapBlendingDefine(parameters);
final cubeUVSize = generateCubeUVSize(parameters);
final customExtensions = parameters.isWebGL2 ? '' : generateExtensions(parameters);
String customDefines = generateDefines(defines);
String prefixVertex, prefixFragment;
String defaultVersionString = "";
String versionString = parameters.glslVersion != null ? '#version ${parameters.glslVersion}\n' : defaultVersionString;
if (parameters.isRawShaderMaterial) {
prefixVertex = [customDefines].where((s) => filterEmptyLine(s)).join('\n');
if (prefixVertex.isNotEmpty) {
prefixVertex = "$prefixVertex\n";
}
prefixFragment = [customExtensions, customDefines].where((s) => filterEmptyLine(s)).join('\n');
if (prefixFragment.isNotEmpty) {
prefixFragment = "$prefixFragment\n";
}
} else {
prefixVertex = [
generatePrecision(parameters),
'#define SHADER_NAME ${parameters.shaderName}',
customDefines,
parameters.instancing ? '#define USE_INSTANCING' : '',
parameters.instancingColor ? '#define USE_INSTANCING_COLOR' : '',
parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
(parameters.useFog && parameters.fog) ? '#define USE_FOG' : '',
(parameters.useFog && parameters.fogExp2) ? '#define FOG_EXP2' : '',
parameters.map ? '#define USE_MAP' : '',
parameters.envMap ? '#define USE_ENVMAP' : '',
parameters.envMap ? '#define $envMapModeDefine' : '',
parameters.lightMap ? '#define USE_LIGHTMAP' : '',
parameters.aoMap ? '#define USE_AOMAP' : '',
parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
parameters.bumpMap ? '#define USE_BUMPMAP' : '',
parameters.normalMap ? '#define USE_NORMALMAP' : '',
(parameters.normalMap && parameters.objectSpaceNormalMap) ? '#define OBJECTSPACE_NORMALMAP' : '',
(parameters.normalMap && parameters.tangentSpaceNormalMap) ? '#define TANGENTSPACE_NORMALMAP' : '',
parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '',
parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '',
parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',
parameters.specularMap ? '#define USE_SPECULARMAP' : '',
parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '',
parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '',
parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
parameters.transmission ? '#define USE_TRANSMISSION' : '',
parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '',
parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '',
parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '',
parameters.vertexTangents ? '#define USE_TANGENT' : '',
parameters.vertexColors ? '#define USE_COLOR' : '',
parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '',
parameters.vertexUvs ? '#define USE_UV' : '',
parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '',
parameters.flatShading ? '#define FLAT_SHADED' : '',
parameters.skinning ? '#define USE_SKINNING' : '',
parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
(parameters.morphTargets && parameters.isWebGL2) ? '#define MORPHTARGETS_TEXTURE' : '',
(parameters.morphTargets && parameters.isWebGL2)
? '#define MORPHTARGETS_COUNT ${parameters.morphTargetsCount}'
: '',
parameters.morphNormals && parameters.flatShading == false ? '#define USE_MORPHNORMALS' : '',
(parameters.morphColors && parameters.isWebGL2) ? '#define USE_MORPHCOLORS' : '',
(parameters.morphTargetsCount > 0 && parameters.isWebGL2) ? '#define MORPHTARGETS_TEXTURE' : '',
(parameters.morphTargetsCount > 0 && parameters.isWebGL2)
? '#define MORPHTARGETS_TEXTURE_STRIDE ${parameters.morphTextureStride}'
: '',
(parameters.morphTargetsCount > 0 && parameters.isWebGL2)
? '#define MORPHTARGETS_COUNT ${parameters.morphTargetsCount}'
: '',
parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
parameters.flipSided ? '#define FLIP_SIDED' : '',
parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
parameters.shadowMapEnabled ? '#define $shadowMapTypeDefine' : '',
parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
(parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth)
? '#define USE_LOGDEPTHBUF_EXT'
: '',
'uniform mat4 modelMatrix;',
'uniform mat4 modelViewMatrix;',
'uniform mat4 projectionMatrix;',
'uniform mat4 viewMatrix;',
'uniform mat3 normalMatrix;',
'uniform vec3 cameraPosition;',
'uniform bool isOrthographic;',
'#ifdef USE_INSTANCING',
' attribute mat4 instanceMatrix;',
'#endif',
'#ifdef USE_INSTANCING_COLOR',
' attribute vec3 instanceColor;',
'#endif',
'attribute vec3 position;',
'attribute vec3 normal;',
'attribute vec2 uv;',
'#ifdef USE_TANGENT',
' attribute vec4 tangent;',
'#endif',
'#if defined( USE_COLOR_ALPHA )',
' attribute vec4 color;',
'#elif defined( USE_COLOR )',
' attribute vec3 color;',
'#endif',
'#if ( defined( USE_MORPHTARGETS ) && ! defined( MORPHTARGETS_TEXTURE ) )',
' attribute vec3 morphTarget0;',
' attribute vec3 morphTarget1;',
' attribute vec3 morphTarget2;',
' attribute vec3 morphTarget3;',
' #ifdef USE_MORPHNORMALS',
' attribute vec3 morphNormal0;',
' attribute vec3 morphNormal1;',
' attribute vec3 morphNormal2;',
' attribute vec3 morphNormal3;',
' #else',
' attribute vec3 morphTarget4;',
' attribute vec3 morphTarget5;',
' attribute vec3 morphTarget6;',
' attribute vec3 morphTarget7;',
' #endif',
'#endif',
'#ifdef USE_SKINNING',
' attribute vec4 skinIndex;',
' attribute vec4 skinWeight;',
'#endif',
'\n'
].where((s) => filterEmptyLine(s)).join('\n');
prefixFragment = [
customExtensions,
generatePrecision(parameters),
'#define SHADER_NAME ${parameters.shaderName}',
customDefines,
(parameters.useFog && parameters.fog) ? '#define USE_FOG' : '',
(parameters.useFog && parameters.fogExp2) ? '#define FOG_EXP2' : '',
parameters.map ? '#define USE_MAP' : '',
parameters.matcap ? '#define USE_MATCAP' : '',
parameters.envMap ? '#define USE_ENVMAP' : '',
parameters.envMap ? '#define $envMapTypeDefine' : '',
parameters.envMap ? '#define $envMapModeDefine' : '',
parameters.envMap ? '#define $envMapBlendingDefine' : '',
cubeUVSize != null ? '#define CUBEUV_TEXEL_WIDTH ${cubeUVSize["texelWidth"]}' : '',
cubeUVSize != null ? '#define CUBEUV_TEXEL_HEIGHT ${cubeUVSize["texelHeight"]}' : '',
cubeUVSize != null ? '#define CUBEUV_MAX_MIP ${cubeUVSize["maxMip"].toString()}.0' : '',
parameters.lightMap ? '#define USE_LIGHTMAP' : '',
parameters.aoMap ? '#define USE_AOMAP' : '',
parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
parameters.bumpMap ? '#define USE_BUMPMAP' : '',
parameters.normalMap ? '#define USE_NORMALMAP' : '',
(parameters.normalMap && parameters.objectSpaceNormalMap) ? '#define OBJECTSPACE_NORMALMAP' : '',
(parameters.normalMap && parameters.tangentSpaceNormalMap) ? '#define TANGENTSPACE_NORMALMAP' : '',
parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '',
parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '',
parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
parameters.specularMap ? '#define USE_SPECULARMAP' : '',
parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '',
parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '',
parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
parameters.alphaTest ? '#define USE_ALPHATEST' : '',
parameters.sheen ? '#define USE_SHEEN' : '',
parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '',
parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '',
parameters.transmission ? '#define USE_TRANSMISSION' : '',
parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '',
parameters.decodeVideoTexture ? '#define DECODE_VIDEO_TEXTURE' : '',
parameters.vertexTangents ? '#define USE_TANGENT' : '',
parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '',
parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '',
parameters.vertexUvs ? '#define USE_UV' : '',
parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '',
parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
parameters.flatShading ? '#define FLAT_SHADED' : '',
parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
parameters.flipSided ? '#define FLIP_SIDED' : '',
parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
parameters.shadowMapEnabled ? '#define $shadowMapTypeDefine' : '',
parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '',
parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '',
parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
(parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth)? '#define USE_LOGDEPTHBUF_EXT': '',
'uniform mat4 viewMatrix;',
'uniform vec3 cameraPosition;',
'uniform bool isOrthographic;',
(parameters.toneMapping != NoToneMapping) ? '#define TONE_MAPPING' : '',
(parameters.toneMapping != NoToneMapping)? shaderChunk['tonemapping_pars_fragment']: '', // this code is required here because it is used by the toneMapping() defined below
(parameters.toneMapping != NoToneMapping) ? getToneMappingFunction('toneMapping', parameters.toneMapping) : '',
parameters.dithering ? '#define DITHERING' : '',
parameters.opaque ? '#define OPAQUE' : '',
shaderChunk['encodings_pars_fragment'], // this code is required here because it is used by the various encoding/decoding defined below
getTexelEncodingFunction('linearToOutputTexel', parameters.outputEncoding),
parameters.useDepthPacking ? '#define DEPTH_PACKING ${parameters.depthPacking}' : '',
'\n'
].where((s) => filterEmptyLine(s)).join('\n');
}
vertexShader = resolveIncludes(vertexShader);
vertexShader = replaceLightNums(vertexShader, parameters);
vertexShader = replaceClippingPlaneNums(vertexShader, parameters);
fragmentShader = resolveIncludes(fragmentShader);
fragmentShader = replaceLightNums(fragmentShader, parameters);
fragmentShader = replaceClippingPlaneNums(fragmentShader, parameters);
vertexShader = unrollLoops(vertexShader);
fragmentShader = unrollLoops(fragmentShader);
if (parameters.isWebGL2 && parameters.isRawShaderMaterial != true) {
// GLSL 3.0 conversion for built-in materials and ShaderMaterial
versionString = "#version 300 es\n";
prefixVertex = '${[
'precision mediump sampler2DArray;',
'#define attribute in',
'#define varying out',
'#define texture2D texture'
].join('\n')}\n$prefixVertex';
prefixFragment = '${[
'#define varying in',
(parameters.glslVersion == GLSL3) ? '' : 'layout(location = 0) out highp vec4 pc_fragColor;',
(parameters.glslVersion == GLSL3) ? '' : '#define gl_FragColor pc_fragColor',
'#define gl_FragDepthEXT gl_FragDepth',
'#define texture2D texture',
'#define textureCube texture',
'#define texture2DProj textureProj',
'#define texture2DLodEXT textureLod',
'#define texture2DProjLodEXT textureProjLod',
'#define textureCubeLodEXT textureLod',
'#define texture2DGradEXT textureGrad',
'#define texture2DProjGradEXT textureProjGrad',
'#define textureCubeGradEXT textureGrad'
].join('\n')}\n$prefixFragment';
}
String vertexGlsl = versionString + prefixVertex + vertexShader;
String fragmentGlsl = versionString + prefixFragment + fragmentShader;
// print("---- material ${parameters.shaderName} USE_SKINNING: ${parameters.skinning } ");
// print(" 111 ================= VERTEX ");
// print(vertexGlsl);
// print(" 111 ==================== FRAGMENT ");
// print(fragmentGlsl);
final glVertexShader = WebGLShader(gl, WebGL.VERTEX_SHADER, vertexGlsl);
final glFragmentShader = WebGLShader(gl, WebGL.FRAGMENT_SHADER, fragmentGlsl);
vertexShader = glVertexShader.content;
fragmentShader = glFragmentShader.content;
gl.attachShader(program!, glVertexShader.shader);
gl.attachShader(program!, glFragmentShader.shader);
// Force a particular attribute to index 0.
if (parameters.index0AttributeName != null) {
gl.bindAttribLocation(program!, 0, parameters.index0AttributeName ?? '');
} else if (parameters.morphTargets == true) {
// programs with morphTargets displace position out of attribute 0
gl.bindAttribLocation(program!, 0, 'position');
}
// final _b = gl.isProgram(this.program);
gl.linkProgram(program!);
// check for link errors
if (renderer.debug["checkShaderErrors"]) {
final programLog = gl.getProgramInfoLog(program!)?.trim();
final vertexLog = gl.getShaderInfoLog(glVertexShader.shader)?.trim();
final fragmentLog = gl.getShaderInfoLog(glFragmentShader.shader)?.trim();
bool runnable = true;
bool haveDiagnostics = true;
if (gl.getProgramParameter(program!, WebGL.LINK_STATUS).id == 0) {
runnable = false;
final vertexErrors = getShaderErrors(gl, glVertexShader, 'vertex');
final fragmentErrors = getShaderErrors(gl, glFragmentShader, 'fragment');
console.error('WebGLProgram: shader error: ${gl.getError()} gl.VALIDATE_STATUS ${gl.getProgramParameter(program!, WebGL.VALIDATE_STATUS)} gl.getProgramInfoLog $programLog $vertexErrors $fragmentErrors ');
} else if (programLog != '' && programLog != null) {
console.error('WebGLProgram: gl.getProgramInfoLog() programLog: $programLog vertexLog: $vertexLog fragmentLog: $fragmentLog ');
} else if (vertexLog == '' || fragmentLog == '') {
haveDiagnostics = false;
}
if (haveDiagnostics) {
diagnostics = {
"runnable": runnable,
"programLog": programLog,
"vertexShader": {"log": vertexLog, "prefix": prefixVertex},
"fragmentShader": {"log": fragmentLog, "prefix": prefixFragment}
};
}
}
// Clean up
// Crashes in iOS9 and iOS10. #18402
// gl.detachShader( program, glVertexShader );
// gl.detachShader( program, glFragmentShader );
gl.deleteShader(glVertexShader.shader);
gl.deleteShader(glFragmentShader.shader);
// set up caching for uniform locations
}