From deffbca3ee209f6aea3358692d9ca6dc7090e748 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 28 Apr 2022 15:51:31 +0000 Subject: SL-17281 environment map prototype (stupid slow and hacky, but provides a way to get a "real" environment map for shader development) --- indra/llrender/llcubemap.cpp | 218 +++++++------------------------------------ indra/llrender/llcubemap.h | 16 ++-- 2 files changed, 40 insertions(+), 194 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index 834084674e..40d15280d3 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -166,6 +166,39 @@ void LLCubeMap::init(const std::vector >& rawimages) } } +void LLCubeMap::initEnvironmentMap(const std::vector >& rawimages) +{ + llassert(rawimages.size() == 6); + + U32 texname = 0; + + LLImageGL::generateTextures(1, &texname); + + U32 resolution = rawimages[0]->getWidth(); + U32 components = rawimages[0]->getComponents(); + + for (int i = 0; i < 6; i++) + { + llassert(rawimages[i]->getWidth() == resolution); + llassert(rawimages[i]->getHeight() == resolution); + llassert(rawimages[i]->getComponents() == components); + + + mImages[i] = new LLImageGL(resolution, resolution, components, FALSE); + mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP); + mRawImages[i] = rawimages[i]; + mImages[i]->createGLTexture(0, mRawImages[i], texname); + + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname); + mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP); + stop_glerror(); + + mImages[i]->setSubImage(mRawImages[i], 0, 0, resolution, resolution); + } + gGL.getTexUnit(0)->disable(); + disable(); +} + GLuint LLCubeMap::getGLName() { return mImages[0]->getTexName(); @@ -256,191 +289,6 @@ void LLCubeMap::restoreMatrix() }*/ } -void LLCubeMap::setReflection (void) -{ - gGL.getTexUnit(mTextureStage)->bindManual(LLTexUnit::TT_CUBE_MAP, getGLName()); - mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); - mImages[0]->setAddressMode(LLTexUnit::TAM_CLAMP); -} - -LLVector3 LLCubeMap::map(U8 side, U16 v_val, U16 h_val) const -{ - LLVector3 dir; - - const U8 curr_coef = side >> 1; // 0/1 = X axis, 2/3 = Y, 4/5 = Z - const S8 side_dir = (((side & 1) << 1) - 1); // even = -1, odd = 1 - const U8 i_coef = (curr_coef + 1) % 3; - const U8 j_coef = (i_coef + 1) % 3; - - dir.mV[curr_coef] = side_dir; - - switch (side) - { - case 0: // negative X - dir.mV[i_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1; - dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1; - break; - case 1: // positive X - dir.mV[i_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1; - dir.mV[j_coef] = -F32((h_val<<1) + 1) / RESOLUTION + 1; - break; - case 2: // negative Y - dir.mV[i_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1; - dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1; - break; - case 3: // positive Y - dir.mV[i_coef] = F32((v_val<<1) + 1) / RESOLUTION - 1; - dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1; - break; - case 4: // negative Z - dir.mV[i_coef] = -F32((h_val<<1) + 1) / RESOLUTION + 1; - dir.mV[j_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1; - break; - case 5: // positive Z - dir.mV[i_coef] = -F32((h_val<<1) + 1) / RESOLUTION + 1; - dir.mV[j_coef] = F32((v_val<<1) + 1) / RESOLUTION - 1; - break; - default: - dir.mV[i_coef] = F32((v_val<<1) + 1) / RESOLUTION - 1; - dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1; - } - - dir.normVec(); - return dir; -} - - -BOOL LLCubeMap::project(F32& v_val, F32& h_val, BOOL& outside, - U8 side, const LLVector3& dir) const -{ - const U8 curr_coef = side >> 1; // 0/1 = X axis, 2/3 = Y, 4/5 = Z - const S8 side_dir = (((side & 1) << 1) - 1); // even = -1, odd = 1 - const U8 i_coef = (curr_coef + 1) % 3; - const U8 j_coef = (i_coef + 1) % 3; - - outside = TRUE; - if (side_dir * dir.mV[curr_coef] < 0) - return FALSE; - - LLVector3 ray; - - F32 norm_val = fabs(dir.mV[curr_coef]); - - if (norm_val < epsilon) - norm_val = 1e-5f; - - ray.mV[curr_coef] = side_dir; - ray.mV[i_coef] = dir.mV[i_coef] / norm_val; - ray.mV[j_coef] = dir.mV[j_coef] / norm_val; - - - const F32 i_val = (ray.mV[i_coef] + 1) * 0.5f * RESOLUTION; - const F32 j_val = (ray.mV[j_coef] + 1) * 0.5f * RESOLUTION; - - switch (side) - { - case 0: // negative X - v_val = RESOLUTION - i_val; - h_val = j_val; - break; - case 1: // positive X - v_val = RESOLUTION - i_val; - h_val = RESOLUTION - j_val; - break; - case 2: // negative Y - v_val = RESOLUTION - i_val; - h_val = j_val; - break; - case 3: // positive Y - v_val = i_val; - h_val = j_val; - break; - case 4: // negative Z - v_val = RESOLUTION - j_val; - h_val = RESOLUTION - i_val; - break; - case 5: // positive Z - v_val = RESOLUTION - j_val; - h_val = i_val; - break; - default: - v_val = i_val; - h_val = j_val; - } - - outside = ((v_val < 0) || (v_val > RESOLUTION) || - (h_val < 0) || (h_val > RESOLUTION)); - - return TRUE; -} - -BOOL LLCubeMap::project(F32& v_min, F32& v_max, F32& h_min, F32& h_max, - U8 side, LLVector3 dir[4]) const -{ - v_min = h_min = RESOLUTION; - v_max = h_max = 0; - - BOOL fully_outside = TRUE; - for (U8 vtx = 0; vtx < 4; ++vtx) - { - F32 v_val, h_val; - BOOL outside; - BOOL consider = project(v_val, h_val, outside, side, dir[vtx]); - if (!outside) - fully_outside = FALSE; - if (consider) - { - if (v_val < v_min) v_min = v_val; - if (v_val > v_max) v_max = v_val; - if (h_val < h_min) h_min = h_val; - if (h_val > h_max) h_max = h_val; - } - } - - v_min = llmax(0.0f, v_min); - v_max = llmin(RESOLUTION - epsilon, v_max); - h_min = llmax(0.0f, h_min); - h_max = llmin(RESOLUTION - epsilon, h_max); - - return !fully_outside; -} - - -void LLCubeMap::paintIn(LLVector3 dir[4], const LLColor4U& col) -{ - LL_PROFILE_ZONE_SCOPED; - F32 v_min, v_max, h_min, h_max; - LLVector3 center = dir[0] + dir[1] + dir[2] + dir[3]; - center.normVec(); - - for (U8 side = 0; side < 6; ++side) - { - if (!project(v_min, v_max, h_min, h_max, side, dir)) - continue; - - U8 *td = mRawImages[side]->getData(); - - U16 v_minu = (U16) v_min; - U16 v_maxu = (U16) (ceil(v_max) + 0.5); - U16 h_minu = (U16) h_min; - U16 h_maxu = (U16) (ceil(h_max) + 0.5); - - for (U16 v = v_minu; v < v_maxu; ++v) - for (U16 h = h_minu; h < h_maxu; ++h) - //for (U16 v = 0; v < RESOLUTION; ++v) - // for (U16 h = 0; h < RESOLUTION; ++h) - { - const LLVector3 ray = map(side, v, h); - if (ray * center > 0.999) - { - const U32 offset = (RESOLUTION * v + h) * 4; - for (U8 cc = 0; cc < 3; ++cc) - td[offset + cc] = U8((td[offset + cc] + col.mV[cc]) * 0.5); - } - } - mImages[side]->setSubImage(mRawImages[side], 0, 0, RESOLUTION, RESOLUTION); - } -} void LLCubeMap::destroyGL() { diff --git a/indra/llrender/llcubemap.h b/indra/llrender/llcubemap.h index a01636d8d4..9ce4a94bca 100644 --- a/indra/llrender/llcubemap.h +++ b/indra/llrender/llcubemap.h @@ -40,6 +40,13 @@ class LLCubeMap : public LLRefCount public: LLCubeMap(bool init_as_srgb); void init(const std::vector >& rawimages); + + // init from environment map images + // Similar to init, but takes ownership of rawimages and makes this cubemap + // respect the resolution of rawimages + // Raw images must point to array of six square images that are all the same resolution + // For example usage, see LLEnvironmentMap + void initEnvironmentMap(const std::vector >& rawimages); void initGL(); void initRawData(const std::vector >& rawimages); void initGLData(); @@ -54,18 +61,9 @@ public: void disableTexture(void); void setMatrix(S32 stage); void restoreMatrix(); - void setReflection (void); - - void finishPaint(); GLuint getGLName(); - LLVector3 map(U8 side, U16 v_val, U16 h_val) const; - BOOL project(F32& v_val, F32& h_val, BOOL& outside, - U8 side, const LLVector3& dir) const; - BOOL project(F32& v_min, F32& v_max, F32& h_min, F32& h_max, - U8 side, LLVector3 dir[4]) const; - void paintIn(LLVector3 dir[4], const LLColor4U& col); void destroyGL(); public: -- cgit v1.3 From 93a025966649e281ceff8d1471bc983cc036bc17 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 29 Apr 2022 13:51:11 +0000 Subject: SL-17282 prototype mixing of reflection map into legacy materials --- indra/llrender/llcubemap.cpp | 8 +++- indra/llrender/llglslshader.cpp | 18 ++++++++- indra/llrender/llshadermgr.cpp | 1 + indra/llrender/llshadermgr.h | 1 + .../shaders/class1/deferred/multiPointLightF.glsl | 1 - .../shaders/class1/deferred/multiSpotLightF.glsl | 1 - .../shaders/class1/deferred/pointLightF.glsl | 1 - .../shaders/class2/deferred/softenLightF.glsl | 21 +++++++++- indra/newview/llenvironmentmap.cpp | 2 +- indra/newview/pipeline.cpp | 45 ++++++++++++++++++---- 10 files changed, 83 insertions(+), 16 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index 40d15280d3..cc61158aa6 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -183,8 +183,7 @@ void LLCubeMap::initEnvironmentMap(const std::vector >& ra llassert(rawimages[i]->getHeight() == resolution); llassert(rawimages[i]->getComponents() == components); - - mImages[i] = new LLImageGL(resolution, resolution, components, FALSE); + mImages[i] = new LLImageGL(resolution, resolution, components, TRUE); mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP); mRawImages[i] = rawimages[i]; mImages[i]->createGLTexture(0, mRawImages[i], texname); @@ -195,6 +194,11 @@ void LLCubeMap::initEnvironmentMap(const std::vector >& ra mImages[i]->setSubImage(mRawImages[i], 0, 0, resolution, resolution); } + enableTexture(0); + bind(); + mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); gGL.getTexUnit(0)->disable(); disable(); } diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 185c1450c8..3001375c60 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -832,6 +832,9 @@ BOOL LLGLSLShader::mapUniforms(const vector * uniforms) As example where this situation appear see: "Deferred Material Shader 28/29/30/31" And tickets: MAINT-4165, MAINT-4839, MAINT-3568, MAINT-6437 + + --- davep TODO -- pretty sure the entire block here is superstitious and that the uniform index has nothing to do with the texture channel + texture channel should follow the uniform VALUE */ @@ -840,6 +843,7 @@ BOOL LLGLSLShader::mapUniforms(const vector * uniforms) S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap"); S32 altDiffuseMap = glGetUniformLocationARB(mProgramObject, "altDiffuseMap"); S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap"); + S32 reflectionMap = glGetUniformLocationARB(mProgramObject, "reflectionMap"); std::set skip_index; @@ -882,6 +886,12 @@ BOOL LLGLSLShader::mapUniforms(const vector * uniforms) continue; } + if (-1 == reflectionMap && std::string(name) == "reflectionMap") + { + reflectionMap = i; + continue; + } + if (-1 == altDiffuseMap && std::string(name) == "altDiffuseMap") { altDiffuseMap = i; @@ -892,8 +902,9 @@ BOOL LLGLSLShader::mapUniforms(const vector * uniforms) bool specularDiff = specularMap < diffuseMap && -1 != specularMap; bool bumpLessDiff = bumpMap < diffuseMap && -1 != bumpMap; bool envLessDiff = environmentMap < diffuseMap && -1 != environmentMap; + bool refLessDiff = reflectionMap < diffuseMap && -1 != reflectionMap; - if (specularDiff || bumpLessDiff || envLessDiff) + if (specularDiff || bumpLessDiff || envLessDiff || refLessDiff) { mapUniform(diffuseMap, uniforms); skip_index.insert(diffuseMap); @@ -912,6 +923,11 @@ BOOL LLGLSLShader::mapUniforms(const vector * uniforms) mapUniform(environmentMap, uniforms); skip_index.insert(environmentMap); } + + if (-1 != reflectionMap) { + mapUniform(reflectionMap, uniforms); + skip_index.insert(reflectionMap); + } } } diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index c100c182dd..cd7ec478bb 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1155,6 +1155,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("bumpMap"); mReservedUniforms.push_back("bumpMap2"); mReservedUniforms.push_back("environmentMap"); + mReservedUniforms.push_back("reflectionMap"); mReservedUniforms.push_back("cloud_noise_texture"); mReservedUniforms.push_back("cloud_noise_texture_next"); mReservedUniforms.push_back("fullbright"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 67c0d6ab10..7ca4862ed9 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -80,6 +80,7 @@ public: BUMP_MAP, // "bumpMap" BUMP_MAP2, // "bumpMap2" ENVIRONMENT_MAP, // "environmentMap" + REFLECTION_MAP, // "reflectionMap" CLOUD_NOISE_MAP, // "cloud_noise_texture" CLOUD_NOISE_MAP_NEXT, // "cloud_noise_texture_next" FULLBRIGHT, // "fullbright" diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 09c47165dd..0ae4bbfc5d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -36,7 +36,6 @@ out vec4 frag_color; uniform sampler2DRect depthMap; uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; -uniform samplerCube environmentMap; uniform sampler2D noiseMap; uniform sampler2D lightFunc; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index ec3fb9c543..8dcc18080d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -42,7 +42,6 @@ uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; -uniform samplerCube environmentMap; uniform sampler2D noiseMap; uniform sampler2D projectionMap; uniform sampler2D lightFunc; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 18616a9bb3..c1061f1933 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -36,7 +36,6 @@ out vec4 frag_color; uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; uniform sampler2DRect normalMap; -uniform samplerCube environmentMap; uniform sampler2D noiseMap; uniform sampler2D lightFunc; uniform sampler2DRect depthMap; diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 7700d16007..6958841d05 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -40,6 +40,7 @@ uniform sampler2DRect normalMap; uniform sampler2DRect lightMap; uniform sampler2DRect depthMap; uniform samplerCube environmentMap; +uniform samplerCube reflectionMap; uniform sampler2D lightFunc; uniform float blur_size; @@ -119,6 +120,8 @@ void main() vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); + vec3 env_vec = env_mat * refnormpersp; + if (spec.a > 0.0) // specular reflection { float sa = dot(refnormpersp, light_dir.xyz); @@ -128,13 +131,28 @@ void main() vec3 spec_contrib = dumbshiny * spec.rgb; bloom = dot(spec_contrib, spec_contrib) / 6; color.rgb += spec_contrib; + + // add reflection map - EXPERIMENTAL WORK IN PROGRESS + float reflection_lods = 11; // TODO -- base this on resolution of reflection map instead of hard coding + float min_lod = textureQueryLod(reflectionMap,env_vec).y; // lower is higher res + + //vec3 reflected_color = texture(reflectionMap, env_vec, (1.0-spec.a)*reflection_lod).rgb; + vec3 reflected_color = textureLod(reflectionMap, env_vec, max(min_lod, (1.0-spec.a)*reflection_lods)).rgb; + //vec3 reflected_color = texture(reflectionMap, env_vec).rgb; + //vec3 reflected_color = normalize(env_vec)*0.5+0.5; + reflected_color *= spec.rgb; + vec3 mixer = clamp(color.rgb + vec3(1,1,1) - spec.rgb, vec3(0,0,0), vec3(1,1,1)); + + color.rgb = mix(reflected_color*sqrt(spec.a*0.8), color, mixer); + + //color.rgb = mix(reflected_color * spec.rgb * sqrt(spec.a*0.8), color.rgb, color.rgb); + //color.rgb += reflected_color * spec.rgb; // * sqrt(spec.a*0.8), color.rgb, color.rgb); } color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a); if (envIntensity > 0.0) { // add environmentmap - vec3 env_vec = env_mat * refnormpersp; vec3 reflected_color = textureCube(environmentMap, env_vec).rgb; color = mix(color.rgb, reflected_color, envIntensity); } @@ -154,5 +172,6 @@ void main() // convert to linear as fullscreen lights need to sum in linear colorspace // and will be gamma (re)corrected downstream... frag_color.rgb = srgb_to_linear(color.rgb); + //frag_color.r = 1.0; frag_color.a = bloom; } diff --git a/indra/newview/llenvironmentmap.cpp b/indra/newview/llenvironmentmap.cpp index 7f23c630f1..ee185d8ce7 100644 --- a/indra/newview/llenvironmentmap.cpp +++ b/indra/newview/llenvironmentmap.cpp @@ -67,7 +67,7 @@ void LLEnvironmentMap::update(const LLVector3& origin, U32 resolution) LLVector3(0, -1, 0), LLVector3(0, 0, -1), LLVector3(0, 0, 1), - LLVector3(0, 1, 0), + LLVector3(0, -1, 0), LLVector3(0, -1, 0) }; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 09437473d9..ac7276e1e0 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8188,24 +8188,42 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ stop_glerror(); + bool setup_env_mat = false; channel = shader.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); if (channel > -1) { - LLCubeMap* cube_map = mEnvironmentMap.mCubeMap.notNull() ? mEnvironmentMap.mCubeMap : gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if (cube_map) { + setup_env_mat = true; cube_map->enable(channel); cube_map->bind(); - F32* m = gGLModelView; - - F32 mat[] = { m[0], m[1], m[2], - m[4], m[5], m[6], - m[8], m[9], m[10] }; - - shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); } } + channel = shader.enableTexture(LLShaderMgr::REFLECTION_MAP, LLTexUnit::TT_CUBE_MAP); + if (channel > -1) + { + LLCubeMap* cube_map = mEnvironmentMap.mCubeMap; + if (cube_map) + { + setup_env_mat = true; + cube_map->enable(channel); + cube_map->bind(); + } + } + + if (setup_env_mat) + { + F32* m = gGLModelView; + + F32 mat[] = { m[0], m[1], m[2], + m[4], m[5], m[6], + m[8], m[9], m[10] }; + + shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); + } + if (gAtmosphere) { // bind precomputed textures necessary for calculating sun and sky luminance @@ -9103,6 +9121,17 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) cube_map->disable(); } } + + channel = shader.disableTexture(LLShaderMgr::REFLECTION_MAP, LLTexUnit::TT_CUBE_MAP); + if (channel > -1) + { + LLCubeMap* cube_map = mEnvironmentMap.mCubeMap; + if (cube_map) + { + cube_map->disable(); + } + } + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->activate(); shader.unbind(); -- cgit v1.3