mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-08-12 08:05:15 +02:00
Add Clarity boost mode
This commit is contained in:
@@ -5,7 +5,7 @@ uniform sampler2D data;
|
||||
uniform vec2 iResolution;
|
||||
|
||||
const int FILTER_UNSHARP_MASKING = 1;
|
||||
// const int FILTER_CAS = 2;
|
||||
const int FILTER_CAS = 2;
|
||||
|
||||
// constrast = 0.8
|
||||
const float CAS_CONTRAST_PEAK = 0.8 * -3.0 + 8.0;
|
||||
@@ -14,6 +14,7 @@ const float CAS_CONTRAST_PEAK = 0.8 * -3.0 + 8.0;
|
||||
const vec3 LUMINOSITY_FACTOR = vec3(0.299, 0.587, 0.114);
|
||||
|
||||
uniform int filterId;
|
||||
uniform bool qualityMode;
|
||||
uniform float sharpenFactor;
|
||||
uniform float brightness;
|
||||
uniform float contrast;
|
||||
@@ -28,16 +29,22 @@ vec3 clarityBoost(sampler2D tex, vec2 coord, vec3 e) {
|
||||
// a b c
|
||||
// d e f
|
||||
// g h i
|
||||
vec3 a = texture(tex, coord + texelSize * vec2(-1, 1)).rgb;
|
||||
vec3 b = texture(tex, coord + texelSize * vec2(0, 1)).rgb;
|
||||
vec3 c = texture(tex, coord + texelSize * vec2(1, 1)).rgb;
|
||||
|
||||
vec3 d = texture(tex, coord + texelSize * vec2(-1, 0)).rgb;
|
||||
vec3 f = texture(tex, coord + texelSize * vec2(1, 0)).rgb;
|
||||
|
||||
vec3 g = texture(tex, coord + texelSize * vec2(-1, -1)).rgb;
|
||||
vec3 h = texture(tex, coord + texelSize * vec2(0, -1)).rgb;
|
||||
vec3 i = texture(tex, coord + texelSize * vec2(1, -1)).rgb;
|
||||
|
||||
vec3 a;
|
||||
vec3 c;
|
||||
vec3 g;
|
||||
vec3 i;
|
||||
|
||||
if (filterId == FILTER_UNSHARP_MASKING || qualityMode) {
|
||||
a = texture(tex, coord + texelSize * vec2(-1, 1)).rgb;
|
||||
c = texture(tex, coord + texelSize * vec2(1, 1)).rgb;
|
||||
g = texture(tex, coord + texelSize * vec2(-1, -1)).rgb;
|
||||
i = texture(tex, coord + texelSize * vec2(1, -1)).rgb;
|
||||
}
|
||||
|
||||
// USM
|
||||
if (filterId == FILTER_UNSHARP_MASKING) {
|
||||
@@ -55,10 +62,12 @@ vec3 clarityBoost(sampler2D tex, vec2 coord, vec3 e) {
|
||||
// g h i h
|
||||
// These are 2.0x bigger (factored out the extra multiply).
|
||||
vec3 minRgb = min(min(min(d, e), min(f, b)), h);
|
||||
minRgb += min(min(a, c), min(g, i));
|
||||
|
||||
vec3 maxRgb = max(max(max(d, e), max(f, b)), h);
|
||||
maxRgb += max(max(a, c), max(g, i));
|
||||
|
||||
if (qualityMode) {
|
||||
minRgb += min(min(a, c), min(g, i));
|
||||
maxRgb += max(max(a, c), max(g, i));
|
||||
}
|
||||
|
||||
// Smooth minimum distance to signal limit divided by smooth max.
|
||||
vec3 reciprocalMaxRgb = 1.0 / maxRgb;
|
||||
@@ -85,10 +94,12 @@ void main() {
|
||||
vec3 color = texture(data, uv).rgb;
|
||||
|
||||
// Clarity boost
|
||||
color = sharpenFactor > 0.0 ? clarityBoost(data, uv, color) : color;
|
||||
if (sharpenFactor > 0.0) {
|
||||
color = clarityBoost(data, uv, color);
|
||||
}
|
||||
|
||||
// Saturation
|
||||
color = saturation != 1.0 ? mix(vec3(dot(color, LUMINOSITY_FACTOR)), color, saturation) : color;
|
||||
color = mix(vec3(dot(color, LUMINOSITY_FACTOR)), color, saturation);
|
||||
|
||||
// Contrast
|
||||
color = contrast * (color - 0.5) + 0.5;
|
||||
|
@@ -3,7 +3,7 @@ import { compressCodeFile } from "@macros/build" with { type: "macro" };
|
||||
import { StreamPref } from "@/enums/pref-keys";
|
||||
import { getStreamPref } from "@/utils/pref-utils";
|
||||
import { BaseCanvasPlayer } from "../base-canvas-player";
|
||||
import { StreamPlayerType } from "@/enums/pref-values";
|
||||
import { StreamPlayerType, StreamVideoProcessingMode } from "@/enums/pref-values";
|
||||
|
||||
|
||||
export class WebGL2Player extends BaseCanvasPlayer {
|
||||
@@ -25,7 +25,8 @@ export class WebGL2Player extends BaseCanvasPlayer {
|
||||
gl.uniform2f(gl.getUniformLocation(program, 'iResolution'), this.$canvas.width, this.$canvas.height);
|
||||
|
||||
gl.uniform1i(gl.getUniformLocation(program, 'filterId'), filterId);
|
||||
gl.uniform1f(gl.getUniformLocation(program, 'sharpenFactor'), this.options.sharpness);
|
||||
gl.uniform1i(gl.getUniformLocation(program, 'qualityMode'), this.options.processingMode === StreamVideoProcessingMode.QUALITY ? 1 : 0);
|
||||
gl.uniform1f(gl.getUniformLocation(program, 'sharpenFactor'), this.options.sharpness / (this.options.processingMode === StreamVideoProcessingMode.QUALITY ? 1 : 1.2));
|
||||
gl.uniform1f(gl.getUniformLocation(program, 'brightness'), this.options.brightness / 100);
|
||||
gl.uniform1f(gl.getUniformLocation(program, 'contrast'), this.options.contrast / 100);
|
||||
gl.uniform1f(gl.getUniformLocation(program, 'saturation'), this.options.saturation / 100);
|
||||
|
@@ -82,6 +82,10 @@ export class SettingsManager {
|
||||
},
|
||||
[StreamPref.VIDEO_PROCESSING]: {
|
||||
onChange: updateVideoPlayer,
|
||||
onChangeUi: onChangeVideoPlayerType,
|
||||
},
|
||||
[StreamPref.VIDEO_PROCESSING_MODE]: {
|
||||
onChange: updateVideoPlayer,
|
||||
},
|
||||
[StreamPref.VIDEO_SHARPNESS]: {
|
||||
onChange: updateVideoPlayer,
|
||||
|
@@ -8,6 +8,7 @@ import type { StreamPlayerOptions } from "@/types/stream";
|
||||
|
||||
export function onChangeVideoPlayerType() {
|
||||
const playerType = getStreamPref(StreamPref.VIDEO_PLAYER_TYPE);
|
||||
const processing = getStreamPref(StreamPref.VIDEO_PROCESSING);
|
||||
const settingsManager = SettingsManager.getInstance();
|
||||
if (!settingsManager.hasElement(StreamPref.VIDEO_PROCESSING)) {
|
||||
return;
|
||||
@@ -16,6 +17,7 @@ export function onChangeVideoPlayerType() {
|
||||
let isDisabled = false;
|
||||
|
||||
const $videoProcessing = settingsManager.getElement(StreamPref.VIDEO_PROCESSING) as HTMLSelectElement;
|
||||
const $videoProcessingMode = settingsManager.getElement(StreamPref.VIDEO_PROCESSING_MODE) as HTMLSelectElement;
|
||||
const $videoSharpness = settingsManager.getElement(StreamPref.VIDEO_SHARPNESS);
|
||||
const $videoPowerPreference = settingsManager.getElement(StreamPref.VIDEO_POWER_PREFERENCE);
|
||||
const $videoMaxFps = settingsManager.getElement(StreamPref.VIDEO_MAX_FPS);
|
||||
@@ -40,6 +42,7 @@ export function onChangeVideoPlayerType() {
|
||||
$videoSharpness.dataset.disabled = isDisabled.toString();
|
||||
|
||||
// Hide Power Preference setting if renderer isn't WebGL2
|
||||
$videoProcessingMode.closest('.bx-settings-row')!.classList.toggle('bx-gone', !(playerType === StreamPlayerType.WEBGL2 && processing === StreamVideoProcessing.CAS));
|
||||
$videoPowerPreference.closest('.bx-settings-row')!.classList.toggle('bx-gone', playerType !== StreamPlayerType.WEBGL2);
|
||||
$videoMaxFps.closest('.bx-settings-row')!.classList.toggle('bx-gone', playerType === StreamPlayerType.VIDEO);
|
||||
}
|
||||
@@ -59,6 +62,7 @@ export function updateVideoPlayer() {
|
||||
|
||||
const options = {
|
||||
processing: getStreamPref(StreamPref.VIDEO_PROCESSING),
|
||||
processingMode: getStreamPref(StreamPref.VIDEO_PROCESSING_MODE),
|
||||
sharpness: getStreamPref(StreamPref.VIDEO_SHARPNESS),
|
||||
saturation: getStreamPref(StreamPref.VIDEO_SATURATION),
|
||||
contrast: getStreamPref(StreamPref.VIDEO_CONTRAST),
|
||||
|
@@ -452,6 +452,7 @@ export class SettingsDialog extends NavigationDialog {
|
||||
StreamPref.VIDEO_MAX_FPS,
|
||||
StreamPref.VIDEO_POWER_PREFERENCE,
|
||||
StreamPref.VIDEO_PROCESSING,
|
||||
StreamPref.VIDEO_PROCESSING_MODE,
|
||||
StreamPref.VIDEO_RATIO,
|
||||
StreamPref.VIDEO_POSITION,
|
||||
StreamPref.VIDEO_SHARPNESS,
|
||||
|
Reference in New Issue
Block a user