|
@@ -1,263 +0,0 @@
|
|
-# `CustomShader` Documentation
|
|
|
|
-
|
|
|
|
-**Note**: This README is stored in `ModelExperimental/` temporarily while
|
|
|
|
-this is an experimental feature. In the future, this may move to the
|
|
|
|
-`Documentation/` directory.
|
|
|
|
-
|
|
|
|
-## Constructor
|
|
|
|
-
|
|
|
|
-```js
|
|
|
|
-var customShader = new Cesium.CustomShader({
|
|
|
|
- // Any custom uniforms the user wants to add to the shader.
|
|
|
|
- // these can be changed at runtime via customShader.setUniform()
|
|
|
|
- uniforms: {
|
|
|
|
- u_time: {
|
|
|
|
- value: 0, // initial value
|
|
|
|
- type: Cesium.UniformType.FLOAT
|
|
|
|
- },
|
|
|
|
- // Textures can be loaded from a URL, a Resource, or a TypedArray.
|
|
|
|
- // See the Uniforms section for more detail
|
|
|
|
- u_externalTexture: {
|
|
|
|
- value: new Cesium.TextureUniform({
|
|
|
|
- url: "http://example.com/image.png"
|
|
|
|
- }),
|
|
|
|
- type: Cesium.UniformType.SAMPLER_2D
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // Custom varyings that will appear in the custom vertex and fragment shader
|
|
|
|
- // text.
|
|
|
|
- varyings: {
|
|
|
|
- v_customTexCoords: Cesium.VaryingType.VEC2
|
|
|
|
- },
|
|
|
|
- // configure where in the fragment shader's materials/lighting pipeline the
|
|
|
|
- // custom shader goes. More on this below.
|
|
|
|
- mode: Cesium.CustomShaderMode.MODIFY_MATERIAL,
|
|
|
|
- // either PBR (physically-based rendering) or UNLIT depending on the desired
|
|
|
|
- // results.
|
|
|
|
- lightingModel: Cesium.LightingModel.PBR,
|
|
|
|
- // required when setting material.alpha in the fragment shader
|
|
|
|
- isTranslucent: true,
|
|
|
|
- // Custom vertex shader. This is a function from model space -> model space.
|
|
|
|
- // VertexInput is documented below
|
|
|
|
- vertexShaderText: `
|
|
|
|
- void vertexMain(VertexInput vsInput, inout vec3 position) {
|
|
|
|
- // code goes here. e.g. for a no-op:
|
|
|
|
- return position;
|
|
|
|
- }
|
|
|
|
- `,
|
|
|
|
- // Custom fragment shader.
|
|
|
|
- // FragmentInput will be documented below
|
|
|
|
- // Regardless of the mode, this always takes in a material and modifies it in place.
|
|
|
|
- fragmentShaderText: `
|
|
|
|
- void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
|
|
|
|
- // code goes here. e.g. to set the diffuse color to a translucent red:
|
|
|
|
- material.diffuse = vec3(1.0, 0.0, 0.0);
|
|
|
|
- material.alpha = 0.5;
|
|
|
|
- }
|
|
|
|
- `,
|
|
|
|
-});
|
|
|
|
-```
|
|
|
|
-
|
|
|
|
-## Applying A Custom Shader
|
|
|
|
-
|
|
|
|
-Custom shaders can be applied to either 3D Tiles or `ModelExperimental` as
|
|
|
|
-follows:
|
|
|
|
-
|
|
|
|
-```js
|
|
|
|
-var customShader = new Cesium.CustomShader(/* ... */);
|
|
|
|
-
|
|
|
|
-// Applying to all tiles in a tileset.
|
|
|
|
-var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
|
|
|
|
- url: "http://example.com/tileset.json",
|
|
|
|
- customShader: customShader
|
|
|
|
-}));
|
|
|
|
-
|
|
|
|
-// Applying to a model directly
|
|
|
|
-var model = Cesium.ModelExperimental.fromGltf({,
|
|
|
|
- gltf: "http://example.com/model.gltf",
|
|
|
|
- customShader: customShader
|
|
|
|
-});
|
|
|
|
-```
|
|
|
|
-
|
|
|
|
-**Note**: As of this writing, only tilesets that use the `3DTILES_content_gltf`
|
|
|
|
-extension will support `CustomShaders`. Future releases will add support for
|
|
|
|
-other formats such as B3DM.
|
|
|
|
-
|
|
|
|
-## Uniforms
|
|
|
|
-
|
|
|
|
-Custom Shaders currently supports the following uniform types:
|
|
|
|
-
|
|
|
|
-| UniformType | GLSL type | JS type |
|
|
|
|
-| ------------ | ----------- | ---------------- |
|
|
|
|
-| `FLOAT` | `float` | `Number` |
|
|
|
|
-| `VEC2` | `vec2` | `Cartesian2` |
|
|
|
|
-| `VEC3` | `vec3` | `Cartesian3` |
|
|
|
|
-| `VEC4` | `vec4` | `Cartesian4` |
|
|
|
|
-| `INT` | `int` | `Number` |
|
|
|
|
-| `INT_VEC2` | `ivec2` | `Cartesian2` |
|
|
|
|
-| `INT_VEC3` | `ivec3` | `Cartesian3` |
|
|
|
|
-| `INT_VEC4` | `ivec4` | `Cartesian4` |
|
|
|
|
-| `BOOL` | `bool` | `Boolean` |
|
|
|
|
-| `BOOL_VEC2` | `bvec2` | `Cartesian2` |
|
|
|
|
-| `BOOL_VEC3` | `bvec3` | `Cartesian3` |
|
|
|
|
-| `BOOL_VEC4` | `bvec4` | `Cartesian4` |
|
|
|
|
-| `MAT2` | `mat2` | `Matrix2` |
|
|
|
|
-| `MAT3` | `mat3` | `Matrix3` |
|
|
|
|
-| `MAT4` | `mat4` | `Matrix4` |
|
|
|
|
-| `SAMPLER_2D` | `sampler2D` | `TextureUniform` |
|
|
|
|
-
|
|
|
|
-### Texture Uniforms
|
|
|
|
-
|
|
|
|
-Texture uniforms have more options, which have been encapsulated in the
|
|
|
|
-`TextureUniform` class. Textures can be loaded from a URL, a `Resource` or a
|
|
|
|
-typed array. Here are some examples:
|
|
|
|
-
|
|
|
|
-```js
|
|
|
|
-var textureFromUrl = new Cesium.TextureUniform({
|
|
|
|
- url: "https://example.com/image.png",
|
|
|
|
-});
|
|
|
|
-
|
|
|
|
-var textureFromTypedArray = new Cesium.TextureUniform({
|
|
|
|
- typedArray: new Uint8Array([255, 0, 0, 255]),
|
|
|
|
- width: 1,
|
|
|
|
- height: 1,
|
|
|
|
- pixelFormat: Cesium.PixelFormat.RGBA,
|
|
|
|
- pixelDatatype: Cesium.PixelDatatype.UNSIGNED_BYTE,
|
|
|
|
-});
|
|
|
|
-
|
|
|
|
-// TextureUniform also provides options for controlling the sampler
|
|
|
|
-var textureWithSampler = new Cesium.TextureUniform({
|
|
|
|
- url: "https://example.com/image.png",
|
|
|
|
- repeat: false,
|
|
|
|
- minificationFilter: Cesium.TextureMinificationFilter.NEAREST,
|
|
|
|
- magnificationFilter: Cesium.TextureMagnificationFilter.NEAREST,
|
|
|
|
-});
|
|
|
|
-```
|
|
|
|
-
|
|
|
|
-## Varyings
|
|
|
|
-
|
|
|
|
-Varyings are declared in the `CustomShader` constructor. This automatically
|
|
|
|
-adds a line such as `varying float v_userDefinedVarying;` to the top of the
|
|
|
|
-GLSL shader.
|
|
|
|
-
|
|
|
|
-The user is responsible for assigning a value to this varying in
|
|
|
|
-`vertexShaderText` and using it in `fragmentShaderText`. For example:
|
|
|
|
-
|
|
|
|
-```js
|
|
|
|
-var customShader = new Cesium.CustomShader({
|
|
|
|
- // Varying is declared here
|
|
|
|
- varyings: {
|
|
|
|
- v_selectedColor: VaryingType.VEC3,
|
|
|
|
- },
|
|
|
|
- // User assigns the varying in the vertex shader
|
|
|
|
- vertexShaderText: `
|
|
|
|
- void vertexMain(VertexInput vsInput, inout vec3 position) {
|
|
|
|
- float positiveX = step(0.0, position.x);
|
|
|
|
- v_selectedColor = mix(
|
|
|
|
- vsInput.attributes.color_0,
|
|
|
|
- vsInput.attributes.color_1,
|
|
|
|
- position.x
|
|
|
|
- );
|
|
|
|
- return position;
|
|
|
|
- }
|
|
|
|
- `,
|
|
|
|
- // User uses the varying in the fragment shader
|
|
|
|
- fragmentShaderText: `
|
|
|
|
- void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
|
|
|
|
- material.diffuse = v_selectedColor;
|
|
|
|
- }
|
|
|
|
- `,
|
|
|
|
-});
|
|
|
|
-```
|
|
|
|
-
|
|
|
|
-Custom Shaders supports the following varying types:
|
|
|
|
-
|
|
|
|
-| VaryingType | GLSL type |
|
|
|
|
-| ----------- | --------- |
|
|
|
|
-| `FLOAT` | `float` |
|
|
|
|
-| `VEC2` | `vec2` |
|
|
|
|
-| `VEC3` | `vec3` |
|
|
|
|
-| `VEC4` | `vec4` |
|
|
|
|
-| `MAT2` | `mat2` |
|
|
|
|
-| `MAT3` | `mat3` |
|
|
|
|
-| `MAT4` | `mat4` |
|
|
|
|
-
|
|
|
|
-## Custom Shader Modes
|
|
|
|
-
|
|
|
|
-The custom fragment shader is configurable so it can go before/after materials or lighting. here's a summary of what
|
|
|
|
-modes are available.
|
|
|
|
-
|
|
|
|
-| Mode | Fragment shader pipeline | Description |
|
|
|
|
-| --------------------------- | ------------------------------------- | -------------------------------------------------------------------------------------- |
|
|
|
|
-| `MODIFY_MATERIAL` (default) | material -> custom shader -> lighting | The custom shader modifies the results of the material stage |
|
|
|
|
-| `REPLACE_MATERIAL` | custom shader -> lighting | Don't run the material stage at all, but procedurally generate it in the custom shader |
|
|
|
|
-
|
|
|
|
-In the above, "material" does preprocessing of textures, resulting in a `czm_modelMaterial`. This is mostly relevant for PBR, but even for UNLIT, the base color texture is handled.
|
|
|
|
-
|
|
|
|
-## `VertexInput` struct
|
|
|
|
-
|
|
|
|
-An automatically-generated GLSL struct that contains attributes.
|
|
|
|
-
|
|
|
|
-```glsl
|
|
|
|
-// this struct represents the raw attribute values.
|
|
|
|
-struct Attributes {
|
|
|
|
- // required semantics
|
|
|
|
- vec3 position; // model space position. Always present.
|
|
|
|
-
|
|
|
|
- // optional semantics (added if available in the 3D model file)
|
|
|
|
- vec3 normal; // corresponds to attribute with semantic "NORMAL"
|
|
|
|
- vec3 tangent;
|
|
|
|
- vec2 texCoord_0;
|
|
|
|
- // etc.
|
|
|
|
-
|
|
|
|
- // custom attribues
|
|
|
|
- vec3 custom_attribute; // corresponds to attribute "_CUSTOM_ATTRIBUTE"
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct VertexInput {
|
|
|
|
- // raw attribute values
|
|
|
|
- Attributes attributes;
|
|
|
|
- // in the future we may add another struct for derived attributes (e.g. positionEC)
|
|
|
|
-};
|
|
|
|
-```
|
|
|
|
-
|
|
|
|
-## `FragmentInput` struct
|
|
|
|
-
|
|
|
|
-This struct is similar to `VertexInput`, but there are a few more automatic
|
|
|
|
-variables for positions in various coordinate spaces.
|
|
|
|
-
|
|
|
|
-```glsl
|
|
|
|
-// this struct represents the raw attributes from the 3D model file. The
|
|
|
|
-// varyings required to make this work are handled automatically.
|
|
|
|
-struct Attributes {
|
|
|
|
- // required semantics
|
|
|
|
- vec3 position; // Raw model space position. always present as POSITION is required
|
|
|
|
-
|
|
|
|
- // optional semantics (added if available in the 3D model file)
|
|
|
|
- vec3 normal; // corresponds to attribute with semantic "NORMAL"
|
|
|
|
- vec3 tangent;
|
|
|
|
- vec2 texCoord_0;
|
|
|
|
- // etc.
|
|
|
|
-
|
|
|
|
- // custom attribues
|
|
|
|
- vec3 custom_attribute; // corresponds to attribute "_CUSTOM_ATTRIBUTE"
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct FragmentInput {
|
|
|
|
- // raw attribute values interpolated (but not normalized) from varyings.
|
|
|
|
- Attributes attributes;
|
|
|
|
- vec3 positionMC; // model space
|
|
|
|
- vec3 positionWC; // World coords (ECEF). Low precision.
|
|
|
|
- vec3 positionEC; // Eye coordinates
|
|
|
|
-};
|
|
|
|
-```
|
|
|
|
-
|
|
|
|
-## `czm_modelMaterial` struct
|
|
|
|
-
|
|
|
|
-This one is a built-in, see the [documentation comment](https://github.com/CesiumGS/cesium/blob/model-experimental-custom-shaders/Source/Shaders/Builtin/Structs/modelMaterial.glsl). This is similar to `czm_material` from the old Fabric system, but slightly different fields as this one supports PBR lighting.
|
|
|
|
-
|
|
|
|
-This struct serves as the basic input/output of the fragment shader pipeline stages. For example:
|
|
|
|
-
|
|
|
|
-- the material stage produces a material
|
|
|
|
-- the lighting stage takes in a material, computes lighting, and stores the result into `material.diffuse`
|
|
|
|
-- Custom shaders (regardless of where in the pipeline it is) takes in a material (even if it's a material with default values) and modifies this.
|
|
|