2
0
Эх сурвалжийг харах

Fixed radiance encoding images.

Branimir Karadžić 7 жил өмнө
parent
commit
dd9563d491

+ 60 - 4
src/image_cubemap_filter.cpp

@@ -620,6 +620,35 @@ namespace bimg
 		}
 	}
 
+	void importanceSampleGGX(float* _result, const float* _xi, float _roughness, const float* _dir)
+	{
+		const float aa  = bx::square(_roughness);
+		const float phi = bx::kPi2 * _xi[0];
+		const float cosTheta = bx::sqrt( (1.0f - _xi[1]) / (1.0f + (bx::square(aa) - 1.0f) * _xi[1]) );
+		const float sinTheta = bx::sqrt(1.0f - bx::square(cosTheta) );
+
+		float hh[3];
+		hh[0] = sinTheta * bx::cos(phi);
+		hh[1] = sinTheta * bx::sin(phi);
+		hh[2] = cosTheta;
+
+		float up[3] = { 0.0f, 0.0f, 0.0f };
+		up[bx::abs(_dir[2]) < 0.999f ? 2 : 0] = 1.0f;
+
+		float right[3];
+		bx::vec3Cross(right, up, _dir);
+
+		float tangentX[3];
+		bx::vec3Norm(tangentX, right);
+
+		float tangentY[3];
+		bx::vec3Cross(tangentY, _dir, tangentX);
+
+		_result[0] = tangentX[0] * hh[0] + tangentY[0] * hh[1] + _dir[0] * hh[2];
+		_result[1] = tangentX[1] * hh[0] + tangentY[1] * hh[1] + _dir[1] * hh[2];
+		_result[2] = tangentX[2] * hh[0] + tangentY[2] * hh[1] + _dir[2] * hh[2];
+	}
+
 	void processFilterArea(
 		  float* _result
 		, const ImageContainer& _image
@@ -654,6 +683,7 @@ namespace bimg
 				const uint32_t pitch      = mip.m_width*bpp/8;
 				const float widthMinusOne = float(mip.m_width-1);
 				const float texelSize     = 1.0f/float(mip.m_width);
+				BX_UNUSED(texelSize);
 
 				const uint32_t minX = uint32_t(_aabb[side].m_min[0] * widthMinusOne);
 				const uint32_t maxX = uint32_t(_aabb[side].m_max[0] * widthMinusOne);
@@ -675,16 +705,31 @@ namespace bimg
 
 						const float solidAngle = texelSolidAngle(uu, vv, texelSize);
 						const float ndotl = bx::clamp(bx::vec3Dot(normal, _dir), 0.0f, 1.0f);
-#else
+#elif 1
 						const float* normal = (const float*)&nsaMip.m_data[(yy*nsaMip.m_width+xx)*(nsaMip.m_bpp/8)];
 						const float solidAngle = normal[3];
 						const float ndotl = bx::clamp(bx::vec3Dot(normal, _dir), 0.0f, 1.0f);
+#else
+						const float uu = float(xx)*texelSize*2.0f - 1.0f;
+						const float vv = float(yy)*texelSize*2.0f - 1.0f;
+						float xi[2] = { uu, vv };
+
+						float hh[3];
+						importanceSampleGGX(hh, xi, _specularPower, _dir);
+
+						const float ddoth2 = 2.0f * bx::vec3Dot(_dir, hh);
+
+						float ll[3];
+						ll[0] = ddoth2 * hh[0] - _dir[0];
+						ll[1] = ddoth2 * hh[1] - _dir[1];
+						ll[2] = ddoth2 * hh[2] - _dir[2];
+
+						const float ndotl = bx::clamp(bx::vec3Dot(_dir, ll), 0.0f, 1.0f);
 #endif // 0
 
 						if (ndotl >= _specularAngle)
 						{
 							const float weight = solidAngle * bx::pow(ndotl, _specularPower);
-
 							float rgba[4];
 							unpack(rgba, row + xx*bpp/8);
 
@@ -841,9 +886,20 @@ namespace bimg
 
 		ImageContainer* output = imageAlloc(_allocator, TextureFormat::RGBA32F, uint16_t(input->m_width), uint16_t(input->m_width), 1, 1, true, true);
 
-		const uint32_t numMips = input->m_numMips;
+		for (uint8_t side = 0; side < 6; ++side)
+		{
+			ImageMip srcMip;
+			imageGetRawData(*input, side, 0, input->m_data, input->m_size, srcMip);
+
+			ImageMip dstMip;
+			imageGetRawData(*output, side, 0, output->m_data, output->m_size, dstMip);
+
+			uint8_t* dstData = const_cast<uint8_t*>(dstMip.m_data);
+
+			bx::memCopy(dstData, srcMip.m_data, srcMip.m_size);
+		}
 
-		for (uint8_t lod = 0; lod < numMips; ++lod)
+		for (uint8_t lod = 1, numMips = input->m_numMips; lod < numMips; ++lod)
 		{
 			ImageContainer* nsa = imageCubemapNormalSolidAngle(_allocator, bx::max<uint32_t>(_image.m_width>>lod, 1) );
 

+ 16 - 12
src/image_encode.cpp

@@ -228,7 +228,10 @@ namespace bimg
 				break;
 
 			default:
-				BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!");
+				if (!imageConvert(_allocator, _dst, _dstFormat, _src, _srcFormat, _width, _height, 1) )
+				{
+					BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!");
+				}
 				break;
 		}
 	}
@@ -260,17 +263,18 @@ namespace bimg
 					imageGetRawData(*output, side, lod, output->m_data, output->m_size, dstMip);
 					uint8_t* dstData = const_cast<uint8_t*>(dstMip.m_data);
 
-					imageEncode(_allocator
-							, dstData
-							, mip.m_data
-							, mip.m_format
-							, mip.m_width
-							, mip.m_height
-							, mip.m_depth
-							, _dstFormat
-							, _quality
-							, &err
-							);
+					imageEncode(
+						  _allocator
+						, dstData
+						, mip.m_data
+						, mip.m_format
+						, mip.m_width
+						, mip.m_height
+						, mip.m_depth
+						, _dstFormat
+						, _quality
+						, &err
+						);
 				}
 			}
 		}

+ 8 - 0
tools/texturec/texturec.cpp

@@ -307,6 +307,14 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 		{
 			output = bimg::imageCubemapRadianceFilter(_allocator, *input);
 
+			if (bimg::TextureFormat::RGBA32F != outputFormat)
+			{
+				bimg::ImageContainer* temp = bimg::imageEncode(_allocator, outputFormat, _options.quality, *output);
+				bimg::imageFree(output);
+
+				output = temp;
+			}
+
 			bimg::imageFree(input);
 			return output;
 		}