• Unity论坛问答-Spherize(球面化)效果


    原贴地址: https://forum.unity.com/threads/spherize-alternative.907757/

    题主问道:
    我想做一个Gimp中的Spherize(球面化)滤镜效果, 然后使用了ShaderGraph中的Spherize节点, 但是效果不对.

    bgolus回答:
    你想要的效果叫做stereographic projection(球极投影, 立体投影), 在PhotoShop/Gimp中被叫做Spherize.
    ShaderLab

    Shader "Unlit/StereographicProjectionBubble"
    {
        Properties
        {
            _MainTex ("Texture", 2D) = "white" {}
            _PanSpeed ("Pan Speed", Float) = 0.1
            _Spherify ("Spherify", Range(0,1)) = 1
        }
        SubShader
        {
            Tags { "Queue"="Transparent" "RenderType"="Transparent" "PreviewType"="Plane" }
            LOD 100
    
            Blend SrcAlpha OneMinusSrcAlpha
    
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
    
                #include "UnityCG.cginc"
    
                struct v2f
                {
                    float4 pos : SV_POSITION;
                    float2 uv : TEXCOORD0;
                };
    
                sampler2D _MainTex;
                float4 _MainTex_ST;
    
                float _PanSpeed;
                float _Spherify;
    
                v2f vert (appdata_base v)
                {
                    v2f o;
                    o.pos = UnityObjectToClipPos(v.vertex);
                    o.uv = v.texcoord.xy;
                    return o;
                }
    
                fixed4 frag (v2f i) : SV_Target
                {
                    float2 centered_uv = i.uv * 2.0 - 1.0;
                    float z = sqrt(1.0 - saturate(dot(centered_uv.xy, centered_uv.xy)));
                    float2 spherified_uv = centered_uv / (z + 1.0);
                    float2 uv = spherified_uv * 0.5 + 0.5;
    
                    uv = lerp(i.uv, uv, _Spherify);
                    uv = TRANSFORM_TEX(uv, _MainTex);
                    uv.x += frac(_Time.y * _PanSpeed);
                    fixed4 col = tex2D(_MainTex, uv);
    
                    half sqrDist = dot(centered_uv.xy, centered_uv.xy);
                    half mask = 1.0 - sqrDist;
                    mask = saturate(mask / fwidth(mask));
    
                    col.a *= mask;
    
                    return col;
                }
                ENDCG
            }
        }
    }

    ShaderGraph

    一些说明:
        1. ShaderGraph中的Spherize在文档中介绍如下:
        Applies a spherical warping effect similar to a fisheye camera lens

        也就是鱼眼效果
        
        算法大约如下:
            a. 计算点P到圆心的距离d
            b. P' = P * d^4
        当P点在圆周上时, P'与P重合
        P点在圆内时, d<1, P' < P, 并且越接近圆心, P'相比于P越小
        P点在圆外时则相反, d >1, P'>P, 越远离圆心, P'相比于P越大
        
        2. 关于球极投影
        一个半径为1的球体, 从北极点N出发, 过下半球的点P做一条射线, 较赤道平面于P', 参考下图
       
       
        其中P点的坐标为(x, y, z), P'的坐标为(X, Y, 0), 它们之间的关系为:
        
        
        ShaderLab的代码首先将UV转换到(-1, 1), 然后投射到下半球, 计算出z, 注意这里计算得到的z是正数, 而下半球的z应该是负数, 所以1-z变成了1+z.
        再计算出P'坐标, 最后在映射回(0, 1), 从图易知, 越靠近圆心部分, 图形放大的越厉害, 反之缩小的越厉害.
        当UV的值超出圆的范围, 此时z = 0, P' = (x, y), 也就是保持不变.

  • 相关阅读:
    Eluments ui 二级下拉菜单 回显问题
    数据结构与算法李春葆系列之二叉树设计性实验
    数据结构与算法李春葆之判断二叉树子树
    数据结构与算法李春葆系列 判断二叉树相同算法
    数据结构与算法李春葆系列之数组和广义表思维导图
    数据结构与算法李春葆系列之递归思维导图
    C语言之scanf函数
    c标准库(STL)系列-sscanf()
    一个可以把windows系统跑死的Java程序
    解决ubuntu19.0‘E: 无法获得锁 /var/lib/dpkg/lock-frontend
  • 原文地址:https://www.cnblogs.com/yusjoel/p/13260354.html
Copyright © 2020-2023  润新知