mirror of
				https://github.com/Swordfish90/cool-retro-term.git
				synced 2025-10-31 07:04:20 +00:00 
			
		
		
		
	Improve rasterization rendering and add LCD rasterization (with subpixels).
This commit is contained in:
		| @@ -104,6 +104,7 @@ QtObject { | |||||||
|     readonly property int no_rasterization: 0 |     readonly property int no_rasterization: 0 | ||||||
|     readonly property int scanline_rasterization: 1 |     readonly property int scanline_rasterization: 1 | ||||||
|     readonly property int pixel_rasterization: 2 |     readonly property int pixel_rasterization: 2 | ||||||
|  |     readonly property int lcd_rasterization: 3 | ||||||
|  |  | ||||||
|     property int rasterization: no_rasterization |     property int rasterization: no_rasterization | ||||||
|  |  | ||||||
| @@ -145,6 +146,13 @@ QtObject { | |||||||
|                     target: fontManager |                     target: fontManager | ||||||
|                     source: "FontPixels.qml" |                     source: "FontPixels.qml" | ||||||
|                 } |                 } | ||||||
|  |             }, | ||||||
|  |             State { | ||||||
|  |                 when: rasterization == lcd_rasterization | ||||||
|  |                 PropertyChanges { | ||||||
|  |                     target: fontManager | ||||||
|  |                     source: "FontPixels.qml" | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         ] |         ] | ||||||
|  |  | ||||||
|   | |||||||
| @@ -89,6 +89,10 @@ Loader { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         ShaderLibrary { | ||||||
|  |             id: shaderLibrary | ||||||
|  |         } | ||||||
|  |  | ||||||
|         ShaderEffect { |         ShaderEffect { | ||||||
|             id: burnInShaderEffect |             id: burnInShaderEffect | ||||||
|  |  | ||||||
| @@ -118,9 +122,7 @@ Loader { | |||||||
|  |  | ||||||
|                  uniform highp float prevLastUpdate;" + |                  uniform highp float prevLastUpdate;" + | ||||||
|  |  | ||||||
|                 "float rgb2grey(vec3 v){ |                 shaderLibrary.rgb2grey + | ||||||
|                     return dot(v, vec3(0.21, 0.72, 0.04)); |  | ||||||
|                 }" + |  | ||||||
|  |  | ||||||
|                 "void main() { |                 "void main() { | ||||||
|                     vec2 coords = qt_TexCoord0; |                     vec2 coords = qt_TexCoord0; | ||||||
|   | |||||||
| @@ -34,6 +34,10 @@ ShaderEffect { | |||||||
|  |  | ||||||
|     property size aadelta: Qt.size(1.0 / width, 1.0 / height) |     property size aadelta: Qt.size(1.0 / width, 1.0 / height) | ||||||
|  |  | ||||||
|  |     ShaderLibrary { | ||||||
|  |         id: shaderLibrary | ||||||
|  |     } | ||||||
|  |  | ||||||
|     fragmentShader: " |     fragmentShader: " | ||||||
|         #ifdef GL_ES |         #ifdef GL_ES | ||||||
|             precision mediump float; |             precision mediump float; | ||||||
| @@ -52,22 +56,14 @@ ShaderEffect { | |||||||
|             float dist = dot(cc, cc) * screenCurvature; |             float dist = dot(cc, cc) * screenCurvature; | ||||||
|             return (coords + cc * (1.0 + dist) * dist); |             return (coords + cc * (1.0 + dist) * dist); | ||||||
|         } |         } | ||||||
|  |         " + | ||||||
|  |  | ||||||
|         float max2(vec2 v) { |         shaderLibrary.max2 + | ||||||
|             return max(v.x, v.y); |         shaderLibrary.min2 + | ||||||
|         } |         shaderLibrary.prod2 + | ||||||
|  |         shaderLibrary.sum2 + | ||||||
|  |  | ||||||
|         float min2(vec2 v) { |         " | ||||||
|             return min(v.x, v.y); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         float prod2(vec2 v) { |  | ||||||
|             return v.x * v.y; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         float sum2(vec2 v) { |  | ||||||
|             return v.x + v.y; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         void main(){ |         void main(){ | ||||||
|             vec2 staticCoords = qt_TexCoord0; |             vec2 staticCoords = qt_TexCoord0; | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ ColumnLayout { | |||||||
|                 property string selectedElement: model[currentIndex] |                 property string selectedElement: model[currentIndex] | ||||||
|  |  | ||||||
|                 Layout.fillWidth: true |                 Layout.fillWidth: true | ||||||
|                 model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")] |                 model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels"), qsTr("LCD")] | ||||||
|                 currentIndex: appSettings.rasterization |                 currentIndex: appSettings.rasterization | ||||||
|                 onCurrentIndexChanged: { |                 onCurrentIndexChanged: { | ||||||
|                     appSettings.rasterization = currentIndex |                     appSettings.rasterization = currentIndex | ||||||
|   | |||||||
							
								
								
									
										88
									
								
								app/qml/ShaderLibrary.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								app/qml/ShaderLibrary.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | |||||||
|  | import QtQuick 2.0 | ||||||
|  |  | ||||||
|  | QtObject { | ||||||
|  |     property string rasterizationShader: | ||||||
|  |         (appSettings.rasterization === appSettings.no_rasterization ? " | ||||||
|  |             lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) { | ||||||
|  |                 return texel; | ||||||
|  |             }" : "") + | ||||||
|  |  | ||||||
|  |         (appSettings.rasterization === appSettings.scanline_rasterization ? " | ||||||
|  |             #define INTENSITY 0.30 | ||||||
|  |             #define BRIGHTBOOST 0.30 | ||||||
|  |  | ||||||
|  |             lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) { | ||||||
|  |                 lowp vec3 result = texel; | ||||||
|  |  | ||||||
|  |                 lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * texel)) * texel; | ||||||
|  |                 lowp vec3 pixelLow  = ((1.0 - INTENSITY) + (0.1 * texel)) * texel; | ||||||
|  |  | ||||||
|  |                 vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0); | ||||||
|  |                 lowp float mask = 1.0 - abs(coords.y); | ||||||
|  |  | ||||||
|  |                 lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask); | ||||||
|  |                 return mix(texel, rasterizationColor, intensity); | ||||||
|  |             }" : "") + | ||||||
|  |  | ||||||
|  |         (appSettings.rasterization === appSettings.pixel_rasterization ? " | ||||||
|  |             #define INTENSITY 0.30 | ||||||
|  |             #define BRIGHTBOOST 0.30 | ||||||
|  |  | ||||||
|  |             lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) { | ||||||
|  |                 lowp vec3 result = texel; | ||||||
|  |  | ||||||
|  |                 lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * texel)) * texel; | ||||||
|  |                 lowp vec3 pixelLow  = ((1.0 - INTENSITY) + (0.1 * texel)) * texel; | ||||||
|  |  | ||||||
|  |                 vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0); | ||||||
|  |                 coords = coords * coords; | ||||||
|  |                 lowp float mask = 1.0 - coords.x - coords.y; | ||||||
|  |  | ||||||
|  |                 lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask); | ||||||
|  |                 return mix(texel, rasterizationColor, intensity); | ||||||
|  |             }" : "") + | ||||||
|  |  | ||||||
|  |         (appSettings.rasterization === appSettings.lcd_rasterization ? " | ||||||
|  |             #define brighten_scanlines 16.0 | ||||||
|  |             #define brighten_lcd 4.0 | ||||||
|  |             const vec3 offsets = vec3(3.141592654) * vec3(1.0/2.0,1.0/2.0 - 2.0/3.0,1.0/2.0-4.0/3.0); | ||||||
|  |  | ||||||
|  |             lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) { | ||||||
|  |                 vec2 omega = vec2(3.141592654) * vec2(2.0) * virtualResolution; | ||||||
|  |  | ||||||
|  |                 vec2 angle = screenCoords * omega; | ||||||
|  |  | ||||||
|  |                 float yfactor = (brighten_scanlines + sin(angle.y)) / (brighten_scanlines + 1.0); | ||||||
|  |                 vec3 xfactors = (brighten_lcd + sin(angle.x + offsets)) / (brighten_lcd + 1.0); | ||||||
|  |  | ||||||
|  |                 lowp vec3 rasterizationColor = yfactor * xfactors * texel; | ||||||
|  |                 return mix(texel, rasterizationColor, intensity); | ||||||
|  |             }" : "") + | ||||||
|  |  | ||||||
|  |         "\n\n" | ||||||
|  |  | ||||||
|  |     property string min2: " | ||||||
|  |         float min2(vec2 v) { | ||||||
|  |             return min(v.x, v.y); | ||||||
|  |         }\n\n" | ||||||
|  |  | ||||||
|  |     property string rgb2grey: " | ||||||
|  |         float rgb2grey(vec3 v) { | ||||||
|  |             return dot(v, vec3(0.21, 0.72, 0.04)); | ||||||
|  |         }\n\n" | ||||||
|  |  | ||||||
|  |     property string max2: " | ||||||
|  |         float max2(vec2 v) { | ||||||
|  |             return max(v.x, v.y); | ||||||
|  |         }\n\n" | ||||||
|  |  | ||||||
|  |     property string prod2: " | ||||||
|  |         float prod2(vec2 v) { | ||||||
|  |             return v.x * v.y; | ||||||
|  |         }\n\n" | ||||||
|  |  | ||||||
|  |     property string sum2: " | ||||||
|  |         float sum2(vec2 v) { | ||||||
|  |             return v.x + v.y; | ||||||
|  |         }\n\n" | ||||||
|  | } | ||||||
| @@ -38,11 +38,19 @@ Item { | |||||||
|  |  | ||||||
|     property real ambientLight: appSettings.ambientLight * 0.2 |     property real ambientLight: appSettings.ambientLight * 0.2 | ||||||
|  |  | ||||||
|     property size virtual_resolution |     property size virtualResolution | ||||||
|  |     property size screenResolution | ||||||
|  |  | ||||||
|  |     property real _screenDensity: Math.min( | ||||||
|  |         screenResolution.width / virtualResolution.width, | ||||||
|  |         screenResolution.height / virtualResolution.height | ||||||
|  |     ) | ||||||
|  |  | ||||||
|      ShaderEffect { |      ShaderEffect { | ||||||
|          id: dynamicShader |          id: dynamicShader | ||||||
|  |  | ||||||
|  |          property ShaderLibrary shaderLibrary: ShaderLibrary { } | ||||||
|  |  | ||||||
|          property ShaderEffectSource screenBuffer: frameBuffer |          property ShaderEffectSource screenBuffer: frameBuffer | ||||||
|          property ShaderEffectSource burnInSource: burnInEffect.source |          property ShaderEffectSource burnInSource: burnInEffect.source | ||||||
|          property ShaderEffectSource frameSource: terminalFrameLoader.item |          property ShaderEffectSource frameSource: terminalFrameLoader.item | ||||||
| @@ -74,7 +82,11 @@ Item { | |||||||
|          property size scaleNoiseSize: Qt.size((width) / (noiseTexture.width * appSettings.windowScaling * appSettings.totalFontScaling), |          property size scaleNoiseSize: Qt.size((width) / (noiseTexture.width * appSettings.windowScaling * appSettings.totalFontScaling), | ||||||
|                                                (height) / (noiseTexture.height * appSettings.windowScaling * appSettings.totalFontScaling)) |                                                (height) / (noiseTexture.height * appSettings.windowScaling * appSettings.totalFontScaling)) | ||||||
|  |  | ||||||
|          property size virtual_resolution: parent.virtual_resolution |          property size virtualResolution: parent.virtualResolution | ||||||
|  |  | ||||||
|  |          // Rasterization might display oversamping issues if virtual resolution is close to physical display resolution. | ||||||
|  |          // We progressively disable rasterization from 4x up to 2x resolution. | ||||||
|  |          property real rasterizationIntensity: Utils.smoothstep(2.0, 4.0, _screenDensity) | ||||||
|  |  | ||||||
|          property real time: timeManager.time |          property real time: timeManager.time | ||||||
|          property ShaderEffectSource noiseSource: noiseShaderSource |          property ShaderEffectSource noiseSource: noiseShaderSource | ||||||
| @@ -164,7 +176,8 @@ Item { | |||||||
|              uniform highp vec4 backgroundColor; |              uniform highp vec4 backgroundColor; | ||||||
|              uniform lowp float shadowLength; |              uniform lowp float shadowLength; | ||||||
|  |  | ||||||
|              uniform highp vec2 virtual_resolution;" + |              uniform highp vec2 virtualResolution; | ||||||
|  |              uniform lowp float rasterizationIntensity;\n" + | ||||||
|  |  | ||||||
|              (burnIn !== 0 ? " |              (burnIn !== 0 ? " | ||||||
|                  uniform sampler2D burnInSource; |                  uniform sampler2D burnInSource; | ||||||
| @@ -174,8 +187,7 @@ Item { | |||||||
|                  uniform sampler2D slowBurnInSource;" : "") + |                  uniform sampler2D slowBurnInSource;" : "") + | ||||||
|              (staticNoise !== 0 ? " |              (staticNoise !== 0 ? " | ||||||
|                  uniform highp float staticNoise;" : "") + |                  uniform highp float staticNoise;" : "") + | ||||||
|              (((staticNoise !== 0 || jitter !== 0) |              (((staticNoise !== 0 || jitter !== 0) ||(fallBack && (flickering || horizontalSync))) ? " | ||||||
|                ||(fallBack && (flickering || horizontalSync))) ? " |  | ||||||
|                  uniform lowp sampler2D noiseSource; |                  uniform lowp sampler2D noiseSource; | ||||||
|                  uniform highp vec2 scaleNoiseSize;" : "") + |                  uniform highp vec2 scaleNoiseSize;" : "") + | ||||||
|              (screenCurvature !== 0 ? " |              (screenCurvature !== 0 ? " | ||||||
| @@ -203,17 +215,14 @@ Item { | |||||||
|  |  | ||||||
|              (glowingLine !== 0 ? " |              (glowingLine !== 0 ? " | ||||||
|                  float randomPass(vec2 coords){ |                  float randomPass(vec2 coords){ | ||||||
|                      return fract(smoothstep(-120.0, 0.0, coords.y - (virtual_resolution.y + 120.0) * fract(time * 0.00015))); |                      return fract(smoothstep(-120.0, 0.0, coords.y - (virtualResolution.y + 120.0) * fract(time * 0.00015))); | ||||||
|                  }" : "") + |                  }" : "") + | ||||||
|  |  | ||||||
|              "float min2(vec2 v) { |              shaderLibrary.min2 + | ||||||
|                  return min(v.x, v.y); |              shaderLibrary.rgb2grey + | ||||||
|              } |              shaderLibrary.rasterizationShader + | ||||||
|  |  | ||||||
|              float rgb2grey(vec3 v){ |  | ||||||
|                  return dot(v, vec3(0.21, 0.72, 0.04)); |  | ||||||
|              } |  | ||||||
|  |  | ||||||
|  |              " | ||||||
|              float isInScreen(vec2 v) { |              float isInScreen(vec2 v) { | ||||||
|                  return min2(step(0.0, v) - step(1.0, v)); |                  return min2(step(0.0, v) - step(1.0, v)); | ||||||
|              } |              } | ||||||
| @@ -291,7 +300,7 @@ Item { | |||||||
|                      color += noiseVal * noise * (1.0 - distance * 1.3);" : "") + |                      color += noiseVal * noise * (1.0 - distance * 1.3);" : "") + | ||||||
|  |  | ||||||
|                  (glowingLine !== 0 ? " |                  (glowingLine !== 0 ? " | ||||||
|                      color += randomPass(coords * virtual_resolution) * glowingLine;" : "") + |                      color += randomPass(coords * virtualResolution) * glowingLine;" : "") + | ||||||
|  |  | ||||||
|                  "vec3 txt_color = texture2D(screenBuffer, txt_coords).rgb;" + |                  "vec3 txt_color = texture2D(screenBuffer, txt_coords).rgb;" + | ||||||
|  |  | ||||||
| @@ -309,6 +318,8 @@ Item { | |||||||
|  |  | ||||||
|                   "txt_color += fontColor.rgb * vec3(color);" + |                   "txt_color += fontColor.rgb * vec3(color);" + | ||||||
|  |  | ||||||
|  |                   "txt_color = applyRasterization(staticCoords, txt_color, virtualResolution, rasterizationIntensity);\n" + | ||||||
|  |  | ||||||
|                  "vec3 finalColor = txt_color;" + |                  "vec3 finalColor = txt_color;" + | ||||||
|  |  | ||||||
|                  (flickering !== 0 ? " |                  (flickering !== 0 ? " | ||||||
| @@ -360,6 +371,10 @@ Item { | |||||||
|          } |          } | ||||||
|      } |      } | ||||||
|  |  | ||||||
|  |      ShaderLibrary { | ||||||
|  |          id: shaderLibrary | ||||||
|  |      } | ||||||
|  |  | ||||||
|      ShaderEffect { |      ShaderEffect { | ||||||
|          id: staticShader |          id: staticShader | ||||||
|  |  | ||||||
| @@ -385,7 +400,7 @@ Item { | |||||||
|  |  | ||||||
|          property real ambientLight: parent.ambientLight |          property real ambientLight: parent.ambientLight | ||||||
|  |  | ||||||
|          property size virtual_resolution: parent.virtual_resolution |          property size virtualResolution: parent.virtualResolution | ||||||
|  |  | ||||||
|          blending: false |          blending: false | ||||||
|          visible: false |          visible: false | ||||||
| @@ -408,7 +423,7 @@ Item { | |||||||
|              uniform highp vec4 backgroundColor; |              uniform highp vec4 backgroundColor; | ||||||
|              uniform lowp float screen_brightness; |              uniform lowp float screen_brightness; | ||||||
|  |  | ||||||
|              uniform highp vec2 virtual_resolution;" + |              uniform highp vec2 virtualResolution;" + | ||||||
|  |  | ||||||
|              (bloom !== 0 ? " |              (bloom !== 0 ? " | ||||||
|                  uniform highp sampler2D bloomSource; |                  uniform highp sampler2D bloomSource; | ||||||
| @@ -426,25 +441,7 @@ Item { | |||||||
|              (ambientLight !== 0 ? " |              (ambientLight !== 0 ? " | ||||||
|                  uniform lowp float ambientLight;" : "") + |                  uniform lowp float ambientLight;" : "") + | ||||||
|  |  | ||||||
|              "highp float getScanlineIntensity(vec2 coords) { |              " | ||||||
|                  float result = 1.0;" + |  | ||||||
|  |  | ||||||
|                 (appSettings.rasterization != appSettings.no_rasterization ? |  | ||||||
|                     "float val = 0.0; |  | ||||||
|                      vec2 rasterizationCoords = fract(coords * virtual_resolution); |  | ||||||
|                      val += smoothstep(0.0, 0.5, rasterizationCoords.y); |  | ||||||
|                      val -= smoothstep(0.5, 1.0, rasterizationCoords.y); |  | ||||||
|                      result *= mix(0.5, 1.0, val);" : "") + |  | ||||||
|  |  | ||||||
|                 (appSettings.rasterization == appSettings.pixel_rasterization ? |  | ||||||
|                     "val = 0.0; |  | ||||||
|                      val += smoothstep(0.0, 0.5, rasterizationCoords.x); |  | ||||||
|                      val -= smoothstep(0.5, 1.0, rasterizationCoords.x); |  | ||||||
|                      result *= mix(0.5, 1.0, val);" : "") + " |  | ||||||
|  |  | ||||||
|                 return result; |  | ||||||
|              } |  | ||||||
|  |  | ||||||
|              float min2(vec2 v) { |              float min2(vec2 v) { | ||||||
|                  return min(v.x, v.y); |                  return min(v.x, v.y); | ||||||
|              } |              } | ||||||
| @@ -468,6 +465,7 @@ Item { | |||||||
|              "  return outColor; |              "  return outColor; | ||||||
|              }" + |              }" + | ||||||
|  |  | ||||||
|  |              shaderLibrary.rasterizationShader + | ||||||
|  |  | ||||||
|              "void main() {" + |              "void main() {" + | ||||||
|                  "vec2 cc = vec2(0.5) - qt_TexCoord0;" + |                  "vec2 cc = vec2(0.5) - qt_TexCoord0;" + | ||||||
| @@ -490,8 +488,6 @@ Item { | |||||||
|                      txt_color.b = leftColor.b * 0.30 + rightColor.b * 0.10 + txt_color.b * 0.60; |                      txt_color.b = leftColor.b * 0.30 + rightColor.b * 0.10 + txt_color.b * 0.60; | ||||||
|                  " : "") + |                  " : "") + | ||||||
|  |  | ||||||
|                   "txt_color *= getScanlineIntensity(txt_coords);" + |  | ||||||
|  |  | ||||||
|                   "txt_color += vec3(0.0001);" + |                   "txt_color += vec3(0.0001);" + | ||||||
|                   "float greyscale_color = rgb2grey(txt_color);" + |                   "float greyscale_color = rgb2grey(txt_color);" + | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,13 +26,19 @@ ShaderTerminal { | |||||||
|     property alias title: terminal.title |     property alias title: terminal.title | ||||||
|     property alias terminalSize: terminal.terminalSize |     property alias terminalSize: terminal.terminalSize | ||||||
|  |  | ||||||
|  |     property real devicePixelRatio: terminalWindow.screen.devicePixelRatio | ||||||
|  |  | ||||||
|     id: mainShader |     id: mainShader | ||||||
|     opacity: appSettings.windowOpacity * 0.3 + 0.7 |     opacity: appSettings.windowOpacity * 0.3 + 0.7 | ||||||
|  |  | ||||||
|     source: terminal.mainSource |     source: terminal.mainSource | ||||||
|     burnInEffect: terminal.burnInEffect |     burnInEffect: terminal.burnInEffect | ||||||
|     slowBurnInEffect: terminal.slowBurnInEffect |     slowBurnInEffect: terminal.slowBurnInEffect | ||||||
|     virtual_resolution: terminal.virtualResolution |     virtualResolution: terminal.virtualResolution | ||||||
|  |     screenResolution: Qt.size( | ||||||
|  |         terminalWindow.width * devicePixelRatio * appSettings.windowScaling, | ||||||
|  |         terminalWindow.height * devicePixelRatio * appSettings.windowScaling | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     TimeManager { |     TimeManager { | ||||||
|         id: timeManager |         id: timeManager | ||||||
|   | |||||||
| @@ -45,5 +45,6 @@ | |||||||
|         <file>menus/WindowMenu.qml</file> |         <file>menus/WindowMenu.qml</file> | ||||||
|         <file>menus/FullContextMenu.qml</file> |         <file>menus/FullContextMenu.qml</file> | ||||||
|         <file>menus/ShortContextMenu.qml</file> |         <file>menus/ShortContextMenu.qml</file> | ||||||
|  |         <file>ShaderLibrary.qml</file> | ||||||
|     </qresource> |     </qresource> | ||||||
| </RCC> | </RCC> | ||||||
|   | |||||||
| @@ -31,13 +31,18 @@ function lint(a, b, t) { | |||||||
|     return (1 - t) * a + (t) * b; |     return (1 - t) * a + (t) * b; | ||||||
| } | } | ||||||
|  |  | ||||||
| function mix(c1, c2, alpha){ | function mix(c1, c2, alpha) { | ||||||
|     return Qt.rgba(c1.r * alpha + c2.r * (1-alpha), |     return Qt.rgba(c1.r * alpha + c2.r * (1-alpha), | ||||||
|                    c1.g * alpha + c2.g * (1-alpha), |                    c1.g * alpha + c2.g * (1-alpha), | ||||||
|                    c1.b * alpha + c2.b * (1-alpha), |                    c1.b * alpha + c2.b * (1-alpha), | ||||||
|                    c1.a * alpha + c2.a * (1-alpha)) |                    c1.a * alpha + c2.a * (1-alpha)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function smoothstep(min, max, value) { | ||||||
|  |     let x = Math.max(0, Math.min(1, (value - min) / (max - min))); | ||||||
|  |     return x * x * (3 - 2 * x); | ||||||
|  | } | ||||||
|  |  | ||||||
| function strToColor(s){ | function strToColor(s){ | ||||||
|     var r = parseInt(s.substring(1,3), 16) / 256; |     var r = parseInt(s.substring(1,3), 16) / 256; | ||||||
|     var g = parseInt(s.substring(3,5), 16) / 256; |     var g = parseInt(s.substring(3,5), 16) / 256; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user