OSLテクスチャマッピング[複製]

Dec 04 2020

私はOSLとBlenderを初めて使用します。次のコードを使用して、平面上に円を生成しています。ただし、平面は2つの三角形に分割されているように見えます。OSLサークルが正しくマッピングされるようにこれを修正する方法を誰かが説明できますか?ありがとうございました!

shader Circle(
        float rad=0.75 [[float min=0, float max=1]],
        float sharp=0.8 [[float min=0, float max=1]],
        int rep=1[[int min=1, int max=10]],
        point cent=point(0.5, 0.5, 0),
    output color c = 0)
{
    point pt = point(rep*u, rep*v,0);
    float ctx = floor(pt[0])+cent[0];
    float cty = floor(pt[1])+cent[1];
    point ct = point(ctx, cty, 0);
    float d = fmod(distance(ct, pt), rep)/rad;

    c = 1-smoothstep(0.5*sharp, 1-0.5*sharp, d);

}

回答

1 RobinBetts Dec 04 2020 at 16:44

uおよびvは、OSLによって提供されるグローバル変数です。それらはパラメトリックUおよびVを指します。現在シェーディングされている三角形のシェーディングポイントの正規化された重心座標。これらは、[ジオメトリ]ノード> [パラメトリック出力]から取得した2Dベクトルで返されるものと同じUおよびVです。

マップされたクワッドのUとVを取得するには、次を使用して、オブジェクトのアクティブなUVマップからUとVを検索する必要がありますgetattribute()

shader Circle(
        float radius = 0.75,
        float sharpness = 0.8,
        int tiles = 1,
        point center = point(0.5, 0.5, 0.0),
        output color c = (0.0) 
        )
{
    vector UV = (0.0);
    int hasUV = getattribute( "geom:uv", UV);
  
    point pt = point(tiles*UV[0], tiles*UV[1],0);
    float ctx = floor(pt[0])+center[0];
    float cty = floor(pt[1])+center[1];
    point ct = point(ctx, cty, 0);
    float d = fmod(distance(ct, pt), tiles)/radius;

    c = 1-smoothstep(0.5*sharpness, 1-0.5*sharpness, d);
}

..しかし、ここで、Blenderマニュアルで満たされていない約束に遭遇します。これは、この回答の年齢から判断すると、今では修正されていると思われるかもしれません。奇妙なことに、ユーザーに関する限り、BlenderのOSLの実装は、ツリーのどこかにImage Textureノードgeom:uvがない限り、に値を与えることを拒否します。(OSLで他のUVマップを名前で評価する場合は、ツリーに、Image Textureノードに接続された同じ名前のUVマップノードも含まれている必要があります。)

したがって、ツリーは次のようになります。

この答えがあなたの時間を節約することを願っています.. :)