mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Just some work on the shader generators
This commit is contained in:
parent
83a5313a06
commit
129c706cfc
@ -44,6 +44,29 @@
|
||||
|
||||
// #define DEBUG_SHADER
|
||||
|
||||
// TODO: Which binding number?
|
||||
static const char *vulkan_uniform_buffer = R"(
|
||||
layout(set=0, binding=3) uniform constants {
|
||||
// Blend function replacement
|
||||
vec3 u_blendFixA;
|
||||
vec3 u_blendFixB;
|
||||
|
||||
// Texture clamp emulation
|
||||
vec4 u_texclamp;
|
||||
vec2 u_texclampoff;
|
||||
|
||||
// Alpha/Color test emulation
|
||||
vec4 u_alphacolorref;
|
||||
ivec4 u_alphacolormask;
|
||||
|
||||
// Stencil replacement
|
||||
float u_stencilReplaceValue;
|
||||
vec3 u_texenv;
|
||||
|
||||
vec3 u_fogcolor;
|
||||
)";
|
||||
|
||||
|
||||
// Missing: Z depth range
|
||||
bool GenerateVulkanGLSLFragmentShader(const ShaderID &id, char *buffer) {
|
||||
char *p = buffer;
|
||||
@ -87,11 +110,14 @@ bool GenerateVulkanGLSLFragmentShader(const ShaderID &id, char *buffer) {
|
||||
GEBlendSrcFactor replaceBlendFuncA = (GEBlendSrcFactor)id.Bits(FS_BIT_BLENDFUNC_A, 4);
|
||||
GEBlendDstFactor replaceBlendFuncB = (GEBlendDstFactor)id.Bits(FS_BIT_BLENDFUNC_B, 4);
|
||||
GEBlendMode replaceBlendEq = (GEBlendMode)id.Bits(FS_BIT_BLENDEQ, 3);
|
||||
StencilValueType replaceAlphaWithStencilType = (StencilValueType)id.Bits(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, 4);
|
||||
|
||||
bool isModeClear = id.Bit(FS_BIT_CLEARMODE);
|
||||
|
||||
const char *shading = doFlatShading ? "flat" : "";
|
||||
|
||||
WRITE(p, "%s\n", vulkan_uniform_buffer);
|
||||
|
||||
if (doTexture) {
|
||||
WRITE(p, "layout (binding = 1) uniform sampler2D tex;\n");
|
||||
}
|
||||
@ -100,37 +126,6 @@ bool GenerateVulkanGLSLFragmentShader(const ShaderID &id, char *buffer) {
|
||||
if (replaceBlend == REPLACE_BLEND_COPY_FBO) {
|
||||
WRITE(p, "layout (binding = 2) uniform sampler2D fbotex;\n");
|
||||
}
|
||||
if (replaceBlendFuncA == GE_SRCBLEND_FIXA) {
|
||||
WRITE(p, "uniform vec3 u_blendFixA;\n");
|
||||
}
|
||||
if (replaceBlendFuncB == GE_DSTBLEND_FIXB) {
|
||||
WRITE(p, "uniform vec3 u_blendFixB;\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (needShaderTexClamp && doTexture) {
|
||||
WRITE(p, "uniform vec4 u_texclamp;\n");
|
||||
if (id.Bit(FS_BIT_TEXTURE_AT_OFFSET)) {
|
||||
WRITE(p, "uniform vec2 u_texclampoff;\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (enableAlphaTest || enableColorTest) {
|
||||
WRITE(p, "uniform vec4 u_alphacolorref;\n");
|
||||
if (((enableColorTest && !colorTestAgainstZero) || (enableAlphaTest && !alphaTestAgainstZero))) {
|
||||
WRITE(p, "uniform ivec4 u_alphacolormask;\n");
|
||||
}
|
||||
}
|
||||
|
||||
StencilValueType replaceAlphaWithStencilType = (StencilValueType)id.Bits(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, 4);
|
||||
if (stencilToAlpha && replaceAlphaWithStencilType == STENCIL_VALUE_UNIFORM) {
|
||||
WRITE(p, "uniform float u_stencilReplaceValue;\n");
|
||||
}
|
||||
if (doTexture && texFunc == GE_TEXFUNC_BLEND)
|
||||
WRITE(p, "uniform vec3 u_texenv;\n");
|
||||
|
||||
if (enableFog) {
|
||||
WRITE(p, "uniform vec3 u_fogcolor;\n");
|
||||
}
|
||||
|
||||
WRITE(p, "layout (location = 1) %s in vec4 v_color0;\n", shading);
|
||||
|
@ -71,6 +71,41 @@ enum DoLightComputation {
|
||||
};
|
||||
|
||||
|
||||
const char *vulkan_base_uniforms = R"(
|
||||
layout(set=0, binding=4) uniform base {
|
||||
mat4 proj;
|
||||
mat4 world;
|
||||
mat4 view;
|
||||
mat4 texmtx;
|
||||
vec4 uvscaleoffset;
|
||||
vec2 fogcoef;
|
||||
vec4 depthRange;
|
||||
vec4 matambientalpha;
|
||||
};
|
||||
)";
|
||||
|
||||
const char *vulkan_light_uniforms = R"(
|
||||
layout(set=0, binding=5) uniform light {
|
||||
vec4 ambient;
|
||||
vec3 matdiffuse;
|
||||
vec4 matspecular;
|
||||
vec3 matemissive;
|
||||
vec3 pos[4];
|
||||
// TODO: Make lighttype/comp uniforms too
|
||||
vec3 att[4];
|
||||
vec3 dir[4];
|
||||
float angle[4];
|
||||
float spotCoef[4];
|
||||
vec3 ambient[4];
|
||||
vec3 diffuse[4];
|
||||
vec3 specular[4];
|
||||
)";
|
||||
|
||||
const char *vulkan_bone_uniforms = R"(
|
||||
layout(set=0, binding=6) uniform bone {
|
||||
mat4 m[8];
|
||||
)";
|
||||
|
||||
// Depth range and viewport
|
||||
//
|
||||
// After the multiplication with the projection matrix, we have a 4D vector in clip space.
|
||||
@ -178,81 +213,15 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
||||
// We will memcpy the parts into place in a big buffer so we can be quite dynamic about what parts
|
||||
// are present and what parts aren't, but we will not be ultra detailed about it.
|
||||
|
||||
// WRITE(p, )
|
||||
WRITE(p, "%s", vulkan_base_uniforms);
|
||||
if (enableLighting)
|
||||
WRITE(p, "%s", vulkan_light_uniforms);
|
||||
if (enableBones)
|
||||
WRITE(p, "%s", vulkan_bone_uniforms);
|
||||
|
||||
|
||||
if (isModeThrough) {
|
||||
WRITE(p, "uniform mat4 u_proj_through;\n");
|
||||
} else {
|
||||
WRITE(p, "uniform mat4 u_proj;\n");
|
||||
// Add all the uniforms we'll need to transform properly.
|
||||
}
|
||||
|
||||
bool prescale = false;
|
||||
|
||||
if (useHWTransform) {
|
||||
// When transforming by hardware, we need a great deal more uniforms...
|
||||
WRITE(p, "uniform mat4 u_world;\n");
|
||||
WRITE(p, "uniform mat4 u_view;\n");
|
||||
if (doTextureProjection)
|
||||
WRITE(p, "uniform mediump mat4 u_texmtx;\n");
|
||||
if (enableBones) {
|
||||
#ifdef USE_BONE_ARRAY
|
||||
WRITE(p, "uniform mediump mat4 u_bone[%i];\n", numBoneWeights);
|
||||
#else
|
||||
for (int i = 0; i < numBoneWeights; i++) {
|
||||
WRITE(p, "uniform mat4 u_bone%i;\n", i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (doTexture && (!prescale || uvGenMode == GE_TEXMAP_ENVIRONMENT_MAP || uvGenMode == GE_TEXMAP_TEXTURE_MATRIX)) {
|
||||
WRITE(p, "uniform vec4 u_uvscaleoffset;\n");
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (doLight[i] != LIGHT_OFF) {
|
||||
// This is needed for shade mapping
|
||||
WRITE(p, "uniform vec3 u_lightpos%i;\n", i);
|
||||
}
|
||||
if (doLight[i] == LIGHT_FULL) {
|
||||
GELightType type = static_cast<GELightType>(id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2));
|
||||
GELightComputation comp = static_cast<GELightComputation>(id.Bits(VS_BIT_LIGHT0_COMP + 4 * i, 2));
|
||||
|
||||
if (type != GE_LIGHTTYPE_DIRECTIONAL)
|
||||
WRITE(p, "uniform mediump vec3 u_lightatt%i;\n", i);
|
||||
|
||||
if (type == GE_LIGHTTYPE_SPOT || type == GE_LIGHTTYPE_UNKNOWN) {
|
||||
WRITE(p, "uniform mediump vec3 u_lightdir%i;\n", i);
|
||||
WRITE(p, "uniform mediump float u_lightangle%i;\n", i);
|
||||
WRITE(p, "uniform mediump float u_lightspotCoef%i;\n", i);
|
||||
}
|
||||
WRITE(p, "uniform lowp vec3 u_lightambient%i;\n", i);
|
||||
WRITE(p, "uniform lowp vec3 u_lightdiffuse%i;\n", i);
|
||||
|
||||
if (comp != GE_LIGHTCOMP_ONLYDIFFUSE) {
|
||||
WRITE(p, "uniform lowp vec3 u_lightspecular%i;\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (enableLighting) {
|
||||
WRITE(p, "uniform lowp vec4 u_ambient;\n");
|
||||
if ((matUpdate & 2) == 0 || !hasColor)
|
||||
WRITE(p, "uniform lowp vec3 u_matdiffuse;\n");
|
||||
WRITE(p, "uniform lowp vec4 u_matspecular;\n"); // Specular coef is contained in alpha
|
||||
WRITE(p, "uniform lowp vec3 u_matemissive;\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (useHWTransform || !hasColor)
|
||||
WRITE(p, "uniform lowp vec4 u_matambientalpha;\n"); // matambient + matalpha
|
||||
|
||||
if (enableFog) {
|
||||
WRITE(p, "uniform highp vec2 u_fogcoef;\n");
|
||||
}
|
||||
|
||||
if (!isModeThrough && gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, "uniform highp vec4 u_depthRange;\n");
|
||||
}
|
||||
|
||||
WRITE(p, "layout (location = 1) %s out lowp vec4 v_color0;\n", shading);
|
||||
if (lmode) {
|
||||
WRITE(p, "layout (location = 2) %s out lowp vec3 v_color1;\n", shading);
|
||||
@ -276,9 +245,9 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
||||
// Apply the projection and viewport to get the Z buffer value, floor to integer, undo the viewport and projection.
|
||||
WRITE(p, "\nvec4 depthRoundZVP(vec4 v) {\n");
|
||||
WRITE(p, " float z = v.z / v.w;\n");
|
||||
WRITE(p, " z = z * u_depthRange.x + u_depthRange.y;\n");
|
||||
WRITE(p, " z = z * base.depthRange.x + base.depthRange.y;\n");
|
||||
WRITE(p, " z = floor(z);\n");
|
||||
WRITE(p, " z = (z - u_depthRange.z) * u_depthRange.w;\n");
|
||||
WRITE(p, " z = (z - base.depthRange.z) * base.depthRange.w;\n");
|
||||
WRITE(p, " return vec4(v.x, v.y, z * v.w, v.w);\n");
|
||||
WRITE(p, "}\n\n");
|
||||
}
|
||||
@ -299,7 +268,7 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
||||
if (lmode)
|
||||
WRITE(p, " v_color1 = color1;\n");
|
||||
} else {
|
||||
WRITE(p, " v_color0 = u_matambientalpha;\n");
|
||||
WRITE(p, " v_color0 = base.matambientalpha;\n");
|
||||
if (lmode)
|
||||
WRITE(p, " v_color1 = vec3(0.0);\n");
|
||||
}
|
||||
@ -307,22 +276,22 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
||||
WRITE(p, " v_fogdepth = position.w;\n");
|
||||
}
|
||||
if (isModeThrough) {
|
||||
WRITE(p, " gl_Position = u_proj_through * vec4(position.xyz, 1.0);\n");
|
||||
WRITE(p, " gl_Position = base.proj * vec4(position.xyz, 1.0);\n");
|
||||
} else {
|
||||
// The viewport is used in this case, so need to compensate for that.
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " gl_Position = depthRoundZVP(u_proj * vec4(position.xyz, 1.0));\n");
|
||||
WRITE(p, " gl_Position = depthRoundZVP(base.proj * vec4(position.xyz, 1.0));\n");
|
||||
} else {
|
||||
WRITE(p, " gl_Position = u_proj * vec4(position.xyz, 1.0);\n");
|
||||
WRITE(p, " gl_Position = base.proj * vec4(position.xyz, 1.0);\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Step 1: World Transform / Skinning
|
||||
if (!enableBones) {
|
||||
// No skinning, just standard T&L.
|
||||
WRITE(p, " vec3 worldpos = (u_world * vec4(position.xyz, 1.0)).xyz;\n");
|
||||
WRITE(p, " vec3 worldpos = (base.world * vec4(position.xyz, 1.0)).xyz;\n");
|
||||
if (hasNormal)
|
||||
WRITE(p, " mediump vec3 worldnormal = normalize((u_world * vec4(%snormal, 0.0)).xyz);\n", flipNormal ? "-" : "");
|
||||
WRITE(p, " mediump vec3 worldnormal = normalize((base.world * vec4(%snormal, 0.0)).xyz);\n", flipNormal ? "-" : "");
|
||||
else
|
||||
WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n");
|
||||
} else {
|
||||
@ -334,8 +303,6 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
||||
"w2.x", "w2.y", "w2.z", "w2.w",
|
||||
};
|
||||
|
||||
#if defined(USE_FOR_LOOP) && defined(USE_BONE_ARRAY)
|
||||
|
||||
// To loop through the weights, we unfortunately need to put them in a float array.
|
||||
// GLSL ES sucks - no way to directly initialize an array!
|
||||
switch (numBoneWeights) {
|
||||
@ -349,80 +316,48 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
||||
case 8: WRITE(p, " float w[8]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z; w[3] = w1.w; w[4] = w2.x; w[5] = w2.y; w[6] = w2.z; w[7] = w2.w;\n"); break;
|
||||
}
|
||||
|
||||
WRITE(p, " mat4 skinMatrix = w[0] * u_bone[0];\n");
|
||||
WRITE(p, " mat4 skinMatrix = w[0] * bone.m[0];\n");
|
||||
if (numBoneWeights > 1) {
|
||||
WRITE(p, " for (int i = 1; i < %i; i++) {\n", numBoneWeights);
|
||||
WRITE(p, " skinMatrix += w[i] * u_bone[i];\n");
|
||||
WRITE(p, " skinMatrix += w[i] * bone.m[i];\n");
|
||||
WRITE(p, " }\n");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef USE_BONE_ARRAY
|
||||
if (numBoneWeights == 1)
|
||||
WRITE(p, " mat4 skinMatrix = w1 * u_bone[0]");
|
||||
else
|
||||
WRITE(p, " mat4 skinMatrix = w1.x * u_bone[0]");
|
||||
for (int i = 1; i < numBoneWeights; i++) {
|
||||
const char *weightAttr = boneWeightAttr[i];
|
||||
// workaround for "cant do .x of scalar" issue
|
||||
if (numBoneWeights == 1 && i == 0) weightAttr = "w1";
|
||||
if (numBoneWeights == 5 && i == 4) weightAttr = "w2";
|
||||
WRITE(p, " + %s * u_bone[%i]", weightAttr, i);
|
||||
}
|
||||
#else
|
||||
// Uncomment this to screw up bone shaders to check the vertex shader software fallback
|
||||
// WRITE(p, "THIS SHOULD ERROR! #error");
|
||||
if (numBoneWeights == 1)
|
||||
WRITE(p, " mat4 skinMatrix = w1 * u_bone0");
|
||||
else
|
||||
WRITE(p, " mat4 skinMatrix = w1.x * u_bone0");
|
||||
for (int i = 1; i < numBoneWeights; i++) {
|
||||
const char *weightAttr = boneWeightAttr[i];
|
||||
// workaround for "cant do .x of scalar" issue
|
||||
if (numBoneWeights == 1 && i == 0) weightAttr = "w1";
|
||||
if (numBoneWeights == 5 && i == 4) weightAttr = "w2";
|
||||
WRITE(p, " + %s * u_bone%i", weightAttr, i);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
WRITE(p, ";\n");
|
||||
|
||||
// Trying to simplify this results in bugs in LBP...
|
||||
WRITE(p, " vec3 skinnedpos = (skinMatrix * vec4(position, 1.0)).xyz %s;\n", factor);
|
||||
WRITE(p, " vec3 worldpos = (u_world * vec4(skinnedpos, 1.0)).xyz;\n");
|
||||
WRITE(p, " vec3 worldpos = (base.world * vec4(skinnedpos, 1.0)).xyz;\n");
|
||||
|
||||
if (hasNormal) {
|
||||
WRITE(p, " mediump vec3 skinnednormal = (skinMatrix * vec4(%snormal, 0.0)).xyz %s;\n", flipNormal ? "-" : "", factor);
|
||||
} else {
|
||||
WRITE(p, " mediump vec3 skinnednormal = (skinMatrix * vec4(0.0, 0.0, %s1.0, 0.0)).xyz %s;\n", flipNormal ? "-" : "", factor);
|
||||
}
|
||||
WRITE(p, " mediump vec3 worldnormal = normalize((u_world * vec4(skinnednormal, 0.0)).xyz);\n");
|
||||
WRITE(p, " mediump vec3 worldnormal = normalize((base.world * vec4(skinnednormal, 0.0)).xyz);\n");
|
||||
}
|
||||
|
||||
WRITE(p, " vec4 viewPos = u_view * vec4(worldpos, 1.0);\n");
|
||||
WRITE(p, " vec4 viewPos = base.view * vec4(worldpos, 1.0);\n");
|
||||
|
||||
// Final view and projection transforms.
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " gl_Position = depthRoundZVP(u_proj * viewPos);\n");
|
||||
WRITE(p, " gl_Position = depthRoundZVP(base.proj * viewPos);\n");
|
||||
} else {
|
||||
WRITE(p, " gl_Position = u_proj * viewPos;\n");
|
||||
WRITE(p, " gl_Position = base.proj * viewPos;\n");
|
||||
}
|
||||
|
||||
// TODO: Declare variables for dots for shade mapping if needed.
|
||||
|
||||
const char *ambientStr = (matUpdate & 1) && hasColor ? "color0" : "u_matambientalpha";
|
||||
const char *diffuseStr = (matUpdate & 2) && hasColor ? "color0.rgb" : "u_matdiffuse";
|
||||
const char *specularStr = (matUpdate & 4) && hasColor ? "color0.rgb" : "u_matspecular.rgb";
|
||||
const char *ambientStr = (matUpdate & 1) && hasColor ? "color0" : "base.matambientalpha";
|
||||
const char *diffuseStr = (matUpdate & 2) && hasColor ? "color0.rgb" : "light.matdiffuse";
|
||||
const char *specularStr = (matUpdate & 4) && hasColor ? "color0.rgb" : "light.matspecular.rgb";
|
||||
|
||||
bool diffuseIsZero = true;
|
||||
bool specularIsZero = true;
|
||||
bool distanceNeeded = false;
|
||||
|
||||
if (enableLighting) {
|
||||
WRITE(p, " lowp vec4 lightSum0 = u_ambient * %s + vec4(u_matemissive, 0.0);\n", ambientStr);
|
||||
WRITE(p, " lowp vec4 lightSum0 = light.ambient * %s + vec4(light.matemissive, 0.0);\n", ambientStr);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
GELightType type = static_cast<GELightType>(id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2));
|
||||
@ -460,9 +395,9 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
||||
|
||||
if (type == GE_LIGHTTYPE_DIRECTIONAL) {
|
||||
// We prenormalize light positions for directional lights.
|
||||
WRITE(p, " toLight = u_lightpos%i;\n", i);
|
||||
WRITE(p, " toLight = light.pos[%i];\n", i);
|
||||
} else {
|
||||
WRITE(p, " toLight = u_lightpos%i - worldpos;\n", i);
|
||||
WRITE(p, " toLight = light.pos[%i] - worldpos;\n", i);
|
||||
WRITE(p, " distance = length(toLight);\n");
|
||||
WRITE(p, " toLight /= distance;\n");
|
||||
}
|
||||
@ -477,7 +412,7 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
||||
WRITE(p, " if (dot%i == 0.0 && u_matspecular.a == 0.0) {\n", i);
|
||||
WRITE(p, " dot%i = 1.0;\n", i);
|
||||
WRITE(p, " } else {\n");
|
||||
WRITE(p, " dot%i = pow(dot%i, u_matspecular.a);\n", i, i);
|
||||
WRITE(p, " dot%i = pow(dot[%i], u_matspecular.a);\n", i, i);
|
||||
WRITE(p, " }\n");
|
||||
}
|
||||
|
||||
@ -489,13 +424,13 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
||||
timesLightScale = "";
|
||||
break;
|
||||
case GE_LIGHTTYPE_POINT:
|
||||
WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, vec3(1.0, distance, distance*distance)), 0.0, 1.0);\n", i);
|
||||
WRITE(p, " lightScale = clamp(1.0 / dot(light.att[%i], vec3(1.0, distance, distance*distance)), 0.0, 1.0);\n", i);
|
||||
break;
|
||||
case GE_LIGHTTYPE_SPOT:
|
||||
case GE_LIGHTTYPE_UNKNOWN:
|
||||
WRITE(p, " lowp float angle%i = dot(normalize(u_lightdir%i), toLight);\n", i, i);
|
||||
WRITE(p, " if (angle%i >= u_lightangle%i) {\n", i, i);
|
||||
WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, vec3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle%i, u_lightspotCoef%i);\n", i, i, i);
|
||||
WRITE(p, " lowp float angle%i = dot(normalize(light.dir[%i]), toLight);\n", i, i);
|
||||
WRITE(p, " if (angle[%i] >= light.angle[%i]) {\n", i, i);
|
||||
WRITE(p, " lightScale = clamp(1.0 / dot(light.att[%i], vec3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle[%i], light.spotCoef[%i]);\n", i, i, i);
|
||||
WRITE(p, " } else {\n");
|
||||
WRITE(p, " lightScale = 0.0;\n");
|
||||
WRITE(p, " }\n");
|
||||
@ -505,13 +440,13 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
||||
break;
|
||||
}
|
||||
|
||||
WRITE(p, " diffuse = (u_lightdiffuse%i * %s) * dot%i;\n", i, diffuseStr, i);
|
||||
WRITE(p, " diffuse = (light.diffuse[%i] * %s) * dot[%i];\n", i, diffuseStr, i);
|
||||
if (doSpecular) {
|
||||
WRITE(p, " dot%i = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);\n", i);
|
||||
WRITE(p, " if (dot%i > 0.0)\n", i);
|
||||
WRITE(p, " lightSum1 += u_lightspecular%i * %s * (pow(dot%i, u_matspecular.a) %s);\n", i, specularStr, i, timesLightScale);
|
||||
WRITE(p, " dot[%i] = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);\n", i);
|
||||
WRITE(p, " if (dot[%i] > 0.0)\n", i);
|
||||
WRITE(p, " lightSum1 += light.specular[%i] * %s * (pow(dot[%i], u_matspecular.a) %s);\n", i, specularStr, i, timesLightScale);
|
||||
}
|
||||
WRITE(p, " lightSum0.rgb += (u_lightambient%i * %s.rgb + diffuse)%s;\n", i, ambientStr, timesLightScale);
|
||||
WRITE(p, " lightSum0.rgb += (light.ambient[%i] * %s.rgb + diffuse)%s;\n", i, ambientStr, timesLightScale);
|
||||
}
|
||||
|
||||
if (enableLighting) {
|
||||
@ -595,12 +530,12 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
||||
break;
|
||||
}
|
||||
// Transform by texture matrix. XYZ as we are doing projection mapping.
|
||||
WRITE(p, " v_texcoord = (u_texmtx * %s).xyz * vec3(u_uvscaleoffset.xy, 1.0);\n", temp_tc.c_str());
|
||||
WRITE(p, " v_texcoord = (base.texmtx * %s).xyz * vec3(base.uvscaleoffset.xy, 1.0);\n", temp_tc.c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources.
|
||||
WRITE(p, " v_texcoord = u_uvscaleoffset.xy * vec2(1.0 + dot(normalize(u_lightpos%i), worldnormal), 1.0 + dot(normalize(u_lightpos%i), worldnormal)) * 0.5;\n", ls0, ls1);
|
||||
WRITE(p, " v_texcoord = base.uvscaleoffset.xy * vec2(1.0 + dot(normalize(light.pos[%i]), worldnormal), 1.0 + dot(normalize(light.pos[%i]), worldnormal)) * 0.5;\n", ls0, ls1);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user