diff --git a/gpu/compute.go b/gpu/compute.go index 335d9fa7..50110545 100644 --- a/gpu/compute.go +++ b/gpu/compute.go @@ -42,6 +42,7 @@ type compute struct { texOps []textureOp viewport image.Point maxTextureDim int + srgb bool programs struct { elements computeProgram @@ -98,8 +99,14 @@ type compute struct { buffer sizedBuffer - uniforms *materialUniforms - uniBuf driver.Buffer + vert struct { + uniforms *materialVertUniforms + buf driver.Buffer + } + + frag struct { + buf driver.Buffer + } // CPU fields cpuTex cpu.ImageDescriptor @@ -154,11 +161,16 @@ type copyUniforms struct { _ [8]byte // Pad to 16 bytes. } -type materialUniforms struct { +type materialVertUniforms struct { scale [2]float32 pos [2]float32 } +type materialFragUniforms struct { + emulateSRGB float32 + _ [12]byte // Pad to 16 bytes +} + type collector struct { hasher maphash.Hash profile bool @@ -372,6 +384,7 @@ func newCompute(ctx driver.Device) (*compute, error) { g := &compute{ ctx: ctx, maxTextureDim: maxDim, + srgb: caps.Features.Has(driver.FeatureSRGB), conf: new(config), memHeader: new(memoryHeader), } @@ -447,15 +460,27 @@ func newCompute(ctx driver.Device) (*compute, error) { return nil, err } g.materials.layout = progLayout - g.materials.uniforms = new(materialUniforms) + g.materials.vert.uniforms = new(materialVertUniforms) - buf, err = ctx.NewBuffer(driver.BufferBindingUniforms, int(unsafe.Sizeof(*g.materials.uniforms))) + buf, err = ctx.NewBuffer(driver.BufferBindingUniforms, int(unsafe.Sizeof(*g.materials.vert.uniforms))) if err != nil { g.Release() return nil, err } - g.materials.uniBuf = buf + g.materials.vert.buf = buf g.materials.prog.SetVertexUniforms(buf) + var emulateSRGB materialFragUniforms + if !g.srgb { + emulateSRGB.emulateSRGB = 1.0 + } + buf, err = ctx.NewBuffer(driver.BufferBindingUniforms, int(unsafe.Sizeof(emulateSRGB))) + if err != nil { + g.Release() + return nil, err + } + buf.Upload(byteslice.Struct(&emulateSRGB)) + g.materials.frag.buf = buf + g.materials.prog.SetFragmentUniforms(buf) for _, shader := range shaders { if !g.useCPU { @@ -875,9 +900,9 @@ restart: } } // Transform to clip space: [-1, -1] - [1, 1]. - g.materials.uniforms.scale = [2]float32{2 / float32(texSize), 2 / float32(texSize)} - g.materials.uniforms.pos = [2]float32{-1, -1} - g.materials.uniBuf.Upload(byteslice.Struct(g.materials.uniforms)) + g.materials.vert.uniforms.scale = [2]float32{2 / float32(texSize), 2 / float32(texSize)} + g.materials.vert.uniforms.pos = [2]float32{-1, -1} + g.materials.vert.buf.Upload(byteslice.Struct(g.materials.vert.uniforms)) vertexData := byteslice.Slice(m.quads) n := pow2Ceil(len(vertexData)) m.buffer.ensureCapacity(false, g.ctx, driver.BufferBindingVertices, n) @@ -952,7 +977,11 @@ restart: a.tex = nil } sz := a.packer.maxDim - handle, err := g.ctx.NewTexture(driver.TextureFormatSRGBA, sz, sz, driver.FilterLinear, driver.FilterLinear, driver.BufferBindingTexture) + format := driver.TextureFormatSRGBA + if !g.srgb { + format = driver.TextureFormatRGBA8 + } + handle, err := g.ctx.NewTexture(format, sz, sz, driver.FilterLinear, driver.FilterLinear, driver.BufferBindingTexture) if err != nil { return fmt.Errorf("compute: failed to create image atlas: %v", err) } @@ -1316,7 +1345,8 @@ func (g *compute) Release() { g.materials.fbo, g.materials.tex, &g.materials.buffer, - g.materials.uniBuf, + g.materials.vert.buf, + g.materials.frag.buf, g.timers.t, } g.materials.cpuTex.Free() diff --git a/gpu/gpu.go b/gpu/gpu.go index a23f914e..deb6f1b9 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -9,7 +9,6 @@ package gpu import ( "encoding/binary" - "errors" "fmt" "image" "image/color" @@ -361,11 +360,8 @@ func New(api API) (GPU, error) { defer d.EndFrame() forceCompute := os.Getenv("GIORENDERER") == "forcecompute" feats := d.Caps().Features - if !feats.Has(driver.FeatureSRGB) { - return nil, errors.New("gpu: no sRGB texture formats found") - } switch { - case !forceCompute && feats.Has(driver.FeatureFloatRenderTargets): + case !forceCompute && feats.Has(driver.FeatureFloatRenderTargets) && feats.Has(driver.FeatureSRGB): return newGPU(d) } return newCompute(d) diff --git a/gpu/shaders.go b/gpu/shaders.go index 1edb6dfb..7f7394b7 100644 --- a/gpu/shaders.go +++ b/gpu/shaders.go @@ -5073,13 +5073,25 @@ void main() Hash: "e72e482d7f40b2949426017cb5aeb4d391fcfc0e9d42e73bffb5a1e5576e906d", } shader_material_frag = driver.ShaderSources{ - Name: "material.frag", - Inputs: []driver.InputLocation{{Name: "vUV", Location: 0, Semantic: "TEXCOORD", SemanticIndex: 0, Type: 0x0, Size: 2}}, + Name: "material.frag", + Inputs: []driver.InputLocation{{Name: "vUV", Location: 0, Semantic: "TEXCOORD", SemanticIndex: 0, Type: 0x0, Size: 2}}, + Uniforms: driver.UniformsReflection{ + Blocks: []driver.UniformBlock{{Name: "Color", Binding: 0}}, + Locations: []driver.UniformLocation{{Name: "_color.emulateSRGB", Type: 0x0, Size: 1, Offset: 0}}, + Size: 4, + }, Textures: []driver.TextureBinding{{Name: "tex", Binding: 0}}, GLSL100ES: `#version 100 precision mediump float; precision highp int; +struct Color +{ + float emulateSRGB; +}; + +uniform Color _58; + uniform mediump sampler2D tex; varying vec2 vUV; @@ -5095,9 +5107,12 @@ vec3 RGBtosRGB(vec3 rgb) void main() { vec4 texel = texture2D(tex, vUV); - vec3 param = texel.xyz; - vec3 _59 = RGBtosRGB(param); - texel = vec4(_59.x, _59.y, _59.z, texel.w); + if (_58.emulateSRGB == 0.0) + { + vec3 param = texel.xyz; + vec3 _71 = RGBtosRGB(param); + texel = vec4(_71.x, _71.y, _71.z, texel.w); + } gl_FragData[0] = texel; } @@ -5106,6 +5121,11 @@ void main() precision mediump float; precision highp int; +layout(std140) uniform Color +{ + float emulateSRGB; +} _58; + uniform mediump sampler2D tex; in vec2 vUV; @@ -5122,15 +5142,25 @@ vec3 RGBtosRGB(vec3 rgb) void main() { vec4 texel = texture(tex, vUV); - vec3 param = texel.xyz; - vec3 _59 = RGBtosRGB(param); - texel = vec4(_59.x, _59.y, _59.z, texel.w); + if (_58.emulateSRGB == 0.0) + { + vec3 param = texel.xyz; + vec3 _71 = RGBtosRGB(param); + texel = vec4(_71.x, _71.y, _71.z, texel.w); + } fragColor = texel; } `, GLSL130: `#version 130 +struct Color +{ + float emulateSRGB; +}; + +uniform Color _58; + uniform sampler2D tex; in vec2 vUV; @@ -5147,15 +5177,23 @@ vec3 RGBtosRGB(vec3 rgb) void main() { vec4 texel = texture(tex, vUV); - vec3 param = texel.xyz; - vec3 _59 = RGBtosRGB(param); - texel = vec4(_59.x, _59.y, _59.z, texel.w); + if (_58.emulateSRGB == 0.0) + { + vec3 param = texel.xyz; + vec3 _71 = RGBtosRGB(param); + texel = vec4(_71.x, _71.y, _71.z, texel.w); + } fragColor = texel; } `, GLSL150: `#version 150 +layout(std140) uniform Color +{ + float emulateSRGB; +} _58; + uniform sampler2D tex; in vec2 vUV; @@ -5172,14 +5210,17 @@ vec3 RGBtosRGB(vec3 rgb) void main() { vec4 texel = texture(tex, vUV); - vec3 param = texel.xyz; - vec3 _59 = RGBtosRGB(param); - texel = vec4(_59.x, _59.y, _59.z, texel.w); + if (_58.emulateSRGB == 0.0) + { + vec3 param = texel.xyz; + vec3 _71 = RGBtosRGB(param); + texel = vec4(_71.x, _71.y, _71.z, texel.w); + } fragColor = texel; } `, - HLSL: "DXBC\x9e\x87LD\xf3\x17\n\x06\\\xb7\x98\x94\xa9PKe\x01\x00\x00\x00\xc8\x04\x00\x00\x06\x00\x00\x008\x00\x00\x00\xbc\x01\x00\x00D\x03\x00\x00\xc0\x03\x00\x00`\x04\x00\x00\x94\x04\x00\x00Aon9|\x01\x00\x00|\x01\x00\x00\x00\x02\xff\xffT\x01\x00\x00(\x00\x00\x00\x00\x00(\x00\x00\x00(\x00\x00\x00(\x00\x01\x00$\x00\x00\x00(\x00\x00\x00\x00\x00\x00\x02\xff\xffQ\x00\x00\x05\x00\x00\x0f\xa0=\n\x87?\xaeGa\xbd\x00\x00\x00\x00\x00\x00\x00\x00Q\x00\x00\x05\x01\x00\x0f\xa0\x1c.M\xbbR\xb8NAvT\xd5>\x00\x00\x00\x00\x1f\x00\x00\x02\x00\x00\x00\x80\x00\x00\x03\xb0\x1f\x00\x00\x02\x00\x00\x00\x90\x00\b\x0f\xa0B\x00\x00\x03\x00\x00\x0f\x80\x00\x00\xe4\xb0\x00\b\xe4\xa0\x0f\x00\x00\x02\x01\x00\x01\x80\x00\x00\x00\x80\x0f\x00\x00\x02\x01\x00\x02\x80\x00\x00U\x80\x0f\x00\x00\x02\x01\x00\x04\x80\x00\x00\xaa\x80\x05\x00\x00\x03\x01\x00\a\x80\x01\x00\xe4\x80\x01\x00\xaa\xa0\x0e\x00\x00\x02\x02\x00\x01\x80\x01\x00\x00\x80\x0e\x00\x00\x02\x02\x00\x02\x80\x01\x00U\x80\x0e\x00\x00\x02\x02\x00\x04\x80\x01\x00\xaa\x80\x04\x00\x00\x04\x01\x00\a\x80\x02\x00\xe4\x80\x00\x00\x00\xa0\x00\x00U\xa0\x02\x00\x00\x03\x01\x00\b\x80\x00\x00\x00\x80\x01\x00\x00\xa0\x05\x00\x00\x03\x02\x00\a\x80\x00\x00\xe4\x80\x01\x00U\xa0X\x00\x00\x04\x00\x00\x01\x80\x01\x00\xff\x80\x01\x00\x00\x80\x02\x00\x00\x80\x02\x00\x00\x03\x01\x00\x01\x80\x00\x00U\x80\x01\x00\x00\xa0X\x00\x00\x04\x00\x00\x02\x80\x01\x00\x00\x80\x01\x00U\x80\x02\x00U\x80\x02\x00\x00\x03\x01\x00\x01\x80\x00\x00\xaa\x80\x01\x00\x00\xa0X\x00\x00\x04\x00\x00\x04\x80\x01\x00\x00\x80\x01\x00\xaa\x80\x02\x00\xaa\x80\x01\x00\x00\x02\x00\b\x0f\x80\x00\x00\xe4\x80\xff\xff\x00\x00SHDR\x80\x01\x00\x00@\x00\x00\x00`\x00\x00\x00Z\x00\x00\x03\x00`\x10\x00\x00\x00\x00\x00X\x18\x00\x04\x00p\x10\x00\x00\x00\x00\x00UU\x00\x00b\x10\x00\x032\x10\x10\x00\x00\x00\x00\x00e\x00\x00\x03\xf2 \x10\x00\x00\x00\x00\x00h\x00\x00\x02\x03\x00\x00\x00E\x00\x00\t\xf2\x00\x10\x00\x00\x00\x00\x00F\x10\x10\x00\x00\x00\x00\x00F~\x10\x00\x00\x00\x00\x00\x00`\x10\x00\x00\x00\x00\x00/\x00\x00\x05r\x00\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x00\x00\x00\x008\x00\x00\nr\x00\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x01\x00\x00\x00\x02@\x00\x00vT\xd5>vT\xd5>vT\xd5>\x00\x00\x00\x00\x19\x00\x00\x05r\x00\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x01\x00\x00\x002\x00\x00\x0fr\x00\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x01\x00\x00\x00\x02@\x00\x00=\n\x87?=\n\x87?=\n\x87?\x00\x00\x00\x00\x02@\x00\x00\xaeGa\xbd\xaeGa\xbd\xaeGa\xbd\x00\x00\x00\x00\x1d\x00\x00\nr\x00\x10\x00\x02\x00\x00\x00F\x02\x10\x00\x00\x00\x00\x00\x02@\x00\x00\x1c.M;\x1c.M;\x1c.M;\x00\x00\x00\x008\x00\x00\nr\x00\x10\x00\x00\x00\x00\x00F\x02\x10\x00\x00\x00\x00\x00\x02@\x00\x00R\xb8NAR\xb8NAR\xb8NA\x00\x00\x00\x006\x00\x00\x05\x82 \x10\x00\x00\x00\x00\x00:\x00\x10\x00\x00\x00\x00\x007\x00\x00\tr \x10\x00\x00\x00\x00\x00F\x02\x10\x00\x02\x00\x00\x00F\x02\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x00\x00\x00\x00>\x00\x00\x01STATt\x00\x00\x00\n\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00RDEF\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1c\x00\x00\x00\x00\x04\xff\xff\x00\x01\x00\x00m\x00\x00\x00\\\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00i\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x01\x00\x00\x00\r\x00\x00\x00_tex_sampler\x00tex\x00Microsoft (R) HLSL Shader Compiler 10.1\x00\xab\xab\xabISGN,\x00\x00\x00\x01\x00\x00\x00\b\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x03\x00\x00TEXCOORD\x00\xab\xab\xabOSGN,\x00\x00\x00\x01\x00\x00\x00\b\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00SV_Target\x00\xab\xab", + HLSL: "DXBC`l\xc5\r\xe5m\xb2n{\xec\x1c^\xe6\xcao\x04\x01\x00\x00\x00\xc0\x05\x00\x00\x06\x00\x00\x008\x00\x00\x00\xec\x01\x00\x00\xc8\x03\x00\x00D\x04\x00\x00X\x05\x00\x00\x8c\x05\x00\x00Aon9\xac\x01\x00\x00\xac\x01\x00\x00\x00\x02\xff\xffx\x01\x00\x004\x00\x00\x00\x01\x00(\x00\x00\x004\x00\x00\x004\x00\x01\x00$\x00\x00\x004\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x02\xff\xffQ\x00\x00\x05\x01\x00\x0f\xa0=\n\x87?\xaeGa\xbd\x00\x00\x00\x00\x00\x00\x00\x00Q\x00\x00\x05\x02\x00\x0f\xa0\x1c.M\xbbR\xb8NAvT\xd5>\x00\x00\x00\x00\x1f\x00\x00\x02\x00\x00\x00\x80\x00\x00\x03\xb0\x1f\x00\x00\x02\x00\x00\x00\x90\x00\b\x0f\xa0B\x00\x00\x03\x00\x00\x0f\x80\x00\x00\xe4\xb0\x00\b\xe4\xa0\x05\x00\x00\x03\x01\x00\b\x80\x00\x00\x00\xa0\x00\x00\x00\xa0\x0f\x00\x00\x02\x01\x00\x01\x80\x00\x00\x00\x80\x0f\x00\x00\x02\x01\x00\x02\x80\x00\x00U\x80\x0f\x00\x00\x02\x01\x00\x04\x80\x00\x00\xaa\x80\x05\x00\x00\x03\x01\x00\a\x80\x01\x00\xe4\x80\x02\x00\xaa\xa0\x0e\x00\x00\x02\x02\x00\x01\x80\x01\x00\x00\x80\x0e\x00\x00\x02\x02\x00\x02\x80\x01\x00U\x80\x0e\x00\x00\x02\x02\x00\x04\x80\x01\x00\xaa\x80\x04\x00\x00\x04\x01\x00\a\x80\x02\x00\xe4\x80\x01\x00\x00\xa0\x01\x00U\xa0\x02\x00\x00\x03\x02\x00\x01\x80\x00\x00\x00\x80\x02\x00\x00\xa0\x05\x00\x00\x03\x02\x00\x0e\x80\x00\x00\x1b\x80\x02\x00U\xa0X\x00\x00\x04\x03\x00\x01\x80\x02\x00\x00\x80\x01\x00\x00\x80\x02\x00\xff\x80\x02\x00\x00\x03\x03\x00\b\x80\x00\x00U\x80\x02\x00\x00\xa0X\x00\x00\x04\x03\x00\x02\x80\x03\x00\xff\x80\x01\x00U\x80\x02\x00\xaa\x80\x02\x00\x00\x03\x03\x00\b\x80\x00\x00\xaa\x80\x02\x00\x00\xa0X\x00\x00\x04\x03\x00\x04\x80\x03\x00\xff\x80\x01\x00\xaa\x80\x02\x00U\x80X\x00\x00\x04\x00\x00\a\x80\x01\x00\xff\x81\x03\x00\xe4\x80\x00\x00\xe4\x80\x01\x00\x00\x02\x00\b\x0f\x80\x00\x00\xe4\x80\xff\xff\x00\x00SHDR\xd4\x01\x00\x00@\x00\x00\x00u\x00\x00\x00Y\x00\x00\x04F\x8e \x00\x00\x00\x00\x00\x01\x00\x00\x00Z\x00\x00\x03\x00`\x10\x00\x00\x00\x00\x00X\x18\x00\x04\x00p\x10\x00\x00\x00\x00\x00UU\x00\x00b\x10\x00\x032\x10\x10\x00\x00\x00\x00\x00e\x00\x00\x03\xf2 \x10\x00\x00\x00\x00\x00h\x00\x00\x02\x04\x00\x00\x00E\x00\x00\t\xf2\x00\x10\x00\x00\x00\x00\x00F\x10\x10\x00\x00\x00\x00\x00F~\x10\x00\x00\x00\x00\x00\x00`\x10\x00\x00\x00\x00\x00/\x00\x00\x05r\x00\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x00\x00\x00\x008\x00\x00\nr\x00\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x01\x00\x00\x00\x02@\x00\x00vT\xd5>vT\xd5>vT\xd5>\x00\x00\x00\x00\x19\x00\x00\x05r\x00\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x01\x00\x00\x002\x00\x00\x0fr\x00\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x01\x00\x00\x00\x02@\x00\x00=\n\x87?=\n\x87?=\n\x87?\x00\x00\x00\x00\x02@\x00\x00\xaeGa\xbd\xaeGa\xbd\xaeGa\xbd\x00\x00\x00\x00\x1d\x00\x00\nr\x00\x10\x00\x02\x00\x00\x00F\x02\x10\x00\x00\x00\x00\x00\x02@\x00\x00\x1c.M;\x1c.M;\x1c.M;\x00\x00\x00\x008\x00\x00\nr\x00\x10\x00\x03\x00\x00\x00F\x02\x10\x00\x00\x00\x00\x00\x02@\x00\x00R\xb8NAR\xb8NAR\xb8NA\x00\x00\x00\x007\x00\x00\tr\x00\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x02\x00\x00\x00F\x02\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x03\x00\x00\x00\x18\x00\x00\b\x82\x00\x10\x00\x01\x00\x00\x00\x01@\x00\x00\x00\x00\x00\x00\n\x80 \x00\x00\x00\x00\x00\x00\x00\x00\x007\x00\x00\tr \x10\x00\x00\x00\x00\x00\xf6\x0f\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x01\x00\x00\x00F\x02\x10\x00\x00\x00\x00\x006\x00\x00\x05\x82 \x10\x00\x00\x00\x00\x00:\x00\x10\x00\x00\x00\x00\x00>\x00\x00\x01STATt\x00\x00\x00\f\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00RDEF\f\x01\x00\x00\x01\x00\x00\x00\x94\x00\x00\x00\x03\x00\x00\x00\x1c\x00\x00\x00\x00\x04\xff\xff\x00\x01\x00\x00\xe4\x00\x00\x00|\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x89\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x01\x00\x00\x00\r\x00\x00\x00\x8d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00_tex_sampler\x00tex\x00Color\x00\xab\x8d\x00\x00\x00\x01\x00\x00\x00\xac\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc4\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\xd4\x00\x00\x00\x00\x00\x00\x00_58_emulateSRGB\x00\x00\x00\x03\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00Microsoft (R) HLSL Shader Compiler 10.1\x00ISGN,\x00\x00\x00\x01\x00\x00\x00\b\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x03\x00\x00TEXCOORD\x00\xab\xab\xabOSGN,\x00\x00\x00\x01\x00\x00\x00\b\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00SV_Target\x00\xab\xab", } shader_material_vert = driver.ShaderSources{ Name: "material.vert", diff --git a/gpu/shaders/material.frag b/gpu/shaders/material.frag index e21b79f3..d0a1b715 100644 --- a/gpu/shaders/material.frag +++ b/gpu/shaders/material.frag @@ -10,6 +10,12 @@ layout(location = 0) in vec2 vUV; layout(location = 0) out vec4 fragColor; +layout(binding=0) uniform Color { + // If emulateSRGB is set (!= 0), the input texels are sRGB encoded. We save the + // conversion step below, at the cost of texture filtering in sRGB space. + float emulateSRGB; +}; + vec3 RGBtosRGB(vec3 rgb) { bvec3 cutoff = greaterThanEqual(rgb, vec3(0.0031308)); vec3 below = vec3(12.92)*rgb; @@ -19,6 +25,8 @@ vec3 RGBtosRGB(vec3 rgb) { void main() { vec4 texel = texture(tex, vUV); - texel.rgb = RGBtosRGB(texel.rgb); + if (emulateSRGB == 0.0) { + texel.rgb = RGBtosRGB(texel.rgb); + } fragColor = texel; }