버텍스 셰이더로 곡면 만들기

9283 단어 ShaderUnity

하고 싶은 일



이미지를 임의의 곡률로 원통형으로 구부릴 때의 이미지를 만들어야 했습니다.

GIF에서는 곡률 반경을 1~3unit로 변동시키고 있습니다.

기하학적 이야기





점 P의 좌표와 r을 알고 있고, P '의 좌표를 구하고 싶습니다. 원의 전체 둘레가 2πr(2π)로 그 중 θ만이므로 l=rθ입니다. 이제 θ가 구해졌습니다. 그리고는 x는 cos, y는 sin으로 좌표가 구해집니다.

구현



C#에서 정점 버퍼를 괴롭히는 것이 좋지만, 셰이더로 괴롭히는 것이 빠르기 쉽기 때문에 이번은 SurfaceShader로 씁니다. 모델 쪽은 적당히 세세한 그물 모양의 직사각형을 준비해 둡니다. (가로폭을 1unit로)

C#에서 곡률 반경을 받기 위해 _Radius 를 선언합니다.
Properties
{
    _MainTex ("Albedo (RGB)", 2D) = "white" {}
    _Radius ("Radius", Range(1, 20)) = 1.0
}

정점 셰이더를 명시합니다.
#pragma surface surf Lambert vertex:vert

정점 쉐이더 본체입니다. 간편하게하기 위해, 가로폭 1unit이었던 모델을 πunit에 늘리고 나서 처리하고 있습니다.
void vert(inout appdata_full v, out Input o )
{
    UNITY_INITIALIZE_OUTPUT(Input, o);
    float pi = 3.1415926;
    float l = v.vertex.z * pi / 2;
    float r = _Radius;
    float th = l/r;
    v.vertex.xyz = float3(v.vertex.x *pi/2, r*cos(th)-r, r*sin(th));
}

코드 전체



arch.shader
Shader "Custom/arch"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Radius ("Radius", Range(1, 20)) = 1.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        Cull off

        CGPROGRAM
        #pragma surface surf Lambert vertex:vert
        #pragma target 3.0

        sampler2D _MainTex;
        float _Radius;
        struct Input
        {
            float2 uv_MainTex;
        };

        void vert(inout appdata_full v, out Input o )
        {
            UNITY_INITIALIZE_OUTPUT(Input, o);
            float pi = 3.1415926;
            float l = v.vertex.z * pi / 2;
            float r = _Radius;
            float th = l/r;
            v.vertex.xyz = float3(v.vertex.x *pi/2, r*cos(th)-r, r*sin(th));
        }

        void surf (Input IN, inout SurfaceOutput o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

좋은 웹페이지 즐겨찾기