Реализация эффекта рекламного щита, при котором полигон всегда смотрит в сторону камеры при её вращении.
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP, *)' with 'UnityObjectToClipPos(*)'```markdown
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
```shadere "Unlit/fll-Billboard" {
Свойства {
_MainTex ("Основное изображение", 2D) = "white" {}
_Color ("Цветовая накладка", Color) = (1, 1, 1, 1)
_VerticalBillboarding ("Вертикальные ограничения", Range(-5, 5)) = 2
}
Подшейдер {
// Необходимо отключить пакетирование из-за вершинной анимации
Теги {"Очередь"="Прозрачный" "Игнорировать проектор"="Истина" "Тип рендера"="Прозрачный" "Отключить пакетирование"="Истина"}
Скрыть обратную сторону от
Пропускать запись Z
CGPROGRAM
#pragma вершина vert
#pragma фрагмент frag
#include "Lighting.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
fixed _VerticalBillboarding;
struct a2v {
float4 вершина : POSITION;
float4 текстура : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (a2v v) {
v2f o;
// Предполагаем, что центр в пространстве объекта фиксирован
float3 center = float3(0, 0, 0);
float3 viewer = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1));
float3 normalDir = viewer - center;
// Если _VerticalBillboarding равно 1, мы используем желаемое направление просмотра как направление нормали
// То есть направление нормали фиксировано
// Или если _VerticalBillboarding равно 0, y нормали равно 0
// То есть направление верха фиксировано
normalDir.y = normalDir.y * _VerticalBillboarding;
normalDir = normalize(normalDir);
// Получаем приближенное направление верха
// Если направление нормали уже направлено вверх, то направление верха направлено вперед
float3 upDir = abs(normalDir.y) > 0.999 ? float3(0, 0, 1) : float3(0, 1, 0);
float3 rightDir = normalize(cross(upDir, normalDir)) * -1;
upDir = normalize(cross(normalDir, rightDir));
``` // Используем три вектора для вращения квадрата
float3 centerOffs = v. вершина. xyz - center;
float3 localPos = center + rightDir * centerOffs. x + upDir * centerOffs. y + normalDir * centerOffs. z;
o. pos = UnityObjectToClipPos(float4(localPos, 1));
o. uv = TRANSFORM_TEX(v. текстура, _MainTex);```c++
return o;
}
fixed4 frag (v2f i) : SV_Target {
fixed4 c = tex2D (_MainTex, i. uv);
c. rgb *= _Color. rgb;
return c;
}
ENDCG
}
}
FallBack "Transparent/VertexLit"
}```
***Обратите внимание: в коде есть место, которое необходимо изменить, как показано ниже:***
```c++
v2f vert (a2v v) {
//*****
float3 rightDir = normalize(cross(upDir, normalDir)) * -1;
//*****
}
Умножение на -1 меняет направление, иначе в Unity могут возникнуть проблемы с переворотом.
Исходный код взят из Wiki Cg_Programming (https://en.wikibooks.org/wiki/Cg_Programming/Unity/Billboards)
Исходный код:
Шейдер "Cg шейдер для бильбордов" {
Свойства {
_MainTex ("Текстура изображения", 2D) = "white" {}
_ScaleX ("Масштаб X", Float) = 1.0
_ScaleY ("Масштаб Y", Float) = 1.0
}
Подшейдер {
Пропасс {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// Пользовательские переменные
uniform sampler2D _MainTex;
uniform float _ScaleX;
uniform float _ScaleY;
struct vertexInput {
float4 вершина : POSITION;
float4 текст : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 текст : TEXCOORD0;
};
vertexOutput vert(vertexInput вход)
{
vertexOutput выход;
выход.pos = mul(UNITY_MATRIX_P,
mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
+ float4(вход.вершина.x, вход.вершина.y, 0.0, 0.0)
* float4(_ScaleX, _ScaleY, 1.0, 1.0));
выход.текст = вход.текст;
}
half4 frag(vertexOutput выход) : COLOR {
half4 цвет = tex2D(_MainTex, выход.текст);
return цвет;
}
ENDCG
}
}
}
``` возвращаем выход;
}
float4 frag(vertexOutput вход) : COLOR
{
возвращаем tex2D(_MainTex, float2(вход.текст.xy));
}
ENDCG
}
}
}
Этот код имеет некоторые ограничения:
Шейдер "Unlit/fll-Billboard-2" {
Свойства {
_MainTex ("Текстура изображения", 2D) = "white" {}
_ScaleX ("Масштаб X", Float) = 1.0
_ScaleY ("Масштаб Y", Float) = 1.0
_Color ("Цвет", Color) = (1, 1, 1, 1)
}
Подшейдер {
Теги {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True"}
Пропуск {
Теги { "DisableBatching" = "True" }
ZWrite On
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
}
}
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
// Пользовательские uniforms
uniform sampler2D _MainTex;
uniform float _ScaleX;
uniform float _ScaleY;
uniform fixed4 _Color;
uniform float4 _MainTex_ST;
struct vertexInput {
float4 vertex : POSITION;
float4 tex : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float2 tex : TEXCOORD0;
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_P,
mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
+ float4(input.vertex.x, input.vertex.y, 0.0, 0.0)
* float4(_ScaleX, _ScaleY, 1.0, 1.0));
output.tex = TRANSFORM_TEX(input.tex, _MainTex);
return output;
}
float4 frag(vertexOutput input) : SV_Target
{
fixed4 c = tex2D(_MainTex, float2(input.tex.xy));
c.rgb *= _Color.rgb;
return c;
}
ENDCG
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
``````csharp
public class DrawLineRender : MonoBehaviour {
public Color materialColor;
LineRenderer lineRenderer_global;
Vector3 startPos;
Vector3 endPos;
Vector3[] poss;
[SerializeField]
private Vector3 offset = Vector3.zero;
[SerializeField]
[Range(0f, 0.2f)]
private float width = 0.1f;
void Awake () {
LineRenderer lineRenderer = this.gameObject.AddComponent<LineRenderer> ();
Material material = new Material(Shader.Find("Unlit/Color"));
lineRenderer.material = material;
lineRenderer.material.color = materialColor;
lineRenderer.widthMultiplier = width;
lineRenderer.positionCount = 2;
lineRenderer.numCornerVertices = 30;
lineRenderer.numCapVertices = 30;
}
}
``````csharp
startPos = this.transform.parent.GetChild(2).transform.localPosition;
endPos = this.transform.parent.GetChild(0).transform.localPosition;
//var offset = new Vector3(0, 1.254f, 0);
poss = new Vector3[2] { startPos - offset, endPos - offset };
}
void Start()
{
lineRenderer_global = this.GetComponent<LineRenderer>();
}
void Update()
{
}
}
``````markdown
```csharp
for (int i = 0; i < lineRenderer_global.positionCount; i++) {
lineRenderer_global.SetPosition(i, poss[i]);
}
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )