Import mesh as 2 sided (postrocessor)

Лучший способ помочь другим, поделиться своими находками.

Import mesh as 2 sided (postrocessor)

Сообщение waruiyume 29 авг 2013, 04:39

Just throw it into folder named Editor, and put the models you want doubled into a folder named Double-Sided. You might have to reimport your models to see the effects.
http://forum.unity3d.com/threads/197923 ... al-shaders

Синтаксис:
Используется csharp
    using UnityEngine;
    using UnityEditor;
    using System;
    using System.Collections.Generic;
     
    // Doubles and flips imported geometry
     
    public class DoubleSidedModelImporter : AssetPostprocessor {
       
        protected const string kFolderName = "double-sided";
       
        protected void OnPostprocessModel(GameObject modelPrefab) {
           
            // Only double geometry on models in appropriately named folders
            if (!assetPath.ToLower().Contains(kFolderName)) {
                return;
            }
           
            // Collect all meshes, both static and skinned
            var allMeshes = new HashSet<Mesh>();
            var meshFilters = new List<MeshFilter>(
                modelPrefab.GetComponentsInChildren<MeshFilter>()
            );
            foreach (var filter in meshFilters) {
                if (!allMeshes.Contains(filter.sharedMesh)) {
                    allMeshes.Add(filter.sharedMesh);
                }
            }
            var skinnedMeshRenderers = new List<SkinnedMeshRenderer>(
                modelPrefab.GetComponentsInChildren<SkinnedMeshRenderer>()
            );
            foreach (var skinnedRenderers in skinnedMeshRenderers) {
                if (!allMeshes.Contains(skinnedRenderers.sharedMesh)) {
                    allMeshes.Add(skinnedRenderers.sharedMesh);
                }
            }
            foreach (var mesh in allMeshes) {
               
                // Invert normals on duplicated geometry
                var oldVertexCount = mesh.vertexCount;
                var newVertices = DoubleArray(mesh.vertices);
                var newNormals = DoubleArray(mesh.normals);
                for (var i = newNormals.Length/2; i < newNormals.Length; ++i) {
                    newNormals[i] = -newNormals[i];
                }
               
                // Invert tangent W components to account for mirrored UVs
                var newTangents = DoubleArray(mesh.tangents);
                for (var i = newTangents.Length/2; i < newTangents.Length; ++i) {
                    newTangents[i].w = -newTangents[i].w;
                }
               
                // All other attributes remain the same
                var newColors = DoubleArray(mesh.colors);
                var newUVs = DoubleArray(mesh.uv);
                var newUV2s = DoubleArray(mesh.uv2);
                var newBoneWeights = DoubleArray(mesh.boneWeights);
               
                // Reverse winding on doubled triangles so front face matches normal
                // Also point doubled triangles at doubled vertex indices
                var triangleLists = new List<int[]>();
                for (var submeshIndex = 0; submeshIndex < mesh.subMeshCount; ++submeshIndex) {
                    var oldTriangles = mesh.GetTriangles(submeshIndex);
                    var newTriangles = DoubleArray(oldTriangles);
                    for (var i = oldTriangles.Length/3; i < oldTriangles.Length/3*2; ++i) {
                       
                        newTriangles[i*3] += oldVertexCount;
                       
                        var temp = newTriangles[i*3+1] + oldVertexCount;
                        newTriangles[i*3+1] = newTriangles[i*3+2] + oldVertexCount;
                        newTriangles[i*3+2] = temp;
                    }
                    triangleLists.Add(newTriangles);
                }
               
                // Assign all vertex attributes
                mesh.vertices = newVertices;
                mesh.normals = newNormals;
                mesh.tangents = newTangents;
                mesh.colors = newColors;
                mesh.uv = newUVs;
                mesh.uv2 = newUV2s;
                mesh.boneWeights = newBoneWeights;
               
                // Assign triangles last, so they match vertices
                for (var submeshIndex = 0; submeshIndex < mesh.subMeshCount; ++submeshIndex) {
                    mesh.SetTriangles(triangleLists[submeshIndex], submeshIndex);
                }
            }
        }
       
        // Returns the input array concatenated with itself
        protected static T[] DoubleArray<T>(T[] input) {
            var newArray = new T[input.Length*2];
            Array.Copy(
                input,
                0,
                newArray,
                0,
                input.Length
            );
            Array.Copy(
                input,
                0,
                newArray,
                input.Length,
                input.Length
            );
            return newArray;
        }
       
    }
 
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Import mesh as 2 sided (postrocessor)

Сообщение BornFoRdeatH 29 авг 2013, 04:59

Это для корректного освещения? или зачем это и чем оправдано удвоение геометрии?
Не бойся, если ты один, бойся, если ты ноль.
BornFoRdeatH
Адепт
 
Сообщения: 2377
Зарегистрирован: 22 окт 2011, 23:41
Откуда: Украина
Skype: bornfordeath

Re: Import mesh as 2 sided (postrocessor)

Сообщение waruiyume 29 авг 2013, 05:41

Да, для освещения.
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Import mesh as 2 sided (postrocessor)

Сообщение jetyb 06 сен 2013, 07:54

Все равно не врубаюсь, чем хуже просто написать в шейдере Cull Off?
Освещение? Решается, для ламберта просто брать abs от скалярного произведения на нормаль.
jetyb
Адепт
 
Сообщения: 1486
Зарегистрирован: 31 окт 2011, 17:21

Re: Import mesh as 2 sided (postrocessor)

Сообщение waruiyume 06 сен 2013, 08:29

Определёно, это решит все проблемы (popcorn)
У вас нет доступа для просмотра вложений в этом сообщении.
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Import mesh as 2 sided (postrocessor)

Сообщение jetyb 06 сен 2013, 10:14

Не продумал. Но все равно это решается на шейдерном уровне.Я так понимаю, требуется показывать плоскость с освещенной стороны светлой, а с неосвещенной - темной?
Синтаксис:
Используется csharp
Shader "Custom/CullOff" {
Properties {
      _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader {
          Cull Off
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf CullLambert

      half4 LightingCullLambert (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
          half NdotL = dot (s.Normal, lightDir);
                  if(dot(s.Normal, viewDir) < 0) NdotL = -NdotL;
          NdotL = max(0, NdotL);
          half4 c;
          c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 2);
          c.a = s.Alpha;
          return c;
      }

      struct Input {
          float2 uv_MainTex;
      };
      sampler2D _MainTex;
      void surf (Input IN, inout SurfaceOutput o) {
          o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
      }
      ENDCG
    }
    Fallback "Diffuse"
}
 

С тангенсами можно разобраться аналогично.
jetyb
Адепт
 
Сообщения: 1486
Зарегистрирован: 31 окт 2011, 17:21

Re: Import mesh as 2 sided (postrocessor)

Сообщение gnoblin 06 сен 2013, 13:02

(3A4OT)
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт


Вернуться в Исходники (Копилка)

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2