-
Notifications
You must be signed in to change notification settings - Fork 1
/
example.html
142 lines (121 loc) · 4.08 KB
/
example.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<html>
<head>
<script>
var gpuDevice = null;
var gpuContext = null;
let parametricEval = function(x, a, b, c, d, e, f, g) {
const absX = Math.abs(x);
const sgnX = Math.sign(x);
return sgnX * (absX <= d) ? c*absX + f : Math.pow(a*absX + b, g) + e;
}
let srgbToLinear = function(x) {
return parametricEval(
x, 1/1.055, 0.055/1.055, 1/12.92, 0.04045, 0, 0, 2.4);
}
let linearToSrgb = function(x) {
return parametricEval(
x, Math.pow(1.055, 2.4), 0, 12.92, 0.04045 / 12.92, -0.055, 0, 1/2.4);
}
async function drawGpuCanvas() {
if (!gpuDevice) {
const adapter = await navigator.gpu?.requestAdapter();
gpuDevice = await adapter?.requestDevice();
if (!gpuDevice) {
console.error("Failed to initialize WebGPU device");
return;
}
}
if (!gpuContext) {
gpuContext = GpuCanvas.getContext('webgpu');
if (!gpuContext) {
console.error("Failed to initialize WebGPU context");
return;
}
}
// Select the tone mapping mode based on the radio button.
let toneMappingMode = null;
if (ToneMapModeStandard.checked) {
toneMappingMode = "standard";
}
if (ToneMapModeExtended.checked) {
toneMappingMode = "extended";
}
// Select the pixel value to clear to from the slider.
let v = PixelValueSlider.value;
// Configure and clear the canvas.
gpuContext.configure({
device: gpuDevice,
format: 'rgba16float',
colorSpace: 'srgb',
usage: GPUTextureUsage.RENDER_ATTACHMENT,
toneMapping: {mode:toneMappingMode},
});
const renderPassDescriptor = {
colorAttachments: [
{
view: gpuContext.getCurrentTexture().createView(),
clearValue: { r:v, g:v, b:v, a: 1.0 },
loadOp: 'clear',
storeOp: 'store',
},
],
};
const commandEncoder = gpuDevice.createCommandEncoder();
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
passEncoder.setViewport(0, 0, 32, 32, 0, 1);
passEncoder.end();
gpuDevice.queue.submit([commandEncoder.finish()]);
}
let update = function() {
// Update dynamic range query result.
DynamicRangeMatch.innerHTML = "(unsupported)";
if (window.matchMedia("(dynamic-range: standard)").matches) {
DynamicRangeMatch.innerHTML = "standard";
}
if (window.matchMedia("(dynamic-range: high)").matches) {
DynamicRangeMatch.innerHTML = "high";
DynamicRangeExplanation.hidden = true;
} else {
DynamicRangeExplanation.hidden = false;
}
// Update pixel value text.
PixelValue.innerHTML = Number(PixelValueSlider.value).toFixed(2);;
PixelValueLinear.innerHTML = srgbToLinear(PixelValueSlider.value).toFixed(2);
drawGpuCanvas();
}
function main() {
// Configure rendering slider.
PixelValueSlider.addEventListener('input', update, false);
update();
}
</script>
</head>
<body onload='main()'>
<h1>HDR support</h1>
<p>The <tt>dynamic-range</tt> media query matches <tt id="DynamicRangeMatch">?</tt>.</p>
<p id="DynamicRangeExplanation" hidden>This means that, on this display, setting the tone mapping mode to <tt>extended</tt> will have no effect (it will be the same as setting it to <tt>standard</tt>).</p>
<p>
This demo requires that "Experimental Web Platform features" be enabled in chrome://flags.
</p>
<h1>Rendering settings</h1>
<p>
Pixel value:
<input id="PixelValueSlider" type="range" min="0" max="3" step="0.01" value="1" list="PixelValueSliderTicks""/>
<datalist id="PixelValueSliderTicks">
<option value="0" label="0"></option>
<option value="1" label="1"></option>
<option value="2" label="2"></option>
<option value="3" label="3"></option>
</datalist>
<tt id="PixelValue"></tt> (sRGB-encoded), <tt id="PixelValueLinear">?</tt> (linear-encoded)
</p>
<p>
Tone map mode:
<input type="radio" name="ToneMapMode" id="ToneMapModeStandard" onchange="update();" checked="true">
<label for="ToneMapModeStandard"><tt>standard</tt></label>
<input type="radio" name="ToneMapMode" id="ToneMapModeExtended" onchange="update();">
<label for="ToneMapModeExtended"><tt>extended</tt></label>
</p>
<h1>Canvas</h1>
<canvas id="GpuCanvas" style="width:32px; height:32px; border:1px solid black;"></canvas>
</html>