Frag Shader, если еще странное поведение
Ниже приведена упрощенная версия текущей шейдерной системы, над которой я работаю, она извлекает данные из одноразового вычислительного шейдера в вершинную программу: v2f, а затем анализирует эти данные в v2fc - эта структура хранит статические данные с добавленным рендом плавать. Это значение с плавающей запятой, установленное в настоящее время вручную, будет связано с внешним вводом, свойствами или, возможно, другим вычислительным ядром.
Как видно из программы фрагмента, это используется для эффективного принятия решения о том, визуализирован экземпляр или нет.
Я также пытался использовать функцию "сброс", но мне сказали, что этот метод неэффективен. Кроме того, то же самое, если бы я попытался, чтобы rend был int и включал оператор switch.
Все эти методы дали мне один и тот же результат: опция else или case по умолчанию всегда выполняется независимо от условия switch/if.
У меня есть некоторый опыт работы с C++, но в основном C#, и я относительно новичок в сложных системах шейдеров, так что извините, если неверный синтаксис.
Я ценю любой совет или объяснение этой проблемы.
//TODO Rendfiltermethods
Shader "Custom/StarShaderTemp"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_Color(" Color", Color) = (1, 0.5, 0.5, 1)
_Scale(" Scale ", Float) = 1
_Damping(" Damping Value", Float) = 500
}
SubShader
{
Pass
{
Tags { "RenderType" = "Transparent"}
ZTest Off
ZWrite Off
Cull Off
Blend SrcAlpha One
CGPROGRAM
#pragma target 5.0
#pragma vertex star_vertex
#pragma vertex star_cull
#pragma fragment frag
#pragma exclude_renderers gles
#include "UnityCG.cginc"
#include "StarStructInc.cginc"
StructuredBuffer<Star> stars;
StructuredBuffer<float3> quadPoints;
StructuredBuffer<int> cullint; //Input from cull compute shader for bypassing gifmain compute
sampler2D _MainTex;
sampler2D _O;
sampler2D _B;
sampler2D _A;
sampler2D _F;
sampler2D _G;
sampler2D _K;
sampler2D _M;
sampler2D _Blackhole;
float4 _Color;
float _Scale;
float _CamDist;
float _Damping;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 color : COLOR;
};
struct v2fc
{
v2f vetwof : v2f;
float rendfloat: float;
};
// vertex shader with no inputs
// uses the system values SV_VertexID and SV_InstanceID to read from compute buffers
v2f star_vertex(uint id : SV_VertexID, uint inst : SV_InstanceID)
{
v2f o;
float3 worldPosition = stars[inst].position;
float3 Qpoint = quadPoints[id] * _Scale * sqrt(_CamDist / _Damping);
o.pos = mul (UNITY_MATRIX_P, mul (UNITY_MATRIX_V, float4(worldPosition, 1.0f)) + float4(Qpoint, 0.0f));
o.uv = quadPoints[id] + 0.5f; //setting UV texture coord center
return o;
}
v2fc star_cull(v2f i)
{
v2fc c;
c.vetwof = i;
c.rendfloat = 6.0;
return c;
}
float4 frag (v2fc i) : COLOR
{
if(i.rendfloat < 5.0)
{
float4 texColn = tex2D (_MainTex, i.vetwof.uv);
return texColn * _Color;
}
else
{
i.vetwof.pos =0;
float4 texColn = tex2D (_MainTex, i.vetwof.uv);
return texColn * _Color;
}
}
ENDCG
}
}
FallBack "Diffuse"
}
1 ответ
Поведение else исправляется созданием пустых функций вместо успешных фрагментов ETC. После просмотра скомпилированного кода кажется, что существует проблема с предсказанием ветвления, используемым при оптимизации сборки, в которой можно объединить ссылку на функцию фрагмента. Другое исправление заключается в использовании нескольких проходов с целями рендеринга.