work
This commit is contained in:
@@ -11,6 +11,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
||||
var width: Double = 0
|
||||
var height: Double = 0
|
||||
|
||||
var createdAt = Date()
|
||||
|
||||
var targetPixelBuffer: CVPixelBuffer?;
|
||||
// var context: EAGLContext?;
|
||||
@@ -74,6 +75,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
||||
do {
|
||||
let c1 = try found!.resourceValues(forKeys: [.creationDateKey]).creationDate
|
||||
let c2 = try fileURL.resourceValues(forKeys: [.creationDateKey]).creationDate
|
||||
|
||||
if c1! < c2! {
|
||||
found = fileURL
|
||||
print("\(fileURL) is newer, replacing")
|
||||
@@ -86,11 +88,18 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if found != nil {
|
||||
print("Using hot reloaded asset : \(found)")
|
||||
path = found?.path
|
||||
} else {
|
||||
|
||||
do {
|
||||
if let cd = try found?.resourceValues(forKeys:[.creationDateKey]).creationDate {
|
||||
if cd > instance.createdAt {
|
||||
print("Using hot reloaded asset : \(found)")
|
||||
path = found!.path
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
|
||||
}
|
||||
if path == nil {
|
||||
if(uriString.hasPrefix("file://")) {
|
||||
path = String(uriString.dropFirst(7))
|
||||
} else if(uriString.hasPrefix("asset://")) {
|
||||
@@ -103,7 +112,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
||||
}
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
do {
|
||||
print("Opening data from path \(path)")
|
||||
@@ -115,9 +124,8 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
||||
return ResourceBuffer(data:rawPtr, size:UInt32(nsData.count), id:UInt32(resId))
|
||||
} catch {
|
||||
print("Error opening file: \(error)")
|
||||
return ResourceBuffer()
|
||||
}
|
||||
return ResourceBuffer()
|
||||
return ResourceBuffer()
|
||||
}
|
||||
|
||||
var freeResource : @convention(c) (UInt32,UnsafeMutableRawPointer) -> () = { rid, resourcesPtr in
|
||||
@@ -349,7 +357,8 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
||||
remove_skybox(self.viewer!)
|
||||
result("OK");
|
||||
case "loadGlb":
|
||||
let assetPtr = load_glb(self.viewer, call.arguments as! String)
|
||||
let args = call.arguments as! Array<Any>
|
||||
let assetPtr = load_glb(self.viewer, args[0] as! String, args[1] as! Bool)
|
||||
result(unsafeBitCast(assetPtr, to:Int64.self));
|
||||
case "loadGltf":
|
||||
let args = call.arguments as! Array<Any?>
|
||||
@@ -463,16 +472,21 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
|
||||
case "rotateEnd":
|
||||
grab_end(self.viewer)
|
||||
result("OK")
|
||||
case "clearBackgroundImage":
|
||||
clear_background_image(self.viewer!)
|
||||
result("OK")
|
||||
case "setBackgroundColor":
|
||||
let args = call.arguments as! Array<Any>
|
||||
set_background_color(self.viewer!, Float(args[0] as! Double),Float(args[1] as! Double),Float(args[2] as! Double), Float(args[3] as! Double))
|
||||
result("OK")
|
||||
case "setBackgroundImage":
|
||||
let uri = call.arguments as! String
|
||||
set_background_image(self.viewer!, uri)
|
||||
render(self.viewer!, 0)
|
||||
self.registry.textureFrameAvailable(self.textureId!)
|
||||
result("OK")
|
||||
let uri = call.arguments as? String
|
||||
set_background_image(self.viewer!, uri)
|
||||
result("OK")
|
||||
case "setBackgroundImagePosition":
|
||||
let args = call.arguments as! Array<Any>
|
||||
set_background_image_position(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double), args[2] as! Bool)
|
||||
result("OK");
|
||||
let args = call.arguments as! Array<Any>
|
||||
set_background_image_position(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double), args[2] as! Bool)
|
||||
result("OK");
|
||||
case "setPosition":
|
||||
let args = call.arguments as! Array<Any>
|
||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace polyvox {
|
||||
void loadIbl(const char* const iblUri, float intensity);
|
||||
void removeIbl();
|
||||
|
||||
SceneAsset* loadGlb(const char* const uri);
|
||||
SceneAsset* loadGlb(const char* const uri, bool unlit);
|
||||
SceneAsset* loadGltf(const char* const uri, const char* relativeResourcePath);
|
||||
void removeAsset(SceneAsset* asset);
|
||||
// removes all add assets from the current scene
|
||||
@@ -76,8 +76,9 @@ namespace polyvox {
|
||||
|
||||
Renderer* getRenderer();
|
||||
|
||||
void setBackgroundColor(const float* color);
|
||||
void setBackgroundColor(const float r, const float g, const float b, const float a);
|
||||
void setBackgroundImage(const char* resourcePath);
|
||||
void clearBackgroundImage();
|
||||
void setBackgroundImagePosition(float x, float y, bool clamp);
|
||||
void setCameraExposure(float aperture, float shutterSpeed, float sensitivity);
|
||||
void setCameraPosition(float x, float y, float z);
|
||||
@@ -125,8 +126,8 @@ namespace polyvox {
|
||||
|
||||
vector<SceneAsset*> _assets;
|
||||
|
||||
AssetLoader* _assetLoader;
|
||||
SceneAssetLoader* _sceneAssetLoader;
|
||||
SceneAssetLoader* _ubershaderAssetLoader;
|
||||
SceneAssetLoader* _unlitAssetLoader;
|
||||
NameComponentManager* _ncm;
|
||||
std::mutex mtx; // mutex to ensure thread safety when removing assets
|
||||
|
||||
@@ -148,7 +149,9 @@ namespace polyvox {
|
||||
float _cameraFocalLength = 28.0f;
|
||||
float _cameraFocusDistance = 0.0f;
|
||||
|
||||
// these flags relate to the textured quad we use for rendering unlit background images
|
||||
ColorGrading *colorGrading = nullptr;
|
||||
|
||||
// background image properties
|
||||
uint32_t _imageHeight = 0;
|
||||
uint32_t _imageWidth = 0;
|
||||
mat4f _imageScale;
|
||||
@@ -158,12 +161,12 @@ namespace polyvox {
|
||||
IndexBuffer* _imageIb = nullptr;
|
||||
Material* _imageMaterial = nullptr;
|
||||
TextureSampler _imageSampler;
|
||||
ColorGrading *colorGrading = nullptr;
|
||||
void loadKtx2Texture(string path, ResourceBuffer data);
|
||||
void loadKtxTexture(string path, ResourceBuffer data);
|
||||
void loadPngTexture(string path, ResourceBuffer data);
|
||||
void loadTextureFromPath(string path);
|
||||
|
||||
|
||||
|
||||
void _createManipulator();
|
||||
uint32_t _lastFrameTimeInNanos;
|
||||
};
|
||||
|
||||
@@ -26,11 +26,11 @@ typedef struct BoneAnimation BoneAnimation;
|
||||
void* filament_viewer_new(void* context, ResourceBuffer (*loadResource)(const char*), void (*freeResource)(uint32_t));
|
||||
void filament_viewer_delete(void* viewer);
|
||||
void create_render_target(void* viewer, uint32_t textureId, uint32_t width, uint32_t height);
|
||||
void clear_background_image(void* viewer);
|
||||
void set_background_image(void* viewer, const char* path);
|
||||
|
||||
// color is rgba
|
||||
void set_background_color(void* viewer, const float* color);
|
||||
void set_background_image_position(void* viewer, float x, float y, bool clamp);
|
||||
void set_background_color(void* viewer, const float r, const float g, const float b, const float a);
|
||||
|
||||
void load_skybox(void* viewer, const char* skyboxPath);
|
||||
void load_ibl(void* viewer, const char* iblPath, float intensity);
|
||||
void remove_skybox(void* viewer);
|
||||
@@ -38,7 +38,7 @@ void remove_ibl(void* viewer);
|
||||
int32_t add_light(void* viewer, uint8_t type, float colour, float intensity, float posX, float posY, float posZ, float dirX, float dirY, float dirZ, bool shadows);
|
||||
void remove_light(void* viewer, int32_t entityId);
|
||||
void clear_lights(void* viewer);
|
||||
void* load_glb(void* viewer, const char* assetPath);
|
||||
void* load_glb(void* viewer, const char* assetPath, bool unlit);
|
||||
void* load_gltf(void* viewer, const char* assetPath, const char* relativePath);
|
||||
bool set_camera(void* viewer, void* asset, const char* nodeName);
|
||||
void render(void* viewer, uint64_t frameTimeInNanos);
|
||||
|
||||
@@ -20,23 +20,30 @@ namespace polyvox {
|
||||
SceneAssetLoader(
|
||||
LoadResource loadResource,
|
||||
FreeResource freeResource,
|
||||
AssetLoader* assetLoader,
|
||||
MaterialProvider* materialProvider,
|
||||
EntityManager* entityManager,
|
||||
ResourceLoader* resourceLoader,
|
||||
NameComponentManager* ncm,
|
||||
Engine* engine,
|
||||
Scene* scene);
|
||||
~SceneAssetLoader();
|
||||
SceneAsset* fromGltf(const char* uri, const char* relativeResourcePath);
|
||||
SceneAsset* fromGlb(const char* uri);
|
||||
void remove(SceneAsset* asset);
|
||||
void destroyAll();
|
||||
|
||||
private:
|
||||
LoadResource _loadResource;
|
||||
FreeResource _freeResource;
|
||||
MaterialProvider* _materialProvider;
|
||||
EntityManager* _entityManager;
|
||||
AssetLoader* _assetLoader;
|
||||
ResourceLoader* _resourceLoader;
|
||||
NameComponentManager* _ncm;
|
||||
Engine* _engine;
|
||||
Scene* _scene;
|
||||
|
||||
vector<SceneAsset*> _assets;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ namespace polyvox {
|
||||
const Material* _m;
|
||||
const Material* _ms[1];
|
||||
|
||||
const Engine* _engine;
|
||||
|
||||
public:
|
||||
UnlitMaterialProvider(Engine* engine) {
|
||||
_engine = engine;
|
||||
_m = Material::Builder()
|
||||
.package( UNLIT_OPAQUE_UNLIT_OPAQUE_DATA, UNLIT_OPAQUE_UNLIT_OPAQUE_SIZE)
|
||||
.build(*engine);
|
||||
@@ -35,11 +38,11 @@ namespace polyvox {
|
||||
}
|
||||
|
||||
void destroyMaterials() {
|
||||
|
||||
// TODO - do we need to do anything here?
|
||||
}
|
||||
|
||||
bool needsDummyData(filament::VertexAttribute attrib) const noexcept {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b4ce6e725e4beb9d7cd494f24b2bd4608de06b5dcc7290d07c8a6f3668cec6ec
|
||||
size 905232
|
||||
oid sha256:6f40a337ca4ae110bbfee332e03ee496b0f3706b6b9d264a44f3c248733f4f23
|
||||
size 376488
|
||||
|
||||
@@ -106,14 +106,12 @@ struct Vertex {
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
// static const Vertex TRIANGLE_VERTICES[3] = {
|
||||
// {{1, 0}, 0xffff0000u},
|
||||
// {{cos(M_PI * 2 / 3), sin(M_PI * 2 / 3)}, 0xff00ff00u},
|
||||
// {{cos(M_PI * 4 / 3), sin(M_PI * 4 / 3)}, 0xff0000ffu},
|
||||
// };
|
||||
|
||||
// static constexpr uint16_t TRIANGLE_INDICES[3] = { 0, 1, 2 };
|
||||
static constexpr float4 sFullScreenTriangleVertices[3] = {
|
||||
{ -1.0f, -1.0f, 1.0f, 1.0f },
|
||||
{ 3.0f, -1.0f, 1.0f, 1.0f },
|
||||
{ -1.0f, 3.0f, 1.0f, 1.0f } };
|
||||
|
||||
static const uint16_t sFullScreenTriangleIndices[3] = {0, 1, 2};
|
||||
|
||||
FilamentViewer::FilamentViewer(void* context, LoadResource loadResource,
|
||||
FreeResource freeResource)
|
||||
@@ -196,34 +194,85 @@ FilamentViewer::FilamentViewer(void* context, LoadResource loadResource,
|
||||
_unlitProvider = new UnlitMaterialProvider(_engine);
|
||||
_ubershaderProvider = gltfio::createUbershaderProvider(
|
||||
_engine, UBERARCHIVE_DEFAULT_DATA, UBERARCHIVE_DEFAULT_SIZE);
|
||||
Log("Created material provider");
|
||||
|
||||
EntityManager &em = EntityManager::get();
|
||||
_ncm = new NameComponentManager(em);
|
||||
_assetLoader = AssetLoader::create({_engine, _ubershaderProvider, _ncm, &em});
|
||||
|
||||
_resourceLoader = new ResourceLoader({.engine = _engine,
|
||||
.normalizeSkinningWeights = true });
|
||||
_stbDecoder = createStbProvider(_engine);
|
||||
_resourceLoader->addTextureProvider("image/png", _stbDecoder);
|
||||
_resourceLoader->addTextureProvider("image/jpeg", _stbDecoder);
|
||||
_sceneAssetLoader = new SceneAssetLoader(_loadResource,
|
||||
_ubershaderAssetLoader = new SceneAssetLoader(_loadResource,
|
||||
_freeResource,
|
||||
_assetLoader,
|
||||
_ubershaderProvider,
|
||||
&em,
|
||||
_resourceLoader,
|
||||
_ncm,
|
||||
_engine,
|
||||
_scene);
|
||||
|
||||
_unlitAssetLoader = new SceneAssetLoader(_loadResource,
|
||||
_freeResource,
|
||||
_unlitProvider,
|
||||
&em,
|
||||
_resourceLoader,
|
||||
|
||||
_ncm,
|
||||
_engine,
|
||||
_scene);
|
||||
|
||||
|
||||
_imageTexture = Texture::Builder()
|
||||
.width(1)
|
||||
.height(1)
|
||||
.levels(0x01)
|
||||
.format(Texture::InternalFormat::RGB16F)
|
||||
.sampler(Texture::Sampler::SAMPLER_2D)
|
||||
.build(*_engine);
|
||||
|
||||
_imageMaterial =
|
||||
Material::Builder()
|
||||
.package(IMAGE_PACKAGE, IMAGE_IMAGE_SIZE)
|
||||
.build(*_engine);
|
||||
_imageMaterial->setDefaultParameter("showImage",0);
|
||||
_imageMaterial->setDefaultParameter("backgroundColor", RgbType::sRGB, float3(0.f));
|
||||
_imageMaterial->setDefaultParameter("image", _imageTexture, _imageSampler);
|
||||
_imageScale = mat4f { 1.0f , 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
|
||||
_imageMaterial->setDefaultParameter("transform", _imageScale);
|
||||
|
||||
_imageVb = VertexBuffer::Builder()
|
||||
.vertexCount(3)
|
||||
.bufferCount(1)
|
||||
.attribute(VertexAttribute::POSITION, 0,
|
||||
VertexBuffer::AttributeType::FLOAT4, 0)
|
||||
.build(*_engine);
|
||||
|
||||
_imageVb->setBufferAt(
|
||||
*_engine, 0,
|
||||
{sFullScreenTriangleVertices, sizeof(sFullScreenTriangleVertices)});
|
||||
|
||||
_imageIb = IndexBuffer::Builder()
|
||||
.indexCount(3)
|
||||
.bufferType(IndexBuffer::IndexType::USHORT)
|
||||
.build(*_engine);
|
||||
|
||||
_imageIb->setBuffer(*_engine, {sFullScreenTriangleIndices,
|
||||
sizeof(sFullScreenTriangleIndices)});
|
||||
|
||||
Entity imageEntity = em.create();
|
||||
RenderableManager::Builder(1)
|
||||
.boundingBox({{}, {1.0f, 1.0f, 1.0f}})
|
||||
.material(0, _imageMaterial->getDefaultInstance())
|
||||
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, _imageVb,
|
||||
_imageIb, 0, 3)
|
||||
.culling(false)
|
||||
.build(*_engine, imageEntity);
|
||||
_imageEntity = &imageEntity;
|
||||
_scene->addEntity(imageEntity);
|
||||
}
|
||||
|
||||
static constexpr float4 sFullScreenTriangleVertices[3] = {
|
||||
{ -1.0f, -1.0f, 1.0f, 1.0f },
|
||||
{ 3.0f, -1.0f, 1.0f, 1.0f },
|
||||
{ -1.0f, 3.0f, 1.0f, 1.0f } };
|
||||
|
||||
static const uint16_t sFullScreenTriangleIndices[3] = {0, 1, 2};
|
||||
|
||||
void FilamentViewer::setFrameInterval(float frameInterval) {
|
||||
Renderer::FrameRateOptions fro;
|
||||
fro.interval = frameInterval;
|
||||
@@ -260,52 +309,6 @@ void FilamentViewer::clearLights() {
|
||||
_lights.clear();
|
||||
}
|
||||
|
||||
void FilamentViewer::createImageRenderable() {
|
||||
|
||||
if (_imageEntity)
|
||||
return;
|
||||
|
||||
auto &em = EntityManager::get();
|
||||
|
||||
_imageMaterial =
|
||||
Material::Builder()
|
||||
.package(IMAGE_PACKAGE, IMAGE_IMAGE_SIZE)
|
||||
.build(*_engine);
|
||||
|
||||
_imageVb = VertexBuffer::Builder()
|
||||
.vertexCount(3)
|
||||
.bufferCount(1)
|
||||
.attribute(VertexAttribute::POSITION, 0,
|
||||
VertexBuffer::AttributeType::FLOAT4, 0)
|
||||
.build(*_engine);
|
||||
|
||||
_imageVb->setBufferAt(
|
||||
*_engine, 0,
|
||||
{sFullScreenTriangleVertices, sizeof(sFullScreenTriangleVertices)});
|
||||
|
||||
_imageIb = IndexBuffer::Builder()
|
||||
.indexCount(3)
|
||||
.bufferType(IndexBuffer::IndexType::USHORT)
|
||||
.build(*_engine);
|
||||
|
||||
_imageIb->setBuffer(*_engine, {sFullScreenTriangleIndices,
|
||||
sizeof(sFullScreenTriangleIndices)});
|
||||
|
||||
Entity imageEntity = em.create();
|
||||
RenderableManager::Builder(1)
|
||||
.boundingBox({{}, {1.0f, 1.0f, 1.0f}})
|
||||
.material(0, _imageMaterial->getDefaultInstance())
|
||||
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, _imageVb,
|
||||
_imageIb, 0, 3)
|
||||
.culling(false)
|
||||
.build(*_engine, imageEntity);
|
||||
|
||||
_scene->addEntity(imageEntity);
|
||||
|
||||
_imageEntity = &imageEntity;
|
||||
|
||||
}
|
||||
|
||||
static bool endsWith(string path, string ending) {
|
||||
return path.compare(path.length() - ending.length(), ending.length(), ending) == 0;
|
||||
}
|
||||
@@ -367,7 +370,7 @@ void FilamentViewer::loadPngTexture(string path, ResourceBuffer rb) {
|
||||
_imageTexture = Texture::Builder()
|
||||
.width(_imageWidth)
|
||||
.height(_imageHeight)
|
||||
.levels(0xff)
|
||||
.levels(0x01)
|
||||
.format(channels == 3 ? Texture::InternalFormat::RGB16F
|
||||
: Texture::InternalFormat::RGBA16F)
|
||||
.sampler(Texture::Sampler::SAMPLER_2D)
|
||||
@@ -411,26 +414,32 @@ void FilamentViewer::loadTextureFromPath(string path) {
|
||||
|
||||
}
|
||||
|
||||
void FilamentViewer::setBackgroundColor(const float* color) {
|
||||
void FilamentViewer::setBackgroundColor(const float r, const float g, const float b, const float a) {
|
||||
_imageMaterial->setDefaultParameter("showImage", 0);
|
||||
|
||||
_imageMaterial->setDefaultParameter("backgroundColor", RgbType::sRGB, float3(color[0], color[1], color[2]));
|
||||
_imageMaterial->setDefaultParameter("backgroundColor", RgbaType::sRGB, float4(r, g, b, a));
|
||||
const Viewport& vp = _view->getViewport();
|
||||
Log("Image width %d height %d vp width %d height %d", _imageWidth, _imageHeight, vp.width, vp.height);
|
||||
_imageMaterial->setDefaultParameter("transform", _imageScale);
|
||||
}
|
||||
|
||||
void FilamentViewer::clearBackgroundImage() {
|
||||
_imageMaterial->setDefaultParameter("showImage", 0);
|
||||
if (_imageTexture) {
|
||||
Log("Destroying existing texture");
|
||||
_engine->destroy(_imageTexture);
|
||||
Log("Destroyed.");
|
||||
_imageTexture = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FilamentViewer::setBackgroundImage(const char *resourcePath) {
|
||||
|
||||
string resourcePathString(resourcePath);
|
||||
|
||||
Log("Setting background image to %s", resourcePath);
|
||||
|
||||
createImageRenderable();
|
||||
|
||||
if (_imageTexture) {
|
||||
Log("Destroying existing texture");
|
||||
_engine->destroy(_imageTexture);
|
||||
Log("Destroyed.");
|
||||
_imageTexture = nullptr;
|
||||
}
|
||||
clearBackgroundImage();
|
||||
|
||||
loadTextureFromPath(resourcePathString);
|
||||
|
||||
@@ -442,11 +451,8 @@ void FilamentViewer::setBackgroundImage(const char *resourcePath) {
|
||||
|
||||
_imageMaterial->setDefaultParameter("transform", _imageScale);
|
||||
_imageMaterial->setDefaultParameter("image", _imageTexture, _imageSampler);
|
||||
|
||||
_imageMaterial->setDefaultParameter("showImage", 1);
|
||||
|
||||
_imageMaterial->setDefaultParameter("backgroundColor", RgbType::sRGB,
|
||||
float3(0.f));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -529,11 +535,12 @@ void FilamentViewer::setBackgroundImagePosition(float x, float y, bool clamp=fal
|
||||
|
||||
FilamentViewer::~FilamentViewer() {
|
||||
clearAssets();
|
||||
delete _sceneAssetLoader;
|
||||
delete _ubershaderAssetLoader;
|
||||
delete _unlitAssetLoader;
|
||||
_resourceLoader->asyncCancelLoad();
|
||||
_ubershaderProvider->destroyMaterials();
|
||||
_unlitProvider->destroyMaterials();
|
||||
AssetLoader::destroy(&_assetLoader);
|
||||
|
||||
for(auto it : _lights) {
|
||||
_engine->destroy(it);
|
||||
}
|
||||
@@ -609,14 +616,20 @@ void FilamentViewer::destroySwapChain() {
|
||||
}
|
||||
}
|
||||
|
||||
SceneAsset *FilamentViewer::loadGlb(const char *const uri) {
|
||||
SceneAsset *asset = _sceneAssetLoader->fromGlb(uri);
|
||||
SceneAsset *FilamentViewer::loadGlb(const char *const uri, bool unlit) {
|
||||
SceneAsset *asset;
|
||||
if(unlit) {
|
||||
asset = _unlitAssetLoader->fromGlb(uri);
|
||||
} else {
|
||||
asset = _ubershaderAssetLoader->fromGlb(uri);
|
||||
}
|
||||
if (!asset) {
|
||||
Log("Unknown error loading asset.");
|
||||
} else {
|
||||
_assets.push_back(asset);
|
||||
Log("GLB loaded, asset at index %d", _assets.size() - 1);
|
||||
}
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
@@ -624,7 +637,7 @@ SceneAsset *FilamentViewer::loadGltf(const char *const uri,
|
||||
const char *const relativeResourcePath) {
|
||||
Log("Loading GLTF at URI %s with relativeResourcePath %s", uri,
|
||||
relativeResourcePath);
|
||||
SceneAsset *asset = _sceneAssetLoader->fromGltf(uri, relativeResourcePath);
|
||||
SceneAsset *asset = _ubershaderAssetLoader->fromGltf(uri, relativeResourcePath);
|
||||
if (!asset) {
|
||||
Log("Unknown error loading asset.");
|
||||
} else {
|
||||
@@ -633,7 +646,6 @@ SceneAsset *FilamentViewer::loadGltf(const char *const uri,
|
||||
return asset;
|
||||
}
|
||||
|
||||
|
||||
void FilamentViewer::clearAssets() {
|
||||
Log("Clearing all assets");
|
||||
if(_mainCamera) {
|
||||
@@ -644,13 +656,10 @@ void FilamentViewer::clearAssets() {
|
||||
delete _manipulator;
|
||||
_manipulator = nullptr;
|
||||
}
|
||||
|
||||
_ubershaderAssetLoader->destroyAll();
|
||||
_unlitAssetLoader->destroyAll();
|
||||
|
||||
int i = 0;
|
||||
for (auto asset : _assets) {
|
||||
_sceneAssetLoader->remove(asset);
|
||||
Log("Cleared asset %d", i);
|
||||
i++;
|
||||
}
|
||||
_assets.clear();
|
||||
Log("Cleared all assets");
|
||||
}
|
||||
@@ -661,19 +670,8 @@ void FilamentViewer::removeAsset(SceneAsset *asset) {
|
||||
mtx.lock();
|
||||
// todo - what if we are using a camera from this asset?
|
||||
_view->setCamera(_mainCamera);
|
||||
_sceneAssetLoader->remove(asset);
|
||||
|
||||
bool erased = false;
|
||||
for (auto it = _assets.begin(); it != _assets.end();++it) {
|
||||
if (*it == asset) {
|
||||
_assets.erase(it);
|
||||
erased = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!erased) {
|
||||
Log("Error removing asset from scene : not found");
|
||||
}
|
||||
_ubershaderAssetLoader->remove(asset);
|
||||
_unlitAssetLoader->remove(asset);
|
||||
mtx.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,12 @@ extern "C" {
|
||||
delete((FilamentViewer*)viewer);
|
||||
}
|
||||
|
||||
void set_background_color(void* viewer, const float* color) {
|
||||
((FilamentViewer*)viewer)->setBackgroundColor(color);
|
||||
void set_background_color(void* viewer, const float r, const float g, const float b, const float a) {
|
||||
((FilamentViewer*)viewer)->setBackgroundColor(r, g, b, a);
|
||||
}
|
||||
|
||||
void clear_background_image(void* viewer) {
|
||||
((FilamentViewer*)viewer)->clearBackgroundImage();
|
||||
}
|
||||
|
||||
void set_background_image(void* viewer, const char* path) {
|
||||
@@ -63,8 +67,8 @@ extern "C" {
|
||||
((FilamentViewer*)viewer)->clearLights();
|
||||
}
|
||||
|
||||
void* load_glb(void* viewer, const char* assetPath) {
|
||||
return ((FilamentViewer*)viewer)->loadGlb(assetPath);
|
||||
void* load_glb(void* viewer, const char* assetPath, bool unlit) {
|
||||
return ((FilamentViewer*)viewer)->loadGlb(assetPath, unlit);
|
||||
}
|
||||
|
||||
void* load_gltf(void* viewer, const char* assetPath, const char* relativePath) {
|
||||
|
||||
@@ -10,14 +10,22 @@ using namespace filament::gltfio;
|
||||
|
||||
SceneAssetLoader::SceneAssetLoader(LoadResource loadResource,
|
||||
FreeResource freeResource,
|
||||
AssetLoader *assetLoader,
|
||||
MaterialProvider* materialProvider,
|
||||
EntityManager* entityManager,
|
||||
ResourceLoader *resourceLoader,
|
||||
NameComponentManager *ncm,
|
||||
Engine *engine,
|
||||
Scene *scene)
|
||||
: _loadResource(loadResource), _freeResource(freeResource),
|
||||
_assetLoader(assetLoader), _resourceLoader(resourceLoader), _ncm(ncm),
|
||||
_engine(engine), _scene(scene) {}
|
||||
: _loadResource(loadResource), _freeResource(freeResource), _materialProvider(materialProvider), _entityManager(entityManager),
|
||||
_resourceLoader(resourceLoader), _ncm(ncm),
|
||||
_engine(engine), _scene(scene) {
|
||||
_assetLoader = AssetLoader::create({_engine, materialProvider, _ncm, entityManager});
|
||||
}
|
||||
|
||||
SceneAssetLoader::~SceneAssetLoader() {
|
||||
destroyAll();
|
||||
AssetLoader::destroy(&_assetLoader);
|
||||
}
|
||||
|
||||
SceneAsset *SceneAssetLoader::fromGltf(const char *uri,
|
||||
const char *relativeResourcePath) {
|
||||
@@ -87,6 +95,7 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
|
||||
FilamentAsset *asset = _assetLoader->createAsset(
|
||||
(const uint8_t *)rbuf.data, rbuf.size);
|
||||
|
||||
|
||||
if (!asset) {
|
||||
Log("Unknown error loading GLB asset.");
|
||||
return nullptr;
|
||||
@@ -105,12 +114,18 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
|
||||
const Entity *entities = asset->getEntities();
|
||||
|
||||
RenderableManager &rm = _engine->getRenderableManager();
|
||||
|
||||
MaterialKey config;
|
||||
auto mi_new = _materialProvider->createMaterialInstance(&config, nullptr);
|
||||
|
||||
// why did I need to explicitly enable culling?
|
||||
for (int i = 0; i < asset->getEntityCount(); i++) {
|
||||
auto entityInstance = rm.getInstance(entities[i]);
|
||||
rm.setCulling(entityInstance, true);
|
||||
}
|
||||
auto entityInstance = rm.getInstance(entities[i]);
|
||||
auto mi = rm.getMaterialInstanceAt(entityInstance, 0);
|
||||
// auto m = mi->getMaterial();
|
||||
// auto shading = m->getShading();
|
||||
// Log("Shading %d", shading);
|
||||
}
|
||||
|
||||
auto lights = asset->getLightEntities();
|
||||
_scene->addEntities(lights, asset->getLightEntityCount());
|
||||
@@ -118,6 +133,8 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
|
||||
Log("Added %d lights to scene from asset", asset->getLightEntityCount());
|
||||
|
||||
FilamentInstance* inst = asset->getInstance();
|
||||
|
||||
|
||||
inst->getAnimator()->updateBoneMatrices();
|
||||
|
||||
inst->recomputeBoundingBoxes();
|
||||
@@ -128,10 +145,43 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
|
||||
_freeResource(rbuf.id);
|
||||
|
||||
Log("Successfully loaded GLB.");
|
||||
return new SceneAsset(asset, _engine, _ncm, _loadResource, _freeResource);
|
||||
SceneAsset* sceneAsset = new SceneAsset(asset, _engine, _ncm, _loadResource, _freeResource);
|
||||
_assets.push_back(sceneAsset);
|
||||
|
||||
|
||||
|
||||
|
||||
return sceneAsset;
|
||||
}
|
||||
|
||||
void SceneAssetLoader::destroyAll() {
|
||||
for (auto asset : _assets) {
|
||||
_scene->removeEntities(asset->_asset->getEntities(),
|
||||
asset->_asset->getEntityCount());
|
||||
|
||||
_scene->removeEntities(asset->getLightEntities(),
|
||||
asset->getLightEntityCount());
|
||||
|
||||
_resourceLoader->evictResourceData();
|
||||
_assetLoader->destroyAsset(asset->_asset);
|
||||
delete asset;
|
||||
}
|
||||
_assets.clear();
|
||||
}
|
||||
|
||||
void SceneAssetLoader::remove(SceneAsset *asset) {
|
||||
bool erased = false;
|
||||
for (auto it = _assets.begin(); it != _assets.end();++it) {
|
||||
if (*it == asset) {
|
||||
_assets.erase(it);
|
||||
erased = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!erased) {
|
||||
Log("Error removing asset from scene : not found");
|
||||
return;
|
||||
}
|
||||
|
||||
Log("Removing asset and all associated entities/lights.");
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'animations/animation_builder.dart';
|
||||
import 'animations/animations.dart';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
// this is confusing - "FilamentAsset" actually defines a pointer to a SceneAsset, whereas FilamentLight is an Entity ID.
|
||||
// should make this consistent
|
||||
typedef FilamentAsset = int;
|
||||
@@ -26,11 +26,12 @@ abstract class FilamentController {
|
||||
void setPixelRatio(double ratio);
|
||||
Future resize(int width, int height, {double contentScaleFactor = 1});
|
||||
Future setBackgroundColor(Color color);
|
||||
Future clearBackgroundImage();
|
||||
Future setBackgroundImage(String path);
|
||||
Future setBackgroundImagePosition(double x, double y, {bool clamp = false});
|
||||
Future loadSkybox(String skyboxPath);
|
||||
Future removeSkybox();
|
||||
Future loadIbl(String path);
|
||||
Future loadIbl(String path, {double intensity = 30000});
|
||||
Future removeIbl();
|
||||
|
||||
// copied from LightManager.h
|
||||
@@ -54,7 +55,7 @@ abstract class FilamentController {
|
||||
bool castShadows);
|
||||
Future removeLight(FilamentLight light);
|
||||
Future clearLights();
|
||||
Future<FilamentAsset> loadGlb(String path);
|
||||
Future<FilamentAsset> loadGlb(String path, {bool unlit = false});
|
||||
Future<FilamentAsset> loadGltf(String path, String relativeResourcePath);
|
||||
Future zoomBegin();
|
||||
Future zoomUpdate(double z);
|
||||
@@ -172,6 +173,11 @@ class PolyvoxFilamentController extends FilamentController {
|
||||
_textureIdController.add(_textureId);
|
||||
}
|
||||
|
||||
@override
|
||||
Future clearBackgroundImage() async {
|
||||
await _channel.invokeMethod("clearBackgroundImage");
|
||||
}
|
||||
|
||||
@override
|
||||
Future setBackgroundImage(String path) async {
|
||||
await _channel.invokeMethod("setBackgroundImage", path);
|
||||
@@ -179,15 +185,12 @@ class PolyvoxFilamentController extends FilamentController {
|
||||
|
||||
@override
|
||||
Future setBackgroundColor(Color color) async {
|
||||
print(
|
||||
"setting to ${color.red.toDouble() / 255.0} ${color.blue.toDouble() / 255.0} ${color.red.toDouble() / 255.0}");
|
||||
await _channel.invokeMethod(
|
||||
"setBackgroundColor",
|
||||
Float32List.fromList([
|
||||
color.red.toDouble() / 255.0,
|
||||
color.green.toDouble() / 255.0,
|
||||
color.blue.toDouble() / 255.0
|
||||
]));
|
||||
await _channel.invokeMethod("setBackgroundColor", [
|
||||
color.red.toDouble() / 255.0,
|
||||
color.green.toDouble() / 255.0,
|
||||
color.blue.toDouble() / 255.0,
|
||||
color.alpha.toDouble() / 255.0
|
||||
]);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -253,9 +256,9 @@ class PolyvoxFilamentController extends FilamentController {
|
||||
return _channel.invokeMethod("clearLights");
|
||||
}
|
||||
|
||||
Future<FilamentAsset> loadGlb(String path) async {
|
||||
Future<FilamentAsset> loadGlb(String path, {bool unlit = false}) async {
|
||||
print("Loading GLB at $path ");
|
||||
var asset = await _channel.invokeMethod("loadGlb", path);
|
||||
var asset = await _channel.invokeMethod("loadGlb", [path, unlit]);
|
||||
if (asset == FILAMENT_ASSET_ERROR) {
|
||||
throw Exception("An error occurred loading the asset at $path");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -35,6 +36,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
||||
};
|
||||
|
||||
bool _rotating = false;
|
||||
bool _scaling = false;
|
||||
|
||||
// to avoid duplicating code for pan/rotate (panStart, panUpdate, panEnd, rotateStart, rotateUpdate etc)
|
||||
// we have only a single function for start/update/end.
|
||||
@@ -100,6 +102,8 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
||||
onScaleStart: !widget.enableControls
|
||||
? null
|
||||
: (d) async {
|
||||
_scaling = true;
|
||||
print("SCALE START");
|
||||
if (d.pointerCount == 2) {
|
||||
await widget.controller.zoomEnd();
|
||||
await widget.controller.zoomBegin();
|
||||
@@ -108,6 +112,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
||||
onScaleEnd: !widget.enableControls
|
||||
? null
|
||||
: (d) async {
|
||||
_scaling = false;
|
||||
if (d.pointerCount == 2) {
|
||||
_lastScale = 0;
|
||||
await widget.controller.zoomEnd();
|
||||
@@ -118,8 +123,9 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
||||
: (d) async {
|
||||
if (d.pointerCount == 2) {
|
||||
if (_lastScale != 0) {
|
||||
await widget.controller
|
||||
.zoomUpdate(100 * (_lastScale - d.scale));
|
||||
await widget.controller.zoomUpdate(Platform.isIOS
|
||||
? 1000 * (_lastScale - d.scale)
|
||||
: 100 * (_lastScale - d.scale));
|
||||
}
|
||||
}
|
||||
_lastScale = d.scale;
|
||||
@@ -128,6 +134,8 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
||||
onPointerSignal: !widget.enableControls
|
||||
? null
|
||||
: (pointerSignal) async {
|
||||
print("ponter signal");
|
||||
|
||||
// scroll-wheel zoom on desktop
|
||||
if (pointerSignal is PointerScrollEvent) {
|
||||
_scrollTimer?.cancel();
|
||||
@@ -146,6 +154,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
||||
onPointerDown: !widget.enableControls
|
||||
? null
|
||||
: (d) async {
|
||||
print("piinterodoiwn");
|
||||
if (d.buttons == kTertiaryButton || _rotating) {
|
||||
await widget.controller.rotateStart(
|
||||
d.localPosition.dx, d.localPosition.dy);
|
||||
@@ -157,6 +166,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
||||
onPointerMove: !widget.enableControls
|
||||
? null
|
||||
: (d) async {
|
||||
print("pointermove");
|
||||
if (d.buttons == kTertiaryButton || _rotating) {
|
||||
await widget.controller.rotateUpdate(
|
||||
d.localPosition.dx, d.localPosition.dy);
|
||||
@@ -168,6 +178,7 @@ class _FilamentGestureDetectorState extends State<FilamentGestureDetector> {
|
||||
onPointerUp: !widget.enableControls
|
||||
? null
|
||||
: (d) async {
|
||||
print("pointerup");
|
||||
if (d.buttons == kTertiaryButton || _rotating) {
|
||||
await widget.controller.rotateEnd();
|
||||
} else {
|
||||
|
||||
@@ -17,7 +17,7 @@ set(PLUGIN_NAME "polyvox_filament_plugin")
|
||||
link_directories("${CMAKE_CURRENT_SOURCE_DIR}/lib")
|
||||
|
||||
add_library(FILAMENT_SHADERS SHARED
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/include/material/image_material.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/include/material/image.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/include/material/unlit_opaque.c"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,15 +1,178 @@
|
||||
material {
|
||||
name : BakedColor,
|
||||
requires : [
|
||||
color
|
||||
],
|
||||
name : unlit_opaque,
|
||||
requires : [ uv0, uv1, color ],
|
||||
shadingModel : unlit,
|
||||
culling : none
|
||||
blending : ${BLENDING},
|
||||
doubleSided : ${DOUBLESIDED},
|
||||
transparency : ${TRANSPARENCY},
|
||||
flipUV : false,
|
||||
specularAmbientOcclusion : simple,
|
||||
specularAntiAliasing : true,
|
||||
clearCoatIorChange : false,
|
||||
reflections : screenspace,
|
||||
parameters : [
|
||||
|
||||
{ type : float3, name : specularFactor },
|
||||
{ type : float, name : glossinessFactor },
|
||||
|
||||
// Base Color
|
||||
{ type : int, name : baseColorIndex },
|
||||
{ type : float4, name : baseColorFactor },
|
||||
{ type : sampler2d, name : baseColorMap },
|
||||
{ type : mat3, name : baseColorUvMatrix, precision: high },
|
||||
|
||||
// Metallic-Roughness Map
|
||||
{ type : int, name : metallicRoughnessIndex },
|
||||
{ type : float, name : metallicFactor },
|
||||
{ type : float, name : roughnessFactor },
|
||||
{ type : sampler2d, name : metallicRoughnessMap },
|
||||
{ type : mat3, name : metallicRoughnessUvMatrix, precision: high },
|
||||
|
||||
// Normal Map
|
||||
{ type : int, name : normalIndex },
|
||||
{ type : float, name : normalScale },
|
||||
{ type : sampler2d, name : normalMap },
|
||||
{ type : mat3, name : normalUvMatrix, precision: high },
|
||||
|
||||
// Ambient Occlusion
|
||||
{ type : int, name : aoIndex },
|
||||
{ type : float, name : aoStrength },
|
||||
{ type : sampler2d, name : occlusionMap },
|
||||
{ type : mat3, name : occlusionUvMatrix, precision: high },
|
||||
|
||||
// Emissive Map
|
||||
{ type : int, name : emissiveIndex },
|
||||
{ type : float3, name : emissiveFactor },
|
||||
{ type : float, name : emissiveStrength },
|
||||
{ type : sampler2d, name : emissiveMap },
|
||||
{ type : mat3, name : emissiveUvMatrix, precision: high },
|
||||
|
||||
// Clear coat
|
||||
{ type : float, name : clearCoatFactor },
|
||||
{ type : float, name : clearCoatRoughnessFactor },
|
||||
{ type : int, name : clearCoatIndex },
|
||||
{ type : sampler2d, name : clearCoatMap },
|
||||
{ type : mat3, name : clearCoatUvMatrix, precision: high },
|
||||
{ type : int, name : clearCoatRoughnessIndex },
|
||||
{ type : sampler2d, name : clearCoatRoughnessMap },
|
||||
{ type : mat3, name : clearCoatRoughnessUvMatrix, precision: high },
|
||||
{ type : int, name : clearCoatNormalIndex },
|
||||
{ type : sampler2d, name : clearCoatNormalMap },
|
||||
{ type : mat3, name : clearCoatNormalUvMatrix, precision: high },
|
||||
{ type : float, name : clearCoatNormalScale },
|
||||
|
||||
// Reflectance
|
||||
{ type : float, name : reflectance }
|
||||
|
||||
${CUSTOM_PARAMS}
|
||||
],
|
||||
}
|
||||
|
||||
vertex {
|
||||
void materialVertex(inout MaterialVertexInputs material) {
|
||||
${CUSTOM_VERTEX}
|
||||
}
|
||||
}
|
||||
|
||||
fragment {
|
||||
void material(inout MaterialInputs material) {
|
||||
highp float2 uvs[2];
|
||||
uvs[0] = getUV0();
|
||||
uvs[1] = getUV1();
|
||||
|
||||
#if !defined(SHADING_MODEL_UNLIT)
|
||||
if (materialParams.normalIndex > -1) {
|
||||
highp float2 uv = uvs[materialParams.normalIndex];
|
||||
uv = (vec3(uv, 1.0) * materialParams.normalUvMatrix).xy;
|
||||
material.normal = texture(materialParams_normalMap, uv).xyz * 2.0 - 1.0;
|
||||
material.normal.xy *= materialParams.normalScale;
|
||||
}
|
||||
#if defined(SHADING_MODEL_LIT)
|
||||
if (materialParams.clearCoatNormalIndex > -1) {
|
||||
highp float2 uv = uvs[materialParams.clearCoatNormalIndex];
|
||||
uv = (vec3(uv, 1.0) * materialParams.clearCoatNormalUvMatrix).xy;
|
||||
material.clearCoatNormal = texture(materialParams_clearCoatNormalMap, uv).xyz * 2.0 - 1.0;
|
||||
material.clearCoatNormal.xy *= materialParams.clearCoatNormalScale;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
prepareMaterial(material);
|
||||
material.baseColor = getColor();
|
||||
material.baseColor = materialParams.baseColorFactor;
|
||||
|
||||
if (materialParams.baseColorIndex > -1) {
|
||||
highp float2 uv = uvs[materialParams.baseColorIndex];
|
||||
uv = (vec3(uv, 1.0) * materialParams.baseColorUvMatrix).xy;
|
||||
material.baseColor *= texture(materialParams_baseColorMap, uv);
|
||||
}
|
||||
|
||||
#if defined(BLEND_MODE_TRANSPARENT)
|
||||
material.baseColor.rgb *= material.baseColor.a;
|
||||
#endif
|
||||
|
||||
material.baseColor *= getColor();
|
||||
|
||||
#if !defined(SHADING_MODEL_UNLIT)
|
||||
|
||||
#if defined(SHADING_MODEL_LIT)
|
||||
material.roughness = materialParams.roughnessFactor;
|
||||
material.metallic = materialParams.metallicFactor;
|
||||
|
||||
// KHR_materials_clearcoat forbids clear coat from
|
||||
// being applied in the specular/glossiness model
|
||||
material.clearCoat = materialParams.clearCoatFactor;
|
||||
material.clearCoatRoughness = materialParams.clearCoatRoughnessFactor;
|
||||
|
||||
if (materialParams.clearCoatIndex > -1) {
|
||||
highp float2 uv = uvs[materialParams.clearCoatIndex];
|
||||
uv = (vec3(uv, 1.0) * materialParams.clearCoatUvMatrix).xy;
|
||||
material.clearCoat *= texture(materialParams_clearCoatMap, uv).r;
|
||||
}
|
||||
if (materialParams.clearCoatRoughnessIndex > -1) {
|
||||
highp float2 uv = uvs[materialParams.clearCoatRoughnessIndex];
|
||||
uv = (vec3(uv, 1.0) * materialParams.clearCoatRoughnessUvMatrix).xy;
|
||||
material.clearCoatRoughness *= texture(materialParams_clearCoatRoughnessMap, uv).g;
|
||||
}
|
||||
#endif
|
||||
|
||||
material.emissive = vec4(materialParams.emissiveStrength *
|
||||
materialParams.emissiveFactor.rgb, 0.0);
|
||||
|
||||
#if defined(SHADING_MODEL_SPECULAR_GLOSSINESS)
|
||||
material.glossiness = materialParams.glossinessFactor;
|
||||
material.specularColor = materialParams.specularFactor;
|
||||
#else
|
||||
material.reflectance = materialParams.reflectance;
|
||||
#endif
|
||||
|
||||
if (materialParams.metallicRoughnessIndex > -1) {
|
||||
highp float2 uv = uvs[materialParams.metallicRoughnessIndex];
|
||||
uv = (vec3(uv, 1.0) * materialParams.metallicRoughnessUvMatrix).xy;
|
||||
|
||||
#if defined(SHADING_MODEL_SPECULAR_GLOSSINESS)
|
||||
vec4 sg = texture(materialParams_metallicRoughnessMap, uv);
|
||||
material.specularColor *= sg.rgb;
|
||||
material.glossiness *= sg.a;
|
||||
#else
|
||||
vec4 mr = texture(materialParams_metallicRoughnessMap, uv);
|
||||
material.roughness *= mr.g;
|
||||
material.metallic *= mr.b;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (materialParams.aoIndex > -1) {
|
||||
highp float2 uv = uvs[materialParams.aoIndex];
|
||||
uv = (vec3(uv, 1.0) * materialParams.occlusionUvMatrix).xy;
|
||||
float occlusion = texture(materialParams_occlusionMap, uv).r;
|
||||
material.ambientOcclusion = 1.0 + materialParams.aoStrength * (occlusion - 1.0);
|
||||
}
|
||||
if (materialParams.emissiveIndex > -1) {
|
||||
highp float2 uv = uvs[materialParams.emissiveIndex];
|
||||
uv = (vec3(uv, 1.0) * materialParams.emissiveUvMatrix).xy;
|
||||
material.emissive.rgb *= texture(materialParams_emissiveMap, uv).rgb;
|
||||
}
|
||||
#endif
|
||||
|
||||
${CUSTOM_FRAGMENT}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user