Jump to content
Unity Insider Forum
Sign in to follow this  
Elharter

Material/Shader/Script-Problem mit Transparenz

Recommended Posts

Hallo,

ich eröffne den Thread hier weil ich nicht genau weiß ob er ins Scripting, Shader oder sonstwo hingehört.

Folgendes Problem:

Ich erzeuge mit einem Script "Wände" um ein Terrain. Funktioniert alles wie es soll, jedoch sind die beiden Wände auf der Hinterseite (also die, die man von innen sieht) immer transparent.
Existieren tun alle 4 Wände.

Ich vermute ein Shader/Material/Script Problem und komme nicht auf die Lösung....habe bereits (gefühlt) alles probiert > Material wechseln, Shader wechseln, usw usw.

 

Jemand eine Idee?

 

 Parts of the Code:
//-------------------------------------
// new material for the four Baseboards
Material newMat = new Material(Shader.Find("Diffuse"));
newMat.color = selectColor;
newMat.mainTexture = selectTexture;
newMat.name = "BaseboardsMaterial";

//--------------------------------------
// New Object for our mesh border
Mesh CreateEdgeObject(string name)
{
edgeG = new GameObject();
edgeG.name = name;
meshFilter = (MeshFilter)edgeG.AddComponent(typeof(MeshFilter));
edgeG.AddComponent(typeof(MeshRenderer));
Mesh m = new Mesh();
m.name = edgeG.name;
return m;
}
//--------------------------------------
// finalize our border object
void FinalizeEdgeObject(Mesh m, Material mat)
{
m.vertices = vertices;
m.uv = uvs;
m.triangles = triangles;
m.RecalculateNormals();

meshFilter.sharedMesh = m;
m.RecalculateBounds();
meshFilter.GetComponent<Renderer>().material = mat;
edgeG.transform.parent = trackobjectsParent.transform;
edgeG.transform.localPosition = new Vector3(edgeG.transform.localPosition.x, 30, edgeG.transform.localPosition.z);
edgeG.isStatic = true;

}

 

Capture.JPG

Share this post


Link to post
Share on other sites

Ich vermute mal alle 4 Wände sind von Innen transparent?
Vermutlich ein "Fehler" beim Erzeugen des Meshes. Wenn die Normalen der Meshwände nach Außen zeigen, dann sind die Wände von innen nicht sichtbar.

3 Lösungsmöglichkeiten:

  • des Mesh anders konstruieren (doppelte Wände, 1 Wand die nach außen zeigt und eine Wand die nach innen zeigt)
  • alle 4 erzeugten Meshwände 1x kopieren und nach innen drehen
    als Beispiel: die erzeugte Wandseite wird 1xkopiert und 1x um 180 Grad gedreht, damit zeigt die Außenwand der kopierten Wand nun nach innen.
  • Double Sided Shader verwenden, dieser verwendet die Normalen des Meshes auch für die Innenseiten, damit wird die Wand innen sichtbar
  • Like 1

Share this post


Link to post
Share on other sites

Hab mich mal an dem Generator probiert, leider ist er nicht so einfach umzustellen, da er die Pivot-Points der Meshes nicht in die Mitte der Meshes platziert und dadurch kann man den erzeugten Mesh nicht einfach drehen.

Share this post


Link to post
Share on other sites

So, nun hatte ich einmal angefangen. Hier die Lösung mit verdoppelten Wänden und einem einfachen Shader:

using UnityEngine;
using UnityEditor;
using System.Collections;

public class CreateTerrainBaseboards : ScriptableWizard
{

    // PUBLIC DATA
    public float detail = 2.0f;
    public float globalH = -40.0f;
    public Color selectColor = Color.white;
    public float UVFactor = 8.0f;
    public Texture selectTexture;

    // PRIVATE DATA
    private GameObject objterrain = null;
    private Terrain terrain;
    private Vector3 posTerrain;
    private GameObject edgeG;
    private MeshFilter meshFilter;
    private Vector3[] vertices;
    private Vector2[] uvs;
    private int[] triangles;
    private GameObject[] walls = new GameObject[4];
    private int  wallIndex = 0;

    [MenuItem("Terrain/Create Terrain Baseboards...")]
    static void CreateWizard()
    {
        ScriptableWizard.DisplayWizard("Create TerrainBaseboards", typeof(CreateTerrainBaseboards));
    }


    void OnWizardCreate()
    {
        wallIndex = 0;

        // selected terrain
        objterrain = Selection.activeGameObject;

        // try to get terrain 
        if (objterrain == null) { terrain = Terrain.activeTerrain; }
        else { terrain = objterrain.GetComponent<Terrain>(); }

        // position terrain
        posTerrain = terrain.transform.position;

        // init tab
        int sizeTab = (int)(terrain.terrainData.size.x / detail) + 1;
        float[] hh = new float[sizeTab];

        //-------------------------------------
        // new material for the four Baseboards
        Material newMat = new Material(Shader.Find("Diffuse"));
        newMat.color = selectColor;
        newMat.mainTexture = selectTexture;
        newMat.name = "BaseboardsMaterial";


        //**************************************************************************
        //****************** FIRST	BORDER
        //**************************************************************************		
        int id = 0;
        Vector2 terPos = new Vector2(0, 0.001f);
        for (float x = 0; x <= terrain.terrainData.size.x; x += detail)
        {
            terPos.x = x / terrain.terrainData.size.x;
            hh[id++] = terrain.terrainData.GetInterpolatedHeight(terPos.x, terPos.y);
        }
        Mesh m = CreateEdgeObject("BBorderX0");

        int numVertices = sizeTab * 2;
        int numTriangles = (sizeTab - 1) * 2 * 3;
        vertices = new Vector3[numVertices];

        uvs = new Vector2[numVertices];
        triangles = new int[numTriangles];
        float uvFactor = 1.0f / UVFactor;

        // VERTICES
        int index = 0;
        for (int i = 0; i < sizeTab; i++)
        {
            float xx = i * detail;
            vertices[index] = new Vector3(xx, hh[i], 0) + posTerrain;
            uvs[index++] = new Vector2(i * uvFactor, 1);
            vertices[index] = new Vector3(xx, globalH, 0) + posTerrain;
            uvs[index++] = new Vector2(i * uvFactor, 0);
        }
        // TRIANGLES
        for (int i = 0; i < numTriangles / 3; i++)
        {
            if (i - ((i / 2) * 2) == 0)
            {   //IMPAIR
                triangles[i * 3] = i + 1;
                triangles[i * 3 + 1] = i;
                triangles[i * 3 + 2] = i + 2;
            }
            else
            {
                //PAIR
                triangles[i * 3] = i;
                triangles[i * 3 + 1] = i + 1;
                triangles[i * 3 + 2] = i + 2;
            }
        }
        FinalizeEdgeObject(m, newMat);

        //**************************************************************************
        //****************** SECOND BORDER
        //**************************************************************************		
        id = 0;
        terPos.y = 0.9990f;
        for (float x = 0; x <= terrain.terrainData.size.x; x += detail)
        {
            terPos.x = x / terrain.terrainData.size.x;
            hh[id++] = terrain.terrainData.GetInterpolatedHeight(terPos.x, terPos.y);
        }
        m = CreateEdgeObject("BBorderXZ");
        // VERTICES
        index = 0;
        for (int i = 0; i < sizeTab; i++)
        {
            float xx = i * detail;
            vertices[index] = new Vector3(xx, hh[i], terrain.terrainData.size.z) + posTerrain;
            uvs[index++] = new Vector2(i * uvFactor, 1);
            vertices[index] = new Vector3(xx, globalH, terrain.terrainData.size.z) + posTerrain;
            uvs[index++] = new Vector2(i * uvFactor, 0);
        }
        // TRIANGLES
        for (int i = 0; i < numTriangles / 3; i++)
        {
            if (i - ((i / 2) * 2) == 0)
            {   //IMPAIR
                triangles[i * 3] = i + 1;
                triangles[i * 3 + 1] = i + 2;
                triangles[i * 3 + 2] = i;
            }
            else
            {
                //PAIR
                triangles[i * 3] = i;
                triangles[i * 3 + 1] = i + 2;
                triangles[i * 3 + 2] = i + 1;
            }
        }
        FinalizeEdgeObject(m, newMat);

        //**************************************************************************
        //****************** THIRD BORDER
        //**************************************************************************		
        id = 0;
        terPos.x = 0.001f;
        for (float x = 0; x <= terrain.terrainData.size.z; x += detail)
        {
            terPos.y = x / terrain.terrainData.size.z;
            hh[id++] = terrain.terrainData.GetInterpolatedHeight(terPos.x, terPos.y);
        }
        m = CreateEdgeObject("BBorderZ0");
        // VERTICES
        index = 0;
        for (int i = 0; i < sizeTab; i++)
        {
            float xx = i * detail;
            vertices[index] = new Vector3(0, hh[i], xx) + posTerrain;
            uvs[index++] = new Vector2(i * uvFactor, 1);
            vertices[index] = new Vector3(0, globalH, xx) + posTerrain;
            uvs[index++] = new Vector2(i * uvFactor, 0);
        }
        // TRIANGLES
        for (int i = 0; i < numTriangles / 3; i++)
        {
            if (i - ((i / 2) * 2) == 0)
            {   //IMPAIR
                triangles[i * 3] = i + 1;
                triangles[i * 3 + 1] = i + 2;
                triangles[i * 3 + 2] = i;
            }
            else
            {
                //PAIR
                triangles[i * 3] = i;
                triangles[i * 3 + 1] = i + 2;
                triangles[i * 3 + 2] = i + 1;
            }
        }
        //......
        FinalizeEdgeObject(m, newMat);

        //**************************************************************************
        //****************** FOURTH BORDER
        //**************************************************************************		
        id = 0;
        terPos.x = 0.999f;
        for (float x = 0; x <= terrain.terrainData.size.z; x += detail)
        {
            terPos.y = x / terrain.terrainData.size.z;
            hh[id++] = terrain.terrainData.GetInterpolatedHeight(terPos.x, terPos.y);
        }
        m = CreateEdgeObject("BBorderZX");

        // VERTICES
        index = 0;
        for (int i = 0; i < sizeTab; i++)
        {
            float xx = i * detail;
            vertices[index] = new Vector3(terrain.terrainData.size.x, hh[i], xx) + posTerrain;
            uvs[index++] = new Vector2(i * uvFactor, 1);
            vertices[index] = new Vector3(terrain.terrainData.size.x, globalH, xx) + posTerrain;
            uvs[index++] = new Vector2(i * uvFactor, 0);
        }
        // TRIANGLES
        for (int i = 0; i < numTriangles / 3; i++)
        {
            if (i - ((i / 2) * 2) == 0)
            {   //IMPAIR
                triangles[i * 3] = i + 1;
                triangles[i * 3 + 1] = i;
                triangles[i * 3 + 2] = i + 2;
            }
            else
            {
                //PAIR
                triangles[i * 3] = i;
                triangles[i * 3 + 1] = i + 1;
                triangles[i * 3 + 2] = i + 2;
            }
        }
        FinalizeEdgeObject(m, newMat);

        // Weitere 4 Wände erzeugen
        index = 0;
        foreach (GameObject wall in walls)
        {
            if (index == 0) // Wand 1 BBorderX0
            {
                GameObject border = Instantiate(wall, wall.transform.position, Quaternion.identity);
                border.transform.eulerAngles = new Vector3(-180f, 0f, 0f);
                border.transform.Translate(new Vector3(0, -globalH, 0));
                border.transform.parent = terrain.transform;
            }

            if (index == 1) // Wand 2 BBorderXZ
            {
                GameObject border = Instantiate(wall, wall.transform.position, Quaternion.identity);
                border.transform.eulerAngles = new Vector3(-180f, 0f, 0f);
                border.transform.Translate(new Vector3(0, -globalH, -terrain.terrainData.size.z*2));
                border.transform.parent = terrain.transform;
            }

            if (index == 2) // Wand 3 BBorderXZ
            {
                GameObject border = Instantiate(wall, wall.transform.position, Quaternion.identity);
                border.transform.eulerAngles = new Vector3(0f, -180f, 0f);
                border.transform.Translate(new Vector3(0, 0, -terrain.terrainData.size.z));
                border.transform.parent = terrain.transform;
            }

            if (index == 3) // Wand 3 BBorderXZ
            {
                GameObject border = Instantiate(wall, wall.transform.position, Quaternion.identity);
                border.transform.eulerAngles = new Vector3(0f, -180f, 0f);
                border.transform.Translate(new Vector3(-terrain.terrainData.size.x * 2, 0, -terrain.terrainData.size.z));
                border.transform.parent = terrain.transform;
            }

            index++;
        }

    }

    //--------------------------------------
    // New Object for our mesh border
    Mesh CreateEdgeObject(string name)
    {
        edgeG = new GameObject();
        edgeG.name = name;
        meshFilter = (MeshFilter)edgeG.AddComponent(typeof(MeshFilter));
        edgeG.AddComponent(typeof(MeshRenderer));
        Mesh m = new Mesh();
        m.name = edgeG.name;

        walls[wallIndex] = edgeG;
        wallIndex++;

        return m;
    }

    //--------------------------------------
    // finalize our border object
    void FinalizeEdgeObject(Mesh m, Material mat)
    {
        m.vertices = vertices;
        m.uv = uvs;
        m.triangles = triangles;
        m.RecalculateNormals();

        meshFilter.sharedMesh = m;
        m.RecalculateBounds();
        meshFilter.GetComponent<Renderer>().material = mat;
        edgeG.transform.parent = terrain.transform;
        edgeG.isStatic = true;
    }
}

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×