Explorar el Código

Improve MeshPhysicalMaterial transmission support (#21884)

* Imptove MeshPhysicalMaterial transmission support

* Add webgl_loader_gltf_transmission example

* Update webgl_materials_physical_transmission screenshot

* Dispose transmissionRenderTarget in WebGLRenderer.dispose()

* Remove _transmissionSamplerMap from MeshPhysicalMaterial

* Fix transmissionMap

* Remove unnecessary sRGB-Linear conversion from transmission shader

* Improve transmission shaders

* Add more parameters to webgl_materials_physical_transmission example

* Update screenshot
Takahiro hace 4 años
padre
commit
bbe6f1ee0a
Se han modificado 36 ficheros con 2068 adiciones y 50 borrados
  1. 1 0
      examples/files.json
  2. 14 0
      examples/models/gltf/TransmissionTest/README.md
  3. 1628 0
      examples/models/gltf/TransmissionTest/glTF/TransmissionTest.gltf
  4. BIN
      examples/models/gltf/TransmissionTest/glTF/TransmissionTest_binary.bin
  5. BIN
      examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture10487.png
  6. BIN
      examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture14184.jpg
  7. BIN
      examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture15366.jpg
  8. BIN
      examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture175763.png
  9. BIN
      examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture177328.png
  10. BIN
      examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture214190.png
  11. BIN
      examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture28577.jpg
  12. BIN
      examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture4086.png
  13. BIN
      examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture6807.png
  14. BIN
      examples/models/gltf/TransmissionTest/screenshot/screenshot.jpg
  15. BIN
      examples/models/gltf/TransmissionTest/screenshot/screenshot_large.png
  16. BIN
      examples/screenshots/webgl_loader_gltf_transmission.jpg
  17. BIN
      examples/screenshots/webgl_materials_physical_transmission.jpg
  18. 113 0
      examples/webgl_loader_gltf_transmission.html
  19. 35 9
      examples/webgl_materials_physical_transmission.html
  20. 5 1
      src/loaders/MaterialLoader.js
  21. 7 0
      src/materials/Material.js
  22. 16 1
      src/materials/MeshPhysicalMaterial.js
  23. 45 2
      src/renderers/WebGLRenderer.js
  24. 4 4
      src/renderers/shaders/ShaderChunk.js
  25. 34 0
      src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js
  26. 87 0
      src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js
  27. 0 7
      src/renderers/shaders/ShaderChunk/transmissionmap_fragment.glsl.js
  28. 0 7
      src/renderers/shaders/ShaderChunk/transmissionmap_pars_fragment.glsl.js
  29. 1 1
      src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl.js
  30. 6 0
      src/renderers/shaders/ShaderLib.js
  31. 8 10
      src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js
  32. 11 0
      src/renderers/shaders/ShaderLib/meshphysical_vert.glsl.js
  33. 22 3
      src/renderers/webgl/WebGLMaterials.js
  34. 4 0
      src/renderers/webgl/WebGLProgram.js
  35. 5 3
      src/renderers/webgl/WebGLPrograms.js
  36. 22 2
      src/renderers/webgl/WebGLRenderLists.js

+ 1 - 0
examples/files.json

@@ -86,6 +86,7 @@
 		"webgl_loader_gltf",
 		"webgl_loader_gltf",
 		"webgl_loader_gltf_compressed",
 		"webgl_loader_gltf_compressed",
 		"webgl_loader_gltf_extensions",
 		"webgl_loader_gltf_extensions",
+		"webgl_loader_gltf_transmission",
 		"webgl_loader_gltf_variants",
 		"webgl_loader_gltf_variants",
 		"webgl_loader_ifc",
 		"webgl_loader_ifc",
 		"webgl_loader_imagebitmap",
 		"webgl_loader_imagebitmap",

+ 14 - 0
examples/models/gltf/TransmissionTest/README.md

@@ -0,0 +1,14 @@
+# Transmission Test
+
+## Screenshot
+
+![screenshot](screenshot/screenshot_large.png)
+
+## Description
+
+This model demonstrates the usage of the `KHR_materials_transmission`. The grid of spheres demonstrate different combinations of uniform transmission and textured transmission and how they should render in conjunction with opacity (`baseColor.a`) and surface roughness/metalicity.
+
+## License Information
+
+[![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png)](http://creativecommons.org/publicdomain/zero/1.0/)  
+To the extent possible under law, Adobe has waived all copyright and related or neighboring rights to this asset.

+ 1628 - 0
examples/models/gltf/TransmissionTest/glTF/TransmissionTest.gltf

@@ -0,0 +1,1628 @@
+{
+    "asset": {
+        "copyright": "2020 (c) Adobe Inc.",
+        "generator": "Adobe Dimension - 63f6e07d31a7b4abc83cb799813e511e9e5587a5",
+        "version": "2.0",
+        "extensions": {
+            "KHR_xmp": {
+                "packet": 0
+            }
+        }
+    },
+    "accessors": [
+        {
+            "bufferView": 0,
+            "componentType": 5126,
+            "count": 22202,
+            "type": "VEC3",
+            "max": [
+                0.9809443354606628,
+                1.0221298933029175,
+                1.4283748865127564
+            ],
+            "min": [
+                -0.8216659426689148,
+                0.0015843699220567942,
+                -0.46063709259033205
+            ]
+        },
+        {
+            "bufferView": 1,
+            "componentType": 5126,
+            "count": 22202,
+            "type": "VEC3"
+        },
+        {
+            "bufferView": 2,
+            "componentType": 5126,
+            "count": 22202,
+            "type": "VEC2"
+        },
+        {
+            "bufferView": 3,
+            "componentType": 5125,
+            "count": 131337,
+            "type": "SCALAR",
+            "max": [
+                22201
+            ],
+            "min": [
+                0
+            ]
+        },
+        {
+            "bufferView": 4,
+            "componentType": 5126,
+            "count": 3719,
+            "type": "VEC3",
+            "max": [
+                0.09999999403953552,
+                0.19999998807907105,
+                0.10000000894069672
+            ],
+            "min": [
+                -0.1000000387430191,
+                0.0,
+                -0.1000000536441803
+            ]
+        },
+        {
+            "bufferView": 5,
+            "componentType": 5126,
+            "count": 3719,
+            "type": "VEC3"
+        },
+        {
+            "bufferView": 6,
+            "componentType": 5126,
+            "count": 3719,
+            "type": "VEC2"
+        },
+        {
+            "bufferView": 7,
+            "componentType": 5125,
+            "count": 21240,
+            "type": "SCALAR",
+            "max": [
+                3718
+            ],
+            "min": [
+                0
+            ]
+        },
+        {
+            "bufferView": 8,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC3",
+            "max": [
+                0.8968609571456909,
+                0.20853587985038758,
+                3.397480696776256e-8
+            ],
+            "min": [
+                -0.9147982001304627,
+                -0.20853577554225923,
+                -0.010000113397836686
+            ]
+        },
+        {
+            "bufferView": 9,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC3"
+        },
+        {
+            "bufferView": 10,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC2"
+        },
+        {
+            "bufferView": 11,
+            "componentType": 5125,
+            "count": 12,
+            "type": "SCALAR",
+            "max": [
+                7
+            ],
+            "min": [
+                0
+            ]
+        },
+        {
+            "bufferView": 12,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC3",
+            "max": [
+                2.0,
+                0.21764808893203736,
+                3.545937232729557e-8
+            ],
+            "min": [
+                -2.0,
+                -0.21764802932739259,
+                -0.01000013668090105
+            ]
+        },
+        {
+            "bufferView": 13,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC3"
+        },
+        {
+            "bufferView": 14,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC2"
+        },
+        {
+            "bufferView": 15,
+            "componentType": 5125,
+            "count": 12,
+            "type": "SCALAR",
+            "max": [
+                7
+            ],
+            "min": [
+                0
+            ]
+        },
+        {
+            "bufferView": 16,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC3",
+            "max": [
+                1.0280373096466065,
+                0.23501670360565186,
+                3.8289083903464419e-8
+            ],
+            "min": [
+                -0.9682242274284363,
+                -0.2350165843963623,
+                -0.01000012457370758
+            ]
+        },
+        {
+            "bufferView": 17,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC3"
+        },
+        {
+            "bufferView": 18,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC2"
+        },
+        {
+            "bufferView": 19,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC3",
+            "max": [
+                2.0,
+                0.23026323318481446,
+                3.751463495405005e-8
+            ],
+            "min": [
+                -2.0,
+                -0.23026317358016969,
+                -0.010000579059123993
+            ]
+        },
+        {
+            "bufferView": 20,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC3"
+        },
+        {
+            "bufferView": 21,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC2"
+        },
+        {
+            "bufferView": 22,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC3",
+            "max": [
+                2.0,
+                0.22341907024383546,
+                3.6399587344249088e-8
+            ],
+            "min": [
+                -2.0,
+                -0.22341907024383546,
+                -0.009999859146773816
+            ]
+        },
+        {
+            "bufferView": 23,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC3"
+        },
+        {
+            "bufferView": 24,
+            "componentType": 5126,
+            "count": 8,
+            "type": "VEC2"
+        }
+    ],
+    "bufferViews": [
+        {
+            "buffer": 0,
+            "byteOffset": 0,
+            "byteLength": 266424,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 266424,
+            "byteLength": 266424,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 532848,
+            "byteLength": 177616,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 710464,
+            "byteLength": 525348,
+            "target": 34963
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1235812,
+            "byteLength": 44628,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1280440,
+            "byteLength": 44628,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1325068,
+            "byteLength": 29752,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1354820,
+            "byteLength": 84960,
+            "target": 34963
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1439780,
+            "byteLength": 96,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1439876,
+            "byteLength": 96,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1439972,
+            "byteLength": 64,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440036,
+            "byteLength": 48,
+            "target": 34963
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440084,
+            "byteLength": 96,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440180,
+            "byteLength": 96,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440276,
+            "byteLength": 64,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440340,
+            "byteLength": 48,
+            "target": 34963
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440388,
+            "byteLength": 96,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440484,
+            "byteLength": 96,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440580,
+            "byteLength": 64,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440644,
+            "byteLength": 96,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440740,
+            "byteLength": 96,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440836,
+            "byteLength": 64,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440900,
+            "byteLength": 96,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1440996,
+            "byteLength": 96,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 1441092,
+            "byteLength": 64,
+            "target": 34962
+        }
+    ],
+    "buffers": [
+        {
+            "byteLength": 1441156,
+            "uri": "TransmissionTest_binary.bin"
+        }
+    ],
+    "cameras": [
+        {
+            "perspective": {
+                "znear": 0.00005606882768915966,
+                "yfov": 0.6024156808853149,
+                "zfar": 3.0837855339050295,
+                "aspectRatio": 1.3333333730697632
+            },
+            "type": "perspective",
+            "name": "render_camera"
+        }
+    ],
+    "images": [
+        {
+            "name": "texture28577",
+            "uri": "TransmissionTest_images/texture28577.jpg",
+            "mimeType": "image/jpeg"
+        },
+        {
+            "name": "texture14184",
+            "uri": "TransmissionTest_images/texture14184.jpg",
+            "mimeType": "image/jpeg"
+        },
+        {
+            "name": "texture214190",
+            "uri": "TransmissionTest_images/texture214190.png",
+            "mimeType": "image/png"
+        },
+        {
+            "name": "texture4086",
+            "uri": "TransmissionTest_images/texture4086.png",
+            "mimeType": "image/png"
+        },
+        {
+            "name": "texture177328",
+            "uri": "TransmissionTest_images/texture177328.png",
+            "mimeType": "image/png"
+        },
+        {
+            "name": "texture6807",
+            "uri": "TransmissionTest_images/texture6807.png",
+            "mimeType": "image/png"
+        },
+        {
+            "name": "texture175763",
+            "uri": "TransmissionTest_images/texture175763.png",
+            "mimeType": "image/png"
+        },
+        {
+            "name": "texture10487",
+            "uri": "TransmissionTest_images/texture10487.png",
+            "mimeType": "image/png"
+        },
+        {
+            "name": "texture15366",
+            "uri": "TransmissionTest_images/texture15366.jpg",
+            "mimeType": "image/jpeg"
+        }
+    ],
+    "materials": [
+        {
+            "pbrMetallicRoughness": {
+                "baseColorTexture": {
+                    "index": 0
+                },
+                "metallicFactor": 0.0,
+                "roughnessFactor": 0.4934999942779541
+            },
+            "name": "Cloth Backdrop"
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.9559729695320129,
+                    0.17788879573345185,
+                    0.09530720859766007,
+                    1.0
+                ],
+                "metallicFactor": 0.0,
+                "roughnessFactor": 0.0
+            },
+            "name": "RedTransTexture",
+            "doubleSided": true,
+            "extensions": {
+                "KHR_materials_transmission": {
+                    "transmissionFactor": 1,
+                    "transmissionTexture": {
+                        "index": 1
+                    }
+                }
+            }
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.8468738198280335,
+                    0.8713662624359131,
+                    0.09305903315544129,
+                    1.0
+                ],
+                "metallicFactor": 0.0,
+                "roughnessFactor": 0.0
+            },
+            "name": "YellowTrans",
+            "doubleSided": true,
+            "extensions": {
+                "KHR_materials_transmission": {
+                    "transmissionFactor": 1
+                }
+            }
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.08650036156177521,
+                    0.46207714080810549,
+                    0.8468738198280335,
+                    1.0
+                ],
+                "baseColorTexture": {
+                    "index": 2
+                },
+                "metallicFactor": 0.0,
+                "roughnessFactor": 0.0
+            },
+            "alphaMode": "MASK",
+            "name": "BlueTransWithMask",
+            "doubleSided": true,
+            "extensions": {
+                "KHR_materials_transmission": {
+                    "transmissionFactor": 1,
+                    "transmissionTexture": {
+                        "index": 1
+                    }
+                }
+            }
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.1499594897031784,
+                    0.83077073097229,
+                    0.19120188057422639,
+                    1.0
+                ],
+                "baseColorTexture": {
+                    "index": 3
+                },
+                "metallicFactor": 0.0,
+                "roughnessFactor": 0.0
+            },
+            "alphaMode": "MASK",
+            "name": "GreenMask",
+            "doubleSided": true,
+            "extensions": {
+                "KHR_materials_transmission": {
+                    "transmissionFactor": 1
+                }
+            }
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.9559729695320129,
+                    0.17788879573345185,
+                    0.09530720859766007,
+                    1.0
+                ],
+                "metallicFactor": 0.0,
+                "metallicRoughnessTexture": {
+                    "index": 4
+                }
+            },
+            "name": "RedTransTextureRough",
+            "doubleSided": true,
+            "extensions": {
+                "KHR_materials_transmission": {
+                    "transmissionFactor": 1,
+                    "transmissionTexture": {
+                        "index": 1
+                    }
+                }
+            }
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.8468738198280335,
+                    0.8713662624359131,
+                    0.09305903315544129,
+                    1.0
+                ],
+                "metallicFactor": 0.0,
+                "metallicRoughnessTexture": {
+                    "index": 5
+                }
+            },
+            "name": "YellowTransRough",
+            "doubleSided": true,
+            "extensions": {
+                "KHR_materials_transmission": {
+                    "transmissionFactor": 1
+                }
+            }
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.08650036156177521,
+                    0.46207714080810549,
+                    0.8468738198280335,
+                    1.0
+                ],
+                "baseColorTexture": {
+                    "index": 2
+                },
+                "metallicFactor": 0.0,
+                "metallicRoughnessTexture": {
+                    "index": 4
+                }
+            },
+            "alphaMode": "MASK",
+            "name": "BlueTransWithMask",
+            "doubleSided": true,
+            "extensions": {
+                "KHR_materials_transmission": {
+                    "transmissionFactor": 1,
+                    "transmissionTexture": {
+                        "index": 1
+                    }
+                }
+            }
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.1499594897031784,
+                    0.83077073097229,
+                    0.19120188057422639,
+                    1.0
+                ],
+                "baseColorTexture": {
+                    "index": 3
+                },
+                "metallicFactor": 0.0,
+                "roughnessFactor": 0.3199999928474426
+            },
+            "alphaMode": "MASK",
+            "name": "GreenMaskRough",
+            "doubleSided": true,
+            "extensions": {
+                "KHR_materials_transmission": {
+                    "transmissionFactor": 1
+                }
+            }
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.9559729695320129,
+                    0.17788879573345185,
+                    0.09530720859766007,
+                    1.0
+                ],
+                "roughnessFactor": 0.0,
+                "metallicRoughnessTexture": {
+                    "index": 6
+                }
+            },
+            "name": "RedTransTextureMetal",
+            "doubleSided": true,
+            "extensions": {
+                "KHR_materials_transmission": {
+                    "transmissionFactor": 1,
+                    "transmissionTexture": {
+                        "index": 1
+                    }
+                }
+            }
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.8468738198280335,
+                    0.8713662624359131,
+                    0.09305903315544129,
+                    1.0
+                ],
+                "roughnessFactor": 0.0,
+                "metallicRoughnessTexture": {
+                    "index": 7
+                }
+            },
+            "name": "YellowTransMetal",
+            "doubleSided": true,
+            "extensions": {
+                "KHR_materials_transmission": {
+                    "transmissionFactor": 1
+                }
+            }
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.1499594897031784,
+                    0.83077073097229,
+                    0.19120188057422639,
+                    1.0
+                ],
+                "baseColorTexture": {
+                    "index": 3
+                },
+                "roughnessFactor": 0.0,
+                "metallicRoughnessTexture": {
+                    "index": 6
+                }
+            },
+            "alphaMode": "MASK",
+            "name": "GreenMaskMetal",
+            "doubleSided": true,
+            "extensions": {
+                "KHR_materials_transmission": {
+                    "transmissionFactor": 1
+                }
+            }
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.08650036156177521,
+                    0.46207714080810549,
+                    0.8468738198280335,
+                    1.0
+                ],
+                "baseColorTexture": {
+                    "index": 2
+                },
+                "roughnessFactor": 0.0,
+                "metallicRoughnessTexture": {
+                    "index": 6
+                }
+            },
+            "alphaMode": "MASK",
+            "name": "BlueTransWithMask",
+            "doubleSided": true,
+            "extensions": {
+                "KHR_materials_transmission": {
+                    "transmissionFactor": 1,
+                    "transmissionTexture": {
+                        "index": 1
+                    }
+                }
+            }
+        },
+        {
+            "pbrMetallicRoughness": {
+                "baseColorFactor": [
+                    0.0,
+                    0.0,
+                    0.0,
+                    1.0
+                ],
+                "metallicFactor": 0.0,
+                "roughnessFactor": 0.8999999761581421
+            },
+            "emissiveTexture": {
+                "index": 8
+            },
+            "emissiveFactor": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "name": "LabelMaterial"
+        }
+    ],
+    "meshes": [
+        {
+            "name": "Cloth Backdrop 01",
+            "primitives": [
+                {
+                    "attributes": {
+                        "TEXCOORD_0": 2,
+                        "NORMAL": 1,
+                        "POSITION": 0
+                    },
+                    "indices": 3,
+                    "material": 0
+                }
+            ]
+        },
+        {
+            "name": "Sphere",
+            "primitives": [
+                {
+                    "attributes": {
+                        "POSITION": 4,
+                        "NORMAL": 5,
+                        "TEXCOORD_0": 6
+                    },
+                    "indices": 7,
+                    "material": 1
+                }
+            ]
+        },
+        {
+            "name": "Sphere",
+            "primitives": [
+                {
+                    "attributes": {
+                        "TEXCOORD_0": 6,
+                        "NORMAL": 5,
+                        "POSITION": 4
+                    },
+                    "indices": 7,
+                    "material": 2
+                }
+            ]
+        },
+        {
+            "name": "Sphere",
+            "primitives": [
+                {
+                    "attributes": {
+                        "TEXCOORD_0": 6,
+                        "NORMAL": 5,
+                        "POSITION": 4
+                    },
+                    "indices": 7,
+                    "material": 3
+                }
+            ]
+        },
+        {
+            "name": "Sphere",
+            "primitives": [
+                {
+                    "attributes": {
+                        "POSITION": 4,
+                        "NORMAL": 5,
+                        "TEXCOORD_0": 6
+                    },
+                    "indices": 7,
+                    "material": 4
+                }
+            ]
+        },
+        {
+            "name": "Sphere",
+            "primitives": [
+                {
+                    "attributes": {
+                        "POSITION": 4,
+                        "NORMAL": 5,
+                        "TEXCOORD_0": 6
+                    },
+                    "indices": 7,
+                    "material": 5
+                }
+            ]
+        },
+        {
+            "name": "Sphere",
+            "primitives": [
+                {
+                    "attributes": {
+                        "POSITION": 4,
+                        "NORMAL": 5,
+                        "TEXCOORD_0": 6
+                    },
+                    "indices": 7,
+                    "material": 6
+                }
+            ]
+        },
+        {
+            "name": "Sphere",
+            "primitives": [
+                {
+                    "attributes": {
+                        "POSITION": 4,
+                        "NORMAL": 5,
+                        "TEXCOORD_0": 6
+                    },
+                    "indices": 7,
+                    "material": 7
+                }
+            ]
+        },
+        {
+            "name": "Sphere",
+            "primitives": [
+                {
+                    "attributes": {
+                        "TEXCOORD_0": 6,
+                        "NORMAL": 5,
+                        "POSITION": 4
+                    },
+                    "indices": 7,
+                    "material": 8
+                }
+            ]
+        },
+        {
+            "name": "Sphere",
+            "primitives": [
+                {
+                    "attributes": {
+                        "TEXCOORD_0": 6,
+                        "NORMAL": 5,
+                        "POSITION": 4
+                    },
+                    "indices": 7,
+                    "material": 9
+                }
+            ]
+        },
+        {
+            "name": "Sphere",
+            "primitives": [
+                {
+                    "attributes": {
+                        "TEXCOORD_0": 6,
+                        "NORMAL": 5,
+                        "POSITION": 4
+                    },
+                    "indices": 7,
+                    "material": 10
+                }
+            ]
+        },
+        {
+            "name": "Sphere",
+            "primitives": [
+                {
+                    "attributes": {
+                        "TEXCOORD_0": 6,
+                        "NORMAL": 5,
+                        "POSITION": 4
+                    },
+                    "indices": 7,
+                    "material": 11
+                }
+            ]
+        },
+        {
+            "name": "Sphere",
+            "primitives": [
+                {
+                    "attributes": {
+                        "TEXCOORD_0": 6,
+                        "NORMAL": 5,
+                        "POSITION": 4
+                    },
+                    "indices": 7,
+                    "material": 12
+                }
+            ]
+        },
+        {
+            "name": "X1_Label_Coated",
+            "primitives": [
+                {
+                    "attributes": {
+                        "TEXCOORD_0": 10,
+                        "NORMAL": 9,
+                        "POSITION": 8
+                    },
+                    "indices": 11,
+                    "material": 13
+                }
+            ]
+        },
+        {
+            "name": "Y3_Label_BaseNormals",
+            "primitives": [
+                {
+                    "attributes": {
+                        "TEXCOORD_0": 14,
+                        "NORMAL": 13,
+                        "POSITION": 12
+                    },
+                    "indices": 15,
+                    "material": 13
+                }
+            ]
+        },
+        {
+            "name": "X1_Label_Coated",
+            "primitives": [
+                {
+                    "attributes": {
+                        "TEXCOORD_0": 10,
+                        "NORMAL": 9,
+                        "POSITION": 8
+                    },
+                    "indices": 11,
+                    "material": 13
+                }
+            ]
+        },
+        {
+            "name": "Y3_Label_BaseNormals",
+            "primitives": [
+                {
+                    "attributes": {
+                        "POSITION": 12,
+                        "NORMAL": 13,
+                        "TEXCOORD_0": 14
+                    },
+                    "indices": 15,
+                    "material": 13
+                }
+            ]
+        },
+        {
+            "name": "X2_Label_CoatingOnly",
+            "primitives": [
+                {
+                    "attributes": {
+                        "POSITION": 16,
+                        "NORMAL": 17,
+                        "TEXCOORD_0": 18
+                    },
+                    "indices": 11,
+                    "material": 13
+                }
+            ]
+        },
+        {
+            "name": "X2_Label_CoatingOnly",
+            "primitives": [
+                {
+                    "attributes": {
+                        "POSITION": 16,
+                        "NORMAL": 17,
+                        "TEXCOORD_0": 18
+                    },
+                    "indices": 11,
+                    "material": 13
+                }
+            ]
+        },
+        {
+            "name": "Y0_Label_SimpleCoating",
+            "primitives": [
+                {
+                    "attributes": {
+                        "POSITION": 19,
+                        "NORMAL": 20,
+                        "TEXCOORD_0": 21
+                    },
+                    "indices": 11,
+                    "material": 13
+                }
+            ]
+        },
+        {
+            "name": "Y5_Label_SharedNormals",
+            "primitives": [
+                {
+                    "attributes": {
+                        "POSITION": 22,
+                        "NORMAL": 23,
+                        "TEXCOORD_0": 24
+                    },
+                    "indices": 15,
+                    "material": 13
+                }
+            ]
+        },
+        {
+            "name": "X2_Label_CoatingOnly",
+            "primitives": [
+                {
+                    "attributes": {
+                        "POSITION": 16,
+                        "NORMAL": 17,
+                        "TEXCOORD_0": 18
+                    },
+                    "indices": 11,
+                    "material": 13
+                }
+            ]
+        }
+    ],
+    "nodes": [
+        {
+            "translation": [
+                -0.07675539702177048,
+                0.3394200801849365,
+                1.802846074104309
+            ],
+            "rotation": [
+                -0.07035518437623978,
+                0.01940322108566761,
+                0.0013688141480088235,
+                0.9973323345184326
+            ],
+            "scale": [
+                1.0,
+                1.0000001192092896,
+                0.9999999403953552
+            ],
+            "camera": 0,
+            "name": "render_camera_n3d"
+        },
+        {
+            "translation": [
+                -0.15470129251480103,
+                -0.4015843868255615,
+                -0.06036872789263725
+            ],
+            "mesh": 0,
+            "name": "Cloth Backdrop 01"
+        },
+        {
+            "translation": [
+                0.10135379433631897,
+                0.1326718032360077,
+                0.01683981902897358
+            ],
+            "rotation": [
+                0.0,
+                0.9996573328971863,
+                0.0,
+                0.026176994666457177
+            ],
+            "mesh": 1,
+            "name": "RedTransTexture"
+        },
+        {
+            "translation": [
+                -0.36709079146385195,
+                0.1261221021413803,
+                -0.01051957905292511
+            ],
+            "rotation": [
+                0.0,
+                0.9996573328971863,
+                0.0,
+                0.026176994666457177
+            ],
+            "mesh": 2,
+            "name": "YellowTrans"
+        },
+        {
+            "translation": [
+                0.33557596802711489,
+                0.13594670593738557,
+                0.030519530177116395
+            ],
+            "rotation": [
+                0.0,
+                0.9996573328971863,
+                0.0,
+                0.026176994666457177
+            ],
+            "mesh": 3,
+            "name": "BlueTransWithMask"
+        },
+        {
+            "translation": [
+                -0.13286849856376649,
+                0.12939700484275819,
+                0.003160127904266119
+            ],
+            "rotation": [
+                0.0,
+                0.9996573328971863,
+                0.0,
+                0.026176994666457177
+            ],
+            "mesh": 4,
+            "name": "GreenMask"
+        },
+        {
+            "translation": [
+                0.10135379433631897,
+                -0.09345020353794098,
+                0.01683981902897358
+            ],
+            "rotation": [
+                0.0,
+                0.9996573328971863,
+                0.0,
+                0.026176994666457177
+            ],
+            "mesh": 5,
+            "name": "RedTransTextureRough"
+        },
+        {
+            "translation": [
+                -0.36709079146385195,
+                -0.09999999403953552,
+                -0.01051957905292511
+            ],
+            "rotation": [
+                0.0,
+                0.9996573328971863,
+                0.0,
+                0.026176994666457177
+            ],
+            "mesh": 6,
+            "name": "YellowTransRough"
+        },
+        {
+            "translation": [
+                0.33557596802711489,
+                -0.09017530083656311,
+                0.030519530177116395
+            ],
+            "rotation": [
+                0.0,
+                0.9996573328971863,
+                0.0,
+                0.026176994666457177
+            ],
+            "mesh": 7,
+            "name": "BlueTransWithMask"
+        },
+        {
+            "translation": [
+                -0.13286849856376649,
+                -0.09672509878873825,
+                0.003160127904266119
+            ],
+            "rotation": [
+                0.0,
+                0.9996573328971863,
+                0.0,
+                0.026176994666457177
+            ],
+            "mesh": 8,
+            "name": "GreenMaskRough"
+        },
+        {
+            "translation": [
+                0.10135379433631897,
+                -0.32746508717536929,
+                0.01683981902897358
+            ],
+            "rotation": [
+                0.0,
+                0.9996573328971863,
+                0.0,
+                0.026176994666457177
+            ],
+            "mesh": 9,
+            "name": "RedTransTextureMetal"
+        },
+        {
+            "translation": [
+                -0.36709079146385195,
+                -0.334014892578125,
+                -0.01051957905292511
+            ],
+            "rotation": [
+                0.0,
+                0.9996573328971863,
+                0.0,
+                0.026176994666457177
+            ],
+            "mesh": 10,
+            "name": "YellowTransMetal"
+        },
+        {
+            "translation": [
+                -0.13286849856376649,
+                -0.3307400047779083,
+                0.003160127904266119
+            ],
+            "rotation": [
+                0.0,
+                0.9996573328971863,
+                0.0,
+                0.026176994666457177
+            ],
+            "mesh": 11,
+            "name": "GreenMaskMetal"
+        },
+        {
+            "translation": [
+                0.33557596802711489,
+                -0.3241901993751526,
+                0.030519530177116395
+            ],
+            "rotation": [
+                0.0,
+                0.9996573328971863,
+                0.0,
+                0.026176994666457177
+            ],
+            "mesh": 12,
+            "name": "BlueTransWithMask"
+        },
+        {
+            "children": [
+                15,
+                16,
+                17,
+                18,
+                19,
+                20
+            ],
+            "name": "Column Labels"
+        },
+        {
+            "translation": [
+                -0.15605439245700837,
+                0.4127219021320343,
+                -0.03671092912554741
+            ],
+            "rotation": [
+                -0.00009458513522986323,
+                -4.074816573051976e-8,
+                0.00003576850940589793,
+                1.0
+            ],
+            "scale": [
+                0.08348584175109863,
+                0.1557399034500122,
+                0.1557399034500122
+            ],
+            "mesh": 13,
+            "name": "X1_Label_WithOpacity"
+        },
+        {
+            "translation": [
+                0.362414687871933,
+                0.4796152114868164,
+                -0.03672285005450249
+            ],
+            "rotation": [
+                -0.00009458522981731221,
+                -5.835058658476555e-8,
+                0.00003573128196876496,
+                1.0
+            ],
+            "scale": [
+                0.06954946368932724,
+                0.1557399034500122,
+                0.1557399034500122
+            ],
+            "mesh": 14,
+            "name": "Y3_Label_TransmissionTexture"
+        },
+        {
+            "translation": [
+                0.36164841055870058,
+                0.4127587676048279,
+                -0.03671097755432129
+            ],
+            "rotation": [
+                -0.00009458513522986323,
+                -4.47990515795027e-8,
+                0.000035770794056588787,
+                1.0
+            ],
+            "scale": [
+                0.07980477809906006,
+                0.1557399034500122,
+                0.1557399034500122
+            ],
+            "mesh": 15,
+            "name": "X1_Label_WithOpacity"
+        },
+        {
+            "translation": [
+                0.10603449493646622,
+                0.4796152114868164,
+                -0.03672285005450249
+            ],
+            "rotation": [
+                -0.00009458520071348175,
+                -6.512453154527975e-8,
+                0.0000357320714101661,
+                1.0
+            ],
+            "scale": [
+                0.06535045057535172,
+                0.1557399034500122,
+                0.1557399034500122
+            ],
+            "mesh": 16,
+            "name": "Y3_Label_TransmissionTexture"
+        },
+        {
+            "translation": [
+                -0.3994385004043579,
+                0.47961509227752688,
+                -0.03672334924340248
+            ],
+            "rotation": [
+                -0.00009458516433369368,
+                -2.7568585636572608e-8,
+                0.000035779212339548397,
+                1.0
+            ],
+            "scale": [
+                0.09822454303503037,
+                0.1557399034500122,
+                0.1557399034500122
+            ],
+            "mesh": 17,
+            "name": "X2_Label_Transmission"
+        },
+        {
+            "translation": [
+                -0.16186389327049256,
+                0.4796149730682373,
+                -0.03672334924340248
+            ],
+            "rotation": [
+                -0.00009458513522986323,
+                -2.909321139554777e-8,
+                0.00003578040923457593,
+                1.0
+            ],
+            "scale": [
+                0.09625838696956635,
+                0.1557399034500122,
+                0.1557399034500122
+            ],
+            "mesh": 18,
+            "name": "X2_Label_Transmission"
+        },
+        {
+            "children": [
+                22,
+                23,
+                24
+            ],
+            "translation": [
+                -2.265920877456665,
+                1.0377169847488404,
+                -0.036828286945819858
+            ],
+            "rotation": [
+                -0.00009458513522986323,
+                -1.497378067892574e-14,
+                0.00003578418181859888,
+                1.0
+            ],
+            "scale": [
+                0.1557399034500122,
+                0.1557399034500122,
+                0.1557399034500122
+            ],
+            "name": "Row Labels"
+        },
+        {
+            "translation": [
+                10.043020248413086,
+                -8.2355375289917,
+                -0.000007152556463552173
+            ],
+            "rotation": [
+                -2.1582695700073097e-11,
+                -3.345704513435521e-8,
+                -3.844720097845311e-8,
+                1.0
+            ],
+            "scale": [
+                0.5845792293548584,
+                1.0,
+                1.0
+            ],
+            "mesh": 19,
+            "name": "Y0_Label_MetallicTransmission"
+        },
+        {
+            "translation": [
+                10.137709617614746,
+                -6.663864612579346,
+                -0.000002937316821771674
+            ],
+            "rotation": [
+                -1.4305411022430548e-11,
+                -4.159385724733511e-8,
+                -4.7792596546969438e-8,
+                1.0
+            ],
+            "scale": [
+                0.530937910079956,
+                1.0,
+                1.0
+            ],
+            "mesh": 20,
+            "name": "Y5_Label_RoughTransmission"
+        },
+        {
+            "translation": [
+                10.396340370178223,
+                -5.149285316467285,
+                -0.0000057220458984375
+            ],
+            "rotation": [
+                -2.8860731512980743e-11,
+                -1.6422601945009775e-8,
+                -1.886485456736864e-8,
+                1.0
+            ],
+            "scale": [
+                0.741389811038971,
+                1.0,
+                1.0
+            ],
+            "mesh": 21,
+            "name": "X2_Label_Transmission"
+        }
+    ],
+    "samplers": [
+        {},
+        {},
+        {},
+        {},
+        {},
+        {},
+        {},
+        {},
+        {}
+    ],
+    "scenes": [
+        {
+            "nodes": [
+                0,
+                1,
+                2,
+                3,
+                4,
+                5,
+                6,
+                7,
+                8,
+                9,
+                10,
+                11,
+                12,
+                13,
+                14,
+                21
+            ],
+            "name": "scene"
+        }
+    ],
+    "textures": [
+        {
+            "name": "texture28577",
+            "sampler": 0,
+            "source": 0
+        },
+        {
+            "name": "texture14184",
+            "sampler": 1,
+            "source": 1
+        },
+        {
+            "name": "texture214190",
+            "sampler": 2,
+            "source": 2
+        },
+        {
+            "name": "texture4086",
+            "sampler": 3,
+            "source": 3
+        },
+        {
+            "name": "texture177328",
+            "sampler": 4,
+            "source": 4
+        },
+        {
+            "name": "texture6807",
+            "sampler": 5,
+            "source": 5
+        },
+        {
+            "name": "texture175763",
+            "sampler": 6,
+            "source": 6
+        },
+        {
+            "name": "texture10487",
+            "sampler": 7,
+            "source": 7
+        },
+        {
+            "name": "texture15366",
+            "sampler": 8,
+            "source": 8
+        }
+    ],
+    "scene": 0,
+    "extensions": {
+        "KHR_xmp": {
+            "@context": {
+                "dc": "http://purl.org/dc/elements/1.1/"
+            },
+            "packets": [
+                {
+                    "dc:date": "2019-10-25T15:25:01.695-07:00",
+                    "dc:title": "ASM_transparency_labels.dn",
+                    "xmp:CreatorTool": "Adobe Dimension"
+                }
+            ]
+        }
+    },
+    "extensionsUsed": [
+        "KHR_materials_transmission",
+        "KHR_xmp"
+    ]
+}

BIN
examples/models/gltf/TransmissionTest/glTF/TransmissionTest_binary.bin


BIN
examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture10487.png


BIN
examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture14184.jpg


BIN
examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture15366.jpg


BIN
examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture175763.png


BIN
examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture177328.png


BIN
examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture214190.png


BIN
examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture28577.jpg


BIN
examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture4086.png


BIN
examples/models/gltf/TransmissionTest/glTF/TransmissionTest_images/texture6807.png


BIN
examples/models/gltf/TransmissionTest/screenshot/screenshot.jpg


BIN
examples/models/gltf/TransmissionTest/screenshot/screenshot_large.png


BIN
examples/screenshots/webgl_loader_gltf_transmission.jpg


BIN
examples/screenshots/webgl_materials_physical_transmission.jpg


+ 113 - 0
examples/webgl_loader_gltf_transmission.html

@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - glTF loader</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<link type="text/css" rel="stylesheet" href="main.css">
+	</head>
+
+	<body>
+		<div id="info">
+			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - GLTFLoader + <a href="https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission" target="_blank" rel="noopener">KHR_materials_transmission</a> extension<br />
+			<a href="https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/TransmissionTest" target="_blank" rel="noopener">Transmission Test</a> by
+			<a href="https://www.adobe.com/" target="_blank" rel="noopener">Adobe, Inc</a><br />
+			<a href="https://hdrihaven.com/hdri/?h=quarry_01" target="_blank" rel="noopener">Quarry</a> by <a href="https://hdrihaven.com/" target="_blank" rel="noopener">HDRI Haven</a>
+		</div>
+
+		<script type="module">
+
+			import * as THREE from '../build/three.module.js';
+
+			import { OrbitControls } from './jsm/controls/OrbitControls.js';
+			import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
+			import { RGBELoader } from './jsm/loaders/RGBELoader.js';
+			import { RoughnessMipmapper } from './jsm/utils/RoughnessMipmapper.js';
+
+			let camera, scene, renderer;
+
+			init();
+			render();
+
+			function init() {
+
+				const container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
+				camera.position.set( 0, 0, 2.0 );
+
+				scene = new THREE.Scene();
+
+				new RGBELoader()
+					.setDataType( THREE.UnsignedByteType )
+					.setPath( 'textures/equirectangular/' )
+					.load( 'quarry_01_1k.hdr', function ( texture ) {
+
+						const envMap = pmremGenerator.fromEquirectangular( texture ).texture;
+
+						scene.background = envMap;
+						scene.environment = envMap;
+
+						texture.dispose();
+						pmremGenerator.dispose();
+
+						render();
+
+					// model
+
+					const loader = new GLTFLoader().setPath( 'models/gltf/TransmissionTest/glTF/' );
+					loader.load( 'TransmissionTest.gltf', function ( gltf ) {
+
+						scene.add( gltf.scene );
+						render();
+
+					} );
+
+				} );
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.toneMapping = THREE.ACESFilmicToneMapping;
+				renderer.toneMappingExposure = 1;
+				renderer.outputEncoding = THREE.sRGBEncoding;
+				container.appendChild( renderer.domElement );
+
+				const pmremGenerator = new THREE.PMREMGenerator( renderer );
+				pmremGenerator.compileEquirectangularShader();
+
+				const controls = new OrbitControls( camera, renderer.domElement );
+				controls.addEventListener( 'change', render ); // use if there is no animation loop
+				controls.minDistance = 1;
+				controls.maxDistance = 10;
+				controls.target.set( 0, 0.0, - 0.2 );
+				controls.update();
+
+				window.addEventListener( 'resize', onWindowResize );
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+				render();
+
+			}
+
+			//
+
+			function render() {
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 35 - 9
examples/webgl_materials_physical_transmission.html

@@ -23,7 +23,10 @@
 
 
 			const params = {
 			const params = {
 				color: 0xffffff,
 				color: 0xffffff,
-				transmission: 0.90,
+				transmission: 1,
+				opacity: 1,
+				metalness: 0,
+				roughness: 0,
 				envMapIntensity: 1,
 				envMapIntensity: 1,
 				lightIntensity: 1,
 				lightIntensity: 1,
 				exposure: 1
 				exposure: 1
@@ -88,15 +91,14 @@
 
 
 				const material = new THREE.MeshPhysicalMaterial( {
 				const material = new THREE.MeshPhysicalMaterial( {
 					color: params.color,
 					color: params.color,
-					metalness: 0,
-					roughness: 0,
+					metalness: params.metalness,
+					roughness: params.roughness,
 					alphaMap: texture,
 					alphaMap: texture,
-					alphaTest: 0.5,
 					envMap: hdrCubeRenderTarget.texture,
 					envMap: hdrCubeRenderTarget.texture,
 					envMapIntensity: params.envMapIntensity,
 					envMapIntensity: params.envMapIntensity,
 					depthWrite: false,
 					depthWrite: false,
 					transmission: params.transmission, // use material.transmission for glass materials
 					transmission: params.transmission, // use material.transmission for glass materials
-					opacity: 1, // set material.opacity to 1 when material.transmission is non-zero
+					opacity: params.opacity,
 					transparent: true
 					transparent: true
 				} );
 				} );
 
 
@@ -165,7 +167,7 @@
 
 
 					} );
 					} );
 
 
-				gui.add( params, 'transmission', 0, 1 )
+				gui.add( params, 'transmission', 0, 1, 0.01 )
 					.onChange( function () {
 					.onChange( function () {
 
 
 						material1.transmission = material2.transmission = params.transmission;
 						material1.transmission = material2.transmission = params.transmission;
@@ -173,7 +175,31 @@
 
 
 					} );
 					} );
 
 
-				gui.add( params, 'envMapIntensity', 0, 1 )
+				gui.add( params, 'opacity', 0, 1, 0.01 )
+					.onChange( function () {
+
+						material1.opacity = material2.opacity = params.opacity;
+						material1b.opacity = material2b.opacity = params.opacity;
+
+					} );
+
+				gui.add( params, 'metalness', 0, 1, 0.01 )
+					.onChange( function () {
+
+						material1.metalness = material2.metalness = params.metalness;
+						material1b.metalness = material2b.metalness = params.metalness;
+
+					} );
+
+				gui.add( params, 'roughness', 0, 1, 0.01 )
+					.onChange( function () {
+
+						material1.roughness = material2.roughness = params.roughness;
+						material1b.roughness = material2b.roughness = params.roughness;
+
+					} );
+
+				gui.add( params, 'envMapIntensity', 0, 1, 0.01 )
 					.name( 'envMap intensity' )
 					.name( 'envMap intensity' )
 					.onChange( function () {
 					.onChange( function () {
 
 
@@ -182,7 +208,7 @@
 
 
 					} );
 					} );
 
 
-				gui.add( params, 'lightIntensity', 0, 1 )
+				gui.add( params, 'lightIntensity', 0, 1, 0.01 )
 					.name( 'light intensity' )
 					.name( 'light intensity' )
 					.onChange( function () {
 					.onChange( function () {
 
 
@@ -190,7 +216,7 @@
 
 
 					} );
 					} );
 
 
-				gui.add( params, 'exposure', 0, 1 )
+				gui.add( params, 'exposure', 0, 1, 0.01 )
 					.onChange( function () {
 					.onChange( function () {
 
 
 						renderer.toneMappingExposure = params.exposure;
 						renderer.toneMappingExposure = params.exposure;

+ 5 - 1
src/loaders/MaterialLoader.js

@@ -80,6 +80,10 @@ class MaterialLoader extends Loader {
 		if ( json.shininess !== undefined ) material.shininess = json.shininess;
 		if ( json.shininess !== undefined ) material.shininess = json.shininess;
 		if ( json.clearcoat !== undefined ) material.clearcoat = json.clearcoat;
 		if ( json.clearcoat !== undefined ) material.clearcoat = json.clearcoat;
 		if ( json.clearcoatRoughness !== undefined ) material.clearcoatRoughness = json.clearcoatRoughness;
 		if ( json.clearcoatRoughness !== undefined ) material.clearcoatRoughness = json.clearcoatRoughness;
+		if ( json.transmission !== undefined ) material.transmission = json.transmission;
+		if ( json.thickness !== undefined ) material.thickness = json.thickness;
+		if ( json.attenuationDistance !== undefined ) material.attenuationDistance = json.attenuationDistance;
+		if ( json.attenuationColor !== undefined && material.attenuationColor !== undefined ) material.attenuationColor.setHex( json.attenuationColor );
 		if ( json.fog !== undefined ) material.fog = json.fog;
 		if ( json.fog !== undefined ) material.fog = json.fog;
 		if ( json.flatShading !== undefined ) material.flatShading = json.flatShading;
 		if ( json.flatShading !== undefined ) material.flatShading = json.flatShading;
 		if ( json.blending !== undefined ) material.blending = json.blending;
 		if ( json.blending !== undefined ) material.blending = json.blending;
@@ -278,8 +282,8 @@ class MaterialLoader extends Loader {
 		if ( json.clearcoatNormalMap !== undefined ) material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap );
 		if ( json.clearcoatNormalMap !== undefined ) material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap );
 		if ( json.clearcoatNormalScale !== undefined ) material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale );
 		if ( json.clearcoatNormalScale !== undefined ) material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale );
 
 
-		if ( json.transmission !== undefined ) material.transmission = json.transmission;
 		if ( json.transmissionMap !== undefined ) material.transmissionMap = getTexture( json.transmissionMap );
 		if ( json.transmissionMap !== undefined ) material.transmissionMap = getTexture( json.transmissionMap );
+		if ( json.thicknessMap !== undefined ) material.thicknessMap = getTexture( json.thicknessMap );
 
 
 		return material;
 		return material;
 
 

+ 7 - 0
src/materials/Material.js

@@ -262,6 +262,13 @@ class Material extends EventDispatcher {
 
 
 		}
 		}
 
 
+		if ( this.transmission !== undefined ) data.transmission = this.transmission;
+		if ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid;
+		if ( this.thickness !== undefined ) data.thickness = this.thickness;
+		if ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid;
+		if ( this.attenuationDistance !== undefined ) data.attenuationDistance = this.attenuationDistance;
+		if ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex();
+
 		if ( this.size !== undefined ) data.size = this.size;
 		if ( this.size !== undefined ) data.size = this.size;
 		if ( this.shadowSide !== null ) data.shadowSide = this.shadowSide;
 		if ( this.shadowSide !== null ) data.shadowSide = this.shadowSide;
 		if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
 		if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;

+ 16 - 1
src/materials/MeshPhysicalMaterial.js

@@ -18,7 +18,12 @@ import * as MathUtils from '../math/MathUtils.js';
  *  sheen: <Color>,
  *  sheen: <Color>,
  *
  *
  *  transmission: <float>,
  *  transmission: <float>,
- *  transmissionMap: new THREE.Texture( <Image> )
+ *  transmissionMap: new THREE.Texture( <Image> ),
+ *
+ *  thickness: <float>,
+ *  thicknessMap: new THREE.Texture( <Image> ),
+ *  attenuationDistance: <float>,
+ *  attenuationColor: <Color>
  * }
  * }
  */
  */
 
 
@@ -64,6 +69,11 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
 		this.transmission = 0.0;
 		this.transmission = 0.0;
 		this.transmissionMap = null;
 		this.transmissionMap = null;
 
 
+		this.thickness = 0.01;
+		this.thicknessMap = null;
+		this.attenuationDistance = 0.0;
+		this.attenuationColor = new Color( 1, 1, 1 );
+
 		this.setValues( parameters );
 		this.setValues( parameters );
 
 
 	}
 	}
@@ -101,6 +111,11 @@ class MeshPhysicalMaterial extends MeshStandardMaterial {
 		this.transmission = source.transmission;
 		this.transmission = source.transmission;
 		this.transmissionMap = source.transmissionMap;
 		this.transmissionMap = source.transmissionMap;
 
 
+		this.thickness = source.thickness;
+		this.thicknessMap = source.thicknessMap;
+		this.attenuationDistance = source.attenuationDistance;
+		this.attenuationColor.copy( source.attenuationColor );
+
 		return this;
 		return this;
 
 
 	}
 	}

+ 45 - 2
src/renderers/WebGLRenderer.js

@@ -4,7 +4,10 @@ import {
 	FloatType,
 	FloatType,
 	UnsignedByteType,
 	UnsignedByteType,
 	LinearEncoding,
 	LinearEncoding,
-	NoToneMapping
+	NoToneMapping,
+	LinearMipmapLinearFilter,
+	NearestFilter,
+	ClampToEdgeWrapping
 } from '../constants.js';
 } from '../constants.js';
 import { Frustum } from '../math/Frustum.js';
 import { Frustum } from '../math/Frustum.js';
 import { Matrix4 } from '../math/Matrix4.js';
 import { Matrix4 } from '../math/Matrix4.js';
@@ -30,6 +33,7 @@ import { WebGLPrograms } from './webgl/WebGLPrograms.js';
 import { WebGLProperties } from './webgl/WebGLProperties.js';
 import { WebGLProperties } from './webgl/WebGLProperties.js';
 import { WebGLRenderLists } from './webgl/WebGLRenderLists.js';
 import { WebGLRenderLists } from './webgl/WebGLRenderLists.js';
 import { WebGLRenderStates } from './webgl/WebGLRenderStates.js';
 import { WebGLRenderStates } from './webgl/WebGLRenderStates.js';
+import { WebGLRenderTarget } from './WebGLRenderTarget.js';
 import { WebGLShadowMap } from './webgl/WebGLShadowMap.js';
 import { WebGLShadowMap } from './webgl/WebGLShadowMap.js';
 import { WebGLState } from './webgl/WebGLState.js';
 import { WebGLState } from './webgl/WebGLState.js';
 import { WebGLTextures } from './webgl/WebGLTextures.js';
 import { WebGLTextures } from './webgl/WebGLTextures.js';
@@ -160,6 +164,11 @@ function WebGLRenderer( parameters ) {
 	let _clippingEnabled = false;
 	let _clippingEnabled = false;
 	let _localClippingEnabled = false;
 	let _localClippingEnabled = false;
 
 
+	// transmission
+
+	let _transmissionRenderTarget = null;
+	const _transmissionSamplerSize = new Vector2( 1024, 1024 ); // Should be configurable?
+
 	// camera matrices cache
 	// camera matrices cache
 
 
 	const _projScreenMatrix = new Matrix4();
 	const _projScreenMatrix = new Matrix4();
@@ -596,6 +605,13 @@ function WebGLRenderer( parameters ) {
 		xr.removeEventListener( 'sessionstart', onXRSessionStart );
 		xr.removeEventListener( 'sessionstart', onXRSessionStart );
 		xr.removeEventListener( 'sessionend', onXRSessionEnd );
 		xr.removeEventListener( 'sessionend', onXRSessionEnd );
 
 
+		if ( _transmissionRenderTarget ) {
+
+			_transmissionRenderTarget.dispose();
+			_transmissionRenderTarget = null;
+
+		}
+
 		animation.stop();
 		animation.stop();
 
 
 	};
 	};
@@ -1058,9 +1074,11 @@ function WebGLRenderer( parameters ) {
 		// render scene
 		// render scene
 
 
 		const opaqueObjects = currentRenderList.opaque;
 		const opaqueObjects = currentRenderList.opaque;
+		const transmissiveObjects = currentRenderList.transmissive;
 		const transparentObjects = currentRenderList.transparent;
 		const transparentObjects = currentRenderList.transparent;
 
 
 		if ( opaqueObjects.length > 0 ) renderObjects( opaqueObjects, scene, camera );
 		if ( opaqueObjects.length > 0 ) renderObjects( opaqueObjects, scene, camera );
+		if ( transmissiveObjects.length > 0 ) renderTransmissiveObjects( opaqueObjects, transmissiveObjects, scene, camera );
 		if ( transparentObjects.length > 0 ) renderObjects( transparentObjects, scene, camera );
 		if ( transparentObjects.length > 0 ) renderObjects( transparentObjects, scene, camera );
 
 
 		//
 		//
@@ -1246,6 +1264,31 @@ function WebGLRenderer( parameters ) {
 
 
 	}
 	}
 
 
+	function renderTransmissiveObjects( opaqueObjects, transmissiveObjects, scene, camera ) {
+
+		if ( _transmissionRenderTarget === null ) {
+
+			_transmissionRenderTarget = new WebGLRenderTarget( _transmissionSamplerSize.x, _transmissionSamplerSize.y, {
+				generateMipmaps: true,
+				minFilter: LinearMipmapLinearFilter,
+				magFilter: NearestFilter,
+				wrapS: ClampToEdgeWrapping,
+				wrapT: ClampToEdgeWrapping
+			} );
+
+		}
+
+		const currentRenderTarget = _this.getRenderTarget();
+		_this.setRenderTarget( _transmissionRenderTarget );
+		_this.clear();
+		renderObjects( opaqueObjects, scene, camera );
+		textures.updateRenderTargetMipmap( _transmissionRenderTarget );
+		_this.setRenderTarget( currentRenderTarget );
+
+		renderObjects( transmissiveObjects, scene, camera );
+
+	}
+
 	function renderObjects( renderList, scene, camera ) {
 	function renderObjects( renderList, scene, camera ) {
 
 
 		const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
 		const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
@@ -1699,7 +1742,7 @@ function WebGLRenderer( parameters ) {
 
 
 			}
 			}
 
 
-			materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height );
+			materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget );
 
 
 			WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
 			WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
 
 

+ 4 - 4
src/renderers/shaders/ShaderChunk.js

@@ -86,8 +86,8 @@ import specularmap_fragment from './ShaderChunk/specularmap_fragment.glsl.js';
 import specularmap_pars_fragment from './ShaderChunk/specularmap_pars_fragment.glsl.js';
 import specularmap_pars_fragment from './ShaderChunk/specularmap_pars_fragment.glsl.js';
 import tonemapping_fragment from './ShaderChunk/tonemapping_fragment.glsl.js';
 import tonemapping_fragment from './ShaderChunk/tonemapping_fragment.glsl.js';
 import tonemapping_pars_fragment from './ShaderChunk/tonemapping_pars_fragment.glsl.js';
 import tonemapping_pars_fragment from './ShaderChunk/tonemapping_pars_fragment.glsl.js';
-import transmissionmap_fragment from './ShaderChunk/transmissionmap_fragment.glsl.js';
-import transmissionmap_pars_fragment from './ShaderChunk/transmissionmap_pars_fragment.glsl.js';
+import transmission_fragment from './ShaderChunk/transmission_fragment.glsl.js';
+import transmission_pars_fragment from './ShaderChunk/transmission_pars_fragment.glsl.js';
 import uv_pars_fragment from './ShaderChunk/uv_pars_fragment.glsl.js';
 import uv_pars_fragment from './ShaderChunk/uv_pars_fragment.glsl.js';
 import uv_pars_vertex from './ShaderChunk/uv_pars_vertex.glsl.js';
 import uv_pars_vertex from './ShaderChunk/uv_pars_vertex.glsl.js';
 import uv_vertex from './ShaderChunk/uv_vertex.glsl.js';
 import uv_vertex from './ShaderChunk/uv_vertex.glsl.js';
@@ -218,8 +218,8 @@ export const ShaderChunk = {
 	specularmap_pars_fragment: specularmap_pars_fragment,
 	specularmap_pars_fragment: specularmap_pars_fragment,
 	tonemapping_fragment: tonemapping_fragment,
 	tonemapping_fragment: tonemapping_fragment,
 	tonemapping_pars_fragment: tonemapping_pars_fragment,
 	tonemapping_pars_fragment: tonemapping_pars_fragment,
-	transmissionmap_fragment: transmissionmap_fragment,
-	transmissionmap_pars_fragment: transmissionmap_pars_fragment,
+	transmission_fragment: transmission_fragment,
+	transmission_pars_fragment: transmission_pars_fragment,
 	uv_pars_fragment: uv_pars_fragment,
 	uv_pars_fragment: uv_pars_fragment,
 	uv_pars_vertex: uv_pars_vertex,
 	uv_pars_vertex: uv_pars_vertex,
 	uv_vertex: uv_vertex,
 	uv_vertex: uv_vertex,

+ 34 - 0
src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js

@@ -0,0 +1,34 @@
+export default /* glsl */`
+#ifdef USE_TRANSMISSION
+
+	#ifdef USE_TRANSMISSIONMAP
+
+		totalTransmission *= texture2D( transmissionMap, vUv ).r;
+
+	#endif
+
+	#ifdef USE_THICKNESSNMAP
+
+		thicknessFactor *= texture2D( thicknessMap, vUv ).g;
+
+	#endif
+
+	vec3 pos = vWorldPosition.xyz / vWorldPosition.w;
+	vec3 v = normalize( cameraPosition - pos );
+	vec3 viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );
+	vec3 n = normalize( vNormal );
+	float ior = ( 1.0 + 0.4 * reflectivity ) / ( 1.0 - 0.4 * reflectivity );
+
+	// From https://google.github.io/filament/Filament.html#materialsystem/parameterization/remapping
+	vec3 f0 = vec3( pow( ior - 1.0, 2.0 ) / pow( ior + 1.0, 2.0 ) );
+	vec3 f90 = vec3( 1.0 );
+
+	vec3 f_transmission = totalTransmission * getIBLVolumeRefraction(
+		n, v, viewDir, roughnessFactor, diffuseColor.rgb, f0, f90,
+		pos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,
+		attenuationColor, attenuationDistance);
+
+	diffuseColor.rgb = mix( diffuseColor.rgb, f_transmission, totalTransmission );
+
+#endif
+`;

+ 87 - 0
src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js

@@ -0,0 +1,87 @@
+export default /* glsl */`
+#ifdef USE_TRANSMISSION
+
+	// Transmission code is based on glTF-Sampler-Viewer
+	// https://github.com/KhronosGroup/glTF-Sample-Viewer
+
+	#ifdef USE_TRANSMISSIONMAP
+
+		uniform sampler2D transmissionMap;
+
+	#endif
+
+	#ifdef USE_THICKNESSMAP
+
+		uniform sampler2D thicknessMap;
+
+	#endif
+
+	uniform vec2 transmissionSamplerSize;
+	uniform sampler2D transmissionSamplerMap;
+
+	uniform mat4 modelMatrix;
+	uniform mat4 projectionMatrix;
+
+	varying vec4 vWorldPosition;
+
+	vec3 getVolumeTransmissionRay(vec3 n, vec3 v, float thickness, float ior, mat4 modelMatrix) {
+		// Direction of refracted light.
+		vec3 refractionVector = refract(-v, normalize(n), 1.0 / ior);
+
+		// Compute rotation-independant scaling of the model matrix.
+		vec3 modelScale;
+		modelScale.x = length(vec3(modelMatrix[0].xyz));
+		modelScale.y = length(vec3(modelMatrix[1].xyz));
+		modelScale.z = length(vec3(modelMatrix[2].xyz));
+
+		// The thickness is specified in local space.
+		return normalize(refractionVector) * thickness * modelScale;
+	}
+
+	float applyIorToRoughness(float roughness, float ior) {
+		// Scale roughness with IOR so that an IOR of 1.0 results in no microfacet refraction and
+		// an IOR of 1.5 results in the default amount of microfacet refraction.
+		return roughness * clamp(ior * 2.0 - 2.0, 0.0, 1.0);
+	}
+
+	vec3 getTransmissionSample(vec2 fragCoord, float roughness, float ior) {
+		float framebufferLod = log2(transmissionSamplerSize.x) * applyIorToRoughness(roughness, ior);
+		return textureLod(transmissionSamplerMap, fragCoord.xy, framebufferLod).rgb;
+	}
+
+	vec3 applyVolumeAttenuation(vec3 radiance, float transmissionDistance, vec3 attenuationColor, float attenuationDistance) {
+		if (attenuationDistance == 0.0) {
+			// Attenuation distance is +∞ (which we indicate by zero), i.e. the transmitted color is not attenuated at all.
+			return radiance;
+		} else {
+			// Compute light attenuation using Beer's law.
+			vec3 attenuationCoefficient = -log(attenuationColor) / attenuationDistance;
+			vec3 transmittance = exp(-attenuationCoefficient * transmissionDistance); // Beer's law
+			return transmittance * radiance;
+		}
+	}
+
+	vec3 getIBLVolumeRefraction(vec3 n, vec3 v, vec3 viewDir, float perceptualRoughness, vec3 baseColor, vec3 f0, vec3 f90,
+		vec3 position, mat4 modelMatrix, mat4 viewMatrix, mat4 projMatrix, float ior, float thickness, vec3 attenuationColor, float attenuationDistance) {
+		vec3 transmissionRay = getVolumeTransmissionRay(n, v, thickness, ior, modelMatrix);
+		vec3 refractedRayExit = position + transmissionRay;
+
+		// Project refracted vector on the framebuffer, while mapping to normalized device coordinates.
+		vec4 ndcPos = projMatrix * viewMatrix * vec4(refractedRayExit, 1.0);
+		vec2 refractionCoords = ndcPos.xy / ndcPos.w;
+		refractionCoords += 1.0;
+		refractionCoords /= 2.0;
+
+		// Sample framebuffer to get pixel the refracted ray hits.
+		vec3 transmittedLight = getTransmissionSample(refractionCoords, perceptualRoughness, ior);
+
+		vec3 attenuatedColor = applyVolumeAttenuation(transmittedLight, length(transmissionRay), attenuationColor, attenuationDistance);
+
+		float NdotV = saturate(dot(n, viewDir));
+		vec2 brdf = integrateSpecularBRDF(NdotV, perceptualRoughness);
+		vec3 specularColor = f0 * brdf.x + f90 * brdf.y;
+
+		return (1.0 - specularColor) * attenuatedColor * baseColor;
+	}
+#endif
+`;

+ 0 - 7
src/renderers/shaders/ShaderChunk/transmissionmap_fragment.glsl.js

@@ -1,7 +0,0 @@
-export default /* glsl */`
-#ifdef USE_TRANSMISSIONMAP
-
-	totalTransmission *= texture2D( transmissionMap, vUv ).r;
-
-#endif
-`;

+ 0 - 7
src/renderers/shaders/ShaderChunk/transmissionmap_pars_fragment.glsl.js

@@ -1,7 +0,0 @@
-export default /* glsl */`
-#ifdef USE_TRANSMISSIONMAP
-
-	uniform sampler2D transmissionMap;
-
-#endif
-`;

+ 1 - 1
src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl.js

@@ -1,5 +1,5 @@
 export default /* glsl */`
 export default /* glsl */`
-#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )
+#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )
 
 
 	vec4 worldPosition = vec4( transformed, 1.0 );
 	vec4 worldPosition = vec4( transformed, 1.0 );
 
 

+ 6 - 0
src/renderers/shaders/ShaderLib.js

@@ -299,6 +299,12 @@ ShaderLib.physical = {
 			sheen: { value: new Color( 0x000000 ) },
 			sheen: { value: new Color( 0x000000 ) },
 			transmission: { value: 0 },
 			transmission: { value: 0 },
 			transmissionMap: { value: null },
 			transmissionMap: { value: null },
+			transmissionSamplerSize: { value: new Vector2() },
+			transmissionSamplerMap: { value: null },
+			thickness: { value: 0 },
+			thicknessMap: { value: null },
+			attenuationDistance: { value: 0 },
+			attenuationColor: { value: new Color( 0x000000 ) }
 		}
 		}
 	] ),
 	] ),
 
 

+ 8 - 10
src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js

@@ -4,7 +4,6 @@ export default /* glsl */`
 #ifdef PHYSICAL
 #ifdef PHYSICAL
 	#define REFLECTIVITY
 	#define REFLECTIVITY
 	#define CLEARCOAT
 	#define CLEARCOAT
-	#define TRANSMISSION
 #endif
 #endif
 
 
 uniform vec3 diffuse;
 uniform vec3 diffuse;
@@ -13,8 +12,11 @@ uniform float roughness;
 uniform float metalness;
 uniform float metalness;
 uniform float opacity;
 uniform float opacity;
 
 
-#ifdef TRANSMISSION
+#ifdef USE_TRANSMISSION
 	uniform float transmission;
 	uniform float transmission;
+	uniform float thickness;
+	uniform vec3 attenuationColor;
+	uniform float attenuationDistance;
 #endif
 #endif
 
 
 #ifdef REFLECTIVITY
 #ifdef REFLECTIVITY
@@ -56,8 +58,8 @@ varying vec3 vViewPosition;
 #include <aomap_pars_fragment>
 #include <aomap_pars_fragment>
 #include <lightmap_pars_fragment>
 #include <lightmap_pars_fragment>
 #include <emissivemap_pars_fragment>
 #include <emissivemap_pars_fragment>
-#include <transmissionmap_pars_fragment>
 #include <bsdfs>
 #include <bsdfs>
+#include <transmission_pars_fragment>
 #include <cube_uv_reflection_fragment>
 #include <cube_uv_reflection_fragment>
 #include <envmap_common_pars_fragment>
 #include <envmap_common_pars_fragment>
 #include <envmap_physical_pars_fragment>
 #include <envmap_physical_pars_fragment>
@@ -81,8 +83,9 @@ void main() {
 	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
 	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
 	vec3 totalEmissiveRadiance = emissive;
 	vec3 totalEmissiveRadiance = emissive;
 
 
-	#ifdef TRANSMISSION
+	#ifdef USE_TRANSMISSION
 		float totalTransmission = transmission;
 		float totalTransmission = transmission;
+		float thicknessFactor = thickness;
 	#endif
 	#endif
 
 
 	#include <logdepthbuf_fragment>
 	#include <logdepthbuf_fragment>
@@ -97,7 +100,7 @@ void main() {
 	#include <clearcoat_normal_fragment_begin>
 	#include <clearcoat_normal_fragment_begin>
 	#include <clearcoat_normal_fragment_maps>
 	#include <clearcoat_normal_fragment_maps>
 	#include <emissivemap_fragment>
 	#include <emissivemap_fragment>
-	#include <transmissionmap_fragment>
+	#include <transmission_fragment>
 
 
 	// accumulation
 	// accumulation
 	#include <lights_physical_fragment>
 	#include <lights_physical_fragment>
@@ -110,11 +113,6 @@ void main() {
 
 
 	vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;
 	vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;
 
 
-	// this is a stub for the transmission model
-	#ifdef TRANSMISSION
-		diffuseColor.a *= mix( saturate( 1. - totalTransmission + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) ), 1.0, metalness );
-	#endif
-
 	gl_FragColor = vec4( outgoingLight, diffuseColor.a );
 	gl_FragColor = vec4( outgoingLight, diffuseColor.a );
 
 
 	#include <tonemapping_fragment>
 	#include <tonemapping_fragment>

+ 11 - 0
src/renderers/shaders/ShaderLib/meshphysical_vert.glsl.js

@@ -16,6 +16,12 @@ varying vec3 vViewPosition;
 
 
 #endif
 #endif
 
 
+#ifdef USE_TRANSMISSION
+
+	varying vec4 vWorldPosition;
+
+#endif
+
 #include <common>
 #include <common>
 #include <uv_pars_vertex>
 #include <uv_pars_vertex>
 #include <uv2_pars_vertex>
 #include <uv2_pars_vertex>
@@ -67,5 +73,10 @@ void main() {
 	#include <shadowmap_vertex>
 	#include <shadowmap_vertex>
 	#include <fog_vertex>
 	#include <fog_vertex>
 
 
+#ifdef USE_TRANSMISSION
+
+	vWorldPosition = worldPosition;
+
+#endif
 }
 }
 `;
 `;

+ 22 - 3
src/renderers/webgl/WebGLMaterials.js

@@ -19,7 +19,7 @@ function WebGLMaterials( properties ) {
 
 
 	}
 	}
 
 
-	function refreshMaterialUniforms( uniforms, material, pixelRatio, height ) {
+	function refreshMaterialUniforms( uniforms, material, pixelRatio, height, transmissionRenderTarget ) {
 
 
 		if ( material.isMeshBasicMaterial ) {
 		if ( material.isMeshBasicMaterial ) {
 
 
@@ -46,7 +46,7 @@ function WebGLMaterials( properties ) {
 
 
 			if ( material.isMeshPhysicalMaterial ) {
 			if ( material.isMeshPhysicalMaterial ) {
 
 
-				refreshUniformsPhysical( uniforms, material );
+				refreshUniformsPhysical( uniforms, material, transmissionRenderTarget );
 
 
 			} else {
 			} else {
 
 
@@ -553,7 +553,7 @@ function WebGLMaterials( properties ) {
 
 
 	}
 	}
 
 
-	function refreshUniformsPhysical( uniforms, material ) {
+	function refreshUniformsPhysical( uniforms, material, transmissionRenderTarget ) {
 
 
 		refreshUniformsStandard( uniforms, material );
 		refreshUniformsStandard( uniforms, material );
 
 
@@ -561,6 +561,7 @@ function WebGLMaterials( properties ) {
 
 
 		uniforms.clearcoat.value = material.clearcoat;
 		uniforms.clearcoat.value = material.clearcoat;
 		uniforms.clearcoatRoughness.value = material.clearcoatRoughness;
 		uniforms.clearcoatRoughness.value = material.clearcoatRoughness;
+
 		if ( material.sheen ) uniforms.sheen.value.copy( material.sheen );
 		if ( material.sheen ) uniforms.sheen.value.copy( material.sheen );
 
 
 		if ( material.clearcoatMap ) {
 		if ( material.clearcoatMap ) {
@@ -596,6 +597,24 @@ function WebGLMaterials( properties ) {
 
 
 		}
 		}
 
 
+		if ( material.transmission > 0.0 ) {
+
+			uniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture;
+			uniforms.transmissionSamplerSize.value.set( transmissionRenderTarget.width, transmissionRenderTarget.height );
+
+		}
+
+		uniforms.thickness.value = material.thickness;
+
+		if ( material.thicknessMap ) {
+
+			uniforms.thicknessMap.value = material.thicknessMap;
+
+		}
+
+		uniforms.attenuationDistance.value = material.attenuationDistance;
+		uniforms.attenuationColor.value.copy( material.attenuationColor );
+
 	}
 	}
 
 
 	function refreshUniformsMatcap( uniforms, material ) {
 	function refreshUniformsMatcap( uniforms, material ) {

+ 4 - 0
src/renderers/webgl/WebGLProgram.js

@@ -468,7 +468,9 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
 			parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
 			parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
 			parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
 			parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
 			parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
 			parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
+			parameters.transmission ? '#define USE_TRANSMISSION' : '',
 			parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
 			parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
+			parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '',
 
 
 			parameters.vertexTangents ? '#define USE_TANGENT' : '',
 			parameters.vertexTangents ? '#define USE_TANGENT' : '',
 			parameters.vertexColors ? '#define USE_COLOR' : '',
 			parameters.vertexColors ? '#define USE_COLOR' : '',
@@ -609,7 +611,9 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
 			parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
 			parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
 
 
 			parameters.sheen ? '#define USE_SHEEN' : '',
 			parameters.sheen ? '#define USE_SHEEN' : '',
+			parameters.transmission ? '#define USE_TRANSMISSION' : '',
 			parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
 			parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
+			parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '',
 
 
 			parameters.vertexTangents ? '#define USE_TANGENT' : '',
 			parameters.vertexTangents ? '#define USE_TANGENT' : '',
 			parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '',
 			parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '',

+ 5 - 3
src/renderers/webgl/WebGLPrograms.js

@@ -45,7 +45,7 @@ function WebGLPrograms( renderer, cubemaps, extensions, capabilities, bindingSta
 		'numDirLightShadows', 'numPointLightShadows', 'numSpotLightShadows',
 		'numDirLightShadows', 'numPointLightShadows', 'numSpotLightShadows',
 		'shadowMapEnabled', 'shadowMapType', 'toneMapping', 'physicallyCorrectLights',
 		'shadowMapEnabled', 'shadowMapType', 'toneMapping', 'physicallyCorrectLights',
 		'alphaTest', 'doubleSided', 'flipSided', 'numClippingPlanes', 'numClipIntersection', 'depthPacking', 'dithering',
 		'alphaTest', 'doubleSided', 'flipSided', 'numClippingPlanes', 'numClipIntersection', 'depthPacking', 'dithering',
-		'sheen', 'transmissionMap'
+		'sheen', 'transmission', 'transmissionMap', 'thicknessMap'
 	];
 	];
 
 
 	function getMaxBones( object ) {
 	function getMaxBones( object ) {
@@ -202,15 +202,17 @@ function WebGLPrograms( renderer, cubemaps, extensions, capabilities, bindingSta
 
 
 			sheen: !! material.sheen,
 			sheen: !! material.sheen,
 
 
+			transmission: !! material.transmission,
 			transmissionMap: !! material.transmissionMap,
 			transmissionMap: !! material.transmissionMap,
+			thicknessMap: !! material.thicknessMap,
 
 
 			combine: material.combine,
 			combine: material.combine,
 
 
 			vertexTangents: ( material.normalMap && material.vertexTangents ),
 			vertexTangents: ( material.normalMap && material.vertexTangents ),
 			vertexColors: material.vertexColors,
 			vertexColors: material.vertexColors,
 			vertexAlphas: material.vertexColors === true && object.geometry && object.geometry.attributes.color && object.geometry.attributes.color.itemSize === 4,
 			vertexAlphas: material.vertexColors === true && object.geometry && object.geometry.attributes.color && object.geometry.attributes.color.itemSize === 4,
-			vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatMap || !! material.clearcoatRoughnessMap || !! material.clearcoatNormalMap || !! material.displacementMap || !! material.transmissionMap,
-			uvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap || !! material.transmissionMap ) && !! material.displacementMap,
+			vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatMap || !! material.clearcoatRoughnessMap || !! material.clearcoatNormalMap || !! material.displacementMap || !! material.transmission || !! material.transmissionMap || !! material.thicknessMap,
+			uvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap || !! material.transmission || !! material.transmissionMap || !! material.thicknessMap ) && !! material.displacementMap,
 
 
 			fog: !! fog,
 			fog: !! fog,
 			useFog: material.fog,
 			useFog: material.fog,

+ 22 - 2
src/renderers/webgl/WebGLRenderLists.js

@@ -57,6 +57,7 @@ function WebGLRenderList( properties ) {
 	let renderItemsIndex = 0;
 	let renderItemsIndex = 0;
 
 
 	const opaque = [];
 	const opaque = [];
+	const transmissive = [];
 	const transparent = [];
 	const transparent = [];
 
 
 	const defaultProgram = { id: - 1 };
 	const defaultProgram = { id: - 1 };
@@ -66,6 +67,7 @@ function WebGLRenderList( properties ) {
 		renderItemsIndex = 0;
 		renderItemsIndex = 0;
 
 
 		opaque.length = 0;
 		opaque.length = 0;
+		transmissive.length = 0;
 		transparent.length = 0;
 		transparent.length = 0;
 
 
 	}
 	}
@@ -115,7 +117,15 @@ function WebGLRenderList( properties ) {
 
 
 		const renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );
 		const renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );
 
 
-		( material.transparent === true ? transparent : opaque ).push( renderItem );
+		if ( material.transmission !== undefined && material.transmission > 0.0 ) {
+
+			transmissive.push( renderItem );
+
+		} else {
+
+			( material.transparent === true ? transparent : opaque ).push( renderItem );
+
+		}
 
 
 	}
 	}
 
 
@@ -123,13 +133,22 @@ function WebGLRenderList( properties ) {
 
 
 		const renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );
 		const renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );
 
 
-		( material.transparent === true ? transparent : opaque ).unshift( renderItem );
+		if ( material.transmission !== undefined && material.transmission > 0.0 ) {
+
+			transmissive.unshift( renderItem );
+
+		} else {
+
+			( material.transparent === true ? transparent : opaque ).unshift( renderItem );
+
+		}
 
 
 	}
 	}
 
 
 	function sort( customOpaqueSort, customTransparentSort ) {
 	function sort( customOpaqueSort, customTransparentSort ) {
 
 
 		if ( opaque.length > 1 ) opaque.sort( customOpaqueSort || painterSortStable );
 		if ( opaque.length > 1 ) opaque.sort( customOpaqueSort || painterSortStable );
+		if ( transmissive.length > 1 ) transmissive.sort( customTransparentSort || reversePainterSortStable );
 		if ( transparent.length > 1 ) transparent.sort( customTransparentSort || reversePainterSortStable );
 		if ( transparent.length > 1 ) transparent.sort( customTransparentSort || reversePainterSortStable );
 
 
 	}
 	}
@@ -158,6 +177,7 @@ function WebGLRenderList( properties ) {
 	return {
 	return {
 
 
 		opaque: opaque,
 		opaque: opaque,
+		transmissive: transmissive,
 		transparent: transparent,
 		transparent: transparent,
 
 
 		init: init,
 		init: init,