我正在一个项目中,该项目将不同位置的传感器值编码到建筑物的3d热图中。我为此使用了一个顶点着色器,并且在Editor:example中可以正常工作,但是在WebGL中构建场景后,结果就是black。
我尝试使用常量循环索引,或者始终在项目设置等中包含此着色器,但是这些都不起作用。以下是一些代码:
gbm.evals_result()
由于这在Editor中工作正常,所以我认为 v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
o.screenPos = ComputeScreenPos(o.vertex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
//...
float2 boxIntersection(in float3 ro, in float3 rd, in float3 rad)
{
float3 m = 1.0 / rd;
float3 n = m * ro;
float3 k = abs(m) * rad;
float3 t1 = -n - k;
float3 t2 = -n + k;
float tN = max(max(t1.x, t1.y), t1.z);
float tF = min(min(t2.x, t2.y), t2.z);
if (tN > tF || tF < 0.0) return float2(-1.0, -1.0); // no intersection
return float2(tN, tF);
}
//p in object space
float SampleValue(float3 p) {
float totalValue = 0.0;
float denom = 0.0;
for (int i = 0; i < 34; ++i) { // _DataSize
float4 sd = _SensorData[i];
float dist = length(p - sd.xyz);
totalValue += sd.w / (dist * dist);
denom += 1.0 / (dist * dist);
}
if (denom == 0.0) {
return 0.0;
}
return totalValue / denom;
}
float4 transferFunction(float value) {
float tv = (value - _DataScale.x) / (_DataScale.y - _DataScale.x); // _DataScale.x, _DataScale.y
float4 col = tex2D(_TransferTexture, float2(0.5, tv));
col.w *= _Strength; // _Strength
return float4(col.xyz * col.w, col.w);
}
float4 rayMarch(float3 ro, float3 rd, float dp) {
float3 ro1 = mul(unity_WorldToObject, float4(ro, 1.0));
float3 rd1 = mul(unity_WorldToObject, rd);
float2 t = boxIntersection(ro1, rd1, float3(1, 1, 1) * 0.5);
t.x = length(mul(unity_ObjectToWorld, float4(ro1 + rd1 * max(t.x, 0.0), 1.0)) - ro);
t.y = length(mul(unity_ObjectToWorld, float4(ro1 + rd1 * t.y, 1.0)) - ro);
t.y = min(t.y, dp);
float4 acc = float4(0.0, 0.0, 0.0, 1.0);
float totalDelta = (t.y - t.x);
float delta = totalDelta / float(_RM_Samples - 1.0);
float3 p = ro + t.x * rd;
for (int i = 0; i < 34; ++i) { // _RM_Samples
float v = SampleValue(p);
float4 tf = transferFunction(v);
float tr = exp(-tf.w * delta);
acc.xyz += tf.xyz * acc.w * delta;
acc.w *= tr;
p += delta * rd;
}
return float4(acc.xyz, (1.0 - acc.w) * step(t.x, t.y));
}
fixed4 frag(v2f i) : SV_Target
{
float2 tc = i.screenPos.xy / i.screenPos.w;
float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, tc));
float eD = LinearEyeDepth(depth);
float3 ro = _WorldSpaceCameraPos;
float3 rd = normalize(i.worldPos - ro);
float4 col = rayMarch(ro, rd, eD);
//if (col.w < 1) col = float4(1, 0, 0, 1);
//else col = float4(0, 1, 0, 1);
if (wingCullPlaneValue(i.worldPos.xyz) == 0 || cullPlaneValue(i.worldPos.xyz) == 0) {
discard;
}
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
或boxIntersection
函数中没有任何错误。我想知道WebGl中是否有任何特殊之处可以不同地处理像素,我必须相应地调整一些代码。我是WebGL和Shader的新手,非常感谢您的帮助或建议。
答案 0 :(得分:0)
那是因为阶跃函数。 用你自己的 sigmoid 函数近似它(可能很贵)
// get the uptime checks for past X hours
$uptimeData = UptimeChecks::where('user_id', 1)
->where('monitor_id', 1)
->where('checked_at', '>=', '2021-05-02 13:00:00')
->where('checked_at', '<=', '2021-05-03 13:00:00')
->orderBy('checked_at', 'asc')
->select('event', 'checked_at')
->get();
$uptimeDataTimeline = $uptimeData->groupBy(function ($item, $key) {
$date = Carbon::parse($item->checked_at);
// group by hour, how can I get say every 3 hours worth of data?
return $date->format('Y-m-d H:00:00');
});
$uptimeDataTimeline = $uptimeDataTimeline->map(function ($checksInPeriod, $key) {
$down = 0;
$up = 0;
$total = 0;
$uptime = 0;
$fill = '#1fc777'; // green
// $checksInPeriod is all of the data for a given hour at the moment
// I need to group by a bigger period, say, every 3 hours
// add our events
foreach ($checksInPeriod as $key => $value) {
$total++;
if (strtolower($value['event']) == 'down') $down++;
if (strtolower($value['event']) == 'up') $up++;
}
// calculate uptime
$uptime = floatval(number_format(round($up / $total, 5) * 100, 2, '.', ','));
// fill colours
if ($uptime < 100) $fill = '#9deab8'; // lighter green
if ($uptime < 99) $fill = '#fbaa49'; // amber
if ($uptime < 98) $fill = '#e0465e'; // red
return [
'total_events' => $total,
'down_events' => $down,
'up_events' => $up,
'uptime' => $uptime,
'fill' => $fill
];
});