簡體   English   中英

Unity Shader Graph中的Worldspace 2d紋理置換

[英]Worldspace 2d texture displacemet in Unity Shader Graph

我正在開發一個 2d 自上而下的游戲。 我有一個 object 在單個大紋理上移動並在其上投射陰影(只是一個模糊的暗精靈)。 然而我發現,由於我的紋理有凹凸、岩石、折痕等,看起來影子精靈只是在地面上方盤旋。 所以我想我可以使用我的紋理作為位移 map 來根據紋理的表面扭曲陰影精靈。 我正在嘗試在 Shader Graph 中實現它,但我無法獲得正確的 position 和底層紋理的比例以投射陰影。
我試圖實現一個簡化版本的着色器,它可以精確地再現它懸停在上面的Ground Texture部分。

在此處輸入圖像描述

在這種情況下,縮放似乎關閉了,生成的紋理比原始紋理小很多。 我不確定 position 但它似乎也關閉了。 我錯過了什么嗎? 還是有更簡單的方法來實現這一點?

提前致謝。

我不確定這是否是最優雅的解決方案,但我找到了一個。

我應該使用Tiling and Offset節點來縮放和移動地面紋理的 UV。 這是着色器圖:

在此處輸入圖像描述

現在,此着色器使 object 將放置在其上的地面紋理部分投影到自身上。 它似乎與紋理完美對齊。

接地 position 在代碼中計算:

[RequireComponent(typeof(SpriteRenderer))]
public class displaced_shadow : MonoBehaviour
{
    SpriteRenderer sr;
    Rect rect;
    MaterialPropertyBlock material_properties;
    float pixels_per_unit;

    public Vector2 Size //get size of the texture in Unity units
    {
        get { return new Vector2(rect.width * transform.localScale.x/ pixels_per_unit, rect.height * transform.localScale.y/ pixels_per_unit); } 
    }

    private void Awake()
    {
        sr = GetComponent<SpriteRenderer>();
        rect = sr.sprite.rect;
        pixels_per_unit = sr.sprite.pixelsPerUnit;
        material_properties = new MaterialPropertyBlock();
    }

    // Update is called once per frame
    void Update()
    {
        Vector2 relative_position = CalculateRelativePostion();
        FeedMaterial(relative_position);
    }

    private Vector2 CalculateRelativePostion() //calculate the position relative to the background in [0,1] range
    {
        if (background_floor.This == null) return Vector3.zero;

        Vector2 bg_position = background_floor.This.Position; //get the size and position of the background texture
        Vector2 bg_size = background_floor.This.Size;

        float origin_x1 = transform.position.x - Size.x/2f; //calculate the top left corner positions in case textures have their origins in the center
        float origin_y1 = transform.position.y - Size.y / 2f;
        float origin_x2 = bg_position.x - bg_size.x / 2f;
        float origin_y2 = bg_position.y - bg_size.y / 2f;

        float x = (origin_x1 - origin_x2) / bg_size.x; //get the [0,1] position of the object relative to the ground texture
        float y = (origin_y1 - origin_y2) / bg_size.y;

        return new Vector2(x, y);
    }

    private void FeedMaterial(Vector2 relative_position)
    {
        sr.GetPropertyBlock(material_properties);
        material_properties.SetVector("_GroundPosition", relative_position);
        sr.SetPropertyBlock(material_properties);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM