From 80d4c7db0e349decb2f3baec380413e2a3e7e1fd Mon Sep 17 00:00:00 2001 From: chubei-oppen Date: Wed, 16 Mar 2022 18:17:28 +0800 Subject: [PATCH] Revert "WebGLRenderer: Remove RGBEEncoding and RGBEFormat. (#23060)" (#77) This reverts commit cee9706c1c38286cf8ca5cff61202b68a0a478ac. --- docs/api/en/constants/Textures.html | 4 +++ docs/api/en/extras/PMREMGenerator.html | 4 +-- docs/api/ko/constants/Textures.html | 4 +++ docs/api/ko/extras/PMREMGenerator.html | 10 +++---- docs/api/zh/constants/Textures.html | 4 +++ docs/api/zh/extras/PMREMGenerator.html | 4 +-- editor/js/libs/ui.three.js | 2 +- examples/jsm/loaders/HDRCubeTextureLoader.js | 16 +++++++++- examples/jsm/loaders/RGBELoader.js | 23 ++++++++++++++- examples/jsm/nodes/utils/ColorSpaceNode.js | 29 ++++++++++++++++++- examples/misc_controls_arcball.html | 1 + examples/webgl_loader_texture_hdr.html | 1 + examples/webgl_materials_envmaps_hdr.html | 1 + .../webgl_materials_envmaps_hdr_nodes.html | 1 + .../webgl_materials_envmaps_pmrem_nodes.html | 1 + examples/webgl_materials_standard_nodes.html | 1 + examples/webgl_pmrem_test.html | 1 + examples/webxr_ar_lighting.html | 1 + src/constants.js | 2 ++ src/extras/PMREMGenerator.js | 12 ++++++-- .../encodings_pars_fragment.glsl.js | 11 +++++++ src/renderers/webgl/WebGLProgram.js | 4 ++- test/unit/src/constants.tests.js | 2 ++ 23 files changed, 122 insertions(+), 17 deletions(-) diff --git a/docs/api/en/constants/Textures.html b/docs/api/en/constants/Textures.html index bfca169c7e2d8f..286dafa4860f69 100644 --- a/docs/api/en/constants/Textures.html +++ b/docs/api/en/constants/Textures.html @@ -148,6 +148,7 @@

Formats

THREE.RGBAIntegerFormat THREE.LuminanceFormat THREE.LuminanceAlphaFormat + THREE.RGBEFormat THREE.DepthFormat THREE.DepthStencilFormat @@ -189,6 +190,8 @@

Formats

The same process occurs as for the [page:constant LuminanceFormat], except that the alpha channel may have values other than *1.0*.

+ [page:constant RGBEFormat] is identical to [page:constant RGBAFormat].

+ [page:constant DepthFormat] reads each element as a single depth value, converts it to floating point, and clamps to the range [0,1]. This is the default for [page:DepthTexture DepthTexture].

@@ -533,6 +536,7 @@

Encoding

THREE.LinearEncoding THREE.sRGBEncoding + THREE.RGBEEncoding THREE.BasicDepthPacking THREE.RGBADepthPacking diff --git a/docs/api/en/extras/PMREMGenerator.html b/docs/api/en/extras/PMREMGenerator.html index 1754bf12b13cbc..1d4f0d67094933 100644 --- a/docs/api/en/extras/PMREMGenerator.html +++ b/docs/api/en/extras/PMREMGenerator.html @@ -42,7 +42,7 @@

[method:WebGLRenderTarget fromEquirectangular]( [param:Texture equirectangul

[page:Texture equirectangular] - The equirectangular texture.

- Generates a PMREM from an equirectangular texture, which can be either LDR or HDR. + Generates a PMREM from an equirectangular texture, which can be either LDR (RGBFormat) or HDR (RGBEFormat). The ideal input image size is 1k (1024 x 512), as this matches best with the 256 x 256 cubemap output.

@@ -50,7 +50,7 @@

[method:WebGLRenderTarget fromCubemap]( [param:CubeTexture cubemap] )

[page:CubeTexture cubemap] - The cubemap texture.

- Generates a PMREM from an cubemap texture, which can be either LDR or HDR. + Generates a PMREM from an cubemap texture, which can be either LDR (RGBFormat) or HDR (RGBEFormat). The ideal input cube size is 256 x 256, as this matches best with the 256 x 256 cubemap output.

diff --git a/docs/api/ko/constants/Textures.html b/docs/api/ko/constants/Textures.html index f132194917a263..dd07c32a53d159 100644 --- a/docs/api/ko/constants/Textures.html +++ b/docs/api/ko/constants/Textures.html @@ -145,6 +145,7 @@

포맷

THREE.RGBAIntegerFormat THREE.LuminanceFormat THREE.LuminanceAlphaFormat + THREE.RGBEFormat THREE.DepthFormat THREE.DepthStencilFormat @@ -185,6 +186,8 @@

포맷

The same process occurs as for the [page:constant LuminanceFormat]와 같은 절차가 이루어지며, 알파 채널에 *1.0* 이외의 값이 들어갈 수 있다는 점만 다릅니다.

+ [page:constant RGBEFormat]은 [page:constant RGBAFormat]과 동일합니다..

+ [page:constant DepthFormat]은 각 요소를 단일 깊이 값으로 일거들이며 부동 소수점으로 변환하고, [0,1]범위에 고정합니다. [page:DepthTexture DepthTexture]의 기본값이기도 합니다.

@@ -527,6 +530,7 @@

인코딩

THREE.LinearEncoding THREE.sRGBEncoding + THREE.RGBEEncoding THREE.BasicDepthPacking THREE.RGBADepthPacking diff --git a/docs/api/ko/extras/PMREMGenerator.html b/docs/api/ko/extras/PMREMGenerator.html index e6f5a2b69cec1d..2dd845dcf77c98 100644 --- a/docs/api/ko/extras/PMREMGenerator.html +++ b/docs/api/ko/extras/PMREMGenerator.html @@ -11,7 +11,7 @@

[name]

이 클래스는 큐브맵 환경 텍스처로부터 사전 필터링된 Mipmap Radiance Environment Map(PMREM)을 생성합니다. -이를 통해 재질의 거칠기에 따라 다양한 수준의 블러를 빠르게 적용할 수 있습니다. RGBE와 같은 비선형 형식을 지원할 수 있도록 사용자 지정 보간을 수행할 수 있는 특수 CubeUV 형식으로 포장되어 있습니다. +이를 통해 재질의 거칠기에 따라 다양한 수준의 블러를 빠르게 적용할 수 있습니다. RGBE와 같은 비선형 형식을 지원할 수 있도록 사용자 지정 보간을 수행할 수 있는 특수 CubeUV 형식으로 포장되어 있습니다. 기존의 mipmap 체인과는 달리, LOD_MIN 수준까지만 내려가며(위), 더 높은 거칠기 수준과 연관된 동일한 LOD_MIN 해상도에서 훨씬 더 많은 필터링된 'mips'를 생성합니다. 이러한 방법으로 샘플링 계산을 제한하면서 확산 조명을 부드럽게 보간하기 위한 해상도를 유지합니다.

@@ -40,7 +40,7 @@

[method:WebGLRenderTarget fromEquirectangular]( [param:Texture equirectangul

[page:Texture equirectangular] - 등장방형 텍스쳐입니다.

- LDR 또는 HDR일 수 있는 등장방형 텍스처로부터 PMREM을 생성합니다. + LDR(RGBFormat) 또는 HDR(RGBEFormat)일 수 있는 등장방형 텍스처로부터 PMREM을 생성합니다. 이상적인 입력 이미지 크기는 1k(1024 x 512)로, 256 x 256 큐브 맵 출력과 가장 잘 일치합니다.

@@ -48,7 +48,7 @@

[method:WebGLRenderTarget fromCubemap]( [param:CubeTexture cubemap] )

[page:CubeTexture cubemap] - 큐브맵 텍스쳐입니다.

- LDR 또는 HDR일 수 있는 큐브맵 텍스처로부터 PMREM을 생성합니다. + LDR(RGBFormat) 또는 HDR(RGBEFormat)일 수 있는 큐브맵 텍스처로부터 PMREM을 생성합니다. 이상적인 입력 이미지 크기는 1k(1024 x 512)로, 256 x 256 큐브 맵 출력과 가장 잘 일치합니다.

@@ -64,8 +64,8 @@

[method:undefined compileEquirectangularShader]()

[method:undefined dispose]()

- PMREM 제너레이터의 내장 메모리를 폐기합니다. - PMREMGenerator는 정적 클래스이므로 두 개 이상의 PMREMGenerator 개체가 필요하지 않습니다. + PMREM 제너레이터의 내장 메모리를 폐기합니다. + PMREMGenerator는 정적 클래스이므로 두 개 이상의 PMREMGenerator 개체가 필요하지 않습니다. 이 경우 둘 중 하나에 대해 dispose()를 호출하면 다른 항목도 사용할 수 없게 됩니다.

diff --git a/docs/api/zh/constants/Textures.html b/docs/api/zh/constants/Textures.html index 27259f3e176646..194ee7ac2b5102 100644 --- a/docs/api/zh/constants/Textures.html +++ b/docs/api/zh/constants/Textures.html @@ -138,6 +138,7 @@

格式

THREE.RGBAIntegerFormat THREE.LuminanceFormat THREE.LuminanceAlphaFormat + THREE.RGBEFormat THREE.DepthFormat THREE.DepthStencilFormat @@ -175,6 +176,8 @@

格式

[page:constant LuminanceAlphaFormat] 将每个元素同时作为亮度分量和Alpha分量来读取。 和上面[page:constant LuminanceFormat]的处理过程是一致的,除了Alpha分量具有除了*1.0*以外的值。

+ [page:constant RGBEFormat] 与 [page:constant RGBAFormat] 是相同的。

+ [page:constant DepthFormat]将每个元素作为单独的深度值来读取,将其转换为范围限制在[0,1]区间的浮点数。 它是[page:DepthTexture DepthTexture]的默认值。

@@ -522,6 +525,7 @@

编码

THREE.LinearEncoding THREE.sRGBEncoding + THREE.RGBEEncoding THREE.BasicDepthPacking THREE.RGBADepthPacking diff --git a/docs/api/zh/extras/PMREMGenerator.html b/docs/api/zh/extras/PMREMGenerator.html index 98576d94aa5783..310dfc309c88be 100644 --- a/docs/api/zh/extras/PMREMGenerator.html +++ b/docs/api/zh/extras/PMREMGenerator.html @@ -42,7 +42,7 @@

[method:WebGLRenderTarget fromEquirectangular]( [param:Texture equirectangul

[page:Texture equirectangular] - The equirectangular texture.

- Generates a PMREM from an equirectangular texture, which can be either LDR or HDR. + Generates a PMREM from an equirectangular texture, which can be either LDR (RGBFormat) or HDR (RGBEFormat). The ideal input image size is 1k (1024 x 512), as this matches best with the 256 x 256 cubemap output.

@@ -50,7 +50,7 @@

[method:WebGLRenderTarget fromCubemap]( [param:CubeTexture cubemap] )

[page:CubeTexture cubemap] - The cubemap texture.

- Generates a PMREM from an cubemap texture, which can be either LDR or HDR. + Generates a PMREM from an cubemap texture, which can be either LDR (RGBFormat) or HDR (RGBEFormat). The ideal input cube size is 256 x 256, as this matches best with the 256 x 256 cubemap output.

diff --git a/editor/js/libs/ui.three.js b/editor/js/libs/ui.three.js index 89817db9c752cf..cbebd938b49964 100644 --- a/editor/js/libs/ui.three.js +++ b/editor/js/libs/ui.three.js @@ -56,7 +56,7 @@ class UITexture extends UISpan { // assuming RGBE/Radiance HDR iamge format - const loader = new RGBELoader(); + const loader = new RGBELoader().setDataType( THREE.FloatType ); loader.load( event.target.result, function ( hdrTexture ) { hdrTexture.sourceFile = file.name; diff --git a/examples/jsm/loaders/HDRCubeTextureLoader.js b/examples/jsm/loaders/HDRCubeTextureLoader.js index 643f664298f838..00d1552230a14b 100644 --- a/examples/jsm/loaders/HDRCubeTextureLoader.js +++ b/examples/jsm/loaders/HDRCubeTextureLoader.js @@ -6,7 +6,12 @@ import { HalfFloatType, LinearEncoding, LinearFilter, - Loader + Loader, + NearestFilter, + RGBAFormat, + RGBEEncoding, + RGBFormat, + UnsignedByteType } from 'three'; import { RGBELoader } from '../loaders/RGBELoader.js'; @@ -42,6 +47,15 @@ class HDRCubeTextureLoader extends Loader { switch ( texture.type ) { + case UnsignedByteType: + + texture.encoding = RGBEEncoding; + texture.format = RGBAFormat; + texture.minFilter = NearestFilter; + texture.magFilter = NearestFilter; + texture.generateMipmaps = false; + break; + case FloatType: texture.encoding = LinearEncoding; diff --git a/examples/jsm/loaders/RGBELoader.js b/examples/jsm/loaders/RGBELoader.js index faf411300157aa..ee1ee9f792df81 100644 --- a/examples/jsm/loaders/RGBELoader.js +++ b/examples/jsm/loaders/RGBELoader.js @@ -4,7 +4,12 @@ import { FloatType, HalfFloatType, LinearEncoding, - LinearFilter + LinearFilter, + NearestFilter, + RGBEEncoding, + RGBEFormat, + RGBFormat, + UnsignedByteType } from 'three'; // https://github.com/mrdoob/three.js/issues/5552 @@ -375,6 +380,13 @@ class RGBELoader extends DataTextureLoader { switch ( this.type ) { + case UnsignedByteType: + + data = image_rgba_data; + format = RGBEFormat; // handled as THREE.RGBAFormat in shaders + type = UnsignedByteType; + break; + case FloatType: numElements = image_rgba_data.length / 4; @@ -443,6 +455,15 @@ class RGBELoader extends DataTextureLoader { switch ( texture.type ) { + case UnsignedByteType: + + texture.encoding = RGBEEncoding; + texture.minFilter = NearestFilter; + texture.magFilter = NearestFilter; + texture.generateMipmaps = false; + texture.flipY = true; + break; + case FloatType: texture.encoding = LinearEncoding; diff --git a/examples/jsm/nodes/utils/ColorSpaceNode.js b/examples/jsm/nodes/utils/ColorSpaceNode.js index 2c295fcef3d662..3827ee4ce5c50a 100644 --- a/examples/jsm/nodes/utils/ColorSpaceNode.js +++ b/examples/jsm/nodes/utils/ColorSpaceNode.js @@ -1,5 +1,6 @@ import { LinearEncoding, + RGBEEncoding, sRGBEncoding } from 'three'; @@ -122,10 +123,31 @@ ColorSpaceNode.Nodes = ( function () { }` ); + const RGBEToLinear = new FunctionNode( /* glsl */` + vec4 RGBEToLinear( in vec4 value ) { + + return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 ); + + }` + ); + + const LinearToRGBE = new FunctionNode( /* glsl */` + vec4 LinearToRGBE( in vec4 value ) { + + float maxComponent = max( max( value.r, value.g ), value.b ); + float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 ); + return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 ); + + }` + ); + + return { LinearToLinear: LinearToLinear, sRGBToLinear: sRGBToLinear, - LinearTosRGB: LinearTosRGB + LinearTosRGB: LinearTosRGB, + RGBEToLinear: RGBEToLinear, + LinearToRGBE: LinearToRGBE }; } )(); @@ -135,6 +157,9 @@ ColorSpaceNode.LINEAR_TO_LINEAR = 'LinearToLinear'; ColorSpaceNode.SRGB_TO_LINEAR = 'sRGBToLinear'; ColorSpaceNode.LINEAR_TO_SRGB = 'LinearTosRGB'; +ColorSpaceNode.RGBE_TO_LINEAR = 'RGBEToLinear'; +ColorSpaceNode.LINEAR_TO_RGBE = 'LinearToRGBE'; + ColorSpaceNode.getEncodingComponents = function ( encoding ) { switch ( encoding ) { @@ -143,6 +168,8 @@ ColorSpaceNode.getEncodingComponents = function ( encoding ) { return [ 'Linear' ]; case sRGBEncoding: return [ 'sRGB' ]; + case RGBEEncoding: + return [ 'RGBE' ]; } diff --git a/examples/misc_controls_arcball.html b/examples/misc_controls_arcball.html index a38596dc152036..e91a2af5adaf55 100644 --- a/examples/misc_controls_arcball.html +++ b/examples/misc_controls_arcball.html @@ -155,6 +155,7 @@ render(); new RGBELoader() + .setDataType( THREE.UnsignedByteType ) .setPath( 'textures/equirectangular/' ) .load( 'venice_sunset_1k.hdr', function ( hdrEquirect ) { diff --git a/examples/webgl_loader_texture_hdr.html b/examples/webgl_loader_texture_hdr.html index 7394bc1d53459e..0e876f109d0e9c 100644 --- a/examples/webgl_loader_texture_hdr.html +++ b/examples/webgl_loader_texture_hdr.html @@ -60,6 +60,7 @@ camera = new THREE.OrthographicCamera( - aspect, aspect, 1, - 1, 0, 1 ); new RGBELoader() + .setDataType( THREE.UnsignedByteType ) // alt: FloatType, HalfFloatType .load( 'textures/memorial.hdr', function ( texture, textureData ) { //console.log( textureData ); diff --git a/examples/webgl_materials_envmaps_hdr.html b/examples/webgl_materials_envmaps_hdr.html index 347fd64cb49bf6..ccd3d1ceab647a 100644 --- a/examples/webgl_materials_envmaps_hdr.html +++ b/examples/webgl_materials_envmaps_hdr.html @@ -101,6 +101,7 @@ const hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ]; hdrCubeMap = new HDRCubeTextureLoader() .setPath( './textures/cube/pisaHDR/' ) + .setDataType( THREE.UnsignedByteType ) .load( hdrUrls, function () { hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap ); diff --git a/examples/webgl_materials_envmaps_hdr_nodes.html b/examples/webgl_materials_envmaps_hdr_nodes.html index 5fdc284c454cbe..31533428e409e8 100644 --- a/examples/webgl_materials_envmaps_hdr_nodes.html +++ b/examples/webgl_materials_envmaps_hdr_nodes.html @@ -110,6 +110,7 @@ const hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ]; hdrCubeMap = new HDRCubeTextureLoader() .setPath( './textures/cube/pisaHDR/' ) + .setDataType( THREE.UnsignedByteType ) .load( hdrUrls, function () { hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap ); diff --git a/examples/webgl_materials_envmaps_pmrem_nodes.html b/examples/webgl_materials_envmaps_pmrem_nodes.html index 954192eae7b52c..7014756c1df72d 100644 --- a/examples/webgl_materials_envmaps_pmrem_nodes.html +++ b/examples/webgl_materials_envmaps_pmrem_nodes.html @@ -118,6 +118,7 @@ const hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ]; hdrCubeMap = new HDRCubeTextureLoader() .setPath( './textures/cube/pisaHDR/' ) + .setDataType( THREE.UnsignedByteType ) .load( hdrUrls, function () { hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap ); diff --git a/examples/webgl_materials_standard_nodes.html b/examples/webgl_materials_standard_nodes.html index 5b4e8df35ec710..fa0b8f1dd8f5f8 100644 --- a/examples/webgl_materials_standard_nodes.html +++ b/examples/webgl_materials_standard_nodes.html @@ -140,6 +140,7 @@ const filename = environments[ name ].filename; new RGBELoader() + .setDataType( THREE.UnsignedByteType ) .setPath( 'textures/equirectangular/' ) .load( filename, function ( hdrEquirect ) { diff --git a/examples/webgl_pmrem_test.html b/examples/webgl_pmrem_test.html index 983a4627b78c6b..c380cb3f09564c 100644 --- a/examples/webgl_pmrem_test.html +++ b/examples/webgl_pmrem_test.html @@ -139,6 +139,7 @@ let radianceMap = null; new RGBELoader() + .setDataType( THREE.UnsignedByteType ) // .setDataType( THREE.FloatType ) .setPath( 'textures/equirectangular/' ) .load( 'spot1Lux.hdr', function ( texture ) { diff --git a/examples/webxr_ar_lighting.html b/examples/webxr_ar_lighting.html index ea4341c77a97d6..11137d5a700ae1 100644 --- a/examples/webxr_ar_lighting.html +++ b/examples/webxr_ar_lighting.html @@ -96,6 +96,7 @@ // new RGBELoader() + .setDataType( THREE.UnsignedByteType ) .setPath( 'textures/equirectangular/' ) .load( 'royal_esplanade_1k.hdr', function ( texture ) { diff --git a/src/constants.js b/src/constants.js index 6d705056b12195..3dec12f7aa7eeb 100644 --- a/src/constants.js +++ b/src/constants.js @@ -90,6 +90,7 @@ export const RGBFormat = 1022; export const RGBAFormat = 1023; export const LuminanceFormat = 1024; export const LuminanceAlphaFormat = 1025; +export const RGBEFormat = RGBAFormat; export const DepthFormat = 1026; export const DepthStencilFormat = 1027; export const RedFormat = 1028; @@ -140,6 +141,7 @@ export const TriangleStripDrawMode = 1; export const TriangleFanDrawMode = 2; export const LinearEncoding = 3000; export const sRGBEncoding = 3001; +export const RGBEEncoding = 3002; export const BasicDepthPacking = 3200; export const RGBADepthPacking = 3201; export const TangentSpaceNormalMap = 0; diff --git a/src/extras/PMREMGenerator.js b/src/extras/PMREMGenerator.js index 226b7a69bd1c67..40ee4657f399ee 100644 --- a/src/extras/PMREMGenerator.js +++ b/src/extras/PMREMGenerator.js @@ -6,6 +6,7 @@ import { LinearFilter, NoToneMapping, NoBlending, + RGBEEncoding, RGBAFormat, UnsignedByteType, sRGBEncoding, @@ -44,7 +45,8 @@ const MAX_SAMPLES = 20; const ENCODINGS = { [ LinearEncoding ]: 0, - [ sRGBEncoding ]: 1 + [ sRGBEncoding ]: 1, + [ RGBEEncoding ]: 2 }; const _flatCamera = /*@__PURE__*/ new OrthographicCamera(); @@ -128,7 +130,7 @@ class PMREMGenerator { /** * Generates a PMREM from an equirectangular texture, which can be either LDR - * or HDR. The ideal input image size is 1k (1024 x 512), + * (RGBFormat) or HDR (RGBEFormat). The ideal input image size is 1k (1024 x 512), * as this matches best with the 256 x 256 cubemap output. */ fromEquirectangular( equirectangular, renderTarget = null ) { @@ -139,7 +141,7 @@ class PMREMGenerator { /** * Generates a PMREM from an cubemap texture, which can be either LDR - * or HDR. The ideal input cube size is 256 x 256, + * (RGBFormat) or HDR (RGBEFormat). The ideal input cube size is 256 x 256, * as this matches best with the 256 x 256 cubemap output. */ fromCubemap( cubemap, renderTarget = null ) { @@ -914,6 +916,10 @@ function _getEncodings() { return value; + } else if ( inputEncoding == 2 ) { + + return RGBEToLinear( value ); + } else { return sRGBToLinear( value ); diff --git a/src/renderers/shaders/ShaderChunk/encodings_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/encodings_pars_fragment.glsl.js index 67d34ea063a13c..dd90dcb4eed12c 100644 --- a/src/renderers/shaders/ShaderChunk/encodings_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/encodings_pars_fragment.glsl.js @@ -12,4 +12,15 @@ vec4 LinearTosRGB( in vec4 value ) { return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); } +vec4 RGBEToLinear( in vec4 value ) { + return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 ); +} + +vec4 LinearToRGBE( in vec4 value ) { + float maxComponent = max( max( value.r, value.g ), value.b ); + float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 ); + return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 ); + // return vec4( value.brg, ( 3.0 + 128.0 ) / 256.0 ); +} + `; diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index b0b02a3452f6c3..ca2f12fb02e90f 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -1,7 +1,7 @@ import { WebGLUniforms } from './WebGLUniforms.js'; import { WebGLShader } from './WebGLShader.js'; import { ShaderChunk } from '../shaders/ShaderChunk.js'; -import { NoToneMapping, AddOperation, MixOperation, MultiplyOperation, CubeRefractionMapping, CubeUVRefractionMapping, CubeUVReflectionMapping, CubeReflectionMapping, PCFSoftShadowMap, PCFShadowMap, VSMShadowMap, ACESFilmicToneMapping, CineonToneMapping, CustomToneMapping, ReinhardToneMapping, LinearToneMapping, sRGBEncoding, LinearEncoding, GLSL3 } from '../../constants.js'; +import { NoToneMapping, AddOperation, MixOperation, MultiplyOperation, CubeRefractionMapping, CubeUVRefractionMapping, CubeUVReflectionMapping, CubeReflectionMapping, PCFSoftShadowMap, PCFShadowMap, VSMShadowMap, ACESFilmicToneMapping, CineonToneMapping, CustomToneMapping, ReinhardToneMapping, LinearToneMapping, RGBEEncoding, sRGBEncoding, LinearEncoding, GLSL3 } from '../../constants.js'; let programIdCount = 0; @@ -27,6 +27,8 @@ function getEncodingComponents( encoding ) { return [ 'Linear', '( value )' ]; case sRGBEncoding: return [ 'sRGB', '( value )' ]; + case RGBEEncoding: + return [ 'RGBE', '( value )' ]; default: console.warn( 'THREE.WebGLProgram: Unsupported encoding:', encoding ); return [ 'Linear', '( value )' ]; diff --git a/test/unit/src/constants.tests.js b/test/unit/src/constants.tests.js index cd2708828543ae..cee71b138b6aee 100644 --- a/test/unit/src/constants.tests.js +++ b/test/unit/src/constants.tests.js @@ -89,6 +89,7 @@ export default QUnit.module( 'Constants', () => { assert.equal( Constants.RGBAFormat, 1023, 'RGBAFormat is equal to 1023' ); assert.equal( Constants.LuminanceFormat, 1024, 'LuminanceFormat is equal to 1024' ); assert.equal( Constants.LuminanceAlphaFormat, 1025, 'LuminanceAlphaFormat is equal to 1025' ); + assert.equal( Constants.RGBEFormat, Constants.RGBAFormat, 'RGBEFormat is equal to RGBAFormat' ); assert.equal( Constants.DepthFormat, 1026, 'DepthFormat is equal to 1026' ); assert.equal( Constants.DepthStencilFormat, 1027, 'DepthStencilFormat is equal to 1027' ); assert.equal( Constants.RGB_S3TC_DXT1_Format, 33776, 'RGB_S3TC_DXT1_Format is equal to 33776' ); @@ -128,6 +129,7 @@ export default QUnit.module( 'Constants', () => { assert.equal( Constants.TriangleFanDrawMode, 2, 'TriangleFanDrawMode is equal to 2' ); assert.equal( Constants.LinearEncoding, 3000, 'LinearEncoding is equal to 3000' ); assert.equal( Constants.sRGBEncoding, 3001, 'sRGBEncoding is equal to 3001' ); + assert.equal( Constants.RGBEEncoding, 3002, 'RGBEEncoding is equal to 3002' ); assert.equal( Constants.BasicDepthPacking, 3200, 'BasicDepthPacking is equal to 3200' ); assert.equal( Constants.RGBADepthPacking, 3201, 'RGBADepthPacking is equal to 3201' );