Я сделал некоторые изменения в вашем шейдере.В основном для расчета ультрафиолета и альфа-смеси.
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Unlit/Lava"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
iChannel0 ("iChannel0", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="TransparentCutout" }
LOD 100
Blend OneMinusSrcAlpha SrcAlpha // Specify blend mode. This is inverted from usual usage.
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag lambert alpha:blend // Enable alpha blend
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
float4 screenPos : TEXCOORD1;
};
sampler2D _MainTex;
sampler2D iChannel0;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.screenPos = ComputeScreenPos(o.vertex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
#define pi (3.14159265358979323846)
#define EPSILON (0.0001)
float2 rotate(float2 v, float a)
{
float c = cos(a);
float s = sin(a);
return float2(
v.x*c-v.y*s,
v.x*s+v.y*c
);
}
float sphere(float3 p, float r)
{
return length(p)-r;
}
float scene(float3 p)
{
float b = sphere(p, 1.6);
if(b > 0.001) return b; // optimisation
float3 disp = 0;
float f = 0.5;
disp.x = tex2D(iChannel0, p.zy * 0.05 + _Time.y * 0.02).x * f;
disp.z = tex2D(iChannel0, p.xy * 0.05 + _Time.y * 0.03).z * f;
disp.y = tex2D(iChannel0, p.xz * 0.05 + _Time.y * 0.04).y * f;
return sphere(p + disp, 1.0 + sin(_Time.y*2.4) * 0.15);
}
fixed4 frag (v2f i) : SV_Target
{
//float2 uv = float2(fragCoord.x / iResolution.x, fragCoord.y / iResolution.y);
float2 uv = float2(i.screenPos.x , i.screenPos.y); // Unity equivalent of the above
uv -= 0.5;
uv /= float2((_ScreenParams.y / _ScreenParams.x)*0.5, (_ScreenParams.y / _ScreenParams.x)*0.5); // Shrink the globule
float3 cam = float3(0, -0.15, -3.5);
float3 dir = normalize(float3(uv,1));
float cam_a2 = sin(_Time.y) * pi * 0.1;
cam.yz = rotate(cam.yz, cam_a2);
dir.yz = rotate(dir.yz, cam_a2);
float cam_a = _Time.y * pi * 0.1;
cam.xz = rotate(cam.xz, cam_a);
dir.xz = rotate(dir.xz, cam_a);
float4 color = float4(0.16, 0.12, 0.10, 1.0);
float t = 0.00001;
const int maxSteps = 128;
for(int i = 0; i < maxSteps; ++i) {
float3 p = cam + dir * t;
float d = scene(p);
if(d < 0.0001 * t) {
color = float4(1.0, length(p) * (0.6 + (sin(_Time.y*3.0)+1.0) * 0.5 * 0.4), 0, 0);
break;
}
t += d;
}
return color;
}
ENDCG
}
}
}
Результат не идеален, но ближе:
Мне кажется, проблема с шейдером ShaderToy заключается в том, что онпредназначен для экранного пространства.Вы увидите, что когда вы перемещаете камеру, лава теряет сознание.Я думаю, что это из-за расчета пространства экрана уф.Вам нужно будет найти другой метод.
Удачи