-->

分類

2016年7月25日 星期一

Android view static inner class in layout

    <view xmlns:android="http://schemas.android.com/apk/res/android"
          class="com.package.OuterClassName$InnerViewClassName">
</view>

2016年7月19日 星期二

Unity failed wireframe shader

tried to assign uv for each vertex of triangle as (0,0), (0,1), (1,0) then use interpolated uv value in fragment shader to determine if it should be drawn as edge of the triangle

C# script:


using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class SetTriangleVertUV4ForWireframe : MonoBehaviour {
    private enum UVType
    {
        none,
        t00,
        t01,
        t10
    }
    private Mesh mMesh;
    private int[] triangleIndices;
    private Vector2[] mUV;
    // Use this for initialization
    void Start()
    {
        mMesh = GetComponent().mesh;
        triangleIndices = mMesh.triangles;
        mUV = new Vector2[mMesh.vertices.Length];
        for (int i = 0; i < mUV.Length; i++)
        {
            //UVType.none
            mUV[i] = new Vector2(-1.0f, -1.0f);
        }
        for (int i = 0; i < triangleIndices.Length; i += 3)
        {
            Vector2 v0 = mUV[triangleIndices[i]];
            Vector2 v1 = mUV[triangleIndices[i + 1]];
            Vector2 v2 = mUV[triangleIndices[i + 2]];
            HashSet uvTypeSet = new HashSet();
            HashSet vertIndexSet = new HashSet();
            uvTypeSet.Add(UVType.t00);
            uvTypeSet.Add(UVType.t01);
            uvTypeSet.Add(UVType.t10);
            vertIndexSet.Add(i);
            vertIndexSet.Add(i + 1);
            vertIndexSet.Add(i + 2);

            Dictionary uvTypeDic = new Dictionary();
            addUVType(uvTypeDic, v0, i);
            addUVType(uvTypeDic, v1, i + 1);
            addUVType(uvTypeDic, v2, i + 2);


            foreach (KeyValuePair pair in uvTypeDic)
            {
                UVType type = pair.Key;
                if (uvTypeSet.Contains(type))
                {
                    uvTypeSet.Remove(type);
                    vertIndexSet.Remove(pair.Value);
                }
            }

            //uvTypeSet now contains UVType that are not used
            List resultUVType = new List();
            List resultIndices = new List();
            foreach (UVType type in uvTypeSet)
            {
                resultUVType.Add(type);
            }
            resultUVType.Sort();
            foreach (int index in vertIndexSet)
            {
                resultIndices.Add(index);
            }
            resultIndices.Sort();
            //convert unused UVType to Vector2 as UV coord and save to uv4
            for (int j = 0; j < resultIndices.Count; j++)
            {
                mUV[triangleIndices[resultIndices[j]]] = buildVector2ByUVType(resultUVType[j]);
            }
        }
        mMesh.uv4 = mUV;
    }

    private Vector2 buildVector2ByUVType(UVType type)
    {
        switch (type)
        {
            case UVType.t00:
                return new Vector2(0.0f, 0.0f);
            case UVType.t01:
                return new Vector2(0.0f, 1.0f);
            case UVType.t10:
                return new Vector2(1.0f, 0.0f);
            default:
                return new Vector2(-1.0f, -1.0f);
        }
    }

    private void addUVType(Dictionary dic, Vector2 v, int index)
    {
        UVType uvType = checkUVType(v);
        if (uvType != UVType.none && !dic.ContainsKey(uvType))
        {
            dic.Add(uvType, index);
        }
    }

    private UVType checkUVType(Vector2 v)
    {
        if (Mathf.Approximately(v.x, -1.0f))
        {
            return UVType.none;
        }
        if (Mathf.Approximately(v.x, 1.0f))
        {
            return UVType.t10;
        }
        if (Mathf.Approximately(v.y, 1.0f))
        {
            return UVType.t01;
        }
        return UVType.t00;
    }
}


Shader code:

Shader "Unlit/TestWireframeUV4"
{
 Properties
 {
  _MainTex ("Texture", 2D) = "white" {}
 }
 SubShader
 {
  Tags { "RenderType"="Opaque" }
  LOD 100

  Pass
  {
   CGPROGRAM
   #pragma vertex vert
   #pragma fragment frag
   // make fog work
   #pragma multi_compile_fog
   
   #include "UnityCG.cginc"

   struct appdata
   {
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    float2 uv4 : TEXCOORD3;
   };

   struct v2f
   {
    float2 uv : TEXCOORD0;
    float2 uv4 : TEXCOORD3;
    float4 vertex : SV_POSITION;
   };

   sampler2D _MainTex;
   float4 _MainTex_ST;
   
   v2f vert (appdata v)
   {
    v2f o;
    o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    o.uv4 = v.uv4;
    return o;
   }
   
   fixed4 frag (v2f i) : SV_Target
   {
    fixed4 col = tex2D(_MainTex, i.uv);
    if (length(i.uv4) > 0.7 && length(i.uv4) < 0.9) {
     //treated as edge of triangle
     return fixed4(0, 0, 0, 1);
    }
    return col;
   }
   ENDCG
  }
 }
}


result:
as you can see, some triangles don't have correct UV(at the top of the sphere). This is because sometimes the UV coordinates have conflicts in one triangle (e.g. (1,0), (1,0) for two vertices, in that case the second UV coordinate is discarded)




2016年7月5日 星期二

some old stuff


bump mapping by GLSL, but I didn't understance the relations between tangent, normal and binormal that time...


an image rendered by ray tracing, totally forgot  how I made photon mapping work...


3D drawing on Android