- Home /
Wrong weighted order transparencry
I am trying to implement the weighted OIT from this paper : http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html and i am using as a helper an implementation example a guy did in Unity and posted in github https://github.com/candycat1992/OIT_Lab (i want to implement the "OIT/WeightedBlended") The difference is that i dont have any transparent gameobject created in the editor and i am creating some smoke particles dynamically via script. For that reason i use drawMeshInstancedIndirect as a draw call. I did get a result using the 3 shaders ( accumulate, revealage and blend) however the result is wrong i get some strange artifacts
Here is the code in C# and the 3 shaders
void Start()
{
camera = GetComponent<Camera>();
cameraEvent = CameraEvent.AfterEverything;
argsBuffer = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
InitPosition();
//Accum
accumTex = RenderTexture.GetTemporary(Screen.width, Screen.height, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
commandBuffer = new CommandBuffer()
{
name = "Testing"
};
commandBuffer.SetRenderTarget(accumTex);
commandBuffer.ClearRenderTarget(false, true, new Vector4(0.0f,0.0f,0.0f,0.0f), 1f);
commandBuffer.DrawMeshInstancedIndirect(instanceMesh, subMeshIndex, accumMaterial, -1, argsBuffer);
GetComponent<Camera>().AddCommandBuffer(cameraEvent, commandBuffer);
material.SetTexture("_AccumTex", accumTex);
//Revealage
revealTex = RenderTexture.GetTemporary(Screen.width, Screen.height, 0, RenderTextureFormat.RHalf, RenderTextureReadWrite.Linear);
CommandBuffer cm3 = new CommandBuffer();
cm3.SetRenderTarget(revealTex);
cm3.ClearRenderTarget(false, true, new Vector4(1.0f, 1.0f, 1.0f, 1.0f), 1f);
cm3.DrawMeshInstancedIndirect(instanceMesh, subMeshIndex, revealMaterial, -1, argsBuffer);
GetComponent<Camera>().AddCommandBuffer(cameraEvent, cm3);
material.SetTexture("_RevealTex", revealTex);
//Blend
CommandBuffer cm2 = new CommandBuffer();
cm2.SetRenderTarget(BuiltinRenderTextureType.CameraTarget);
cm2.DrawMeshInstancedIndirect(instanceMesh, subMeshIndex, material, -1, argsBuffer);
camera.AddCommandBuffer(cameraEvent, cm2);
}
Shader "Unlit/AccumulateShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True" }
LOD 100
Zwrite Off
Blend One One
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 4.5
#include "UnityCG.cginc"
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float z : TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_ST;
#if SHADER_TARGET >= 45
StructuredBuffer<float4> _Position;
#endif
v2f vert (appdata_full v, uint instanceID: SV_InstanceID)
{
#if SHADER_TARGET >= 45
float4 data = _Position[instanceID];
#else
float4 data = 0;
#endif
v2f o;
float4x4 worldMatrix = unity_ObjectToWorld;
worldMatrix[0][3] = data.x;
worldMatrix[1][3] = data.y;
worldMatrix[2][3] = data.z;
float4 worldPos = mul(worldMatrix, v.vertex);
o.z = (mul(UNITY_MATRIX_V, worldPos)).z;
o.vertex = mul(UNITY_MATRIX_VP, worldPos);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
float weight(float z,float alpha)
{
return alpha * max(1e-2, min(3 * 1e3, 10.0 / (1e-5 + pow(z / 5, 2) + pow(z / 200, 6))));
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
col = float4(col.rgb * col.a, col.a)* weight(i.z,col.a);
return col;
}
ENDCG
}
}
}
Shader "Unlit/RevealShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True" }
LOD 100
Zwrite Off
Blend Zero OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 4.5
#include "UnityCG.cginc"
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
#if SHADER_TARGET >= 45
StructuredBuffer<float4> _Position;
#endif
v2f vert (appdata_full v, uint instanceID: SV_InstanceID)
{
#if SHADER_TARGET >= 45
float4 data = _Position[instanceID];
#else
float4 data = 0;
#endif
v2f o;
float4x4 worldMatrix = unity_ObjectToWorld;
worldMatrix[0][3] = data.x;
worldMatrix[1][3] = data.y;
worldMatrix[2][3] = data.z;
float4 worldPos = mul(worldMatrix, v.vertex);
o.vertex = mul(UNITY_MATRIX_VP, worldPos);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
col = col.aaaa;
return col;
}
ENDCG
}
}
}
Shader "Unlit/SmokeShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_AccumTex ("Accumulate Texture",2D) = "black" {}
_RevealTex("Revealage Texture", 2D) = "white" {}
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True" }
LOD 100
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 4.5
#include "UnityCG.cginc"
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float4 screenpos : TEXCOORD1;
};
sampler2D _MainTex;
sampler2D _AccumTex;
sampler2D _RevealTex;
float4 _AccumTex_TexelSize;
float4 _MainTex_ST;
#if SHADER_TARGET >= 45
StructuredBuffer<float4> _Position;
#endif
v2f vert (appdata_full v, uint instanceID: SV_InstanceID)
{
#if SHADER_TARGET >= 45
float4 data = _Position[instanceID];
#else
float4 data = 0;
#endif
v2f o;
float4x4 worldMatrix = unity_ObjectToWorld;
worldMatrix[0][3] = data.x;
worldMatrix[1][3] = data.y;
worldMatrix[2][3] = data.z;
float4 worldPos = mul(worldMatrix, v.vertex);
o.vertex = mul(UNITY_MATRIX_VP, worldPos);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.screenpos = ComputeScreenPos(o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
/*float2 uv = (floor(i.uv * _AccumTex_TexelSize.zw) + 0.5) * _AccumTex_TexelSize.xy;
fixed4 col = tex2Dlod(_AccumTex, float4(uv, 0, 0));*/
float2 uv = i.screenpos.xy / i.screenpos.w;
fixed4 accum = tex2D(_AccumTex,uv);
float reveal = tex2D(_RevealTex, uv).r;
float4 background = tex2D(_MainTex, i.uv);
//fixed4 col = float4(reveal,reveal,reveal,reveal);
//fixed4 col = float4(accum.rgb / max(accum.a, 1e-5), reveal);
fixed4 col = float4(accum.rgb / clamp(accum.a, 1e-4, 5e4), reveal);
return (1.0 - col.a) * col + col.a * background;
return col;
}
ENDCG
}
}
}
Your answer
Follow this Question
Related Questions
Add Color Property to Unlit Alpha? 1 Answer
Transparency and texture atlases, shader calls affecting performance? 2 Answers
2D dark shader makes my texture transparent? 0 Answers
Fade object transparency evenly from the edge inward 0 Answers
Implement texture masking into simple existing shader 1 Answer