重构材质系统
This commit is contained in:
@@ -2,63 +2,79 @@
|
||||
|
||||
#include "dvc_config.h"
|
||||
#include "dvc_pre_declare.h"
|
||||
#include "math/dvc_vector2.h"
|
||||
#include "math/dvc_vector3.h"
|
||||
#include "math/dvc_vector4.h"
|
||||
#include "math/dvc_matrix3.h"
|
||||
#include "math/dvc_matrix4.h"
|
||||
#include "dvc_texture.h"
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
class DV_CORE_API Material
|
||||
{
|
||||
public:
|
||||
struct TextureInfo
|
||||
typedef std::variant<int32_t, float32_t, fVector2, fVector3, fVector4, fMatrix3, fMatrix4, TextureInfo> Value;
|
||||
|
||||
struct Param
|
||||
{
|
||||
TextureConstPtr texture;
|
||||
int32_t texCoord = 0;
|
||||
fMatrix3 uvTransform;
|
||||
enum ParamType
|
||||
{
|
||||
PF_Int32,
|
||||
PT_Float,
|
||||
PT_Float2,
|
||||
PT_Float3,
|
||||
PT_Float4,
|
||||
PT_Matrix3,
|
||||
PT_Matrix4,
|
||||
PT_Texture,
|
||||
};
|
||||
std::string name;
|
||||
ParamType type;
|
||||
Value value;
|
||||
|
||||
Param() = delete;
|
||||
Param(int32_t v) : type(PF_Int32), value(v) { }
|
||||
Param(float32_t v) : type(PT_Float), value(v) { }
|
||||
Param(const fVector2& v) : type(PT_Float2), value(v) {}
|
||||
Param(const fVector3& v) : type(PT_Float3), value(v) {}
|
||||
Param(const fVector4& v) : type(PT_Float4), value(v) {}
|
||||
Param(const fMatrix3& v) : type(PT_Matrix3), value(v) {}
|
||||
Param(const fMatrix4& v) : type(PT_Matrix4), value(v) {}
|
||||
Param(const TextureInfo& v) : type(PT_Texture), value(v) {}
|
||||
};
|
||||
typedef std::map<std::string, Param> ParamMap;
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
bool setParam(const char* name, const T& value)
|
||||
{
|
||||
ParamMap::iterator it = m_params.find(name);
|
||||
if(it==m_params.end() || (!std::holds_alternative<T>(it->second.value)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
it->second.value = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool getParam(const char* name, T& value) const
|
||||
{
|
||||
ParamMap::const_iterator it = m_params.find(name);
|
||||
if(it==m_params.end() || (!std::holds_alternative<T>(it->second.value)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = std::get<T>(it->second.value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
int32_t getID(void) const { return m_id; }
|
||||
|
||||
void setBaseColorTexture(const TextureConstPtr& texture, int32_t texCoord, const fMatrix3& uvTransform,
|
||||
const fVector4& baseColorfactor);
|
||||
const TextureInfo& getBaseColorTexture() const {
|
||||
return m_baseColorTexture;
|
||||
}
|
||||
|
||||
const fVector4& getBaseColorFactor() const {
|
||||
return m_baseColorFactor;
|
||||
}
|
||||
|
||||
void setMetallicRoughnessTexture(const TextureConstPtr& texture, int32_t texCoord, const fMatrix3& uvTransform,
|
||||
float32_t metallicFactor = 1, float32_t roughnessFactor = 1);
|
||||
|
||||
const TextureInfo& getMetallicRoughnessTexture() const {
|
||||
return m_metallicRoughnessTexture;
|
||||
}
|
||||
|
||||
float32_t getMetallicFactor() const {
|
||||
return m_metallicFactor;
|
||||
}
|
||||
|
||||
float32_t getRoughnessFactor() const {
|
||||
return m_roughnessFactor;
|
||||
}
|
||||
|
||||
void setNormalTexture(const TextureConstPtr& texture, int32_t texCoord, const fMatrix3& uvTransform,
|
||||
float32_t scale = 1);
|
||||
|
||||
const TextureInfo& getNormalTexture() const {
|
||||
return m_normalTexture;
|
||||
}
|
||||
|
||||
float32_t getNormalScale() const {
|
||||
return m_normalScale;
|
||||
}
|
||||
|
||||
void setVertexShader(const char* szShaderFile, const char* vertexShaderName);
|
||||
void setFragementShader(const char* szShaderFile, const char* fragementShaderName);
|
||||
|
||||
VertexShaderInterface* getVertexShader() const {
|
||||
return m_vertexShader;
|
||||
}
|
||||
@@ -67,37 +83,26 @@ public:
|
||||
return m_pixelShader;
|
||||
}
|
||||
|
||||
virtual bool setupMaterial();
|
||||
virtual bool pickupParam(const davinci::MaterialConstPtr otherMaterial) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
bool loadShader();
|
||||
protected:
|
||||
void setVertexShader(const char* szShaderFile, const char* vertexShaderName);
|
||||
void setFragementShader(const char* szShaderFile, const char* fragementShaderName);
|
||||
|
||||
template<typename T>
|
||||
bool registerParam(const char* name, const T& defaultValue) {
|
||||
if (m_params.find(name) != m_params.end()) return false;
|
||||
m_params.insert(std::make_pair(name, Param(defaultValue)));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
int32_t m_id;
|
||||
std::string m_name;
|
||||
|
||||
/*The base color texture.
|
||||
* The first three components (RGB) MUST be encoded with the sRGB transfer function.
|
||||
*/
|
||||
TextureInfo m_baseColorTexture;
|
||||
fVector4 m_baseColorFactor = fVector4::ONE;
|
||||
|
||||
/*The metallic - roughness texture.
|
||||
* The metalness values are sampled from the B channel.
|
||||
* The roughness values are sampled from the G channel.
|
||||
*/
|
||||
TextureInfo m_metallicRoughnessTexture;
|
||||
float32_t m_metallicFactor = 1.0f;
|
||||
float32_t m_roughnessFactor = 1.0f;
|
||||
|
||||
/*The normal texture.
|
||||
*/
|
||||
TextureInfo m_normalTexture;
|
||||
/*The scalar parameter applied to each normal vector of the texture.
|
||||
* This value scales the normal vector in X and Y directions using the formula:
|
||||
* scaledNormal = (normalize<sampled normal texture value> * 2.0 - 1.0) * vec3(<normal scale>, <normal scale>, 1.0).
|
||||
*/
|
||||
float32_t m_normalScale = 1.0f;
|
||||
|
||||
protected:
|
||||
VertexShaderInterface* m_vertexShader = nullptr;
|
||||
PixelShaderInterface* m_pixelShader = nullptr;
|
||||
|
||||
@@ -107,8 +112,9 @@ protected:
|
||||
std::string m_fragementShaderFile;
|
||||
std::string m_fragementShaderName;
|
||||
|
||||
ParamMap m_params;
|
||||
public:
|
||||
Material(int32_t id);
|
||||
Material(int32_t id, const char* name);
|
||||
~Material();
|
||||
};
|
||||
|
||||
|
||||
@@ -26,4 +26,12 @@ public:
|
||||
Texture(int32_t id);
|
||||
~Texture();
|
||||
};
|
||||
|
||||
struct TextureInfo
|
||||
{
|
||||
TextureConstPtr texture;
|
||||
int32_t texCoord = 0;
|
||||
fMatrix3 uvTransform;
|
||||
};
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
|
||||
@@ -30,7 +30,13 @@ public:
|
||||
TexturePtr newTextureAsset();
|
||||
TexturePtr getTexture(int32_t id) const;
|
||||
|
||||
MaterialPtr newMaterialAsset();
|
||||
template<typename T>
|
||||
MaterialPtr newMaterialAsset(const char* name) {
|
||||
MaterialPtr materialPtr = std::make_shared<T>(nextID(), name);
|
||||
m_materialAssetMap.insert(std::make_pair(materialPtr->getID(), materialPtr));
|
||||
return materialPtr;
|
||||
}
|
||||
|
||||
MaterialPtr getMaterial(int32_t id) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -46,7 +46,8 @@ enum VertexElementType
|
||||
{
|
||||
VET_UNKNOWN,
|
||||
|
||||
VET_POSITION,
|
||||
VET_POSITION_MODEL, VET_POSITION_WORLD, VET_POSITION_VIEW, VET_POSITION_NDC,
|
||||
|
||||
VET_NORMAL,
|
||||
VET_TANGENT,
|
||||
VET_BINORMAL,
|
||||
|
||||
@@ -17,18 +17,28 @@ public:
|
||||
const Device& getDevice() const {
|
||||
return m_device;
|
||||
}
|
||||
|
||||
UniformBuffer& getUniformBuffer() {
|
||||
return m_uniformBuffer;
|
||||
}
|
||||
const UniformBuffer& getUniformBuffer() const {
|
||||
return m_uniformBuffer;
|
||||
}
|
||||
|
||||
AntiAliasingTech getAntiAliasingTech() const {
|
||||
return m_aaTech;
|
||||
}
|
||||
void setAntiAliasingTech(AntiAliasingTech aaTech) {
|
||||
m_aaTech = aaTech;
|
||||
}
|
||||
|
||||
MaterialPtr getDebugMaterial() const {
|
||||
return m_debugMaterial;
|
||||
}
|
||||
void setDebugMaterial(MaterialPtr material) {
|
||||
m_debugMaterial = material;
|
||||
}
|
||||
|
||||
void pushRenderable(RenderableConstPtr renderable);
|
||||
|
||||
void process(RenderTarget& renderTarget);
|
||||
@@ -38,6 +48,7 @@ protected:
|
||||
AntiAliasingTech m_aaTech = AntiAliasingTech::AA_None;
|
||||
UniformBuffer m_uniformBuffer;
|
||||
RenderableArray m_renderableQueue;
|
||||
MaterialPtr m_debugMaterial;
|
||||
|
||||
public:
|
||||
RenderPipe(Device& device);
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
static DV_CORE_API fVector4 texture2D(const RenderPipe& pipe, const Material::TextureInfo& texturePtr, const fVector2& uv, const fVector4& defaultValue);
|
||||
static DV_CORE_API fVector4 texture2D(const RenderPipe& pipe, const TextureInfo& texturePtr, const fVector2& uv, const fVector4& defaultValue);
|
||||
};
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
|
||||
@@ -16,9 +16,11 @@ public:
|
||||
virtual const VertexDesc& getOutputVertexDesc() const = 0;
|
||||
|
||||
typedef std::function<DeviceBufferAccessorConstPtr(VertexElementType)> SetInputAttributeFunc;
|
||||
virtual void prepare(const RenderPipe* pipe, SetInputAttributeFunc setInputAttributeFunc) = 0;
|
||||
virtual void begin(const RenderPipe* pipe, SetInputAttributeFunc setInputAttributeFunc) = 0;
|
||||
|
||||
virtual void process(size_t index, void* outputVertex, fVector3& vertexWorldPos) = 0;
|
||||
virtual void process(size_t index, float32_t* outputVertex) = 0;
|
||||
|
||||
virtual void end() = 0;
|
||||
};
|
||||
|
||||
class PixelShaderInterface
|
||||
@@ -26,9 +28,11 @@ class PixelShaderInterface
|
||||
public:
|
||||
virtual const char* getName(void) const = 0;
|
||||
|
||||
virtual void prepare(const RenderPipe* pipe, MaterialConstPtr material) = 0;
|
||||
virtual void begin(const RenderPipe* pipe, MaterialConstPtr material) = 0;
|
||||
|
||||
virtual void process(const VertexDesc& veretexDesc, const float32_t* pixelData, fVector4& color) = 0;
|
||||
|
||||
virtual void end() = 0;
|
||||
};
|
||||
|
||||
class ShaderFileInterface
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
Material::Material(int32_t id)
|
||||
Material::Material(int32_t id, const char* name)
|
||||
: m_id(id)
|
||||
, m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -12,37 +13,6 @@ Material::~Material()
|
||||
{
|
||||
}
|
||||
|
||||
void Material::setBaseColorTexture(const TextureConstPtr& texture, int32_t texCoord, const fMatrix3& uvTransform,
|
||||
const fVector4& baseColorfactor)
|
||||
{
|
||||
m_baseColorTexture.texture = texture;
|
||||
m_baseColorTexture.texCoord = texCoord;
|
||||
m_baseColorTexture.uvTransform = uvTransform;
|
||||
|
||||
m_baseColorFactor = baseColorfactor;
|
||||
}
|
||||
|
||||
void Material::setMetallicRoughnessTexture(const TextureConstPtr& texture, int32_t texCoord, const fMatrix3& uvTransform,
|
||||
float32_t metallicFactor, float32_t roughnessFactor)
|
||||
{
|
||||
m_metallicRoughnessTexture.texture = texture;
|
||||
m_metallicRoughnessTexture.texCoord = texCoord;
|
||||
m_metallicRoughnessTexture.uvTransform = uvTransform;
|
||||
|
||||
m_metallicFactor = metallicFactor;
|
||||
m_roughnessFactor = roughnessFactor;
|
||||
}
|
||||
|
||||
void Material::setNormalTexture(const TextureConstPtr& texture, int32_t texCoord, const fMatrix3& uvTransform,
|
||||
float32_t scale)
|
||||
{
|
||||
m_normalTexture.texture = texture;
|
||||
m_normalTexture.texCoord = texCoord;
|
||||
m_normalTexture.uvTransform = uvTransform;
|
||||
|
||||
m_normalScale = scale;
|
||||
}
|
||||
|
||||
void Material::setVertexShader(const char* szShaderFile, const char* vertexShaderName)
|
||||
{
|
||||
m_vertexshaderFile = szShaderFile;
|
||||
@@ -55,7 +25,7 @@ void Material::setFragementShader(const char* szShaderFile, const char* fragemen
|
||||
m_fragementShaderName = fragementShaderName;
|
||||
}
|
||||
|
||||
bool Material::loadShader()
|
||||
bool Material::setupMaterial()
|
||||
{
|
||||
ShaderFileInterface* shaderInterface = davinci::LoadShaderFile(m_vertexshaderFile.c_str());
|
||||
if (shaderInterface == nullptr)
|
||||
|
||||
@@ -135,13 +135,6 @@ TexturePtr Device::getTexture(int32_t id) const
|
||||
return it->second;
|
||||
}
|
||||
|
||||
MaterialPtr Device::newMaterialAsset()
|
||||
{
|
||||
MaterialPtr materialPtr = std::make_shared<Material>(nextID());
|
||||
m_materialAssetMap.insert(std::make_pair(materialPtr->getID(), materialPtr));
|
||||
return materialPtr;
|
||||
}
|
||||
|
||||
MaterialPtr Device::getMaterial(int32_t id) const
|
||||
{
|
||||
std::map<int32_t, MaterialPtr>::const_iterator it = m_materialAssetMap.find(id);
|
||||
|
||||
@@ -28,8 +28,8 @@ void VertexShaderStep::process(RenderPipe& pipe, const InputAssemberStep::NodeAr
|
||||
fMatrix4 worldInverseTrans = inputNode.transform.inverse().transpose();
|
||||
uniformBuffer.setAttribute("self:world_transform_inverse_trans", worldInverseTrans);
|
||||
|
||||
VertexShaderInterface* vs = inputNode.material->getVertexShader();
|
||||
vs->prepare(&pipe,
|
||||
VertexShaderInterface* vs = pipe.getDebugMaterial() ? pipe.getDebugMaterial()->getVertexShader(): inputNode.material->getVertexShader();
|
||||
vs->begin(&pipe,
|
||||
[inputNode](VertexElementType type) -> DeviceBufferAccessorConstPtr
|
||||
{
|
||||
InputAssemberStep::PrimitiveAttributes::const_iterator it = inputNode.vertexData.find(type);
|
||||
@@ -42,12 +42,13 @@ void VertexShaderStep::process(RenderPipe& pipe, const InputAssemberStep::NodeAr
|
||||
);
|
||||
|
||||
size_t vertexCounts = inputNode.indices->getCount();
|
||||
size_t outputVertexByteSize = vs->getOutputVertexDesc().vertexByteSize();
|
||||
|
||||
Node outputNode;
|
||||
outputNode.material = inputNode.material;
|
||||
outputNode.vertexCounts = vertexCounts;
|
||||
outputNode.vertexDesc = vs->getOutputVertexDesc();
|
||||
outputNode.vertexBuf = device.newDeviceBuffer(outputNode.vertexDesc.vertexByteSize() * vertexCounts);
|
||||
outputNode.vertexBuf = device.newDeviceBuffer(outputVertexByteSize * vertexCounts);
|
||||
outputNode.depth.resize(vertexCounts);
|
||||
outputNode.invZ.resize(vertexCounts);
|
||||
|
||||
@@ -55,22 +56,25 @@ void VertexShaderStep::process(RenderPipe& pipe, const InputAssemberStep::NodeAr
|
||||
{
|
||||
uint16_t index = *((const uint16_t*)(inputNode.indices->getElement(i)));
|
||||
|
||||
fVector3 vertexWorldPos;
|
||||
void* outputVertexMemory = outputNode.vertexBuf->ptr(i* outputNode.vertexDesc.vertexByteSize());
|
||||
vs->process(index, outputVertexMemory, vertexWorldPos);
|
||||
uint8_t* outputVertexMemory = (uint8_t*)(outputNode.vertexBuf->ptr(i * outputVertexByteSize));
|
||||
vs->process(index, (float32_t*)outputVertexMemory);
|
||||
|
||||
//TODO: clip
|
||||
|
||||
|
||||
//TODO: div-zero
|
||||
fVector3 cameraSpacePos = (*cameraView) * vertexWorldPos;
|
||||
outputNode.depth[i] = (std::fabsf(cameraSpacePos.z) - cameraNear) / (cameraFar - cameraNear);
|
||||
|
||||
float32_t cameraSpaceZ = cameraSpacePos.z;
|
||||
outputNode.invZ[i] = 1.f/std::fabsf(cameraSpacePos.z);
|
||||
size_t ndcPosOffset = outputNode.vertexDesc.getElement(VET_POSITION_NDC)->offset;
|
||||
const fVector3* vertexNDCPos = (const fVector3*)(outputVertexMemory+ndcPosOffset);
|
||||
|
||||
outputNode.depth[i] = (std::fabsf(vertexNDCPos->z) - cameraNear) / (cameraFar - cameraNear);
|
||||
float32_t cameraSpaceZ = vertexNDCPos->z;
|
||||
outputNode.invZ[i] = 1.f/std::fabsf(vertexNDCPos->z);
|
||||
}
|
||||
|
||||
m_nodes.push_back(outputNode);
|
||||
|
||||
vs->end();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
void RasterizerStep::process(RenderPipe& pipe, const VertexShaderStep::NodeArray& vsNodeArray, AntiAliasingTech aaTech, int32_t canvasWidth, int32_t canvasHeight)
|
||||
{
|
||||
//ShaderFileInterface* shaderInterface = davinci::LoadShaderFile("TestShader.dll");
|
||||
//PixelShaderInterface* pixelShader = shaderInterface->getPixelShader("test");
|
||||
Device& device = pipe.getDevice();
|
||||
UniformBuffer& uniformBuffer = pipe.getUniformBuffer();
|
||||
|
||||
@@ -21,16 +19,22 @@ void RasterizerStep::process(RenderPipe& pipe, const VertexShaderStep::NodeArray
|
||||
|
||||
m_startOffsetArray.resize(canvasWidth* canvasHeight, -1);
|
||||
|
||||
MaterialPtr debugMaterial = pipe.getDebugMaterial();
|
||||
|
||||
VertexShaderStep::NodeArray::const_iterator it, end = vsNodeArray.end();
|
||||
for (it = vsNodeArray.begin(); it != end; ++it)
|
||||
{
|
||||
const VertexShaderStep::Node& node = *it;
|
||||
|
||||
PixelShaderInterface* pixelShader = node.material->getPixelShader();
|
||||
pixelShader->prepare(&pipe, node.material);
|
||||
if (debugMaterial)
|
||||
{
|
||||
debugMaterial->pickupParam(node.material);
|
||||
}
|
||||
PixelShaderInterface* pixelShader = debugMaterial ? debugMaterial->getPixelShader() : node.material->getPixelShader();
|
||||
pixelShader->begin(&pipe, debugMaterial ?debugMaterial : node.material);
|
||||
|
||||
size_t vertexSize = node.vertexDesc.vertexByteSize();
|
||||
size_t POS_offset = node.vertexDesc.getElement(VET_POSITION)->offset;
|
||||
size_t POS_offset = node.vertexDesc.getElement(VET_POSITION_NDC)->offset;
|
||||
|
||||
for (size_t i = 0; i < node.vertexCounts; i += 3)
|
||||
{
|
||||
@@ -65,10 +69,10 @@ void RasterizerStep::process(RenderPipe& pipe, const VertexShaderStep::NodeArray
|
||||
pixelData[j] = MathUtil::lerp3(vertex0[j], vertex1[j], vertex2[j], percentCorrected);
|
||||
}
|
||||
|
||||
if(dot.first==570 && dot.second==405 )
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
//if(dot.first==570 && dot.second==405 )
|
||||
//{
|
||||
// int a = 0;
|
||||
//}
|
||||
fVector4 color;
|
||||
pixelShader->process(node.vertexDesc, &(pixelData[0]), color);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
fVector4 shader::texture2D(const RenderPipe& pipe, const Material::TextureInfo& textureInfo, const fVector2& uv, const fVector4& defaultValue)
|
||||
fVector4 shader::texture2D(const RenderPipe& pipe, const TextureInfo& textureInfo, const fVector2& uv, const fVector4& defaultValue)
|
||||
{
|
||||
if (!(textureInfo.texture)) return defaultValue;
|
||||
fVector3 uvTransform = textureInfo.uvTransform * fVector3(uv, 1);
|
||||
|
||||
Reference in New Issue
Block a user