getProgram method

WebGLProgram? getProgram(
  1. Material material,
  2. Object3D? scene,
  3. Object3D object
)

Implementation

WebGLProgram? getProgram(Material material, Object3D? scene, Object3D object) {
  if (scene is! Scene) scene = _emptyScene;
  // scene could be a Mesh, Line, Points, ...

  final materialProperties = properties.get(material);

  final lights = currentRenderState!.state.lights;
  final shadowsArray = currentRenderState!.state.shadowsArray;

  final lightsStateVersion = lights.state.version;

  final parameters = programCache.getParameters(material, lights.state, shadowsArray, scene, object);
  final programCacheKey = programCache.getProgramCacheKey(parameters);

  Map? programs = materialProperties["programs"];

  // always update environment and fog - changing these trigger an getProgram call, but it's possible that the program doesn't change
  materialProperties["environment"] = material is MeshStandardMaterial ? scene.environment : null;
  materialProperties["fog"] = scene.fog;
		materialProperties['envMap'] = ( material is MeshStandardMaterial ? cubeuvmaps.get( material.envMap ?? materialProperties['environment'] ) : cubemaps.get( material.envMap ?? materialProperties['environment'] ) );
		materialProperties['envMapRotation'] = ( materialProperties['environment'] != null && material.envMap == null ) ? scene.environmentRotation : material.envMapRotation;

  if (programs == null) {
    material.addEventListener('dispose', onMaterialDispose);
    programs = {};
    materialProperties["programs"] = programs;
  }

  WebGLProgram? program = programs[programCacheKey];

  if (program != null) {
    // early out if program and light state is identical
    if (materialProperties["currentProgram"] == program && materialProperties["lightsStateVersion"] == lightsStateVersion) {
      updateCommonMaterialProperties(material, parameters);
      return program;
    }
  }
  else {
    parameters.uniforms = programCache.getUniforms(material);

    //material.onBuild(parameters, this);
    material.onBeforeCompile?.call(parameters, this);
    program = programCache.acquireProgram(parameters, programCacheKey);
    programs[programCacheKey] = program;

    materialProperties["uniforms"] = parameters.uniforms;
  }

  Map<String, dynamic> uniforms = materialProperties["uniforms"];

  if ((material is! ShaderMaterial && material is! RawShaderMaterial) || material.clipping == true) {
    uniforms["clippingPlanes"] = clipping.uniform;
  }

  updateCommonMaterialProperties(material, parameters);

  // store the light setup it was created for

  materialProperties["needsLights"] = materialNeedsLights(material);
  materialProperties["lightsStateVersion"] = lightsStateVersion;

  if (materialProperties["needsLights"] == true) {
    // wire up the material to this renderer's lighting state

    uniforms["ambientLightColor"]["value"] = lights.state.ambient;
    uniforms["lightProbe"]["value"] = lights.state.probe;
    uniforms["directionalLights"]["value"] = lights.state.directional;
    uniforms["directionalLightShadows"]["value"] = lights.state.directionalShadow;
    uniforms["spotLights"]["value"] = lights.state.spot;
    uniforms["spotLightShadows"]["value"] = lights.state.spotShadow;
    uniforms["rectAreaLights"]["value"] = lights.state.rectArea;
    uniforms["ltc_1"]["value"] = lights.state.rectAreaLTC1;
    uniforms["ltc_2"]["value"] = lights.state.rectAreaLTC2;
    uniforms["pointLights"]["value"] = lights.state.point;
    uniforms["pointLightShadows"]["value"] = lights.state.pointShadow;
    uniforms["hemisphereLights"]["value"] = lights.state.hemi;

    uniforms["directionalShadowMap"]["value"] = lights.state.directionalShadowMap;
    uniforms["directionalShadowMatrix"]["value"] = lights.state.directionalShadowMatrix;
    uniforms["spotShadowMap"]["value"] = lights.state.spotShadowMap;
    uniforms["spotLightMatrix"]["value"] = lights.state.spotLightMatrix;
    uniforms["spotLightMap"]["value"] = lights.state.spotLightMap;
    uniforms["pointShadowMap"]["value"] = lights.state.pointShadowMap;
    uniforms["pointShadowMatrix"]["value"] = lights.state.pointShadowMatrix;
  }

  materialProperties["currentProgram"] = program;
  materialProperties["uniformsList"] = null;

  return program;
}