当前位置:网站首页>Filament - Material basic graphics drawing

Filament - Material basic graphics drawing

2022-08-10 00:32:00 In hindsight

        Filament中,The custom material format is as follows:


material {
    name : mylit,
    requires : [
        uv0
    ],
    shadingModel : lit,

    parameters : [
        // The color must be passed in linear space, not sRGB
        {
            type : float3,
            name : baseColor
        },
        {
            type : float,
            name : roughness
        },
        {
            type : float,
            name : metallic
        },
        {
            type : float,
            name : reflectance
        },
        {
            type : float,
            name : anisotropy
        },
        {
            type : float4,
            name : emissive
        },
        {
            type : float,
            name : resolution
        },
        {
            type : float,
            name : i_time
        },
        {
            type : sampler2d,
            name : myTexture
        }
    ],
    specularAntiAliasing : true
}

fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);
        material.baseColor = texture(materialParams_myTexture, getUV0);
        material.roughness = materialParams.roughness;
        material.metallic = materialParams.metallic;
        material.reflectance = materialParams.reflectance;
        material.anisotropy = materialParams.anisotropy;
        material.emissive = materialParams.emissive;
    }
   
}

通过配置*.mat 文件,然后通过matc,将*.mat文件,编译为 *.filamat文件:

*.mat  ->  *.filamat  --> load filamat

This can be used in the programMaterial:

package com.filament.demo;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.os.Handler;
import android.util.AndroidRuntimeException;

import com.google.android.filament.Colors;
import com.google.android.filament.Engine;
import com.google.android.filament.Material;
import com.google.android.filament.MaterialInstance;
import com.google.android.filament.Texture;
import com.google.android.filament.TextureSampler;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;

public class TextMaterial {
    private Context mContext;
    private MaterialInstance mMaterialInstance;
    private Material mMaterial;
    private Engine mEngine;
    private final Object mLock = new Object();

    public TextMaterial(Context context, Engine engine) {
        mContext = context;
        mEngine = engine;
        mMaterial = createMaterial();
        mMaterialInstance = createMaterialInstance();
    }

    public Material getMaterial() {
        return mMaterial;
    }

    public MaterialInstance getMaterialInstance() {
        return mMaterialInstance;
    }

    private Material createMaterial() {
        ByteBuffer buffer = readUncompressedAsset("my.filamat");
        if (buffer == null) {
            throw new AndroidRuntimeException("load filamat failed");
        }
        Material.Builder builder = new Material.Builder();
        Material material = builder.payload(buffer, buffer.remaining()).build(mEngine);
        return material;
    }

    private MaterialInstance createMaterialInstance() {
        MaterialInstance materialInstance = mMaterial.createInstance();
        materialInstance.setParameter("metallic", 0.5f);
        materialInstance.setParameter("roughness", 0.32f);
        materialInstance.setParameter("reflectance", 0.5f);
        materialInstance.setParameter("anisotropy", 1.0f);
        materialInstance.setParameter("emissive", Colors.RgbaType.SRGB, 0.0f, 1f, 0f, 1.0f);
        return materialInstance;
    }


    private ByteBuffer readUncompressedAsset(String assetName) {
        AssetManager assetManager = mContext.getApplicationContext().getAssets();
        try {
            AssetFileDescriptor descriptor = assetManager.openFd(assetName);
            InputStream inputStream = descriptor.createInputStream();
            ByteBuffer dst = ByteBuffer.allocate((int) (descriptor.getLength()));
            ReadableByteChannel src = Channels.newChannel(inputStream);
            src.read(dst);
            src.close();
            dst.rewind();
            inputStream.close();
            return dst;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public void onDestroy() {
        synchronized (mLock) {
            if (mMaterialInstance != null && mEngine.isValid()) {
                mEngine.destroyMaterialInstance(mMaterialInstance);
                mMaterialInstance = null;
            }
            if (mMaterial != null && mEngine.isValid()) {
                mEngine.destroyMaterial(mMaterial);
                mMaterial = null;
            }
        }
    }
}

Materials alone do not draw objects,还需要Mesh,MeshThat is, vertex information needs to be created by yourself,Also available from modelGLTF中加载,Let's try to create a cube ourselves:

package com.filament.demo;

import com.google.android.filament.Engine;
import com.google.android.filament.IndexBuffer;
import com.google.android.filament.VertexBuffer;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class TextMesh {
    private static final int FLOAT_SIZE = 4;
    private static final int SHORT_SIZE = 2;
    private static final int VERTEX_COUNT = 1 * 4;
    private static final int VERTEX_SIZE = 3 * FLOAT_SIZE + 2 * FLOAT_SIZE;

    private Engine mEngine;
    private VertexBuffer mVertexBuffer;
    private IndexBuffer mIndexBuffer;

    public TextMesh(Engine engine) {
        mEngine = engine;
        mVertexBuffer = createVertexBuffer();
        mIndexBuffer = createIndexBuffer();
    }

    public VertexBuffer getVertexBuffer() {
        return mVertexBuffer;
    }

    public IndexBuffer getIndexBuffer() {
        return mIndexBuffer;
    }

    private VertexBuffer createVertexBuffer() {
        ByteBuffer vertexData = createVertexData();
        VertexBuffer vertexBuffer = new VertexBuffer.Builder()
                .bufferCount(1)
                .vertexCount(VERTEX_COUNT)
                .attribute(VertexBuffer.VertexAttribute.POSITION, 0,
                        VertexBuffer.AttributeType.FLOAT3, 0, VERTEX_SIZE)
                .attribute(VertexBuffer.VertexAttribute.UV0, 0,
                        VertexBuffer.AttributeType.FLOAT2, 3 * FLOAT_SIZE, VERTEX_SIZE)
                .build(mEngine);
        vertexBuffer.setBufferAt(mEngine, 0, vertexData);
        return vertexBuffer;
    }

    private IndexBuffer createIndexBuffer() {
        ByteBuffer indexData = createIndexData();
        IndexBuffer indexBuffer = new IndexBuffer.Builder()
                .indexCount(VERTEX_COUNT * 2)
                .bufferType(IndexBuffer.Builder.IndexType.USHORT)
                .build(mEngine);
        indexBuffer.setBuffer(mEngine, indexData);
        return indexBuffer;
    }

    private static ByteBuffer createVertexData() {
        ByteBuffer vertexData = ByteBuffer.allocate(VERTEX_COUNT * VERTEX_SIZE)
                .order(ByteOrder.nativeOrder());
        setData(vertexData, -1.0f, -1.0f, 0.0f, 0, 0);
        setData(vertexData, 1.0f, -1.0f, 0.0f, 1, 0);
        setData(vertexData, 1.0f, 1.0f, 0.0f, 1, 1);
        setData(vertexData, -1.0f, 1.0f, 0.0f, 0, 1);

        vertexData.flip();
        return vertexData;
    }

    private static ByteBuffer createIndexData() {
        ByteBuffer indexData = ByteBuffer.allocate(1 * 2 * 3 * SHORT_SIZE)
                .order(ByteOrder.nativeOrder());
        for (short i = 0; i < 1; i++) {
            short value = (short) (i * 4);
            indexData
                    .putShort(value)
                    .putShort((short) (value + 1))
                    .putShort((short) (value + 2))
                    .putShort(value)
                    .putShort((short) (value + 2))
                    .putShort((short) (value + 3));
        }
        indexData.flip();
        return indexData;
    }

    private static void setData(ByteBuffer vertexData, float x, float y, float z, float u, float v) {
        vertexData.putFloat(x);
        vertexData.putFloat(y);
        vertexData.putFloat(z);
        vertexData.putFloat(u);
        vertexData.putFloat(v);
    }

    public void onDestroy() {
        if (mIndexBuffer != null && mEngine.isValid()) {
            mEngine.destroyIndexBuffer(mIndexBuffer);
            mIndexBuffer = null;
        }
        if (mVertexBuffer != null && mEngine.isValid()) {
            mEngine.destroyVertexBuffer(mVertexBuffer);
            mVertexBuffer = null;
        }
    }
}

With material andMeshThe object can be drawn,但对Filament来说,How to represent a drawn object:Renderable:

        new RenderableManager.Builder(1)
                .boundingBox(new Box(0.0f, 0.0f, 0f,
                        1.0f, 1.0f, 1.0f))
                .geometry(0, RenderableManager.PrimitiveType.TRIANGLES,
                        mTextMesh.getVertexBuffer(), mTextMesh.getIndexBuffer(), 0, 1 * 6)
                .material(0, mTextMaterial.getMaterialInstance())
                .build(engine, mTextRenderable);

至此,准备工作完成,开始绘制:

            if (mUiHelper.isReadyToRender()) {
                if (mRenderer.beginFrame(mSwapChain, frameTimeNanos)) {
                    mRenderer.render(mView);
                    mRenderer.endFrame();
                }
            }

Welcome to exchange research together.

原网站

版权声明
本文为[In hindsight]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/222/202208092209037871.html