Pārlūkot izejas kodu

Some refactoring in materials

Panagiotis Christopoulos Charitos 8 gadi atpakaļ
vecāks
revīzija
6a7432e159

+ 6 - 2
CMakeLists.txt

@@ -94,6 +94,10 @@ else()
 	set(VULKAN TRUE)
 endif()
 
+if(NOT DEFINED CMAKE_BUILD_TYPE)
+	message(FATAL_ERROR "You need to define CMAKE_BUILD_TYPE")
+endif()
+
 ################################################################################
 # Compiler & linker flags                                                      #
 ################################################################################
@@ -103,7 +107,7 @@ set(COMPILER_FLAGS "")
 set(LINKER_FLAGS "")
 
 # When building AnKi define this special flag
-set(COMPILER_FLAGS "${COMPILER_FLAGS} -DANKI_BUILD ")
+set(COMPILER_FLAGS "${COMPILER_FLAGS} -DANKI_BUILD -fPIC ")
 
 if(NOT ANKI_CPU_ADDR_SPACE STREQUAL "0")
 	set(LINKER_FLAGS "${LINKER_FLAGS} -m${ANKI_CPU_ADDR_SPACE} ")
@@ -314,7 +318,7 @@ if(ANDROID)
 endif()
 
 # AnKi compiler flags (Mainly warnings)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wall -W -Wextra -Wstrict-aliasing -Wwrite-strings -Wunused -Wunused-variable -Wno-unused-parameter -Wundef -Wno-ignored-attributes -std=c++11")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wall -W -Wextra -Wstrict-aliasing -Wwrite-strings -Wunused -Wunused-variable -Wno-unused-parameter -Wundef -Wno-ignored-attributes -Wunused-result -std=c++11")
 
 # Set platform specific
 if(LINUX)

+ 2 - 2
shaders/MsCommonFrag.glsl

@@ -291,9 +291,9 @@ void writeRts(in vec3 diffColor, // from 0 to 1
 	in float metallic)
 {
 	GbufferInfo g;
-	g.diffuse = mix(diffColor, vec3(0.0), metallic);
+	g.diffuse = diffColor;
 	g.normal = normal;
-	g.specular = mix(specularColor, diffColor, metallic);
+	g.specular = specularColor;
 	g.roughness = roughness;
 	g.subsurface = subsurface;
 	g.emission = emission;

+ 14 - 21
shaders/Pack.glsl

@@ -114,28 +114,12 @@ struct GbufferInfo
 // Populate the G buffer
 void writeGBuffer(in GbufferInfo g, out vec4 rt0, out vec4 rt1, out vec4 rt2)
 {
-	float comp = packUnorm2ToUnorm1(vec2(g.subsurface, g.emission / MAX_EMISSION));
+	float comp = packUnorm2ToUnorm1(vec2(g.subsurface, g.metallic));
 	rt0 = vec4(g.diffuse, comp);
 	rt1 = vec4(g.specular, g.roughness);
-	rt2 = vec4(g.normal * 0.5 + 0.5, g.metallic);
+	rt2 = vec4(g.normal * 0.5 + 0.5, g.emission / MAX_EMISSION);
 }
 
-// Read from G-buffer
-#define readSpecularRoughnessFromGBuffer(rt1_, uv_, lod_, g_)                                                          \
-	{                                                                                                                  \
-		vec4 comp = textureLod(rt1_, uv_, lod_);                                                                       \
-		g_.specular = comp.xyz;                                                                                        \
-		g_.roughness = max(EPSILON, comp.w);                                                                           \
-	}
-
-// Read from G-buffer
-#define readNormalMetallicFromGBuffer(rt2_, uv_, lod_, g_)                                                             \
-	{                                                                                                                  \
-		vec4 comp = textureLod(rt2_, uv_, lod_);                                                                       \
-		g_.normal = comp.xyz * 2.0 - 1.0;                                                                              \
-		g_.metallic = comp.w;                                                                                          \
-	}
-
 // Read from G-buffer
 void readNormalFromGBuffer(in sampler2D rt2, in vec2 uv, out vec3 normal)
 {
@@ -149,10 +133,19 @@ void readGBuffer(in sampler2D rt0, in sampler2D rt1, in sampler2D rt2, in vec2 u
 	g.diffuse = comp.xyz;
 	vec2 comp2 = unpackUnorm1ToUnorm2(comp.w);
 	g.subsurface = comp2.x;
-	g.emission = comp2.y * MAX_EMISSION;
+	g.metallic = comp2.y;
+
+	comp = textureLod(rt1, uv, lod);
+	g.specular = comp.xyz;
+	g.roughness = max(EPSILON, comp.w);
+
+	comp = textureLod(rt2, uv, lod);
+	g.normal = comp.xyz * 2.0 - 1.0;
+	g.emission = comp.w * MAX_EMISSION;
 
-	readSpecularRoughnessFromGBuffer(rt1, uv, lod, g);
-	readNormalMetallicFromGBuffer(rt2, uv, lod, g);
+	// Fix values
+	g.specular = mix(g.specular, g.diffuse, g.metallic);
+	g.diffuse *= (1.0 - g.metallic);
 }
 
 #endif

+ 9 - 0
src/anki/misc/Xml.h

@@ -65,6 +65,15 @@ public:
 	/// Return the text inside as a float
 	ANKI_USE_RESULT Error getF64(F64& out) const;
 
+	/// Return the text inside as a float
+	ANKI_USE_RESULT Error getF32(F32& out) const
+	{
+		F64 outd;
+		ANKI_CHECK(getF64(outd));
+		out = outd;
+		return ErrorCode::NONE;
+	}
+
 	/// Get a number of floats
 	ANKI_USE_RESULT Error getFloats(DynamicArrayAuto<F64>& out) const;
 

+ 40 - 57
src/anki/resource/MaterialLoader.cpp

@@ -226,12 +226,6 @@ static ShaderVariableDataType getBuiltinType(BuiltinMaterialVariableId in)
 
 void MaterialLoaderInputVariable::move(MaterialLoaderInputVariable& b)
 {
-	m_alloc = std::move(b.m_alloc);
-
-	m_name = std::move(b.m_name);
-	m_value = std::move(b.m_value);
-	m_line = std::move(b.m_line);
-
 	m_type = b.m_type;
 	m_builtin = b.m_builtin;
 	m_flags = b.m_flags;
@@ -250,22 +244,14 @@ CString MaterialLoaderInputVariable::typeStr() const
 
 MaterialLoader::MaterialLoader(GenericMemoryPoolAllocator<U8> alloc)
 	: m_alloc(alloc)
+	, m_source{{{alloc}, {alloc}, {alloc}, {alloc}, {alloc}}}
+	, m_sourceBaked{{{alloc}, {alloc}, {alloc}, {alloc}, {alloc}}}
+	, m_inputs{alloc}
 {
 }
 
 MaterialLoader::~MaterialLoader()
 {
-	for(auto& it : m_source)
-	{
-		it.destroy(m_alloc);
-	}
-
-	for(auto& it : m_sourceBaked)
-	{
-		it.destroy(m_alloc);
-	}
-
-	m_inputs.destroy(m_alloc);
 }
 
 Error MaterialLoader::parseXmlDocument(const XmlDocument& doc)
@@ -384,14 +370,13 @@ Error MaterialLoader::parseProgramTag(const XmlElement& programEl)
 	}
 
 	// Some instancing crap
-	lines.pushBackSprintf(m_alloc,
-		"\n#if INSTANCE_COUNT > 1\n"
-		"#define INSTANCE_ID [%s]\n"
-		"#define INSTANCED [INSTANCE_COUNT]\n"
-		"#else\n"
-		"#define INSTANCE_ID\n"
-		"#define INSTANCED\n"
-		"#endif\n",
+	lines.pushBackSprintf("\n#if INSTANCE_COUNT > 1\n"
+						  "#define INSTANCE_ID [%s]\n"
+						  "#define INSTANCED [INSTANCE_COUNT]\n"
+						  "#else\n"
+						  "#define INSTANCE_ID\n"
+						  "#define INSTANCED\n"
+						  "#endif\n",
 		glshader == ShaderType::VERTEX ? "gl_InstanceID" : "in_instanceId");
 
 	// <includes></includes>
@@ -404,7 +389,7 @@ Error MaterialLoader::parseProgramTag(const XmlElement& programEl)
 	{
 		CString tmp;
 		ANKI_CHECK(includeEl.getText(tmp));
-		lines.pushBackSprintf(m_alloc, "#include \"%s\"", &tmp[0]);
+		lines.pushBackSprintf("#include \"%s\"", &tmp[0]);
 
 		ANKI_CHECK(includeEl.getNextSiblingElement("include", includeEl));
 	} while(includeEl);
@@ -414,19 +399,17 @@ Error MaterialLoader::parseProgramTag(const XmlElement& programEl)
 	// Block
 	if((m_uniformBlockReferencedMask & glshaderbit) != ShaderTypeBit::NONE)
 	{
-		lines.pushBackSprintf(m_alloc,
-			"\nlayout(ANKI_UBO_BINDING(0, 0), std140, row_major) "
-			"uniform u00_\n{");
+		lines.pushBack("\nlayout(ANKI_UBO_BINDING(0, 0), std140, row_major) uniform u00_\n{");
 
 		for(Input& in : m_inputs)
 		{
 			if(in.m_flags.m_inBlock)
 			{
-				lines.pushBackSprintf(m_alloc, &in.m_line[0]);
+				lines.pushBack(&in.m_line[0]);
 			}
 		}
 
-		lines.pushBackSprintf(m_alloc, "};");
+		lines.pushBack("};");
 	}
 
 	// Other variables
@@ -435,12 +418,20 @@ Error MaterialLoader::parseProgramTag(const XmlElement& programEl)
 		if(!in.m_flags.m_inBlock && (in.m_shaderDefinedMask & glshaderbit) != ShaderTypeBit::NONE
 			&& !in.m_flags.m_specialBuiltin)
 		{
-			lines.pushBackSprintf(m_alloc, &in.m_line[0]);
+			lines.pushBack(&in.m_line[0]);
 		}
 	}
 
 	// <operations></operations>
-	lines.pushBackSprintf(m_alloc, "\nvoid main()\n{");
+	lines.pushBack("\nvoid main()\n{");
+
+	if(!m_forwardShading && glshader == ShaderType::FRAGMENT)
+	{
+		// Write default values
+		lines.pushBack("#if defined(writeRts_DEFINED)");
+		lines.pushBack("writeRts(vec3(0.0), vec3(1.0), vec3(0.04), 0.5, 0.0, 0.0, 0.0);");
+		lines.pushBack("#endif");
+	}
 
 	XmlElement opsEl;
 	ANKI_CHECK(programEl.getChildElement("operations", opsEl));
@@ -450,14 +441,14 @@ Error MaterialLoader::parseProgramTag(const XmlElement& programEl)
 	{
 		String out;
 		ANKI_CHECK(parseOperationTag(opEl, glshader, glshaderbit, out));
-		lines.pushBackSprintf(m_alloc, &out[0]);
+		lines.pushBack(&out[0]);
 		out.destroy(m_alloc);
 
 		// Advance
 		ANKI_CHECK(opEl.getNextSiblingElement("operation", opEl));
 	} while(opEl);
 
-	lines.pushBackSprintf(m_alloc, "}\n");
+	lines.pushBack("}\n");
 	return ErrorCode::NONE;
 }
 
@@ -484,13 +475,12 @@ Error MaterialLoader::parseInputsTag(const XmlElement& programEl)
 	ANKI_CHECK(inputsEl.getChildElement("input", inputEl));
 	do
 	{
-		Input in;
-		in.m_alloc = m_alloc;
+		Input in(m_alloc);
 
 		// <name>
 		ANKI_CHECK(inputEl.getChildElement("name", el));
 		ANKI_CHECK(el.getText(cstr));
-		in.m_name.create(m_alloc, cstr);
+		in.m_name.create(cstr);
 
 		ANKI_CHECK(computeBuiltin(in.m_name.toCString(), in.m_builtin));
 
@@ -559,7 +549,7 @@ Error MaterialLoader::parseInputsTag(const XmlElement& programEl)
 				return ErrorCode::USER_DATA;
 			}
 
-			in.m_value.splitString(m_alloc, cstr, ' ');
+			in.m_value.splitString(cstr, ' ');
 		}
 		else
 		{
@@ -620,9 +610,7 @@ Error MaterialLoader::parseInputsTag(const XmlElement& programEl)
 
 			if(!same)
 			{
-				ANKI_LOGE("Variable defined differently between "
-						  "shaders: %s",
-					&in.m_name[0]);
+				ANKI_LOGE("Variable defined differently between shaders: %s", &in.m_name[0]);
 				return ErrorCode::USER_DATA;
 			}
 
@@ -637,8 +625,7 @@ Error MaterialLoader::parseInputsTag(const XmlElement& programEl)
 		{
 			in.m_shaderDefinedMask = glshaderbit;
 
-			m_inputs.emplaceBack(m_alloc);
-			m_inputs.getBack().move(in);
+			m_inputs.emplaceBack(std::move(in));
 		}
 
 		// Advance
@@ -667,8 +654,7 @@ void MaterialLoader::processInputs()
 				{
 					in.m_binding = m_texBinding++;
 
-					in.m_line.sprintf(m_alloc,
-						"layout(ANKI_TEX_BINDING(0, %u)) uniform %s tex%u;",
+					in.m_line.sprintf("layout(ANKI_TEX_BINDING(0, %u)) uniform %s tex%u;",
 						in.m_binding,
 						&in.typeStr()[0],
 						in.m_binding);
@@ -680,10 +666,9 @@ void MaterialLoader::processInputs()
 
 				in.m_index = m_nextIndex++;
 
-				in.m_line.sprintf(m_alloc,
-					"#if %s\n"
-					"%s var%u%s;\n"
-					"#endif",
+				in.m_line.sprintf("#if %s\n"
+								  "%s var%u%s;\n"
+								  "#endif",
 					!in.m_flags.m_inShadow ? "PASS == COLOR" : "1",
 					&in.typeStr()[0],
 					in.m_index,
@@ -703,8 +688,7 @@ void MaterialLoader::processInputs()
 			String initList;
 			in.m_value.join(m_alloc, ", ", initList);
 
-			in.m_line.sprintf(
-				m_alloc, "const %s var%u = %s(%s);", &in.typeStr()[0], in.m_index, &in.typeStr()[0], &initList[0]);
+			in.m_line.sprintf("const %s var%u = %s(%s);", &in.typeStr()[0], in.m_index, &in.typeStr()[0], &initList[0]);
 
 			initList.destroy(m_alloc);
 		}
@@ -968,13 +952,12 @@ void MaterialLoader::mutate(const RenderingKey& key)
 	{
 		if(!m_source[i].isEmpty())
 		{
-			m_sourceBaked[i].destroy(m_alloc);
+			m_sourceBaked[i].destroy();
 
-			String tmp;
-			m_source[i].join(m_alloc, "\n", tmp);
+			StringAuto tmp(m_alloc);
+			m_source[i].join("\n", tmp);
 
-			m_sourceBaked[i].sprintf(m_alloc, "%s%s", &defines[0], &tmp[0]);
-			tmp.destroy(m_alloc);
+			m_sourceBaked[i].sprintf("%s%s", &defines[0], &tmp[0]);
 		}
 	}
 }

+ 19 - 14
src/anki/resource/MaterialLoader.h

@@ -20,11 +20,9 @@ class XmlElement;
 class MaterialLoaderInputVariable : public NonCopyable
 {
 public:
-	GenericMemoryPoolAllocator<U8> m_alloc;
-
-	String m_name;
-	StringList m_value;
-	String m_line;
+	StringAuto m_name;
+	StringListAuto m_value;
+	StringAuto m_line;
 
 	ShaderVariableDataType m_type = ShaderVariableDataType::NONE;
 	BuiltinMaterialVariableId m_builtin = BuiltinMaterialVariableId::NONE;
@@ -54,30 +52,34 @@ public:
 	ShaderTypeBit m_shaderDefinedMask = ShaderTypeBit::NONE; ///< Defined in
 	ShaderTypeBit m_shaderReferencedMask = ShaderTypeBit::NONE; ///< Referenced
 
-	MaterialLoaderInputVariable()
+	MaterialLoaderInputVariable(GenericMemoryPoolAllocator<U8> alloc)
+		: m_name(alloc)
+		, m_value(alloc)
+		, m_line(alloc)
 	{
 	}
 
 	MaterialLoaderInputVariable(MaterialLoaderInputVariable&& b)
+		: m_name(std::move(b.m_name))
+		, m_value(std::move(b.m_value))
+		, m_line(std::move(b.m_line))
 	{
 		move(b);
 	}
 
 	~MaterialLoaderInputVariable()
 	{
-		m_name.destroy(m_alloc);
-		m_value.destroy(m_alloc);
-		m_line.destroy(m_alloc);
 	}
 
 	MaterialLoaderInputVariable& operator=(MaterialLoaderInputVariable&& b)
 	{
+		m_name = std::move(b.m_name);
+		m_value = std::move(b.m_value);
+		m_line = std::move(b.m_line);
 		move(b);
 		return *this;
 	}
 
-	void move(MaterialLoaderInputVariable& b);
-
 	Bool duplicate(const MaterialLoaderInputVariable& b) const
 	{
 		return b.m_name == m_name && b.m_value == m_value && b.m_type == m_type && b.m_builtin == m_builtin
@@ -85,6 +87,9 @@ public:
 	}
 
 	CString typeStr() const;
+
+private:
+	void move(MaterialLoaderInputVariable& b);
 };
 
 /// Creator of shader programs. This class parses between
@@ -159,9 +164,9 @@ public:
 
 private:
 	GenericMemoryPoolAllocator<char> m_alloc;
-	Array<StringList, 5> m_source; ///< Shader program final source
-	Array<String, 5> m_sourceBaked; ///< Final source baked
-	List<Input> m_inputs;
+	Array<StringListAuto, 5> m_source; ///< Shader program final source
+	Array<StringAuto, 5> m_sourceBaked; ///< Final source baked
+	ListAuto<Input> m_inputs;
 	ShaderTypeBit m_uniformBlockReferencedMask = ShaderTypeBit::NONE;
 	U32 m_blockSize = 0;
 	Bool8 m_instanced = false;

+ 2 - 2
src/anki/util/List.h

@@ -500,14 +500,14 @@ public:
 	template<typename... TArgs>
 	void emplaceBack(TArgs&&... args)
 	{
-		Base::emplaceBack(m_alloc, std::forward(args)...);
+		Base::emplaceBack(m_alloc, std::forward<TArgs>(args)...);
 	}
 
 	/// Construct element at the beginning of the list.
 	template<typename... TArgs>
 	void emplaceFront(TArgs&&... args)
 	{
-		Base::emplaceFront(m_alloc, std::forward(args)...);
+		Base::emplaceFront(m_alloc, std::forward<TArgs>(args)...);
 	}
 
 	/// Construct element at the the given position.

+ 6 - 0
src/anki/util/String.cpp

@@ -54,6 +54,12 @@ Error CString::toI64(I64& out) const
 	return err;
 }
 
+String& String::operator=(StringAuto&& b)
+{
+	m_data = std::move(b.m_data);
+	return *this;
+}
+
 void String::create(Allocator alloc, const CStringType& cstr)
 {
 	auto len = cstr.getLength();

+ 16 - 1
src/anki/util/String.h

@@ -18,6 +18,7 @@ namespace anki
 
 // Forward
 class String;
+class StringAuto;
 
 /// @addtogroup util_private
 /// @{
@@ -264,7 +265,12 @@ public:
 	/// Move constructor.
 	String(String&& b)
 	{
-		move(b);
+		*this = std::move(b);
+	}
+
+	String(StringAuto&& b)
+	{
+		*this = std::move(b);
 	}
 
 	/// Requires manual destruction.
@@ -300,6 +306,9 @@ public:
 		return *this;
 	}
 
+	/// Move a StringAuto to this one.
+	String& operator=(StringAuto&& b);
+
 	/// Return char at the specified position.
 	const Char& operator[](U pos) const
 	{
@@ -498,6 +507,12 @@ public:
 		return toCString().toF64(out);
 	}
 
+	/// Convert to F32.
+	ANKI_USE_RESULT Error toF32(F32& out) const
+	{
+		return toCString().toF32(out);
+	}
+
 	/// Convert to I64.
 	ANKI_USE_RESULT Error toI64(I64& out) const
 	{

+ 8 - 1
src/anki/util/StringList.cpp

@@ -21,6 +21,13 @@ void StringList::destroy(Allocator alloc)
 }
 
 void StringList::join(Allocator alloc, const CString& separator, String& out) const
+{
+	StringAuto outl(alloc);
+	join(separator, outl);
+	out = std::move(outl);
+}
+
+void StringList::join(const CString& separator, StringAuto& out) const
 {
 	if(Base::isEmpty())
 	{
@@ -39,7 +46,7 @@ void StringList::join(Allocator alloc, const CString& separator, String& out) co
 	ANKI_ASSERT(charCount > 0);
 
 	// Allocate
-	out.create(alloc, '?', charCount);
+	out.create('?', charCount);
 
 	// Append to output
 	Char* to = &out[0];

+ 19 - 0
src/anki/util/StringList.h

@@ -38,6 +38,9 @@ public:
 	/// Join all the elements into a single big string using a the seperator @a separator
 	void join(Allocator alloc, const CString& separator, String& out) const;
 
+	/// Join all the elements into a single big string using a the seperator @a separator
+	void join(const CString& separator, StringAuto& out) const;
+
 	/// Returns the index position of the last occurrence of @a value in the list.
 	/// @return -1 of not found
 	I getIndexOf(const CString& value) const;
@@ -56,6 +59,16 @@ public:
 		Base::getBack() = std::move(str);
 	}
 
+	/// Push back plain CString.
+	void pushBack(Allocator alloc, CString cstr)
+	{
+		String str;
+		str.create(alloc, cstr);
+
+		Base::emplaceBack(alloc);
+		Base::getBack() = std::move(str);
+	}
+
 	/// Split a string using a separator (@a separator) and return these strings in a string list.
 	void splitString(Allocator alloc, const CString& s, const Char separator, Bool keepEmpty = false);
 };
@@ -106,6 +119,12 @@ public:
 		Base::pushBackSprintf(m_alloc, args...);
 	}
 
+	/// Push back plain CString.
+	void pushBack(CString cstr)
+	{
+		Base::pushBack(m_alloc, cstr);
+	}
+
 	/// Split a string using a separator (@a separator) and return these strings in a string list.
 	void splitString(const CString& s, const Base::Char separator, Bool keepEmpty = false)
 	{

+ 5 - 4
tools/scene/ExporterMaterial.cpp

@@ -273,11 +273,12 @@ void Exporter::exportMaterial(const aiMaterial& mtl) const
 		materialStr = replaceAllString(materialStr, "%specularColorArg%", "uSpecularColor");
 	}
 
+	// Roughness
 	if(!shininessTex.empty())
 	{
 		materialStr = replaceAllString(materialStr,
 			"%specularPowerInput%",
-			R"(<input><type>sampler2D</type><name>uSpecularPower</name><value>)" + m_texrpath + shininessTex
+			R"(<input><type>sampler2D</type><name>roughness</name><value>)" + m_texrpath + shininessTex
 				+ R"(</value></input>)");
 
 		materialStr = replaceAllString(materialStr, "%specularPowerValue%", m_texrpath + shininessTex);
@@ -286,7 +287,7 @@ void Exporter::exportMaterial(const aiMaterial& mtl) const
 
 		materialStr = replaceAllString(materialStr, "%id%", "60");
 
-		materialStr = replaceAllString(materialStr, "%map%", "uSpecularPower");
+		materialStr = replaceAllString(materialStr, "%map%", "roughness");
 
 		materialStr = replaceAllString(materialStr, "%specularPowerArg%", "out60");
 	}
@@ -305,12 +306,12 @@ void Exporter::exportMaterial(const aiMaterial& mtl) const
 
 		materialStr = replaceAllString(materialStr,
 			"%specularPowerInput%",
-			R"(<input><type>float</type><name>uSpecularPower</name><value>)" + std::to_string(shininess)
+			R"(<input><type>float</type><name>roughness</name><const>1</const><value>)" + std::to_string(shininess)
 				+ R"(</value></input>)");
 
 		materialStr = replaceAllString(materialStr, "%specularPowerFunc%", "");
 
-		materialStr = replaceAllString(materialStr, "%specularPowerArg%", "uSpecularPower");
+		materialStr = replaceAllString(materialStr, "%specularPowerArg%", "roughness");
 	}
 
 	materialStr = replaceAllString(materialStr, "%maxSpecularPower%", " ");