【问题标题】:Worldspace 2d texture displacemet in Unity Shader GraphUnity Shader Graph中的Worldspace 2d纹理置换
【发布时间】:2020-06-29 16:31:00
【问题描述】:

我正在开发一款 2D 自上而下的游戏。我有一个在单个大纹理上移动并在其上投射阴影的对象(只是一个模糊的深色精灵)。然而我发现,由于我的纹理有凹凸、岩石、折痕等,看起来影子精灵只是在地面上方盘旋。 所以我想我可以使用我的纹理作为置换贴图来根据纹理的表面扭曲阴影精灵。我正在尝试在 Shader Graph 中实现它,但我无法获得底层纹理的正确位置和比例来投射阴影。
我尝试实现一个简化版本的着色器,它精确地再现了它悬停在上方的Ground Texture 部分。

在这种情况下,缩放似乎已关闭,生成的纹理比原始纹理小很多。我不确定这个位置,但它似乎也关闭了。我错过了什么吗?还是有更简单的方法来实现这一点?

提前致谢。

【问题讨论】:

    标签: unity3d 2d shader game-engine shader-graph


    【解决方案1】:

    我不确定这是否是最优雅的解决方案,但我找到了。

    我应该使用Tiling and Offset 节点来缩放和移动地面纹理的UV。这是着色器图:

    现在,这个着色器使对象将其放置在其上的地面纹理部分投影到自身上。它似乎与纹理完美对齐。

    地面位置在代码中计算:

    [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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-16
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 2021-10-07
      相关资源
      最近更新 更多